summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-06-01 10:39:30 +1000
committerAndrew Tridgell <tridge@samba.org>2009-06-01 10:39:30 +1000
commitba95882155db4f8c10725f47f70ae482d5343f9a (patch)
tree52c65ddfbcd81f3dcbb3b91183ae043b9c51acd5
parent67b83d2489788f1899c253fdab554d0998f9c044 (diff)
parent14c13620345dfd9f1e18761f103aa66138bf8907 (diff)
downloadsamba-ba95882155db4f8c10725f47f70ae482d5343f9a.tar.gz
samba-ba95882155db4f8c10725f47f70ae482d5343f9a.tar.bz2
samba-ba95882155db4f8c10725f47f70ae482d5343f9a.zip
Merge branch 'master' of ssh://git.samba.org/data/git/samba
-rw-r--r--docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml2
-rw-r--r--lib/async_req/async_sock.c40
-rw-r--r--lib/async_req/async_sock.h20
-rw-r--r--lib/async_req/config.mk1
-rw-r--r--lib/crypto/sha256.c2
-rw-r--r--lib/nss_wrapper/nss_wrapper.c84
-rw-r--r--lib/nss_wrapper/nss_wrapper.h6
-rw-r--r--lib/nss_wrapper/testsuite.c332
-rw-r--r--lib/replace/system/config.m41
-rw-r--r--lib/util/config.mk3
-rw-r--r--lib/util/tevent_unix.c20
-rw-r--r--lib/util/tevent_unix.h20
-rw-r--r--lib/util/util.h12
-rw-r--r--lib/util/util_id.c88
-rw-r--r--librpc/gen_ndr/security.h6
-rw-r--r--librpc/idl/security.idl6
-rw-r--r--nsswitch/config.mk6
-rw-r--r--nsswitch/libwbclient/config.mk15
-rw-r--r--nsswitch/libwbclient/libwbclient.h1
-rw-r--r--nsswitch/libwbclient/wb_reqtrans.c (renamed from source3/lib/wb_reqtrans.c)38
-rw-r--r--nsswitch/libwbclient/wbc_async.c (renamed from source3/lib/wbclient.c)51
-rw-r--r--nsswitch/libwbclient/wbc_async.h (renamed from source3/include/wbc_async.h)28
-rw-r--r--nsswitch/libwbclient/wbc_pam.c2
-rw-r--r--nsswitch/libwbclient/wbclient.c2
-rw-r--r--nsswitch/libwbclient/wbclient_internal.h1
-rw-r--r--nsswitch/winbind_struct_protocol.h5
-rw-r--r--selftest/target/Samba3.pm1
-rw-r--r--source3/Makefile.in15
-rw-r--r--source3/auth/auth_util.c12
-rw-r--r--source3/client/client.c16
-rw-r--r--source3/include/proto.h57
-rw-r--r--source3/include/smbldap.h11
-rw-r--r--source3/lib/ads_flags.c150
-rw-r--r--source3/lib/smbldap.c133
-rw-r--r--source3/lib/util.c33
-rw-r--r--source3/libads/ads_utils.c138
-rw-r--r--source3/libads/ldap.c119
-rw-r--r--source3/libsmb/clifile.c755
-rw-r--r--source3/libsmb/dsgetdcname.c4
-rw-r--r--source3/libsmb/libsmb_context.c2
-rw-r--r--source3/modules/onefs.h13
-rw-r--r--source3/modules/onefs_acl.c5
-rw-r--r--source3/modules/onefs_dir.c12
-rw-r--r--source3/modules/onefs_notify.c8
-rw-r--r--source3/modules/onefs_open.c38
-rw-r--r--source3/modules/onefs_streams.c83
-rw-r--r--source3/modules/onefs_system.c94
-rw-r--r--source3/modules/vfs_onefs.c16
-rw-r--r--source3/pam_smbpass/pam_smb_passwd.c2
-rw-r--r--source3/pam_smbpass/support.c14
-rw-r--r--source3/param/loadparm.c5
-rw-r--r--source3/passdb/passdb.c326
-rw-r--r--source3/passdb/pdb_interface.c20
-rw-r--r--source3/passdb/pdb_ldap.c104
-rw-r--r--source3/rpc_server/srv_lsa_hnd.c2
-rw-r--r--source3/rpc_server/srv_netlog_nt.c13
-rw-r--r--source3/samba4.m41
-rw-r--r--source3/samba4.mk1
-rwxr-xr-xsource3/script/tests/selftest.sh1
-rwxr-xr-xsource3/script/tests/test_posix_s3.sh4
-rw-r--r--source3/smbd/dosmode.c20
-rw-r--r--source3/smbd/filename.c13
-rw-r--r--source3/smbd/open.c6
-rw-r--r--source3/smbd/trans2.c14
-rw-r--r--source3/torture/torture.c22
-rw-r--r--source3/utils/pdbedit.c755
-rw-r--r--source3/utils/smbpasswd.c42
-rw-r--r--source3/winbindd/idmap_adex/gc_util.c4
-rw-r--r--source3/winbindd/idmap_adex/provider_unified.c4
-rw-r--r--source4/Makefile1
-rw-r--r--source4/client/smbmnt.c306
-rw-r--r--source4/client/smbmount.c942
-rw-r--r--source4/client/smbumount.c186
-rw-r--r--source4/configure.ac1
-rw-r--r--source4/ldap_server/ldap_server.c22
-rw-r--r--source4/libcli/security/sddl.c23
-rw-r--r--source4/libcli/wbclient/config.mk4
-rw-r--r--source4/main.mk1
-rw-r--r--source4/ntvfs/posix/config.mk2
-rw-r--r--source4/rpc_server/config.mk2
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c19
-rwxr-xr-xsource4/selftest/tests.sh2
-rw-r--r--source4/setup/provision_configuration.ldif195
-rw-r--r--source4/torture/config.mk1
-rw-r--r--source4/torture/libnetapi/config.m428
-rw-r--r--source4/torture/libnetapi/config.mk17
-rw-r--r--source4/torture/libnetapi/libnetapi.c80
-rw-r--r--source4/torture/libnetapi/libnetapi_group.c520
-rw-r--r--source4/torture/libnetapi/libnetapi_user.c476
-rw-r--r--source4/torture/local/config.mk4
-rw-r--r--source4/torture/local/local.c1
-rw-r--r--source4/torture/rpc/samr.c160
-rw-r--r--source4/torture/torture.c9
93 files changed, 3977 insertions, 2905 deletions
diff --git a/docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml b/docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml
index b8bd3277a6..91e9712cb5 100644
--- a/docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml
+++ b/docs-xml/Samba3-HOWTO/TOSHARG-VFS.xml
@@ -276,7 +276,7 @@ quotasettings: gid nolimit = no
<para>
<indexterm><primary>logging</primary></indexterm>
- This auditing tool is more felxible than most people readily will recognize. There are a number of ways
+ This auditing tool is more flexible than most people will readily recognize. There are a number of ways
by which useful logging information can be recorded.
</para>
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index fe71b29117..d88edb177a 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -3,17 +3,21 @@
async socket syscalls
Copyright (C) Volker Lendecke 2008
- 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.
+ ** NOTE! The following LGPL license applies to the async_sock
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
- This program is distributed in the hope that it will be useful,
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -77,6 +81,10 @@ static void async_send_handler(struct tevent_context *ev,
tevent_req_data(req, struct async_send_state);
state->sent = send(state->fd, state->buf, state->len, state->flags);
+ if ((state->sent == -1) && (errno == EINTR)) {
+ /* retry */
+ return;
+ }
if (state->sent == -1) {
tevent_req_error(req, errno);
return;
@@ -144,6 +152,10 @@ static void async_recv_handler(struct tevent_context *ev,
state->received = recv(state->fd, state->buf, state->len,
state->flags);
+ if ((state->received == -1) && (errno == EINTR)) {
+ /* retry */
+ return;
+ }
if (state->received == -1) {
tevent_req_error(req, errno);
return;
@@ -422,7 +434,11 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
to_write += state->iov[i].iov_len;
}
- written = sys_writev(state->fd, state->iov, state->count);
+ written = writev(state->fd, state->iov, state->count);
+ if ((written == -1) && (errno = EINTR)) {
+ /* retry */
+ return;
+ }
if (written == -1) {
tevent_req_error(req, errno);
return;
@@ -530,6 +546,10 @@ static void read_packet_handler(struct tevent_context *ev,
nread = recv(state->fd, state->buf+state->nread, total-state->nread,
0);
+ if ((nread == -1) && (errno == EINTR)) {
+ /* retry */
+ return;
+ }
if (nread == -1) {
tevent_req_error(req, errno);
return;
@@ -566,7 +586,7 @@ static void read_packet_handler(struct tevent_context *ev,
return;
}
- tmp = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t, total+more);
+ tmp = talloc_realloc(state, state->buf, uint8_t, total+more);
if (tevent_req_nomem(tmp, req)) {
return;
}
diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h
index a50e93238a..d47be30589 100644
--- a/lib/async_req/async_sock.h
+++ b/lib/async_req/async_sock.h
@@ -3,17 +3,21 @@
async socket operations
Copyright (C) Volker Lendecke 2008
- 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.
+ ** NOTE! The following LGPL license applies to the async_sock
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
- This program is distributed in the hope that it will be useful,
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
diff --git a/lib/async_req/config.mk b/lib/async_req/config.mk
index bf0fd6a2db..1f4b557ce4 100644
--- a/lib/async_req/config.mk
+++ b/lib/async_req/config.mk
@@ -1,3 +1,4 @@
[SUBSYSTEM::LIBASYNC_REQ]
+PUBLIC_DEPENDENCIES = LIBREPLACE_NETWORK
LIBASYNC_REQ_OBJ_FILES = $(addprefix ../lib/async_req/, async_sock.o)
diff --git a/lib/crypto/sha256.c b/lib/crypto/sha256.c
index a2def25814..233abe23f8 100644
--- a/lib/crypto/sha256.c
+++ b/lib/crypto/sha256.c
@@ -189,7 +189,7 @@ struct x32{
void
SHA256_Update (SHA256_CTX *m, const void *v, size_t len)
{
- const unsigned char *p = v;
+ const unsigned char *p = (const unsigned char *)v;
size_t old_sz = m->sz[0];
size_t offset;
diff --git a/lib/nss_wrapper/nss_wrapper.c b/lib/nss_wrapper/nss_wrapper.c
index 1875dc3e4f..d7f7b0ba56 100644
--- a/lib/nss_wrapper/nss_wrapper.c
+++ b/lib/nss_wrapper/nss_wrapper.c
@@ -68,6 +68,11 @@
#define getgrent_r(grdst, buf, buflen, grdstp) ENOSYS
#endif
+/* not all systems have getgrouplist */
+#ifndef HAVE_GETGROUPLIST
+#define getgrouplist(user, group, groups, ngroups) 0
+#endif
+
/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support
* for now */
#define REWRITE_CALLS
@@ -90,6 +95,7 @@
#define real_initgroups_dyn initgroups_dyn
*/
#define real_initgroups initgroups
+#define real_getgrouplist getgrouplist
#define real_getgrnam getgrnam
#define real_getgrnam_r getgrnam_r
@@ -1222,3 +1228,81 @@ _PUBLIC_ void nwrap_endgrent(void)
nwrap_files_endgrent();
}
+
+static int nwrap_files_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
+{
+ struct group *grp;
+ gid_t *groups_tmp;
+ int count = 1;
+ const char *name_of_group = NULL;
+
+ NWRAP_DEBUG(("%s: getgrouplist called for %s\n", __location__, user));
+
+ groups_tmp = (gid_t *)malloc(count * sizeof(gid_t));
+ if (!groups_tmp) {
+ NWRAP_ERROR(("%s:calloc failed\n",__location__));
+ errno = ENOMEM;
+ return -1;
+ }
+
+ memcpy(groups_tmp, &group, sizeof(gid_t));
+
+ grp = nwrap_getgrgid(group);
+ if (grp) {
+ name_of_group = grp->gr_name;
+ }
+
+ nwrap_files_setgrent();
+ while ((grp = nwrap_files_getgrent()) != NULL) {
+ int i = 0;
+
+ NWRAP_VERBOSE(("%s: inspecting %s for group membership\n",
+ __location__, grp->gr_name));
+
+ for (i=0; grp->gr_mem && grp->gr_mem[i] != NULL; i++) {
+
+ if ((strcmp(user, grp->gr_mem[i]) == 0) &&
+ (strcmp(name_of_group, grp->gr_name) != 0)) {
+
+ NWRAP_DEBUG(("%s: %s is member of %s\n",
+ __location__, user, grp->gr_name));
+
+ groups_tmp = (gid_t *)realloc(groups_tmp, (count + 1) * sizeof(gid_t));
+ if (!groups_tmp) {
+ NWRAP_ERROR(("%s:calloc failed\n",__location__));
+ errno = ENOMEM;
+ return -1;
+ }
+
+ memcpy(&groups_tmp[count], &grp->gr_gid, sizeof(gid_t));
+ count++;
+ }
+ }
+ }
+ nwrap_files_endgrent();
+
+ NWRAP_VERBOSE(("%s: %s is member of %d groups: %d\n",
+ __location__, user, *ngroups));
+
+ if (*ngroups < count) {
+ *ngroups = count;
+ free(groups_tmp);
+ return -1;
+ }
+
+ *ngroups = count;
+ memcpy(groups, groups_tmp, count * sizeof(gid_t));
+ free(groups_tmp);
+
+ return count;
+}
+
+_PUBLIC_ int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups)
+{
+ if (!nwrap_enabled()) {
+ return real_getgrouplist(user, group, groups, ngroups);
+ }
+
+ return nwrap_files_getgrouplist(user, group, groups, ngroups);
+}
+
diff --git a/lib/nss_wrapper/nss_wrapper.h b/lib/nss_wrapper/nss_wrapper.h
index 35a47348a8..5bcd42ead4 100644
--- a/lib/nss_wrapper/nss_wrapper.h
+++ b/lib/nss_wrapper/nss_wrapper.h
@@ -46,6 +46,7 @@ int nwrap_getpwent_r(struct passwd *pwbuf, char *buf,
size_t buflen, struct passwd **pwbufp);
void nwrap_endpwent(void);
int nwrap_initgroups(const char *user, gid_t group);
+int nwrap_getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups);
struct group *nwrap_getgrnam(const char *name);
int nwrap_getgrnam_r(const char *name, struct group *gbuf,
char *buf, size_t buflen, struct group **gbufp);
@@ -120,6 +121,11 @@ void nwrap_endgrent(void);
#endif
#define initgroups nwrap_initgroups
+#ifdef getgrouplist
+#undef getgrouplist
+#endif
+#define getgrouplist nwrap_getgrouplist
+
#ifdef getgrnam
#undef getgrnam
#endif
diff --git a/lib/nss_wrapper/testsuite.c b/lib/nss_wrapper/testsuite.c
new file mode 100644
index 0000000000..4f37354e12
--- /dev/null
+++ b/lib/nss_wrapper/testsuite.c
@@ -0,0 +1,332 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ local testing of the nss wrapper
+
+ Copyright (C) Guenther Deschner 2009
+
+ 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/>.
+*/
+
+#include "includes.h"
+#include "torture/torture.h"
+#include "lib/replace/system/passwd.h"
+#include "lib/nss_wrapper/nss_wrapper.h"
+
+static void print_passwd(struct passwd *pwd)
+{
+ printf("%s:%s:%lu:%lu:%s:%s:%s\n",
+ pwd->pw_name,
+ pwd->pw_passwd,
+ (unsigned long)pwd->pw_uid,
+ (unsigned long)pwd->pw_gid,
+ pwd->pw_gecos,
+ pwd->pw_dir,
+ pwd->pw_shell);
+}
+
+
+static bool test_nwrap_getpwnam(struct torture_context *tctx,
+ const char *name)
+{
+ struct passwd *pwd;
+
+ torture_comment(tctx, "Testing getpwnam: %s\n", name);
+
+ pwd = getpwnam(name);
+ if (pwd) {
+ print_passwd(pwd);
+ }
+
+ return pwd ? true : false;
+}
+
+static bool test_nwrap_getpwuid(struct torture_context *tctx,
+ uid_t uid)
+{
+ struct passwd *pwd;
+
+ torture_comment(tctx, "Testing getpwuid: %lu\n", (unsigned long)uid);
+
+ pwd = getpwuid(uid);
+ if (pwd) {
+ print_passwd(pwd);
+ }
+
+ return pwd ? true : false;
+}
+
+static void print_group(struct group *grp)
+{
+ int i;
+ printf("%s:%s:%lu:",
+ grp->gr_name,
+ grp->gr_passwd,
+ (unsigned long)grp->gr_gid);
+
+ if (!grp->gr_mem[0]) {
+ printf("\n");
+ return;
+ }
+
+ for (i=0; grp->gr_mem[i+1]; i++) {
+ printf("%s,", grp->gr_mem[i]);
+ }
+ printf("%s\n", grp->gr_mem[i]);
+}
+
+static bool test_nwrap_getgrnam(struct torture_context *tctx,
+ const char *name)
+{
+ struct group *grp;
+
+ torture_comment(tctx, "Testing getgrnam: %s\n", name);
+
+ grp = getgrnam(name);
+ if (grp) {
+ print_group(grp);
+ }
+
+ return grp ? true : false;
+}
+
+static bool test_nwrap_getgrgid(struct torture_context *tctx,
+ gid_t gid)
+{
+ struct group *grp;
+
+ torture_comment(tctx, "Testing getgrgid: %lu\n", (unsigned long)gid);
+
+ grp = getgrgid(gid);
+ if (grp) {
+ print_group(grp);
+ }
+
+ return grp ? true : false;
+}
+
+static bool test_nwrap_enum_passwd(struct torture_context *tctx,
+ struct passwd **pwd_array_p,
+ size_t *num_pwd_p)
+{
+ struct passwd *pwd;
+ struct passwd *pwd_array = NULL;
+ size_t num_pwd = 0;
+
+ torture_comment(tctx, "Testing setpwent\n");
+ setpwent();
+
+ while ((pwd = getpwent()) != NULL) {
+ torture_comment(tctx, "Testing getpwent\n");
+
+ print_passwd(pwd);
+ if (pwd_array_p && num_pwd_p) {
+ pwd_array = talloc_realloc(tctx, pwd_array, struct passwd, num_pwd+1);
+ torture_assert(tctx, pwd_array, "out of memory");
+ pwd_array[num_pwd].pw_name = talloc_strdup(tctx, pwd->pw_name);
+ pwd_array[num_pwd].pw_uid = pwd->pw_uid;
+ pwd_array[num_pwd].pw_gid = pwd->pw_gid;
+ num_pwd++;
+ }
+ }
+
+ torture_comment(tctx, "Testing endpwent\n");
+ endpwent();
+
+ if (pwd_array_p) {
+ *pwd_array_p = pwd_array;
+ }
+ if (num_pwd_p) {
+ *num_pwd_p = num_pwd;
+ }
+
+ return true;
+}
+
+static bool test_nwrap_passwd(struct torture_context *tctx)
+{
+ int i;
+ struct passwd *pwd;
+ size_t num_pwd;
+
+ torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd),
+ "failed to enumerate passwd");
+
+ for (i=0; i < num_pwd; i++) {
+ torture_assert(tctx, test_nwrap_getpwnam(tctx, pwd[i].pw_name),
+ "failed to call getpwnam for enumerated user");
+ torture_assert(tctx, test_nwrap_getpwuid(tctx, pwd[i].pw_uid),
+ "failed to call getpwuid for enumerated user");
+ }
+
+ return true;
+}
+
+static bool test_nwrap_enum_group(struct torture_context *tctx,
+ struct group **grp_array_p,
+ size_t *num_grp_p)
+{
+ struct group *grp;
+ struct group *grp_array = NULL;
+ size_t num_grp = 0;
+
+ torture_comment(tctx, "Testing setgrent\n");
+ setgrent();
+
+ while ((grp = getgrent()) != NULL) {
+ torture_comment(tctx, "Testing getgrent\n");
+
+ print_group(grp);
+ if (grp_array_p && num_grp_p) {
+ grp_array = talloc_realloc(tctx, grp_array, struct group, num_grp+1);
+ torture_assert(tctx, grp_array, "out of memory");
+ grp_array[num_grp].gr_name = talloc_strdup(tctx, grp->gr_name);
+ grp_array[num_grp].gr_gid = grp->gr_gid;
+ num_grp++;
+ }
+ }
+
+ torture_comment(tctx, "Testing endgrent\n");
+ endgrent();
+
+ if (grp_array_p) {
+ *grp_array_p = grp_array;
+ }
+ if (num_grp_p) {
+ *num_grp_p = num_grp;
+ }
+
+
+ return true;
+}
+
+static bool test_nwrap_group(struct torture_context *tctx)
+{
+ int i;
+ struct group *grp;
+ size_t num_grp;
+
+ torture_assert(tctx, test_nwrap_enum_group(tctx, &grp, &num_grp),
+ "failed to enumerate group");
+
+ for (i=0; i < num_grp; i++) {
+ torture_assert(tctx, test_nwrap_getgrnam(tctx, grp[i].gr_name),
+ "failed to call getgrnam for enumerated user");
+ torture_assert(tctx, test_nwrap_getgrgid(tctx, grp[i].gr_gid),
+ "failed to call getgrgid for enumerated user");
+ }
+
+ return true;
+}
+
+static bool test_nwrap_getgrouplist(struct torture_context *tctx,
+ const char *user,
+ gid_t gid,
+ gid_t **gids_p,
+ int *num_gids_p)
+{
+ int ret;
+ int num_groups = 0;
+ gid_t *groups = NULL;
+
+ torture_comment(tctx, "Testing getgrouplist: %s\n", user);
+
+ ret = getgrouplist(user, gid, NULL, &num_groups);
+ if (ret == -1 || num_groups != 0) {
+
+ groups = talloc_array(tctx, gid_t, num_groups);
+ torture_assert(tctx, groups, "out of memory\n");
+
+ ret = getgrouplist(user, gid, groups, &num_groups);
+ }
+
+ torture_assert(tctx, (ret != -1), "failed to call getgrouplist");
+
+ torture_comment(tctx, "%s is member in %d groups\n", user, num_groups);
+
+ if (gids_p) {
+ *gids_p = groups;
+ }
+ if (num_gids_p) {
+ *num_gids_p = num_groups;
+ }
+
+ return true;
+}
+
+static bool test_nwrap_membership(struct torture_context *tctx)
+{
+ const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
+ const char *old_group = getenv("NSS_WRAPPER_GROUP");
+ struct passwd *pwd;
+ size_t num_pwd;
+ int i;
+
+ if (!old_pwd || !old_group) {
+ torture_skip(tctx, "nothing to test\n");
+ return true;
+ }
+
+ torture_assert(tctx, test_nwrap_enum_passwd(tctx, &pwd, &num_pwd),
+ "failed to enumerate passwd");
+
+ for (i=0; i < num_pwd; i++) {
+
+ int num_user_groups = 0;
+ gid_t *user_groups = NULL;
+ int g;
+
+ torture_assert(tctx, test_nwrap_getgrouplist(tctx,
+ pwd[i].pw_name,
+ pwd[i].pw_gid,
+ &user_groups,
+ &num_user_groups),
+ "failed to test getgrouplist");
+
+ for (g=0; g < num_user_groups; g++) {
+ torture_assert(tctx, test_nwrap_getgrgid(tctx, user_groups[g]),
+ "failed to find the group the user is a member of");
+ }
+ }
+
+ return true;
+}
+
+static bool test_nwrap_env(struct torture_context *tctx)
+{
+ const char *old_pwd = getenv("NSS_WRAPPER_PASSWD");
+ const char *old_group = getenv("NSS_WRAPPER_GROUP");
+
+ if (!old_pwd || !old_group) {
+ torture_skip(tctx, "nothing to test\n");
+ return true;
+ }
+
+ torture_assert(tctx, test_nwrap_passwd(tctx),
+ "failed to test users");
+ torture_assert(tctx, test_nwrap_group(tctx),
+ "failed to test groups");
+
+ return true;
+}
+
+struct torture_suite *torture_local_nss_wrapper(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "NSS-WRAPPER");
+
+ torture_suite_add_simple_test(suite, "env", test_nwrap_env);
+ torture_suite_add_simple_test(suite, "membership", test_nwrap_membership);
+
+ return suite;
+}
diff --git a/lib/replace/system/config.m4 b/lib/replace/system/config.m4
index 5c9b53d5c5..e2196586ad 100644
--- a/lib/replace/system/config.m4
+++ b/lib/replace/system/config.m4
@@ -116,6 +116,7 @@ AC_VERIFY_C_PROTOTYPE([struct group *getgrent_r(struct group *src, char *buf, si
#include <unistd.h>
#include <grp.h>
])
+AC_CHECK_FUNCS(getgrouplist)
# locale
AC_CHECK_HEADERS(ctype.h locale.h)
diff --git a/lib/util/config.mk b/lib/util/config.mk
index 1b620d1464..3ae8a22780 100644
--- a/lib/util/config.mk
+++ b/lib/util/config.mk
@@ -28,7 +28,8 @@ LIBSAMBA-UTIL_OBJ_FILES = $(addprefix $(libutilsrcdir)/, \
rbtree.o \
talloc_stack.o \
smb_threads.o \
- params.o)
+ params.o \
+ util_id.o)
PUBLIC_HEADERS += $(addprefix $(libutilsrcdir)/, util.h \
dlinklist.h \
diff --git a/lib/util/tevent_unix.c b/lib/util/tevent_unix.c
index b89d5cd4d4..0a8c4c6b30 100644
--- a/lib/util/tevent_unix.c
+++ b/lib/util/tevent_unix.c
@@ -3,17 +3,21 @@
Wrap unix errno around tevent_req
Copyright (C) Volker Lendecke 2009
- 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.
+ ** NOTE! The following LGPL license applies to the tevent_unix
+ ** helper library. This does NOT imply that all of Samba is released
+ ** under the LGPL
- This program is distributed in the hope that it will be useful,
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
diff --git a/lib/util/tevent_unix.h b/lib/util/tevent_unix.h
index dc3ffaef33..bc2cea9199 100644
--- a/lib/util/tevent_unix.h
+++ b/lib/util/tevent_unix.h
@@ -3,17 +3,21 @@
Wrap unix errno around tevent_req
Copyright (C) Volker Lendecke 2009
- 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.
+ ** NOTE! The following LGPL license applies to the tevent_unix
+ ** helper library. This does NOT imply that all of Samba is released
+ ** under the LGPL
- This program is distributed in the hope that it will be useful,
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
diff --git a/lib/util/util.h b/lib/util/util.h
index dab5ff9360..20050d2f0a 100644
--- a/lib/util/util.h
+++ b/lib/util/util.h
@@ -817,4 +817,16 @@ bool unmap_file(void *start, size_t size);
void print_asc(int level, const uint8_t *buf,int len);
+/**
+ * Add an id to an array of ids.
+ *
+ * num should be a pointer to an integer that holds the current
+ * number of elements in ids. It will be updated by this function.
+ */
+
+bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, uid_t uid,
+ uid_t **uids, size_t *num_uids);
+bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
+ gid_t **gids, size_t *num_gids);
+
#endif /* _SAMBA_UTIL_H_ */
diff --git a/lib/util/util_id.c b/lib/util/util_id.c
new file mode 100644
index 0000000000..8744ce4e4e
--- /dev/null
+++ b/lib/util/util_id.c
@@ -0,0 +1,88 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Helper routines for uid and gid arrays
+
+ Copyright (C) Guenther Deschner 2009
+
+ 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/>.
+*/
+
+#include "includes.h"
+
+/****************************************************************************
+ Add a gid to an array of gids if it's not already there.
+****************************************************************************/
+
+bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
+ gid_t **gids, size_t *num_gids)
+{
+ int i;
+
+ if ((*num_gids != 0) && (*gids == NULL)) {
+ /*
+ * A former call to this routine has failed to allocate memory
+ */
+ return false;
+ }
+
+ for (i=0; i<*num_gids; i++) {
+ if ((*gids)[i] == gid) {
+ return true;
+ }
+ }
+
+ *gids = talloc_realloc(mem_ctx, *gids, gid_t, *num_gids+1);
+ if (*gids == NULL) {
+ *num_gids = 0;
+ return false;
+ }
+
+ (*gids)[*num_gids] = gid;
+ *num_gids += 1;
+ return true;
+}
+
+/****************************************************************************
+ Add a uid to an array of uids if it's not already there.
+****************************************************************************/
+
+bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx, uid_t uid,
+ uid_t **uids, size_t *num_uids)
+{
+ int i;
+
+ if ((*num_uids != 0) && (*uids == NULL)) {
+ /*
+ * A former call to this routine has failed to allocate memory
+ */
+ return false;
+ }
+
+ for (i=0; i<*num_uids; i++) {
+ if ((*uids)[i] == uid) {
+ return true;
+ }
+ }
+
+ *uids = talloc_realloc(mem_ctx, *uids, uid_t, *num_uids+1);
+ if (*uids == NULL) {
+ *num_uids = 0;
+ return false;
+ }
+
+ (*uids)[*num_uids] = uid;
+ *num_uids += 1;
+ return true;
+}
diff --git a/librpc/gen_ndr/security.h b/librpc/gen_ndr/security.h
index 16635f0bb8..d1dcbe552a 100644
--- a/librpc/gen_ndr/security.h
+++ b/librpc/gen_ndr/security.h
@@ -121,17 +121,21 @@
#define SID_BUILTIN_REPLICATOR ( "S-1-5-32-552" )
#define SID_BUILTIN_RAS_SERVERS ( "S-1-5-32-553" )
#define SID_BUILTIN_PREW2K ( "S-1-5-32-554" )
+#define SID_BUILTIN_REMOTE_DESKTOP_USERS ( "S-1-5-32-555" )
+#define SID_BUILTIN_NETWORK_CONF_OPERATORS ( "S-1-5-32-556" )
#define DOMAIN_RID_LOGON ( 9 )
#define DOMAIN_RID_ADMINISTRATOR ( 500 )
#define DOMAIN_RID_GUEST ( 501 )
+#define DOMAIN_RID_KRBTGT ( 502 )
#define DOMAIN_RID_ADMINS ( 512 )
#define DOMAIN_RID_USERS ( 513 )
-#define DOMAIN_RID_KRBTGT ( 514 )
+#define DOMAIN_RID_GUESTS ( 514 )
#define DOMAIN_RID_DOMAIN_MEMBERS ( 515 )
#define DOMAIN_RID_DCS ( 516 )
#define DOMAIN_RID_CERT_ADMINS ( 517 )
#define DOMAIN_RID_SCHEMA_ADMINS ( 518 )
#define DOMAIN_RID_ENTERPRISE_ADMINS ( 519 )
+#define DOMAIN_RID_POLICY_ADMINS ( 520 )
#define NT4_ACL_REVISION ( SECURITY_ACL_REVISION_NT4 )
#define SD_REVISION ( SECURITY_DESCRIPTOR_REVISION_1 )
struct dom_sid {
diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl
index 9e47ff45fc..9728c7fb07 100644
--- a/librpc/idl/security.idl
+++ b/librpc/idl/security.idl
@@ -219,19 +219,23 @@ interface security
const string SID_BUILTIN_REPLICATOR = "S-1-5-32-552";
const string SID_BUILTIN_RAS_SERVERS = "S-1-5-32-553";
const string SID_BUILTIN_PREW2K = "S-1-5-32-554";
+ const string SID_BUILTIN_REMOTE_DESKTOP_USERS = "S-1-5-32-555";
+ const string SID_BUILTIN_NETWORK_CONF_OPERATORS = "S-1-5-32-556";
/* well-known domain RIDs */
const int DOMAIN_RID_LOGON = 9;
const int DOMAIN_RID_ADMINISTRATOR = 500;
const int DOMAIN_RID_GUEST = 501;
+ const int DOMAIN_RID_KRBTGT = 502;
const int DOMAIN_RID_ADMINS = 512;
const int DOMAIN_RID_USERS = 513;
- const int DOMAIN_RID_KRBTGT = 514;
+ const int DOMAIN_RID_GUESTS = 514;
const int DOMAIN_RID_DOMAIN_MEMBERS = 515;
const int DOMAIN_RID_DCS = 516;
const int DOMAIN_RID_CERT_ADMINS = 517;
const int DOMAIN_RID_SCHEMA_ADMINS = 518;
const int DOMAIN_RID_ENTERPRISE_ADMINS = 519;
+ const int DOMAIN_RID_POLICY_ADMINS = 520;
/*
diff --git a/nsswitch/config.mk b/nsswitch/config.mk
index 3a4f054d1f..264032e530 100644
--- a/nsswitch/config.mk
+++ b/nsswitch/config.mk
@@ -26,7 +26,11 @@ PRIVATE_DEPENDENCIES = \
LIBCLI_AUTH \
LIBPOPT \
POPT_SAMBA \
- LIBWINBIND-CLIENT
+ LIBWINBIND-CLIENT \
+ LIBWBCLIENT \
+ LIBTEVENT \
+ UTIL_TEVENT \
+ LIBASYNC_REQ
# End BINARY nsstest
#################################
diff --git a/nsswitch/libwbclient/config.mk b/nsswitch/libwbclient/config.mk
new file mode 100644
index 0000000000..ffdab159f8
--- /dev/null
+++ b/nsswitch/libwbclient/config.mk
@@ -0,0 +1,15 @@
+[SUBSYSTEM::LIBWBCLIENT]
+PUBLIC_DEPENDENCIES = LIBASYNC_REQ \
+ LIBTEVENT \
+ LIBTALLOC \
+ UTIL_TEVENT
+
+LIBWBCLIENT_OBJ_FILES = $(addprefix $(libwbclientsrcdir)/, wbc_async.o \
+ wbc_guid.o \
+ wbc_idmap.o \
+ wbclient.o \
+ wbc_pam.o \
+ wbc_pwd.o \
+ wbc_sid.o \
+ wbc_util.o \
+ wb_reqtrans.o )
diff --git a/nsswitch/libwbclient/libwbclient.h b/nsswitch/libwbclient/libwbclient.h
index 74cba7e796..5a25cf462c 100644
--- a/nsswitch/libwbclient/libwbclient.h
+++ b/nsswitch/libwbclient/libwbclient.h
@@ -36,6 +36,7 @@
/* Public headers */
#include "wbclient.h"
+#include "wbc_async.h"
/* Private headers */
diff --git a/source3/lib/wb_reqtrans.c b/nsswitch/libwbclient/wb_reqtrans.c
index 55883ba8c7..84ed7198f2 100644
--- a/source3/lib/wb_reqtrans.c
+++ b/nsswitch/libwbclient/wb_reqtrans.c
@@ -5,25 +5,41 @@
Copyright (C) Volker Lendecke 2008
- 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.
+ ** NOTE! The following LGPL license applies to the wbclient
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
- This program is distributed in the hope that it will be useful,
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
-#include "wbc_async.h"
-
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/network.h"
+#include <talloc.h>
+#include <tevent.h>
+struct fd_event;
+struct event_context;
+#include "lib/async_req/async_sock.h"
+#include "lib/util/tevent_unix.h"
+#include "nsswitch/winbind_struct_protocol.h"
+#include "nsswitch/libwbclient/wbclient.h"
+#include "nsswitch/libwbclient/wbc_async.h"
+
+#ifdef DBGC_CLASS
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
+#endif
struct req_read_state {
struct winbindd_request *wb_req;
diff --git a/source3/lib/wbclient.c b/nsswitch/libwbclient/wbc_async.c
index 164cfc9691..5f985f9d5a 100644
--- a/source3/lib/wbclient.c
+++ b/nsswitch/libwbclient/wbc_async.c
@@ -3,22 +3,35 @@
Infrastructure for async winbind requests
Copyright (C) Volker Lendecke 2008
- 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.
+ ** NOTE! The following LGPL license applies to the wbclient
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
- This program is distributed in the hope that it will be useful,
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "includes.h"
-#include "wbc_async.h"
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/network.h"
+#include <talloc.h>
+#include <tevent.h>
+struct fd_event;
+struct event_context;
+#include "lib/async_req/async_sock.h"
+#include "nsswitch/winbind_struct_protocol.h"
+#include "nsswitch/libwbclient/wbclient.h"
+#include "nsswitch/libwbclient/wbc_async.h"
wbcErr map_wbc_err_from_errno(int error)
{
@@ -75,6 +88,7 @@ struct wb_context {
struct tevent_queue *queue;
int fd;
bool is_priv;
+ const char *dir;
};
static int make_nonstd_fd(int fd)
@@ -166,7 +180,10 @@ static int make_safe_fd(int fd)
return -1;
}
-struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
+/* Just put a prototype to avoid moving the whole function around */
+static const char *winbindd_socket_dir(void);
+
+struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx, const char* dir)
{
struct wb_context *result;
@@ -181,6 +198,16 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
}
result->fd = -1;
result->is_priv = false;
+
+ if (dir != NULL) {
+ result->dir = talloc_strdup(result, dir);
+ } else {
+ result->dir = winbindd_socket_dir();
+ }
+ if (result->dir == NULL) {
+ TALLOC_FREE(result);
+ return NULL;
+ }
return result;
}
@@ -338,7 +365,7 @@ static struct tevent_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
wb_ctx->fd = -1;
}
- subreq = wb_connect_send(state, ev, wb_ctx, winbindd_socket_dir());
+ subreq = wb_connect_send(state, ev, wb_ctx, wb_ctx->dir);
if (subreq == NULL) {
goto fail;
}
diff --git a/source3/include/wbc_async.h b/nsswitch/libwbclient/wbc_async.h
index 57625d5baf..607dd9de28 100644
--- a/source3/include/wbc_async.h
+++ b/nsswitch/libwbclient/wbc_async.h
@@ -1,28 +1,36 @@
/*
Unix SMB/CIFS implementation.
Headers for the async winbind client library
- Copyright (C) Kai Blin 2009
+ Copyright (C) Volker Lendecke 2008
- 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.
+ ** NOTE! The following LGPL license applies to the wbclient
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
- This program is distributed in the hope that it will be useful,
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _WBC_ASYNC_H_
#define _WBC_ASYNC_H_
+#include <talloc.h>
+#include <tevent.h>
#include "nsswitch/libwbclient/wbclient.h"
struct wb_context;
+struct winbindd_request;
+struct winbindd_response;
struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -30,7 +38,7 @@ struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
struct winbindd_request *wb_req);
wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct winbindd_response **presponse);
-struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx);
+struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx, const char* dir);
/* Definitions from wb_reqtrans.c */
wbcErr map_wbc_err_from_errno(int error);
diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c
index 61ce2a12d2..eeb798a78c 100644
--- a/nsswitch/libwbclient/wbc_pam.c
+++ b/nsswitch/libwbclient/wbc_pam.c
@@ -255,7 +255,7 @@ done:
}
static wbcErr wbc_create_logon_info(TALLOC_CTX *mem_ctx,
- const struct winbindd_response *resp,
+ struct winbindd_response *resp,
struct wbcLogonUserInfo **_i)
{
wbcErr wbc_status = WBC_ERR_SUCCESS;
diff --git a/nsswitch/libwbclient/wbclient.c b/nsswitch/libwbclient/wbclient.c
index f5c72315f2..77b7e12d04 100644
--- a/nsswitch/libwbclient/wbclient.c
+++ b/nsswitch/libwbclient/wbclient.c
@@ -22,6 +22,8 @@
/* Required Headers */
+#include "lib/talloc/talloc.h"
+#include "lib/tevent/tevent.h"
#include "libwbclient.h"
/* From wb_common.c */
diff --git a/nsswitch/libwbclient/wbclient_internal.h b/nsswitch/libwbclient/wbclient_internal.h
index fc03c5409b..2d103ab3df 100644
--- a/nsswitch/libwbclient/wbclient_internal.h
+++ b/nsswitch/libwbclient/wbclient_internal.h
@@ -28,5 +28,4 @@ wbcErr wbcRequestResponse(int cmd,
struct winbindd_request *request,
struct winbindd_response *response);
-
#endif /* _WBCLIENT_INTERNAL_H */
diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h
index 11b2069c3a..1785c30906 100644
--- a/nsswitch/winbind_struct_protocol.h
+++ b/nsswitch/winbind_struct_protocol.h
@@ -15,6 +15,11 @@
#define SAFE_FREE(x) do { if(x) {free(x); x=NULL;} } while(0)
#endif
+#ifndef FSTRING_LEN
+#define FSTRING_LEN 256
+typedef char fstring[FSTRING_LEN];
+#endif
+
#ifndef _WINBINDD_NTDOM_H
#define _WINBINDD_NTDOM_H
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 95d2a8253f..4723fd6909 100644
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -542,6 +542,7 @@ $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false
open(GROUP, ">$nss_wrapper_group") or die("Unable to open $nss_wrapper_group");
print GROUP "nobody:x:65533:
nogroup:x:65534:nobody
+root:x:65532:
$unix_name-group:x:$unix_gids[0]:
";
close(GROUP);
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 2b30b4a5bd..9c87c6776a 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -355,7 +355,7 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \
../lib/util/genrand.o ../lib/util/util_net.o \
../lib/util/become_daemon.o ../lib/util/system.o \
../lib/util/tevent_unix.o ../lib/util/tevent_ntstatus.o \
- ../lib/util/smb_threads.o
+ ../lib/util/smb_threads.o ../lib/util/util_id.o
CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \
../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \
@@ -372,6 +372,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \
lib/interface.o lib/pidfile.o \
lib/system.o lib/sendfile.o lib/recvfile.o lib/time.o \
lib/username.o \
+ lib/ads_flags.o \
lib/util_pw.o lib/access.o lib/smbrun.o \
lib/bitmap.o lib/dprintf.o $(UTIL_REG_OBJ) \
lib/wins_srv.o \
@@ -992,7 +993,7 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta
SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \
$(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
- lib/wb_reqtrans.o lib/wbclient.o \
+ @LIBWBCLIENT_STATIC@ \
$(LIBNDR_GEN_OBJ0)
MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \
@@ -1186,7 +1187,7 @@ TDBTOOL_OBJ = @tdbdir@/tools/tdbtool.o $(LIBREPLACE_OBJ) \
TDBDUMP_OBJ = @tdbdir@/tools/tdbdump.o $(LIBREPLACE_OBJ) \
$(SOCKET_WRAPPER_OBJ)
-TDBTORTURE_OBJ = @tdbdir@/tools/tdbtorture.o $(LIBREPLACE_OBJ) \
+TDBTORTURE_OBJ = @tdbdir@/tools/tdbtorture.o $(LIBTDB_OBJ) \
$(SOCKET_WRAPPER_OBJ)
@@ -1876,7 +1877,10 @@ LIBWBCLIENT_OBJ0 = ../nsswitch/libwbclient/wbclient.o \
../nsswitch/libwbclient/wbc_idmap.o \
../nsswitch/libwbclient/wbc_sid.o \
../nsswitch/libwbclient/wbc_guid.o \
- ../nsswitch/libwbclient/wbc_pam.o
+ ../nsswitch/libwbclient/wbc_pam.o \
+ ../nsswitch/libwbclient/wb_reqtrans.o \
+ ../nsswitch/libwbclient/wbc_async.o
+
LIBWBCLIENT_OBJ = $(LIBWBCLIENT_OBJ0) \
$(WBCOMMON_OBJ) \
$(LIBREPLACE_OBJ)
@@ -1887,7 +1891,8 @@ LIBWBCLIENT_SHARED_TARGET_SONAME=$(LIBWBCLIENT_SHARED_TARGET).$(LIBWBCLIENT_SOVE
LIBWBCLIENT_STATIC_TARGET=@LIBWBCLIENT_STATIC_TARGET@
LIBWBCLIENT=@LIBWBCLIENT_STATIC@ @LIBWBCLIENT_SHARED@
LIBWBCLIENT_SYMS=$(srcdir)/exports/libwbclient.@SYMSEXT@
-LIBWBCLIENT_HEADERS=$(srcdir)/../nsswitch/libwbclient/wbclient.h
+LIBWBCLIENT_HEADERS=$(srcdir)/../nsswitch/libwbclient/wbclient.h \
+ $(srcdir)/../nsswitch/libwbclient/wbc_async.h
$(LIBWBCLIENT_SYMS): $(LIBWBCLIENT_HEADERS)
@$(MKSYMS_SH) $(AWK) $@ $(LIBWBCLIENT_HEADERS)
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index a27025fc8d..9d29987c0d 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -208,21 +208,15 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
client_domain, smb_name, wksta_name));
- /* don't allow "" as a domain, fixes a Win9X bug
- where it doens't supply a domain for logon script
- 'net use' commands. */
-
- if ( *client_domain )
- domain = client_domain;
- else
- domain = lp_workgroup();
+ domain = client_domain;
/* If you connect to a Windows domain member using a bogus domain name,
* the Windows box will map the BOGUS\user to SAMNAME\user. Thus, if
* the Windows box is a DC the name will become DOMAIN\user and be
* authenticated against AD, if the Windows box is a member server but
* not a DC the name will become WORKSTATION\user. A standalone
- * non-domain member box will also map to WORKSTATION\user. */
+ * non-domain member box will also map to WORKSTATION\user.
+ * This also deals with the client passing in a "" domain */
if (!is_trusted_domain(domain) &&
!strequal(domain, get_global_sam_name()) )
diff --git a/source3/client/client.c b/source3/client/client.c
index 2edeb1ae2b..0852652725 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -2872,7 +2872,7 @@ static int cmd_chmod(void)
return 1;
}
- if (!cli_unix_chmod(targetcli, targetname, mode)) {
+ if (!NT_STATUS_IS_OK(cli_posix_chmod(targetcli, targetname, mode))) {
d_printf("%s chmod file %s 0%o\n",
cli_errstr(targetcli), src, (unsigned int)mode);
return 1;
@@ -3037,23 +3037,22 @@ static int cmd_getfacl(void)
return 1;
}
- if (!cli_unix_stat(targetcli, targetname, &sbuf)) {
+ if (!NT_STATUS_IS_OK(cli_posix_stat(targetcli, targetname, &sbuf))) {
d_printf("%s getfacl doing a stat on file %s\n",
cli_errstr(targetcli), src);
return 1;
}
- if (!cli_unix_getfacl(targetcli, targetname, &rb_size, &retbuf)) {
+ if (!NT_STATUS_IS_OK(cli_posix_getfacl(targetcli, targetname, ctx, &rb_size, &retbuf))) {
d_printf("%s getfacl file %s\n",
cli_errstr(targetcli), src);
return 1;
}
/* ToDo : Print out the ACL values. */
- if (SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION || rb_size < 6) {
+ if (rb_size < 6 || SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION) {
d_printf("getfacl file %s, unknown POSIX acl version %u.\n",
src, (unsigned int)CVAL(retbuf,0) );
- SAFE_FREE(retbuf);
return 1;
}
@@ -3064,8 +3063,6 @@ static int cmd_getfacl(void)
src,
(unsigned int)(SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)),
(unsigned int)rb_size);
-
- SAFE_FREE(retbuf);
return 1;
}
@@ -3150,7 +3147,6 @@ static int cmd_getfacl(void)
d_printf("%s\n", perms_to_string(permstring, perms));
}
- SAFE_FREE(retbuf);
return 0;
}
@@ -3192,7 +3188,7 @@ static int cmd_stat(void)
return 1;
}
- if (!cli_unix_stat(targetcli, targetname, &sbuf)) {
+ if (!NT_STATUS_IS_OK(cli_posix_stat(targetcli, targetname, &sbuf))) {
d_printf("%s stat file %s\n",
cli_errstr(targetcli), src);
return 1;
@@ -3296,7 +3292,7 @@ static int cmd_chown(void)
return 1;
}
- if (!cli_unix_chown(targetcli, targetname, uid, gid)) {
+ if (!NT_STATUS_IS_OK(cli_posix_chown(targetcli, targetname, uid, gid))) {
d_printf("%s chown file %s uid=%d, gid=%d\n",
cli_errstr(targetcli), src, (int)uid, (int)gid);
return 1;
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 2217b3315b..81d254f1ff 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1088,8 +1088,6 @@ struct user_auth_info *get_cmdline_auth_info_copy(TALLOC_CTX *mem_ctx,
const struct user_auth_info *info);
bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_info);
void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info);
-bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
- gid_t **gids, size_t *num_gids);
bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf);
bool socket_exist(const char *fname);
bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st);
@@ -2361,10 +2359,46 @@ NTSTATUS cli_posix_hardlink(struct cli_state *cli,
const char *newname);
uint32_t unix_perms_to_wire(mode_t perms);
mode_t wire_perms_to_unix(uint32_t perms);
-bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf);
-bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf);
-bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode);
-bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid);
+struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname);
+NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ size_t *prb_size,
+ char **retbuf);
+NTSTATUS cli_posix_getfacl(struct cli_state *cli,
+ const char *fname,
+ TALLOC_CTX *mem_ctx,
+ size_t *prb_size,
+ char **retbuf);
+struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname);
+NTSTATUS cli_posix_stat_recv(struct tevent_req *req,
+ SMB_STRUCT_STAT *sbuf);
+NTSTATUS cli_posix_stat(struct cli_state *cli,
+ const char *fname,
+ SMB_STRUCT_STAT *sbuf);
+struct tevent_req *cli_posix_chmod_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ mode_t mode);
+NTSTATUS cli_posix_chmod_recv(struct tevent_req *req);
+NTSTATUS cli_posix_chmod(struct cli_state *cli, const char *fname, mode_t mode);
+struct tevent_req *cli_posix_chown_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ uid_t uid,
+ gid_t gid);
+NTSTATUS cli_posix_chown_recv(struct tevent_req *req);
+NTSTATUS cli_posix_chown(struct cli_state *cli,
+ const char *fname,
+ uid_t uid,
+ gid_t gid);
struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
struct cli_state *cli,
@@ -2408,7 +2442,13 @@ struct tevent_req *cli_rmdir_send(TALLOC_CTX *mem_ctx,
const char *dname);
NTSTATUS cli_rmdir_recv(struct tevent_req *req);
NTSTATUS cli_rmdir(struct cli_state *cli, const char *dname);
-int cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag);
+struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ bool flag);
+NTSTATUS cli_nt_delete_on_close_recv(struct tevent_req *req);
+NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag);
struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
struct cli_state *cli,
@@ -2967,6 +3007,7 @@ NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode);
void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode);
NTSTATUS werror_to_ntstatus(WERROR error);
WERROR ntstatus_to_werror(NTSTATUS error);
+NTSTATUS map_nt_error_from_wbcErr(wbcErr wbc_err);
NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor);
/* The following definitions come from libsmb/namecache.c */
@@ -4278,7 +4319,7 @@ enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp);
void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val);
int lp_min_receive_file_size(void);
char* lp_perfcount_module(void);
-
+void lp_set_passdb_backend(const char *backend);
/* The following definitions come from param/util.c */
diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h
index c28d43d53b..8710e77f3d 100644
--- a/source3/include/smbldap.h
+++ b/source3/include/smbldap.h
@@ -2,20 +2,20 @@
Unix SMB/CIFS mplementation.
LDAP protocol helper functions for SAMBA
Copyright (C) Gerald Carter 2001-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/>.
-
+
*/
#ifndef _SMBLDAP_H
@@ -214,6 +214,9 @@ 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_talloc_single_blob(TALLOC_CTX *mem_ctx, LDAP *ld,
+ LDAPMessage *msg, const char *attrib,
+ DATA_BLOB *blob);
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);
diff --git a/source3/lib/ads_flags.c b/source3/lib/ads_flags.c
new file mode 100644
index 0000000000..a8fa062f2a
--- /dev/null
+++ b/source3/lib/ads_flags.c
@@ -0,0 +1,150 @@
+/*
+ Unix SMB/CIFS implementation.
+ ads (active directory) utility library
+
+ Copyright (C) Stefan (metze) Metzmacher 2002
+ Copyright (C) Andrew Tridgell 2001
+
+ 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/>.
+*/
+
+#include "includes.h"
+
+/*
+translated the ACB_CTRL Flags to UserFlags (userAccountControl)
+*/
+uint32 ads_acb2uf(uint32 acb)
+{
+ uint32 uf = 0x00000000;
+
+ if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE;
+ if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED;
+ if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD;
+ if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT;
+ if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT;
+ if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT;
+ if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT;
+ if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT;
+ if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT;
+ if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD;
+ if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT;
+ if (acb & ACB_USE_DES_KEY_ONLY) uf |= UF_USE_DES_KEY_ONLY;
+ if (acb & ACB_SMARTCARD_REQUIRED) uf |= UF_SMARTCARD_REQUIRED;
+ if (acb & ACB_TRUSTED_FOR_DELEGATION) uf |= UF_TRUSTED_FOR_DELEGATION;
+ if (acb & ACB_DONT_REQUIRE_PREAUTH) uf |= UF_DONT_REQUIRE_PREAUTH;
+ if (acb & ACB_NO_AUTH_DATA_REQD) uf |= UF_NO_AUTH_DATA_REQUIRED;
+ if (acb & ACB_NOT_DELEGATED) uf |= UF_NOT_DELEGATED;
+ if (acb & ACB_ENC_TXT_PWD_ALLOWED) uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
+
+ return uf;
+}
+
+/*
+translated the UserFlags (userAccountControl) to ACB_CTRL Flags
+*/
+uint32 ads_uf2acb(uint32 uf)
+{
+ uint32 acb = 0x00000000;
+
+ if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED;
+ if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ;
+ if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ;
+ if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS;
+ if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP;
+ if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK;
+ if (uf & UF_USE_DES_KEY_ONLY) acb |= ACB_USE_DES_KEY_ONLY;
+ if (uf & UF_SMARTCARD_REQUIRED) acb |= ACB_SMARTCARD_REQUIRED;
+ if (uf & UF_TRUSTED_FOR_DELEGATION) acb |= ACB_TRUSTED_FOR_DELEGATION;
+ if (uf & UF_DONT_REQUIRE_PREAUTH) acb |= ACB_DONT_REQUIRE_PREAUTH;
+ if (uf & UF_NO_AUTH_DATA_REQUIRED) acb |= ACB_NO_AUTH_DATA_REQD;
+ if (uf & UF_NOT_DELEGATED) acb |= ACB_NOT_DELEGATED;
+ if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED;
+
+ switch (uf & UF_ACCOUNT_TYPE_MASK)
+ {
+ case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break;
+ case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break;
+ case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break;
+ case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break;
+ case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break;
+ /*Fix Me: what should we do here? */
+ default: acb |= ACB_NORMAL;break;
+ }
+
+ return acb;
+}
+
+/*
+get the accountType from the UserFlags
+*/
+uint32 ads_uf2atype(uint32 uf)
+{
+ uint32 atype = 0x00000000;
+
+ if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
+ else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
+ else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
+ else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
+ else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST;
+
+ return atype;
+}
+
+/*
+get the accountType from the groupType
+*/
+uint32 ads_gtype2atype(uint32 gtype)
+{
+ uint32 atype = 0x00000000;
+
+ switch(gtype) {
+ case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
+ atype = ATYPE_SECURITY_LOCAL_GROUP;
+ break;
+ case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
+ atype = ATYPE_SECURITY_LOCAL_GROUP;
+ break;
+ case GTYPE_SECURITY_GLOBAL_GROUP:
+ atype = ATYPE_SECURITY_GLOBAL_GROUP;
+ break;
+
+ case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
+ atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP;
+ break;
+ case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
+ atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP;
+ break;
+ case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
+ atype = ATYPE_DISTRIBUTION_LOCAL_GROUP;
+ break;
+ }
+
+ return atype;
+}
+
+/* turn a sAMAccountType into a SID_NAME_USE */
+enum lsa_SidType ads_atype_map(uint32 atype)
+{
+ switch (atype & 0xF0000000) {
+ case ATYPE_GLOBAL_GROUP:
+ return SID_NAME_DOM_GRP;
+ case ATYPE_SECURITY_LOCAL_GROUP:
+ return SID_NAME_ALIAS;
+ case ATYPE_ACCOUNT:
+ return SID_NAME_USER;
+ default:
+ DEBUG(1,("hmm, need to map account type 0x%x\n", atype));
+ }
+ return SID_NAME_UNKNOWN;
+}
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index b6921c329c..4833b96c5f 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -6,20 +6,20 @@
Copyright (C) Shahms King 2001
Copyright (C) Andrew Bartlett 2002-2003
Copyright (C) Stefan (metze) Metzmacher 2002-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/>.
-
+
*/
#include "includes.h"
@@ -217,13 +217,13 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
{
int i = 0;
-
+
while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
if ( table[i].attrib == key )
return table[i].name;
i++;
}
-
+
return NULL;
}
@@ -236,7 +236,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
{
const char **names;
int i = 0;
-
+
while ( table[i].attrib != LDAP_ATTR_LIST_END )
i++;
i++;
@@ -253,7 +253,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
i++;
}
names[i] = NULL;
-
+
return names;
}
@@ -266,25 +266,25 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
int max_len)
{
char **values;
-
+
if ( !attribute )
return False;
-
+
value[0] = '\0';
if ((values = ldap_get_values (ldap_struct, entry, attribute)) == NULL) {
DEBUG (10, ("smbldap_get_single_attribute: [%s] = [<does not exist>]\n", attribute));
-
+
return False;
}
-
+
if (convert_string(CH_UTF8, CH_UNIX,values[0], -1, value, max_len, False) == (size_t)-1) {
DEBUG(1, ("smbldap_get_single_attribute: string conversion of [%s] = [%s] failed!\n",
attribute, values[0]));
ldap_value_free(values);
return False;
}
-
+
ldap_value_free(values);
#ifdef DEBUG_PASSWORDS
DEBUG (100, ("smbldap_get_single_attribute: [%s] = [%s]\n", attribute, value));
@@ -389,23 +389,42 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
return result;
}
- bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib,
- struct dom_sid *sid)
+ bool smbldap_talloc_single_blob(TALLOC_CTX *mem_ctx, LDAP *ld,
+ LDAPMessage *msg, const char *attrib,
+ DATA_BLOB *blob)
{
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);
+ if (ldap_count_values_len(values) != 1) {
+ DEBUG(10, ("Expected one value for %s, got %d\n", attrib,
+ ldap_count_values_len(values)));
+ return false;
}
+ *blob = data_blob_talloc(mem_ctx, values[0]->bv_val,
+ values[0]->bv_len);
ldap_value_free_len(values);
+
+ return (blob->data != NULL);
+}
+
+ bool smbldap_pull_sid(LDAP *ld, LDAPMessage *msg, const char *attrib,
+ struct dom_sid *sid)
+{
+ DATA_BLOB blob;
+ bool ret;
+
+ if (!smbldap_talloc_single_blob(talloc_tos(), ld, msg, attrib,
+ &blob)) {
+ return false;
+ }
+ ret = sid_parse((char *)blob.data, blob.length, sid);
+ TALLOC_FREE(blob.data);
return ret;
}
@@ -514,7 +533,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
for (; mods[i]->mod_values[j] != NULL; j++);
}
mods[i]->mod_values = SMB_REALLOC_ARRAY(mods[i]->mod_values, char *, j + 2);
-
+
if (mods[i]->mod_values == NULL) {
smb_panic("smbldap_set_mod: out of memory!");
/* notreached. */
@@ -524,8 +543,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
smb_panic("smbldap_set_mod: String conversion failure!");
/* notreached. */
}
-
-
+
mods[i]->mod_values[j] = SMB_STRDUP(utf8_value);
TALLOC_FREE(utf8_value);
SMB_ASSERT(mods[i]->mod_values[j] != NULL);
@@ -561,9 +579,9 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
}
/* all of our string attributes are case insensitive */
-
+
if (existed && newval && (StrCaseCmp(oldval, newval) == 0)) {
-
+
/* Believe it or not, but LDAP will deny a delete and
an add at the same time if the values are the
same... */
@@ -582,7 +600,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
/* This will also allow modifying single valued attributes
* in Novell NDS. In NDS you have to first remove attribute and then
* you could add new value */
-
+
DEBUG(10,("smbldap_make_mod: deleting attribute |%s| values |%s|\n", attribute, oldval));
smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, oldval);
}
@@ -640,7 +658,7 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
{
struct smbldap_state *tmp_ldap_state;
struct smbldap_state_lookup *t;
-
+
if ((tmp_ldap_state = smbldap_find_state(ld))) {
SMB_ASSERT(tmp_ldap_state == smbldap_state);
return;
@@ -648,7 +666,7 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
t = SMB_XMALLOC_P(struct smbldap_state_lookup);
ZERO_STRUCTP(t);
-
+
DLIST_ADD_END(smbldap_state_lookup_list, t, struct smbldap_state_lookup *);
t->ld = ld;
t->smbldap_state = smbldap_state;
@@ -663,11 +681,11 @@ int smb_ldap_start_tls(LDAP *ldap_struct, int version)
#ifdef LDAP_OPT_X_TLS
int rc;
#endif
-
+
if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {
return LDAP_SUCCESS;
}
-
+
#ifdef LDAP_OPT_X_TLS
if (version != LDAP_VERSION3) {
DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
@@ -697,9 +715,9 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
int rc;
DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri));
-
+
#ifdef HAVE_LDAP_INITIALIZE
-
+
rc = ldap_initialize(ldap_struct, uri);
if (rc) {
DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
@@ -721,9 +739,9 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
if ( strnequal( uri, "URL:", 4 ) ) {
uri += 4;
}
-
+
sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port);
-
+
if (port == 0) {
if (strequal(protocol, "ldap")) {
port = LDAP_PORT;
@@ -733,12 +751,12 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
}
}
-
+
if ((*ldap_struct = ldap_init(host, port)) == NULL) {
DEBUG(0, ("ldap_init failed !\n"));
return LDAP_OPERATIONS_ERROR;
}
-
+
if (strequal(protocol, "ldaps")) {
#ifdef LDAP_OPT_X_TLS
int tls = LDAP_OPT_X_TLS_HARD;
@@ -746,7 +764,7 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
{
DEBUG(0, ("Failed to setup a TLS session\n"));
}
-
+
DEBUG(3,("LDAPS option set...!\n"));
#else
DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
@@ -792,7 +810,7 @@ int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version)
{
int version;
int rc;
-
+
/* assume the worst */
*new_version = LDAP_VERSION2;
@@ -812,7 +830,7 @@ int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version)
if (rc) {
return rc;
}
-
+
*new_version = LDAP_VERSION3;
return LDAP_SUCCESS;
}
@@ -875,7 +893,7 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state)
if (rc) {
return rc;
}
-
+
DEBUG(2, ("smbldap_open_connection: connection opened\n"));
return rc;
}
@@ -890,11 +908,11 @@ static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
int *methodp, int freeit, void *arg)
{
struct smbldap_state *ldap_state = arg;
-
+
/** @TODO Should we be doing something to check what servers we rebind to?
Could we get a referral to a machine that we don't want to give our
username and password to? */
-
+
if (freeit) {
SAFE_FREE(*whop);
if (*credp) {
@@ -923,7 +941,7 @@ static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
}
GetTimeOfDay(&ldap_state->last_rebind);
-
+
return 0;
}
#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
@@ -998,7 +1016,6 @@ static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
return rebindproc_with_state(ldap_struct, whop, credp,
method, freeit, ldap_state);
-
}
# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
@@ -1039,7 +1056,7 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
/* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
(OpenLDAP) doesnt' seem to support it */
-
+
DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
ldap_state->uri, ldap_state->bind_dn));
@@ -1175,17 +1192,17 @@ static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
{
if (!ldap_state)
return NT_STATUS_INVALID_PARAMETER;
-
+
if (ldap_state->ldap_struct != NULL) {
ldap_unbind(ldap_state->ldap_struct);
ldap_state->ldap_struct = NULL;
}
smbldap_delete_state(ldap_state);
-
+
DEBUG(5,("The connection to the LDAP server was closed\n"));
/* maybe free the results here --metze */
-
+
return NT_STATUS_OK;
}
@@ -1279,7 +1296,7 @@ static int smbldap_search_ext(struct smbldap_state *ldap_state,
size_t converted_size;
SMB_ASSERT(ldap_state);
-
+
DEBUG(5,("smbldap_search_ext: base => [%s], filter => [%s], "
"scope => [%d]\n", base, filter, scope));
@@ -1506,7 +1523,7 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
}
}
}
-
+
TALLOC_FREE(utf8_dn);
return rc;
}
@@ -1518,7 +1535,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
char *utf8_dn;
time_t endtime = time(NULL)+lp_ldap_timeout();
size_t converted_size;
-
+
SMB_ASSERT(ldap_state);
DEBUG(5,("smbldap_add: dn => [%s]\n", dn ));
@@ -1550,7 +1567,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
}
}
}
-
+
TALLOC_FREE(utf8_dn);
return rc;
}
@@ -1562,7 +1579,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
char *utf8_dn;
time_t endtime = time(NULL)+lp_ldap_timeout();
size_t converted_size;
-
+
SMB_ASSERT(ldap_state);
DEBUG(5,("smbldap_delete: dn => [%s]\n", dn ));
@@ -1594,7 +1611,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
}
}
}
-
+
TALLOC_FREE(utf8_dn);
return rc;
}
@@ -1607,7 +1624,7 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state,
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
time_t endtime = time(NULL)+lp_ldap_timeout();
-
+
if (!ldap_state)
return (-1);
@@ -1636,7 +1653,7 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state,
}
}
}
-
+
return rc;
}
@@ -1664,7 +1681,7 @@ static void smbldap_idle_fn(struct event_context *event_ctx,
DEBUG(10,("ldap connection not connected...\n"));
return;
}
-
+
if ((state->last_use+SMBLDAP_IDLE_TIME) > now.tv_sec) {
DEBUG(10,("ldap connection not idle...\n"));
@@ -1675,7 +1692,7 @@ static void smbldap_idle_fn(struct event_context *event_ctx,
private_data);
return;
}
-
+
DEBUG(7,("ldap connection idle...closing connection\n"));
smbldap_close(state);
}
@@ -1687,7 +1704,7 @@ static void smbldap_idle_fn(struct event_context *event_ctx,
void smbldap_free_struct(struct smbldap_state **ldap_state)
{
smbldap_close(*ldap_state);
-
+
if ((*ldap_state)->bind_secret) {
memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 8e67edeae6..b85f29e136 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -495,39 +495,6 @@ void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info)
TALLOC_FREE(frame);
}
-/****************************************************************************
- Add a gid to an array of gids if it's not already there.
-****************************************************************************/
-
-bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
- gid_t **gids, size_t *num_gids)
-{
- int i;
-
- if ((*num_gids != 0) && (*gids == NULL)) {
- /*
- * A former call to this routine has failed to allocate memory
- */
- return False;
- }
-
- for (i=0; i<*num_gids; i++) {
- if ((*gids)[i] == gid) {
- return True;
- }
- }
-
- *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1);
- if (*gids == NULL) {
- *num_gids = 0;
- return False;
- }
-
- (*gids)[*num_gids] = gid;
- *num_gids += 1;
- return True;
-}
-
/*******************************************************************
Check if a file exists - call vfs_file_exist for samba files.
********************************************************************/
diff --git a/source3/libads/ads_utils.c b/source3/libads/ads_utils.c
index fc2ea9d9fd..213242c223 100644
--- a/source3/libads/ads_utils.c
+++ b/source3/libads/ads_utils.c
@@ -1,154 +1,26 @@
-/*
+/*
Unix SMB/CIFS implementation.
ads (active directory) utility library
-
+
Copyright (C) Stefan (metze) Metzmacher 2002
Copyright (C) Andrew Tridgell 2001
-
+
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/>.
*/
#include "includes.h"
-/*
-translated the ACB_CTRL Flags to UserFlags (userAccountControl)
-*/
-uint32 ads_acb2uf(uint32 acb)
-{
- uint32 uf = 0x00000000;
-
- if (acb & ACB_DISABLED) uf |= UF_ACCOUNTDISABLE;
- if (acb & ACB_HOMDIRREQ) uf |= UF_HOMEDIR_REQUIRED;
- if (acb & ACB_PWNOTREQ) uf |= UF_PASSWD_NOTREQD;
- if (acb & ACB_TEMPDUP) uf |= UF_TEMP_DUPLICATE_ACCOUNT;
- if (acb & ACB_NORMAL) uf |= UF_NORMAL_ACCOUNT;
- if (acb & ACB_MNS) uf |= UF_MNS_LOGON_ACCOUNT;
- if (acb & ACB_DOMTRUST) uf |= UF_INTERDOMAIN_TRUST_ACCOUNT;
- if (acb & ACB_WSTRUST) uf |= UF_WORKSTATION_TRUST_ACCOUNT;
- if (acb & ACB_SVRTRUST) uf |= UF_SERVER_TRUST_ACCOUNT;
- if (acb & ACB_PWNOEXP) uf |= UF_DONT_EXPIRE_PASSWD;
- if (acb & ACB_AUTOLOCK) uf |= UF_LOCKOUT;
- if (acb & ACB_USE_DES_KEY_ONLY) uf |= UF_USE_DES_KEY_ONLY;
- if (acb & ACB_SMARTCARD_REQUIRED) uf |= UF_SMARTCARD_REQUIRED;
- if (acb & ACB_TRUSTED_FOR_DELEGATION) uf |= UF_TRUSTED_FOR_DELEGATION;
- if (acb & ACB_DONT_REQUIRE_PREAUTH) uf |= UF_DONT_REQUIRE_PREAUTH;
- if (acb & ACB_NO_AUTH_DATA_REQD) uf |= UF_NO_AUTH_DATA_REQUIRED;
- if (acb & ACB_NOT_DELEGATED) uf |= UF_NOT_DELEGATED;
- if (acb & ACB_ENC_TXT_PWD_ALLOWED) uf |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
-
- return uf;
-}
-
-/*
-translated the UserFlags (userAccountControl) to ACB_CTRL Flags
-*/
-uint32 ads_uf2acb(uint32 uf)
-{
- uint32 acb = 0x00000000;
-
- if (uf & UF_ACCOUNTDISABLE) acb |= ACB_DISABLED;
- if (uf & UF_HOMEDIR_REQUIRED) acb |= ACB_HOMDIRREQ;
- if (uf & UF_PASSWD_NOTREQD) acb |= ACB_PWNOTREQ;
- if (uf & UF_MNS_LOGON_ACCOUNT) acb |= ACB_MNS;
- if (uf & UF_DONT_EXPIRE_PASSWD) acb |= ACB_PWNOEXP;
- if (uf & UF_LOCKOUT) acb |= ACB_AUTOLOCK;
- if (uf & UF_USE_DES_KEY_ONLY) acb |= ACB_USE_DES_KEY_ONLY;
- if (uf & UF_SMARTCARD_REQUIRED) acb |= ACB_SMARTCARD_REQUIRED;
- if (uf & UF_TRUSTED_FOR_DELEGATION) acb |= ACB_TRUSTED_FOR_DELEGATION;
- if (uf & UF_DONT_REQUIRE_PREAUTH) acb |= ACB_DONT_REQUIRE_PREAUTH;
- if (uf & UF_NO_AUTH_DATA_REQUIRED) acb |= ACB_NO_AUTH_DATA_REQD;
- if (uf & UF_NOT_DELEGATED) acb |= ACB_NOT_DELEGATED;
- if (uf & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED) acb |= ACB_ENC_TXT_PWD_ALLOWED;
-
- switch (uf & UF_ACCOUNT_TYPE_MASK)
- {
- case UF_TEMP_DUPLICATE_ACCOUNT: acb |= ACB_TEMPDUP;break;
- case UF_NORMAL_ACCOUNT: acb |= ACB_NORMAL;break;
- case UF_INTERDOMAIN_TRUST_ACCOUNT: acb |= ACB_DOMTRUST;break;
- case UF_WORKSTATION_TRUST_ACCOUNT: acb |= ACB_WSTRUST;break;
- case UF_SERVER_TRUST_ACCOUNT: acb |= ACB_SVRTRUST;break;
- /*Fix Me: what should we do here? */
- default: acb |= ACB_NORMAL;break;
- }
-
- return acb;
-}
-
-/*
-get the accountType from the UserFlags
-*/
-uint32 ads_uf2atype(uint32 uf)
-{
- uint32 atype = 0x00000000;
-
- if (uf & UF_NORMAL_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
- else if (uf & UF_TEMP_DUPLICATE_ACCOUNT) atype = ATYPE_NORMAL_ACCOUNT;
- else if (uf & UF_SERVER_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
- else if (uf & UF_WORKSTATION_TRUST_ACCOUNT) atype = ATYPE_WORKSTATION_TRUST;
- else if (uf & UF_INTERDOMAIN_TRUST_ACCOUNT) atype = ATYPE_INTERDOMAIN_TRUST;
-
- return atype;
-}
-
-/*
-get the accountType from the groupType
-*/
-uint32 ads_gtype2atype(uint32 gtype)
-{
- uint32 atype = 0x00000000;
-
- switch(gtype) {
- case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
- atype = ATYPE_SECURITY_LOCAL_GROUP;
- break;
- case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
- atype = ATYPE_SECURITY_LOCAL_GROUP;
- break;
- case GTYPE_SECURITY_GLOBAL_GROUP:
- atype = ATYPE_SECURITY_GLOBAL_GROUP;
- break;
-
- case GTYPE_DISTRIBUTION_GLOBAL_GROUP:
- atype = ATYPE_DISTRIBUTION_GLOBAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP:
- atype = ATYPE_DISTRIBUTION_UNIVERSAL_GROUP;
- break;
- case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP:
- atype = ATYPE_DISTRIBUTION_LOCAL_GROUP;
- break;
- }
-
- return atype;
-}
-
-/* turn a sAMAccountType into a SID_NAME_USE */
-enum lsa_SidType ads_atype_map(uint32 atype)
-{
- switch (atype & 0xF0000000) {
- case ATYPE_GLOBAL_GROUP:
- return SID_NAME_DOM_GRP;
- case ATYPE_SECURITY_LOCAL_GROUP:
- return SID_NAME_ALIAS;
- case ATYPE_ACCOUNT:
- return SID_NAME_USER;
- default:
- DEBUG(1,("hmm, need to map account type 0x%x\n", atype));
- }
- return SID_NAME_UNKNOWN;
-}
-
const char *ads_get_ldap_server_name(ADS_STRUCT *ads)
{
return ads->config.ldap_server_name;
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 3e5764a598..102fc83d0f 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -6,17 +6,17 @@
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
Copyright (C) Guenther Deschner 2005
Copyright (C) Gerald Carter 2006
-
+
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/>.
*/
@@ -198,7 +198,7 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
if (!server || !*server) {
return False;
}
-
+
DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n",
server, ads->server.realm));
@@ -209,7 +209,7 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
}
/* this copes with inet_ntoa brokenness */
-
+
srv = SMB_STRDUP(server);
ZERO_STRUCT( cldap_reply );
@@ -411,7 +411,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
SAFE_FREE(sitename);
return NT_STATUS_OK;
}
-
+
/* keep track of failures */
add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL );
}
@@ -652,7 +652,7 @@ got_connection:
#endif
/* If the caller() requested no LDAP bind, then we are done */
-
+
if (ads->auth.flags & ADS_AUTH_NO_BIND) {
status = ADS_SUCCESS;
goto out;
@@ -663,7 +663,7 @@ got_connection:
status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
goto out;
}
-
+
/* Otherwise setup the TCP LDAP session */
ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name,
@@ -690,14 +690,14 @@ got_connection:
}
/* fill in the current time and offsets */
-
+
status = ads_current_time( ads );
if ( !ADS_ERR_OK(status) ) {
goto out;
}
/* Now do the bind */
-
+
if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
status = ADS_ERROR(ldap_simple_bind_s(ads->ldap.ld, NULL, NULL));
goto out;
@@ -781,7 +781,7 @@ static struct berval **ads_dup_values(TALLOC_CTX *ctx,
{
struct berval **values;
int i;
-
+
if (!in_vals) return NULL;
for (i=0; in_vals[i]; i++)
; /* count values */
@@ -826,7 +826,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals)
char **values;
int i;
size_t converted_size;
-
+
if (!in_vals) return NULL;
for (i=0; in_vals[i]; i++)
; /* count values */
@@ -901,7 +901,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads,
goto done;
}
}
-
+
/* Paged results only available on ldap v3 or later */
ldap_get_option(ads->ldap.ld, LDAP_OPT_PROTOCOL_VERSION, &version);
if (version < LDAP_VERSION3) {
@@ -976,7 +976,7 @@ static ADS_STATUS ads_do_paged_search_args(ADS_STRUCT *ads,
handle them and paged results at the same time. Using them
together results in the result record containing the server
page control being removed from the result list (tridge/jmcd)
-
+
leaving this in despite the control that says don't generate
referrals, in case the server doesn't support it (jmcd)
*/
@@ -1031,7 +1031,7 @@ done:
if (ext_bv) {
ber_bvfree(ext_bv);
}
-
+
/* if/when we decide to utf8-encode attrs, take out this next line */
TALLOC_FREE(search_attrs);
@@ -1159,7 +1159,7 @@ ADS_STATUS ads_do_search_all_fn(ADS_STRUCT *ads, const char *bind_path,
&res, &count, &cookie);
if (!ADS_ERR_OK(status)) break;
-
+
ads_process_results(ads, res, fn, data_area);
ads_msgfree(ads, res);
}
@@ -1347,7 +1347,7 @@ char *ads_parent_dn(const char *dn)
DEBUG(1, ("asprintf failed!\n"));
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
}
-
+
status = ads_search(ads, res, expr, attrs);
SAFE_FREE(expr);
return status;
@@ -1362,12 +1362,12 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx)
{
#define ADS_MODLIST_ALLOC_SIZE 10
LDAPMod **mods;
-
+
if ((mods = TALLOC_ZERO_ARRAY(ctx, LDAPMod *, ADS_MODLIST_ALLOC_SIZE + 1)))
/* -1 is safety to make sure we don't go over the end.
need to reset it to NULL before doing ldap modify */
mods[ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
-
+
return (ADS_MODLIST)mods;
}
@@ -1408,7 +1408,7 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods,
modlist[curmod+ADS_MODLIST_ALLOC_SIZE] = (LDAPMod *) -1;
*mods = (ADS_MODLIST)modlist;
}
-
+
if (!(modlist[curmod] = TALLOC_ZERO_P(ctx, LDAPMod)))
return ADS_ERROR(LDAP_NO_MEMORY);
modlist[curmod]->mod_type = talloc_strdup(ctx, name);
@@ -1541,7 +1541,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods)
DEBUG(1, ("ads_gen_add: push_utf8_talloc failed!"));
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
}
-
+
/* find the end of the list, marked by NULL or -1 */
for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);
/* make sure the end of the list is NULL */
@@ -1567,7 +1567,7 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn)
DEBUG(1, ("ads_del_dn: push_utf8_talloc failed!"));
return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
}
-
+
ret = ldap_delete_s(ads->ldap.ld, utf8_dn);
TALLOC_FREE(utf8_dn);
return ADS_ERROR(ret);
@@ -1593,7 +1593,7 @@ char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit)
/* samba4 might not yet respond to a wellknownobject-query */
return ret ? ret : SMB_STRDUP("cn=Computers");
}
-
+
if (strequal(org_unit, "Computers")) {
return SMB_STRDUP("cn=Computers");
}
@@ -1668,7 +1668,7 @@ char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid)
for (i=1; i < new_ln; i++) {
char *s = NULL;
-
+
if (asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]) == -1) {
SAFE_FREE(ret);
goto out;
@@ -1895,7 +1895,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
}
/* add short name spn */
-
+
if ( (psp1 = talloc_asprintf(ctx, "%s/%s", spn, machine_name)) == NULL ) {
talloc_destroy(ctx);
ads_msgfree(ads, res);
@@ -1904,13 +1904,13 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
strupper_m(psp1);
strlower_m(&psp1[strlen(spn)]);
servicePrincipalName[0] = psp1;
-
+
DEBUG(5,("ads_add_service_principal_name: INFO: Adding %s to host %s\n",
psp1, machine_name));
/* add fully qualified spn */
-
+
if ( (psp2 = talloc_asprintf(ctx, "%s/%s", spn, my_fqdn)) == NULL ) {
ret = ADS_ERROR(LDAP_NO_MEMORY);
goto out;
@@ -1926,18 +1926,18 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
ret = ADS_ERROR(LDAP_NO_MEMORY);
goto out;
}
-
+
ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
if (!ADS_ERR_OK(ret)) {
DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n"));
goto out;
}
-
+
if ( (dn_string = ads_get_dn(ads, ctx, res)) == NULL ) {
ret = ADS_ERROR(LDAP_NO_MEMORY);
goto out;
}
-
+
ret = ads_gen_mod(ads, dn_string, mods);
if (!ADS_ERR_OK(ret)) {
DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n"));
@@ -1974,7 +1974,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name,
uint32 acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\
UF_DONT_EXPIRE_PASSWD |\
UF_ACCOUNTDISABLE );
-
+
if (!(ctx = talloc_init("ads_add_machine_acct")))
return ADS_ERROR(LDAP_NO_MEMORY);
@@ -1991,7 +1991,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name,
if ( !new_dn || !samAccountName ) {
goto done;
}
-
+
#ifndef ENCTYPE_ARCFOUR_HMAC
acct_control |= UF_USE_DES_KEY_ONLY;
#endif
@@ -2003,7 +2003,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, const char *machine_name,
if (!(mods = ads_init_mods(ctx))) {
goto done;
}
-
+
ads_mod_str(ctx, &mods, "cn", machine_name);
ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName);
ads_mod_strlist(ctx, &mods, "objectClass", objectClass);
@@ -2015,7 +2015,7 @@ done:
SAFE_FREE(machine_escaped);
ads_msgfree(ads, res);
talloc_destroy(ctx);
-
+
return ret;
}
@@ -2254,7 +2254,7 @@ static bool ads_dump_field(ADS_STRUCT *ads, char *field, void **values, void *da
msg = ads_next_entry(ads, msg)) {
char *utf8_field;
BerElement *b;
-
+
for (utf8_field=ldap_first_attribute(ads->ldap.ld,
(LDAPMessage *)msg,&b);
utf8_field;
@@ -2373,7 +2373,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
values = ldap_get_values(ads->ldap.ld, msg, field);
if (!values)
return NULL;
-
+
if (values[0] && pull_utf8_talloc(mem_ctx, &ux_string, values[0],
&converted_size))
{
@@ -2455,7 +2455,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
size_t num_new_strings;
unsigned long int range_start;
unsigned long int range_end;
-
+
/* we might have been given the whole lot anyway */
if ((strings = ads_pull_strings(ads, mem_ctx, msg, field, num_strings))) {
*more_strings = False;
@@ -2481,7 +2481,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
*more_strings = False;
return NULL;
}
-
+
if (sscanf(&range_attr[strlen(expected_range_attrib)], "%lu-%lu",
&range_start, &range_end) == 2) {
*more_strings = True;
@@ -2508,7 +2508,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
}
new_strings = ads_pull_strings(ads, mem_ctx, msg, range_attr, &num_new_strings);
-
+
if (*more_strings && ((*num_strings + num_new_strings) != (range_end + 1))) {
DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) tells us we have %lu "
"strings in this bunch, but we only got %lu - aborting range retreival\n",
@@ -2521,13 +2521,13 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
strings = TALLOC_REALLOC_ARRAY(mem_ctx, current_strings, char *,
*num_strings + num_new_strings);
-
+
if (strings == NULL) {
ldap_memfree(range_attr);
*more_strings = False;
return NULL;
}
-
+
if (new_strings && num_new_strings) {
memcpy(&strings[*num_strings], new_strings,
sizeof(*new_strings) * num_new_strings);
@@ -2540,7 +2540,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
"%s;range=%d-*",
field,
(int)*num_strings);
-
+
if (!*next_attribute) {
DEBUG(1, ("talloc_asprintf for next attribute failed!\n"));
ldap_memfree(range_attr);
@@ -2595,7 +2595,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
values = ldap_get_values(ads->ldap.ld, msg, "objectGUID");
if (!values)
return False;
-
+
if (values[0]) {
memcpy(&flat_guid.info, values[0], sizeof(UUID_FLAT));
smb_uuid_unpack(flat_guid, guid);
@@ -2665,7 +2665,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
count++;
}
}
-
+
ldap_value_free_len(values);
return count;
}
@@ -2700,7 +2700,7 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
ret = false;
}
}
-
+
ldap_value_free_len(values);
return ret;
}
@@ -2829,7 +2829,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads)
}
/* but save the time and offset in the original ADS_STRUCT */
-
+
ads->config.current_time = ads_parse_time(timestr);
if (ads->config.current_time != 0) {
@@ -2860,7 +2860,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val)
ADS_STATUS status;
LDAPMessage *res;
ADS_STRUCT *ads_s = ads;
-
+
*val = DS_DOMAIN_FUNCTION_2000;
/* establish a new ldap tcp session if necessary */
@@ -2880,7 +2880,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val)
/* If the attribute does not exist assume it is a Windows 2000
functional domain */
-
+
status = ads_do_search(ads_s, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
if (!ADS_ERR_OK(status)) {
if ( status.err.rc == LDAP_NO_SUCH_ATTRIBUTE ) {
@@ -2894,7 +2894,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32 *val)
}
DEBUG(3,("ads_domain_func_level: %d\n", *val));
-
+
ads_msgfree(ads, res);
done:
@@ -2926,7 +2926,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
return ADS_ERROR_SYSTEM(ENOENT);
}
ads_msgfree(ads, res);
-
+
return ADS_SUCCESS;
}
@@ -3301,26 +3301,26 @@ char* ads_get_dnshostname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *machine
ADS_STATUS status;
int count = 0;
char *name = NULL;
-
+
status = ads_find_machine_acct(ads, &res, global_myname());
if (!ADS_ERR_OK(status)) {
DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n",
global_myname()));
goto out;
}
-
+
if ( (count = ads_count_replies(ads, res)) != 1 ) {
DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count));
goto out;
}
-
+
if ( (name = ads_pull_string(ads, ctx, res, "dNSHostName")) == NULL ) {
DEBUG(0,("ads_get_dnshostname: No dNSHostName attribute!\n"));
}
out:
ads_msgfree(ads, res);
-
+
return name;
}
@@ -3365,26 +3365,26 @@ char* ads_get_samaccountname( ADS_STRUCT *ads, TALLOC_CTX *ctx, const char *mach
ADS_STATUS status;
int count = 0;
char *name = NULL;
-
+
status = ads_find_machine_acct(ads, &res, global_myname());
if (!ADS_ERR_OK(status)) {
DEBUG(0,("ads_get_dnshostname: Failed to find account for %s\n",
global_myname()));
goto out;
}
-
+
if ( (count = ads_count_replies(ads, res)) != 1 ) {
DEBUG(1,("ads_get_dnshostname: %d entries returned!\n", count));
goto out;
}
-
+
if ( (name = ads_pull_string(ads, ctx, res, "sAMAccountName")) == NULL ) {
DEBUG(0,("ads_get_dnshostname: No sAMAccountName attribute!\n"));
}
out:
ads_msgfree(ads, res);
-
+
return name;
}
@@ -3700,7 +3700,7 @@ ADS_STATUS ads_find_samaccount(ADS_STRUCT *ads,
status = ads_do_search_all(ads, ads->config.bind_path,
LDAP_SCOPE_SUBTREE,
filter, attrs, &res);
-
+
if (!ADS_ERR_OK(status)) {
goto out;
}
@@ -3828,7 +3828,6 @@ const char *ads_get_extended_right_name_by_guid(ADS_STRUCT *ads,
done:
ads_msgfree(ads, res);
return result;
-
}
/**
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 187fcdf625..693d97626f 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -453,7 +453,6 @@ NTSTATUS cli_posix_readlink(struct cli_state *cli, const char *fname,
return status;
}
-
/****************************************************************************
Hard link a file (UNIX extensions).
****************************************************************************/
@@ -624,222 +623,570 @@ static mode_t unix_filetype_from_wire(uint32_t wire_type)
Do a POSIX getfacl (UNIX extensions).
****************************************************************************/
-bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf)
+struct getfacl_state {
+ uint16_t setup;
+ uint8_t *param;
+ uint32_t num_data;
+ uint8_t *data;
+};
+
+static void cli_posix_getfacl_done(struct tevent_req *subreq)
{
- unsigned int param_len = 0;
- unsigned int data_len = 0;
- uint16_t setup = TRANSACT2_QPATHINFO;
- char *param;
- size_t nlen = 2*(strlen(name)+1);
- char *rparam=NULL, *rdata=NULL;
- char *p;
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct getfacl_state *state = tevent_req_data(req, struct getfacl_state);
+ NTSTATUS status;
- param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
- if (!param) {
- return false;
+ status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
+ &state->data, &state->num_data);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
}
+ tevent_req_done(req);
+}
- p = param;
- memset(p, '\0', 6);
- SSVAL(p, 0, SMB_QUERY_POSIX_ACL);
- p += 6;
- p += clistr_push(cli, p, name, nlen, STR_TERMINATE);
- param_len = PTR_DIFF(p, param);
+struct tevent_req *cli_posix_getfacl_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct link_state *state = NULL;
- if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
- NULL, 0, cli->max_xmit /* data, length, max */
- )) {
- SAFE_FREE(param);
- return false;
+ req = tevent_req_create(mem_ctx, &state, struct getfacl_state);
+ if (req == NULL) {
+ return NULL;
}
- SAFE_FREE(param);
+ /* Setup setup word. */
+ SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO);
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &param_len,
- &rdata, &data_len)) {
- return false;
+ /* Setup param array. */
+ state->param = talloc_array(state, uint8_t, 6);
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
}
+ memset(state->param, '\0', 6);
+ SSVAL(state->param, 0, SMB_QUERY_POSIX_ACL);
- if (data_len < 6) {
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
- return false;
+ state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
+ strlen(fname)+1, NULL);
+
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
}
- SAFE_FREE(rparam);
- *retbuf = rdata;
- *prb_size = (size_t)data_len;
+ subreq = cli_trans_send(state, /* mem ctx. */
+ ev, /* event ctx. */
+ cli, /* cli_state. */
+ SMBtrans2, /* cmd. */
+ NULL, /* pipe name. */
+ -1, /* fid. */
+ 0, /* function. */
+ 0, /* flags. */
+ &state->setup, /* setup. */
+ 1, /* num setup uint16_t words. */
+ 0, /* max returned setup. */
+ state->param, /* param. */
+ talloc_get_size(state->param), /* num param. */
+ 2, /* max returned param. */
+ NULL, /* data. */
+ 0, /* num data. */
+ cli->max_xmit); /* max returned data. */
- return true;
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_posix_getfacl_done, req);
+ return req;
+}
+
+NTSTATUS cli_posix_getfacl_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ size_t *prb_size,
+ char **retbuf)
+{
+ struct getfacl_state *state = tevent_req_data(req, struct getfacl_state);
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ *prb_size = (size_t)state->num_data;
+ *retbuf = (char *)talloc_move(mem_ctx, &state->data);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_getfacl(struct cli_state *cli,
+ const char *fname,
+ TALLOC_CTX *mem_ctx,
+ size_t *prb_size,
+ char **retbuf)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_posix_getfacl_send(frame,
+ ev,
+ cli,
+ fname);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_posix_getfacl_recv(req, mem_ctx, prb_size, retbuf);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
Stat a file (UNIX extensions).
****************************************************************************/
-bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf)
+struct stat_state {
+ uint16_t setup;
+ uint8_t *param;
+ uint32_t num_data;
+ uint8_t *data;
+};
+
+static void cli_posix_stat_done(struct tevent_req *subreq)
{
- unsigned int param_len = 0;
- unsigned int data_len = 0;
- uint16_t setup = TRANSACT2_QPATHINFO;
- char *param;
- size_t nlen = 2*(strlen(name)+1);
- char *rparam=NULL, *rdata=NULL;
- char *p;
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct stat_state *state = tevent_req_data(req, struct stat_state);
+ NTSTATUS status;
- ZERO_STRUCTP(sbuf);
+ status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
+ &state->data, &state->num_data);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ tevent_req_done(req);
+}
- param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
- if (!param) {
- return false;
+struct tevent_req *cli_posix_stat_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct stat_state *state = NULL;
+
+ req = tevent_req_create(mem_ctx, &state, struct stat_state);
+ if (req == NULL) {
+ return NULL;
}
- p = param;
- memset(p, '\0', 6);
- SSVAL(p, 0, SMB_QUERY_FILE_UNIX_BASIC);
- p += 6;
- p += clistr_push(cli, p, name, nlen, STR_TERMINATE);
- param_len = PTR_DIFF(p, param);
- if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
- NULL, 0, cli->max_xmit /* data, length, max */
- )) {
- SAFE_FREE(param);
- return false;
+ /* Setup setup word. */
+ SSVAL(&state->setup, 0, TRANSACT2_QPATHINFO);
+
+ /* Setup param array. */
+ state->param = talloc_array(state, uint8_t, 6);
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
}
+ memset(state->param, '\0', 6);
+ SSVAL(state->param, 0, SMB_QUERY_FILE_UNIX_BASIC);
- SAFE_FREE(param);
+ state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
+ strlen(fname)+1, NULL);
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &param_len,
- &rdata, &data_len)) {
- return false;
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
}
- if (data_len < 96) {
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
- return false;
+ subreq = cli_trans_send(state, /* mem ctx. */
+ ev, /* event ctx. */
+ cli, /* cli_state. */
+ SMBtrans2, /* cmd. */
+ NULL, /* pipe name. */
+ -1, /* fid. */
+ 0, /* function. */
+ 0, /* flags. */
+ &state->setup, /* setup. */
+ 1, /* num setup uint16_t words. */
+ 0, /* max returned setup. */
+ state->param, /* param. */
+ talloc_get_size(state->param), /* num param. */
+ 2, /* max returned param. */
+ NULL, /* data. */
+ 0, /* num data. */
+ 96); /* max returned data. */
+
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_posix_stat_done, req);
+ return req;
+}
+
+NTSTATUS cli_posix_stat_recv(struct tevent_req *req,
+ SMB_STRUCT_STAT *sbuf)
+{
+ struct stat_state *state = tevent_req_data(req, struct stat_state);
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+
+ if (state->num_data != 96) {
+ return NT_STATUS_DATA_ERROR;
}
- sbuf->st_ex_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */
- sbuf->st_ex_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */
+ sbuf->st_ex_size = IVAL2_TO_SMB_BIG_UINT(state->data,0); /* total size, in bytes */
+ sbuf->st_ex_blocks = IVAL2_TO_SMB_BIG_UINT(state->data,8); /* number of blocks allocated */
#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
sbuf->st_ex_blocks /= STAT_ST_BLOCKSIZE;
#else
/* assume 512 byte blocks */
sbuf->st_ex_blocks /= 512;
#endif
- sbuf->st_ex_ctime = interpret_long_date(rdata + 16); /* time of last change */
- sbuf->st_ex_atime = interpret_long_date(rdata + 24); /* time of last access */
- sbuf->st_ex_mtime = interpret_long_date(rdata + 32); /* time of last modification */
+ sbuf->st_ex_ctime = interpret_long_date((char *)(state->data + 16)); /* time of last change */
+ sbuf->st_ex_atime = interpret_long_date((char *)(state->data + 24)); /* time of last access */
+ sbuf->st_ex_mtime = interpret_long_date((char *)(state->data + 32)); /* time of last modification */
- sbuf->st_ex_uid = (uid_t) IVAL(rdata,40); /* user ID of owner */
- sbuf->st_ex_gid = (gid_t) IVAL(rdata,48); /* group ID of owner */
- sbuf->st_ex_mode |= unix_filetype_from_wire(IVAL(rdata, 56));
+ sbuf->st_ex_uid = (uid_t) IVAL(state->data,40); /* user ID of owner */
+ sbuf->st_ex_gid = (gid_t) IVAL(state->data,48); /* group ID of owner */
+ sbuf->st_ex_mode = unix_filetype_from_wire(IVAL(state->data, 56));
#if defined(HAVE_MAKEDEV)
{
- uint32_t dev_major = IVAL(rdata,60);
- uint32_t dev_minor = IVAL(rdata,68);
+ uint32_t dev_major = IVAL(state->data,60);
+ uint32_t dev_minor = IVAL(state->data,68);
sbuf->st_ex_rdev = makedev(dev_major, dev_minor);
}
#endif
- sbuf->st_ex_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76); /* inode */
- sbuf->st_ex_mode |= wire_perms_to_unix(IVAL(rdata,84)); /* protection */
- sbuf->st_ex_nlink = IVAL(rdata,92); /* number of hard links */
+ sbuf->st_ex_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(state->data,76); /* inode */
+ sbuf->st_ex_mode |= wire_perms_to_unix(IVAL(state->data,84)); /* protection */
+ sbuf->st_ex_nlink = IVAL(state->data,92); /* number of hard links */
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
+ return NT_STATUS_OK;
+}
- return true;
+NTSTATUS cli_posix_stat(struct cli_state *cli,
+ const char *fname,
+ SMB_STRUCT_STAT *sbuf)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_posix_stat_send(frame,
+ ev,
+ cli,
+ fname);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_posix_stat_recv(req, sbuf);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
+
/****************************************************************************
Chmod or chown a file internal (UNIX extensions).
****************************************************************************/
-static bool cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32_t mode, uint32_t uid, uint32_t gid)
+struct ch_state {
+ uint16_t setup;
+ uint8_t *param;
+ uint8_t *data;
+};
+
+static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq)
{
- unsigned int data_len = 0;
- unsigned int param_len = 0;
- uint16_t setup = TRANSACT2_SETPATHINFO;
- size_t nlen = 2*(strlen(fname)+1);
- char *param;
- char data[100];
- char *rparam=NULL, *rdata=NULL;
- char *p;
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct ch_state *state = tevent_req_data(req, struct ch_state);
+ NTSTATUS status;
- param = SMB_MALLOC_ARRAY(char, 6+nlen+2);
- if (!param) {
- return false;
+ status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
}
- memset(param, '\0', 6);
- memset(data, 0, sizeof(data));
+ tevent_req_done(req);
+}
- SSVAL(param,0,SMB_SET_FILE_UNIX_BASIC);
- p = &param[6];
+static struct tevent_req *cli_posix_chown_chmod_internal_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ uint32_t mode,
+ uint32_t uid,
+ uint32_t gid)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct ch_state *state = NULL;
- p += clistr_push(cli, p, fname, nlen, STR_TERMINATE);
- param_len = PTR_DIFF(p, param);
+ req = tevent_req_create(mem_ctx, &state, struct ch_state);
+ if (req == NULL) {
+ return NULL;
+ }
- memset(data, 0xff, 40); /* Set all sizes/times to no change. */
+ /* Setup setup word. */
+ SSVAL(&state->setup, 0, TRANSACT2_SETPATHINFO);
- SIVAL(data,40,uid);
- SIVAL(data,48,gid);
- SIVAL(data,84,mode);
+ /* Setup param array. */
+ state->param = talloc_array(state, uint8_t, 6);
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
+ }
+ memset(state->param, '\0', 6);
+ SSVAL(state->param,0,SMB_SET_FILE_UNIX_BASIC);
- data_len = 100;
+ state->param = trans2_bytes_push_str(state->param, cli_ucs2(cli), fname,
+ strlen(fname)+1, NULL);
- if (!cli_send_trans(cli, SMBtrans2,
- NULL, /* name */
- -1, 0, /* fid, flags */
- &setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
- (char *)&data, data_len, cli->max_xmit /* data, length, max */
- )) {
- SAFE_FREE(param);
- return False;
+ if (tevent_req_nomem(state->param, req)) {
+ return tevent_req_post(req, ev);
}
- SAFE_FREE(param);
-
- if (!cli_receive_trans(cli, SMBtrans2,
- &rparam, &param_len,
- &rdata, &data_len)) {
- return false;
+ /* Setup data array. */
+ state->data = talloc_array(state, uint8_t, 100);
+ if (tevent_req_nomem(state->data, req)) {
+ return tevent_req_post(req, ev);
}
+ memset(state->data, 0xff, 40); /* Set all sizes/times to no change. */
+ memset(&state->data[40], '\0', 60);
+ SIVAL(state->data,40,uid);
+ SIVAL(state->data,48,gid);
+ SIVAL(state->data,84,mode);
- SAFE_FREE(rdata);
- SAFE_FREE(rparam);
+ subreq = cli_trans_send(state, /* mem ctx. */
+ ev, /* event ctx. */
+ cli, /* cli_state. */
+ SMBtrans2, /* cmd. */
+ NULL, /* pipe name. */
+ -1, /* fid. */
+ 0, /* function. */
+ 0, /* flags. */
+ &state->setup, /* setup. */
+ 1, /* num setup uint16_t words. */
+ 0, /* max returned setup. */
+ state->param, /* param. */
+ talloc_get_size(state->param), /* num param. */
+ 2, /* max returned param. */
+ state->data, /* data. */
+ talloc_get_size(state->data), /* num data. */
+ 0); /* max returned data. */
- return true;
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_posix_chown_chmod_internal_done, req);
+ return req;
}
/****************************************************************************
chmod a file (UNIX extensions).
****************************************************************************/
-bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode)
+struct tevent_req *cli_posix_chmod_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ mode_t mode)
+{
+ return cli_posix_chown_chmod_internal_send(mem_ctx, ev, cli,
+ fname,
+ unix_perms_to_wire(mode),
+ SMB_UID_NO_CHANGE,
+ SMB_GID_NO_CHANGE);
+}
+
+NTSTATUS cli_posix_chmod_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_chmod(struct cli_state *cli, const char *fname, mode_t mode)
{
- return cli_unix_chmod_chown_internal(cli, fname,
- unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE);
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_posix_chmod_send(frame,
+ ev,
+ cli,
+ fname,
+ mode);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_posix_chmod_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
chown a file (UNIX extensions).
****************************************************************************/
-bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid)
+struct tevent_req *cli_posix_chown_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *fname,
+ uid_t uid,
+ gid_t gid)
+{
+ return cli_posix_chown_chmod_internal_send(mem_ctx, ev, cli,
+ fname,
+ SMB_MODE_NO_CHANGE,
+ (uint32_t)uid,
+ (uint32_t)gid);
+}
+
+NTSTATUS cli_posix_chown_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_posix_chown(struct cli_state *cli,
+ const char *fname,
+ uid_t uid,
+ gid_t gid)
{
- return cli_unix_chmod_chown_internal(cli, fname,
- SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid);
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_posix_chown_send(frame,
+ ev,
+ cli,
+ fname,
+ uid,
+ gid);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_posix_chown_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
@@ -1506,6 +1853,135 @@ NTSTATUS cli_rmdir(struct cli_state *cli, const char *dname)
Set or clear the delete on close flag.
****************************************************************************/
+struct doc_state {
+ uint16_t setup;
+ uint8_t param[6];
+ uint8_t data[1];
+};
+
+static void cli_nt_delete_on_close_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct doc_state *state = tevent_req_data(req, struct doc_state);
+ NTSTATUS status;
+
+ status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ tevent_req_done(req);
+}
+
+struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum,
+ bool flag)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct doc_state *state = NULL;
+
+ req = tevent_req_create(mem_ctx, &state, struct doc_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ /* Setup setup word. */
+ SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO);
+
+ /* Setup param array. */
+ memset(state->param, '\0', 6);
+ SSVAL(state->param,0,fnum);
+ SSVAL(state->param,2,SMB_SET_FILE_DISPOSITION_INFO);
+
+ /* Setup data array. */
+ SCVAL(&state->data[0], 0, flag ? 1 : 0);
+
+ subreq = cli_trans_send(state, /* mem ctx. */
+ ev, /* event ctx. */
+ cli, /* cli_state. */
+ SMBtrans2, /* cmd. */
+ NULL, /* pipe name. */
+ -1, /* fid. */
+ 0, /* function. */
+ 0, /* flags. */
+ &state->setup, /* setup. */
+ 1, /* num setup uint16_t words. */
+ 0, /* max returned setup. */
+ state->param, /* param. */
+ 6, /* num param. */
+ 2, /* max returned param. */
+ state->data, /* data. */
+ 1, /* num data. */
+ 0); /* max returned data. */
+
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_nt_delete_on_close_done, req);
+ return req;
+}
+
+NTSTATUS cli_nt_delete_on_close_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev = NULL;
+ struct tevent_req *req = NULL;
+ NTSTATUS status = NT_STATUS_OK;
+
+ if (cli_has_async_calls(cli)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_nt_delete_on_close_send(frame,
+ ev,
+ cli,
+ fnum,
+ flag);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ status = cli_nt_delete_on_close_recv(req);
+
+ fail:
+ TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
+}
+
+#if 0
int cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag)
{
unsigned int data_len = 1;
@@ -1542,6 +2018,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag)
return true;
}
+#endif
struct cli_ntcreate_state {
uint16_t vwv[24];
diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
index 5606b8e7c9..fb87b4dc9a 100644
--- a/source3/libsmb/dsgetdcname.c
+++ b/source3/libsmb/dsgetdcname.c
@@ -626,8 +626,8 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx,
struct ip_service_name *r = &dclist[count];
- r->port = dcs[count].port;
- r->hostname = dcs[count].hostname;
+ r->port = dcs[i].port;
+ r->hostname = dcs[i].hostname;
/* If we don't have an IP list for a name, lookup it up */
diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c
index bacd907512..98885876b3 100644
--- a/source3/libsmb/libsmb_context.c
+++ b/source3/libsmb/libsmb_context.c
@@ -120,7 +120,7 @@ SMBC_module_init(void * punused)
}
-void
+static void
SMBC_module_terminate(void)
{
gencache_shutdown();
diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
index 9d63021f42..70f90b5cd5 100644
--- a/source3/modules/onefs.h
+++ b/source3/modules/onefs.h
@@ -170,4 +170,17 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd,
ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset,
size_t count);
+void init_stat_ex_from_onefs_stat(struct stat_ex *dst, const struct stat *src);
+
+int onefs_sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf);
+
+int onefs_sys_fstat(int fd, SMB_STRUCT_STAT *sbuf);
+
+int onefs_sys_fstat_at(int base_fd, const char *fname, SMB_STRUCT_STAT *sbuf,
+ int flags);
+
+int onefs_sys_lstat(const char *fname, SMB_STRUCT_STAT *sbuf);
+
+
+
#endif /* _ONEFS_H */
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c
index d66e5d65fa..81bdfd26cc 100644
--- a/source3/modules/onefs_acl.c
+++ b/source3/modules/onefs_acl.c
@@ -393,7 +393,7 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd)
if (error)
return false;
- if ((sbuf.st_flags & SF_HASNTFSACL) != 0) {
+ if ((sbuf.st_ex_flags & SF_HASNTFSACL) != 0) {
DEBUG(10, ("Did not canonicalize ACLs because a "
"Windows ACL set was found for file %s\n",
fsp->fsp_name));
@@ -540,7 +540,8 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd)
}
/* Only continue if this is a synthetic ACL and a directory. */
- if (S_ISDIR(sbuf.st_mode) && (sbuf.st_flags & SF_HASNTFSACL) == 0) {
+ if (S_ISDIR(sbuf.st_ex_mode) &&
+ (sbuf.st_ex_flags & SF_HASNTFSACL) == 0) {
struct ifs_ace new_aces[6];
struct ifs_ace *old_aces;
int i, num_aces_to_add = 0;
diff --git a/source3/modules/onefs_dir.c b/source3/modules/onefs_dir.c
index 47da33fff1..2ab8b86771 100644
--- a/source3/modules/onefs_dir.c
+++ b/source3/modules/onefs_dir.c
@@ -43,7 +43,7 @@
#define RDP_DIRENTRIES_SIZE ((size_t)(RDP_BATCH_SIZE * sizeof(struct dirent)))
static char *rdp_direntries = NULL;
-static SMB_STRUCT_STAT *rdp_stats = NULL;
+static struct stat *rdp_stats = NULL;
static uint64_t *rdp_cookies = NULL;
struct rdp_dir_state {
@@ -113,7 +113,7 @@ rdp_init(struct rdp_dir_state *dsp)
if (!rdp_stats) {
rdp_stats =
- SMB_MALLOC(RDP_BATCH_SIZE * sizeof(SMB_STRUCT_STAT));
+ SMB_MALLOC(RDP_BATCH_SIZE * sizeof(struct stat));
if (!rdp_stats)
return ENOMEM;
}
@@ -367,11 +367,15 @@ onefs_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp,
/* Return an entry from cache */
ret_direntp = ((SMB_STRUCT_DIRENT *)dsp->direntries_cursor);
if (sbuf) {
- *sbuf = rdp_stats[dsp->stat_cursor];
+ struct stat onefs_sbuf;
+
+ onefs_sbuf = rdp_stats[dsp->stat_cursor];
+ init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
+
/* readdirplus() sets st_ino field to 0, if it was
* unable to retrieve stat information for that
* particular directory entry. */
- if (sbuf->st_ino == 0)
+ if (sbuf->st_ex_ino == 0)
SET_STAT_INVALID(*sbuf);
}
diff --git a/source3/modules/onefs_notify.c b/source3/modules/onefs_notify.c
index 3455afd4ab..0447d0c03e 100644
--- a/source3/modules/onefs_notify.c
+++ b/source3/modules/onefs_notify.c
@@ -630,21 +630,21 @@ onefs_notify_watch(vfs_handle_struct *vfs_handle,
}
/* Get LIN for directory */
- if (sys_fstat(e->dir_fd, &sbuf)) {
+ if (onefs_sys_fstat(e->dir_fd, &sbuf)) {
DEBUG(0, ("stat on directory fd failed: %s\n",
strerror(errno)));
status = map_nt_error_from_unix(errno);
goto err;
}
- if (sbuf.st_ino == 0) {
+ if (sbuf.st_ex_ino == 0) {
DEBUG(0, ("0 LIN found!\n"));
goto err;
}
wc->ctx = ctx;
wc->watch_fd = e->dir_fd;
- wc->watch_lin = sbuf.st_ino;
+ wc->watch_lin = sbuf.st_ex_ino;
wc->ifs_event_fd = ifs_event_fd;
wc->ifs_filter = ifs_filter;
wc->smb_filter = smb_filter;
@@ -669,7 +669,7 @@ onefs_notify_watch(vfs_handle_struct *vfs_handle,
"ifs_filter=0x%x, watch_tree=%d, ifs_event_fd=%d, "
"dir_fd=%d, dir_lin=0x%llx\n",
e->path, smb_filter, ifs_filter, watch_tree,
- ifs_event_fd, e->dir_fd, sbuf.st_ino));
+ ifs_event_fd, e->dir_fd, sbuf.st_ex_ino));
return NT_STATUS_OK;
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index 6cfa24f9f6..21c5d51f90 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -148,7 +148,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
* open flags. JRA.
*/
- if (file_existed && S_ISFIFO(psbuf->st_mode)) {
+ if (file_existed && S_ISFIFO(psbuf->st_ex_mode)) {
local_flags |= O_NONBLOCK;
}
#endif
@@ -289,13 +289,13 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
* so catch a directory open and return an EISDIR. JRA.
*/
- if(S_ISDIR(psbuf->st_mode)) {
+ if(S_ISDIR(psbuf->st_ex_mode)) {
fd_close(fsp);
errno = EISDIR;
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
- fsp->mode = psbuf->st_mode;
+ fsp->mode = psbuf->st_ex_mode;
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
@@ -661,7 +661,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
"FILE_CREATE requested for file %s "
"and file already exists.\n",
fname));
- if (S_ISDIR(psbuf->st_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
errno = EISDIR;
} else {
errno = EEXIST;
@@ -687,13 +687,13 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
(create_disposition == FILE_OVERWRITE_IF))) {
if (!open_match_attributes(conn, fname,
existing_dos_attributes,
- new_dos_attributes, psbuf->st_mode,
+ new_dos_attributes, psbuf->st_ex_mode,
unx_mode, &new_unx_mode)) {
DEBUG(5, ("onefs_open_file_ntcreate: attributes "
"missmatch for file %s (%x %x) (0%o, 0%o)\n",
fname, existing_dos_attributes,
new_dos_attributes,
- (unsigned int)psbuf->st_mode,
+ (unsigned int)psbuf->st_ex_mode,
(unsigned int)unx_mode ));
errno = EACCES;
return NT_STATUS_ACCESS_DENIED;
@@ -816,7 +816,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
}
if (file_existed) {
- struct timespec old_write_time = get_mtimespec(psbuf);
+ struct timespec old_write_time = psbuf->st_ex_mtime;
id = vfs_file_id_from_sbuf(conn, psbuf);
lck = get_share_mode_lock(talloc_tos(), id,
@@ -900,7 +900,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
struct deferred_open_record state;
struct timespec old_write_time;
- old_write_time = get_mtimespec(psbuf);
+ old_write_time = psbuf->st_ex_mtime;
DEBUG(3, ("Someone created file %s with an "
"oplock after we looked: Retrying\n",
@@ -1089,7 +1089,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
}
if (!file_existed) {
- struct timespec old_write_time = get_mtimespec(psbuf);
+ struct timespec old_write_time = psbuf->st_ex_mtime;
/*
* Deal with the race condition where two smbd's detect the
* file doesn't exist and do the create at the same time. One
@@ -1267,7 +1267,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
* May be necessary depending on acl policies.
*/
if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
- && (psbuf->st_flags & SF_HASNTFSACL))) {
+ && (psbuf->st_ex_flags & SF_HASNTFSACL))) {
int saved_errno = errno; /* We might get ENOSYS in the next
* call.. */
@@ -1495,7 +1495,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
return map_nt_error_from_unix(errno);
}
- if (!S_ISDIR(psbuf->st_mode)) {
+ if (!S_ISDIR(psbuf->st_ex_mode)) {
DEBUG(0, ("Directory just '%s' created is not a "
"directory\n", fname));
return NT_STATUS_ACCESS_DENIED;
@@ -1509,9 +1509,9 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
* parent dir.
*/
if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
- (mode & ~psbuf->st_mode)) {
- SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
- (mode & ~psbuf->st_mode)));
+ (mode & ~psbuf->st_ex_mode)) {
+ SMB_VFS_CHMOD(conn, fname, (psbuf->st_ex_mode |
+ (mode & ~psbuf->st_ex_mode)));
}
}
@@ -1533,7 +1533,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
}
/* Setup the files_struct for it. */
- fsp->mode = psbuf->st_mode;
+ fsp->mode = psbuf->st_ex_mode;
fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
fsp->file_pid = req ? req->smbpid : 0;
@@ -1556,7 +1556,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
string_set(&fsp->fsp_name,fname);
- mtimespec = get_mtimespec(psbuf);
+ mtimespec = psbuf->st_ex_mtime;
/*
* Still set the samba share mode lock for correct delete-on-close
@@ -1904,7 +1904,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
}
}
- if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
+ if (!fsp->is_directory && S_ISDIR(sbuf.st_ex_mode)) {
status = NT_STATUS_ACCESS_DENIED;
goto fail;
}
@@ -1912,7 +1912,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
/* Save the requested allocation size. */
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
if (allocation_size
- && (allocation_size > sbuf.st_size)) {
+ && (allocation_size > sbuf.st_ex_size)) {
fsp->initial_allocation_size = smb_roundup(
fsp->conn, allocation_size);
if (fsp->is_directory) {
@@ -1927,7 +1927,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
}
} else {
fsp->initial_allocation_size = smb_roundup(
- fsp->conn, (uint64_t)sbuf.st_size);
+ fsp->conn, (uint64_t)sbuf.st_ex_size);
}
}
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index 05b36d7d3c..284e199fc5 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -222,81 +222,84 @@ static void merge_stat(SMB_STRUCT_STAT *stream_sbuf,
{
int dos_flags = (UF_DOS_NOINDEX | UF_DOS_ARCHIVE |
UF_DOS_HIDDEN | UF_DOS_RO | UF_DOS_SYSTEM);
- stream_sbuf->st_mtime = base_sbuf->st_mtime;
- stream_sbuf->st_ctime = base_sbuf->st_ctime;
- stream_sbuf->st_atime = base_sbuf->st_atime;
- stream_sbuf->st_flags &= ~dos_flags;
- stream_sbuf->st_flags |= base_sbuf->st_flags & dos_flags;
+ stream_sbuf->st_ex_mtime = base_sbuf->st_ex_mtime;
+ stream_sbuf->st_ex_ctime = base_sbuf->st_ex_ctime;
+ stream_sbuf->st_ex_atime = base_sbuf->st_ex_atime;
+ stream_sbuf->st_ex_flags &= ~dos_flags;
+ stream_sbuf->st_ex_flags |= base_sbuf->st_ex_flags & dos_flags;
}
/* fake timestamps */
-static void onefs_adjust_stat_time(vfs_handle_struct *handle, const char *fname,
- SMB_STRUCT_STAT *sbuf)
+static void onefs_adjust_stat_time(struct connection_struct *conn,
+ const char *fname, SMB_STRUCT_STAT *sbuf)
{
struct onefs_vfs_share_config cfg;
struct timeval tv_now = {0, 0};
bool static_mtime = False;
bool static_atime = False;
- if (!onefs_get_config(SNUM(handle->conn),
+ if (!onefs_get_config(SNUM(conn),
ONEFS_VFS_CONFIG_FAKETIMESTAMPS, &cfg)) {
return;
}
- if (IS_MTIME_STATIC_PATH(handle->conn, &cfg, fname)) {
- sbuf->st_mtime = sbuf->st_birthtime;
+ if (IS_MTIME_STATIC_PATH(conn, &cfg, fname)) {
+ sbuf->st_ex_mtime = sbuf->st_ex_btime;
static_mtime = True;
}
- if (IS_ATIME_STATIC_PATH(handle->conn, &cfg, fname)) {
- sbuf->st_atime = sbuf->st_birthtime;
+ if (IS_ATIME_STATIC_PATH(conn, &cfg, fname)) {
+ sbuf->st_ex_atime = sbuf->st_ex_btime;
static_atime = True;
}
- if (IS_CTIME_NOW_PATH(handle->conn, &cfg, fname)) {
+ if (IS_CTIME_NOW_PATH(conn, &cfg, fname)) {
if (cfg.ctime_slop < 0) {
- sbuf->st_birthtime = INT_MAX - 1;
+ sbuf->st_ex_btime.tv_sec = INT_MAX - 1;
} else {
GetTimeOfDay(&tv_now);
- sbuf->st_birthtime = tv_now.tv_sec + cfg.ctime_slop;
+ sbuf->st_ex_btime.tv_sec = tv_now.tv_sec +
+ cfg.ctime_slop;
}
}
- if (!static_mtime && IS_MTIME_NOW_PATH(handle->conn,&cfg,fname)) {
+ if (!static_mtime && IS_MTIME_NOW_PATH(conn,&cfg,fname)) {
if (cfg.mtime_slop < 0) {
- sbuf->st_mtime = INT_MAX - 1;
+ sbuf->st_ex_mtime.tv_sec = INT_MAX - 1;
} else {
if (tv_now.tv_sec == 0)
GetTimeOfDay(&tv_now);
- sbuf->st_mtime = tv_now.tv_sec + cfg.mtime_slop;
+ sbuf->st_ex_mtime.tv_sec = tv_now.tv_sec +
+ cfg.mtime_slop;
}
}
- if (!static_atime && IS_ATIME_NOW_PATH(handle->conn,&cfg,fname)) {
+ if (!static_atime && IS_ATIME_NOW_PATH(conn,&cfg,fname)) {
if (cfg.atime_slop < 0) {
- sbuf->st_atime = INT_MAX - 1;
+ sbuf->st_ex_atime.tv_sec = INT_MAX - 1;
} else {
if (tv_now.tv_sec == 0)
GetTimeOfDay(&tv_now);
- sbuf->st_atime = tv_now.tv_sec + cfg.atime_slop;
+ sbuf->st_ex_atime.tv_sec = tv_now.tv_sec +
+ cfg.atime_slop;
}
}
}
-static int stat_stream(vfs_handle_struct *handle, const char *base,
+static int stat_stream(struct connection_struct *conn, const char *base,
const char *stream, SMB_STRUCT_STAT *sbuf, int flags)
{
SMB_STRUCT_STAT base_sbuf;
int base_fd = -1, dir_fd, ret, saved_errno;
- dir_fd = get_stream_dir_fd(handle->conn, base, &base_fd);
+ dir_fd = get_stream_dir_fd(conn, base, &base_fd);
if (dir_fd < 0) {
return -1;
}
/* Stat the stream. */
- ret = enc_fstatat(dir_fd, stream, ENC_DEFAULT, sbuf, flags);
+ ret = onefs_sys_fstat_at(dir_fd, stream, sbuf, flags);
if (ret != -1) {
/* Now stat the base file and merge the results. */
- ret = sys_fstat(base_fd, &base_sbuf);
+ ret = onefs_sys_fstat(base_fd, &base_sbuf);
if (ret != -1) {
merge_stat(sbuf, &base_sbuf);
}
@@ -322,15 +325,15 @@ int onefs_stat(vfs_handle_struct *handle, const char *path,
return ret;
if (!is_stream) {
- ret = SMB_VFS_NEXT_STAT(handle, path, sbuf);
+ ret = onefs_sys_stat(path, sbuf);
} else if (!stream) {
/* If it's the ::$DATA stream just stat the base file name. */
- ret = SMB_VFS_NEXT_STAT(handle, base, sbuf);
+ ret = onefs_sys_stat(base, sbuf);
} else {
- ret = stat_stream(handle, base, stream, sbuf, 0);
+ ret = stat_stream(handle->conn, base, stream, sbuf, 0);
}
- onefs_adjust_stat_time(handle, path, sbuf);
+ onefs_adjust_stat_time(handle->conn, path, sbuf);
return ret;
}
@@ -341,20 +344,20 @@ int onefs_fstat(vfs_handle_struct *handle, struct files_struct *fsp,
int ret;
/* Stat the stream, by calling next_fstat on the stream's fd. */
- ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+ ret = onefs_sys_fstat(fsp->fh->fd, sbuf);
if (ret == -1) {
return ret;
}
/* Stat the base file and merge the results. */
if (fsp != NULL && fsp->base_fsp != NULL) {
- ret = sys_fstat(fsp->base_fsp->fh->fd, &base_sbuf);
+ ret = onefs_sys_fstat(fsp->base_fsp->fh->fd, &base_sbuf);
if (ret != -1) {
merge_stat(sbuf, &base_sbuf);
}
}
- onefs_adjust_stat_time(handle, fsp->fsp_name, sbuf);
+ onefs_adjust_stat_time(handle->conn, fsp->fsp_name, sbuf);
return ret;
}
@@ -371,16 +374,16 @@ int onefs_lstat(vfs_handle_struct *handle, const char *path,
return ret;
if (!is_stream) {
- ret = SMB_VFS_NEXT_LSTAT(handle, path, sbuf);
+ ret = onefs_sys_lstat(path, sbuf);
} else if (!stream) {
/* If it's the ::$DATA stream just stat the base file name. */
- ret = SMB_VFS_NEXT_LSTAT(handle, base, sbuf);
+ ret = onefs_sys_lstat(base, sbuf);
} else {
- ret = stat_stream(handle, base, stream, sbuf,
+ ret = stat_stream(handle->conn, base, stream, sbuf,
AT_SYMLINK_NOFOLLOW);
}
- onefs_adjust_stat_time(handle, path, sbuf);
+ onefs_adjust_stat_time(handle->conn, path, sbuf);
return ret;
}
@@ -614,7 +617,7 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp,
if (!add_one_stream(state->mem_ctx,
&state->num_streams, &state->streams,
- dp->d_name, stream_sbuf.st_size,
+ dp->d_name, stream_sbuf.st_ex_size,
SMB_VFS_GET_ALLOC_SIZE(conn, NULL,
&stream_sbuf))) {
state->status = NT_STATUS_NO_MEMORY;
@@ -677,10 +680,10 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
}
/* Add the default stream. */
- if (S_ISREG(sbuf.st_mode)) {
+ if (S_ISREG(sbuf.st_ex_mode)) {
if (!add_one_stream(mem_ctx,
&state.num_streams, &state.streams,
- "", sbuf.st_size,
+ "", sbuf.st_ex_size,
SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp,
&sbuf))) {
return NT_STATUS_NO_MEMORY;
@@ -692,7 +695,7 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle,
state.status = NT_STATUS_OK;
/* If there are more streams, add them too. */
- if (sbuf.st_flags & UF_HASADS) {
+ if (sbuf.st_ex_flags & UF_HASADS) {
status = walk_onefs_streams(handle->conn, fsp, fname,
&state, &sbuf);
diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c
index 3e51c6cd85..d2f853f9ee 100644
--- a/source3/modules/onefs_system.c
+++ b/source3/modules/onefs_system.c
@@ -666,3 +666,97 @@ out:
return ret;
}
+
+void init_stat_ex_from_onefs_stat(struct stat_ex *dst, const struct stat *src)
+{
+ ZERO_STRUCT(*dst);
+
+ dst->st_ex_dev = src->st_dev;
+ dst->st_ex_ino = src->st_ino;
+ dst->st_ex_mode = src->st_mode;
+ dst->st_ex_nlink = src->st_nlink;
+ dst->st_ex_uid = src->st_uid;
+ dst->st_ex_gid = src->st_gid;
+ dst->st_ex_rdev = src->st_rdev;
+ dst->st_ex_size = src->st_size;
+ dst->st_ex_atime = src->st_atimespec;
+ dst->st_ex_mtime = src->st_mtimespec;
+ dst->st_ex_ctime = src->st_ctimespec;
+ dst->st_ex_btime = src->st_birthtimespec;
+ dst->st_ex_blksize = src->st_blksize;
+ dst->st_ex_blocks = src->st_blocks;
+
+ dst->st_ex_flags = src->st_flags;
+
+ dst->vfs_private = src->st_snapid;
+}
+
+int onefs_sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf)
+{
+ int ret;
+ struct stat onefs_sbuf;
+
+ ret = stat(fname, &onefs_sbuf);
+
+ if (ret == 0) {
+ /* we always want directories to appear zero size */
+ if (S_ISDIR(onefs_sbuf.st_mode)) {
+ onefs_sbuf.st_size = 0;
+ }
+ init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
+ }
+ return ret;
+}
+
+int onefs_sys_fstat(int fd, SMB_STRUCT_STAT *sbuf)
+{
+ int ret;
+ struct stat onefs_sbuf;
+
+ ret = fstat(fd, &onefs_sbuf);
+
+ if (ret == 0) {
+ /* we always want directories to appear zero size */
+ if (S_ISDIR(onefs_sbuf.st_mode)) {
+ onefs_sbuf.st_size = 0;
+ }
+ init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
+ }
+ return ret;
+}
+
+int onefs_sys_fstat_at(int base_fd, const char *fname, SMB_STRUCT_STAT *sbuf,
+ int flags)
+{
+ int ret;
+ struct stat onefs_sbuf;
+
+ ret = enc_fstatat(base_fd, fname, ENC_DEFAULT, &onefs_sbuf, flags);
+
+ if (ret == 0) {
+ /* we always want directories to appear zero size */
+ if (S_ISDIR(onefs_sbuf.st_mode)) {
+ onefs_sbuf.st_size = 0;
+ }
+ init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
+ }
+ return ret;
+}
+
+int onefs_sys_lstat(const char *fname, SMB_STRUCT_STAT *sbuf)
+{
+ int ret;
+ struct stat onefs_sbuf;
+
+ ret = lstat(fname, &onefs_sbuf);
+
+ if (ret == 0) {
+ /* we always want directories to appear zero size */
+ if (S_ISDIR(onefs_sbuf.st_mode)) {
+ onefs_sbuf.st_size = 0;
+ }
+ init_stat_ex_from_onefs_stat(sbuf, &onefs_sbuf);
+ }
+ return ret;
+}
+
diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c
index e4a0febbec..7414f16cf9 100644
--- a/source3/modules/vfs_onefs.c
+++ b/source3/modules/vfs_onefs.c
@@ -88,7 +88,7 @@ static uint64_t onefs_get_alloc_size(struct vfs_handle_struct *handle,
START_PROFILE(syscall_get_alloc_size);
- if(S_ISDIR(sbuf->st_mode)) {
+ if(S_ISDIR(sbuf->st_ex_mode)) {
result = 0;
goto out;
}
@@ -115,9 +115,9 @@ static struct file_id onefs_file_id_create(struct vfs_handle_struct *handle,
* blob */
ZERO_STRUCT(key);
- key.devid = sbuf->st_dev;
- key.inode = sbuf->st_ino;
- key.extid = sbuf->st_snapid;
+ key.devid = sbuf->st_ex_dev;
+ key.inode = sbuf->st_ex_ino;
+ key.extid = sbuf->vfs_private;
return key;
}
@@ -152,7 +152,7 @@ static int onefs_get_real_filename(vfs_handle_struct *handle, const char *path,
const char *name, TALLOC_CTX *mem_ctx,
char **found_name)
{
- SMB_STRUCT_STAT sb;
+ struct stat sb;
struct connection_struct *conn = handle->conn;
struct stat_extra se;
int result;
@@ -278,11 +278,11 @@ static vfs_op_tuple onefs_ops[] = {
{SMB_VFS_OP(onefs_rename), SMB_VFS_OP_RENAME,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(onefs_stat), SMB_VFS_OP_STAT,
- SMB_VFS_LAYER_TRANSPARENT},
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_fstat), SMB_VFS_OP_FSTAT,
- SMB_VFS_LAYER_TRANSPARENT},
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_lstat), SMB_VFS_OP_LSTAT,
- SMB_VFS_LAYER_TRANSPARENT},
+ SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(onefs_unlink), SMB_VFS_OP_UNLINK,
diff --git a/source3/pam_smbpass/pam_smb_passwd.c b/source3/pam_smbpass/pam_smb_passwd.c
index 9504e4d53c..0563af383c 100644
--- a/source3/pam_smbpass/pam_smb_passwd.c
+++ b/source3/pam_smbpass/pam_smb_passwd.c
@@ -45,7 +45,7 @@
#include "support.h"
-int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user, const char *pass_new )
+static int smb_update_db( pam_handle_t *pamh, int ctrl, const char *user, const char *pass_new )
{
int retval;
char *err_str = NULL;
diff --git a/source3/pam_smbpass/support.c b/source3/pam_smbpass/support.c
index 855885a6d7..98dda4e8cc 100644
--- a/source3/pam_smbpass/support.c
+++ b/source3/pam_smbpass/support.c
@@ -21,7 +21,21 @@
#include "support.h"
#include "../libcli/auth/libcli_auth.h"
+#if defined(HAVE_SECURITY_PAM_EXT_H)
+#include <security/pam_ext.h>
+#elif defined(HAVE_PAM_PAM_EXT_H)
+#include <pam/pam_ext.h>
+#endif
+
+#if defined(HAVE_SECURITY__PAM_MACROS_H)
+#include <security/_pam_macros.h>
+#elif defined(HAVE_PAM__PAM_MACROS_H)
+#include <pam/_pam_macros.h>
+#endif
+#ifdef HAVE_SYSLOG_H
+#include <syslog.h>
+#endif
#define _pam_overwrite(x) \
do { \
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 57fdb6e044..7e4371bf0b 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -9775,3 +9775,8 @@ const char *lp_socket_address(void)
}
return Globals.szSocketAddress;
}
+
+void lp_set_passdb_backend(const char *backend)
+{
+ string_set(&Globals.szPassdbBackend, backend);
+}
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 6aab5e377c..51190e0bc2 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -627,7 +627,14 @@ bool lookup_global_sam_name(const char *name, int flags, uint32_t *rid,
}
/*************************************************************
- Change a password entry in the local smbpasswd file.
+ Change a password entry in the local passdb backend.
+
+ Assumptions:
+ - always called as root
+ - ignores the account type except when adding a new account
+ - will create/delete the unix account if the relative
+ add/delete user script is configured
+
*************************************************************/
NTSTATUS local_password_change(const char *user_name,
@@ -636,133 +643,135 @@ NTSTATUS local_password_change(const char *user_name,
char **pp_err_str,
char **pp_msg_str)
{
- struct samu *sam_pass=NULL;
- uint32 other_acb;
+ TALLOC_CTX *tosctx;
+ struct samu *sam_pass;
+ uint32_t acb;
+ uint32_t rid;
NTSTATUS result;
+ bool user_exists;
+ int ret = -1;
*pp_err_str = NULL;
*pp_msg_str = NULL;
- /* Get the smb passwd entry for this user */
-
- if ( !(sam_pass = samu_new( NULL )) ) {
+ tosctx = talloc_tos();
+ if (!tosctx) {
return NT_STATUS_NO_MEMORY;
}
- become_root();
- if(!pdb_getsampwnam(sam_pass, user_name)) {
- unbecome_root();
- TALLOC_FREE(sam_pass);
-
- if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
- int tmp_debug = DEBUGLEVEL;
- struct passwd *pwd;
-
- /* Might not exist in /etc/passwd. */
-
- if (tmp_debug < 1) {
- DEBUGLEVEL = 1;
- }
+ sam_pass = samu_new(tosctx);
+ if (!sam_pass) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
- if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), user_name)) ) {
- return NT_STATUS_NO_SUCH_USER;
+ /* Get the smb passwd entry for this user */
+ user_exists = pdb_getsampwnam(sam_pass, user_name);
+
+ /* Check delete first, we don't need to do anything else if we
+ * are going to delete the acocunt */
+ if (user_exists && (local_flags & LOCAL_DELETE_USER)) {
+
+ result = pdb_delete_user(tosctx, sam_pass);
+ if (!NT_STATUS_IS_OK(result)) {
+ ret = asprintf(pp_err_str,
+ "Failed to delete entry for user %s.\n",
+ user_name);
+ if (ret < 0) {
+ *pp_err_str = NULL;
}
-
- /* create the struct samu and initialize the basic Unix properties */
-
- if ( !(sam_pass = samu_new( NULL )) ) {
- return NT_STATUS_NO_MEMORY;
+ result = NT_STATUS_UNSUCCESSFUL;
+ } else {
+ ret = asprintf(pp_msg_str,
+ "Deleted user %s.\n",
+ user_name);
+ if (ret < 0) {
+ *pp_msg_str = NULL;
}
+ }
+ goto done;
+ }
- result = samu_set_unix( sam_pass, pwd );
-
- DEBUGLEVEL = tmp_debug;
+ if (user_exists && (local_flags & LOCAL_ADD_USER)) {
+ /* the entry already existed */
+ local_flags &= ~LOCAL_ADD_USER;
+ }
- TALLOC_FREE( pwd );
+ if (!user_exists && !(local_flags & LOCAL_ADD_USER)) {
+ ret = asprintf(pp_err_str,
+ "Failed to find entry for user %s.\n",
+ user_name);
+ if (ret < 0) {
+ *pp_err_str = NULL;
+ }
+ result = NT_STATUS_NO_SUCH_USER;
+ goto done;
+ }
- if (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PRIMARY_GROUP)) {
- return result;
- }
+ /* First thing add the new user if we are required to do so */
+ if (local_flags & LOCAL_ADD_USER) {
- if (!NT_STATUS_IS_OK(result)) {
- if (asprintf(pp_err_str, "Failed to " "initialize account for user %s: %s\n",
- user_name, nt_errstr(result)) < 0) {
- *pp_err_str = NULL;
- }
- return result;
- }
+ if (local_flags & LOCAL_TRUST_ACCOUNT) {
+ acb = ACB_WSTRUST;
+ } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
+ acb = ACB_DOMTRUST;
} else {
- if (asprintf(pp_err_str, "Failed to find entry for user %s.\n", user_name) < 0) {
- *pp_err_str = NULL;
- }
- return NT_STATUS_NO_SUCH_USER;
+ acb = ACB_NORMAL;
}
- } else {
- unbecome_root();
- /* the entry already existed */
- local_flags &= ~LOCAL_ADD_USER;
- }
- /* the 'other' acb bits not being changed here */
- other_acb = (pdb_get_acct_ctrl(sam_pass) & (~(ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST|ACB_NORMAL)));
- if (local_flags & LOCAL_TRUST_ACCOUNT) {
- if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST | other_acb, PDB_CHANGED) ) {
- if (asprintf(pp_err_str, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name) < 0) {
+ result = pdb_create_user(tosctx, user_name, acb, &rid);
+ if (!NT_STATUS_IS_OK(result)) {
+ ret = asprintf(pp_err_str,
+ "Failed to add entry for user %s.\n",
+ user_name);
+ if (ret < 0) {
*pp_err_str = NULL;
}
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- } else if (local_flags & LOCAL_INTERDOM_ACCOUNT) {
- if (!pdb_set_acct_ctrl(sam_pass, ACB_DOMTRUST | other_acb, PDB_CHANGED)) {
- if (asprintf(pp_err_str, "Failed to set 'domain trust account' flags for user %s.\n", user_name) < 0) {
- *pp_err_str = NULL;
- }
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
+
+ sam_pass = samu_new(tosctx);
+ if (!sam_pass) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
}
- } else {
- if (!pdb_set_acct_ctrl(sam_pass, ACB_NORMAL | other_acb, PDB_CHANGED)) {
- if (asprintf(pp_err_str, "Failed to set 'normal account' flags for user %s.\n", user_name) < 0) {
+
+ /* Now get back the smb passwd entry for this new user */
+ user_exists = pdb_getsampwnam(sam_pass, user_name);
+ if (!user_exists) {
+ ret = asprintf(pp_err_str,
+ "Failed to add entry for user %s.\n",
+ user_name);
+ if (ret < 0) {
*pp_err_str = NULL;
}
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
}
+ acb = pdb_get_acct_ctrl(sam_pass);
+
/*
* We are root - just write the new password
* and the valid last change time.
*/
-
- if (local_flags & LOCAL_DISABLE_USER) {
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_DISABLED, PDB_CHANGED)) {
- if (asprintf(pp_err_str, "Failed to set 'disabled' flag for user %s.\n", user_name) < 0) {
- *pp_err_str = NULL;
- }
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
- } else if (local_flags & LOCAL_ENABLE_USER) {
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
- if (asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name) < 0) {
+ if ((local_flags & LOCAL_SET_NO_PASSWORD) && !(acb & ACB_PWNOTREQ)) {
+ acb |= ACB_PWNOTREQ;
+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
+ ret = asprintf(pp_err_str,
+ "Failed to set 'no password required' "
+ "flag for user %s.\n", user_name);
+ if (ret < 0) {
*pp_err_str = NULL;
}
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
}
- if (local_flags & LOCAL_SET_NO_PASSWORD) {
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)|ACB_PWNOTREQ, PDB_CHANGED)) {
- if (asprintf(pp_err_str, "Failed to set 'no password required' flag for user %s.\n", user_name) < 0) {
- *pp_err_str = NULL;
- }
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
- } else if (local_flags & LOCAL_SET_PASSWORD) {
+ if (local_flags & LOCAL_SET_PASSWORD) {
/*
* If we're dealing with setting a completely empty user account
* ie. One with a password of 'XXXX', but not set disabled (like
@@ -772,83 +781,106 @@ NTSTATUS local_password_change(const char *user_name,
* and the decision hasn't really been made to disable them (ie.
* don't create them disabled). JRA.
*/
- if ((pdb_get_lanman_passwd(sam_pass)==NULL) && (pdb_get_acct_ctrl(sam_pass)&ACB_DISABLED)) {
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_DISABLED), PDB_CHANGED)) {
- if (asprintf(pp_err_str, "Failed to unset 'disabled' flag for user %s.\n", user_name) < 0) {
+ if ((pdb_get_lanman_passwd(sam_pass) == NULL) &&
+ (acb & ACB_DISABLED)) {
+ acb &= (~ACB_DISABLED);
+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
+ ret = asprintf(pp_err_str,
+ "Failed to unset 'disabled' "
+ "flag for user %s.\n",
+ user_name);
+ if (ret < 0) {
*pp_err_str = NULL;
}
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
- }
- if (!pdb_set_acct_ctrl (sam_pass, pdb_get_acct_ctrl(sam_pass)&(~ACB_PWNOTREQ), PDB_CHANGED)) {
- if (asprintf(pp_err_str, "Failed to unset 'no password required' flag for user %s.\n", user_name) < 0) {
- *pp_err_str = NULL;
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
}
- if (!pdb_set_plaintext_passwd (sam_pass, new_passwd)) {
- if (asprintf(pp_err_str, "Failed to set password for user %s.\n", user_name) < 0) {
+ acb &= (~ACB_PWNOTREQ);
+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
+ ret = asprintf(pp_err_str,
+ "Failed to unset 'no password required'"
+ " flag for user %s.\n", user_name);
+ if (ret < 0) {
*pp_err_str = NULL;
}
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- }
- if (local_flags & LOCAL_ADD_USER) {
- if (NT_STATUS_IS_OK(pdb_add_sam_account(sam_pass))) {
- if (asprintf(pp_msg_str, "Added user %s.\n", user_name) < 0) {
- *pp_msg_str = NULL;
- }
- TALLOC_FREE(sam_pass);
- return NT_STATUS_OK;
- } else {
- if (asprintf(pp_err_str, "Failed to add entry for user %s.\n", user_name) < 0) {
+ if (!pdb_set_plaintext_passwd(sam_pass, new_passwd)) {
+ ret = asprintf(pp_err_str,
+ "Failed to set password for "
+ "user %s.\n", user_name);
+ if (ret < 0) {
*pp_err_str = NULL;
}
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- } else if (local_flags & LOCAL_DELETE_USER) {
- if (!NT_STATUS_IS_OK(pdb_delete_sam_account(sam_pass))) {
- if (asprintf(pp_err_str, "Failed to delete entry for user %s.\n", user_name) < 0) {
+ }
+
+ if ((local_flags & LOCAL_DISABLE_USER) && !(acb & ACB_DISABLED)) {
+ acb |= ACB_DISABLED;
+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
+ ret = asprintf(pp_err_str,
+ "Failed to set 'disabled' flag for "
+ "user %s.\n", user_name);
+ if (ret < 0) {
*pp_err_str = NULL;
}
- TALLOC_FREE(sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
- if (asprintf(pp_msg_str, "Deleted user %s.\n", user_name) < 0) {
- *pp_msg_str = NULL;
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- } else {
- result = pdb_update_sam_account(sam_pass);
- if(!NT_STATUS_IS_OK(result)) {
- if (asprintf(pp_err_str, "Failed to modify entry for user %s.\n", user_name) < 0) {
+ }
+
+ if ((local_flags & LOCAL_ENABLE_USER) && (acb & ACB_DISABLED)) {
+ acb &= (~ACB_DISABLED);
+ if (!pdb_set_acct_ctrl(sam_pass, acb, PDB_CHANGED)) {
+ ret = asprintf(pp_err_str,
+ "Failed to unset 'disabled' flag for "
+ "user %s.\n", user_name);
+ if (ret < 0) {
*pp_err_str = NULL;
}
- TALLOC_FREE(sam_pass);
- return result;
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
- if(local_flags & LOCAL_DISABLE_USER) {
- if (asprintf(pp_msg_str, "Disabled user %s.\n", user_name) < 0) {
- *pp_msg_str = NULL;
- }
- } else if (local_flags & LOCAL_ENABLE_USER) {
- if (asprintf(pp_msg_str, "Enabled user %s.\n", user_name) < 0) {
- *pp_msg_str = NULL;
- }
- } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
- if (asprintf(pp_msg_str, "User %s password set to none.\n", user_name) < 0) {
- *pp_msg_str = NULL;
- }
+ }
+
+ /* now commit changes if any */
+ result = pdb_update_sam_account(sam_pass);
+ if (!NT_STATUS_IS_OK(result)) {
+ ret = asprintf(pp_err_str,
+ "Failed to modify entry for user %s.\n",
+ user_name);
+ if (ret < 0) {
+ *pp_err_str = NULL;
}
+ goto done;
+ }
+
+ if (local_flags & LOCAL_ADD_USER) {
+ ret = asprintf(pp_msg_str, "Added user %s.\n", user_name);
+ } else if (local_flags & LOCAL_DISABLE_USER) {
+ ret = asprintf(pp_msg_str, "Disabled user %s.\n", user_name);
+ } else if (local_flags & LOCAL_ENABLE_USER) {
+ ret = asprintf(pp_msg_str, "Enabled user %s.\n", user_name);
+ } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
+ ret = asprintf(pp_msg_str,
+ "User %s password set to none.\n", user_name);
}
+ if (ret < 0) {
+ *pp_msg_str = NULL;
+ }
+
+ result = NT_STATUS_OK;
+
+done:
TALLOC_FREE(sam_pass);
- return NT_STATUS_OK;
+ return result;
}
/**********************************************************************
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index b4e1bd436c..b69e41590f 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -1330,26 +1330,6 @@ static bool pdb_default_sid_to_id(struct pdb_methods *methods,
return ret;
}
-static bool add_uid_to_array_unique(TALLOC_CTX *mem_ctx,
- uid_t uid, uid_t **pp_uids, size_t *p_num)
-{
- size_t i;
-
- for (i=0; i<*p_num; i++) {
- if ((*pp_uids)[i] == uid)
- return True;
- }
-
- *pp_uids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_uids, uid_t, *p_num+1);
-
- if (*pp_uids == NULL)
- return False;
-
- (*pp_uids)[*p_num] = uid;
- *p_num += 1;
- return True;
-}
-
static bool get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size_t *p_num)
{
struct group *grp;
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index c853258a34..0bebcc7c2c 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -7,20 +7,20 @@
Copyright (C) Andrew Bartlett 2002-2003
Copyright (C) Stefan (metze) Metzmacher 2002-2003
Copyright (C) Simo Sorce 2006
-
+
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/>.
-
+
*/
/* TODO:
@@ -98,10 +98,10 @@ static const char* get_userattr_key2string( int schema_ver, int key )
switch ( schema_ver ) {
case SCHEMAVER_SAMBAACCOUNT:
return get_attr_key2string( attrib_map_v22, key );
-
+
case SCHEMAVER_SAMBASAMACCOUNT:
return get_attr_key2string( attrib_map_v30, key );
-
+
default:
DEBUG(0,("get_userattr_key2string: unknown schema version specified\n"));
break;
@@ -118,14 +118,14 @@ const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver )
switch ( schema_ver ) {
case SCHEMAVER_SAMBAACCOUNT:
return get_attr_list( mem_ctx, attrib_map_v22 );
-
+
case SCHEMAVER_SAMBASAMACCOUNT:
return get_attr_list( mem_ctx, attrib_map_v30 );
default:
DEBUG(0,("get_userattr_list: unknown schema version specified!\n"));
break;
}
-
+
return NULL;
}
@@ -140,7 +140,7 @@ static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx,
case SCHEMAVER_SAMBAACCOUNT:
return get_attr_list( mem_ctx,
attrib_map_to_delete_v22 );
-
+
case SCHEMAVER_SAMBASAMACCOUNT:
return get_attr_list( mem_ctx,
attrib_map_to_delete_v30 );
@@ -148,7 +148,7 @@ static const char** get_userattr_delete_list( TALLOC_CTX *mem_ctx,
DEBUG(0,("get_userattr_delete_list: unknown schema version specified!\n"));
break;
}
-
+
return NULL;
}
@@ -162,7 +162,7 @@ static const char* get_objclass_filter( int schema_ver )
{
fstring objclass_filter;
char *result;
-
+
switch( schema_ver ) {
case SCHEMAVER_SAMBAACCOUNT:
fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
@@ -175,7 +175,7 @@ static const char* get_objclass_filter( int schema_ver )
objclass_filter[0] = '\0';
break;
}
-
+
result = talloc_strdup(talloc_tos(), objclass_filter);
SMB_ASSERT(result != NULL);
return result;
@@ -448,7 +448,7 @@ static int ldapsam_delete_entry(struct ldapsam_privates *priv,
}
/* Ok, delete only the SAM attributes */
-
+
for (name = ldap_first_attribute(priv2ld(priv), entry, &ptr);
name != NULL;
name = ldap_next_attribute(priv2ld(priv), entry, ptr)) {
@@ -1501,7 +1501,7 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu
int count;
const char ** attr_list;
int rc;
-
+
attr_list = get_userattr_list( user, ldap_state->schema_ver );
append_attr(user, &attr_list,
get_userattr_key2string(ldap_state->schema_ver,
@@ -1513,9 +1513,9 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, struct samu
if ( rc != LDAP_SUCCESS )
return NT_STATUS_NO_SUCH_USER;
-
+
count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
+
if (count < 1) {
DEBUG(4, ("ldapsam_getsampwnam: Unable to locate user [%s] count=%d\n", sname, count));
ldap_msgfree(result);
@@ -1572,12 +1572,12 @@ static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
return rc;
break;
}
-
+
case SCHEMAVER_SAMBAACCOUNT:
if (!sid_peek_check_rid(&ldap_state->domain_sid, sid, &rid)) {
return rc;
}
-
+
attr_list = get_userattr_list(NULL,
ldap_state->schema_ver);
rc = ldapsam_search_suffix_by_rid(ldap_state, rid, result, attr_list );
@@ -1608,7 +1608,7 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, struct samu
return NT_STATUS_NO_SUCH_USER;
count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
-
+
if (count < 1) {
DEBUG(4, ("ldapsam_getsampwsid: Unable to locate SID [%s] "
"count=%d\n", sid_string_dbg(sid), count));
@@ -1652,11 +1652,11 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
{
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
int rc;
-
+
if (!newpwd || !dn) {
return NT_STATUS_INVALID_PARAMETER;
}
-
+
if (!mods) {
DEBUG(5,("ldapsam_modify_entry: mods is empty: nothing to modify\n"));
/* may be password change below however */
@@ -1684,12 +1684,12 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
ldap_op));
return NT_STATUS_INVALID_PARAMETER;
}
-
+
if (rc!=LDAP_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
}
}
-
+
if (!(pdb_get_acct_ctrl(newpwd)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)) &&
(lp_ldap_passwd_sync() != LDAP_PASSWD_SYNC_OFF) &&
need_update(newpwd, PDB_PLAINTEXT_PW) &&
@@ -1749,7 +1749,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
TALLOC_FREE(utf8_password);
return NT_STATUS_UNSUCCESSFUL;
}
-
+
TALLOC_FREE(utf8_dn);
TALLOC_FREE(utf8_password);
ber_free(ber, 1);
@@ -1846,7 +1846,7 @@ static NTSTATUS ldapsam_delete_sam_account(struct pdb_methods *my_methods,
result = NT_STATUS_NO_SUCH_USER;
goto done;
}
-
+
rc = ldapsam_delete_entry(
priv, mem_ctx, entry,
priv->schema_ver == SCHEMAVER_SAMBASAMACCOUNT ?
@@ -1932,7 +1932,7 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, struc
TALLOC_FREE(dn);
return NT_STATUS_OK;
}
-
+
ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
if (mods != NULL) {
@@ -2670,7 +2670,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
ret = NT_STATUS_NO_MEMORY;
goto done;
}
-
+
filter = talloc_asprintf_append_buffer(filter, "(uid=%s)", escape_memberuid);
if (filter == NULL) {
SAFE_FREE(escape_memberuid);
@@ -2775,7 +2775,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
}
ret = NT_STATUS_OK;
-
+
done:
if (values)
@@ -3268,7 +3268,7 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
rc = ldapsam_delete_entry(priv, mem_ctx, entry, LDAP_OBJ_GROUPMAP,
get_attr_list(mem_ctx,
groupmap_attr_list_to_delete));
-
+
if ((rc == LDAP_NAMING_VIOLATION) ||
(rc == LDAP_NOT_ALLOWED_ON_RDN) ||
(rc == LDAP_OBJECT_CLASS_VIOLATION)) {
@@ -3376,11 +3376,11 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
while (!bret) {
if (!ldap_state->entry)
return ret;
-
+
ldap_state->index++;
bret = init_group_from_ldap(ldap_state, map,
ldap_state->entry);
-
+
ldap_state->entry =
ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
ldap_state->entry);
@@ -3874,7 +3874,7 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods
}
*value = (uint32)atol(vals[0]);
-
+
ntstatus = NT_STATUS_OK;
out:
@@ -3889,7 +3889,7 @@ out:
- if user hasn't decided to use account policies inside LDAP just reuse the
old tdb values
-
+
- if there is a valid cache entry, return that
- if there is an LDAP entry, update cache and return
- otherwise set to default, update cache and return
@@ -3928,16 +3928,16 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods,
if (!account_policy_get_default(policy_index, value)) {
return ntstatus;
}
-
+
/* update_ldap: */
-
+
ntstatus = ldapsam_set_account_policy(methods, policy_index, *value);
if (!NT_STATUS_IS_OK(ntstatus)) {
return ntstatus;
}
-
+
update_cache:
-
+
if (!cache_account_policy_set(policy_index, *value)) {
DEBUG(0,("ldapsam_get_account_policy: failed to update local "
"tdb as a cache\n"));
@@ -4467,7 +4467,7 @@ static bool ldapuser2displayentry(struct ldap_search_state *state,
DEBUG(0, ("talloc failed\n"));
return False;
}
-
+
vals = ldap_get_values(ld, entry, "sambaSid");
if ((vals == NULL) || (vals[0] == NULL)) {
DEBUG(0, ("\"objectSid\" not found\n"));
@@ -4623,7 +4623,7 @@ static bool ldapgroup2displayentry(struct ldap_search_state *state,
DEBUG(0, ("talloc failed\n"));
return False;
}
-
+
vals = ldap_get_values(ld, entry, "sambaSid");
if ((vals == NULL) || (vals[0] == NULL)) {
DEBUG(0, ("\"objectSid\" not found\n"));
@@ -4652,7 +4652,7 @@ static bool ldapgroup2displayentry(struct ldap_search_state *state,
return False;
}
break;
-
+
default:
DEBUG(0,("unkown group type: %d\n", group_type));
return False;
@@ -4980,7 +4980,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
uid_t uid = -1;
NTSTATUS ret;
int rc;
-
+
if (((acb_info & ACB_NORMAL) && name[strlen(name)-1] == '$') ||
acb_info & ACB_WSTRUST ||
acb_info & ACB_SVRTRUST ||
@@ -5006,7 +5006,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
DEBUG (0, ("ldapsam_create_user: More than one user with name [%s] ?!\n", name));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
-
+
if (num_result == 1) {
char *tmp;
/* check if it is just a posix account.
@@ -5035,7 +5035,7 @@ static NTSTATUS ldapsam_create_user(struct pdb_methods *my_methods,
if (num_result == 0) {
add_posix = True;
}
-
+
/* Create the basic samu structure and generate the mods for the ldap commit */
if (!NT_STATUS_IS_OK((ret = ldapsam_new_rid_internal(my_methods, rid)))) {
DEBUG(1, ("ldapsam_create_user: Could not allocate a new RID\n"));
@@ -5181,7 +5181,7 @@ static NTSTATUS ldapsam_delete_user(struct pdb_methods *my_methods, TALLOC_CTX *
int rc;
DEBUG(0,("ldapsam_delete_user: Attempt to delete user [%s]\n", pdb_get_username(sam_acct)));
-
+
filter = talloc_asprintf(tmp_ctx,
"(&(uid=%s)"
"(objectClass=%s)"
@@ -5263,7 +5263,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
DOM_SID group_sid;
gid_t gid = -1;
int rc;
-
+
groupname = escape_ldap_string_alloc(name);
filter = talloc_asprintf(tmp_ctx, "(&(cn=%s)(objectClass=%s))",
groupname, LDAP_OBJ_POSIXGROUP);
@@ -5282,7 +5282,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
DEBUG (0, ("ldapsam_create_group: There exists more than one group with name [%s]: bailing out!\n", name));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
-
+
if (num_result == 1) {
char *tmp;
/* check if it is just a posix group.
@@ -5306,7 +5306,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
DEBUG (1, ("ldapsam_create_group: Couldn't retrieve the gidNumber for [%s]?!?!\n", name));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
-
+
gid = strtoul(tmp, NULL, 10);
dn = smbldap_talloc_dn(tmp_ctx, priv2ld(ldap_state), entry);
@@ -5322,7 +5322,7 @@ static NTSTATUS ldapsam_create_dom_group(struct pdb_methods *my_methods,
DEBUG(3,("ldapsam_create_user: Creating new posix group\n"));
is_new_entry = True;
-
+
/* lets allocate a new groupid for this group */
if (!winbind_allocate_gid(&gid)) {
DEBUG (0, ("ldapsam_create_group: Unable to allocate a new group id: bailing out!\n"));
@@ -5519,7 +5519,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
default:
return NT_STATUS_UNSUCCESSFUL;
}
-
+
/* get member sid */
sid_compose(&member_sid, get_global_sam_sid(), member_rid);
@@ -5566,7 +5566,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
/* check if we are trying to remove the member from his primary group */
char *gidstr;
gid_t user_gid, group_gid;
-
+
gidstr = smbldap_talloc_single_attribute(priv2ld(ldap_state), entry, "gidNumber", tmp_ctx);
if (!gidstr) {
DEBUG (0, ("ldapsam_change_groupmem: Unable to find the member's gid!\n"));
@@ -5574,7 +5574,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
}
user_gid = strtoul(gidstr, NULL, 10);
-
+
if (!sid_to_gid(&group_sid, &group_gid)) {
DEBUG (0, ("ldapsam_change_groupmem: Unable to get group gid from SID!\n"));
return NT_STATUS_UNSUCCESSFUL;
@@ -5649,7 +5649,7 @@ static NTSTATUS ldapsam_change_groupmem(struct pdb_methods *my_methods,
}
return NT_STATUS_UNSUCCESSFUL;
}
-
+
return NT_STATUS_OK;
}
diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c
index d8c48058be..94e73fb54d 100644
--- a/source3/rpc_server/srv_lsa_hnd.c
+++ b/source3/rpc_server/srv_lsa_hnd.c
@@ -46,7 +46,7 @@ struct handle_list {
/* This is the max handles across all instances of a pipe name. */
#ifndef MAX_OPEN_POLS
-#define MAX_OPEN_POLS 1024
+#define MAX_OPEN_POLS 2048
#endif
/****************************************************************************
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index 333eabe2ce..7f45a4809c 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -882,6 +882,13 @@ NTSTATUS _netr_LogonSamLogon(pipes_struct *p,
return NT_STATUS_ACCESS_DENIED;
}
+ *r->out.authoritative = true; /* authoritative response */
+ if (r->in.validation_level != 2 && r->in.validation_level != 3) {
+ DEBUG(0,("%s: bad validation_level value %d.\n",
+ fn, (int)r->in.validation_level));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
sam3 = TALLOC_ZERO_P(p->mem_ctx, struct netr_SamInfo3);
if (!sam3) {
return NT_STATUS_NO_MEMORY;
@@ -889,12 +896,6 @@ NTSTATUS _netr_LogonSamLogon(pipes_struct *p,
/* store the user information, if there is any. */
r->out.validation->sam3 = sam3;
- *r->out.authoritative = true; /* authoritative response */
- if (r->in.validation_level != 2 && r->in.validation_level != 3) {
- DEBUG(0,("%s: bad validation_level value %d.\n",
- fn, (int)r->in.validation_level));
- return NT_STATUS_ACCESS_DENIED;
- }
if (process_creds) {
diff --git a/source3/samba4.m4 b/source3/samba4.m4
index 9e86f3fb1f..6b7c140bc1 100644
--- a/source3/samba4.m4
+++ b/source3/samba4.m4
@@ -128,6 +128,7 @@ SMB_INCLUDE_MK(lib/ldb/python.mk)
SMB_ENABLE(swig_ldb,YES)
m4_include(lib/tls/config.m4)
+m4_include(torture/libnetapi/config.m4)
dnl m4_include(auth/kerberos/config.m4)
m4_include(auth/gensec/config.m4)
diff --git a/source3/samba4.mk b/source3/samba4.mk
index 3f661bdd14..e63a8453c0 100644
--- a/source3/samba4.mk
+++ b/source3/samba4.mk
@@ -74,6 +74,7 @@ clustersrcdir := $(samba4srcdir)/cluster
libnetsrcdir := $(samba4srcdir)/libnet
authsrcdir := $(samba4srcdir)/auth
nsswitchsrcdir := $(samba4srcdir)/../nsswitch
+libwbclientsrcdir := $(nsswitchsrcdir)/libwbclient
libsrcdir := $(samba4srcdir)/lib
libsocketsrcdir := $(samba4srcdir)/lib/socket
libcharsetsrcdir := $(samba4srcdir)/../lib/util/charset
diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh
index 956c5af77b..e3871132d2 100755
--- a/source3/script/tests/selftest.sh
+++ b/source3/script/tests/selftest.sh
@@ -289,6 +289,7 @@ EOF
cat >$NSS_WRAPPER_GROUP<<EOF
nobody:x:65533:
nogroup:x:65534:nobody
+root:x:65532:
$USERNAME-group:x:$GROUPID:
EOF
diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh
index 0bcf3695ed..83593dde4d 100755
--- a/source3/script/tests/test_posix_s3.sh
+++ b/source3/script/tests/test_posix_s3.sh
@@ -45,12 +45,14 @@ rpc="$rpc RPC-LSA-GETUSER RPC-LSA-LOOKUPSIDS RPC-LSA-LOOKUPNAMES"
rpc="$rpc RPC-SAMR-USERS RPC-SAMR-USERS-PRIVILEGES RPC-SAMR-PASSWORDS RPC-SAMR-PASSWORDS-PWDLASTSET RPC-SAMR-LARGE-DC RPC-JOIN"
rpc="$rpc RPC-SCHANNEL RPC-SCHANNEL2 RPC-BENCH-SCHANNEL1"
+local="LOCAL-NSS-WRAPPER"
+
# NOTE: to enable the UNIX-WHOAMI test, we need to change the default share
# config to allow guest access. I'm not sure whether this would break other
# tests, so leaving it alone for now -- jpeach
unix="UNIX-INFO2"
-tests="$base $raw $rpc $unix"
+tests="$base $raw $rpc $unix $local"
if test "x$POSIX_SUBTESTS" != "x" ; then
tests="$POSIX_SUBTESTS"
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 6468544748..eeed76329c 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -379,7 +379,7 @@ int dos_attributes_to_stat_dos_flags(uint32_t dosmode)
}
/****************************************************************************
- Gets DOS attributes, accessed via st_flags in the stat struct.
+ Gets DOS attributes, accessed via st_ex_flags in the stat struct.
****************************************************************************/
static bool get_stat_dos_flags(connection_struct *conn,
@@ -396,15 +396,15 @@ static bool get_stat_dos_flags(connection_struct *conn,
DEBUG(5, ("Getting stat dos attributes for %s.\n", fname));
- if (sbuf->st_flags & UF_DOS_ARCHIVE)
+ if (sbuf->st_ex_flags & UF_DOS_ARCHIVE)
*dosmode |= aARCH;
- if (sbuf->st_flags & UF_DOS_HIDDEN)
+ if (sbuf->st_ex_flags & UF_DOS_HIDDEN)
*dosmode |= aHIDDEN;
- if (sbuf->st_flags & UF_DOS_RO)
+ if (sbuf->st_ex_flags & UF_DOS_RO)
*dosmode |= aRONLY;
- if (sbuf->st_flags & UF_DOS_SYSTEM)
+ if (sbuf->st_ex_flags & UF_DOS_SYSTEM)
*dosmode |= aSYSTEM;
- if (sbuf->st_flags & UF_DOS_NOINDEX)
+ if (sbuf->st_ex_flags & UF_DOS_NOINDEX)
*dosmode |= FILE_ATTRIBUTE_NONINDEXED;
if (S_ISDIR(sbuf->st_ex_mode))
*dosmode |= aDIR;
@@ -416,7 +416,7 @@ static bool get_stat_dos_flags(connection_struct *conn,
}
/****************************************************************************
- Sets DOS attributes, stored in st_flags of the inode.
+ Sets DOS attributes, stored in st_ex_flags of the inode.
****************************************************************************/
static bool set_stat_dos_flags(connection_struct *conn,
@@ -439,15 +439,15 @@ static bool set_stat_dos_flags(connection_struct *conn,
DEBUG(5, ("Setting stat dos attributes for %s.\n", fname));
- new_flags = (sbuf->st_flags & ~UF_DOS_FLAGS) |
+ new_flags = (sbuf->st_ex_flags & ~UF_DOS_FLAGS) |
dos_attributes_to_stat_dos_flags(dosmode);
/* Return early if no flags changed. */
- if (new_flags == sbuf->st_flags)
+ if (new_flags == sbuf->st_ex_flags)
return true;
DEBUG(5, ("Setting stat dos attributes=0x%x, prev=0x%x\n", new_flags,
- sbuf->st_flags));
+ sbuf->st_ex_flags));
/* Set new flags with chflags. */
error = SMB_VFS_CHFLAGS(conn, fname, new_flags);
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 72b4ab7aa6..059dca29c8 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -513,8 +513,14 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
goto fail;
}
- /* ENOENT is the only valid error here. */
- if ((errno != 0) && (errno != ENOENT)) {
+ /*
+ * ENOENT/EACCESS are the only valid errors
+ * here. EACCESS needs handling here for
+ * "dropboxes", i.e. directories where users
+ * can only put stuff with permission -wx.
+ */
+ if ((errno != 0) && (errno != ENOENT)
+ && (errno != EACCES)) {
/*
* ENOTDIR and ELOOP both map to
* NT_STATUS_OBJECT_PATH_NOT_FOUND
@@ -524,8 +530,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
errno == ELOOP) {
result =
NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
- else {
+ } else {
result =
map_nt_error_from_unix(errno);
}
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index c1b29f68f3..fdfa99953f 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -346,7 +346,7 @@ static NTSTATUS open_file(files_struct *fsp,
if (!CAN_WRITE(conn)) {
/* It's a read-only share - fail if we wanted to write. */
- if(accmode != O_RDONLY) {
+ if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
DEBUG(3,("Permission denied opening %s\n", path));
return NT_STATUS_ACCESS_DENIED;
} else if(flags & O_CREAT) {
@@ -354,8 +354,8 @@ static NTSTATUS open_file(files_struct *fsp,
O_CREAT doesn't create the file if we have write
access into the directory.
*/
- flags &= ~O_CREAT;
- local_flags &= ~O_CREAT;
+ flags &= ~(O_CREAT|O_EXCL);
+ local_flags &= ~(O_CREAT|O_EXCL);
}
}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 1d95c207ba..d11bf088e0 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -6870,16 +6870,20 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
}
}
- if (!CAN_WRITE(conn)) {
- reply_doserror(req, ERRSRV, ERRaccess);
- return;
- }
-
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
reply_nterror(req, NT_STATUS_INVALID_LEVEL);
return;
}
+ if (!CAN_WRITE(conn)) {
+ /* Allow POSIX opens. The open path will deny
+ * any non-readonly opens. */
+ if (info_level != SMB_POSIX_PATH_OPEN) {
+ reply_doserror(req, ERRSRV, ERRaccess);
+ return;
+ }
+ }
+
DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index b05ca44f0e..d185a71727 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -18,7 +18,7 @@
*/
#include "includes.h"
-#include "wbc_async.h"
+#include "nsswitch/libwbclient/wbc_async.h"
extern char *optarg;
extern int optind;
@@ -3092,7 +3092,7 @@ static bool run_deletetest(int dummy)
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
correct = False;
goto fail;
@@ -3145,7 +3145,7 @@ static bool run_deletetest(int dummy)
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
correct = False;
goto fail;
@@ -3201,7 +3201,7 @@ static bool run_deletetest(int dummy)
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
correct = False;
goto fail;
@@ -3235,7 +3235,7 @@ static bool run_deletetest(int dummy)
/* This should fail - only allowed on NT opens with DELETE access. */
- if (cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
correct = False;
goto fail;
@@ -3263,7 +3263,7 @@ static bool run_deletetest(int dummy)
/* This should fail - only allowed on NT opens with DELETE access. */
- if (cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
correct = False;
goto fail;
@@ -3288,13 +3288,13 @@ static bool run_deletetest(int dummy)
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[7] setting delete_on_close on file failed !\n");
correct = False;
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
printf("[7] unsetting delete_on_close on file failed !\n");
correct = False;
goto fail;
@@ -3350,7 +3350,7 @@ static bool run_deletetest(int dummy)
goto fail;
}
- if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
printf("[8] setting delete_on_close on file failed !\n");
correct = False;
goto fail;
@@ -3639,7 +3639,7 @@ static bool run_rename(int dummy)
printf("Fourth open failed - %s\n", cli_errstr(cli1));
return False;
}
- if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
+ if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
printf("[8] setting delete_on_close on file failed !\n");
return False;
}
@@ -5985,7 +5985,7 @@ static bool run_local_wbclient(int dummy)
d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
for (i=0; i<nprocs; i++) {
- wb_ctx[i] = wb_context_init(ev);
+ wb_ctx[i] = wb_context_init(ev, NULL);
if (wb_ctx[i] == NULL) {
goto fail;
}
diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c
index 328b2cb1f4..23c4e71e0d 100644
--- a/source3/utils/pdbedit.c
+++ b/source3/utils/pdbedit.c
@@ -1,21 +1,21 @@
-/*
+/*
Unix SMB/CIFS implementation.
passdb editing frontend
-
- Copyright (C) Simo Sorce 2000
- Copyright (C) Andrew Bartlett 2001
+
+ Copyright (C) Simo Sorce 2000-2009
+ Copyright (C) Andrew Bartlett 2001
Copyright (C) Jelmer Vernooij 2002
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/>.
*/
@@ -53,13 +53,33 @@
#define MASK_ALWAYS_GOOD 0x0000001F
#define MASK_USER_GOOD 0x00405FE0
+static int get_sid_from_cli_string(DOM_SID *sid, const char *str_sid)
+{
+ uint32_t rid;
+
+ if (!string_to_sid(sid, str_sid)) {
+ /* not a complete sid, may be a RID,
+ * try building a SID */
+
+ if (sscanf(str_sid, "%u", &rid) != 1) {
+ fprintf(stderr, "Error passed string is not "
+ "a complete SID or RID!\n");
+ return -1;
+ }
+ sid_copy(sid, get_global_sam_sid());
+ sid_append_rid(sid, rid);
+ }
+
+ return 0;
+}
+
/*********************************************************
Add all currently available users to another db
********************************************************/
-static int export_database (struct pdb_methods *in,
- struct pdb_methods *out,
- const char *username)
+static int export_database (struct pdb_methods *in,
+ struct pdb_methods *out,
+ const char *username)
{
NTSTATUS status;
struct pdb_search *u_search;
@@ -148,13 +168,13 @@ static int export_database (struct pdb_methods *in,
Add all currently available group mappings to another db
********************************************************/
-static int export_groups (struct pdb_methods *in, struct pdb_methods *out)
+static int export_groups (struct pdb_methods *in, struct pdb_methods *out)
{
GROUP_MAP *maps = NULL;
size_t i, entries = 0;
NTSTATUS status;
- status = in->enum_group_mapping(in, get_global_sam_sid(),
+ status = in->enum_group_mapping(in, get_global_sam_sid(),
SID_NAME_DOM_GRP, &maps, &entries, False);
if ( NT_STATUS_IS_ERR(status) ) {
@@ -175,7 +195,7 @@ static int export_groups (struct pdb_methods *in, struct pdb_methods *out)
Reset account policies to their default values and remove marker
********************************************************/
-static int reinit_account_policies (void)
+static int reinit_account_policies (void)
{
int i;
@@ -260,31 +280,31 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst
printf ("Munged dial: %s\n", pdb_get_munged_dial(sam_pwent));
tmp = pdb_get_logon_time(sam_pwent);
- printf ("Logon time: %s\n",
+ printf ("Logon time: %s\n",
tmp ? http_timestring(talloc_tos(), tmp) : "0");
tmp = pdb_get_logoff_time(sam_pwent);
- printf ("Logoff time: %s\n",
+ printf ("Logoff time: %s\n",
tmp ? http_timestring(talloc_tos(), tmp) : "0");
tmp = pdb_get_kickoff_time(sam_pwent);
- printf ("Kickoff time: %s\n",
+ printf ("Kickoff time: %s\n",
tmp ? http_timestring(talloc_tos(), tmp) : "0");
tmp = pdb_get_pass_last_set_time(sam_pwent);
- printf ("Password last set: %s\n",
+ printf ("Password last set: %s\n",
tmp ? http_timestring(talloc_tos(), tmp) : "0");
tmp = pdb_get_pass_can_change_time(sam_pwent);
- printf ("Password can change: %s\n",
+ printf ("Password can change: %s\n",
tmp ? http_timestring(talloc_tos(), tmp) : "0");
tmp = pdb_get_pass_must_change_time(sam_pwent);
- printf ("Password must change: %s\n",
+ printf ("Password must change: %s\n",
tmp ? http_timestring(talloc_tos(), tmp) : "0");
tmp = pdb_get_bad_password_time(sam_pwent);
- printf ("Last bad password : %s\n",
+ printf ("Last bad password : %s\n",
tmp ? http_timestring(talloc_tos(), tmp) : "0");
printf ("Bad password count : %d\n",
pdb_get_bad_password_count(sam_pwent));
@@ -310,7 +330,7 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst
(uint32)convert_time_t_to_uint32(pdb_get_pass_last_set_time(sam_pwent)));
} else {
uid = nametouid(pdb_get_username(sam_pwent));
- printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid,
+ printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid,
pdb_get_fullname(sam_pwent));
}
@@ -321,167 +341,186 @@ static int print_sam_info (struct samu *sam_pwent, bool verbosity, bool smbpwdst
Get an Print User Info
**********************************************************/
-static int print_user_info (struct pdb_methods *in, const char *username, bool verbosity, bool smbpwdstyle)
+static int print_user_info(const char *username,
+ bool verbosity, bool smbpwdstyle)
{
- struct samu *sam_pwent=NULL;
- bool ret;
+ struct samu *sam_pwent = NULL;
+ bool bret;
+ int ret;
- if ( (sam_pwent = samu_new( NULL )) == NULL ) {
+ sam_pwent = samu_new(NULL);
+ if (!sam_pwent) {
return -1;
}
- ret = NT_STATUS_IS_OK(in->getsampwnam (in, sam_pwent, username));
-
- if (ret==False) {
+ bret = pdb_getsampwnam(sam_pwent, username);
+ if (!bret) {
fprintf (stderr, "Username not found!\n");
TALLOC_FREE(sam_pwent);
return -1;
}
- ret=print_sam_info (sam_pwent, verbosity, smbpwdstyle);
+ ret = print_sam_info(sam_pwent, verbosity, smbpwdstyle);
+
TALLOC_FREE(sam_pwent);
-
return ret;
}
-
+
/*********************************************************
List Users
**********************************************************/
-static int print_users_list (struct pdb_methods *in, bool verbosity, bool smbpwdstyle)
+static int print_users_list(bool verbosity, bool smbpwdstyle)
{
struct pdb_search *u_search;
struct samr_displayentry userentry;
-
- u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH);
- if (u_search == NULL) {
- DEBUG(0, ("pdb_search_init failed\n"));
+ struct samu *sam_pwent;
+ TALLOC_CTX *tosctx;
+ DOM_SID user_sid;
+ bool bret;
+ int ret;
+
+ tosctx = talloc_tos();
+ if (!tosctx) {
+ DEBUG(0, ("talloc failed\n"));
return 1;
}
- if (!in->search_users(in, u_search, 0)) {
- DEBUG(0, ("Could not start searching users\n"));
- TALLOC_FREE(u_search);
- return 1;
+ u_search = pdb_search_users(tosctx, 0);
+ if (!u_search) {
+ DEBUG(0, ("User Search failed!\n"));
+ ret = 1;
+ goto done;
}
while (u_search->next_entry(u_search, &userentry)) {
- struct samu *sam_pwent;
- DOM_SID user_sid;
- NTSTATUS status;
- sam_pwent = samu_new(talloc_tos());
+ sam_pwent = samu_new(tosctx);
if (sam_pwent == NULL) {
DEBUG(0, ("talloc failed\n"));
- break;
+ ret = 1;
+ goto done;
}
sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);
- status = in->getsampwsid(in, sam_pwent, &user_sid);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(2, ("getsampwsid failed: %s\n",
- nt_errstr(status)));
+ bret = pdb_getsampwsid(sam_pwent, &user_sid);
+ if (!bret) {
+ DEBUG(2, ("getsampwsid failed\n"));
TALLOC_FREE(sam_pwent);
continue;
}
- if (verbosity)
+ if (verbosity) {
printf ("---------------\n");
- print_sam_info (sam_pwent, verbosity, smbpwdstyle);
+ }
+ print_sam_info(sam_pwent, verbosity, smbpwdstyle);
TALLOC_FREE(sam_pwent);
}
- TALLOC_FREE(u_search);
- return 0;
+ ret = 0;
+
+done:
+ TALLOC_FREE(tosctx);
+ return ret;
}
/*********************************************************
Fix a list of Users for uninitialised passwords
**********************************************************/
-static int fix_users_list (struct pdb_methods *in)
+static int fix_users_list(void)
{
struct pdb_search *u_search;
struct samr_displayentry userentry;
+ struct samu *sam_pwent;
+ TALLOC_CTX *tosctx;
+ DOM_SID user_sid;
+ NTSTATUS status;
+ bool bret;
+ int ret;
- u_search = pdb_search_init(talloc_tos(), PDB_USER_SEARCH);
- if (u_search == NULL) {
- DEBUG(0, ("pdb_search_init failed\n"));
+ tosctx = talloc_tos();
+ if (!tosctx) {
+ fprintf(stderr, "Out of memory!\n");
return 1;
}
- if (!in->search_users(in, u_search, 0)) {
- DEBUG(0, ("Could not start searching users\n"));
- TALLOC_FREE(u_search);
- return 1;
+ u_search = pdb_search_users(tosctx, 0);
+ if (!u_search) {
+ fprintf(stderr, "User Search failed!\n");
+ ret = 1;
+ goto done;
}
while (u_search->next_entry(u_search, &userentry)) {
- struct samu *sam_pwent;
- DOM_SID user_sid;
- NTSTATUS status;
- sam_pwent = samu_new(talloc_tos());
+ sam_pwent = samu_new(tosctx);
if (sam_pwent == NULL) {
- DEBUG(0, ("talloc failed\n"));
- break;
+ fprintf(stderr, "Out of memory!\n");
+ ret = 1;
+ goto done;
}
sid_compose(&user_sid, get_global_sam_sid(), userentry.rid);
- status = in->getsampwsid(in, sam_pwent, &user_sid);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(2, ("getsampwsid failed: %s\n",
- nt_errstr(status)));
+ bret = pdb_getsampwsid(sam_pwent, &user_sid);
+ if (!bret) {
+ DEBUG(2, ("getsampwsid failed\n"));
TALLOC_FREE(sam_pwent);
continue;
}
- if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
+ status = pdb_update_sam_account(sam_pwent);
+ if (!NT_STATUS_IS_OK(status)) {
printf("Update of user %s failed!\n",
pdb_get_username(sam_pwent));
}
TALLOC_FREE(sam_pwent);
}
- TALLOC_FREE(u_search);
- return 0;
+
+ ret = 0;
+
+done:
+ TALLOC_FREE(tosctx);
+ return ret;
}
/*********************************************************
Set User Info
**********************************************************/
-static int set_user_info (struct pdb_methods *in, const char *username,
- const char *fullname, const char *homedir,
- const char *acct_desc,
- const char *drive, const char *script,
- const char *profile, const char *account_control,
- const char *user_sid, const char *user_domain,
- const bool badpw, const bool hours)
+static int set_user_info(const char *username, const char *fullname,
+ const char *homedir, const char *acct_desc,
+ const char *drive, const char *script,
+ const char *profile, const char *account_control,
+ const char *user_sid, const char *user_domain,
+ const bool badpw, const bool hours)
{
bool updated_autolock = False, updated_badpw = False;
- struct samu *sam_pwent=NULL;
+ struct samu *sam_pwent;
+ uint8_t hours_array[MAX_HOURS_LEN];
+ uint32_t hours_len;
+ uint32_t acb_flags;
+ uint32_t not_settable;
+ uint32_t new_flags;
+ DOM_SID u_sid;
bool ret;
-
- if ( (sam_pwent = samu_new( NULL )) == NULL ) {
+
+ sam_pwent = samu_new(NULL);
+ if (!sam_pwent) {
return 1;
}
-
- ret = NT_STATUS_IS_OK(in->getsampwnam (in, sam_pwent, username));
- if (ret==False) {
+
+ ret = pdb_getsampwnam(sam_pwent, username);
+ if (!ret) {
fprintf (stderr, "Username not found!\n");
TALLOC_FREE(sam_pwent);
return -1;
}
if (hours) {
- uint8 hours_array[MAX_HOURS_LEN];
- uint32 hours_len;
-
hours_len = pdb_get_hours_len(sam_pwent);
memset(hours_array, 0xff, hours_len);
-
+
pdb_set_hours(sam_pwent, hours_array, PDB_CHANGED);
}
@@ -509,35 +548,29 @@ static int set_user_info (struct pdb_methods *in, const char *username,
pdb_set_domain(sam_pwent, user_domain, PDB_CHANGED);
if (account_control) {
- uint32 not_settable = ~(ACB_DISABLED|ACB_HOMDIRREQ|ACB_PWNOTREQ|
- ACB_PWNOEXP|ACB_AUTOLOCK);
+ not_settable = ~(ACB_DISABLED | ACB_HOMDIRREQ |
+ ACB_PWNOTREQ | ACB_PWNOEXP | ACB_AUTOLOCK);
- uint32 newflag = pdb_decode_acct_ctrl(account_control);
+ new_flags = pdb_decode_acct_ctrl(account_control);
- if (newflag & not_settable) {
+ if (new_flags & not_settable) {
fprintf(stderr, "Can only set [NDHLX] flags\n");
TALLOC_FREE(sam_pwent);
return -1;
}
+ acb_flags = pdb_get_acct_ctrl(sam_pwent);
+
pdb_set_acct_ctrl(sam_pwent,
- (pdb_get_acct_ctrl(sam_pwent) & not_settable) | newflag,
+ (acb_flags & not_settable) | new_flags,
PDB_CHANGED);
}
if (user_sid) {
- DOM_SID u_sid;
- if (!string_to_sid(&u_sid, user_sid)) {
- /* not a complete sid, may be a RID, try building a SID */
- int u_rid;
-
- if (sscanf(user_sid, "%d", &u_rid) != 1) {
- fprintf(stderr, "Error passed string is not a complete user SID or RID!\n");
- return -1;
- }
- sid_copy(&u_sid, get_global_sam_sid());
- sid_append_rid(&u_sid, u_rid);
+ if (get_sid_from_cli_string(&u_sid, user_sid)) {
+ fprintf(stderr, "Failed to parse SID\n");
+ return -1;
}
- pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED);
+ pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);
}
if (badpw) {
@@ -545,9 +578,9 @@ static int set_user_info (struct pdb_methods *in, const char *username,
pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
}
- if (NT_STATUS_IS_OK(in->update_sam_account (in, sam_pwent)))
- print_user_info (in, username, True, False);
- else {
+ if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
+ print_user_info(username, True, False);
+ } else {
fprintf (stderr, "Unable to modify entry!\n");
TALLOC_FREE(sam_pwent);
return -1;
@@ -556,180 +589,315 @@ static int set_user_info (struct pdb_methods *in, const char *username,
return 0;
}
-/*********************************************************
- Add New User
-**********************************************************/
-static int new_user (struct pdb_methods *in, const char *username,
- const char *fullname, const char *homedir,
- const char *drive, const char *script,
- const char *profile, char *user_sid, bool stdin_get)
+static int set_machine_info(const char *machinename,
+ const char *account_control,
+ const char *machine_sid)
{
- struct samu *sam_pwent;
- char *password1, *password2;
- int rc_pwd_cmp;
- struct passwd *pwd;
-
- get_global_sam_sid();
+ struct samu *sam_pwent = NULL;
+ TALLOC_CTX *tosctx;
+ uint32_t acb_flags;
+ uint32_t not_settable;
+ uint32_t new_flags;
+ DOM_SID m_sid;
+ char *name;
+ int len;
+ bool ret;
- if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), username )) ) {
- DEBUG(0,("Cannot locate Unix account for %s\n", username));
+ len = strlen(machinename);
+ if (len == 0) {
+ fprintf(stderr, "No machine name given\n");
return -1;
}
- if ( (sam_pwent = samu_new( NULL )) == NULL ) {
- DEBUG(0, ("Memory allocation failure!\n"));
+ tosctx = talloc_tos();
+ if (!tosctx) {
+ fprintf(stderr, "Out of memory!\n");
return -1;
}
- if (!NT_STATUS_IS_OK(samu_alloc_rid_unix(sam_pwent, pwd ))) {
- TALLOC_FREE( sam_pwent );
- TALLOC_FREE( pwd );
- DEBUG(0, ("could not create account to add new user %s\n", username));
+ sam_pwent = samu_new(tosctx);
+ if (!sam_pwent) {
+ return 1;
+ }
+
+ if (machinename[len-1] == '$') {
+ name = talloc_strdup(sam_pwent, machinename);
+ } else {
+ name = talloc_asprintf(sam_pwent, "%s$", machinename);
+ }
+ if (!name) {
+ fprintf(stderr, "Out of memory!\n");
+ TALLOC_FREE(sam_pwent);
return -1;
}
- password1 = get_pass( "new password:", stdin_get);
- password2 = get_pass( "retype new password:", stdin_get);
- if ((rc_pwd_cmp = strcmp (password1, password2))) {
- fprintf (stderr, "Passwords do not match!\n");
+ strlower_m(name);
+
+ ret = pdb_getsampwnam(sam_pwent, name);
+ if (!ret) {
+ fprintf (stderr, "Username not found!\n");
TALLOC_FREE(sam_pwent);
+ return -1;
+ }
+
+ if (account_control) {
+ not_settable = ~(ACB_DISABLED);
+
+ new_flags = pdb_decode_acct_ctrl(account_control);
+
+ if (new_flags & not_settable) {
+ fprintf(stderr, "Can only set [D] flags\n");
+ TALLOC_FREE(sam_pwent);
+ return -1;
+ }
+
+ acb_flags = pdb_get_acct_ctrl(sam_pwent);
+
+ pdb_set_acct_ctrl(sam_pwent,
+ (acb_flags & not_settable) | new_flags,
+ PDB_CHANGED);
+ }
+ if (machine_sid) {
+ if (get_sid_from_cli_string(&m_sid, machine_sid)) {
+ fprintf(stderr, "Failed to parse SID\n");
+ return -1;
+ }
+ pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);
+ }
+
+ if (NT_STATUS_IS_OK(pdb_update_sam_account(sam_pwent))) {
+ print_user_info(name, True, False);
} else {
- pdb_set_plaintext_passwd(sam_pwent, password1);
+ fprintf (stderr, "Unable to modify entry!\n");
+ TALLOC_FREE(sam_pwent);
+ return -1;
}
+ TALLOC_FREE(sam_pwent);
+ return 0;
+}
- memset(password1, 0, strlen(password1));
- SAFE_FREE(password1);
- memset(password2, 0, strlen(password2));
- SAFE_FREE(password2);
+/*********************************************************
+ Add New User
+**********************************************************/
+static int new_user(const char *username, const char *fullname,
+ const char *homedir, const char *drive,
+ const char *script, const char *profile,
+ char *user_sid, bool stdin_get)
+{
+ char *pwd1 = NULL, *pwd2 = NULL;
+ char *err = NULL, *msg = NULL;
+ struct samu *sam_pwent = NULL;
+ TALLOC_CTX *tosctx;
+ NTSTATUS status;
+ DOM_SID u_sid;
+ int flags;
+ int ret;
- /* pwds do _not_ match? */
- if (rc_pwd_cmp)
+ tosctx = talloc_tos();
+ if (!tosctx) {
+ fprintf(stderr, "Out of memory!\n");
return -1;
+ }
+
+ if (user_sid) {
+ if (get_sid_from_cli_string(&u_sid, user_sid)) {
+ fprintf(stderr, "Failed to parse SID\n");
+ return -1;
+ }
+ }
+
+ pwd1 = get_pass( "new password:", stdin_get);
+ pwd2 = get_pass( "retype new password:", stdin_get);
+ ret = strcmp(pwd1, pwd2);
+ if (ret != 0) {
+ fprintf (stderr, "Passwords do not match!\n");
+ goto done;
+ }
+
+ flags = LOCAL_ADD_USER | LOCAL_SET_PASSWORD;
+
+ status = local_password_change(username, flags, pwd1, &err, &msg);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (err) fprintf(stderr, "%s", err);
+ ret = -1;
+ goto done;
+ }
+
+ sam_pwent = samu_new(tosctx);
+ if (!sam_pwent) {
+ fprintf(stderr, "Out of memory!\n");
+ ret = -1;
+ goto done;
+ }
+
+ if (!pdb_getsampwnam(sam_pwent, username)) {
+ fprintf(stderr, "User %s not found!\n", username);
+ ret = -1;
+ goto done;
+ }
if (fullname)
pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
if (homedir)
- pdb_set_homedir (sam_pwent, homedir, PDB_CHANGED);
+ pdb_set_homedir(sam_pwent, homedir, PDB_CHANGED);
if (drive)
- pdb_set_dir_drive (sam_pwent, drive, PDB_CHANGED);
+ pdb_set_dir_drive(sam_pwent, drive, PDB_CHANGED);
if (script)
pdb_set_logon_script(sam_pwent, script, PDB_CHANGED);
if (profile)
- pdb_set_profile_path (sam_pwent, profile, PDB_CHANGED);
- if (user_sid) {
- DOM_SID u_sid;
- if (!string_to_sid(&u_sid, user_sid)) {
- /* not a complete sid, may be a RID, try building a SID */
- int u_rid;
-
- if (sscanf(user_sid, "%d", &u_rid) != 1) {
- fprintf(stderr, "Error passed string is not a complete user SID or RID!\n");
- TALLOC_FREE(sam_pwent);
- return -1;
- }
- sid_copy(&u_sid, get_global_sam_sid());
- sid_append_rid(&u_sid, u_rid);
- }
- pdb_set_user_sid (sam_pwent, &u_sid, PDB_CHANGED);
- }
-
- pdb_set_acct_ctrl (sam_pwent, ACB_NORMAL, PDB_CHANGED);
-
- if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) {
- print_user_info (in, username, True, False);
- } else {
- fprintf (stderr, "Unable to add user! (does it already exist?)\n");
- TALLOC_FREE(sam_pwent);
- return -1;
+ pdb_set_profile_path(sam_pwent, profile, PDB_CHANGED);
+ if (user_sid)
+ pdb_set_user_sid(sam_pwent, &u_sid, PDB_CHANGED);
+
+ status = pdb_update_sam_account(sam_pwent);
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr,
+ "Failed to modify entry for user %s.!\n",
+ username);
+ ret = -1;
+ goto done;
}
+
+ print_user_info(username, True, False);
+ ret = 0;
+
+done:
+ if (pwd1) memset(pwd1, 0, strlen(pwd1));
+ if (pwd2) memset(pwd2, 0, strlen(pwd2));
+ SAFE_FREE(pwd1);
+ SAFE_FREE(pwd2);
+ SAFE_FREE(err);
+ SAFE_FREE(msg);
TALLOC_FREE(sam_pwent);
- return 0;
+ return ret;
}
/*********************************************************
Add New Machine
**********************************************************/
-static int new_machine (struct pdb_methods *in, const char *machine_in)
+static int new_machine(const char *machinename, char *machine_sid)
{
- struct samu *sam_pwent=NULL;
- fstring machinename;
- fstring machineaccount;
- struct passwd *pwd = NULL;
-
- get_global_sam_sid();
-
- if (strlen(machine_in) == 0) {
+ char *err = NULL, *msg = NULL;
+ struct samu *sam_pwent = NULL;
+ TALLOC_CTX *tosctx;
+ NTSTATUS status;
+ DOM_SID m_sid;
+ char *compatpwd;
+ char *name;
+ int flags;
+ int len;
+ int ret;
+
+ len = strlen(machinename);
+ if (len == 0) {
fprintf(stderr, "No machine name given\n");
return -1;
}
- fstrcpy(machinename, machine_in);
- machinename[15]= '\0';
+ tosctx = talloc_tos();
+ if (!tosctx) {
+ fprintf(stderr, "Out of memory!\n");
+ return -1;
+ }
- if (machinename[strlen (machinename) -1] == '$')
- machinename[strlen (machinename) -1] = '\0';
-
- strlower_m(machinename);
-
- fstrcpy(machineaccount, machinename);
- fstrcat(machineaccount, "$");
+ if (machine_sid) {
+ if (get_sid_from_cli_string(&m_sid, machine_sid)) {
+ fprintf(stderr, "Failed to parse SID\n");
+ return -1;
+ }
+ }
- if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), machineaccount )) ) {
- DEBUG(0,("Cannot locate Unix account for %s\n", machineaccount));
+ compatpwd = talloc_strdup(tosctx, machinename);
+ if (!compatpwd) {
+ fprintf(stderr, "Out of memory!\n");
return -1;
}
- if ( (sam_pwent = samu_new( NULL )) == NULL ) {
- fprintf(stderr, "Memory allocation error!\n");
- TALLOC_FREE(pwd);
+ if (machinename[len-1] == '$') {
+ name = talloc_strdup(tosctx, machinename);
+ compatpwd[len-1] = '\0';
+ } else {
+ name = talloc_asprintf(tosctx, "%s$", machinename);
+ }
+ if (!name) {
+ fprintf(stderr, "Out of memory!\n");
return -1;
}
- if ( !NT_STATUS_IS_OK(samu_alloc_rid_unix(sam_pwent, pwd )) ) {
- fprintf(stderr, "Could not init sam from pw\n");
- TALLOC_FREE(pwd);
- return -1;
+ strlower_m(name);
+
+ flags = LOCAL_ADD_USER | LOCAL_TRUST_ACCOUNT | LOCAL_SET_PASSWORD;
+
+ status = local_password_change(name, flags, compatpwd, &err, &msg);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ if (err) fprintf(stderr, "%s", err);
+ ret = -1;
}
- TALLOC_FREE(pwd);
+ sam_pwent = samu_new(tosctx);
+ if (!sam_pwent) {
+ fprintf(stderr, "Out of memory!\n");
+ ret = -1;
+ goto done;
+ }
- pdb_set_plaintext_passwd (sam_pwent, machinename);
- pdb_set_username (sam_pwent, machineaccount, PDB_CHANGED);
- pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST, PDB_CHANGED);
-
- if (NT_STATUS_IS_OK(in->add_sam_account (in, sam_pwent))) {
- print_user_info (in, machineaccount, True, False);
- } else {
- fprintf (stderr, "Unable to add machine! (does it already exist?)\n");
- TALLOC_FREE(sam_pwent);
- return -1;
+ if (!pdb_getsampwnam(sam_pwent, name)) {
+ fprintf(stderr, "Machine %s not found!\n", name);
+ ret = -1;
+ goto done;
}
+
+ if (machine_sid)
+ pdb_set_user_sid(sam_pwent, &m_sid, PDB_CHANGED);
+
+ status = pdb_update_sam_account(sam_pwent);
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr,
+ "Failed to modify entry for %s.!\n", name);
+ ret = -1;
+ goto done;
+ }
+
+ print_user_info(name, True, False);
+ ret = 0;
+
+done:
+ SAFE_FREE(err);
+ SAFE_FREE(msg);
TALLOC_FREE(sam_pwent);
- return 0;
+ return ret;
}
/*********************************************************
Delete user entry
**********************************************************/
-static int delete_user_entry (struct pdb_methods *in, const char *username)
+static int delete_user_entry(const char *username)
{
- struct samu *samaccount = NULL;
+ struct samu *samaccount;
- if ( (samaccount = samu_new( NULL )) == NULL ) {
+ samaccount = samu_new(NULL);
+ if (!samaccount) {
+ fprintf(stderr, "Out of memory!\n");
return -1;
}
- if (!NT_STATUS_IS_OK(in->getsampwnam(in, samaccount, username))) {
- fprintf (stderr, "user %s does not exist in the passdb\n", username);
+ if (!pdb_getsampwnam(samaccount, username)) {
+ fprintf (stderr,
+ "user %s does not exist in the passdb\n", username);
+ TALLOC_FREE(samaccount);
return -1;
}
- if (!NT_STATUS_IS_OK(in->delete_sam_account (in, samaccount))) {
+ if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
fprintf (stderr, "Unable to delete user %s\n", username);
+ TALLOC_FREE(samaccount);
return -1;
}
+
+ TALLOC_FREE(samaccount);
return 0;
}
@@ -737,35 +905,42 @@ static int delete_user_entry (struct pdb_methods *in, const char *username)
Delete machine entry
**********************************************************/
-static int delete_machine_entry (struct pdb_methods *in, const char *machinename)
+static int delete_machine_entry(const char *machinename)
{
- fstring name;
struct samu *samaccount = NULL;
+ const char *name;
if (strlen(machinename) == 0) {
fprintf(stderr, "No machine name given\n");
return -1;
}
-
- fstrcpy(name, machinename);
- name[15] = '\0';
- if (name[strlen(name)-1] != '$')
- fstrcat (name, "$");
- if ( (samaccount = samu_new( NULL )) == NULL ) {
+ samaccount = samu_new(NULL);
+ if (!samaccount) {
+ fprintf(stderr, "Out of memory!\n");
return -1;
}
- if (!NT_STATUS_IS_OK(in->getsampwnam(in, samaccount, name))) {
- fprintf (stderr, "machine %s does not exist in the passdb\n", name);
+ if (machinename[strlen(machinename)-1] != '$') {
+ name = talloc_asprintf(samaccount, "%s$", machinename);
+ } else {
+ name = machinename;
+ }
+
+ if (!pdb_getsampwnam(samaccount, name)) {
+ fprintf (stderr,
+ "machine %s does not exist in the passdb\n", name);
return -1;
+ TALLOC_FREE(samaccount);
}
- if (!NT_STATUS_IS_OK(in->delete_sam_account (in, samaccount))) {
+ if (!NT_STATUS_IS_OK(pdb_delete_sam_account(samaccount))) {
fprintf (stderr, "Unable to delete machine %s\n", name);
+ TALLOC_FREE(samaccount);
return -1;
}
+ TALLOC_FREE(samaccount);
return 0;
}
@@ -789,7 +964,7 @@ int main (int argc, char **argv)
static const char *user_name = NULL;
static char *home_dir = NULL;
static char *home_drive = NULL;
- static char *backend = NULL;
+ static const char *backend = NULL;
static char *backend_in = NULL;
static char *backend_out = NULL;
static int transfer_groups = False;
@@ -802,14 +977,16 @@ int main (int argc, char **argv)
static char *account_control = NULL;
static char *account_policy = NULL;
static char *user_sid = NULL;
+ static char *machine_sid = NULL;
static long int account_policy_value = 0;
bool account_policy_value_set = False;
static int badpw_reset = False;
static int hours_reset = False;
static char *pwd_time_format = NULL;
static int pw_from_stdin = False;
- struct pdb_methods *bin, *bout, *bdef;
+ struct pdb_methods *bin, *bout;
TALLOC_CTX *frame = talloc_stackframe();
+ NTSTATUS status;
poptContext pc;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -825,6 +1002,7 @@ int main (int argc, char **argv)
{"profile", 'p', POPT_ARG_STRING, &profile_path, 0, "set profile path", NULL},
{"domain", 'I', POPT_ARG_STRING, &user_domain, 0, "set a users' domain", NULL},
{"user SID", 'U', POPT_ARG_STRING, &user_sid, 0, "set user SID or RID", NULL},
+ {"machine SID", 'M', POPT_ARG_STRING, &machine_sid, 0, "set machine SID or RID", NULL},
{"create", 'a', POPT_ARG_NONE, &add_user, 0, "create user", NULL},
{"modify", 'r', POPT_ARG_NONE, &modify_user, 0, "modify user", NULL},
{"machine", 'm', POPT_ARG_NONE, &machine, 0, "account is a machine account", NULL},
@@ -846,16 +1024,16 @@ int main (int argc, char **argv)
POPT_COMMON_SAMBA
POPT_TABLEEND
};
-
- bin = bout = bdef = NULL;
+
+ bin = bout = NULL;
load_case_tables();
setup_logging("pdbedit", True);
-
+
pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
POPT_CONTEXT_KEEP_FIRST);
-
+
while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case 'C':
@@ -874,9 +1052,6 @@ int main (int argc, char **argv)
exit(1);
}
- if(!initialize_password_db(False, NULL))
- exit(1);
-
if (!init_names())
exit(1);
@@ -894,6 +1069,7 @@ int main (int argc, char **argv)
(list_users ? BIT_LIST : 0) +
(force_initialised_password ? BIT_FIX_INIT : 0) +
(user_sid ? BIT_USERSIDS : 0) +
+ (machine_sid ? BIT_USERSIDS : 0) +
(modify_user ? BIT_MODIFY : 0) +
(add_user ? BIT_CREATE : 0) +
(delete_user ? BIT_DELETE : 0) +
@@ -906,22 +1082,24 @@ int main (int argc, char **argv)
(hours_reset ? BIT_LOGONHOURS : 0);
if (setparms & BIT_BACKEND) {
- if (!NT_STATUS_IS_OK(make_pdb_method_name( &bdef, backend ))) {
- fprintf(stderr, "Can't initialize passdb backend.\n");
- return 1;
- }
+ /* HACK: set the global passdb backend by overwriting globals.
+ * This way we can use regular pdb functions for default
+ * operations that do not involve passdb migrations */
+ lp_set_passdb_backend(backend);
} else {
- if (!NT_STATUS_IS_OK(make_pdb_method_name(&bdef, lp_passdb_backend()))) {
- fprintf(stderr, "Can't initialize passdb backend.\n");
- return 1;
- }
+ backend = lp_passdb_backend();
}
-
+
+ if (!initialize_password_db(False, NULL)) {
+ fprintf(stderr, "Can't initialize passdb backend.\n");
+ exit(1);
+ }
+
/* the lowest bit options are always accepted */
checkparms = setparms & ~MASK_ALWAYS_GOOD;
if (checkparms & BIT_FIX_INIT) {
- return fix_users_list(bdef);
+ return fix_users_list();
}
/* account policy operations */
@@ -973,45 +1151,49 @@ int main (int argc, char **argv)
/* import and export operations */
- if ( ((checkparms & BIT_IMPORT)
- || (checkparms & BIT_EXPORT))
- && !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER)) )
- {
- NTSTATUS status;
-
- bin = bout = bdef;
+ if (((checkparms & BIT_IMPORT) ||
+ (checkparms & BIT_EXPORT)) &&
+ !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER))) {
if (backend_in) {
status = make_pdb_method_name(&bin, backend_in);
+ } else {
+ status = make_pdb_method_name(&bin, backend);
+ }
- if ( !NT_STATUS_IS_OK(status) ) {
- fprintf(stderr, "Unable to initialize %s.\n", backend_in);
- return 1;
- }
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr, "Unable to initialize %s.\n",
+ backend_in ? backend_in : backend);
+ return 1;
}
if (backend_out) {
status = make_pdb_method_name(&bout, backend_out);
+ } else {
+ status = make_pdb_method_name(&bout, backend);
+ }
- if ( !NT_STATUS_IS_OK(status) ) {
- fprintf(stderr, "Unable to initialize %s.\n", backend_out);
- return 1;
- }
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr, "Unable to initialize %s.\n",
+ backend_out ? backend_out : backend);
+ return 1;
}
if (transfer_account_policies) {
- if (!(checkparms & BIT_USER))
+ if (!(checkparms & BIT_USER)) {
return export_account_policies(bin, bout);
+ }
} else if (transfer_groups) {
- if (!(checkparms & BIT_USER))
+ if (!(checkparms & BIT_USER)) {
return export_groups(bin, bout);
+ }
} else {
- return export_database(bin, bout,
- (checkparms & BIT_USER) ? user_name : NULL );
+ return export_database(bin, bout,
+ (checkparms & BIT_USER) ? user_name : NULL);
}
}
@@ -1020,7 +1202,7 @@ int main (int argc, char **argv)
if ((checkparms & BIT_USER) && !(checkparms & ~BIT_USER)) {
checkparms += BIT_LIST;
}
-
+
/* modify flag is optional to maintain backwards compatibility */
/* fake up BIT_MODIFY if BIT_USER and at least one of MASK_USER_GOOD is defined */
if (!((checkparms & ~MASK_USER_GOOD) & ~BIT_USER) && (checkparms & MASK_USER_GOOD)) {
@@ -1030,13 +1212,13 @@ int main (int argc, char **argv)
/* list users operations */
if (checkparms & BIT_LIST) {
if (!(checkparms & ~BIT_LIST)) {
- return print_users_list (bdef, verbose, spstyle);
+ return print_users_list(verbose, spstyle);
}
if (!(checkparms & ~(BIT_USER + BIT_LIST))) {
- return print_user_info (bdef, user_name, verbose, spstyle);
+ return print_user_info(user_name, verbose, spstyle);
}
}
-
+
/* mask out users options */
checkparms &= ~MASK_USER_GOOD;
@@ -1051,7 +1233,7 @@ int main (int argc, char **argv)
checkparms |= BIT_MODIFY;
checkparms &= ~BIT_LOGONHOURS;
}
-
+
/* account operation */
if ((checkparms & BIT_CREATE) || (checkparms & BIT_MODIFY) || (checkparms & BIT_DELETE)) {
/* check use of -u option */
@@ -1063,27 +1245,38 @@ int main (int argc, char **argv)
/* account creation operations */
if (!(checkparms & ~(BIT_CREATE + BIT_USER + BIT_MACHINE))) {
if (checkparms & BIT_MACHINE) {
- return new_machine (bdef, user_name);
+ return new_machine(user_name, machine_sid);
} else {
- return new_user (bdef, user_name, full_name, home_dir,
- home_drive, logon_script, profile_path, user_sid, pw_from_stdin);
+ return new_user(user_name, full_name,
+ home_dir, home_drive,
+ logon_script, profile_path,
+ user_sid, pw_from_stdin);
}
}
/* account deletion operations */
if (!(checkparms & ~(BIT_DELETE + BIT_USER + BIT_MACHINE))) {
if (checkparms & BIT_MACHINE) {
- return delete_machine_entry (bdef, user_name);
+ return delete_machine_entry(user_name);
} else {
- return delete_user_entry (bdef, user_name);
+ return delete_user_entry(user_name);
}
}
/* account modification operations */
- if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) {
- return set_user_info (bdef, user_name, full_name, home_dir,
- acct_desc, home_drive, logon_script, profile_path, account_control,
- user_sid, user_domain, badpw_reset, hours_reset);
+ if (!(checkparms & ~(BIT_MODIFY + BIT_USER + BIT_MACHINE))) {
+ if (checkparms & BIT_MACHINE) {
+ return set_machine_info(user_name,
+ account_control,
+ machine_sid);
+ } else {
+ return set_user_info(user_name, full_name,
+ home_dir, acct_desc,
+ home_drive, logon_script,
+ profile_path, account_control,
+ user_sid, user_domain,
+ badpw_reset, hours_reset);
+ }
}
}
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index 8cca93f5de..c0b2cac18a 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -242,26 +242,29 @@ static NTSTATUS password_change(const char *remote_mach, char *username,
char *msg_str = NULL;
if (remote_mach != NULL) {
- if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|
- LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) {
+ if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|
+ LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|
+ LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) {
/* these things can't be done remotely yet */
+ fprintf(stderr, "Invalid remote operation!\n");
return NT_STATUS_UNSUCCESSFUL;
}
- ret = remote_password_change(remote_mach, username,
+ ret = remote_password_change(remote_mach, username,
old_passwd, new_pw, &err_str);
- if (err_str != NULL)
- fprintf(stderr, "%s", err_str);
- SAFE_FREE(err_str);
- return ret;
+ } else {
+ ret = local_password_change(username, local_flags, new_pw,
+ &err_str, &msg_str);
}
- ret = local_password_change(username, local_flags, new_pw,
- &err_str, &msg_str);
-
- if(msg_str)
+ if (msg_str) {
printf("%s", msg_str);
- if(err_str)
+ }
+ if (err_str) {
fprintf(stderr, "%s", err_str);
+ }
+ if (!NT_STATUS_IS_OK(ret) && !err_str) {
+ fprintf(stderr, "Failed to change password!\n");
+ }
SAFE_FREE(msg_str);
SAFE_FREE(err_str);
@@ -430,21 +433,8 @@ static int process_root(int local_flags)
}
if((local_flags & LOCAL_SET_PASSWORD) && (new_passwd == NULL)) {
- struct passwd *passwd;
-
- if (remote_machine == NULL) {
- passwd = getpwnam_alloc(NULL, user_name);
-
- if (!passwd) {
- fprintf(stderr, "Cannot locate Unix account for "
- "'%s'!\n", user_name);
- exit(1);
- }
- TALLOC_FREE(passwd);
- }
new_passwd = prompt_for_new_password(stdin_passwd_get);
-
if(!new_passwd) {
fprintf(stderr, "Unable to get new password.\n");
exit(1);
@@ -455,7 +445,6 @@ static int process_root(int local_flags)
if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name,
old_passwd, new_passwd,
local_flags))) {
- fprintf(stderr,"Failed to modify password entry for user %s\n", user_name);
result = 1;
goto done;
}
@@ -550,7 +539,6 @@ static int process_nonroot(int local_flags)
if (!NT_STATUS_IS_OK(password_change(remote_machine, user_name, old_pw,
new_pw, 0))) {
- fprintf(stderr,"Failed to change password for %s\n", user_name);
result = 1;
goto done;
}
diff --git a/source3/winbindd/idmap_adex/gc_util.c b/source3/winbindd/idmap_adex/gc_util.c
index 58e641b630..879c2e0ecf 100644
--- a/source3/winbindd/idmap_adex/gc_util.c
+++ b/source3/winbindd/idmap_adex/gc_util.c
@@ -716,11 +716,11 @@ done:
*name = NULL;
- sid_string = sid_binstring(sid);
+ sid_string = sid_binstring(frame, sid);
BAIL_ON_PTR_ERROR(sid_string, nt_status);
filter = talloc_asprintf(frame, "(objectSid=%s)", sid_string);
- SAFE_FREE(sid_string);
+ TALLOC_FREE(sid_string);
BAIL_ON_PTR_ERROR(filter, nt_status);
nt_status = gc_search_all_forests_unique(filter, &ads, &msg);
diff --git a/source3/winbindd/idmap_adex/provider_unified.c b/source3/winbindd/idmap_adex/provider_unified.c
index f9d73f5f95..00db018de2 100644
--- a/source3/winbindd/idmap_adex/provider_unified.c
+++ b/source3/winbindd/idmap_adex/provider_unified.c
@@ -483,11 +483,11 @@ static NTSTATUS search_forest(struct likewise_cell *forest_cell,
switch (fdata->ftype) {
case SidFilter:
- sid_binstr = sid_binstring(&fdata->filter.sid);
+ sid_binstr = sid_binstring(frame, &fdata->filter.sid);
BAIL_ON_PTR_ERROR(sid_binstr, nt_status);
filter = talloc_asprintf(frame, "(objectSid=%s)", sid_binstr);
- SAFE_FREE(sid_binstr);
+ TALLOC_FREE(sid_binstr);
break;
case IdFilter:
filter = build_id_filter(fdata->filter.id.id,
diff --git a/source4/Makefile b/source4/Makefile
index 7bc48b9fe4..2a3ad2def1 100644
--- a/source4/Makefile
+++ b/source4/Makefile
@@ -58,6 +58,7 @@ clustersrcdir := cluster
libnetsrcdir := libnet
authsrcdir := auth
nsswitchsrcdir := ../nsswitch
+libwbclientsrcdir := ../nsswitch/libwbclient
libsrcdir := lib
libsocketsrcdir := lib/socket
libcharsetsrcdir := ../lib/util/charset
diff --git a/source4/client/smbmnt.c b/source4/client/smbmnt.c
deleted file mode 100644
index 0d619a88fe..0000000000
--- a/source4/client/smbmnt.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * smbmnt.c
- *
- * Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke
- * extensively modified by Tridge
- *
- */
-
-#include "includes.h"
-
-#include <mntent.h>
-#include <sys/utsname.h>
-
-#include <asm/types.h>
-#include <asm/posix_types.h>
-#include <linux/smb.h>
-#include <linux/smb_mount.h>
-#include <asm/unistd.h>
-
-#ifndef MS_MGC_VAL
-/* This may look strange but MS_MGC_VAL is what we are looking for and
- is what we need from <linux/fs.h> under libc systems and is
- provided in standard includes on glibc systems. So... We
- switch on what we need... */
-#include <linux/fs.h>
-#endif
-
-static uid_t mount_uid;
-static gid_t mount_gid;
-static int mount_ro;
-static uint_t mount_fmask;
-static uint_t mount_dmask;
-static int user_mount;
-static char *options;
-
-static void
-help(void)
-{
- printf("\n");
- printf("Usage: smbmnt mount-point [options]\n");
- printf("Version %s\n\n",VERSION);
- printf("-s share share name on server\n"
- "-r mount read-only\n"
- "-u uid mount as uid\n"
- "-g gid mount as gid\n"
- "-f mask permission mask for files\n"
- "-d mask permission mask for directories\n"
- "-o options name=value, list of options\n"
- "-h print this help text\n");
-}
-
-static int
-parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
-{
- int opt;
-
- while ((opt = getopt (argc, argv, "s:u:g:rf:d:o:")) != EOF)
- {
- switch (opt)
- {
- case 's':
- *share = optarg;
- break;
- case 'u':
- if (!user_mount) {
- mount_uid = strtol(optarg, NULL, 0);
- }
- break;
- case 'g':
- if (!user_mount) {
- mount_gid = strtol(optarg, NULL, 0);
- }
- break;
- case 'r':
- mount_ro = 1;
- break;
- case 'f':
- mount_fmask = strtol(optarg, NULL, 8);
- break;
- case 'd':
- mount_dmask = strtol(optarg, NULL, 8);
- break;
- case 'o':
- options = optarg;
- break;
- default:
- return -1;
- }
- }
- return 0;
-
-}
-
-static char *
-fullpath(const char *p)
-{
- char path[MAXPATHLEN];
-
- if (strlen(p) > MAXPATHLEN-1) {
- return NULL;
- }
-
- if (realpath(p, path) == NULL) {
- fprintf(stderr,"Failed to find real path for mount point\n");
- exit(1);
- }
- return strdup(path);
-}
-
-/* Check whether user is allowed to mount on the specified mount point. If it's
- OK then we change into that directory - this prevents race conditions */
-static int mount_ok(char *mount_point)
-{
- struct stat st;
-
- if (chdir(mount_point) != 0) {
- return -1;
- }
-
- if (stat(".", &st) != 0) {
- return -1;
- }
-
- if (!S_ISDIR(st.st_mode)) {
- errno = ENOTDIR;
- return -1;
- }
-
- if ((getuid() != 0) &&
- ((getuid() != st.st_uid) ||
- ((st.st_mode & S_IRWXU) != S_IRWXU))) {
- errno = EPERM;
- return -1;
- }
-
- return 0;
-}
-
-/* Tries to mount using the appropriate format. For 2.2 the struct,
- for 2.4 the ascii version. */
-static int
-do_mount(char *share_name, uint_t flags, struct smb_mount_data *data)
-{
- pstring opts;
- struct utsname uts;
- char *release, *major, *minor;
- char *data1, *data2;
-
- uname(&uts);
- release = uts.release;
- major = strtok(release, ".");
- minor = strtok(NULL, ".");
- if (major && minor && atoi(major) == 2 && atoi(minor) < 4) {
- /* < 2.4, assume struct */
- data1 = (char *) data;
- data2 = opts;
- } else {
- /* >= 2.4, assume ascii but fall back on struct */
- data1 = opts;
- data2 = (char *) data;
- }
-
- slprintf(opts, sizeof(opts)-1,
- "version=7,uid=%d,gid=%d,file_mode=0%o,dir_mode=0%o,%s",
- data->uid, data->gid, data->file_mode, data->dir_mode,options);
- if (mount(share_name, ".", "smbfs", flags, data1) == 0)
- return 0;
- return mount(share_name, ".", "smbfs", flags, data2);
-}
-
- int main(int argc, char *argv[])
-{
- char *mount_point, *share_name = NULL;
- FILE *mtab;
- int fd;
- uint_t flags;
- struct smb_mount_data data;
- struct mntent ment;
-
- memset(&data, 0, sizeof(struct smb_mount_data));
-
- if (argc < 2) {
- help();
- exit(1);
- }
-
- if (argv[1][0] == '-') {
- help();
- exit(1);
- }
-
- if (getuid() != 0) {
- user_mount = 1;
- }
-
- if (geteuid() != 0) {
- fprintf(stderr, "smbmnt must be installed suid root for direct user mounts (%d,%d)\n", getuid(), geteuid());
- exit(1);
- }
-
- mount_uid = getuid();
- mount_gid = getgid();
- mount_fmask = umask(0);
- umask(mount_fmask);
- mount_fmask = ~mount_fmask;
-
- mount_point = fullpath(argv[1]);
-
- argv += 1;
- argc -= 1;
-
- if (mount_ok(mount_point) != 0) {
- fprintf(stderr, "cannot mount on %s: %s\n",
- mount_point, strerror(errno));
- exit(1);
- }
-
- data.version = SMB_MOUNT_VERSION;
-
- /* getuid() gives us the real uid, who may umount the fs */
- data.mounted_uid = getuid();
-
- if (parse_args(argc, argv, &data, &share_name) != 0) {
- help();
- return -1;
- }
-
- data.uid = mount_uid;
- data.gid = mount_gid;
- data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_fmask;
- data.dir_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_dmask;
-
- if (mount_dmask == 0) {
- data.dir_mode = data.file_mode;
- if ((data.dir_mode & S_IRUSR) != 0)
- data.dir_mode |= S_IXUSR;
- if ((data.dir_mode & S_IRGRP) != 0)
- data.dir_mode |= S_IXGRP;
- if ((data.dir_mode & S_IROTH) != 0)
- data.dir_mode |= S_IXOTH;
- }
-
- flags = MS_MGC_VAL;
-
- if (mount_ro) flags |= MS_RDONLY;
-
- if (do_mount(share_name, flags, &data) < 0) {
- switch (errno) {
- case ENODEV:
- fprintf(stderr, "ERROR: smbfs filesystem not supported by the kernel\n");
- break;
- default:
- perror("mount error");
- }
- fprintf(stderr, "Please refer to the smbmnt(8) manual page\n");
- return -1;
- }
-
- ment.mnt_fsname = share_name ? share_name : "none";
- ment.mnt_dir = mount_point;
- ment.mnt_type = "smbfs";
- ment.mnt_opts = "";
- ment.mnt_freq = 0;
- ment.mnt_passno= 0;
-
- mount_point = ment.mnt_dir;
-
- if (mount_point == NULL)
- {
- fprintf(stderr, "Mount point too long\n");
- return -1;
- }
-
- if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
- {
- fprintf(stderr, "Can't get "MOUNTED"~ lock file");
- return 1;
- }
- close(fd);
-
- if ((mtab = setmntent(MOUNTED, "a+")) == NULL)
- {
- fprintf(stderr, "Can't open " MOUNTED);
- return 1;
- }
-
- if (addmntent(mtab, &ment) == 1)
- {
- fprintf(stderr, "Can't write mount entry");
- return 1;
- }
- if (fchmod(fileno(mtab), 0644) == -1)
- {
- fprintf(stderr, "Can't set perms on "MOUNTED);
- return 1;
- }
- endmntent(mtab);
-
- if (unlink(MOUNTED"~") == -1)
- {
- fprintf(stderr, "Can't remove "MOUNTED"~");
- return 1;
- }
-
- return 0;
-}
diff --git a/source4/client/smbmount.c b/source4/client/smbmount.c
deleted file mode 100644
index c219a42f3a..0000000000
--- a/source4/client/smbmount.c
+++ /dev/null
@@ -1,942 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMBFS mount program
- Copyright (C) Andrew Tridgell 1999
-
- 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/>.
-*/
-
-#include "includes.h"
-#include "system/passwd.h"
-
-#include <mntent.h>
-#include <asm/types.h>
-#include <linux/smb_fs.h>
-
-#define pstrcpy(d,s) safe_strcpy((d),(s),sizeof(pstring)-1)
-#define pstrcat(d,s) safe_strcat((d),(s),sizeof(pstring)-1)
-
-static pstring credentials;
-static pstring my_netbios_name;
-static pstring password;
-static pstring username;
-static pstring workgroup;
-static pstring mpoint;
-static pstring service;
-static pstring options;
-
-static struct in_addr dest_ip;
-static bool have_ip;
-static int smb_port = 0;
-static bool got_user;
-static bool got_pass;
-static uid_t mount_uid;
-static gid_t mount_gid;
-static int mount_ro;
-static uint_t mount_fmask;
-static uint_t mount_dmask;
-static bool use_kerberos;
-/* TODO: Add code to detect smbfs version in kernel */
-static bool status32_smbfs = false;
-
-static void usage(void);
-
-static void exit_parent(int sig)
-{
- /* parent simply exits when child says go... */
- exit(0);
-}
-
-static void daemonize(void)
-{
- int j, status;
- pid_t child_pid;
-
- signal( SIGTERM, exit_parent );
-
- if ((child_pid = sys_fork()) < 0) {
- DEBUG(0,("could not fork\n"));
- }
-
- if (child_pid > 0) {
- while( 1 ) {
- j = waitpid( child_pid, &status, 0 );
- if( j < 0 ) {
- if( EINTR == errno ) {
- continue;
- }
- status = errno;
- }
- break;
- }
-
- /* If we get here - the child exited with some error status */
- if (WIFSIGNALED(status))
- exit(128 + WTERMSIG(status));
- else
- exit(WEXITSTATUS(status));
- }
-
- signal( SIGTERM, SIG_DFL );
- chdir("/");
-}
-
-static void close_our_files(int client_fd)
-{
- int i;
- struct rlimit limits;
-
- getrlimit(RLIMIT_NOFILE,&limits);
- for (i = 0; i< limits.rlim_max; i++) {
- if (i == client_fd)
- continue;
- close(i);
- }
-}
-
-static void usr1_handler(int x)
-{
- return;
-}
-
-
-/*****************************************************
-return a connection to a server
-*******************************************************/
-static struct smbcli_state *do_connection(const char *the_service, bool unicode, int maxprotocol,
- struct smbcli_session_options session_options)
-{
- struct smbcli_state *c;
- struct nmb_name called, calling;
- char *server_n;
- struct in_addr ip;
- pstring server;
- char *share;
-
- if (the_service[0] != '\\' || the_service[1] != '\\') {
- usage();
- exit(1);
- }
-
- pstrcpy(server, the_service+2);
- share = strchr_m(server,'\\');
- if (!share) {
- usage();
- exit(1);
- }
- *share = 0;
- share++;
-
- server_n = server;
-
- make_nmb_name(&calling, my_netbios_name, 0x0);
- choose_called_name(&called, server, 0x20);
-
- again:
- zero_ip(&ip);
- if (have_ip) ip = dest_ip;
-
- /* have to open a new connection */
- if (!(c=smbcli_initialise(NULL)) || (smbcli_set_port(c, smb_port) != smb_port) ||
- !smbcli_connect(c, server_n, &ip)) {
- DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
- if (c) {
- talloc_free(c);
- }
- return NULL;
- }
-
- /* SPNEGO doesn't work till we get NTSTATUS error support */
- /* But it is REQUIRED for kerberos authentication */
- if(!use_kerberos) c->use_spnego = false;
-
- /* The kernel doesn't yet know how to sign it's packets */
- c->sign_info.allow_smb_signing = false;
-
- /* Use kerberos authentication if specified */
- c->use_kerberos = use_kerberos;
-
- if (!smbcli_session_request(c, &calling, &called)) {
- char *p;
- DEBUG(0,("%d: session request to %s failed (%s)\n",
- sys_getpid(), called.name, smbcli_errstr(c)));
- talloc_free(c);
- if ((p=strchr_m(called.name, '.'))) {
- *p = 0;
- goto again;
- }
- if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20);
- goto again;
- }
- return NULL;
- }
-
- DEBUG(4,("%d: session request ok\n", sys_getpid()));
-
- if (!smbcli_negprot(c, unicode, maxprotocol)) {
- DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid()));
- talloc_free(c);
- return NULL;
- }
-
- if (!got_pass) {
- char *pass = getpass("Password: ");
- if (pass) {
- pstrcpy(password, pass);
- }
- }
-
- /* This should be right for current smbfs. Future versions will support
- large files as well as unicode and oplocks. */
- if (status32_smbfs) {
- c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS |
- CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS);
- }
- else {
- c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS |
- CAP_NT_FIND | CAP_STATUS32 |
- CAP_LEVEL_II_OPLOCKS);
- c->force_dos_errors = true;
- }
-
- if (!smbcli_session_setup(c, username,
- password, strlen(password),
- password, strlen(password),
- workgroup, session_options)) {
- /* if a password was not supplied then try again with a
- null username */
- if (password[0] || !username[0] ||
- !smbcli_session_setup(c, "", "", 0, "", 0, workgroup,
- session_options)) {
- DEBUG(0,("%d: session setup failed: %s\n",
- sys_getpid(), smbcli_errstr(c)));
- talloc_free(c);
- return NULL;
- }
- DEBUG(0,("Anonymous login successful\n"));
- }
-
- DEBUG(4,("%d: session setup ok\n", sys_getpid()));
-
- if (!smbcli_tconX(c, share, "?????", password, strlen(password)+1)) {
- DEBUG(0,("%d: tree connect failed: %s\n",
- sys_getpid(), smbcli_errstr(c)));
- talloc_free(c);
- return NULL;
- }
-
- DEBUG(4,("%d: tconx ok\n", sys_getpid()));
-
- got_pass = true;
-
- return c;
-}
-
-
-/****************************************************************************
-unmount smbfs (this is a bailout routine to clean up if a reconnect fails)
- Code blatently stolen from smbumount.c
- -mhw-
-****************************************************************************/
-static void smb_umount(const char *mount_point)
-{
- int fd;
- struct mntent *mnt;
- FILE* mtab;
- FILE* new_mtab;
-
- /* Programmers Note:
- This routine only gets called to the scene of a disaster
- to shoot the survivors... A connection that was working
- has now apparently failed. We have an active mount point
- (presumably) that we need to dump. If we get errors along
- the way - make some noise, but we are already turning out
- the lights to exit anyways...
- */
- if (umount(mount_point) != 0) {
- DEBUG(0,("%d: Could not umount %s: %s\n",
- sys_getpid(), mount_point, strerror(errno)));
- return;
- }
-
- if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
- DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid()));
- return;
- }
-
- close(fd);
-
- if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
- DEBUG(0,("%d: Can't open " MOUNTED ": %s\n",
- sys_getpid(), strerror(errno)));
- return;
- }
-
-#define MOUNTED_TMP MOUNTED".tmp"
-
- if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
- DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n",
- sys_getpid(), strerror(errno)));
- endmntent(mtab);
- return;
- }
-
- while ((mnt = getmntent(mtab)) != NULL) {
- if (strcmp(mnt->mnt_dir, mount_point) != 0) {
- addmntent(new_mtab, mnt);
- }
- }
-
- endmntent(mtab);
-
- if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
- DEBUG(0,("%d: Error changing mode of %s: %s\n",
- sys_getpid(), MOUNTED_TMP, strerror(errno)));
- return;
- }
-
- endmntent(new_mtab);
-
- if (rename(MOUNTED_TMP, MOUNTED) < 0) {
- DEBUG(0,("%d: Cannot rename %s to %s: %s\n",
- sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
- return;
- }
-
- if (unlink(MOUNTED"~") == -1) {
- DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid()));
- return;
- }
-}
-
-
-/*
- * Call the smbfs ioctl to install a connection socket,
- * then wait for a signal to reconnect. Note that we do
- * not exit after open_sockets() or send_login() errors,
- * as the smbfs mount would then have no way to recover.
- */
-static void send_fs_socket(struct loadparm_context *lp_ctx,
- const char *the_service, const char *mount_point, struct smbcli_state *c)
-{
- int fd, closed = 0, res = 1;
- pid_t parentpid = getppid();
- struct smb_conn_opt conn_options;
- struct smbcli_session_options session_options;
-
- lp_smbcli_session_options(lp_ctx, &session_options);
-
- memset(&conn_options, 0, sizeof(conn_options));
-
- while (1) {
- if ((fd = open(mount_point, O_RDONLY)) < 0) {
- DEBUG(0,("mount.smbfs[%d]: can't open %s\n",
- sys_getpid(), mount_point));
- break;
- }
-
- conn_options.fd = c->fd;
- conn_options.protocol = c->protocol;
- conn_options.case_handling = SMB_CASE_DEFAULT;
- conn_options.max_xmit = c->max_xmit;
- conn_options.server_uid = c->vuid;
- conn_options.tid = c->cnum;
- conn_options.secmode = c->sec_mode;
- conn_options.rawmode = 0;
- conn_options.sesskey = c->sesskey;
- conn_options.maxraw = 0;
- conn_options.capabilities = c->capabilities;
- conn_options.serverzone = c->serverzone/60;
-
- res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
- if (res != 0) {
- DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n",
- sys_getpid(), res));
- close(fd);
- break;
- }
-
- if (parentpid) {
- /* Ok... We are going to kill the parent. Now
- is the time to break the process group... */
- setsid();
- /* Send a signal to the parent to terminate */
- kill(parentpid, SIGTERM);
- parentpid = 0;
- }
-
- close(fd);
-
- /* This looks wierd but we are only closing the userspace
- side, the connection has already been passed to smbfs and
- it has increased the usage count on the socket.
-
- If we don't do this we will "leak" sockets and memory on
- each reconnection we have to make. */
- talloc_free(c);
- c = NULL;
-
- if (!closed) {
- /* redirect stdout & stderr since we can't know that
- the library functions we use are using DEBUG. */
- if ( (fd = open("/dev/null", O_WRONLY)) < 0)
- DEBUG(2,("mount.smbfs: can't open /dev/null\n"));
- close_our_files(fd);
- if (fd >= 0) {
- dup2(fd, STDOUT_FILENO);
- dup2(fd, STDERR_FILENO);
- close(fd);
- }
-
- /* here we are no longer interactive */
- set_remote_machine_name("smbmount"); /* sneaky ... */
- setup_logging("mount.smbfs", DEBUG_STDERR);
- reopen_logs();
- DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid()));
-
- closed = 1;
- }
-
- /* Wait for a signal from smbfs ... but don't continue
- until we actually get a new connection. */
- while (!c) {
- CatchSignal(SIGUSR1, &usr1_handler);
- pause();
- DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid()));
- c = do_connection(the_service,
- lp_unicode(lp_ctx),
- lp_cli_maxprotocol(lp_ctx),
- session_options);
- }
- }
-
- smb_umount(mount_point);
- DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid()));
- exit(1);
-}
-
-
-/**
- * Mount a smbfs
- **/
-static void init_mount(struct loadparm_context *lp_ctx)
-{
- char mount_point[MAXPATHLEN+1];
- pstring tmp;
- pstring svc2;
- struct smbcli_state *c;
- char *args[20];
- int i, status;
- struct smbcli_session_options session_options;
-
- if (realpath(mpoint, mount_point) == NULL) {
- fprintf(stderr, "Could not resolve mount point %s\n", mpoint);
- return;
- }
-
- lp_smbcli_session_options(lp_ctx, &session_options);
-
- c = do_connection(service, lp_unicode(lp_ctx), lp_cli_maxprotocol(lp_ctx),
- session_options);
- if (!c) {
- fprintf(stderr,"SMB connection failed\n");
- exit(1);
- }
-
- /*
- Set up to return as a daemon child and wait in the parent
- until the child say it's ready...
- */
- daemonize();
-
- pstrcpy(svc2, service);
- string_replace(svc2, '\\','/');
- string_replace(svc2, ' ','_');
-
- memset(args, 0, sizeof(args[0])*20);
-
- i=0;
- args[i++] = "smbmnt";
-
- args[i++] = mount_point;
- args[i++] = "-s";
- args[i++] = svc2;
-
- if (mount_ro) {
- args[i++] = "-r";
- }
- if (mount_uid) {
- slprintf(tmp, sizeof(tmp)-1, "%d", mount_uid);
- args[i++] = "-u";
- args[i++] = smb_xstrdup(tmp);
- }
- if (mount_gid) {
- slprintf(tmp, sizeof(tmp)-1, "%d", mount_gid);
- args[i++] = "-g";
- args[i++] = smb_xstrdup(tmp);
- }
- if (mount_fmask) {
- slprintf(tmp, sizeof(tmp)-1, "0%o", mount_fmask);
- args[i++] = "-f";
- args[i++] = smb_xstrdup(tmp);
- }
- if (mount_dmask) {
- slprintf(tmp, sizeof(tmp)-1, "0%o", mount_dmask);
- args[i++] = "-d";
- args[i++] = smb_xstrdup(tmp);
- }
- if (options) {
- args[i++] = "-o";
- args[i++] = options;
- }
-
- if (sys_fork() == 0) {
- char *smbmnt_path;
-
- asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR);
-
- if (file_exist(smbmnt_path)) {
- execv(smbmnt_path, args);
- fprintf(stderr,
- "smbfs/init_mount: execv of %s failed. Error was %s.",
- smbmnt_path, strerror(errno));
- } else {
- execvp("smbmnt", args);
- fprintf(stderr,
- "smbfs/init_mount: execv of %s failed. Error was %s.",
- "smbmnt", strerror(errno));
- }
- free(smbmnt_path);
- exit(1);
- }
-
- if (waitpid(-1, &status, 0) == -1) {
- fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) );
- /* FIXME: do some proper error handling */
- exit(1);
- }
-
- if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
- fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
- /* FIXME: do some proper error handling */
- exit(1);
- } else if (WIFSIGNALED(status)) {
- fprintf(stderr, "smbmnt killed by signal %d\n", WTERMSIG(status));
- exit(1);
- }
-
- /* Ok... This is the rubicon for that mount point... At any point
- after this, if the connections fail and can not be reconstructed
- for any reason, we will have to unmount the mount point. There
- is no exit from the next call...
- */
- send_fs_socket(lp_ctx, service, mount_point, c);
-}
-
-
-/****************************************************************************
-get a password from a a file or file descriptor
-exit on failure (from smbclient, move to libsmb or shared .c file?)
-****************************************************************************/
-static void get_password_file(void)
-{
- int fd = -1;
- char *p;
- bool close_it = false;
- pstring spec;
- char pass[128];
-
- if ((p = getenv("PASSWD_FD")) != NULL) {
- pstrcpy(spec, "descriptor ");
- pstrcat(spec, p);
- sscanf(p, "%d", &fd);
- close_it = false;
- } else if ((p = getenv("PASSWD_FILE")) != NULL) {
- fd = open(p, O_RDONLY, 0);
- pstrcpy(spec, p);
- if (fd < 0) {
- fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
- spec, strerror(errno));
- exit(1);
- }
- close_it = true;
- }
-
- for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
- p && p - pass < sizeof(pass);) {
- switch (read(fd, p, 1)) {
- case 1:
- if (*p != '\n' && *p != '\0') {
- *++p = '\0'; /* advance p, and null-terminate pass */
- break;
- }
- case 0:
- if (p - pass) {
- *p = '\0'; /* null-terminate it, just in case... */
- p = NULL; /* then force the loop condition to become false */
- break;
- } else {
- fprintf(stderr, "Error reading password from file %s: %s\n",
- spec, "empty password\n");
- exit(1);
- }
-
- default:
- fprintf(stderr, "Error reading password from file %s: %s\n",
- spec, strerror(errno));
- exit(1);
- }
- }
- pstrcpy(password, pass);
- if (close_it)
- close(fd);
-}
-
-/****************************************************************************
-get username and password from a credentials file
-exit on failure (from smbclient, move to libsmb or shared .c file?)
-****************************************************************************/
-static void read_credentials_file(char *filename)
-{
- FILE *auth;
- fstring buf;
- uint16_t len = 0;
- char *ptr, *val, *param;
-
- if ((auth=sys_fopen(filename, "r")) == NULL)
- {
- /* fail if we can't open the credentials file */
- DEBUG(0,("ERROR: Unable to open credentials file!\n"));
- exit (-1);
- }
-
- while (!feof(auth))
- {
- /* get a line from the file */
- if (!fgets (buf, sizeof(buf), auth))
- continue;
- len = strlen(buf);
-
- if ((len) && (buf[len-1]=='\n'))
- {
- buf[len-1] = '\0';
- len--;
- }
- if (len == 0)
- continue;
-
- /* break up the line into parameter & value.
- will need to eat a little whitespace possibly */
- param = buf;
- if (!(ptr = strchr (buf, '=')))
- continue;
- val = ptr+1;
- *ptr = '\0';
-
- /* eat leading white space */
- while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
- val++;
-
- if (strwicmp("password", param) == 0)
- {
- pstrcpy(password, val);
- got_pass = true;
- }
- else if (strwicmp("username", param) == 0) {
- pstrcpy(username, val);
- }
-
- memset(buf, 0, sizeof(buf));
- }
- fclose(auth);
-}
-
-
-/****************************************************************************
-usage on the program
-****************************************************************************/
-static void usage(void)
-{
- printf("Usage: mount.smbfs service mountpoint [-o options,...]\n");
-
- printf("Version %s\n\n",VERSION);
-
- printf(
-"Options:\n\
- username=<arg> SMB username\n\
- password=<arg> SMB password\n\
- credentials=<filename> file with username/password\n\
- krb use kerberos (active directory)\n\
- netbiosname=<arg> source NetBIOS name\n\
- uid=<arg> mount uid or username\n\
- gid=<arg> mount gid or groupname\n\
- port=<arg> remote SMB port number\n\
- fmask=<arg> file umask\n\
- dmask=<arg> directory umask\n\
- debug=<arg> debug level\n\
- ip=<arg> destination host or IP address\n\
- workgroup=<arg> workgroup on destination\n\
- sockopt=<arg> TCP socket options\n\
- scope=<arg> NetBIOS scope\n\
- iocharset=<arg> Linux charset (iso8859-1, utf8)\n\
- codepage=<arg> server codepage (cp850)\n\
- ttl=<arg> dircache time to live\n\
- guest don't prompt for a password\n\
- ro mount read-only\n\
- rw mount read-write\n\
-\n\
-This command is designed to be run from within /bin/mount by giving\n\
-the option '-t smbfs'. For example:\n\
- mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\
-");
-}
-
-
-/****************************************************************************
- Argument parsing for mount.smbfs interface
- mount will call us like this:
- mount.smbfs device mountpoint -o <options>
-
- <options> is never empty, containing at least rw or ro
- ****************************************************************************/
-static void parse_mount_smb(int argc, char **argv)
-{
- int opt;
- char *opts;
- char *opteq;
- extern char *optarg;
- int val;
- char *p;
-
- /* FIXME: This function can silently fail if the arguments are
- * not in the expected order.
-
- > The arguments syntax of smbmount 2.2.3a (smbfs of Debian stable)
- > requires that one gives "-o" before further options like username=...
- > . Without -o, the username=.. setting is *silently* ignored. I've
- > spent about an hour trying to find out why I couldn't log in now..
-
- */
-
-
- if (argc < 2 || argv[1][0] == '-') {
- usage();
- exit(1);
- }
-
- pstrcpy(service, argv[1]);
- pstrcpy(mpoint, argv[2]);
-
- /* Convert any '/' characters in the service name to
- '\' characters */
- string_replace(service, '/','\\');
- argc -= 2;
- argv += 2;
-
- opt = getopt(argc, argv, "o:");
- if(opt != 'o') {
- return;
- }
-
- options[0] = 0;
- p = options;
-
- /*
- * option parsing from nfsmount.c (util-linux-2.9u)
- */
- for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) {
- DEBUG(3, ("opts: %s\n", opts));
- if ((opteq = strchr_m(opts, '='))) {
- val = atoi(opteq + 1);
- *opteq = '\0';
-
- if (!strcmp(opts, "username") ||
- !strcmp(opts, "logon")) {
- char *lp;
- got_user = true;
- pstrcpy(username,opteq+1);
- if ((lp=strchr_m(username,'%'))) {
- *lp = 0;
- pstrcpy(password,lp+1);
- got_pass = true;
- memset(strchr_m(opteq+1,'%')+1,'X',strlen(password));
- }
- if ((lp=strchr_m(username,'/'))) {
- *lp = 0;
- pstrcpy(workgroup,lp+1);
- }
- } else if(!strcmp(opts, "passwd") ||
- !strcmp(opts, "password")) {
- pstrcpy(password,opteq+1);
- got_pass = true;
- memset(opteq+1,'X',strlen(password));
- } else if(!strcmp(opts, "credentials")) {
- pstrcpy(credentials,opteq+1);
- } else if(!strcmp(opts, "netbiosname")) {
- pstrcpy(my_netbios_name,opteq+1);
- } else if(!strcmp(opts, "uid")) {
- mount_uid = nametouid(opteq+1);
- } else if(!strcmp(opts, "gid")) {
- mount_gid = nametogid(opteq+1);
- } else if(!strcmp(opts, "port")) {
- smb_port = val;
- } else if(!strcmp(opts, "fmask")) {
- mount_fmask = strtol(opteq+1, NULL, 8);
- } else if(!strcmp(opts, "dmask")) {
- mount_dmask = strtol(opteq+1, NULL, 8);
- } else if(!strcmp(opts, "debug")) {
- DEBUGLEVEL = val;
- } else if(!strcmp(opts, "ip")) {
- dest_ip = interpret_addr2(opteq+1);
- if (is_zero_ip_v4(dest_ip)) {
- fprintf(stderr,"Can't resolve address %s\n", opteq+1);
- exit(1);
- }
- have_ip = true;
- } else if(!strcmp(opts, "workgroup")) {
- pstrcpy(workgroup,opteq+1);
- } else if(!strcmp(opts, "sockopt")) {
- lp_set_cmdline("socket options", opteq+1);
- } else if(!strcmp(opts, "scope")) {
- lp_set_cmdline("netbios scope", opteq+1);
- } else {
- slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1);
- p += strlen(p);
- }
- } else {
- val = 1;
- if(!strcmp(opts, "nocaps")) {
- fprintf(stderr, "Unhandled option: %s\n", opteq+1);
- exit(1);
- } else if(!strcmp(opts, "guest")) {
- *password = '\0';
- got_pass = true;
- } else if(!strcmp(opts, "krb")) {
-#ifdef HAVE_KRB5
-
- use_kerberos = true;
- if(!status32_smbfs)
- fprintf(stderr, "Warning: kerberos support will only work for samba servers\n");
-#else
- fprintf(stderr,"No kerberos support compiled in\n");
- exit(1);
-#endif
- } else if(!strcmp(opts, "rw")) {
- mount_ro = 0;
- } else if(!strcmp(opts, "ro")) {
- mount_ro = 1;
- } else {
- strncpy(p, opts, sizeof(pstring) - (p - options) - 1);
- p += strlen(opts);
- *p++ = ',';
- *p = 0;
- }
- }
- }
-
- if (!*service) {
- usage();
- exit(1);
- }
-
- if (p != options) {
- *(p-1) = 0; /* remove trailing , */
- DEBUG(3,("passthrough options '%s'\n", options));
- }
-}
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- extern char *optarg;
- extern int optind;
- char *p;
- struct loadparm_context *lp_ctx;
-
- DEBUGLEVEL = 1;
-
- /* here we are interactive, even if run from autofs */
- setup_logging("mount.smbfs",DEBUG_STDERR);
-
-#if 0 /* JRA - Urban says not needed ? */
- /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default
- is to not announce any unicode capabilities as current smbfs does
- not support it. */
- p = getenv("CLI_FORCE_ASCII");
- if (p && !strcmp(p, "false"))
- unsetenv("CLI_FORCE_ASCII");
- else
- setenv("CLI_FORCE_ASCII", "true", 1);
-#endif
-
- if (getenv("USER")) {
- pstrcpy(username,getenv("USER"));
-
- if ((p=strchr_m(username,'%'))) {
- *p = 0;
- pstrcpy(password,p+1);
- got_pass = true;
- memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
- }
- strupper(username);
- }
-
- if (getenv("PASSWD")) {
- pstrcpy(password, getenv("PASSWD"));
- got_pass = true;
- }
-
- if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
- get_password_file();
- got_pass = true;
- }
-
- if (*username == 0 && getenv("LOGNAME")) {
- pstrcpy(username,getenv("LOGNAME"));
- }
-
- lp_ctx = loadparm_init(talloc_autofree_context());
-
- if (!lp_load(lp_ctx, dyn_CONFIGFILE)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n",
- lp_config_file());
- }
-
- parse_mount_smb(argc, argv);
-
- if (use_kerberos && !got_user) {
- got_pass = true;
- }
-
- if (*credentials != 0) {
- read_credentials_file(credentials);
- }
-
- DEBUG(3,("mount.smbfs started (version %s)\n", VERSION));
-
- if (*workgroup == 0) {
- pstrcpy(workgroup, lp_workgroup());
- }
-
- if (!*my_netbios_name) {
- pstrcpy(my_netbios_name, myhostname());
- }
- strupper(my_netbios_name);
-
- init_mount(lp_ctx);
- return 0;
-}
diff --git a/source4/client/smbumount.c b/source4/client/smbumount.c
deleted file mode 100644
index 9ea3083a6f..0000000000
--- a/source4/client/smbumount.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * smbumount.c
- *
- * Copyright (C) 1995-1998 by Volker Lendecke
- *
- */
-
-#include "includes.h"
-
-#include <mntent.h>
-
-#include <asm/types.h>
-#include <asm/posix_types.h>
-#include <linux/smb.h>
-#include <linux/smb_mount.h>
-#include <linux/smb_fs.h>
-
-/* This is a (hopefully) temporary hack due to the fact that
- sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc.
- This may change in the future and smb.h may get fixed in the
- future. In the mean time, it's ugly hack time - get over it.
-*/
-#undef SMB_IOC_GETMOUNTUID
-#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t)
-
-#ifndef O_NOFOLLOW
-#define O_NOFOLLOW 0400000
-#endif
-
-static void
-usage(void)
-{
- printf("usage: smbumount mountpoint\n");
-}
-
-static int
-umount_ok(const char *mount_point)
-{
- /* we set O_NOFOLLOW to prevent users playing games with symlinks to
- umount filesystems they don't own */
- int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0);
- __kernel_uid_t mount_uid;
-
- if (fid == -1) {
- fprintf(stderr, "Could not open %s: %s\n",
- mount_point, strerror(errno));
- return -1;
- }
-
- if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid) != 0) {
- fprintf(stderr, "%s probably not smb-filesystem\n",
- mount_point);
- return -1;
- }
-
- if ((getuid() != 0)
- && (mount_uid != getuid())) {
- fprintf(stderr, "You are not allowed to umount %s\n",
- mount_point);
- return -1;
- }
-
- close(fid);
- return 0;
-}
-
-/* Make a canonical pathname from PATH. Returns a freshly malloced string.
- It is up the *caller* to ensure that the PATH is sensible. i.e.
- canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
- is not a legal pathname for ``/dev/fd0'' Anything we cannot parse
- we return unmodified. */
-static char *
-canonicalize (char *path)
-{
- char *canonical = malloc (PATH_MAX + 1);
-
- if (!canonical) {
- fprintf(stderr, "Error! Not enough memory!\n");
- return NULL;
- }
-
- if (strlen(path) > PATH_MAX) {
- fprintf(stderr, "Mount point string too long\n");
- return NULL;
- }
-
- if (path == NULL)
- return NULL;
-
- if (realpath (path, canonical))
- return canonical;
-
- strncpy (canonical, path, PATH_MAX);
- canonical[PATH_MAX] = '\0';
- return canonical;
-}
-
-
-int
-main(int argc, char *argv[])
-{
- int fd;
- char* mount_point;
- struct mntent *mnt;
- FILE* mtab;
- FILE* new_mtab;
-
- if (argc != 2) {
- usage();
- exit(1);
- }
-
- if (geteuid() != 0) {
- fprintf(stderr, "smbumount must be installed suid root\n");
- exit(1);
- }
-
- mount_point = canonicalize(argv[1]);
-
- if (mount_point == NULL)
- {
- exit(1);
- }
-
- if (umount_ok(mount_point) != 0) {
- exit(1);
- }
-
- if (umount(mount_point) != 0) {
- fprintf(stderr, "Could not umount %s: %s\n",
- mount_point, strerror(errno));
- exit(1);
- }
-
- if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
- {
- fprintf(stderr, "Can't get "MOUNTED"~ lock file");
- return 1;
- }
- close(fd);
-
- if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
- fprintf(stderr, "Can't open " MOUNTED ": %s\n",
- strerror(errno));
- return 1;
- }
-
-#define MOUNTED_TMP MOUNTED".tmp"
-
- if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
- fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
- strerror(errno));
- endmntent(mtab);
- return 1;
- }
-
- while ((mnt = getmntent(mtab)) != NULL) {
- if (strcmp(mnt->mnt_dir, mount_point) != 0) {
- addmntent(new_mtab, mnt);
- }
- }
-
- endmntent(mtab);
-
- if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
- fprintf(stderr, "Error changing mode of %s: %s\n",
- MOUNTED_TMP, strerror(errno));
- exit(1);
- }
-
- endmntent(new_mtab);
-
- if (rename(MOUNTED_TMP, MOUNTED) < 0) {
- fprintf(stderr, "Cannot rename %s to %s: %s\n",
- MOUNTED, MOUNTED_TMP, strerror(errno));
- exit(1);
- }
-
- if (unlink(MOUNTED"~") == -1)
- {
- fprintf(stderr, "Can't remove "MOUNTED"~");
- return 1;
- }
-
- return 0;
-}
diff --git a/source4/configure.ac b/source4/configure.ac
index 82dd1346da..943a7c4345 100644
--- a/source4/configure.ac
+++ b/source4/configure.ac
@@ -99,6 +99,7 @@ SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = LDB_REQUIRED_VERSION,
SMB_INCLUDE_MK(lib/ldb/python.mk)
m4_include(lib/tls/config.m4)
+m4_include(torture/libnetapi/config.m4)
dnl m4_include(auth/kerberos/config.m4)
m4_include(auth/gensec/config.m4)
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index a924024160..38858efc7c 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -6,17 +6,17 @@
Copyright (C) Andrew Tridgell 2005
Copyright (C) Volker Lendecke 2004
Copyright (C) Stefan Metzmacher 2004
-
+
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/>.
*/
@@ -77,20 +77,20 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn,
ldapsrv_terminate_connection(conn, "no memory");
return;
}
-
+
call->request = talloc_steal(call, msg);
call->conn = conn;
call->replies = NULL;
call->send_callback = NULL;
call->send_private = NULL;
-
+
/* make the call */
status = ldapsrv_do_call(call);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(call);
return;
}
-
+
blob = data_blob(NULL, 0);
if (call->replies == NULL) {
@@ -210,7 +210,7 @@ static void ldapsrv_send(struct stream_connection *c, uint16_t flags)
{
struct ldapsrv_connection *conn =
talloc_get_type(c->private_data, struct ldapsrv_connection);
-
+
packet_queue_run(conn->packet);
}
@@ -294,7 +294,7 @@ static int ldapsrv_load_limits(struct ldapsrv_connection *conn)
s = sscanf((const char *)el->values[i].data, "%255[^=]=%d", policy_name, &policy_value);
if (ret != 2 || policy_value == 0)
continue;
-
+
if (strcasecmp("InitRecvTimeout", policy_name) == 0) {
conn->limits.initial_timeout = policy_value;
continue;
@@ -390,7 +390,7 @@ static void ldapsrv_accept(struct stream_connection *c)
if (conn->sockets.tls) {
packet_set_unreliable_select(conn->packet);
}
-
+
/* Ensure we don't get packets until the database is ready below */
packet_recv_disable(conn->packet);
@@ -399,7 +399,7 @@ static void ldapsrv_accept(struct stream_connection *c)
stream_terminate_connection(c, "Failed to init server credentials\n");
return;
}
-
+
cli_credentials_set_conf(server_credentials, conn->lp_ctx);
status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx);
if (!NT_STATUS_IS_OK(status)) {
@@ -483,7 +483,7 @@ static NTSTATUS add_socket(struct tevent_context *event_context,
if (!ldb) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
-
+
if (samdb_is_gc(ldb)) {
port = 3268;
status = stream_setup_socket(event_context, lp_ctx,
diff --git a/source4/libcli/security/sddl.c b/source4/libcli/security/sddl.c
index a8d893f085..39bdf047ac 100644
--- a/source4/libcli/security/sddl.c
+++ b/source4/libcli/security/sddl.c
@@ -80,11 +80,34 @@ static const struct {
{ "CO", SID_CREATOR_OWNER },
{ "CG", SID_CREATOR_GROUP },
+ { "AN", SID_NT_ANONYMOUS },
+ { "BG", SID_BUILTIN_GUESTS },
+ { "BO", SID_BUILTIN_BACKUP_OPERATORS },
+ { "BU", SID_BUILTIN_USERS },
+ { "IU", SID_NT_INTERACTIVE },
+ { "LS", SID_NT_LOCAL_SERVICE },
+ { "NO", SID_BUILTIN_NETWORK_CONF_OPERATORS },
+ { "NS", SID_NT_NETWORK_SERVICE },
+ { "NU", SID_NT_NETWORK },
+ { "PU", SID_BUILTIN_POWER_USERS },
+ { "RC", SID_NT_RESTRICTED },
+ { "RD", SID_BUILTIN_REMOTE_DESKTOP_USERS },
+ { "RE", SID_BUILTIN_REPLICATOR },
+ { "SO", SID_BUILTIN_ACCOUNT_OPERATORS },
+ { "SU", SID_NT_SERVICE },
+
{ "DA", NULL, DOMAIN_RID_ADMINS },
{ "EA", NULL, DOMAIN_RID_ENTERPRISE_ADMINS },
{ "DD", NULL, DOMAIN_RID_DCS },
{ "DU", NULL, DOMAIN_RID_USERS },
{ "CA", NULL, DOMAIN_RID_CERT_ADMINS },
+
+ { "DC", NULL, DOMAIN_RID_DOMAIN_MEMBERS },
+ { "DG", NULL, DOMAIN_RID_GUESTS },
+ { "LA", NULL, DOMAIN_RID_ADMINISTRATOR },
+ { "LG", NULL, DOMAIN_RID_GUEST },
+ { "PA", NULL, DOMAIN_RID_POLICY_ADMINS },
+ { "SA", NULL, DOMAIN_RID_SCHEMA_ADMINS },
};
/*
diff --git a/source4/libcli/wbclient/config.mk b/source4/libcli/wbclient/config.mk
index 00df5dbb22..af4d3eff82 100644
--- a/source4/libcli/wbclient/config.mk
+++ b/source4/libcli/wbclient/config.mk
@@ -1,5 +1,5 @@
-[SUBSYSTEM::LIBWBCLIENT]
+[SUBSYSTEM::LIBWBCLIENT_OLD]
PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBEVENTS
PRIVATE_DEPENDENCIES = NDR_WINBIND MESSAGING
-LIBWBCLIENT_OBJ_FILES = $(libclisrcdir)/wbclient/wbclient.o
+LIBWBCLIENT_OLD_OBJ_FILES = $(libclisrcdir)/wbclient/wbclient.o
diff --git a/source4/main.mk b/source4/main.mk
index 2e74ba9a5b..b4a82017c8 100644
--- a/source4/main.mk
+++ b/source4/main.mk
@@ -7,6 +7,7 @@ mkinclude smbd/process_model.mk
mkinclude libnet/config.mk
mkinclude auth/config.mk
mkinclude ../nsswitch/config.mk
+mkinclude ../nsswitch/libwbclient/config.mk
mkinclude lib/samba3/config.mk
mkinclude lib/socket/config.mk
mkinclude ../lib/util/charset/config.mk
diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk
index 1d7949214a..1aaef3f1d4 100644
--- a/source4/ntvfs/posix/config.mk
+++ b/source4/ntvfs/posix/config.mk
@@ -42,7 +42,7 @@ OUTPUT_TYPE = MERGED_OBJ
INIT_FUNCTION = ntvfs_posix_init
#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4
PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING \
- LIBWBCLIENT pvfs_acl pvfs_aio
+ LIBWBCLIENT_OLD pvfs_acl pvfs_aio
# End MODULE ntvfs_posix
################################################
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk
index dfc3d17bed..f3dc074125 100644
--- a/source4/rpc_server/config.mk
+++ b/source4/rpc_server/config.mk
@@ -85,7 +85,7 @@ PRIVATE_DEPENDENCIES = \
SAMDB \
NDR_UNIXINFO \
NSS_WRAPPER \
- LIBWBCLIENT
+ LIBWBCLIENT_OLD
# End MODULE dcerpc_unixinfo
################################################
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index fabc88d02d..03acf97cab 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -1213,6 +1213,9 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
if (d_state->builtin) {
DEBUG(5, ("Cannot create a user in the BUILTIN domain"));
return NT_STATUS_ACCESS_DENIED;
+ } else if (r->in.acct_flags == ACB_DOMTRUST) {
+ /* Domain trust accounts must be created by the LSA calls */
+ return NT_STATUS_ACCESS_DENIED;
}
account_name = r->in.account_name->string;
@@ -1220,6 +1223,11 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
return NT_STATUS_INVALID_PARAMETER;
}
+ /*
+ * Start a transaction, so we can query and do a subsequent atomic
+ * modify
+ */
+
ret = ldb_transaction_start(d_state->sam_ctx);
if (ret != 0) {
DEBUG(0,("Failed to start a transaction for user creation: %s\n",
@@ -1258,6 +1266,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
} else if (r->in.acct_flags == ACB_WSTRUST) {
if (cn_name[cn_name_len - 1] != '$') {
+ ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_FOOBAR;
}
cn_name[cn_name_len - 1] = '\0';
@@ -1267,17 +1276,13 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
} else if (r->in.acct_flags == ACB_SVRTRUST) {
if (cn_name[cn_name_len - 1] != '$') {
+ ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_FOOBAR;
}
cn_name[cn_name_len - 1] = '\0';
container = "OU=Domain Controllers";
obj_class = "computer";
samdb_msg_add_int(d_state->sam_ctx, mem_ctx, msg, "primaryGroupID", DOMAIN_RID_DCS);
-
- } else if (r->in.acct_flags == ACB_DOMTRUST) {
- container = "CN=Users";
- obj_class = "user";
-
} else {
ldb_transaction_cancel(d_state->sam_ctx);
return NT_STATUS_INVALID_PARAMETER;
@@ -1292,9 +1297,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL
samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "sAMAccountName", account_name);
samdb_msg_add_string(d_state->sam_ctx, mem_ctx, msg, "objectClass", obj_class);
-
- /* Start a transaction, so we can query and do a subsequent atomic modify */
-
+
/* create the user */
ret = ldb_add(d_state->sam_ctx, msg);
switch (ret) {
diff --git a/source4/selftest/tests.sh b/source4/selftest/tests.sh
index 79199bc2c0..58cdc0898b 100755
--- a/source4/selftest/tests.sh
+++ b/source4/selftest/tests.sh
@@ -117,7 +117,7 @@ plantest "ldb" none TEST_DATA_PREFIX=\$PREFIX $LDBDIR/tests/test-tdb.sh
ncacn_np_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-HANDLES RPC-SAMSYNC RPC-SAMBA3SESSIONKEY RPC-SAMBA3-GETUSERNAME RPC-SAMBA3-LSA RPC-BINDSAMBA3 RPC-NETLOGSAMBA3 RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT"
ncalrpc_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-DRSUAPI RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT"
ncacn_ip_tcp_tests="RPC-SCHANNEL RPC-JOIN RPC-LSA RPC-DSSETUP RPC-ALTERCONTEXT RPC-MULTIBIND RPC-NETLOGON RPC-HANDLES RPC-DSSYNC RPC-ASYNCBIND RPC-LSALOOKUP RPC-LSA-GETUSER RPC-SCHANNEL2 RPC-AUTHCONTEXT RPC-OBJECTUUID"
-slow_ncacn_np_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-PASSWORDS"
+slow_ncacn_np_tests="RPC-SAMLOGON RPC-SAMR RPC-SAMR-USERS RPC-SAMR-USERS-PRIVILEGES RPC-SAMR-PASSWORDS RPC-SAMR-PASSWORDS-PWDLASTSET"
slow_ncalrpc_tests="RPC-SAMR RPC-SAMR-PASSWORDS"
slow_ncacn_ip_tcp_tests="RPC-SAMR RPC-SAMR-PASSWORDS RPC-CRACKNAMES"
diff --git a/source4/setup/provision_configuration.ldif b/source4/setup/provision_configuration.ldif
index 63b807ba4a..fff380505f 100644
--- a/source4/setup/provision_configuration.ldif
+++ b/source4/setup/provision_configuration.ldif
@@ -96,21 +96,15 @@ dn: CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: container
cn: Extended-Rights
-instanceType: 4
-showInAdvancedViewOnly: TRUE
systemFlags: -2147483648
-objectCategory: CN=Container,CN=Schema,${CONFIGDN}
dn: CN=Change-Rid-Master,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Change-Rid-Master
-instanceType: 4
displayName: Change Rid Master
-showInAdvancedViewOnly: TRUE
rightsGuid: d58d5f36-0a98-11d1-adbb-00c04fd8d5cd
appliesTo: 6617188d-8f3c-11d0-afda-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 29
validAccesses: 256
@@ -118,12 +112,9 @@ dn: CN=Do-Garbage-Collection,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Do-Garbage-Collection
-instanceType: 4
displayName: Do Garbage Collection
-showInAdvancedViewOnly: TRUE
rightsGuid: fec364e0-0a98-11d1-adbb-00c04fd8d5cd
appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 31
validAccesses: 256
@@ -131,12 +122,9 @@ dn: CN=Recalculate-Hierarchy,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Recalculate-Hierarchy
-instanceType: 4
displayName: Recalculate Hierarchy
-showInAdvancedViewOnly: TRUE
rightsGuid: 0bc1554e-0a99-11d1-adbb-00c04fd8d5cd
appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 32
validAccesses: 256
@@ -144,12 +132,9 @@ dn: CN=Allocate-Rids,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Allocate-Rids
-instanceType: 4
displayName: Allocate Rids
-showInAdvancedViewOnly: TRUE
rightsGuid: 1abd7cf8-0a99-11d1-adbb-00c04fd8d5cd
appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 33
validAccesses: 256
@@ -157,12 +142,9 @@ dn: CN=Change-PDC,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Change-PDC
-instanceType: 4
displayName: Change PDC
-showInAdvancedViewOnly: TRUE
rightsGuid: bae50096-4752-11d1-9052-00c04fc2d4cf
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 34
validAccesses: 256
@@ -170,12 +152,9 @@ dn: CN=Add-GUID,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Add-GUID
-instanceType: 4
displayName: Add GUID
-showInAdvancedViewOnly: TRUE
rightsGuid: 440820ad-65b4-11d1-a3da-0000f875ae0d
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 35
validAccesses: 256
@@ -183,12 +162,9 @@ dn: CN=Change-Domain-Master,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Change-Domain-Master
-instanceType: 4
displayName: Change Domain Master
-showInAdvancedViewOnly: TRUE
rightsGuid: 014bf69c-7b3b-11d1-85f6-08002be74fab
appliesTo: ef9e60e0-56f7-11d1-a9c6-0000f80367c1
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 36
validAccesses: 256
@@ -196,14 +172,11 @@ dn: CN=Public-Information,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Public-Information
-instanceType: 4
displayName: Public Information
-showInAdvancedViewOnly: TRUE
rightsGuid: e48d0154-bcf8-11d1-8702-00c04fb96050
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 37
validAccesses: 48
@@ -211,12 +184,9 @@ dn: CN=msmq-Receive-Dead-Letter,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: msmq-Receive-Dead-Letter
-instanceType: 4
displayName: Receive Dead Letter
-showInAdvancedViewOnly: TRUE
rightsGuid: 4b6e08c0-df3c-11d1-9c86-006008764d0e
appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 38
validAccesses: 256
@@ -224,12 +194,9 @@ dn: CN=msmq-Peek-Dead-Letter,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: msmq-Peek-Dead-Letter
-instanceType: 4
displayName: Peek Dead Letter
-showInAdvancedViewOnly: TRUE
rightsGuid: 4b6e08c1-df3c-11d1-9c86-006008764d0e
appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 39
validAccesses: 256
@@ -237,12 +204,9 @@ dn: CN=msmq-Receive-computer-Journal,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: msmq-Receive-computer-Journal
-instanceType: 4
displayName: Receive Computer Journal
-showInAdvancedViewOnly: TRUE
rightsGuid: 4b6e08c2-df3c-11d1-9c86-006008764d0e
appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 40
validAccesses: 256
@@ -250,12 +214,9 @@ dn: CN=msmq-Peek-computer-Journal,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: msmq-Peek-computer-Journal
-instanceType: 4
displayName: Peek Computer Journal
-showInAdvancedViewOnly: TRUE
rightsGuid: 4b6e08c3-df3c-11d1-9c86-006008764d0e
appliesTo: 9a0dc344-c100-11d1-bbc5-0080c76670c0
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 41
validAccesses: 256
@@ -263,12 +224,9 @@ dn: CN=msmq-Receive,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: msmq-Receive
-instanceType: 4
displayName: Receive Message
-showInAdvancedViewOnly: TRUE
rightsGuid: 06bd3200-df3e-11d1-9c86-006008764d0e
appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 42
validAccesses: 256
@@ -276,12 +234,9 @@ dn: CN=msmq-Peek,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: msmq-Peek
-instanceType: 4
displayName: Peek Message
-showInAdvancedViewOnly: TRUE
rightsGuid: 06bd3201-df3e-11d1-9c86-006008764d0e
appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 43
validAccesses: 256
@@ -289,13 +244,10 @@ dn: CN=msmq-Send,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: msmq-Send
-instanceType: 4
displayName: Send Message
-showInAdvancedViewOnly: TRUE
rightsGuid: 06bd3202-df3e-11d1-9c86-006008764d0e
appliesTo: 46b27aac-aafa-4ffb-b773-e5bf621ee87b
appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 44
validAccesses: 256
@@ -303,12 +255,9 @@ dn: CN=msmq-Receive-journal,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: msmq-Receive-journal
-instanceType: 4
displayName: Receive Journal
-showInAdvancedViewOnly: TRUE
rightsGuid: 06bd3203-df3e-11d1-9c86-006008764d0e
appliesTo: 9a0dc343-c100-11d1-bbc5-0080c76670c0
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 45
validAccesses: 256
@@ -316,12 +265,9 @@ dn: CN=msmq-Open-Connector,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: msmq-Open-Connector
-instanceType: 4
displayName: Open Connector Queue
-showInAdvancedViewOnly: TRUE
rightsGuid: b4e60130-df3f-11d1-9c86-006008764d0e
appliesTo: bf967ab3-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 46
validAccesses: 256
@@ -329,12 +275,9 @@ dn: CN=Apply-Group-Policy,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Apply-Group-Policy
-instanceType: 4
displayName: Apply Group Policy
-showInAdvancedViewOnly: TRUE
rightsGuid: edacfd8f-ffb3-11d1-b41d-00a0c968f939
appliesTo: f30e3bc2-9ff0-11d1-b603-0000f80367c1
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 47
validAccesses: 256
@@ -342,13 +285,10 @@ dn: CN=RAS-Information,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: RAS-Information
-instanceType: 4
displayName: Remote Access Information
-showInAdvancedViewOnly: TRUE
rightsGuid: 037088f8-0ae1-11d2-b422-00a0c968f939
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 48
validAccesses: 48
@@ -356,12 +296,9 @@ dn: CN=DS-Install-Replica,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DS-Install-Replica
-instanceType: 4
displayName: Add/Remove Replica In Domain
-showInAdvancedViewOnly: TRUE
rightsGuid: 9923a32a-3607-11d2-b9be-0000f87a36b2
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 49
validAccesses: 256
@@ -369,12 +306,9 @@ dn: CN=Change-Infrastructure-Master,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Change-Infrastructure-Master
-instanceType: 4
displayName: Change Infrastructure Master
-showInAdvancedViewOnly: TRUE
rightsGuid: cc17b1fb-33d9-11d2-97d4-00c04fd8d5cd
appliesTo: 2df90d89-009f-11d2-aa4c-00c04fd7d83a
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 50
validAccesses: 256
@@ -382,12 +316,9 @@ dn: CN=Update-Schema-Cache,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Update-Schema-Cache
-instanceType: 4
displayName: Update Schema Cache
-showInAdvancedViewOnly: TRUE
rightsGuid: be2bb760-7f46-11d2-b9ad-00c04f79f805
appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 51
validAccesses: 256
@@ -395,12 +326,9 @@ dn: CN=Recalculate-Security-Inheritance,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Recalculate-Security-Inheritance
-instanceType: 4
displayName: Recalculate Security Inheritance
-showInAdvancedViewOnly: TRUE
rightsGuid: 62dd28a8-7f46-11d2-b9ad-00c04f79f805
appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 52
validAccesses: 256
@@ -408,12 +336,9 @@ dn: CN=DS-Check-Stale-Phantoms,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DS-Check-Stale-Phantoms
-instanceType: 4
displayName: Check Stale Phantoms
-showInAdvancedViewOnly: TRUE
rightsGuid: 69ae6200-7f46-11d2-b9ad-00c04f79f805
appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 53
validAccesses: 256
@@ -421,12 +346,9 @@ dn: CN=Certificate-Enrollment,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Certificate-Enrollment
-instanceType: 4
displayName: Enroll
-showInAdvancedViewOnly: TRUE
rightsGuid: 0e10c968-78fb-11d2-90d4-00c04f79dc55
appliesTo: e5209ca2-3bba-11d2-90cc-00c04fd91ab1
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 54
validAccesses: 256
@@ -434,12 +356,9 @@ dn: CN=Self-Membership,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Self-Membership
-instanceType: 4
displayName: Add/Remove self as member
-showInAdvancedViewOnly: TRUE
rightsGuid: bf9679c0-0de6-11d0-a285-00aa003049e2
appliesTo: bf967a9c-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 12
validAccesses: 8
@@ -447,12 +366,9 @@ dn: CN=Validated-DNS-Host-Name,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Validated-DNS-Host-Name
-instanceType: 4
displayName: Validated write to DNS host name
-showInAdvancedViewOnly: TRUE
rightsGuid: 72e39547-7b18-11d1-adef-00c04fd8d5cd
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 13
validAccesses: 8
@@ -460,12 +376,9 @@ dn: CN=Validated-SPN,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Validated-SPN
-instanceType: 4
displayName: Validated write to service principal name
-showInAdvancedViewOnly: TRUE
rightsGuid: f3a64788-5306-11d1-a9c5-0000f80367c1
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 14
validAccesses: 8
@@ -473,13 +386,10 @@ dn: CN=Generate-RSoP-Planning,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Generate-RSoP-Planning
-instanceType: 4
displayName: Generate Resultant Set of Policy (Planning)
-showInAdvancedViewOnly: TRUE
rightsGuid: b7b1b3dd-ab09-4242-9e30-9980e5d322f7
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
appliesTo: bf967aa5-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 55
validAccesses: 256
@@ -487,12 +397,9 @@ dn: CN=Refresh-Group-Cache,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Refresh-Group-Cache
-instanceType: 4
displayName: Refresh Group Cache for Logons
-showInAdvancedViewOnly: TRUE
rightsGuid: 9432c620-033c-4db7-8b58-14ef6d0bf477
appliesTo: f0f8ffab-1191-11d0-a060-00aa006c33ed
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 56
validAccesses: 256
@@ -500,12 +407,9 @@ dn: CN=SAM-Enumerate-Entire-Domain,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: SAM-Enumerate-Entire-Domain
-instanceType: 4
displayName: Enumerate Entire SAM Domain
-showInAdvancedViewOnly: TRUE
rightsGuid: 91d67418-0135-4acc-8d79-c08e857cfbec
appliesTo: bf967aad-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 57
validAccesses: 256
@@ -513,13 +417,10 @@ dn: CN=Generate-RSoP-Logging,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Generate-RSoP-Logging
-instanceType: 4
displayName: Generate Resultant Set of Policy (Logging)
-showInAdvancedViewOnly: TRUE
rightsGuid: b7b1b3de-ab09-4242-9e30-9980e5d322f7
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
appliesTo: bf967aa5-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 58
validAccesses: 256
@@ -527,12 +428,9 @@ dn: CN=Domain-Other-Parameters,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Domain-Other-Parameters
-instanceType: 4
displayName: Other Domain Parameters (for use by SAM)
-showInAdvancedViewOnly: TRUE
rightsGuid: b8119fd0-04f6-4762-ab7a-4986c76b3f9a
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 59
validAccesses: 48
@@ -540,12 +438,9 @@ dn: CN=DNS-Host-Name-Attributes,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DNS-Host-Name-Attributes
-instanceType: 4
displayName: DNS Host Name Attributes
-showInAdvancedViewOnly: TRUE
rightsGuid: 72e39547-7b18-11d1-adef-00c04fd8d5cd
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 60
validAccesses: 48
@@ -553,12 +448,9 @@ dn: CN=Create-Inbound-Forest-Trust,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Create-Inbound-Forest-Trust
-instanceType: 4
displayName: Create Inbound Forest Trust
-showInAdvancedViewOnly: TRUE
rightsGuid: e2a36dc9-ae17-47c3-b58b-be34c55ba633
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 61
validAccesses: 256
@@ -566,14 +458,11 @@ dn: CN=DS-Replication-Get-Changes-All,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DS-Replication-Get-Changes-All
-instanceType: 4
displayName: Replicating Directory Changes All
-showInAdvancedViewOnly: TRUE
rightsGuid: 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2
appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 62
validAccesses: 256
@@ -581,12 +470,9 @@ dn: CN=Migrate-SID-History,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Migrate-SID-History
-instanceType: 4
displayName: Migrate SID History
-showInAdvancedViewOnly: TRUE
rightsGuid: BA33815A-4F93-4c76-87F3-57574BFF8109
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 63
validAccesses: 256
@@ -594,14 +480,11 @@ dn: CN=Reanimate-Tombstones,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Reanimate-Tombstones
-instanceType: 4
displayName: Reanimate Tombstones
-showInAdvancedViewOnly: TRUE
rightsGuid: 45EC5156-DB7E-47bb-B53F-DBEB2D03C40F
appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2
appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 64
validAccesses: 256
@@ -609,14 +492,11 @@ dn: CN=Allowed-To-Authenticate,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Allowed-To-Authenticate
-instanceType: 4
displayName: Allowed to Authenticate
-showInAdvancedViewOnly: TRUE
rightsGuid: 68B1D179-0D15-4d4f-AB71-46152E79A7BC
appliesTo: 4828cc14-1437-45bc-9b07-ad6f015e5f28
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 65
validAccesses: 256
@@ -624,12 +504,9 @@ dn: CN=DS-Execute-Intentions-Script,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DS-Execute-Intentions-Script
-instanceType: 4
displayName: Execute Forest Update Script
-showInAdvancedViewOnly: TRUE
rightsGuid: 2f16c4a5-b98e-432c-952a-cb388ba33f2e
appliesTo: ef9e60e0-56f7-11d1-a9c6-0000f80367c1
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 66
validAccesses: 256
@@ -637,14 +514,11 @@ dn: CN=DS-Replication-Monitor-Topology,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DS-Replication-Monitor-Topology
-instanceType: 4
displayName: Monitor Active Directory Replication
-showInAdvancedViewOnly: TRUE
rightsGuid: f98340fb-7c5b-4cdb-a00b-2ebdfa115a96
appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2
appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 67
validAccesses: 256
@@ -652,12 +526,9 @@ dn: CN=Update-Password-Not-Required-Bit,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Update-Password-Not-Required-Bit
-instanceType: 4
displayName: Update Password Not Required Bit
-showInAdvancedViewOnly: TRUE
rightsGuid: 280f369c-67c7-438e-ae98-1d46f3c6f541
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 68
validAccesses: 256
@@ -665,12 +536,9 @@ dn: CN=Unexpire-Password,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Unexpire-Password
-instanceType: 4
displayName: Unexpire Password
-showInAdvancedViewOnly: TRUE
rightsGuid: ccc2dc7d-a6ad-4a7a-8846-c04e3cc53501
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 69
validAccesses: 256
@@ -678,12 +546,9 @@ dn: CN=Enable-Per-User-Reversibly-Encrypted-Password,CN=Extended-Rights,${CONFIG
objectClass: top
objectClass: controlAccessRight
cn: Enable-Per-User-Reversibly-Encrypted-Password
-instanceType: 4
displayName: Enable Per User Reversibly Encrypted Password
-showInAdvancedViewOnly: TRUE
rightsGuid: 05c74c5e-4deb-43b4-bd9f-86664c2a7fd5
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 70
validAccesses: 256
@@ -691,12 +556,9 @@ dn: CN=DS-Query-Self-Quota,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DS-Query-Self-Quota
-instanceType: 4
displayName: Query Self Quota
-showInAdvancedViewOnly: TRUE
rightsGuid: 4ecc03fe-ffc0-4947-b630-eb672a8a9dbc
appliesTo: da83fc4f-076f-4aea-b4dc-8f4dab9b5993
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 71
validAccesses: 256
@@ -704,12 +566,9 @@ dn: CN=Domain-Administer-Server,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Domain-Administer-Server
-instanceType: 4
displayName: Domain Administer Server
-showInAdvancedViewOnly: TRUE
rightsGuid: ab721a52-1e2f-11d0-9819-00aa0040529b
appliesTo: bf967aad-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 1
validAccesses: 256
@@ -717,14 +576,11 @@ dn: CN=User-Change-Password,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: User-Change-Password
-instanceType: 4
displayName: Change Password
-showInAdvancedViewOnly: TRUE
rightsGuid: ab721a53-1e2f-11d0-9819-00aa0040529b
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 2
validAccesses: 256
@@ -732,14 +588,11 @@ dn: CN=User-Force-Change-Password,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: User-Force-Change-Password
-instanceType: 4
displayName: Reset Password
-showInAdvancedViewOnly: TRUE
rightsGuid: 00299570-246d-11d0-a768-00aa006e0529
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 3
validAccesses: 256
@@ -747,14 +600,11 @@ dn: CN=Send-As,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Send-As
-instanceType: 4
displayName: Send As
-showInAdvancedViewOnly: TRUE
rightsGuid: ab721a54-1e2f-11d0-9819-00aa0040529b
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 4
validAccesses: 256
@@ -762,14 +612,11 @@ dn: CN=Receive-As,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Receive-As
-instanceType: 4
displayName: Receive As
-showInAdvancedViewOnly: TRUE
rightsGuid: ab721a56-1e2f-11d0-9819-00aa0040529b
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 5
validAccesses: 256
@@ -777,12 +624,9 @@ dn: CN=Send-To,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Send-To
-instanceType: 4
displayName: Send To
-showInAdvancedViewOnly: TRUE
rightsGuid: ab721a55-1e2f-11d0-9819-00aa0040529b
appliesTo: bf967a9c-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 6
validAccesses: 256
@@ -790,13 +634,10 @@ dn: CN=Domain-Password,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Domain-Password
-instanceType: 4
displayName: Domain Password & Lockout Policies
-showInAdvancedViewOnly: TRUE
rightsGuid: c7407360-20bf-11d0-a768-00aa006e0529
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
appliesTo: 19195a5a-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 7
validAccesses: 48
@@ -804,13 +645,10 @@ dn: CN=General-Information,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: General-Information
-instanceType: 4
displayName: General Information
-showInAdvancedViewOnly: TRUE
rightsGuid: 59ba2f42-79a2-11d0-9020-00c04fc2d3cf
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 8
validAccesses: 48
@@ -818,14 +656,11 @@ dn: CN=User-Account-Restrictions,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: User-Account-Restrictions
-instanceType: 4
displayName: Account Restrictions
-showInAdvancedViewOnly: TRUE
rightsGuid: 4c164200-20c0-11d0-a768-00aa006e0529
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 9
validAccesses: 48
@@ -833,13 +668,10 @@ dn: CN=User-Logon,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: User-Logon
-instanceType: 4
displayName: Logon Information
-showInAdvancedViewOnly: TRUE
rightsGuid: 5f202010-79a5-11d0-9020-00c04fc2d4cf
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 10
validAccesses: 48
@@ -847,13 +679,10 @@ dn: CN=Membership,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Membership
-instanceType: 4
displayName: Group Membership
-showInAdvancedViewOnly: TRUE
rightsGuid: bc0ac240-79a9-11d0-9020-00c04fc2d4cf
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 11
validAccesses: 48
@@ -861,12 +690,9 @@ dn: CN=Open-Address-Book,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Open-Address-Book
-instanceType: 4
displayName: Open Address List
-showInAdvancedViewOnly: TRUE
rightsGuid: a1990816-4298-11d1-ade2-00c04fd8d5cd
appliesTo: 3e74f60f-3e73-11d1-a9c0-0000f80367c1
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 21
validAccesses: 256
@@ -874,15 +700,12 @@ dn: CN=Personal-Information,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Personal-Information
-instanceType: 4
displayName: Personal Information
-showInAdvancedViewOnly: TRUE
rightsGuid: 77B5B886-944A-11d1-AEBD-0000F80367C1
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967a86-0de6-11d0-a285-00aa003049e2
appliesTo: 5cb41ed0-0e4c-11d0-a286-00aa003049e2
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 23
validAccesses: 48
@@ -890,14 +713,11 @@ dn: CN=Email-Information,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Email-Information
-instanceType: 4
displayName: Phone and Mail Options
-showInAdvancedViewOnly: TRUE
rightsGuid: E45795B2-9455-11d1-AEBD-0000F80367C1
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: bf967a9c-0de6-11d0-a285-00aa003049e2
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 22
validAccesses: 48
@@ -905,14 +725,11 @@ dn: CN=Web-Information,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Web-Information
-instanceType: 4
displayName: Web Information
-showInAdvancedViewOnly: TRUE
rightsGuid: E45795B3-9455-11d1-AEBD-0000F80367C1
appliesTo: 4828CC14-1437-45bc-9B07-AD6F015E5F28
appliesTo: 5cb41ed0-0e4c-11d0-a286-00aa003049e2
appliesTo: bf967aba-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 24
validAccesses: 48
@@ -920,14 +737,11 @@ dn: CN=DS-Replication-Get-Changes,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DS-Replication-Get-Changes
-instanceType: 4
displayName: Replicating Directory Changes
-showInAdvancedViewOnly: TRUE
rightsGuid: 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2
appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 25
validAccesses: 256
@@ -935,14 +749,11 @@ dn: CN=DS-Replication-Synchronize,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DS-Replication-Synchronize
-instanceType: 4
displayName: Replication Synchronization
-showInAdvancedViewOnly: TRUE
rightsGuid: 1131f6ab-9c07-11d1-f79f-00c04fc2dcd2
appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2
appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 26
validAccesses: 256
@@ -950,14 +761,11 @@ dn: CN=DS-Replication-Manage-Topology,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: DS-Replication-Manage-Topology
-instanceType: 4
displayName: Manage Replication Topology
-showInAdvancedViewOnly: TRUE
rightsGuid: 1131f6ac-9c07-11d1-f79f-00c04fc2dcd2
appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2
appliesTo: bf967a87-0de6-11d0-a285-00aa003049e2
appliesTo: 19195a5b-6da0-11d0-afd3-00c04fd930c9
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 27
validAccesses: 256
@@ -965,11 +773,8 @@ dn: CN=Change-Schema-Master,CN=Extended-Rights,${CONFIGDN}
objectClass: top
objectClass: controlAccessRight
cn: Change-Schema-Master
-instanceType: 4
displayName: Change Schema Master
-showInAdvancedViewOnly: TRUE
rightsGuid: e12b56b6-0a95-11d1-adbb-00c04fd8d5cd
appliesTo: bf967a8f-0de6-11d0-a285-00aa003049e2
-objectCategory: CN=Control-Access-Right,CN=Schema,${CONFIGDN}
localizationDisplayId: 28
validAccesses: 256
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index 72747a7886..dd1d5ea817 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -89,6 +89,7 @@ $(eval $(call proto_header_template,$(torturesrcdir)/raw/proto.h,$(TORTURE_RAW_O
mkinclude smb2/config.mk
mkinclude winbind/config.mk
+mkinclude libnetapi/config.mk
[SUBSYSTEM::TORTURE_NDR]
PRIVATE_DEPENDENCIES = torture SERVICE_SMB
diff --git a/source4/torture/libnetapi/config.m4 b/source4/torture/libnetapi/config.m4
new file mode 100644
index 0000000000..43724908ca
--- /dev/null
+++ b/source4/torture/libnetapi/config.m4
@@ -0,0 +1,28 @@
+###############################
+# start SMB_EXT_LIB_NETAPI
+# check for netapi.h and -lnetapi
+
+use_netapi=auto
+AC_ARG_ENABLE(netapi,
+AS_HELP_STRING([--enable-netapi],[Turn on netapi support (default=yes)]),
+ [if test x$enable_netapi = xno; then
+ use_netapi=no
+ fi])
+
+
+#if test x$use_netapi = xauto && pkg-config --exists netapi; then
+# SMB_EXT_LIB_FROM_PKGCONFIG(NETAPI, netapi < 0.1,
+# [use_netapi=yes],
+# [use_netapi=no])
+#fi
+
+if test x$use_netapi = xauto; then
+ AC_CHECK_HEADERS(netapi.h)
+ AC_CHECK_LIB_EXT(netapi, NETAPI_LIBS, libnetapi_init)
+ if test x"$ac_cv_header_netapi_h" = x"yes" -a x"$ac_cv_lib_ext_netapi_libnetapi_init" = x"yes";then
+ SMB_ENABLE(NETAPI,YES)
+ else
+ SMB_ENABLE(TORTURE_LIBNETAPI,NO)
+ fi
+ SMB_EXT_LIB(NETAPI, $NETAPI_LIBS)
+fi
diff --git a/source4/torture/libnetapi/config.mk b/source4/torture/libnetapi/config.mk
new file mode 100644
index 0000000000..2ac506e1b2
--- /dev/null
+++ b/source4/torture/libnetapi/config.mk
@@ -0,0 +1,17 @@
+#################################
+# Start SUBSYSTEM TORTURE_LIBNETAPI
+[MODULE::TORTURE_LIBNETAPI]
+SUBSYSTEM = smbtorture
+OUTPUT_TYPE = MERGED_OBJ
+INIT_FUNCTION = torture_libnetapi_init
+PRIVATE_DEPENDENCIES = \
+ POPT_CREDENTIALS \
+ NETAPI
+# End SUBSYSTEM TORTURE_LIBNETAPI
+#################################
+
+TORTURE_LIBNETAPI_OBJ_FILES = $(addprefix $(torturesrcdir)/libnetapi/, libnetapi.o \
+ libnetapi_user.o \
+ libnetapi_group.o)
+
+$(eval $(call proto_header_template,$(torturesrcdir)/libnetapi/proto.h,$(TORTURE_LIBNETAPI_OBJ_FILES:.o=.c)))
diff --git a/source4/torture/libnetapi/libnetapi.c b/source4/torture/libnetapi/libnetapi.c
new file mode 100644
index 0000000000..c3a27eba0c
--- /dev/null
+++ b/source4/torture/libnetapi/libnetapi.c
@@ -0,0 +1,80 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB torture tester
+ Copyright (C) Guenther Deschner 2009
+
+ 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/>.
+*/
+
+#include "includes.h"
+#include "torture/smbtorture.h"
+#include "auth/credentials/credentials.h"
+#include "lib/cmdline/popt_common.h"
+#include <netapi.h>
+#include "torture/libnetapi/proto.h"
+
+bool torture_libnetapi_init_context(struct torture_context *tctx,
+ struct libnetapi_ctx **ctx_p)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx;
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return false;
+ }
+
+ libnetapi_set_debuglevel(ctx,
+ talloc_asprintf(ctx, "%d", DEBUGLEVEL));
+ libnetapi_set_username(ctx,
+ cli_credentials_get_username(cmdline_credentials));
+ libnetapi_set_password(ctx,
+ cli_credentials_get_password(cmdline_credentials));
+
+ *ctx_p = ctx;
+
+ return true;
+}
+
+static bool torture_libnetapi_initialize(struct torture_context *tctx)
+{
+ NET_API_STATUS status;
+ struct libnetapi_ctx *ctx;
+
+ status = libnetapi_init(&ctx);
+ if (status != 0) {
+ return false;
+ }
+
+ libnetapi_free(ctx);
+
+ return true;
+}
+
+NTSTATUS torture_libnetapi_init(void)
+{
+ struct torture_suite *suite;
+
+ suite = torture_suite_create(talloc_autofree_context(), "NETAPI");
+
+ torture_suite_add_simple_test(suite, "GROUP", torture_libnetapi_group);
+ torture_suite_add_simple_test(suite, "USER", torture_libnetapi_user);
+ torture_suite_add_simple_test(suite, "INITIALIZE", torture_libnetapi_initialize);
+
+ suite->description = talloc_strdup(suite, "libnetapi convenience interface tests");
+
+ torture_register_suite(suite);
+
+ return NT_STATUS_OK;
+}
diff --git a/source4/torture/libnetapi/libnetapi_group.c b/source4/torture/libnetapi/libnetapi_group.c
new file mode 100644
index 0000000000..e8e5ad931a
--- /dev/null
+++ b/source4/torture/libnetapi/libnetapi_group.c
@@ -0,0 +1,520 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB torture tester
+ Copyright (C) Guenther Deschner 2009
+
+ 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/>.
+*/
+
+#include "includes.h"
+#include "torture/smbtorture.h"
+#include <netapi.h>
+#include "torture/libnetapi/proto.h"
+
+#define TORTURE_TEST_USER "testuser"
+
+#define NETAPI_STATUS(tctx, x,y,fn) \
+ torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \
+ __LINE__, fn, libnetapi_get_error_string(x,y), y);
+
+#define NETAPI_STATUS_MSG(tctx, x,y,fn,z) \
+ torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d), %s\n", \
+ __LINE__, fn, libnetapi_get_error_string(x,y), y, z);
+
+static NET_API_STATUS test_netgroupenum(struct torture_context *tctx,
+ const char *hostname,
+ uint32_t level,
+ const char *groupname)
+{
+ NET_API_STATUS status;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ int found_group = 0;
+ const char *current_name = NULL;
+ uint8_t *buffer = NULL;
+ int i;
+
+ struct GROUP_INFO_0 *info0 = NULL;
+ struct GROUP_INFO_1 *info1 = NULL;
+ struct GROUP_INFO_2 *info2 = NULL;
+ struct GROUP_INFO_3 *info3 = NULL;
+
+ torture_comment(tctx, "testing NetGroupEnum level %d\n", level);
+
+ do {
+ status = NetGroupEnum(hostname,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ switch (level) {
+ case 0:
+ info0 = (struct GROUP_INFO_0 *)buffer;
+ break;
+ case 1:
+ info1 = (struct GROUP_INFO_1 *)buffer;
+ break;
+ case 2:
+ info2 = (struct GROUP_INFO_2 *)buffer;
+ break;
+ case 3:
+ info3 = (struct GROUP_INFO_3 *)buffer;
+ break;
+ default:
+ return -1;
+ }
+
+ for (i=0; i<entries_read; i++) {
+
+ switch (level) {
+ case 0:
+ current_name = info0->grpi0_name;
+ break;
+ case 1:
+ current_name = info1->grpi1_name;
+ break;
+ case 2:
+ current_name = info2->grpi2_name;
+ break;
+ case 3:
+ current_name = info3->grpi3_name;
+ break;
+ default:
+ break;
+ }
+
+ if (strcasecmp(current_name, groupname) == 0) {
+ found_group = 1;
+ }
+
+ switch (level) {
+ case 0:
+ info0++;
+ break;
+ case 1:
+ info1++;
+ break;
+ case 2:
+ info2++;
+ break;
+ case 3:
+ info3++;
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status) {
+ return status;
+ }
+
+ if (!found_group) {
+ torture_comment(tctx, "failed to get group\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static NET_API_STATUS test_netgroupgetusers(struct torture_context *tctx,
+ const char *hostname,
+ uint32_t level,
+ const char *groupname,
+ const char *username)
+{
+ NET_API_STATUS status;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ int found_user = 0;
+ const char *current_name = NULL;
+ uint8_t *buffer = NULL;
+ int i;
+
+ struct GROUP_USERS_INFO_0 *info0 = NULL;
+ struct GROUP_USERS_INFO_1 *info1 = NULL;
+
+ torture_comment(tctx, "testing NetGroupGetUsers level %d\n", level);
+
+ do {
+ status = NetGroupGetUsers(hostname,
+ groupname,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+
+ switch (level) {
+ case 0:
+ info0 = (struct GROUP_USERS_INFO_0 *)buffer;
+ break;
+ case 1:
+ info1 = (struct GROUP_USERS_INFO_1 *)buffer;
+ break;
+ default:
+ break;
+ }
+ for (i=0; i<entries_read; i++) {
+ switch (level) {
+ case 0:
+ current_name = info0->grui0_name;
+ break;
+ case 1:
+ current_name = info1->grui1_name;
+ break;
+ default:
+ break;
+ }
+
+ if (username && strcasecmp(current_name, username) == 0) {
+ found_user = 1;
+ }
+
+ switch (level) {
+ case 0:
+ info0++;
+ break;
+ case 1:
+ info1++;
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status) {
+ return status;
+ }
+
+ if (username && !found_user) {
+ torture_comment(tctx, "failed to get user\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static NET_API_STATUS test_netgroupsetusers(struct torture_context *tctx,
+ const char *hostname,
+ const char *groupname,
+ uint32_t level,
+ size_t num_entries,
+ const char **names)
+{
+ NET_API_STATUS status;
+ uint8_t *buffer = NULL;
+ int i = 0;
+ size_t buf_size = 0;
+
+ struct GROUP_USERS_INFO_0 *g0 = NULL;
+ struct GROUP_USERS_INFO_1 *g1 = NULL;
+
+ torture_comment(tctx, "testing NetGroupSetUsers level %d\n", level);
+
+ switch (level) {
+ case 0:
+ buf_size = sizeof(struct GROUP_USERS_INFO_0) * num_entries;
+
+ status = NetApiBufferAllocate(buf_size, (void **)&g0);
+ if (status) {
+ goto out;
+ }
+
+ for (i=0; i<num_entries; i++) {
+ g0[i].grui0_name = names[i];
+ }
+
+ buffer = (uint8_t *)g0;
+ break;
+ case 1:
+ buf_size = sizeof(struct GROUP_USERS_INFO_1) * num_entries;
+
+ status = NetApiBufferAllocate(buf_size, (void **)&g1);
+ if (status) {
+ goto out;
+ }
+
+ for (i=0; i<num_entries; i++) {
+ g1[i].grui1_name = names[i];
+ }
+
+ buffer = (uint8_t *)g1;
+ break;
+ default:
+ break;
+ }
+
+ /* NetGroupSetUsers */
+
+ status = NetGroupSetUsers(hostname,
+ groupname,
+ level,
+ buffer,
+ num_entries);
+ if (status) {
+ goto out;
+ }
+
+ out:
+ NetApiBufferFree(buffer);
+ return status;
+}
+
+bool torture_libnetapi_group(struct torture_context *tctx)
+{
+ NET_API_STATUS status = 0;
+ const char *username, *groupname, *groupname2;
+ uint8_t *buffer = NULL;
+ struct GROUP_INFO_0 g0;
+ uint32_t parm_err = 0;
+ uint32_t levels[] = { 0, 1, 2, 3};
+ uint32_t enum_levels[] = { 0, 1, 2, 3};
+ uint32_t getmem_levels[] = { 0, 1};
+ int i;
+ const char *hostname = torture_setting_string(tctx, "host", NULL);
+ struct libnetapi_ctx *ctx;
+
+ torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx),
+ "failed to initialize libnetapi");
+
+ torture_comment(tctx, "NetGroup tests\n");
+
+ username = "torture_test_user";
+ groupname = "torture_test_group";
+ groupname2 = "torture_test_group2";
+
+ /* cleanup */
+ NetGroupDel(hostname, groupname);
+ NetGroupDel(hostname, groupname2);
+ NetUserDel(hostname, username);
+
+ /* add a group */
+
+ g0.grpi0_name = groupname;
+
+ torture_comment(tctx, "testing NetGroupAdd\n");
+
+ status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupAdd");
+ goto out;
+ }
+
+ /* 2nd add must fail */
+
+ status = NetGroupAdd(hostname, 0, (uint8_t *)&g0, &parm_err);
+ if (status == 0) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupAdd");
+ status = -1;
+ goto out;
+ }
+
+ /* test enum */
+
+ for (i=0; i<ARRAY_SIZE(enum_levels); i++) {
+
+ status = test_netgroupenum(tctx, hostname, enum_levels[i], groupname);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupEnum");
+ goto out;
+ }
+ }
+
+ /* basic queries */
+
+ for (i=0; i<ARRAY_SIZE(levels); i++) {
+
+ torture_comment(tctx, "testing NetGroupGetInfo level %d\n", levels[i]);
+
+ status = NetGroupGetInfo(hostname, groupname, levels[i], &buffer);
+ if (status && status != 124) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupGetInfo");
+ goto out;
+ }
+ }
+
+ /* group rename */
+
+ g0.grpi0_name = groupname2;
+
+ torture_comment(tctx, "testing NetGroupSetInfo level 0\n");
+
+ status = NetGroupSetInfo(hostname, groupname, 0, (uint8_t *)&g0, &parm_err);
+ switch (status) {
+ case 0:
+ break;
+ case 50: /* not supported */
+ case 124: /* not implemented */
+ groupname2 = groupname;
+ goto skip_rename;
+ default:
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupSetInfo");
+ goto out;
+ }
+
+ /* should not exist anymore */
+
+ status = NetGroupDel(hostname, groupname);
+ if (status == 0) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupDel");
+ goto out;
+ }
+
+ skip_rename:
+ /* query info */
+
+ for (i=0; i<ARRAY_SIZE(levels); i++) {
+
+ status = NetGroupGetInfo(hostname, groupname2, levels[i], &buffer);
+ if (status && status != 124) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupGetInfo");
+ goto out;
+ }
+ }
+
+ /* add user to group */
+
+ status = test_netuseradd(tctx, hostname, username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserAdd");
+ goto out;
+ }
+
+ /* should not be member */
+
+ for (i=0; i<ARRAY_SIZE(getmem_levels); i++) {
+
+ status = test_netgroupgetusers(tctx, hostname, getmem_levels[i], groupname2, NULL);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
+ goto out;
+ }
+ }
+
+ torture_comment(tctx, "testing NetGroupAddUser\n");
+
+ status = NetGroupAddUser(hostname, groupname2, username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupAddUser");
+ goto out;
+ }
+
+ /* should be member */
+
+ for (i=0; i<ARRAY_SIZE(getmem_levels); i++) {
+
+ status = test_netgroupgetusers(tctx, hostname, getmem_levels[i], groupname2, username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
+ goto out;
+ }
+ }
+
+ torture_comment(tctx, "testing NetGroupDelUser\n");
+
+ status = NetGroupDelUser(hostname, groupname2, username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupDelUser");
+ goto out;
+ }
+
+ /* should not be member */
+
+ status = test_netgroupgetusers(tctx, hostname, 0, groupname2, NULL);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
+ goto out;
+ }
+
+ /* set it again via exlicit member set */
+
+ status = test_netgroupsetusers(tctx, hostname, groupname2, 0, 1, &username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupSetUsers");
+ goto out;
+ }
+
+ /* should be member */
+
+ status = test_netgroupgetusers(tctx, hostname, 0, groupname2, username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
+ goto out;
+ }
+#if 0
+ /* wipe out member list */
+
+ status = test_netgroupsetusers(hostname, groupname2, 0, 0, NULL);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupSetUsers");
+ goto out;
+ }
+
+ /* should not be member */
+
+ status = test_netgroupgetusers(hostname, 0, groupname2, NULL);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupGetUsers");
+ goto out;
+ }
+#endif
+ status = NetUserDel(hostname, username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserDel");
+ goto out;
+ }
+
+ /* delete */
+
+ torture_comment(tctx, "testing NetGroupDel\n");
+
+ status = NetGroupDel(hostname, groupname2);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetGroupDel");
+ goto out;
+ };
+
+ /* should not exist anymore */
+
+ status = NetGroupGetInfo(hostname, groupname2, 0, &buffer);
+ if (status == 0) {
+ NETAPI_STATUS_MSG(tctx, ctx, status, "NetGroupGetInfo", "expected failure and error code");
+ status = -1;
+ goto out;
+ };
+
+ status = 0;
+
+ torture_comment(tctx, "NetGroup tests succeeded\n");
+ out:
+ if (status != 0) {
+ torture_comment(tctx, "NetGroup testsuite failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ libnetapi_free(ctx);
+ return false;
+ }
+
+ libnetapi_free(ctx);
+ return true;
+}
diff --git a/source4/torture/libnetapi/libnetapi_user.c b/source4/torture/libnetapi/libnetapi_user.c
new file mode 100644
index 0000000000..c6343301e3
--- /dev/null
+++ b/source4/torture/libnetapi/libnetapi_user.c
@@ -0,0 +1,476 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB torture tester
+ Copyright (C) Guenther Deschner 2009
+
+ 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/>.
+*/
+
+#include "includes.h"
+#include "torture/smbtorture.h"
+#include <netapi.h>
+#include "torture/libnetapi/proto.h"
+
+#define TORTURE_TEST_USER "testuser"
+
+#define NETAPI_STATUS(tctx, x,y,fn) \
+ torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \
+ __LINE__, fn, libnetapi_get_error_string(x,y), y);
+
+static NET_API_STATUS test_netuserenum(struct torture_context *tctx,
+ const char *hostname,
+ uint32_t level,
+ const char *username)
+{
+ NET_API_STATUS status;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ uint32_t resume_handle = 0;
+ const char *current_name = NULL;
+ int found_user = 0;
+ uint8_t *buffer = NULL;
+ int i;
+
+ struct USER_INFO_0 *info0 = NULL;
+ struct USER_INFO_1 *info1 = NULL;
+ struct USER_INFO_2 *info2 = NULL;
+ struct USER_INFO_3 *info3 = NULL;
+ struct USER_INFO_4 *info4 = NULL;
+ struct USER_INFO_10 *info10 = NULL;
+ struct USER_INFO_11 *info11 = NULL;
+ struct USER_INFO_20 *info20 = NULL;
+ struct USER_INFO_23 *info23 = NULL;
+
+ torture_comment(tctx, "testing NetUserEnum level %d\n", level);
+
+ do {
+ status = NetUserEnum(hostname,
+ level,
+ FILTER_NORMAL_ACCOUNT,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries,
+ &resume_handle);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ switch (level) {
+ case 0:
+ info0 = (struct USER_INFO_0 *)buffer;
+ break;
+ case 1:
+ info1 = (struct USER_INFO_1 *)buffer;
+ break;
+ case 2:
+ info2 = (struct USER_INFO_2 *)buffer;
+ break;
+ case 3:
+ info3 = (struct USER_INFO_3 *)buffer;
+ break;
+ case 4:
+ info4 = (struct USER_INFO_4 *)buffer;
+ break;
+ case 10:
+ info10 = (struct USER_INFO_10 *)buffer;
+ break;
+ case 11:
+ info11 = (struct USER_INFO_11 *)buffer;
+ break;
+ case 20:
+ info20 = (struct USER_INFO_20 *)buffer;
+ break;
+ case 23:
+ info23 = (struct USER_INFO_23 *)buffer;
+ break;
+ default:
+ return -1;
+ }
+
+ for (i=0; i<entries_read; i++) {
+
+ switch (level) {
+ case 0:
+ current_name = info0->usri0_name;
+ break;
+ case 1:
+ current_name = info1->usri1_name;
+ break;
+ case 2:
+ current_name = info2->usri2_name;
+ break;
+ case 3:
+ current_name = info3->usri3_name;
+ break;
+ case 4:
+ current_name = info4->usri4_name;
+ break;
+ case 10:
+ current_name = info10->usri10_name;
+ break;
+ case 11:
+ current_name = info11->usri11_name;
+ break;
+ case 20:
+ current_name = info20->usri20_name;
+ break;
+ case 23:
+ current_name = info23->usri23_name;
+ break;
+ default:
+ return -1;
+ }
+
+ if (strcasecmp(current_name, username) == 0) {
+ found_user = 1;
+ }
+
+ switch (level) {
+ case 0:
+ info0++;
+ break;
+ case 1:
+ info1++;
+ break;
+ case 2:
+ info2++;
+ break;
+ case 3:
+ info3++;
+ break;
+ case 4:
+ info4++;
+ break;
+ case 10:
+ info10++;
+ break;
+ case 11:
+ info11++;
+ break;
+ case 20:
+ info20++;
+ break;
+ case 23:
+ info23++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status) {
+ return status;
+ }
+
+ if (!found_user) {
+ torture_comment(tctx, "failed to get user\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+NET_API_STATUS test_netuseradd(struct torture_context *tctx,
+ const char *hostname,
+ const char *username)
+{
+ struct USER_INFO_1 u1;
+ uint32_t parm_err = 0;
+
+ ZERO_STRUCT(u1);
+
+ torture_comment(tctx, "testing NetUserAdd\n");
+
+ u1.usri1_name = username;
+ u1.usri1_password = "W297!832jD8J";
+ u1.usri1_password_age = 0;
+ u1.usri1_priv = 0;
+ u1.usri1_home_dir = NULL;
+ u1.usri1_comment = "User created using Samba NetApi Example code";
+ u1.usri1_flags = 0;
+ u1.usri1_script_path = NULL;
+
+ return NetUserAdd(hostname, 1, (uint8_t *)&u1, &parm_err);
+}
+
+static NET_API_STATUS test_netusermodals(struct torture_context *tctx,
+ struct libnetapi_ctx *ctx,
+ const char *hostname)
+{
+ NET_API_STATUS status;
+ struct USER_MODALS_INFO_0 *u0 = NULL;
+ struct USER_MODALS_INFO_0 *_u0 = NULL;
+ uint8_t *buffer = NULL;
+ uint32_t parm_err = 0;
+ uint32_t levels[] = { 0, 1, 2, 3 };
+ int i = 0;
+
+ for (i=0; i<ARRAY_SIZE(levels); i++) {
+
+ torture_comment(tctx, "testing NetUserModalsGet level %d\n", levels[i]);
+
+ status = NetUserModalsGet(hostname, levels[i], &buffer);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserModalsGet");
+ return status;
+ }
+ }
+
+ status = NetUserModalsGet(hostname, 0, (uint8_t **)&u0);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserModalsGet");
+ return status;
+ }
+
+ torture_comment(tctx, "testing NetUserModalsSet\n");
+
+ status = NetUserModalsSet(hostname, 0, (uint8_t *)u0, &parm_err);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserModalsSet");
+ return status;
+ }
+
+ status = NetUserModalsGet(hostname, 0, (uint8_t **)&_u0);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserModalsGet");
+ return status;
+ }
+
+ if (memcmp(u0, _u0, sizeof(u0) != 0)) {
+ torture_comment(tctx, "USER_MODALS_INFO_0 struct has changed!!!!\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static NET_API_STATUS test_netusergetgroups(struct torture_context *tctx,
+ const char *hostname,
+ uint32_t level,
+ const char *username,
+ const char *groupname)
+{
+ NET_API_STATUS status;
+ uint32_t entries_read = 0;
+ uint32_t total_entries = 0;
+ const char *current_name;
+ int found_group = 0;
+ uint8_t *buffer = NULL;
+ int i;
+
+ struct GROUP_USERS_INFO_0 *i0;
+ struct GROUP_USERS_INFO_1 *i1;
+
+ torture_comment(tctx, "testing NetUserGetGroups level %d\n", level);
+
+ do {
+ status = NetUserGetGroups(hostname,
+ username,
+ level,
+ &buffer,
+ (uint32_t)-1,
+ &entries_read,
+ &total_entries);
+ if (status == 0 || status == ERROR_MORE_DATA) {
+ switch (level) {
+ case 0:
+ i0 = (struct GROUP_USERS_INFO_0 *)buffer;
+ break;
+ case 1:
+ i1 = (struct GROUP_USERS_INFO_1 *)buffer;
+ break;
+ default:
+ return -1;
+ }
+
+ for (i=0; i<entries_read; i++) {
+
+ switch (level) {
+ case 0:
+ current_name = i0->grui0_name;
+ break;
+ case 1:
+ current_name = i1->grui1_name;
+ break;
+ default:
+ return -1;
+ }
+
+ if (groupname && strcasecmp(current_name, groupname) == 0) {
+ found_group = 1;
+ }
+
+ switch (level) {
+ case 0:
+ i0++;
+ break;
+ case 1:
+ i1++;
+ break;
+ default:
+ break;
+ }
+ }
+ NetApiBufferFree(buffer);
+ }
+ } while (status == ERROR_MORE_DATA);
+
+ if (status) {
+ return status;
+ }
+
+ if (groupname && !found_group) {
+ torture_comment(tctx, "failed to get membership\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+bool torture_libnetapi_user(struct torture_context *tctx)
+{
+ NET_API_STATUS status = 0;
+ const char *username, *username2;
+ uint8_t *buffer = NULL;
+ uint32_t levels[] = { 0, 1, 2, 3, 4, 10, 11, 20, 23 };
+ uint32_t enum_levels[] = { 0, 1, 2, 3, 4, 10, 11, 20, 23 };
+ uint32_t getgr_levels[] = { 0, 1 };
+ int i;
+
+ struct USER_INFO_1007 u1007;
+ uint32_t parm_err = 0;
+
+ const char *hostname = torture_setting_string(tctx, "host", NULL);
+ struct libnetapi_ctx *ctx;
+
+ torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx),
+ "failed to initialize libnetapi");
+
+ torture_comment(tctx, "NetUser tests\n");
+
+ username = "torture_test_user";
+ username2 = "torture_test_user2";
+
+ /* cleanup */
+ NetUserDel(hostname, username);
+ NetUserDel(hostname, username2);
+
+ /* add a user */
+
+ status = test_netuseradd(tctx, hostname, username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserAdd");
+ goto out;
+ }
+
+ /* enum the new user */
+
+ for (i=0; i<ARRAY_SIZE(enum_levels); i++) {
+
+ status = test_netuserenum(tctx, hostname, enum_levels[i], username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserEnum");
+ goto out;
+ }
+ }
+
+ /* basic queries */
+
+ for (i=0; i<ARRAY_SIZE(levels); i++) {
+
+ torture_comment(tctx, "testing NetUserGetInfo level %d\n", levels[i]);
+
+ status = NetUserGetInfo(hostname, username, levels[i], &buffer);
+ if (status && status != 124) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserGetInfo");
+ goto out;
+ }
+ }
+
+ /* testing getgroups */
+
+ for (i=0; i<ARRAY_SIZE(getgr_levels); i++) {
+
+ status = test_netusergetgroups(tctx, hostname, getgr_levels[i], username, NULL);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserGetGroups");
+ goto out;
+ }
+ }
+
+ /* modify description */
+
+ torture_comment(tctx, "testing NetUserSetInfo level %d\n", 1007);
+
+ u1007.usri1007_comment = "NetApi modified user";
+
+ status = NetUserSetInfo(hostname, username, 1007, (uint8_t *)&u1007, &parm_err);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserSetInfo");
+ goto out;
+ }
+
+ /* query info */
+
+ for (i=0; i<ARRAY_SIZE(levels); i++) {
+ status = NetUserGetInfo(hostname, username, levels[i], &buffer);
+ if (status && status != 124) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserGetInfo");
+ goto out;
+ }
+ }
+
+ /* delete */
+
+ torture_comment(tctx, "testing NetUserDel\n");
+
+ status = NetUserDel(hostname, username);
+ if (status) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserDel");
+ goto out;
+ }
+
+ /* should not exist anymore */
+
+ status = NetUserGetInfo(hostname, username, 0, &buffer);
+ if (status == 0) {
+ NETAPI_STATUS(tctx, ctx, status, "NetUserGetInfo");
+ status = -1;
+ goto out;
+ }
+
+ status = test_netusermodals(tctx, ctx, hostname);
+ if (status) {
+ goto out;
+ }
+
+ status = 0;
+
+ torture_comment(tctx, "NetUser tests succeeded\n");
+ out:
+ /* cleanup */
+ NetUserDel(hostname, username);
+ NetUserDel(hostname, username2);
+
+ if (status != 0) {
+ torture_comment(tctx, "NetUser testsuite failed with: %s\n",
+ libnetapi_get_error_string(ctx, status));
+ libnetapi_free(ctx);
+ return false;
+ }
+
+ libnetapi_free(ctx);
+ return true;
+}
diff --git a/source4/torture/local/config.mk b/source4/torture/local/config.mk
index 5c8c1d5762..28599e4bda 100644
--- a/source4/torture/local/config.mk
+++ b/source4/torture/local/config.mk
@@ -17,7 +17,8 @@ PRIVATE_DEPENDENCIES = \
TORTURE_LIBCRYPTO \
share \
torture_registry \
- PROVISION
+ PROVISION \
+ NSS_WRAPPER
# End SUBSYSTEM TORTURE_LOCAL
#################################
@@ -34,6 +35,7 @@ TORTURE_LOCAL_OBJ_FILES = \
$(torturesrcdir)/../../lib/util/tests/idtree.o \
$(torturesrcdir)/../lib/socket/testsuite.o \
$(torturesrcdir)/../../lib/socket_wrapper/testsuite.o \
+ $(torturesrcdir)/../../lib/nss_wrapper/testsuite.o \
$(torturesrcdir)/../libcli/resolve/testsuite.o \
$(torturesrcdir)/../../lib/util/tests/strlist.o \
$(torturesrcdir)/../../lib/util/tests/str.o \
diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c
index a1b100edb8..73ee366dcd 100644
--- a/source4/torture/local/local.c
+++ b/source4/torture/local/local.c
@@ -43,6 +43,7 @@
torture_local_iconv,
torture_local_socket,
torture_local_socket_wrapper,
+ torture_local_nss_wrapper,
torture_pac,
torture_local_resolve,
torture_local_sddl,
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index 92ce66fef2..30e7e0889c 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -2673,21 +2673,20 @@ static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
return true;
}
-static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *tctx,
- struct cli_credentials *machine_credentials,
- struct cli_credentials *test_credentials,
- struct netlogon_creds_CredentialState *creds,
- NTSTATUS expected_result)
+static bool test_SamLogon(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct cli_credentials *test_credentials,
+ NTSTATUS expected_result)
{
NTSTATUS status;
- struct netr_LogonSamLogon r;
- struct netr_Authenticator auth, auth2;
+ struct netr_LogonSamLogonEx r;
union netr_LogonLevel logon;
union netr_Validation validation;
uint8_t authoritative;
struct netr_NetworkInfo ninfo;
DATA_BLOB names_blob, chal, lm_resp, nt_resp;
int flags = CLI_CRED_NTLM_AUTH;
+ uint32_t samlogon_flags = 0;
if (lp_client_lanman_auth(tctx->lp_ctx)) {
flags |= CLI_CRED_LANMAN_AUTH;
@@ -2706,8 +2705,8 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t
chal = data_blob_const(ninfo.challenge,
sizeof(ninfo.challenge));
- names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(machine_credentials),
- cli_credentials_get_domain(machine_credentials));
+ names_blob = NTLMv2_generate_names_blob(tctx, cli_credentials_get_workstation(test_credentials),
+ cli_credentials_get_domain(test_credentials));
status = cli_credentials_get_ntlm_response(test_credentials, tctx,
&flags,
@@ -2728,56 +2727,38 @@ static bool test_SamLogon_Creds(struct dcerpc_pipe *p, struct torture_context *t
MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
ninfo.identity_info.logon_id_low = 0;
ninfo.identity_info.logon_id_high = 0;
- ninfo.identity_info.workstation.string = cli_credentials_get_workstation(machine_credentials);
+ ninfo.identity_info.workstation.string = cli_credentials_get_workstation(test_credentials);
logon.network = &ninfo;
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
- r.in.computer_name = cli_credentials_get_workstation(machine_credentials);
- r.in.credential = &auth;
- r.in.return_authenticator = &auth2;
- r.in.logon_level = 2;
+ r.in.computer_name = cli_credentials_get_workstation(test_credentials);
+ r.in.logon_level = NetlogonNetworkInformation;
r.in.logon = &logon;
+ r.in.flags = &samlogon_flags;
+ r.out.flags = &samlogon_flags;
r.out.validation = &validation;
r.out.authoritative = &authoritative;
d_printf("Testing LogonSamLogon with name %s\n", ninfo.identity_info.account_name.string);
- ZERO_STRUCT(auth2);
- netlogon_creds_client_authenticator(creds, &auth);
-
- r.in.validation_level = 2;
+ r.in.validation_level = 6;
- status = dcerpc_netr_LogonSamLogon(p, tctx, &r);
+ status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
+ r.in.validation_level = 3;
+ status = dcerpc_netr_LogonSamLogonEx(p, tctx, &r);
+ }
if (!NT_STATUS_IS_OK(status)) {
- torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogon failed");
+ torture_assert_ntstatus_equal(tctx, status, expected_result, "LogonSamLogonEx failed");
return true;
} else {
- torture_assert_ntstatus_ok(tctx, status, "LogonSamLogon failed");
+ torture_assert_ntstatus_ok(tctx, status, "LogonSamLogonEx failed");
}
- torture_assert(tctx, netlogon_creds_client_check(creds, &r.out.return_authenticator->cred),
- "Credential chaining failed");
-
return true;
}
-static bool test_SamLogon(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct cli_credentials *machine_credentials,
- struct cli_credentials *test_credentials,
- NTSTATUS expected_result)
-{
- struct netlogon_creds_CredentialState *creds;
-
- if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
- return false;
- }
-
- return test_SamLogon_Creds(p, tctx, machine_credentials, test_credentials,
- creds, expected_result);
-}
-
static bool test_SamLogon_with_creds(struct torture_context *tctx,
struct dcerpc_pipe *p,
struct cli_credentials *machine_creds,
@@ -2791,19 +2772,18 @@ static bool test_SamLogon_with_creds(struct torture_context *tctx,
test_credentials = cli_credentials_init(tctx);
cli_credentials_set_workstation(test_credentials,
- TEST_ACCOUNT_NAME_PWD, CRED_SPECIFIED);
+ cli_credentials_get_workstation(machine_creds), CRED_SPECIFIED);
cli_credentials_set_domain(test_credentials,
- lp_workgroup(tctx->lp_ctx), CRED_SPECIFIED);
+ cli_credentials_get_domain(machine_creds), CRED_SPECIFIED);
cli_credentials_set_username(test_credentials,
acct_name, CRED_SPECIFIED);
cli_credentials_set_password(test_credentials,
password, CRED_SPECIFIED);
- cli_credentials_set_secure_channel_type(test_credentials, SEC_CHAN_BDC);
- printf("testing samlogon as %s@%s password: %s\n",
- acct_name, TEST_ACCOUNT_NAME_PWD, password);
+ printf("testing samlogon as %s password: %s\n",
+ acct_name, password);
- if (!test_SamLogon(tctx, p, machine_creds, test_credentials,
+ if (!test_SamLogon(tctx, p, test_credentials,
expected_samlogon_result)) {
torture_warning(tctx, "new password did not work\n");
ret = false;
@@ -2886,11 +2866,12 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
struct cli_credentials *machine_credentials)
{
int s = 0, q = 0, f = 0, l = 0, z = 0;
+ struct dcerpc_binding *b;
bool ret = true;
- int delay = 500000;
+ int delay = 50000;
bool set_levels[] = { false, true };
bool query_levels[] = { false, true };
- uint32_t levels[] = { 18, 21, 23, 24, 25, 26 };
+ uint32_t levels[] = { 18, 21, 26, 23, 24, 25 }; /* Second half only used when TEST_ALL_LEVELS defined */
uint32_t nonzeros[] = { 1, 24 };
uint32_t fields_present[] = {
0,
@@ -2915,19 +2896,41 @@ static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
delay);
}
- status = torture_rpc_connection(tctx, &np, &ndr_table_netlogon);
+ status = torture_rpc_binding(tctx, &b);
if (!NT_STATUS_IS_OK(status)) {
- return false;
+ ret = false;
+ return ret;
+ }
+
+ /* We have to use schannel, otherwise the SamLogonEx fails
+ * with INTERNAL_ERROR */
+
+ b->flags &= ~DCERPC_AUTH_OPTIONS;
+ b->flags |= DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128;
+
+ status = dcerpc_pipe_connect_b(tctx, &np, b,
+ &ndr_table_netlogon,
+ machine_credentials, tctx->ev, tctx->lp_ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("RPC pipe connect as domain member failed: %s\n", nt_errstr(status));
+ ret = false;
+ return ret;
}
/* set to 1 to enable testing for all possible opcode
(SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
combinations */
#if 0
+#define TEST_ALL_LEVELS 1
#define TEST_SET_LEVELS 1
#define TEST_QUERY_LEVELS 1
#endif
+#ifdef TEST_ALL_LEVELS
for (l=0; l<ARRAY_SIZE(levels); l++) {
+#else
+ for (l=0; l<(ARRAY_SIZE(levels))/2; l++) {
+#endif
for (z=0; z<ARRAY_SIZE(nonzeros); z++) {
for (f=0; f<ARRAY_SIZE(fields_present); f++) {
#ifdef TEST_SET_LEVELS
@@ -4373,7 +4376,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
{ ACB_SVRTRUST, TEST_MACHINENAME, NT_STATUS_OK },
{ ACB_SVRTRUST | ACB_DISABLED, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
{ ACB_SVRTRUST | ACB_PWNOEXP, TEST_MACHINENAME, NT_STATUS_INVALID_PARAMETER },
- { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_OK },
+ { ACB_DOMTRUST, TEST_DOMAINNAME, NT_STATUS_ACCESS_DENIED },
{ ACB_DOMTRUST | ACB_DISABLED, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
{ ACB_DOMTRUST | ACB_PWNOEXP, TEST_DOMAINNAME, NT_STATUS_INVALID_PARAMETER },
{ 0, TEST_ACCOUNT_NAME, NT_STATUS_INVALID_PARAMETER },
@@ -6177,6 +6180,8 @@ static bool test_ManyObjects(struct dcerpc_pipe *p,
NTSTATUS status;
uint32_t i;
+ struct policy_handle *handles = talloc_zero_array(tctx, struct policy_handle, num_total);
+
/* query */
{
@@ -6209,29 +6214,25 @@ static bool test_ManyObjects(struct dcerpc_pipe *p,
for (i=0; i < num_total; i++) {
- struct policy_handle handle;
const char *name = NULL;
- ZERO_STRUCT(handle);
-
switch (which_ops) {
case TORTURE_SAMR_MANY_ACCOUNTS:
name = talloc_asprintf(tctx, "%s%04d", TEST_ACCOUNT_NAME, i);
- ret &= test_CreateUser(p, tctx, domain_handle, name, &handle, domain_sid, 0, NULL, false);
+ ret &= test_CreateUser(p, tctx, domain_handle, name, &handles[i], domain_sid, 0, NULL, false);
break;
case TORTURE_SAMR_MANY_GROUPS:
name = talloc_asprintf(tctx, "%s%04d", TEST_GROUPNAME, i);
- ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handle, domain_sid, false);
+ ret &= test_CreateDomainGroup(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
break;
case TORTURE_SAMR_MANY_ALIASES:
name = talloc_asprintf(tctx, "%s%04d", TEST_ALIASNAME, i);
- ret &= test_CreateAlias(p, tctx, domain_handle, name, &handle, domain_sid, false);
+ ret &= test_CreateAlias(p, tctx, domain_handle, name, &handles[i], domain_sid, false);
break;
default:
return false;
}
- if (!policy_handle_empty(&handle)) {
- ret &= test_samr_handle_Close(p, tctx, &handle);
+ if (!policy_handle_empty(&handles[i])) {
num_created++;
}
}
@@ -6252,9 +6253,6 @@ static bool test_ManyObjects(struct dcerpc_pipe *p,
return false;
}
- torture_assert_int_equal(tctx, num_enum, num_anounced + num_created,
- "unexpected number of results returned in enum call");
-#if 0
/* TODO: dispinfo */
switch (which_ops) {
@@ -6268,9 +6266,38 @@ static bool test_ManyObjects(struct dcerpc_pipe *p,
return false;
}
+
+ /* delete */
+
+ for (i=0; i < num_total; i++) {
+
+ if (policy_handle_empty(&handles[i])) {
+ continue;
+ }
+
+ switch (which_ops) {
+ case TORTURE_SAMR_MANY_ACCOUNTS:
+ ret &= test_DeleteUser(p, tctx, &handles[i]);
+ break;
+ case TORTURE_SAMR_MANY_GROUPS:
+ ret &= test_DeleteDomainGroup(p, tctx, &handles[i]);
+ break;
+ case TORTURE_SAMR_MANY_ALIASES:
+ ret &= test_DeleteAlias(p, tctx, &handles[i]);
+ break;
+ default:
+ return false;
+ }
+ }
+
+ talloc_free(handles);
+
+#if 0
torture_assert_int_equal(tctx, num_disp, num_anounced + num_created,
"unexpected number of results returned in dispinfo call");
#endif
+ torture_assert_int_equal(tctx, num_enum, num_anounced + num_created,
+ "unexpected number of results returned in enum call");
return ret;
}
@@ -6310,9 +6337,14 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
ret &= test_samr_handle_Close(p, tctx, handle);
switch (which_ops) {
- case TORTURE_SAMR_USER_ATTRIBUTES:
- case TORTURE_SAMR_USER_PRIVILEGES:
case TORTURE_SAMR_PASSWORDS:
+ case TORTURE_SAMR_USER_PRIVILEGES:
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
+ }
+ ret &= test_CreateUser(p, tctx, &domain_handle, TEST_ACCOUNT_NAME, &user_handle, sid, which_ops, NULL, true);
+ break;
+ case TORTURE_SAMR_USER_ATTRIBUTES:
if (!torture_setting_bool(tctx, "samba3", false)) {
ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops, NULL);
}
diff --git a/source4/torture/torture.c b/source4/torture/torture.c
index a9ec325dd6..d80acffa0d 100644
--- a/source4/torture/torture.c
+++ b/source4/torture/torture.c
@@ -45,6 +45,12 @@ bool torture_register_suite(struct torture_suite *suite)
return torture_suite_add_suite(torture_root, suite);
}
+#ifndef HAVE_NETAPI_H
+NTSTATUS torture_libnetapi_init(void)
+{
+ return NT_STATUS_OK;
+}
+#endif
_PUBLIC_ int torture_init(void)
{
@@ -57,6 +63,9 @@ _PUBLIC_ int torture_init(void)
extern NTSTATUS torture_rpc_init(void);
extern NTSTATUS torture_smb2_init(void);
extern NTSTATUS torture_net_init(void);
+#ifdef HAVE_NETAPI_H
+ extern NTSTATUS torture_libnetapi_init(void);
+#endif
extern NTSTATUS torture_raw_init(void);
extern NTSTATUS torture_unix_init(void);
extern NTSTATUS torture_winbind_init(void);