summaryrefslogtreecommitdiff
path: root/source3
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 /source3
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
Diffstat (limited to 'source3')
-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/include/wbc_async.h71
-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/lib/wb_reqtrans.c429
-rw-r--r--source3/lib/wbclient.c674
-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
45 files changed, 1975 insertions, 2286 deletions
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/include/wbc_async.h b/source3/include/wbc_async.h
deleted file mode 100644
index 57625d5baf..0000000000
--- a/source3/include/wbc_async.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Headers for the async winbind client library
- Copyright (C) Kai Blin 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/>.
-*/
-
-#ifndef _WBC_ASYNC_H_
-#define _WBC_ASYNC_H_
-
-#include "nsswitch/libwbclient/wbclient.h"
-
-struct wb_context;
-
-struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx, bool need_priv,
- 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);
-
-/* Definitions from wb_reqtrans.c */
-wbcErr map_wbc_err_from_errno(int error);
-
-bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err);
-wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req);
-
-struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, size_t max_extra_data);
-ssize_t wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_request **preq, int *err);
-
-struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct tevent_queue *queue, int fd,
- struct winbindd_request *wb_req);
-ssize_t wb_req_write_recv(struct tevent_req *req, int *err);
-
-struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev, int fd);
-ssize_t wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_response **presp, int *err);
-
-struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct tevent_queue *queue, int fd,
- struct winbindd_response *wb_resp);
-ssize_t wb_resp_write_recv(struct tevent_req *req, int *err);
-
-struct tevent_req *wb_simple_trans_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct tevent_queue *queue, int fd,
- struct winbindd_request *wb_req);
-int wb_simple_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_response **presponse, int *err);
-
-#endif /*_WBC_ASYNC_H_*/
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/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c
deleted file mode 100644
index 55883ba8c7..0000000000
--- a/source3/lib/wb_reqtrans.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Async transfer of winbindd_request and _response structs
-
- 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.
-
- 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 "wbc_async.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-struct req_read_state {
- struct winbindd_request *wb_req;
- size_t max_extra_data;
- ssize_t ret;
-};
-
-static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data);
-static void wb_req_read_done(struct tevent_req *subreq);
-
-struct tevent_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, size_t max_extra_data)
-{
- struct tevent_req *req, *subreq;
- struct req_read_state *state;
-
- req = tevent_req_create(mem_ctx, &state, struct req_read_state);
- if (req == NULL) {
- return NULL;
- }
- state->max_extra_data = max_extra_data;
-
- subreq = read_packet_send(state, ev, fd, 4, wb_req_more, state);
- if (tevent_req_nomem(subreq, req)) {
- return tevent_req_post(req, ev);
- }
- tevent_req_set_callback(subreq, wb_req_read_done, req);
- return req;
-}
-
-static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data)
-{
- struct req_read_state *state = talloc_get_type_abort(
- private_data, struct req_read_state);
- struct winbindd_request *req = (struct winbindd_request *)buf;
-
- if (buflen == 4) {
- if (req->length != sizeof(struct winbindd_request)) {
- DEBUG(0, ("wb_req_read_len: Invalid request size "
- "received: %d (expected %d)\n",
- (int)req->length,
- (int)sizeof(struct winbindd_request)));
- return -1;
- }
- return sizeof(struct winbindd_request) - 4;
- }
-
- if ((state->max_extra_data != 0)
- && (req->extra_len > state->max_extra_data)) {
- DEBUG(3, ("Got request with %d bytes extra data on "
- "unprivileged socket\n", (int)req->extra_len));
- return -1;
- }
-
- return req->extra_len;
-}
-
-static void wb_req_read_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct req_read_state *state = tevent_req_data(
- req, struct req_read_state);
- int err;
- uint8_t *buf;
-
- state->ret = read_packet_recv(subreq, state, &buf, &err);
- TALLOC_FREE(subreq);
- if (state->ret == -1) {
- tevent_req_error(req, err);
- return;
- }
-
- state->wb_req = (struct winbindd_request *)buf;
-
- if (state->wb_req->extra_len != 0) {
- state->wb_req->extra_data.data =
- (char *)buf + sizeof(struct winbindd_request);
- } else {
- state->wb_req->extra_data.data = NULL;
- }
- tevent_req_done(req);
-}
-
-ssize_t wb_req_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_request **preq, int *err)
-{
- struct req_read_state *state = tevent_req_data(
- req, struct req_read_state);
-
- if (tevent_req_is_unix_error(req, err)) {
- return -1;
- }
- *preq = talloc_move(mem_ctx, &state->wb_req);
- return state->ret;
-}
-
-struct req_write_state {
- struct iovec iov[2];
- ssize_t ret;
-};
-
-static void wb_req_write_done(struct tevent_req *subreq);
-
-struct tevent_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct tevent_queue *queue, int fd,
- struct winbindd_request *wb_req)
-{
- struct tevent_req *req, *subreq;
- struct req_write_state *state;
- int count = 1;
-
- req = tevent_req_create(mem_ctx, &state, struct req_write_state);
- if (req == NULL) {
- return NULL;
- }
-
- state->iov[0].iov_base = (void *)wb_req;
- state->iov[0].iov_len = sizeof(struct winbindd_request);
-
- if (wb_req->extra_len != 0) {
- state->iov[1].iov_base = (void *)wb_req->extra_data.data;
- state->iov[1].iov_len = wb_req->extra_len;
- count = 2;
- }
-
- subreq = writev_send(state, ev, queue, fd, true, state->iov, count);
- if (tevent_req_nomem(subreq, req)) {
- return tevent_req_post(req, ev);
- }
- tevent_req_set_callback(subreq, wb_req_write_done, req);
- return req;
-}
-
-static void wb_req_write_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct req_write_state *state = tevent_req_data(
- req, struct req_write_state);
- int err;
-
- state->ret = writev_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (state->ret < 0) {
- tevent_req_error(req, err);
- return;
- }
- tevent_req_done(req);
-}
-
-ssize_t wb_req_write_recv(struct tevent_req *req, int *err)
-{
- struct req_write_state *state = tevent_req_data(
- req, struct req_write_state);
-
- if (tevent_req_is_unix_error(req, err)) {
- return -1;
- }
- return state->ret;
-}
-
-struct resp_read_state {
- struct winbindd_response *wb_resp;
- ssize_t ret;
-};
-
-static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data);
-static void wb_resp_read_done(struct tevent_req *subreq);
-
-struct tevent_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev, int fd)
-{
- struct tevent_req *req, *subreq;
- struct resp_read_state *state;
-
- req = tevent_req_create(mem_ctx, &state, struct resp_read_state);
- if (req == NULL) {
- return NULL;
- }
-
- subreq = read_packet_send(state, ev, fd, 4, wb_resp_more, state);
- if (tevent_req_nomem(subreq, req)) {
- return tevent_req_post(req, ev);
- }
- tevent_req_set_callback(subreq, wb_resp_read_done, req);
- return req;
-}
-
-static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data)
-{
- struct winbindd_response *resp = (struct winbindd_response *)buf;
-
- if (buflen == 4) {
- if (resp->length < sizeof(struct winbindd_response)) {
- DEBUG(0, ("wb_resp_read_len: Invalid response size "
- "received: %d (expected at least%d)\n",
- (int)resp->length,
- (int)sizeof(struct winbindd_response)));
- return -1;
- }
- }
- return resp->length - buflen;
-}
-
-static void wb_resp_read_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct resp_read_state *state = tevent_req_data(
- req, struct resp_read_state);
- uint8_t *buf;
- int err;
-
- state->ret = read_packet_recv(subreq, state, &buf, &err);
- TALLOC_FREE(subreq);
- if (state->ret == -1) {
- tevent_req_error(req, err);
- return;
- }
-
- state->wb_resp = (struct winbindd_response *)buf;
-
- if (state->wb_resp->length > sizeof(struct winbindd_response)) {
- state->wb_resp->extra_data.data =
- (char *)buf + sizeof(struct winbindd_response);
- } else {
- state->wb_resp->extra_data.data = NULL;
- }
- tevent_req_done(req);
-}
-
-ssize_t wb_resp_read_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_response **presp, int *err)
-{
- struct resp_read_state *state = tevent_req_data(
- req, struct resp_read_state);
-
- if (tevent_req_is_unix_error(req, err)) {
- return -1;
- }
- *presp = talloc_move(mem_ctx, &state->wb_resp);
- return state->ret;
-}
-
-struct resp_write_state {
- struct iovec iov[2];
- ssize_t ret;
-};
-
-static void wb_resp_write_done(struct tevent_req *subreq);
-
-struct tevent_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct tevent_queue *queue, int fd,
- struct winbindd_response *wb_resp)
-{
- struct tevent_req *req, *subreq;
- struct resp_write_state *state;
- int count = 1;
-
- req = tevent_req_create(mem_ctx, &state, struct resp_write_state);
- if (req == NULL) {
- return NULL;
- }
-
- state->iov[0].iov_base = (void *)wb_resp;
- state->iov[0].iov_len = sizeof(struct winbindd_response);
-
- if (wb_resp->length > sizeof(struct winbindd_response)) {
- state->iov[1].iov_base = (void *)wb_resp->extra_data.data;
- state->iov[1].iov_len =
- wb_resp->length - sizeof(struct winbindd_response);
- count = 2;
- }
-
- subreq = writev_send(state, ev, queue, fd, true, state->iov, count);
- if (tevent_req_nomem(subreq, req)) {
- return tevent_req_post(req, ev);
- }
- tevent_req_set_callback(subreq, wb_resp_write_done, req);
- return req;
-}
-
-static void wb_resp_write_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct resp_write_state *state = tevent_req_data(
- req, struct resp_write_state);
- int err;
-
- state->ret = writev_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (state->ret < 0) {
- tevent_req_error(req, err);
- return;
- }
- tevent_req_done(req);
-}
-
-ssize_t wb_resp_write_recv(struct tevent_req *req, int *err)
-{
- struct resp_write_state *state = tevent_req_data(
- req, struct resp_write_state);
-
- if (tevent_req_is_unix_error(req, err)) {
- return -1;
- }
- return state->ret;
-}
-
-struct wb_simple_trans_state {
- struct tevent_context *ev;
- int fd;
- struct winbindd_response *wb_resp;
-};
-
-static void wb_simple_trans_write_done(struct tevent_req *subreq);
-static void wb_simple_trans_read_done(struct tevent_req *subreq);
-
-struct tevent_req *wb_simple_trans_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct tevent_queue *queue, int fd,
- struct winbindd_request *wb_req)
-{
- struct tevent_req *req, *subreq;
- struct wb_simple_trans_state *state;
-
- req = tevent_req_create(mem_ctx, &state, struct wb_simple_trans_state);
- if (req == NULL) {
- return NULL;
- }
-
- wb_req->length = sizeof(struct winbindd_request);
-
- state->ev = ev;
- state->fd = fd;
-
- subreq = wb_req_write_send(state, ev, queue, fd, wb_req);
- if (tevent_req_nomem(subreq, req)) {
- return tevent_req_post(req, ev);
- }
- tevent_req_set_callback(subreq, wb_simple_trans_write_done, req);
-
- return req;
-}
-
-static void wb_simple_trans_write_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_simple_trans_state *state = tevent_req_data(
- req, struct wb_simple_trans_state);
- ssize_t ret;
- int err;
-
- ret = wb_req_write_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret == -1) {
- tevent_req_error(req, err);
- return;
- }
- subreq = wb_resp_read_send(state, state->ev, state->fd);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_simple_trans_read_done, req);
-}
-
-static void wb_simple_trans_read_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_simple_trans_state *state = tevent_req_data(
- req, struct wb_simple_trans_state);
- ssize_t ret;
- int err;
-
- ret = wb_resp_read_recv(subreq, state, &state->wb_resp, &err);
- TALLOC_FREE(subreq);
- if (ret == -1) {
- tevent_req_error(req, err);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int wb_simple_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_response **presponse, int *err)
-{
- struct wb_simple_trans_state *state = tevent_req_data(
- req, struct wb_simple_trans_state);
-
- if (tevent_req_is_unix_error(req, err)) {
- return -1;
- }
- *presponse = talloc_move(mem_ctx, &state->wb_resp);
- return 0;
-}
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
deleted file mode 100644
index 164cfc9691..0000000000
--- a/source3/lib/wbclient.c
+++ /dev/null
@@ -1,674 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- 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.
-
- 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 "wbc_async.h"
-
-wbcErr map_wbc_err_from_errno(int error)
-{
- switch(error) {
- case EPERM:
- case EACCES:
- return WBC_ERR_AUTH_ERROR;
- case ENOMEM:
- return WBC_ERR_NO_MEMORY;
- case EIO:
- default:
- return WBC_ERR_UNKNOWN_FAILURE;
- }
-}
-
-bool tevent_req_is_wbcerr(struct tevent_req *req, wbcErr *pwbc_err)
-{
- enum tevent_req_state state;
- uint64_t error;
- if (!tevent_req_is_error(req, &state, &error)) {
- *pwbc_err = WBC_ERR_SUCCESS;
- return false;
- }
-
- switch (state) {
- case TEVENT_REQ_USER_ERROR:
- *pwbc_err = error;
- break;
- case TEVENT_REQ_TIMED_OUT:
- *pwbc_err = WBC_ERR_UNKNOWN_FAILURE;
- break;
- case TEVENT_REQ_NO_MEMORY:
- *pwbc_err = WBC_ERR_NO_MEMORY;
- break;
- default:
- *pwbc_err = WBC_ERR_UNKNOWN_FAILURE;
- break;
- }
- return true;
-}
-
-wbcErr tevent_req_simple_recv_wbcerr(struct tevent_req *req)
-{
- wbcErr wbc_err;
-
- if (tevent_req_is_wbcerr(req, &wbc_err)) {
- return wbc_err;
- }
-
- return WBC_ERR_SUCCESS;
-}
-
-struct wb_context {
- struct tevent_queue *queue;
- int fd;
- bool is_priv;
-};
-
-static int make_nonstd_fd(int fd)
-{
- int i;
- int sys_errno = 0;
- int fds[3];
- int num_fds = 0;
-
- if (fd == -1) {
- return -1;
- }
- while (fd < 3) {
- fds[num_fds++] = fd;
- fd = dup(fd);
- if (fd == -1) {
- sys_errno = errno;
- break;
- }
- }
- for (i=0; i<num_fds; i++) {
- close(fds[i]);
- }
- if (fd == -1) {
- errno = sys_errno;
- }
- return fd;
-}
-
-/****************************************************************************
- Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
- else
- if SYSV use O_NDELAY
- if BSD use FNDELAY
- Set close on exec also.
-****************************************************************************/
-
-static int make_safe_fd(int fd)
-{
- int result, flags;
- int new_fd = make_nonstd_fd(fd);
-
- if (new_fd == -1) {
- goto fail;
- }
-
- /* Socket should be nonblocking. */
-
-#ifdef O_NONBLOCK
-#define FLAG_TO_SET O_NONBLOCK
-#else
-#ifdef SYSV
-#define FLAG_TO_SET O_NDELAY
-#else /* BSD */
-#define FLAG_TO_SET FNDELAY
-#endif
-#endif
-
- if ((flags = fcntl(new_fd, F_GETFL)) == -1) {
- goto fail;
- }
-
- flags |= FLAG_TO_SET;
- if (fcntl(new_fd, F_SETFL, flags) == -1) {
- goto fail;
- }
-
-#undef FLAG_TO_SET
-
- /* Socket should be closed on exec() */
-#ifdef FD_CLOEXEC
- result = flags = fcntl(new_fd, F_GETFD, 0);
- if (flags >= 0) {
- flags |= FD_CLOEXEC;
- result = fcntl( new_fd, F_SETFD, flags );
- }
- if (result < 0) {
- goto fail;
- }
-#endif
- return new_fd;
-
- fail:
- if (new_fd != -1) {
- int sys_errno = errno;
- close(new_fd);
- errno = sys_errno;
- }
- return -1;
-}
-
-struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
-{
- struct wb_context *result;
-
- result = talloc(mem_ctx, struct wb_context);
- if (result == NULL) {
- return NULL;
- }
- result->queue = tevent_queue_create(result, "wb_trans");
- if (result->queue == NULL) {
- TALLOC_FREE(result);
- return NULL;
- }
- result->fd = -1;
- result->is_priv = false;
- return result;
-}
-
-struct wb_connect_state {
- int dummy;
-};
-
-static void wbc_connect_connected(struct tevent_req *subreq);
-
-static struct tevent_req *wb_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx,
- const char *dir)
-{
- struct tevent_req *result, *subreq;
- struct wb_connect_state *state;
- struct sockaddr_un sunaddr;
- struct stat st;
- char *path = NULL;
- wbcErr wbc_err;
-
- result = tevent_req_create(mem_ctx, &state, struct wb_connect_state);
- if (result == NULL) {
- return NULL;
- }
-
- if (wb_ctx->fd != -1) {
- close(wb_ctx->fd);
- wb_ctx->fd = -1;
- }
-
- /* Check permissions on unix socket directory */
-
- if (lstat(dir, &st) == -1) {
- wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE;
- goto post_status;
- }
-
- if (!S_ISDIR(st.st_mode) ||
- (st.st_uid != 0 && st.st_uid != geteuid())) {
- wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE;
- goto post_status;
- }
-
- /* Connect to socket */
-
- path = talloc_asprintf(talloc_tos(), "%s/%s", dir,
- WINBINDD_SOCKET_NAME);
- if (path == NULL) {
- goto nomem;
- }
-
- sunaddr.sun_family = AF_UNIX;
- strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path));
- TALLOC_FREE(path);
-
- /* If socket file doesn't exist, don't bother trying to connect
- with retry. This is an attempt to make the system usable when
- the winbindd daemon is not running. */
-
- if ((lstat(sunaddr.sun_path, &st) == -1)
- || !S_ISSOCK(st.st_mode)
- || (st.st_uid != 0 && st.st_uid != geteuid())) {
- wbc_err = WBC_ERR_WINBIND_NOT_AVAILABLE;
- goto post_status;
- }
-
- wb_ctx->fd = make_safe_fd(socket(AF_UNIX, SOCK_STREAM, 0));
- if (wb_ctx->fd == -1) {
- wbc_err = map_wbc_err_from_errno(errno);
- goto post_status;
- }
-
- subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd,
- (struct sockaddr *)(void *)&sunaddr,
- sizeof(sunaddr));
- if (subreq == NULL) {
- goto nomem;
- }
- tevent_req_set_callback(subreq, wbc_connect_connected, result);
- return result;
-
- post_status:
- tevent_req_error(result, wbc_err);
- return tevent_req_post(result, ev);
- nomem:
- TALLOC_FREE(result);
- return NULL;
-}
-
-static void wbc_connect_connected(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- int res, err;
-
- res = async_connect_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (res == -1) {
- tevent_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
- tevent_req_done(req);
-}
-
-static wbcErr wb_connect_recv(struct tevent_req *req)
-{
- return tevent_req_simple_recv_wbcerr(req);
-}
-
-static const char *winbindd_socket_dir(void)
-{
-#ifdef SOCKET_WRAPPER
- const char *env_dir;
-
- env_dir = getenv(WINBINDD_SOCKET_DIR_ENVVAR);
- if (env_dir) {
- return env_dir;
- }
-#endif
-
- return WINBINDD_SOCKET_DIR;
-}
-
-struct wb_open_pipe_state {
- struct wb_context *wb_ctx;
- struct tevent_context *ev;
- bool need_priv;
- struct winbindd_request wb_req;
-};
-
-static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq);
-static void wb_open_pipe_ping_done(struct tevent_req *subreq);
-static void wb_open_pipe_getpriv_done(struct tevent_req *subreq);
-static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq);
-
-static struct tevent_req *wb_open_pipe_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx,
- bool need_priv)
-{
- struct tevent_req *result, *subreq;
- struct wb_open_pipe_state *state;
-
- result = tevent_req_create(mem_ctx, &state, struct wb_open_pipe_state);
- if (result == NULL) {
- return NULL;
- }
- state->wb_ctx = wb_ctx;
- state->ev = ev;
- state->need_priv = need_priv;
-
- if (wb_ctx->fd != -1) {
- close(wb_ctx->fd);
- wb_ctx->fd = -1;
- }
-
- subreq = wb_connect_send(state, ev, wb_ctx, winbindd_socket_dir());
- if (subreq == NULL) {
- goto fail;
- }
- tevent_req_set_callback(subreq, wb_open_pipe_connect_nonpriv_done,
- result);
- return result;
-
- fail:
- TALLOC_FREE(result);
- return NULL;
-}
-
-static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_open_pipe_state *state = tevent_req_data(
- req, struct wb_open_pipe_state);
- wbcErr wbc_err;
-
- wbc_err = wb_connect_recv(subreq);
- TALLOC_FREE(subreq);
- if (!WBC_ERROR_IS_OK(wbc_err)) {
- state->wb_ctx->is_priv = true;
- tevent_req_error(req, wbc_err);
- return;
- }
-
- ZERO_STRUCT(state->wb_req);
- state->wb_req.cmd = WINBINDD_INTERFACE_VERSION;
- state->wb_req.pid = getpid();
-
- subreq = wb_simple_trans_send(state, state->ev, NULL,
- state->wb_ctx->fd, &state->wb_req);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_open_pipe_ping_done, req);
-}
-
-static void wb_open_pipe_ping_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_open_pipe_state *state = tevent_req_data(
- req, struct wb_open_pipe_state);
- struct winbindd_response *wb_resp;
- int ret, err;
-
- ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err);
- TALLOC_FREE(subreq);
- if (ret == -1) {
- tevent_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- if (!state->need_priv) {
- tevent_req_done(req);
- return;
- }
-
- state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR;
- state->wb_req.pid = getpid();
-
- subreq = wb_simple_trans_send(state, state->ev, NULL,
- state->wb_ctx->fd, &state->wb_req);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_open_pipe_getpriv_done, req);
-}
-
-static void wb_open_pipe_getpriv_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_open_pipe_state *state = tevent_req_data(
- req, struct wb_open_pipe_state);
- struct winbindd_response *wb_resp = NULL;
- int ret, err;
-
- ret = wb_simple_trans_recv(subreq, state, &wb_resp, &err);
- TALLOC_FREE(subreq);
- if (ret == -1) {
- tevent_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- close(state->wb_ctx->fd);
- state->wb_ctx->fd = -1;
-
- subreq = wb_connect_send(state, state->ev, state->wb_ctx,
- (char *)wb_resp->extra_data.data);
- TALLOC_FREE(wb_resp);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_open_pipe_connect_priv_done, req);
-}
-
-static void wb_open_pipe_connect_priv_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_open_pipe_state *state = tevent_req_data(
- req, struct wb_open_pipe_state);
- wbcErr wbc_err;
-
- wbc_err = wb_connect_recv(subreq);
- TALLOC_FREE(subreq);
- if (!WBC_ERROR_IS_OK(wbc_err)) {
- tevent_req_error(req, wbc_err);
- return;
- }
- state->wb_ctx->is_priv = true;
- tevent_req_done(req);
-}
-
-static wbcErr wb_open_pipe_recv(struct tevent_req *req)
-{
- return tevent_req_simple_recv_wbcerr(req);
-}
-
-struct wb_trans_state {
- struct wb_trans_state *prev, *next;
- struct wb_context *wb_ctx;
- struct tevent_context *ev;
- struct winbindd_request *wb_req;
- struct winbindd_response *wb_resp;
- bool need_priv;
-};
-
-static bool closed_fd(int fd)
-{
- struct timeval tv;
- fd_set r_fds;
- int selret;
-
- if (fd == -1) {
- return true;
- }
-
- FD_ZERO(&r_fds);
- FD_SET(fd, &r_fds);
- ZERO_STRUCT(tv);
-
- selret = select(fd+1, &r_fds, NULL, NULL, &tv);
- if (selret == -1) {
- return true;
- }
- if (selret == 0) {
- return false;
- }
- return (FD_ISSET(fd, &r_fds));
-}
-
-static void wb_trans_trigger(struct tevent_req *req, void *private_data);
-static void wb_trans_connect_done(struct tevent_req *subreq);
-static void wb_trans_done(struct tevent_req *subreq);
-static void wb_trans_retry_wait_done(struct tevent_req *subreq);
-
-struct tevent_req *wb_trans_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx, bool need_priv,
- struct winbindd_request *wb_req)
-{
- struct tevent_req *req;
- struct wb_trans_state *state;
-
- req = tevent_req_create(mem_ctx, &state, struct wb_trans_state);
- if (req == NULL) {
- return NULL;
- }
- state->wb_ctx = wb_ctx;
- state->ev = ev;
- state->wb_req = wb_req;
- state->need_priv = need_priv;
-
- if (!tevent_queue_add(wb_ctx->queue, ev, req, wb_trans_trigger,
- NULL)) {
- tevent_req_nomem(NULL, req);
- return tevent_req_post(req, ev);
- }
- return req;
-}
-
-static void wb_trans_trigger(struct tevent_req *req, void *private_data)
-{
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- struct tevent_req *subreq;
-
- if ((state->wb_ctx->fd != -1) && closed_fd(state->wb_ctx->fd)) {
- close(state->wb_ctx->fd);
- state->wb_ctx->fd = -1;
- }
-
- if ((state->wb_ctx->fd == -1)
- || (state->need_priv && !state->wb_ctx->is_priv)) {
- subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
- state->need_priv);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_trans_connect_done, req);
- return;
- }
-
- state->wb_req->pid = getpid();
-
- subreq = wb_simple_trans_send(state, state->ev, NULL,
- state->wb_ctx->fd, state->wb_req);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_trans_done, req);
-}
-
-static bool wb_trans_retry(struct tevent_req *req,
- struct wb_trans_state *state,
- wbcErr wbc_err)
-{
- struct tevent_req *subreq;
-
- if (WBC_ERROR_IS_OK(wbc_err)) {
- return false;
- }
-
- if (wbc_err == WBC_ERR_WINBIND_NOT_AVAILABLE) {
- /*
- * Winbind not around or we can't connect to the pipe. Fail
- * immediately.
- */
- tevent_req_error(req, wbc_err);
- return true;
- }
-
- /*
- * The transfer as such failed, retry after one second
- */
-
- if (state->wb_ctx->fd != -1) {
- close(state->wb_ctx->fd);
- state->wb_ctx->fd = -1;
- }
-
- subreq = tevent_wakeup_send(state, state->ev,
- timeval_current_ofs(1, 0));
- if (tevent_req_nomem(subreq, req)) {
- return true;
- }
- tevent_req_set_callback(subreq, wb_trans_retry_wait_done, req);
- return true;
-}
-
-static void wb_trans_retry_wait_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- bool ret;
-
- ret = tevent_wakeup_recv(subreq);
- TALLOC_FREE(subreq);
- if (!ret) {
- tevent_req_error(req, WBC_ERR_UNKNOWN_FAILURE);
- return;
- }
-
- subreq = wb_open_pipe_send(state, state->ev, state->wb_ctx,
- state->need_priv);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_trans_connect_done, req);
-}
-
-static void wb_trans_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- wbcErr wbc_err;
-
- wbc_err = wb_open_pipe_recv(subreq);
- TALLOC_FREE(subreq);
-
- if (wb_trans_retry(req, state, wbc_err)) {
- return;
- }
-
- subreq = wb_simple_trans_send(state, state->ev, NULL,
- state->wb_ctx->fd, state->wb_req);
- if (tevent_req_nomem(subreq, req)) {
- return;
- }
- tevent_req_set_callback(subreq, wb_trans_done, req);
-}
-
-static void wb_trans_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- int ret, err;
-
- ret = wb_simple_trans_recv(subreq, state, &state->wb_resp, &err);
- TALLOC_FREE(subreq);
- if ((ret == -1)
- && wb_trans_retry(req, state, map_wbc_err_from_errno(err))) {
- return;
- }
-
- tevent_req_done(req);
-}
-
-wbcErr wb_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- struct winbindd_response **presponse)
-{
- struct wb_trans_state *state = tevent_req_data(
- req, struct wb_trans_state);
- wbcErr wbc_err;
-
- if (tevent_req_is_wbcerr(req, &wbc_err)) {
- return wbc_err;
- }
-
- *presponse = talloc_move(mem_ctx, &state->wb_resp);
- return WBC_ERR_SUCCESS;
-}
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,