summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2009-04-20 16:53:02 +0200
committerAndrew Bartlett <abartlet@samba.org>2009-04-20 16:53:02 +0200
commit6c9caed48187a0d18becf59ab636af44cbe521b0 (patch)
treec47170169077be6f8ae60aed739803ab4ba861b7 /source3
parent53765c81f726a8c056cc4e57004592dd489975c9 (diff)
parent31120c9eacafd93e0f2c6b0f906af21adadd318a (diff)
downloadsamba-6c9caed48187a0d18becf59ab636af44cbe521b0.tar.gz
samba-6c9caed48187a0d18becf59ab636af44cbe521b0.tar.bz2
samba-6c9caed48187a0d18becf59ab636af44cbe521b0.zip
Merge commit 'origin/master' into libcli-auth-merge-without-netlogond
Diffstat (limited to 'source3')
-rw-r--r--source3/configure.in1
-rw-r--r--source3/include/ntdomain.h18
-rw-r--r--source3/include/proto.h26
-rw-r--r--source3/lib/netapi/group.c18
-rw-r--r--source3/lib/netapi/localgroup.c25
-rw-r--r--source3/lib/netapi/user.c30
-rw-r--r--source3/libnet/libnet_join.c2
-rw-r--r--source3/librpc/gen_ndr/ndr_notify.c63
-rw-r--r--source3/librpc/gen_ndr/ndr_notify.h3
-rw-r--r--source3/librpc/gen_ndr/notify.h7
-rw-r--r--source3/librpc/idl/IDL_LICENSE.txt9
-rw-r--r--source3/librpc/idl/notify.idl5
-rw-r--r--source3/libsmb/cliconnect.c2
-rw-r--r--source3/m4/aclocal.m42
-rw-r--r--source3/printing/nt_printing.c13
-rw-r--r--source3/registry/reg_api.c10
-rw-r--r--source3/rpc_server/srv_lsa_hnd.c129
-rw-r--r--source3/rpc_server/srv_lsa_nt.c10
-rw-r--r--source3/rpc_server/srv_samr_nt.c625
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c207
-rwxr-xr-x[-rw-r--r--]source3/script/installmo.sh0
-rwxr-xr-xsource3/script/tests/test_posix_s3.sh3
-rwxr-xr-x[-rw-r--r--]source3/script/uninstallmo.sh3
-rw-r--r--source3/smbd/conn.c2
-rw-r--r--source3/smbd/filename.c30
-rw-r--r--source3/smbd/files.c4
-rw-r--r--source3/smbd/lanman.c6
-rw-r--r--source3/smbd/notify.c10
-rw-r--r--source3/smbd/notify_internal.c307
-rw-r--r--source3/smbd/uid.c11
-rw-r--r--source3/torture/torture.c99
-rw-r--r--source3/utils/net.c1
-rw-r--r--source3/utils/net.h1
-rw-r--r--source3/utils/net_conf.c8
-rw-r--r--source3/utils/net_rpc.c19
-rw-r--r--source3/utils/net_rpc_join.c2
-rw-r--r--source3/utils/net_util.c2
-rw-r--r--source3/utils/smbpasswd.c16
38 files changed, 1252 insertions, 477 deletions
diff --git a/source3/configure.in b/source3/configure.in
index d0ff14fa2f..663c3a8361 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -671,6 +671,7 @@ SAVE_CPPFLAGS="${CPPFLAGS}"
CPPFLAGS="${CPPFLAGS} ${SAMBA_CONFIGURE_CPPFLAGS}"
AC_LIBREPLACE_BROKEN_CHECKS
+AC_CHECK_FUNCS([syslog],[],[AC_MSG_ERROR([Required function not found])])
AC_LIBREPLACE_NETWORK_CHECKS
CPPFLAGS="${SAVE_CPPFLAGS}"
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index c95931b5d0..de53aebb91 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -110,23 +110,7 @@ typedef struct _input_data {
prs_struct data;
} input_data;
-/*
- * Handle database - stored per pipe.
- */
-
-struct policy {
- struct policy *next, *prev;
-
- struct policy_handle pol_hnd;
-
- void *data_ptr;
-};
-
-struct handle_list {
- struct policy *Policy; /* List of policies. */
- size_t count; /* Current number of handles. */
- size_t pipe_ref_count; /* Number of pipe handles referring to this list. */
-};
+struct handle_list;
/* Domain controller authentication protocol info */
struct dcinfo {
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 4cb908b665..c40d9c680c 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -5767,14 +5767,33 @@ NTSTATUS evlog_convert_tdb_to_evt(TALLOC_CTX *mem_ctx,
/* The following definitions come from rpc_server/srv_lsa_hnd.c */
+size_t num_pipe_handles(struct handle_list *list);
bool init_pipe_handle_list(pipes_struct *p,
const struct ndr_syntax_id *syntax);
bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_ptr);
-bool find_policy_by_hnd(pipes_struct *p, struct policy_handle *hnd, void **data_p);
+bool find_policy_by_hnd(pipes_struct *p, const struct policy_handle *hnd,
+ void **data_p);
bool close_policy_hnd(pipes_struct *p, struct policy_handle *hnd);
void close_policy_by_pipe(pipes_struct *p);
bool pipe_access_check(pipes_struct *p);
+void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
+ uint32_t access_granted, size_t data_size,
+ const char *type, NTSTATUS *pstatus);
+#define policy_handle_create(_p, _hnd, _access, _type, _pstatus) \
+ (_type *)_policy_handle_create((_p), (_hnd), (_access), sizeof(_type), #_type, \
+ (_pstatus))
+
+void *_policy_handle_find(struct pipes_struct *p,
+ const struct policy_handle *hnd,
+ uint32_t access_required, uint32_t *paccess_granted,
+ const char *name, const char *location,
+ NTSTATUS *pstatus);
+#define policy_handle_find(_p, _hnd, _access_required, _access_granted, _type, _pstatus) \
+ (_type *)_policy_handle_find((_p), (_hnd), (_access_required), \
+ (_access_granted), #_type, __location__, (_pstatus))
+
+
/* The following definitions come from rpc_server/srv_pipe.c */
bool create_next_pdu(pipes_struct *p);
@@ -6446,6 +6465,11 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0,
void (*callback)(void *, const struct notify_event *),
void *private_data);
NTSTATUS notify_remove(struct notify_context *notify, void *private_data);
+NTSTATUS notify_remove_onelevel(struct notify_context *notify,
+ const struct file_id *fid,
+ void *private_data);
+void notify_onelevel(struct notify_context *notify, uint32_t action,
+ uint32_t filter, struct file_id fid, const char *name);
void notify_trigger(struct notify_context *notify,
uint32_t action, uint32_t filter, const char *path);
diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c
index c09632a857..004fd3aff6 100644
--- a/source3/lib/netapi/group.c
+++ b/source3/lib/netapi/group.c
@@ -79,7 +79,7 @@ WERROR NetGroupAdd_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_CREATE_GROUP |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -250,7 +250,7 @@ WERROR NetGroupDel_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -415,7 +415,7 @@ WERROR NetGroupSetInfo_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -650,7 +650,7 @@ WERROR NetGroupGetInfo_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -766,7 +766,7 @@ WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -887,7 +887,7 @@ WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -1165,7 +1165,7 @@ WERROR NetGroupEnum_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
@@ -1296,7 +1296,7 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -1448,7 +1448,7 @@ WERROR NetGroupSetUsers_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
diff --git a/source3/lib/netapi/localgroup.c b/source3/lib/netapi/localgroup.c
index 13405b553e..d389c1f4a2 100644
--- a/source3/lib/netapi/localgroup.c
+++ b/source3/lib/netapi/localgroup.c
@@ -157,7 +157,7 @@ WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
}
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
- SAMR_ACCESS_OPEN_DOMAIN |
+ SAMR_ACCESS_LOOKUP_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -182,7 +182,7 @@ WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -277,7 +277,7 @@ WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
}
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
- SAMR_ACCESS_OPEN_DOMAIN |
+ SAMR_ACCESS_LOOKUP_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -302,7 +302,7 @@ WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -449,7 +449,7 @@ WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
}
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
- SAMR_ACCESS_OPEN_DOMAIN |
+ SAMR_ACCESS_LOOKUP_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -474,7 +474,7 @@ WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_CREATE_ALIAS |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -620,7 +620,7 @@ WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
}
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
- SAMR_ACCESS_OPEN_DOMAIN |
+ SAMR_ACCESS_LOOKUP_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -647,7 +647,7 @@ WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -762,7 +762,7 @@ WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
}
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
- SAMR_ACCESS_OPEN_DOMAIN |
+ SAMR_ACCESS_LOOKUP_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
@@ -774,7 +774,7 @@ WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx,
}
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
- SAMR_ACCESS_OPEN_DOMAIN |
+ SAMR_ACCESS_LOOKUP_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
@@ -1068,7 +1068,7 @@ static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
}
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
- SAMR_ACCESS_OPEN_DOMAIN |
+ SAMR_ACCESS_LOOKUP_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -1098,7 +1098,7 @@ static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -1318,4 +1318,3 @@ WERROR NetLocalGroupSetMembers_l(struct libnetapi_ctx *ctx,
{
LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetLocalGroupSetMembers);
}
-
diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c
index 1cbb883169..849ba9cc92 100644
--- a/source3/lib/netapi/user.c
+++ b/source3/lib/netapi/user.c
@@ -395,7 +395,7 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
SAMR_DOMAIN_ACCESS_CREATE_USER |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
@@ -517,7 +517,7 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -1223,7 +1223,7 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
&connect_handle,
@@ -1234,7 +1234,7 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
@@ -1522,7 +1522,7 @@ WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
@@ -1648,7 +1648,7 @@ WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -1659,7 +1659,7 @@ WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
&connect_handle,
@@ -1800,7 +1800,7 @@ WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
@@ -1812,7 +1812,7 @@ WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
&connect_handle,
@@ -2220,7 +2220,7 @@ WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
access_mask,
&connect_handle,
&domain_handle,
@@ -2698,7 +2698,7 @@ WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
access_mask,
&connect_handle,
&domain_handle,
@@ -2831,7 +2831,7 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -2982,7 +2982,7 @@ WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
&connect_handle,
&domain_handle,
@@ -3264,7 +3264,7 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
&connect_handle,
@@ -3276,7 +3276,7 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli,
SAMR_ACCESS_ENUM_DOMAINS |
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
&connect_handle,
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 8e75d36fe3..894f5cba32 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -786,7 +786,7 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
status = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
pipe_hnd->desthost,
SAMR_ACCESS_ENUM_DOMAINS
- | SAMR_ACCESS_OPEN_DOMAIN,
+ | SAMR_ACCESS_LOOKUP_DOMAIN,
&sam_pol);
if (!NT_STATUS_IS_OK(status)) {
goto done;
diff --git a/source3/librpc/gen_ndr/ndr_notify.c b/source3/librpc/gen_ndr/ndr_notify.c
index d4ac42e961..844c278cd2 100644
--- a/source3/librpc/gen_ndr/ndr_notify.c
+++ b/source3/librpc/gen_ndr/ndr_notify.c
@@ -68,6 +68,69 @@ _PUBLIC_ void ndr_print_notify_entry(struct ndr_print *ndr, const char *name, co
ndr->depth--;
}
+_PUBLIC_ enum ndr_err_code ndr_push_notify_entry_array(struct ndr_push *ndr, int ndr_flags, const struct notify_entry_array *r)
+{
+ uint32_t cntr_entries_0;
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 8));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_entries));
+ for (cntr_entries_0 = 0; cntr_entries_0 < r->num_entries; cntr_entries_0++) {
+ NDR_CHECK(ndr_push_notify_entry(ndr, NDR_SCALARS, &r->entries[cntr_entries_0]));
+ }
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ for (cntr_entries_0 = 0; cntr_entries_0 < r->num_entries; cntr_entries_0++) {
+ NDR_CHECK(ndr_push_notify_entry(ndr, NDR_BUFFERS, &r->entries[cntr_entries_0]));
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ enum ndr_err_code ndr_pull_notify_entry_array(struct ndr_pull *ndr, int ndr_flags, struct notify_entry_array *r)
+{
+ uint32_t cntr_entries_0;
+ TALLOC_CTX *_mem_save_entries_0;
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 8));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_entries));
+ NDR_PULL_ALLOC_N(ndr, r->entries, r->num_entries);
+ _mem_save_entries_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->entries, 0);
+ for (cntr_entries_0 = 0; cntr_entries_0 < r->num_entries; cntr_entries_0++) {
+ NDR_CHECK(ndr_pull_notify_entry(ndr, NDR_SCALARS, &r->entries[cntr_entries_0]));
+ }
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_entries_0, 0);
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ _mem_save_entries_0 = NDR_PULL_GET_MEM_CTX(ndr);
+ NDR_PULL_SET_MEM_CTX(ndr, r->entries, 0);
+ for (cntr_entries_0 = 0; cntr_entries_0 < r->num_entries; cntr_entries_0++) {
+ NDR_CHECK(ndr_pull_notify_entry(ndr, NDR_BUFFERS, &r->entries[cntr_entries_0]));
+ }
+ NDR_PULL_SET_MEM_CTX(ndr, _mem_save_entries_0, 0);
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+_PUBLIC_ void ndr_print_notify_entry_array(struct ndr_print *ndr, const char *name, const struct notify_entry_array *r)
+{
+ uint32_t cntr_entries_0;
+ ndr_print_struct(ndr, name, "notify_entry_array");
+ ndr->depth++;
+ ndr_print_uint32(ndr, "num_entries", r->num_entries);
+ ndr->print(ndr, "%s: ARRAY(%d)", "entries", (int)r->num_entries);
+ ndr->depth++;
+ for (cntr_entries_0=0;cntr_entries_0<r->num_entries;cntr_entries_0++) {
+ char *idx_0=NULL;
+ if (asprintf(&idx_0, "[%d]", cntr_entries_0) != -1) {
+ ndr_print_notify_entry(ndr, "entries", &r->entries[cntr_entries_0]);
+ free(idx_0);
+ }
+ }
+ ndr->depth--;
+ ndr->depth--;
+}
+
static enum ndr_err_code ndr_push_notify_depth(struct ndr_push *ndr, int ndr_flags, const struct notify_depth *r)
{
uint32_t cntr_entries_0;
diff --git a/source3/librpc/gen_ndr/ndr_notify.h b/source3/librpc/gen_ndr/ndr_notify.h
index 23d3d3fc0a..fa2972dbc6 100644
--- a/source3/librpc/gen_ndr/ndr_notify.h
+++ b/source3/librpc/gen_ndr/ndr_notify.h
@@ -10,6 +10,9 @@
enum ndr_err_code ndr_push_notify_entry(struct ndr_push *ndr, int ndr_flags, const struct notify_entry *r);
enum ndr_err_code ndr_pull_notify_entry(struct ndr_pull *ndr, int ndr_flags, struct notify_entry *r);
void ndr_print_notify_entry(struct ndr_print *ndr, const char *name, const struct notify_entry *r);
+enum ndr_err_code ndr_push_notify_entry_array(struct ndr_push *ndr, int ndr_flags, const struct notify_entry_array *r);
+enum ndr_err_code ndr_pull_notify_entry_array(struct ndr_pull *ndr, int ndr_flags, struct notify_entry_array *r);
+void ndr_print_notify_entry_array(struct ndr_print *ndr, const char *name, const struct notify_entry_array *r);
void ndr_print_notify_depth(struct ndr_print *ndr, const char *name, const struct notify_depth *r);
enum ndr_err_code ndr_push_notify_array(struct ndr_push *ndr, int ndr_flags, const struct notify_array *r);
enum ndr_err_code ndr_pull_notify_array(struct ndr_pull *ndr, int ndr_flags, struct notify_array *r);
diff --git a/source3/librpc/gen_ndr/notify.h b/source3/librpc/gen_ndr/notify.h
index a5ec4a46e6..a390fa8a0b 100644
--- a/source3/librpc/gen_ndr/notify.h
+++ b/source3/librpc/gen_ndr/notify.h
@@ -2,6 +2,8 @@
#include <stdint.h>
+#include "libcli/util/ntstatus.h"
+
#ifndef _HEADER_notify
#define _HEADER_notify
@@ -16,6 +18,11 @@ struct notify_entry {
void* private_data;
}/* [public] */;
+struct notify_entry_array {
+ uint32_t num_entries;
+ struct notify_entry *entries;
+}/* [public] */;
+
struct notify_depth {
uint32_t max_mask;
uint32_t max_mask_subdir;
diff --git a/source3/librpc/idl/IDL_LICENSE.txt b/source3/librpc/idl/IDL_LICENSE.txt
new file mode 100644
index 0000000000..01ae670b69
--- /dev/null
+++ b/source3/librpc/idl/IDL_LICENSE.txt
@@ -0,0 +1,9 @@
+The IDL files in this directory are made available by the Samba Team
+under the following license:
+
+ Permission to use, copy, modify, and distribute these interface
+ definitions for any purpose is hereby granted without fee.
+
+ This work 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.
diff --git a/source3/librpc/idl/notify.idl b/source3/librpc/idl/notify.idl
index 550783b5cd..0e80679074 100644
--- a/source3/librpc/idl/notify.idl
+++ b/source3/librpc/idl/notify.idl
@@ -25,6 +25,11 @@ interface notify
pointer private_data;
} notify_entry;
+ typedef [public] struct {
+ uint32 num_entries;
+ notify_entry entries[num_entries];
+ } notify_entry_array;
+
/*
to allow for efficient search for matching entries, we
divide them by the directory depth, with a separate array
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 143bdf7019..ffe2960967 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1212,7 +1212,7 @@ bool cli_ulogoff(struct cli_state *cli)
return False;
}
- cli->cnum = -1;
+ cli->vuid = -1;
return True;
}
diff --git a/source3/m4/aclocal.m4 b/source3/m4/aclocal.m4
index 386829d1b0..ae205023a4 100644
--- a/source3/m4/aclocal.m4
+++ b/source3/m4/aclocal.m4
@@ -334,7 +334,7 @@ AC_DEFUN([AC_CHECK_FUNC_EXT],
[AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1])) $3],
[$4])dnl
AS_VAR_POPDEF([ac_var])dnl
-])# AC_CHECK_FUNC
+])# AC_CHECK_FUNC_EXT
# AH_CHECK_FUNC_EXT(FUNCNAME)
# ---------------------
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index f3b938e6ff..d6fead11c2 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -745,7 +745,7 @@ int get_builtin_ntforms(nt_forms_struct **list)
if (!*list) {
return 0;
}
- return sizeof(default_forms) / sizeof(default_forms[0]);
+ return ARRAY_SIZE(default_forms);
}
/****************************************************************************
@@ -754,18 +754,17 @@ int get_builtin_ntforms(nt_forms_struct **list)
bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form)
{
- int i,count;
+ int i;
DEBUGADD(6,("Looking for builtin form %s \n", form_name));
- count = sizeof(default_forms) / sizeof(default_forms[0]);
- for (i=0;i<count;i++) {
+ for (i=0; i<ARRAY_SIZE(default_forms); i++) {
if (strequal(form_name,default_forms[i].name)) {
DEBUGADD(6,("Found builtin form %s \n", form_name));
memcpy(form,&default_forms[i],sizeof(*form));
- break;
+ return true;
}
}
- return (i !=count);
+ return false;
}
/****************************************************************************
@@ -5736,7 +5735,7 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
/* Always allow root or SE_PRINT_OPERATROR to do anything */
- if (server_info->utok.uid == 0
+ if (server_info->utok.uid == sec_initial_uid()
|| user_has_privileges(server_info->ptok, &se_printop ) ) {
return True;
}
diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c
index 67767a2e56..c1a78c14dc 100644
--- a/source3/registry/reg_api.c
+++ b/source3/registry/reg_api.c
@@ -459,6 +459,16 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent,
char *path, *end;
WERROR err;
+ /*
+ * We must refuse to handle subkey-paths containing
+ * a '/' character because at a lower level, after
+ * normalization, '/' is treated as a key separator
+ * just like '\\'.
+ */
+ if (strchr(subkeypath, '/') != NULL) {
+ return WERR_INVALID_PARAM;
+ }
+
if (!(mem_ctx = talloc_new(ctx))) return WERR_NOMEM;
if (!(path = talloc_strdup(mem_ctx, subkeypath))) {
diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c
index e853bb2047..21b297af2d 100644
--- a/source3/rpc_server/srv_lsa_hnd.c
+++ b/source3/rpc_server/srv_lsa_hnd.c
@@ -24,6 +24,26 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_SRV
+/*
+ * Handle database - stored per pipe.
+ */
+
+struct policy {
+ struct policy *next, *prev;
+
+ struct policy_handle pol_hnd;
+
+ uint32_t access_granted;
+
+ void *data_ptr;
+};
+
+struct handle_list {
+ struct policy *Policy; /* List of policies. */
+ size_t count; /* Current number of handles. */
+ size_t pipe_ref_count; /* Number of pipe handles referring to this list. */
+};
+
/* This is the max handles across all instances of a pipe name. */
#ifndef MAX_OPEN_POLS
#define MAX_OPEN_POLS 1024
@@ -40,6 +60,14 @@ static bool is_samr_lsa_pipe(const struct ndr_syntax_id *syntax)
|| ndr_syntax_id_equal(syntax, &ndr_table_lsarpc.syntax_id));
}
+size_t num_pipe_handles(struct handle_list *list)
+{
+ if (list == NULL) {
+ return 0;
+ }
+ return list->count;
+}
+
/****************************************************************************
Initialise a policy handle list on a pipe. Handle list is shared between all
pipes of the same name.
@@ -112,7 +140,9 @@ bool init_pipe_handle_list(pipes_struct *p, const struct ndr_syntax_id *syntax)
data_ptr is TALLOC_FREE()'ed
****************************************************************************/
-bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_ptr)
+static struct policy *create_policy_hnd_internal(pipes_struct *p,
+ struct policy_handle *hnd,
+ void *data_ptr)
{
static uint32 pol_hnd_low = 0;
static uint32 pol_hnd_high = 0;
@@ -123,13 +153,13 @@ bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_pt
if (p->pipe_handles->count > MAX_OPEN_POLS) {
DEBUG(0,("create_policy_hnd: ERROR: too many handles (%d) on this pipe.\n",
(int)p->pipe_handles->count));
- return False;
+ return NULL;
}
pol = TALLOC_ZERO_P(NULL, struct policy);
if (!pol) {
DEBUG(0,("create_policy_hnd: ERROR: out of memory!\n"));
- return False;
+ return NULL;
}
if (data_ptr != NULL) {
@@ -160,14 +190,22 @@ bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd, void *data_pt
DEBUG(4,("Opened policy hnd[%d] ", (int)p->pipe_handles->count));
dump_data(4, (uint8 *)hnd, sizeof(*hnd));
- return True;
+ return pol;
+}
+
+bool create_policy_hnd(pipes_struct *p, struct policy_handle *hnd,
+ void *data_ptr)
+{
+ return create_policy_hnd_internal(p, hnd, data_ptr) != NULL;
}
/****************************************************************************
find policy by handle - internal version.
****************************************************************************/
-static struct policy *find_policy_by_hnd_internal(pipes_struct *p, struct policy_handle *hnd, void **data_p)
+static struct policy *find_policy_by_hnd_internal(pipes_struct *p,
+ const struct policy_handle *hnd,
+ void **data_p)
{
struct policy *pol;
size_t i;
@@ -197,7 +235,8 @@ static struct policy *find_policy_by_hnd_internal(pipes_struct *p, struct policy
find policy by handle
****************************************************************************/
-bool find_policy_by_hnd(pipes_struct *p, struct policy_handle *hnd, void **data_p)
+bool find_policy_by_hnd(pipes_struct *p, const struct policy_handle *hnd,
+ void **data_p)
{
return find_policy_by_hnd_internal(p, hnd, data_p) == NULL ? False : True;
}
@@ -277,3 +316,81 @@ bool pipe_access_check(pipes_struct *p)
return True;
}
+
+void *_policy_handle_create(struct pipes_struct *p, struct policy_handle *hnd,
+ uint32_t access_granted, size_t data_size,
+ const char *type, NTSTATUS *pstatus)
+{
+ struct policy *pol;
+ void *data;
+
+ if (p->pipe_handles->count > MAX_OPEN_POLS) {
+ DEBUG(0, ("policy_handle_create: ERROR: too many handles (%d) "
+ "on pipe %s.\n", (int)p->pipe_handles->count,
+ get_pipe_name_from_iface(&p->syntax)));
+ *pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
+ return NULL;
+ }
+
+ data = talloc_size(talloc_tos(), data_size);
+ if (data == NULL) {
+ *pstatus = NT_STATUS_NO_MEMORY;
+ return NULL;
+ }
+ talloc_set_name(data, "%s", type);
+
+ pol = create_policy_hnd_internal(p, hnd, data);
+ if (pol == NULL) {
+ TALLOC_FREE(data);
+ *pstatus = NT_STATUS_NO_MEMORY;
+ return NULL;
+ }
+ pol->access_granted = access_granted;
+ *pstatus = NT_STATUS_OK;
+ return data;
+}
+
+void *_policy_handle_find(struct pipes_struct *p,
+ const struct policy_handle *hnd,
+ uint32_t access_required,
+ uint32_t *paccess_granted,
+ const char *name, const char *location,
+ NTSTATUS *pstatus)
+{
+ struct policy *pol;
+ void *data;
+
+ pol = find_policy_by_hnd_internal(p, hnd, &data);
+ if (pol == NULL) {
+ *pstatus = NT_STATUS_INVALID_HANDLE;
+ return NULL;
+ }
+ if (strcmp(name, talloc_get_name(data)) != 0) {
+ DEBUG(10, ("expected %s, got %s\n", name,
+ talloc_get_name(data)));
+ *pstatus = NT_STATUS_INVALID_HANDLE;
+ return NULL;
+ }
+ if ((access_required & pol->access_granted) != access_required) {
+ if (geteuid() == sec_initial_uid()) {
+ DEBUG(4, ("%s: ACCESS should be DENIED (granted: "
+ "%#010x; required: %#010x)\n", location,
+ pol->access_granted, access_required));
+ DEBUGADD(4,("but overwritten by euid == 0\n"));
+ goto okay;
+ }
+ DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: "
+ "%#010x)\n", location, pol->access_granted,
+ access_required));
+ *pstatus = NT_STATUS_ACCESS_DENIED;
+ return NULL;
+ }
+
+ okay:
+ DEBUG(10, ("found handle of type %s\n", talloc_get_name(data)));
+ if (paccess_granted != NULL) {
+ *paccess_granted = pol->access_granted;
+ }
+ *pstatus = NT_STATUS_OK;
+ return data;
+}
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index 0ce2b40f65..9481c206f6 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -827,7 +827,15 @@ NTSTATUS _lsa_LookupSids(pipes_struct *p,
&names,
&mapped_count);
- if (NT_STATUS_IS_ERR(status)) {
+ /* Only return here when there is a real error.
+ NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
+ the requested sids could be resolved. Older versions of XP (pre SP3)
+ rely that we return with the string representations of those SIDs in
+ that case. If we don't, XP crashes - Guenther
+ */
+
+ if (NT_STATUS_IS_ERR(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
return status;
}
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 187c721dfb..b54ed717a3 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -49,9 +49,17 @@
#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */
#define MAX_SAM_ENTRIES_W95 50
+struct samr_connect_info {
+ uint8_t dummy;
+};
+
+struct samr_domain_info {
+ struct dom_sid sid;
+ struct disp_info *disp_info;
+};
+
typedef struct disp_info {
DOM_SID sid; /* identify which domain this is. */
- bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
struct pdb_search *users; /* querydispinfo 1 and 4 */
struct pdb_search *machines; /* querydispinfo 2 */
struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
@@ -70,7 +78,6 @@ typedef struct disp_info {
struct samr_info {
/* for use by the \PIPE\samr policy */
DOM_SID sid;
- bool builtin_domain; /* Quick flag to check if this is the builtin domain. */
uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
uint32 acc_granted;
DISP_INFO *disp_info;
@@ -298,7 +305,7 @@ static void map_max_allowed_access(const NT_USER_TOKEN *token,
Fetch or create a dispinfo struct.
********************************************************************/
-static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
+static DISP_INFO *get_samr_dispinfo_by_sid(const struct dom_sid *psid)
{
/*
* We do a static cache for DISP_INFO's here. Explanation can be found
@@ -377,26 +384,20 @@ static struct samr_info *get_samr_info_by_sid(TALLOC_CTX *mem_ctx,
DOM_SID *psid)
{
struct samr_info *info;
- fstring sid_str;
- if (psid) {
- sid_to_fstring(sid_str, psid);
- } else {
- fstrcpy(sid_str,"(NULL)");
- }
-
- if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL) {
+ info = talloc_zero(mem_ctx, struct samr_info);
+ if (info == NULL) {
return NULL;
}
talloc_set_destructor(info, samr_info_destructor);
- DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
+ DEBUG(10, ("get_samr_info_by_sid: created new info for sid %s\n",
+ sid_string_dbg(psid)));
+
if (psid) {
sid_copy( &info->sid, psid);
- info->builtin_domain = sid_check_is_builtin(psid);
} else {
DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
- info->builtin_domain = False;
}
info->disp_info = get_samr_dispinfo_by_sid(psid);
@@ -481,8 +482,10 @@ static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromno
We must also remove the timeout handler.
********************************************************************/
-static void force_flush_samr_cache(DISP_INFO *disp_info)
+static void force_flush_samr_cache(const struct dom_sid *sid)
{
+ struct disp_info *disp_info = get_samr_dispinfo_by_sid(sid);
+
if ((disp_info == NULL) || (disp_info->cache_timeout_event == NULL)) {
return;
}
@@ -512,7 +515,7 @@ static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
{
struct samr_displayentry *entry;
- if (info->builtin_domain) {
+ if (sid_check_is_builtin(&info->sid)) {
/* No users in builtin. */
return 0;
}
@@ -536,7 +539,7 @@ static uint32 count_sam_groups(struct disp_info *info)
{
struct samr_displayentry *entry;
- if (info->builtin_domain) {
+ if (sid_check_is_builtin(&info->sid)) {
/* No groups in builtin. */
return 0;
}
@@ -597,7 +600,8 @@ NTSTATUS _samr_Close(pipes_struct *p, struct samr_Close *r)
NTSTATUS _samr_OpenDomain(pipes_struct *p,
struct samr_OpenDomain *r)
{
- struct samr_info *info;
+ struct samr_connect_info *cinfo;
+ struct samr_domain_info *dinfo;
SEC_DESC *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
@@ -607,15 +611,11 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
/* find the connection policy handle. */
- if ( !find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info) )
- return NT_STATUS_INVALID_HANDLE;
-
- status = access_check_samr_function(info->acc_granted,
- SAMR_ACCESS_OPEN_DOMAIN,
- "_samr_OpenDomain" );
-
- if ( !NT_STATUS_IS_OK(status) )
+ cinfo = policy_handle_find(p, r->in.connect_handle, 0, NULL,
+ struct samr_connect_info, &status);
+ if (!NT_STATUS_IS_OK(status)) {
return status;
+ }
/*check if access can be granted as requested by client. */
map_max_allowed_access(p->server_info->ptok, &des_access);
@@ -638,14 +638,13 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p,
return NT_STATUS_NO_SUCH_DOMAIN;
}
- /* associate the domain SID with the (unique) handle. */
- if ((info = get_samr_info_by_sid(p->mem_ctx, r->in.sid))==NULL)
- return NT_STATUS_NO_MEMORY;
- info->acc_granted = acc_granted;
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, r->out.domain_handle, info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ dinfo = policy_handle_create(p, r->out.domain_handle, acc_granted,
+ struct samr_domain_info, &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ dinfo->sid = *r->in.sid;
+ dinfo->disp_info = get_samr_dispinfo_by_sid(r->in.sid);
DEBUG(5,("_samr_OpenDomain: %d\n", __LINE__));
@@ -964,7 +963,7 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
struct samr_EnumDomainUsers *r)
{
NTSTATUS status;
- struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
int num_account;
uint32 enum_context = *r->in.resume_handle;
enum remote_arch_types ra_type = get_remote_arch();
@@ -974,20 +973,16 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
struct samr_SamArray *samr_array = NULL;
struct samr_SamEntry *samr_entries = NULL;
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
- return NT_STATUS_INVALID_HANDLE;
+ DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
- status = access_check_samr_function(info->acc_granted,
- SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
- "_samr_EnumDomainUsers");
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+ struct samr_domain_info, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- DEBUG(5,("_samr_EnumDomainUsers: %d\n", __LINE__));
-
- if (info->builtin_domain) {
+ if (sid_check_is_builtin(&dinfo->sid)) {
/* No users in builtin. */
*r->out.resume_handle = *r->in.resume_handle;
DEBUG(5,("_samr_EnumDomainUsers: No users in BUILTIN\n"));
@@ -1004,24 +999,24 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
/* AS ROOT !!!! */
- if ((info->disp_info->enum_users != NULL) &&
- (info->disp_info->enum_acb_mask != r->in.acct_flags)) {
- TALLOC_FREE(info->disp_info->enum_users);
+ if ((dinfo->disp_info->enum_users != NULL) &&
+ (dinfo->disp_info->enum_acb_mask != r->in.acct_flags)) {
+ TALLOC_FREE(dinfo->disp_info->enum_users);
}
- if (info->disp_info->enum_users == NULL) {
- info->disp_info->enum_users = pdb_search_users(
- info->disp_info, r->in.acct_flags);
- info->disp_info->enum_acb_mask = r->in.acct_flags;
+ if (dinfo->disp_info->enum_users == NULL) {
+ dinfo->disp_info->enum_users = pdb_search_users(
+ dinfo->disp_info, r->in.acct_flags);
+ dinfo->disp_info->enum_acb_mask = r->in.acct_flags;
}
- if (info->disp_info->enum_users == NULL) {
+ if (dinfo->disp_info->enum_users == NULL) {
/* END AS ROOT !!!! */
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
- num_account = pdb_search_entries(info->disp_info->enum_users,
+ num_account = pdb_search_entries(dinfo->disp_info->enum_users,
enum_context, max_entries,
&entries);
@@ -1050,7 +1045,7 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p,
}
/* Ensure we cache this enumeration. */
- set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+ set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
DEBUG(5, ("_samr_EnumDomainUsers: %d\n", __LINE__));
@@ -1107,26 +1102,22 @@ NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
struct samr_EnumDomainGroups *r)
{
NTSTATUS status;
- struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
struct samr_displayentry *groups;
uint32 num_groups;
struct samr_SamArray *samr_array = NULL;
struct samr_SamEntry *samr_entries = NULL;
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- status = access_check_samr_function(info->acc_granted,
- SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
- "_samr_EnumDomainGroups");
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+ struct samr_domain_info, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
DEBUG(5,("_samr_EnumDomainGroups: %d\n", __LINE__));
- if (info->builtin_domain) {
+ if (sid_check_is_builtin(&dinfo->sid)) {
/* No groups in builtin. */
*r->out.resume_handle = *r->in.resume_handle;
DEBUG(5,("_samr_EnumDomainGroups: No groups in BUILTIN\n"));
@@ -1142,22 +1133,22 @@ NTSTATUS _samr_EnumDomainGroups(pipes_struct *p,
become_root();
- if (info->disp_info->groups == NULL) {
- info->disp_info->groups = pdb_search_groups(info->disp_info);
+ if (dinfo->disp_info->groups == NULL) {
+ dinfo->disp_info->groups = pdb_search_groups(dinfo->disp_info);
- if (info->disp_info->groups == NULL) {
+ if (dinfo->disp_info->groups == NULL) {
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
}
- num_groups = pdb_search_entries(info->disp_info->groups,
+ num_groups = pdb_search_entries(dinfo->disp_info->groups,
*r->in.resume_handle,
MAX_SAM_ENTRIES, &groups);
unbecome_root();
/* Ensure we cache this enumeration. */
- set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+ set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
make_group_sam_entry_list(p->mem_ctx, &samr_entries,
num_groups, groups);
@@ -1182,26 +1173,22 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
struct samr_EnumDomainAliases *r)
{
NTSTATUS status;
- struct samr_info *info;
+ struct samr_domain_info *dinfo;
struct samr_displayentry *aliases;
uint32 num_aliases = 0;
struct samr_SamArray *samr_array = NULL;
struct samr_SamEntry *samr_entries = NULL;
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
- sid_string_dbg(&info->sid)));
-
- status = access_check_samr_function(info->acc_granted,
- SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
- "_samr_EnumDomainAliases");
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+ struct samr_domain_info, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+ DEBUG(5,("_samr_EnumDomainAliases: sid %s\n",
+ sid_string_dbg(&dinfo->sid)));
+
samr_array = TALLOC_ZERO_P(p->mem_ctx, struct samr_SamArray);
if (!samr_array) {
return NT_STATUS_NO_MEMORY;
@@ -1209,22 +1196,22 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p,
become_root();
- if (info->disp_info->aliases == NULL) {
- info->disp_info->aliases = pdb_search_aliases(
- info->disp_info, &info->sid);
- if (info->disp_info->aliases == NULL) {
+ if (dinfo->disp_info->aliases == NULL) {
+ dinfo->disp_info->aliases = pdb_search_aliases(
+ dinfo->disp_info, &dinfo->sid);
+ if (dinfo->disp_info->aliases == NULL) {
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
}
- num_aliases = pdb_search_entries(info->disp_info->aliases,
+ num_aliases = pdb_search_entries(dinfo->disp_info->aliases,
*r->in.resume_handle,
MAX_SAM_ENTRIES, &aliases);
unbecome_root();
/* Ensure we cache this enumeration. */
- set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+ set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
make_group_sam_entry_list(p->mem_ctx, &samr_entries,
num_aliases, aliases);
@@ -1447,7 +1434,7 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
struct samr_QueryDisplayInfo *r)
{
NTSTATUS status;
- struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
uint32 max_entries = r->in.max_entries;
@@ -1465,18 +1452,9 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
DEBUG(5,("_samr_QueryDisplayInfo: %d\n", __LINE__));
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- if (info->builtin_domain) {
- DEBUG(5,("_samr_QueryDisplayInfo: Nothing in BUILTIN\n"));
- return NT_STATUS_OK;
- }
-
- status = access_check_samr_function(info->acc_granted,
- SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
- "_samr_QueryDisplayInfo");
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+ struct samr_domain_info, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -1541,10 +1519,10 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
switch (r->in.level) {
case 0x1:
case 0x4:
- if (info->disp_info->users == NULL) {
- info->disp_info->users = pdb_search_users(
- info->disp_info, ACB_NORMAL);
- if (info->disp_info->users == NULL) {
+ if (dinfo->disp_info->users == NULL) {
+ dinfo->disp_info->users = pdb_search_users(
+ dinfo->disp_info, ACB_NORMAL);
+ if (dinfo->disp_info->users == NULL) {
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
@@ -1555,15 +1533,15 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
(unsigned int)enum_context ));
}
- num_account = pdb_search_entries(info->disp_info->users,
+ num_account = pdb_search_entries(dinfo->disp_info->users,
enum_context, max_entries,
&entries);
break;
case 0x2:
- if (info->disp_info->machines == NULL) {
- info->disp_info->machines = pdb_search_users(
- info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
- if (info->disp_info->machines == NULL) {
+ if (dinfo->disp_info->machines == NULL) {
+ dinfo->disp_info->machines = pdb_search_users(
+ dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
+ if (dinfo->disp_info->machines == NULL) {
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
@@ -1574,16 +1552,16 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
(unsigned int)enum_context ));
}
- num_account = pdb_search_entries(info->disp_info->machines,
+ num_account = pdb_search_entries(dinfo->disp_info->machines,
enum_context, max_entries,
&entries);
break;
case 0x3:
case 0x5:
- if (info->disp_info->groups == NULL) {
- info->disp_info->groups = pdb_search_groups(
- info->disp_info);
- if (info->disp_info->groups == NULL) {
+ if (dinfo->disp_info->groups == NULL) {
+ dinfo->disp_info->groups = pdb_search_groups(
+ dinfo->disp_info);
+ if (dinfo->disp_info->groups == NULL) {
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
@@ -1594,7 +1572,7 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
(unsigned int)enum_context ));
}
- num_account = pdb_search_entries(info->disp_info->groups,
+ num_account = pdb_search_entries(dinfo->disp_info->groups,
enum_context, max_entries,
&entries);
break;
@@ -1651,7 +1629,7 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p,
}
/* Ensure we cache this enumeration. */
- set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+ set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
DEBUG(5, ("_samr_QueryDisplayInfo: %d\n", __LINE__));
@@ -1776,25 +1754,20 @@ NTSTATUS _samr_QueryAliasInfo(pipes_struct *p,
NTSTATUS _samr_LookupNames(pipes_struct *p,
struct samr_LookupNames *r)
{
+ struct samr_domain_info *dinfo;
NTSTATUS status;
uint32 *rid;
enum lsa_SidType *type;
int i;
int num_rids = r->in.num_names;
- DOM_SID pol_sid;
- uint32 acc_granted;
struct samr_Ids rids, types;
uint32_t num_mapped = 0;
DEBUG(5,("_samr_LookupNames: %d\n", __LINE__));
- if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL)) {
- return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
-
- status = access_check_samr_function(acc_granted,
- 0, /* Don't know the acc_bits yet */
- "_samr_LookupNames");
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ 0 /* Don't know the acc_bits yet */, NULL,
+ struct samr_domain_info, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -1811,7 +1784,7 @@ NTSTATUS _samr_LookupNames(pipes_struct *p,
NT_STATUS_HAVE_NO_MEMORY(type);
DEBUG(5,("_samr_LookupNames: looking name on SID %s\n",
- sid_string_dbg(&pol_sid)));
+ sid_string_dbg(&dinfo->sid)));
for (i = 0; i < num_rids; i++) {
@@ -1820,7 +1793,7 @@ NTSTATUS _samr_LookupNames(pipes_struct *p,
rid[i] = 0xffffffff;
- if (sid_check_is_builtin(&pol_sid)) {
+ if (sid_check_is_builtin(&dinfo->sid)) {
if (lookup_builtin_name(r->in.names[i].string,
&rid[i]))
{
@@ -2037,13 +2010,12 @@ static bool make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
NTSTATUS _samr_LookupRids(pipes_struct *p,
struct samr_LookupRids *r)
{
+ struct samr_domain_info *dinfo;
NTSTATUS status;
const char **names;
enum lsa_SidType *attrs = NULL;
uint32 *wire_attrs = NULL;
- DOM_SID pol_sid;
int num_rids = (int)r->in.num_rids;
- uint32 acc_granted;
int i;
struct lsa_Strings names_array;
struct samr_Ids types_array;
@@ -2051,13 +2023,9 @@ NTSTATUS _samr_LookupRids(pipes_struct *p,
DEBUG(5,("_samr_LookupRids: %d\n", __LINE__));
- /* find the policy handle. open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &pol_sid, &acc_granted, NULL))
- return NT_STATUS_INVALID_HANDLE;
-
- status = access_check_samr_function(acc_granted,
- 0, /* Don't know the acc_bits yet */
- "_samr_LookupRids");
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ 0 /* Don't know the acc_bits yet */, NULL,
+ struct samr_domain_info, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -2082,7 +2050,7 @@ NTSTATUS _samr_LookupRids(pipes_struct *p,
}
become_root(); /* lookup_sid can require root privs */
- status = pdb_lookup_rids(&pol_sid, num_rids, r->in.rids,
+ status = pdb_lookup_rids(&dinfo->sid, num_rids, r->in.rids,
names, attrs);
unbecome_root();
@@ -2123,7 +2091,8 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
{
struct samu *sampass=NULL;
DOM_SID sid;
- struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
+ struct samr_info *info;
SEC_DESC *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
@@ -2131,18 +2100,14 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
bool ret;
NTSTATUS nt_status;
SE_PRIV se_rights;
+ NTSTATUS status;
- /* find the domain policy handle and get domain SID / access bits in the domain policy. */
-
- if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
- return NT_STATUS_INVALID_HANDLE;
-
- nt_status = access_check_samr_function(acc_granted,
- SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
- "_samr_OpenUser" );
-
- if ( !NT_STATUS_IS_OK(nt_status) )
- return nt_status;
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
+ struct samr_domain_info, &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
if ( !(sampass = samu_new( p->mem_ctx )) ) {
return NT_STATUS_NO_MEMORY;
@@ -2150,7 +2115,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p,
/* append the user's RID to it */
- if (!sid_append_rid(&sid, r->in.rid))
+ if (!sid_compose(&sid, &dinfo->sid, r->in.rid))
return NT_STATUS_NO_SUCH_USER;
/* check if access can be granted as requested by client. */
@@ -2788,7 +2753,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
struct samr_QueryDomainInfo *r)
{
NTSTATUS status = NT_STATUS_OK;
- struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
union samr_DomainInfo *dom_info;
time_t u_expire, u_min_age;
@@ -2802,23 +2767,18 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
DEBUG(5,("_samr_QueryDomainInfo: %d\n", __LINE__));
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
+ struct samr_domain_info, &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
dom_info = TALLOC_ZERO_P(p->mem_ctx, union samr_DomainInfo);
if (!dom_info) {
return NT_STATUS_NO_MEMORY;
}
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
- return NT_STATUS_INVALID_HANDLE;
- }
-
- status = access_check_samr_function(info->acc_granted,
- SAMR_ACCESS_OPEN_DOMAIN,
- "_samr_QueryDomainInfo" );
-
- if ( !NT_STATUS_IS_OK(status) )
- return status;
-
switch (r->in.level) {
case 0x01:
@@ -2860,9 +2820,12 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p,
/* AS ROOT !!! */
- dom_info->general.num_users = count_sam_users(info->disp_info, ACB_NORMAL);
- dom_info->general.num_groups = count_sam_groups(info->disp_info);
- dom_info->general.num_aliases = count_sam_aliases(info->disp_info);
+ dom_info->general.num_users = count_sam_users(
+ dinfo->disp_info, ACB_NORMAL);
+ dom_info->general.num_groups = count_sam_groups(
+ dinfo->disp_info);
+ dom_info->general.num_aliases = count_sam_aliases(
+ dinfo->disp_info);
pdb_get_account_policy(AP_TIME_TO_LOGOUT, &u_logout);
@@ -3032,7 +2995,8 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
const char *account = NULL;
DOM_SID sid;
uint32_t acb_info = r->in.acct_flags;
- struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
+ struct samr_info *info;
NTSTATUS nt_status;
uint32 acc_granted;
SEC_DESC *psd;
@@ -3041,25 +3005,19 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
bool can_add_account = False;
SE_PRIV se_rights;
- DISP_INFO *disp_info = NULL;
- /* Get the domain SID stored in the domain policy */
- if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted,
- &disp_info))
- return NT_STATUS_INVALID_HANDLE;
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_CREATE_USER, NULL,
+ struct samr_domain_info, &nt_status);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
- if (disp_info->builtin_domain) {
+ if (sid_check_is_builtin(&dinfo->sid)) {
DEBUG(5,("_samr_CreateUser2: Refusing user create in BUILTIN\n"));
return NT_STATUS_ACCESS_DENIED;
}
- nt_status = access_check_samr_function(acc_granted,
- SAMR_DOMAIN_ACCESS_CREATE_USER,
- "_samr_CreateUser2");
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
-
if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
/* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
@@ -3161,7 +3119,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p,
}
/* After a "set" ensure we have no cached display info. */
- force_flush_samr_cache(info->disp_info);
+ force_flush_samr_cache(&sid);
*r->out.access_granted = acc_granted;
@@ -3195,8 +3153,11 @@ NTSTATUS _samr_CreateUser(pipes_struct *p,
NTSTATUS _samr_Connect(pipes_struct *p,
struct samr_Connect *r)
{
- struct samr_info *info = NULL;
+ struct samr_connect_info *info;
+ uint32_t acc_granted;
+ struct policy_handle hnd;
uint32 des_access = r->in.access_mask;
+ NTSTATUS status;
/* Access check */
@@ -3205,12 +3166,6 @@ NTSTATUS _samr_Connect(pipes_struct *p,
return NT_STATUS_ACCESS_DENIED;
}
- /* set up the SAMR connect_anon response */
-
- /* associate the user's SID with the new handle. */
- if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
/* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS
was observed from a win98 client trying to enumerate users (when configured
user level access control on shares) --jerry */
@@ -3218,12 +3173,20 @@ NTSTATUS _samr_Connect(pipes_struct *p,
map_max_allowed_access(p->server_info->ptok, &des_access);
se_map_generic( &des_access, &sam_generic_mapping );
- info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN);
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, r->out.connect_handle, info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS
+ |SAMR_ACCESS_LOOKUP_DOMAIN);
+
+ /* set up the SAMR connect_anon response */
+
+ info = policy_handle_create(p, &hnd, acc_granted,
+ struct samr_connect_info,
+ &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ *r->out.connect_handle = hnd;
return NT_STATUS_OK;
}
@@ -3234,7 +3197,8 @@ NTSTATUS _samr_Connect(pipes_struct *p,
NTSTATUS _samr_Connect2(pipes_struct *p,
struct samr_Connect2 *r)
{
- struct samr_info *info = NULL;
+ struct samr_connect_info *info = NULL;
+ struct policy_handle hnd;
SEC_DESC *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
@@ -3277,20 +3241,16 @@ NTSTATUS _samr_Connect2(pipes_struct *p,
if ( !NT_STATUS_IS_OK(nt_status) )
return nt_status;
- /* associate the user's SID and access granted with the new handle. */
- if ((info = get_samr_info_by_sid(p->mem_ctx, NULL)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- info->acc_granted = acc_granted;
- info->status = r->in.access_mask; /* this looks so wrong... - gd */
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, r->out.connect_handle, info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ info = policy_handle_create(p, &hnd, acc_granted,
+ struct samr_connect_info, &nt_status);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
DEBUG(5,("%s: %d\n", fn, __LINE__));
- return nt_status;
+ *r->out.connect_handle = hnd;
+ return NT_STATUS_OK;
}
/****************************************************************
@@ -3361,20 +3321,18 @@ NTSTATUS _samr_Connect5(pipes_struct *p,
NTSTATUS _samr_LookupDomain(pipes_struct *p,
struct samr_LookupDomain *r)
{
- NTSTATUS status = NT_STATUS_OK;
- struct samr_info *info;
+ NTSTATUS status;
+ struct samr_connect_info *info;
const char *domain_name;
DOM_SID *sid = NULL;
- if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
- return NT_STATUS_INVALID_HANDLE;
-
/* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here.
Reverted that change so we will work with RAS servers again */
- status = access_check_samr_function(info->acc_granted,
- SAMR_ACCESS_OPEN_DOMAIN,
- "_samr_LookupDomain");
+ info = policy_handle_find(p, r->in.connect_handle,
+ SAMR_ACCESS_LOOKUP_DOMAIN, NULL,
+ struct samr_connect_info,
+ &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -3413,17 +3371,14 @@ NTSTATUS _samr_EnumDomains(pipes_struct *p,
struct samr_EnumDomains *r)
{
NTSTATUS status;
- struct samr_info *info;
+ struct samr_connect_info *info;
uint32_t num_entries = 2;
struct samr_SamEntry *entry_array = NULL;
struct samr_SamArray *sam;
- if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- status = access_check_samr_function(info->acc_granted,
- SAMR_ACCESS_ENUM_DOMAINS,
- "_samr_EnumDomains");
+ info = policy_handle_find(p, r->in.connect_handle,
+ SAMR_ACCESS_ENUM_DOMAINS, NULL,
+ struct samr_connect_info, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -3465,6 +3420,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
DOM_SID sid;
uint32 alias_rid = r->in.rid;
struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
SEC_DESC *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
@@ -3472,21 +3428,16 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p,
NTSTATUS status;
SE_PRIV se_rights;
- /* find the domain policy and get the SID / access bits stored in the domain policy */
-
- if ( !get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL) )
- return NT_STATUS_INVALID_HANDLE;
-
- status = access_check_samr_function(acc_granted,
- SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
- "_samr_OpenAlias");
-
- if ( !NT_STATUS_IS_OK(status) )
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
+ struct samr_domain_info, &status);
+ if (!NT_STATUS_IS_OK(status)) {
return status;
+ }
/* append the alias' RID to it */
- if (!sid_append_rid(&sid, alias_rid))
+ if (!sid_compose(&sid, &dinfo->sid, alias_rid))
return NT_STATUS_NO_SUCH_ALIAS;
/*check if access can be granted as requested by client. */
@@ -4288,7 +4239,7 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p,
/* ================ END SeMachineAccountPrivilege BLOCK ================ */
if (NT_STATUS_IS_OK(status)) {
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&sid);
}
return status;
@@ -4319,36 +4270,25 @@ NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
{
size_t num_alias_rids;
uint32 *alias_rids;
- struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
size_t i;
- NTSTATUS ntstatus1;
- NTSTATUS ntstatus2;
+ NTSTATUS status;
DOM_SID *members;
DEBUG(5,("_samr_GetAliasMembership: %d\n", __LINE__));
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
- return NT_STATUS_INVALID_HANDLE;
-
- ntstatus1 = access_check_samr_function(info->acc_granted,
- SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS,
- "_samr_GetAliasMembership");
- ntstatus2 = access_check_samr_function(info->acc_granted,
- SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
- "_samr_GetAliasMembership");
-
- if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
- if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
- !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
- return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
- }
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS
+ | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
+ struct samr_domain_info, &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- if (!sid_check_is_domain(&info->sid) &&
- !sid_check_is_builtin(&info->sid))
+ if (!sid_check_is_domain(&dinfo->sid) &&
+ !sid_check_is_builtin(&dinfo->sid))
return NT_STATUS_OBJECT_TYPE_MISMATCH;
if (r->in.sids->num_sids) {
@@ -4367,13 +4307,13 @@ NTSTATUS _samr_GetAliasMembership(pipes_struct *p,
num_alias_rids = 0;
become_root();
- ntstatus1 = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
- r->in.sids->num_sids,
- &alias_rids, &num_alias_rids);
+ status = pdb_enum_alias_memberships(p->mem_ctx, &dinfo->sid, members,
+ r->in.sids->num_sids,
+ &alias_rids, &num_alias_rids);
unbecome_root();
- if (!NT_STATUS_IS_OK(ntstatus1)) {
- return ntstatus1;
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
r->out.rids->count = num_alias_rids;
@@ -4560,7 +4500,7 @@ NTSTATUS _samr_AddAliasMember(pipes_struct *p,
/******** END SeAddUsers BLOCK *********/
if (NT_STATUS_IS_OK(status)) {
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&alias_sid);
}
return status;
@@ -4610,7 +4550,7 @@ NTSTATUS _samr_DeleteAliasMember(pipes_struct *p,
/******** END SeAddUsers BLOCK *********/
if (NT_STATUS_IS_OK(status)) {
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&alias_sid);
}
return status;
@@ -4664,7 +4604,7 @@ NTSTATUS _samr_AddGroupMember(pipes_struct *p,
/******** END SeAddUsers BLOCK *********/
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&group_sid);
return status;
}
@@ -4722,7 +4662,7 @@ NTSTATUS _samr_DeleteGroupMember(pipes_struct *p,
/******** END SeAddUsers BLOCK *********/
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&group_sid);
return status;
}
@@ -4812,7 +4752,7 @@ NTSTATUS _samr_DeleteUser(pipes_struct *p,
ZERO_STRUCTP(r->out.user_handle);
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&user_sid);
return NT_STATUS_OK;
}
@@ -4878,7 +4818,7 @@ NTSTATUS _samr_DeleteDomainGroup(pipes_struct *p,
if (!close_policy_hnd(p, r->in.group_handle))
return NT_STATUS_OBJECT_NAME_INVALID;
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&group_sid);
return NT_STATUS_OK;
}
@@ -4949,7 +4889,7 @@ NTSTATUS _samr_DeleteDomAlias(pipes_struct *p,
if (!close_policy_hnd(p, r->in.alias_handle))
return NT_STATUS_OBJECT_NAME_INVALID;
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&alias_sid);
return NT_STATUS_OK;
}
@@ -4963,27 +4903,21 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
{
NTSTATUS status;
- DOM_SID dom_sid;
DOM_SID info_sid;
const char *name;
+ struct samr_domain_info *dinfo;
struct samr_info *info;
- uint32 acc_granted;
SE_PRIV se_rights;
bool can_add_accounts;
- DISP_INFO *disp_info = NULL;
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
- return NT_STATUS_INVALID_HANDLE;
- status = access_check_samr_function(acc_granted,
- SAMR_DOMAIN_ACCESS_CREATE_GROUP,
- "_samr_CreateDomainGroup");
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_CREATE_GROUP, NULL,
+ struct samr_domain_info, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- if (!sid_equal(&dom_sid, get_global_sam_sid()))
+ if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
return NT_STATUS_ACCESS_DENIED;
name = r->in.name->string;
@@ -5018,7 +4952,7 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
if ( !NT_STATUS_IS_OK(status) )
return status;
- sid_compose(&info_sid, get_global_sam_sid(), *r->out.rid);
+ sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
return NT_STATUS_NO_MEMORY;
@@ -5031,7 +4965,7 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
if (!create_policy_hnd(p, r->out.group_handle, info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&info_sid);
return NT_STATUS_OK;
}
@@ -5043,29 +4977,23 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
struct samr_CreateDomAlias *r)
{
- DOM_SID dom_sid;
DOM_SID info_sid;
const char *name = NULL;
+ struct samr_domain_info *dinfo;
struct samr_info *info;
- uint32 acc_granted;
gid_t gid;
NTSTATUS result;
SE_PRIV se_rights;
bool can_add_accounts;
- DISP_INFO *disp_info = NULL;
-
- /* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &dom_sid, &acc_granted, &disp_info))
- return NT_STATUS_INVALID_HANDLE;
- result = access_check_samr_function(acc_granted,
- SAMR_DOMAIN_ACCESS_CREATE_ALIAS,
- "_samr_CreateDomAlias");
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_CREATE_ALIAS, NULL,
+ struct samr_domain_info, &result);
if (!NT_STATUS_IS_OK(result)) {
return result;
}
- if (!sid_equal(&dom_sid, get_global_sam_sid()))
+ if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
return NT_STATUS_ACCESS_DENIED;
name = r->in.alias_name->string;
@@ -5097,8 +5025,7 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
return result;
}
- sid_copy(&info_sid, get_global_sam_sid());
- sid_append_rid(&info_sid, *r->out.rid);
+ sid_compose(&info_sid, &dinfo->sid, *r->out.rid);
if (!sid_to_gid(&info_sid, &gid)) {
DEBUG(10, ("Could not find alias just created\n"));
@@ -5123,7 +5050,7 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
if (!create_policy_hnd(p, r->out.alias_handle, info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&info_sid);
return NT_STATUS_OK;
}
@@ -5293,7 +5220,7 @@ NTSTATUS _samr_SetGroupInfo(pipes_struct *p,
/******** End SeAddUsers BLOCK *********/
if (NT_STATUS_IS_OK(status)) {
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&group_sid);
}
return status;
@@ -5395,7 +5322,7 @@ NTSTATUS _samr_SetAliasInfo(pipes_struct *p,
/******** End SeAddUsers BLOCK *********/
if (NT_STATUS_IS_OK(status))
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&group_sid);
return status;
}
@@ -5444,28 +5371,24 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
struct samr_OpenGroup *r)
{
- DOM_SID sid;
DOM_SID info_sid;
GROUP_MAP map;
+ struct samr_domain_info *dinfo;
struct samr_info *info;
SEC_DESC *psd = NULL;
uint32 acc_granted;
uint32 des_access = r->in.access_mask;
size_t sd_size;
NTSTATUS status;
- fstring sid_string;
bool ret;
SE_PRIV se_rights;
- if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &sid, &acc_granted, NULL))
- return NT_STATUS_INVALID_HANDLE;
-
- status = access_check_samr_function(acc_granted,
- SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
- "_samr_OpenGroup");
-
- if ( !NT_STATUS_IS_OK(status) )
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, NULL,
+ struct samr_domain_info, &status);
+ if (!NT_STATUS_IS_OK(status)) {
return status;
+ }
/*check if access can be granted as requested by client. */
map_max_allowed_access(p->server_info->ptok, &des_access);
@@ -5484,19 +5407,18 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
/* this should not be hard-coded like this */
- if (!sid_equal(&sid, get_global_sam_sid()))
+ if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
return NT_STATUS_ACCESS_DENIED;
- sid_copy(&info_sid, get_global_sam_sid());
- sid_append_rid(&info_sid, r->in.rid);
- sid_to_fstring(sid_string, &info_sid);
+ sid_compose(&info_sid, &dinfo->sid, r->in.rid);
if ((info = get_samr_info_by_sid(p->mem_ctx, &info_sid)) == NULL)
return NT_STATUS_NO_MEMORY;
info->acc_granted = acc_granted;
- DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n", sid_string));
+ DEBUG(10, ("_samr_OpenGroup:Opening SID: %s\n",
+ sid_string_dbg(&info_sid)));
/* check if that group really exists */
become_root();
@@ -5519,31 +5441,23 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
struct samr_RemoveMemberFromForeignDomain *r)
{
- DOM_SID delete_sid, domain_sid;
- uint32 acc_granted;
+ struct samr_domain_info *dinfo;
NTSTATUS result;
- DISP_INFO *disp_info = NULL;
-
- sid_copy( &delete_sid, r->in.sid );
DEBUG(5,("_samr_RemoveMemberFromForeignDomain: removing SID [%s]\n",
- sid_string_dbg(&delete_sid)));
+ sid_string_dbg(r->in.sid)));
/* Find the policy handle. Open a policy on it. */
- if (!get_lsa_policy_samr_sid(p, r->in.domain_handle, &domain_sid,
- &acc_granted, &disp_info))
- return NT_STATUS_INVALID_HANDLE;
-
- result = access_check_samr_function(acc_granted,
- STD_RIGHT_DELETE_ACCESS,
- "_samr_RemoveMemberFromForeignDomain");
-
- if (!NT_STATUS_IS_OK(result))
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ STD_RIGHT_DELETE_ACCESS, NULL,
+ struct samr_domain_info, &result);
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
DEBUG(8, ("_samr_RemoveMemberFromForeignDomain: sid is %s\n",
- sid_string_dbg(&domain_sid)));
+ sid_string_dbg(&dinfo->sid)));
/* we can only delete a user from a group since we don't have
nested groups anyways. So in the latter case, just say OK */
@@ -5559,16 +5473,16 @@ NTSTATUS _samr_RemoveMemberFromForeignDomain(pipes_struct *p,
* only application of this call. To verify this, let people report
* other cases. */
- if (!sid_check_is_builtin(&domain_sid)) {
+ if (!sid_check_is_builtin(&dinfo->sid)) {
DEBUG(1,("_samr_RemoveMemberFromForeignDomain: domain_sid = %s, "
"global_sam_sid() = %s\n",
- sid_string_dbg(&domain_sid),
+ sid_string_dbg(&dinfo->sid),
sid_string_dbg(get_global_sam_sid())));
DEBUGADD(1,("please report to samba-technical@samba.org!\n"));
return NT_STATUS_OK;
}
- force_flush_samr_cache(disp_info);
+ force_flush_samr_cache(&dinfo->sid);
result = NT_STATUS_OK;
@@ -5599,7 +5513,7 @@ NTSTATUS _samr_QueryDomainInfo2(pipes_struct *p,
NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
struct samr_SetDomainInfo *r)
{
- struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
time_t u_expire, u_min_age;
time_t u_logout;
time_t u_lock_duration, u_reset_time;
@@ -5607,10 +5521,6 @@ NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
DEBUG(5,("_samr_SetDomainInfo: %d\n", __LINE__));
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info))
- return NT_STATUS_INVALID_HANDLE;
-
/* We do have different access bits for info
* levels here, but we're really just looking for
* GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately
@@ -5618,12 +5528,12 @@ NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
* assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1
* set we are ok. */
- result = access_check_samr_function(info->acc_granted,
- SAMR_DOMAIN_ACCESS_SET_INFO_1,
- "_samr_SetDomainInfo");
-
- if (!NT_STATUS_IS_OK(result))
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_SET_INFO_1, NULL,
+ struct samr_domain_info, &result);
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
DEBUG(5,("_samr_SetDomainInfo: level: %d\n", r->in.level));
@@ -5676,7 +5586,7 @@ NTSTATUS _samr_SetDomainInfo(pipes_struct *p,
NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
struct samr_GetDisplayEnumerationIndex *r)
{
- struct samr_info *info = NULL;
+ struct samr_domain_info *dinfo;
uint32_t max_entries = (uint32_t) -1;
uint32_t enum_context = 0;
int i;
@@ -5686,14 +5596,9 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__));
- /* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) {
- return NT_STATUS_INVALID_HANDLE;
- }
-
- status = access_check_samr_function(info->acc_granted,
- SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS,
- "_samr_GetDisplayEnumerationIndex");
+ dinfo = policy_handle_find(p, r->in.domain_handle,
+ SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, NULL,
+ struct samr_domain_info, &status);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -5711,10 +5616,10 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
switch (r->in.level) {
case 1:
- if (info->disp_info->users == NULL) {
- info->disp_info->users = pdb_search_users(
- info->disp_info, ACB_NORMAL);
- if (info->disp_info->users == NULL) {
+ if (dinfo->disp_info->users == NULL) {
+ dinfo->disp_info->users = pdb_search_users(
+ dinfo->disp_info, ACB_NORMAL);
+ if (dinfo->disp_info->users == NULL) {
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
@@ -5726,15 +5631,15 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
"using cached user enumeration at index %u\n",
(unsigned int)enum_context));
}
- num_account = pdb_search_entries(info->disp_info->users,
+ num_account = pdb_search_entries(dinfo->disp_info->users,
enum_context, max_entries,
&entries);
break;
case 2:
- if (info->disp_info->machines == NULL) {
- info->disp_info->machines = pdb_search_users(
- info->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
- if (info->disp_info->machines == NULL) {
+ if (dinfo->disp_info->machines == NULL) {
+ dinfo->disp_info->machines = pdb_search_users(
+ dinfo->disp_info, ACB_WSTRUST|ACB_SVRTRUST);
+ if (dinfo->disp_info->machines == NULL) {
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
@@ -5746,15 +5651,15 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
"using cached machine enumeration at index %u\n",
(unsigned int)enum_context));
}
- num_account = pdb_search_entries(info->disp_info->machines,
+ num_account = pdb_search_entries(dinfo->disp_info->machines,
enum_context, max_entries,
&entries);
break;
case 3:
- if (info->disp_info->groups == NULL) {
- info->disp_info->groups = pdb_search_groups(
- info->disp_info);
- if (info->disp_info->groups == NULL) {
+ if (dinfo->disp_info->groups == NULL) {
+ dinfo->disp_info->groups = pdb_search_groups(
+ dinfo->disp_info);
+ if (dinfo->disp_info->groups == NULL) {
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
@@ -5766,7 +5671,7 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
"using cached group enumeration at index %u\n",
(unsigned int)enum_context));
}
- num_account = pdb_search_entries(info->disp_info->groups,
+ num_account = pdb_search_entries(dinfo->disp_info->groups,
enum_context, max_entries,
&entries);
break;
@@ -5779,7 +5684,7 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p,
unbecome_root();
/* Ensure we cache this enumeration. */
- set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+ set_disp_info_cache_timeout(dinfo->disp_info, DISP_INFO_CACHE_TIMEOUT);
DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n",
r->in.name->string));
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index d114152f64..629e41c003 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -591,7 +591,8 @@ static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
new_printer->access_granted = access_granted;
- DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
+ DEBUG(5, ("%d printer handles active\n",
+ (int)num_pipe_handles(p->pipe_handles)));
return true;
}
@@ -4846,6 +4847,121 @@ static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
}
/********************************************************************
+ * fill a spoolss_DriverInfo4 struct
+ ********************************************************************/
+
+static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo4 *r,
+ const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+ const char *servername)
+{
+ const char *cservername = canon_servername(servername);
+
+ r->version = driver->info_3->cversion;
+
+ r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name);
+ W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+ r->architecture = talloc_strdup(mem_ctx, driver->info_3->environment);
+ W_ERROR_HAVE_NO_MEMORY(r->architecture);
+
+ if (strlen(driver->info_3->driverpath)) {
+ r->driver_path = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->driverpath);
+ } else {
+ r->driver_path = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->driver_path);
+
+ if (strlen(driver->info_3->datafile)) {
+ r->data_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->datafile);
+ } else {
+ r->data_file = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->data_file);
+
+ if (strlen(driver->info_3->configfile)) {
+ r->config_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->configfile);
+ } else {
+ r->config_file = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->config_file);
+
+ if (strlen(driver->info_3->helpfile)) {
+ r->help_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->helpfile);
+ } else {
+ r->help_file = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->help_file);
+
+ r->dependent_files = string_array_from_driver_info(mem_ctx,
+ driver->info_3->dependentfiles,
+ cservername);
+
+
+ r->monitor_name = talloc_strdup(mem_ctx, driver->info_3->monitorname);
+ W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
+ r->default_datatype = talloc_strdup(mem_ctx, driver->info_3->defaultdatatype);
+ W_ERROR_HAVE_NO_MEMORY(r->default_datatype);
+
+ r->previous_names = string_array_from_driver_info(mem_ctx,
+ NULL,
+ cservername);
+
+ return WERR_OK;
+}
+
+/********************************************************************
+ * fill a spoolss_DriverInfo5 struct
+ ********************************************************************/
+
+static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo5 *r,
+ const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+ const char *servername)
+{
+ const char *cservername = canon_servername(servername);
+
+ r->version = driver->info_3->cversion;
+
+ r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name);
+ W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+ r->architecture = talloc_strdup(mem_ctx, driver->info_3->environment);
+ W_ERROR_HAVE_NO_MEMORY(r->architecture);
+
+ if (strlen(driver->info_3->driverpath)) {
+ r->driver_path = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->driverpath);
+ } else {
+ r->driver_path = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->driver_path);
+
+ if (strlen(driver->info_3->datafile)) {
+ r->data_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->datafile);
+ } else {
+ r->data_file = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->data_file);
+
+ if (strlen(driver->info_3->configfile)) {
+ r->config_file = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, driver->info_3->configfile);
+ } else {
+ r->config_file = talloc_strdup(mem_ctx, "");
+ }
+ W_ERROR_HAVE_NO_MEMORY(r->config_file);
+
+ r->driver_attributes = 0;
+ r->config_version = 0;
+ r->driver_version = 0;
+
+ return WERR_OK;
+}
+/********************************************************************
* fill a spoolss_DriverInfo6 struct
********************************************************************/
@@ -4893,7 +5009,7 @@ static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
} else {
r->help_file = talloc_strdup(mem_ctx, "");
}
- W_ERROR_HAVE_NO_MEMORY(r->config_file);
+ W_ERROR_HAVE_NO_MEMORY(r->help_file);
r->monitor_name = talloc_strdup(mem_ctx, driver->info_3->monitorname);
W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
@@ -6673,6 +6789,18 @@ static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
result = fill_printer_driver_info3(info, &info[count+i].info3,
&driver, servername);
break;
+ case 4:
+ result = fill_printer_driver_info4(info, &info[count+i].info4,
+ &driver, servername);
+ break;
+ case 5:
+ result = fill_printer_driver_info5(info, &info[count+i].info5,
+ &driver, servername);
+ break;
+ case 6:
+ result = fill_printer_driver_info6(info, &info[count+i].info6,
+ &driver, servername);
+ break;
default:
result = WERR_UNKNOWN_LEVEL;
break;
@@ -6745,6 +6873,49 @@ static WERROR enumprinterdrivers_level3(TALLOC_CTX *mem_ctx,
info_p, count);
}
+/****************************************************************************
+ Enumerates all printer drivers at level 4.
+****************************************************************************/
+
+static WERROR enumprinterdrivers_level4(TALLOC_CTX *mem_ctx,
+ const char *servername,
+ const char *architecture,
+ union spoolss_DriverInfo **info_p,
+ uint32_t *count)
+{
+ return enumprinterdrivers_level(mem_ctx, servername, architecture, 4,
+ info_p, count);
+}
+
+/****************************************************************************
+ Enumerates all printer drivers at level 5.
+****************************************************************************/
+
+static WERROR enumprinterdrivers_level5(TALLOC_CTX *mem_ctx,
+ const char *servername,
+ const char *architecture,
+ union spoolss_DriverInfo **info_p,
+ uint32_t *count)
+{
+ return enumprinterdrivers_level(mem_ctx, servername, architecture, 5,
+ info_p, count);
+}
+
+/****************************************************************************
+ Enumerates all printer drivers at level 6.
+****************************************************************************/
+
+static WERROR enumprinterdrivers_level6(TALLOC_CTX *mem_ctx,
+ const char *servername,
+ const char *architecture,
+ union spoolss_DriverInfo **info_p,
+ uint32_t *count)
+{
+ return enumprinterdrivers_level(mem_ctx, servername, architecture, 6,
+ info_p, count);
+}
+
+
/****************************************************************
_spoolss_EnumPrinterDrivers
****************************************************************/
@@ -6789,6 +6960,21 @@ WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
r->in.environment,
r->out.info, r->out.count);
break;
+ case 4:
+ result = enumprinterdrivers_level4(p->mem_ctx, cservername,
+ r->in.environment,
+ r->out.info, r->out.count);
+ break;
+ case 5:
+ result = enumprinterdrivers_level5(p->mem_ctx, cservername,
+ r->in.environment,
+ r->out.info, r->out.count);
+ break;
+ case 6:
+ result = enumprinterdrivers_level6(p->mem_ctx, cservername,
+ r->in.environment,
+ r->out.info, r->out.count);
+ break;
default:
return WERR_UNKNOWN_LEVEL;
}
@@ -8111,7 +8297,7 @@ WERROR _spoolss_AddForm(pipes_struct *p,
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ((p->server_info->utok.uid != 0) &&
+ if ((p->server_info->utok.uid != sec_initial_uid()) &&
!user_has_privileges(p->server_info->ptok, &se_printop) &&
!token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
NULL, NULL,
@@ -8135,7 +8321,9 @@ WERROR _spoolss_AddForm(pipes_struct *p,
goto done;
}
+ become_root();
write_ntforms(&list, count);
+ unbecome_root();
/*
* ChangeID must always be set if this is a printer
@@ -8168,6 +8356,7 @@ WERROR _spoolss_DeleteForm(pipes_struct *p,
WERROR status = WERR_OK;
NT_PRINTER_INFO_LEVEL *printer = NULL;
SE_PRIV se_printop = SE_PRINT_OPERATOR;
+ bool ret = false;
DEBUG(5,("_spoolss_DeleteForm\n"));
@@ -8189,7 +8378,7 @@ WERROR _spoolss_DeleteForm(pipes_struct *p,
goto done;
}
- if ((p->server_info->utok.uid != 0) &&
+ if ((p->server_info->utok.uid != sec_initial_uid()) &&
!user_has_privileges(p->server_info->ptok, &se_printop) &&
!token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
NULL, NULL,
@@ -8209,8 +8398,12 @@ WERROR _spoolss_DeleteForm(pipes_struct *p,
count = get_ntforms(&list);
- if ( !delete_a_form(&list, form_name, &count, &status ))
+ become_root();
+ ret = delete_a_form(&list, form_name, &count, &status);
+ unbecome_root();
+ if (ret == false) {
goto done;
+ }
/*
* ChangeID must always be set if this is a printer
@@ -8268,7 +8461,7 @@ WERROR _spoolss_SetForm(pipes_struct *p,
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
and not a printer admin, then fail */
- if ((p->server_info->utok.uid != 0) &&
+ if ((p->server_info->utok.uid != sec_initial_uid()) &&
!user_has_privileges(p->server_info->ptok, &se_printop) &&
!token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
NULL, NULL,
@@ -8286,7 +8479,9 @@ WERROR _spoolss_SetForm(pipes_struct *p,
count = get_ntforms(&list);
update_a_form(&list, form, count);
+ become_root();
write_ntforms(&list, count);
+ unbecome_root();
/*
* ChangeID must always be set if this is a printer
diff --git a/source3/script/installmo.sh b/source3/script/installmo.sh
index 5ca3371d80..5ca3371d80 100644..100755
--- a/source3/script/installmo.sh
+++ b/source3/script/installmo.sh
diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh
index b3a66e1db7..40421fd85d 100755
--- a/source3/script/tests/test_posix_s3.sh
+++ b/source3/script/tests/test_posix_s3.sh
@@ -40,7 +40,8 @@ raw="$raw RAW-SAMBA3ROOTDIRFID"
rpc="RPC-AUTHCONTEXT RPC-BINDSAMBA3 RPC-SAMBA3-SRVSVC RPC-SAMBA3-SHARESEC"
rpc="$rpc RPC-SAMBA3-SPOOLSS RPC-SAMBA3-WKSSVC"
rpc="$rpc RPC-NETLOGSAMBA3 RPC-SAMBA3SESSIONKEY RPC-SAMBA3-GETUSERNAME"
-rpc="$rpc RPC-SVCCTL RPC-SPOOLSS-WIN RPC-NTSVCS"
+rpc="$rpc RPC-SVCCTL RPC-SPOOLSS RPC-SPOOLSS-WIN RPC-NTSVCS RPC-LSA-LOOKUPSIDS"
+rpc="$rpc RPC-SAMR-PASSWORDS-PWDLASTSET RPC-JOIN"
# 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
diff --git a/source3/script/uninstallmo.sh b/source3/script/uninstallmo.sh
index 5b4475f5c2..663c6b1296 100644..100755
--- a/source3/script/uninstallmo.sh
+++ b/source3/script/uninstallmo.sh
@@ -1 +1,2 @@
-installmo.sh
+#!/bin/sh
+script/installmo.sh
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index a52f2d2e96..3800643769 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -212,7 +212,7 @@ bool conn_idle_all(time_t t)
for (plist = get_first_internal_pipe(); plist;
plist = get_next_internal_pipe(plist)) {
- if (plist->pipe_handles && plist->pipe_handles->count) {
+ if (num_pipe_handles(plist->pipe_handles) != 0) {
return False;
}
}
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 80722a7cd0..e35f23ef37 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -33,6 +33,9 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
const char *streamname,
SMB_STRUCT_STAT *pst,
char **path);
+static int get_real_filename_mangled(connection_struct *conn, const char *path,
+ const char *name, TALLOC_CTX *mem_ctx,
+ char **found_name);
/****************************************************************************
Mangle the 2nd name and check if it is then equal to the first name.
@@ -447,7 +450,7 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
*/
if (name_has_wildcard ||
- (SMB_VFS_GET_REAL_FILENAME(
+ (get_real_filename_mangled(
conn, dirpath, start,
talloc_tos(), &found_name) == -1)) {
char *unmangled;
@@ -789,15 +792,12 @@ static bool fname_equal(const char *name1, const char *name2,
If the name looks like a mangled name then try via the mangling functions
****************************************************************************/
-int get_real_filename(connection_struct *conn, const char *path,
- const char *name, TALLOC_CTX *mem_ctx,
- char **found_name)
+static int get_real_filename_mangled(connection_struct *conn, const char *path,
+ const char *name, TALLOC_CTX *mem_ctx,
+ char **found_name)
{
- struct smb_Dir *cur_dir;
- const char *dname;
bool mangled;
char *unmangled_name = NULL;
- long curpos;
mangled = mangle_is_mangled(name, conn->params);
@@ -838,8 +838,24 @@ int get_real_filename(connection_struct *conn, const char *path,
/* Name is now unmangled. */
name = unmangled_name;
}
+ return get_real_filename(conn, path, name, mem_ctx,
+ found_name);
}
+ return SMB_VFS_GET_REAL_FILENAME(conn, path, name, mem_ctx,
+ found_name);
+}
+
+int get_real_filename(connection_struct *conn, const char *path,
+ const char *name, TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ struct smb_Dir *cur_dir;
+ const char *dname;
+ bool mangled;
+ char *unmangled_name = NULL;
+ long curpos;
+
/* open the directory */
if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) {
DEBUG(3,("scan dir didn't open dir [%s]\n",path));
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 36e80a086a..d2ea520146 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -433,6 +433,10 @@ void file_free(struct smb_request *req, files_struct *fsp)
}
if (fsp->notify) {
+ if (fsp->is_directory) {
+ notify_remove_onelevel(fsp->conn->notify_ctx,
+ &fsp->file_id, fsp);
+ }
notify_remove(fsp->conn->notify_ctx, fsp);
TALLOC_FREE(fsp->notify);
}
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 6f8f8ed5e4..979e5b57a4 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -2073,7 +2073,7 @@ static bool api_RNetGroupEnum(connection_struct *conn,uint16 vuid,
}
status = rpccli_samr_Connect2(samr_pipe, talloc_tos(), global_myname(),
- SAMR_ACCESS_OPEN_DOMAIN, &samr_handle);
+ SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
nt_errstr(status)));
@@ -2254,7 +2254,7 @@ static bool api_NetUserGetGroups(connection_struct *conn,uint16 vuid,
}
status = rpccli_samr_Connect2(samr_pipe, talloc_tos(), global_myname(),
- SAMR_ACCESS_OPEN_DOMAIN, &samr_handle);
+ SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
nt_errstr(status)));
@@ -2409,7 +2409,7 @@ static bool api_RNetUserEnum(connection_struct *conn, uint16 vuid,
}
status = rpccli_samr_Connect2(samr_pipe, talloc_tos(), global_myname(),
- SAMR_ACCESS_OPEN_DOMAIN, &samr_handle);
+ SAMR_ACCESS_LOOKUP_DOMAIN, &samr_handle);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("api_RNetUserEnum: samr_Connect2 failed: %s\n",
nt_errstr(status)));
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index d141fb2180..12a75cc9f6 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -339,6 +339,9 @@ void notify_fname(connection_struct *conn, uint32 action, uint32 filter,
const char *path)
{
char *fullpath;
+ char *parent;
+ const char *name;
+ SMB_STRUCT_STAT sbuf;
if (path[0] == '.' && path[1] == '/') {
path += 2;
@@ -348,6 +351,13 @@ void notify_fname(connection_struct *conn, uint32 action, uint32 filter,
return;
}
+ if (parent_dirname(talloc_tos(), path, &parent, &name)
+ && (SMB_VFS_STAT(conn, parent, &sbuf) != -1)) {
+ notify_onelevel(conn->notify_ctx, action, filter,
+ SMB_VFS_FILE_ID_CREATE(conn, &sbuf),
+ name);
+ }
+
notify_trigger(conn->notify_ctx, action, filter, fullpath);
SAFE_FREE(fullpath);
}
diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c
index 1e45c54cbb..a42404db3e 100644
--- a/source3/smbd/notify_internal.c
+++ b/source3/smbd/notify_internal.c
@@ -27,7 +27,8 @@
#include "librpc/gen_ndr/ndr_notify.h"
struct notify_context {
- struct db_context *db;
+ struct db_context *db_recursive;
+ struct db_context *db_onelevel;
struct server_id server;
struct messaging_context *messaging_ctx;
struct notify_list *list;
@@ -91,10 +92,18 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server,
return NULL;
}
- notify->db = db_open(notify, lock_path("notify.tdb"),
- 0, TDB_SEQNUM|TDB_CLEAR_IF_FIRST,
- O_RDWR|O_CREAT, 0644);
- if (notify->db == NULL) {
+ notify->db_recursive = db_open(notify, lock_path("notify.tdb"),
+ 0, TDB_SEQNUM|TDB_CLEAR_IF_FIRST,
+ O_RDWR|O_CREAT, 0644);
+ if (notify->db_recursive == NULL) {
+ talloc_free(notify);
+ return NULL;
+ }
+
+ notify->db_onelevel = db_open(notify, lock_path("notify_onelevel.tdb"),
+ 0, TDB_SEQNUM|TDB_CLEAR_IF_FIRST,
+ O_RDWR|O_CREAT, 0644);
+ if (notify->db_onelevel == NULL) {
talloc_free(notify);
return NULL;
}
@@ -103,7 +112,8 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server,
notify->messaging_ctx = messaging_ctx;
notify->list = NULL;
notify->array = NULL;
- notify->seqnum = notify->db->get_seqnum(notify->db);
+ notify->seqnum = notify->db_recursive->get_seqnum(
+ notify->db_recursive);
notify->key = string_term_tdb_data(NOTIFY_KEY);
talloc_set_destructor(notify, notify_destructor);
@@ -123,7 +133,8 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server,
*/
static NTSTATUS notify_fetch_locked(struct notify_context *notify, struct db_record **rec)
{
- *rec = notify->db->fetch_locked(notify->db, notify, notify->key);
+ *rec = notify->db_recursive->fetch_locked(notify->db_recursive,
+ notify, notify->key);
if (*rec == NULL) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -140,7 +151,7 @@ static NTSTATUS notify_load(struct notify_context *notify, struct db_record *rec
NTSTATUS status;
int seqnum;
- seqnum = notify->db->get_seqnum(notify->db);
+ seqnum = notify->db_recursive->get_seqnum(notify->db_recursive);
if (seqnum == notify->seqnum && notify->array != NULL) {
return NT_STATUS_OK;
@@ -153,7 +164,8 @@ static NTSTATUS notify_load(struct notify_context *notify, struct db_record *rec
NT_STATUS_HAVE_NO_MEMORY(notify->array);
if (!rec) {
- if (notify->db->fetch(notify->db, notify, notify->key, &dbuf) != 0) {
+ if (notify->db_recursive->fetch(notify->db_recursive, notify,
+ notify->key, &dbuf) != 0) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
} else {
@@ -344,6 +356,96 @@ static NTSTATUS notify_add_array(struct notify_context *notify, struct db_record
}
/*
+ Add a non-recursive watch
+*/
+
+static void notify_add_onelevel(struct notify_context *notify,
+ struct notify_entry *e, void *private_data)
+{
+ struct notify_entry_array *array;
+ struct db_record *rec;
+ DATA_BLOB blob;
+ TDB_DATA dbuf;
+ enum ndr_err_code ndr_err;
+ NTSTATUS status;
+
+ array = talloc_zero(talloc_tos(), struct notify_entry_array);
+ if (array == NULL) {
+ return;
+ }
+
+ rec = notify->db_onelevel->fetch_locked(
+ notify->db_onelevel, talloc_tos(),
+ make_tdb_data((uint8_t *)&e->dir_id, sizeof(e->dir_id)));
+ if (rec == NULL) {
+ DEBUG(10, ("notify_add_onelevel: fetch_locked for %s failed"
+ "\n", file_id_string_tos(&e->dir_id)));
+ TALLOC_FREE(array);
+ return;
+ }
+
+ blob.data = (uint8_t *)rec->value.dptr;
+ blob.length = rec->value.dsize;
+
+ if (blob.length > 0) {
+ ndr_err = ndr_pull_struct_blob(
+ &blob, array, NULL, array,
+ (ndr_pull_flags_fn_t)ndr_pull_notify_entry_array);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(10, ("ndr_pull_notify_entry_array failed: %s\n",
+ ndr_errstr(ndr_err)));
+ TALLOC_FREE(array);
+ return;
+ }
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10, ("notify_add_onelevel:\n"));
+ NDR_PRINT_DEBUG(notify_entry_array, array);
+ }
+ }
+
+ array->entries = talloc_realloc(array, array->entries,
+ struct notify_entry,
+ array->num_entries+1);
+ if (array->entries == NULL) {
+ TALLOC_FREE(array);
+ return;
+ }
+ array->entries[array->num_entries] = *e;
+ array->entries[array->num_entries].private_data = private_data;
+ array->entries[array->num_entries].server = notify->server;
+ array->num_entries += 1;
+
+ ndr_err = ndr_push_struct_blob(
+ &blob, rec, NULL, array,
+ (ndr_push_flags_fn_t)ndr_push_notify_entry_array);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(10, ("ndr_push_notify_entry_array failed: %s\n",
+ ndr_errstr(ndr_err)));
+ TALLOC_FREE(array);
+ return;
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10, ("notify_add_onelevel:\n"));
+ NDR_PRINT_DEBUG(notify_entry_array, array);
+ }
+
+ dbuf.dptr = blob.data;
+ dbuf.dsize = blob.length;
+
+ status = rec->store(rec, dbuf, TDB_REPLACE);
+ TALLOC_FREE(array);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("notify_add_onelevel: store failed: %s\n",
+ nt_errstr(status)));
+ return;
+ }
+ e->filter = 0;
+ return;
+}
+
+
+/*
add a notify watch. This is called when a notify is first setup on a open
directory handle.
*/
@@ -411,6 +513,11 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0,
}
}
+ if (e.filter != 0) {
+ notify_add_onelevel(notify, &e, private_data);
+ status = NT_STATUS_OK;
+ }
+
/* if the system notify handler couldn't handle some of the
filter bits, or couldn't handle a request for recursion
then we need to install it in the array used for the
@@ -426,6 +533,102 @@ done:
return status;
}
+NTSTATUS notify_remove_onelevel(struct notify_context *notify,
+ const struct file_id *fid,
+ void *private_data)
+{
+ struct notify_entry_array *array;
+ struct db_record *rec;
+ DATA_BLOB blob;
+ TDB_DATA dbuf;
+ enum ndr_err_code ndr_err;
+ NTSTATUS status;
+ int i;
+
+ array = talloc_zero(talloc_tos(), struct notify_entry_array);
+ if (array == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ rec = notify->db_onelevel->fetch_locked(
+ notify->db_onelevel, talloc_tos(),
+ make_tdb_data((uint8_t *)fid, sizeof(*fid)));
+ if (rec == NULL) {
+ DEBUG(10, ("notify_remove_onelevel: fetch_locked for %s failed"
+ "\n", file_id_string_tos(fid)));
+ TALLOC_FREE(array);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ blob.data = (uint8_t *)rec->value.dptr;
+ blob.length = rec->value.dsize;
+
+ if (blob.length > 0) {
+ ndr_err = ndr_pull_struct_blob(
+ &blob, array, NULL, array,
+ (ndr_pull_flags_fn_t)ndr_pull_notify_entry_array);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(10, ("ndr_pull_notify_entry_array failed: %s\n",
+ ndr_errstr(ndr_err)));
+ TALLOC_FREE(array);
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10, ("notify_remove_onelevel:\n"));
+ NDR_PRINT_DEBUG(notify_entry_array, array);
+ }
+ }
+
+ for (i=0; i<array->num_entries; i++) {
+ if ((private_data == array->entries[i].private_data) &&
+ cluster_id_equal(&notify->server,
+ &array->entries[i].server)) {
+ break;
+ }
+ }
+
+ if (i == array->num_entries) {
+ TALLOC_FREE(array);
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ array->entries[i] = array->entries[array->num_entries-1];
+ array->num_entries -= 1;
+
+ if (array->num_entries == 0) {
+ rec->delete_rec(rec);
+ TALLOC_FREE(array);
+ return NT_STATUS_OK;
+ }
+
+ ndr_err = ndr_push_struct_blob(
+ &blob, rec, NULL, array,
+ (ndr_push_flags_fn_t)ndr_push_notify_entry_array);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(10, ("ndr_push_notify_entry_array failed: %s\n",
+ ndr_errstr(ndr_err)));
+ TALLOC_FREE(array);
+ return ndr_map_error2ntstatus(ndr_err);
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10, ("notify_add_onelevel:\n"));
+ NDR_PRINT_DEBUG(notify_entry_array, array);
+ }
+
+ dbuf.dptr = blob.data;
+ dbuf.dsize = blob.length;
+
+ status = rec->store(rec, dbuf, TDB_REPLACE);
+ TALLOC_FREE(array);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("notify_add_onelevel: store failed: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
/*
remove a notify watch. Called when the directory handle is closed
*/
@@ -574,6 +777,92 @@ static NTSTATUS notify_send(struct notify_context *notify, struct notify_entry *
return status;
}
+void notify_onelevel(struct notify_context *notify, uint32_t action,
+ uint32_t filter, struct file_id fid, const char *name)
+{
+ struct notify_entry_array *array;
+ TDB_DATA dbuf;
+ DATA_BLOB blob;
+ bool have_dead_entries = false;
+ int i;
+
+ array = talloc_zero(talloc_tos(), struct notify_entry_array);
+ if (array == NULL) {
+ return;
+ }
+
+ if (notify->db_onelevel->fetch(
+ notify->db_onelevel, array,
+ make_tdb_data((uint8_t *)&fid, sizeof(fid)),
+ &dbuf) == -1) {
+ TALLOC_FREE(array);
+ return;
+ }
+
+ blob.data = (uint8 *)dbuf.dptr;
+ blob.length = dbuf.dsize;
+
+ if (blob.length > 0) {
+ enum ndr_err_code ndr_err;
+ ndr_err = ndr_pull_struct_blob(
+ &blob, array, NULL, array,
+ (ndr_pull_flags_fn_t)ndr_pull_notify_entry_array);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(10, ("ndr_pull_notify_entry_array failed: %s\n",
+ ndr_errstr(ndr_err)));
+ TALLOC_FREE(array);
+ return;
+ }
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10, ("notify_onelevel:\n"));
+ NDR_PRINT_DEBUG(notify_entry_array, array);
+ }
+ }
+
+ for (i=0; i<array->num_entries; i++) {
+ struct notify_entry *e = &array->entries[i];
+
+ if ((e->filter & filter) != 0) {
+ NTSTATUS status;
+
+ status = notify_send(notify, e, name, action);
+ if (NT_STATUS_EQUAL(
+ status, NT_STATUS_INVALID_HANDLE)) {
+ /*
+ * Mark the entry as dead. All entries have a
+ * path set. The marker used here is setting
+ * that to NULL.
+ */
+ e->path = NULL;
+ have_dead_entries = true;
+ }
+ }
+ }
+
+ if (!have_dead_entries) {
+ TALLOC_FREE(array);
+ return;
+ }
+
+ for (i=0; i<array->num_entries; i++) {
+ struct notify_entry *e = &array->entries[i];
+ if (e->path != NULL) {
+ continue;
+ }
+ DEBUG(10, ("Deleting notify entries for process %s because "
+ "it's gone\n", procid_str_static(&e->server)));
+ /*
+ * Potential TODO: This might need optimizing,
+ * notify_remove_onelevel() does a fetch_locked() operation at
+ * every call. But this would only matter if a process with
+ * MANY notifies has died without shutting down properly.
+ */
+ notify_remove_onelevel(notify, &e->dir_id, e->private_data);
+ }
+
+ TALLOC_FREE(array);
+ return;
+}
/*
trigger a notify message for anyone waiting on a matching event
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index f8c55b1b8f..b8ed321a45 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -164,6 +164,10 @@ void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid)
if (ent->vuid == vuid) {
ent->vuid = UID_FIELD_INVALID;
+ /* Ensure we're not freeing an active pointer. */
+ if (conn->server_info == ent->server_info) {
+ conn->server_info = NULL;
+ }
TALLOC_FREE(ent->server_info);
ent->read_only = False;
ent->admin_user = False;
@@ -216,6 +220,13 @@ bool change_to_user(connection_struct *conn, uint16 vuid)
server_info = vuser ? vuser->server_info : conn->server_info;
+ if (!server_info) {
+ /* Invalid vuid sent - even with security = share. */
+ DEBUG(2,("change_to_user: Invalid vuid %d used on "
+ "share %s.\n",vuid, lp_servicename(snum) ));
+ return false;
+ }
+
if (!check_user_ok(conn, vuid, server_info, snum)) {
DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) "
"not permitted access to share %s.\n",
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 804e772516..07945fccf1 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -5105,6 +5105,59 @@ static bool run_chain1(int dummy)
return True;
}
+static bool run_mangle1(int dummy)
+{
+ struct cli_state *cli;
+ const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
+ int fnum;
+ fstring alt_name;
+ NTSTATUS status;
+ time_t change, access, write;
+ SMB_OFF_T size;
+ uint16_t mode;
+
+ printf("starting chain1 test\n");
+ if (!torture_open_connection(&cli, 0)) {
+ return False;
+ }
+
+ cli_sockopt(cli, sockops);
+
+ fnum = cli_nt_create_full(
+ cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
+ FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
+ if (fnum == -1) {
+ d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
+ return false;
+ }
+ cli_close(cli, fnum);
+
+ status = cli_qpathinfo_alt_name(cli, fname, alt_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("cli_qpathinfo_alt_name failed: %s\n",
+ nt_errstr(status));
+ return false;
+ }
+ d_printf("alt_name: %s\n", alt_name);
+
+ fnum = cli_open(cli, alt_name, O_RDONLY, DENY_NONE);
+ if (fnum == -1) {
+ d_printf("cli_open(%s) failed: %s\n", alt_name,
+ cli_errstr(cli));
+ return false;
+ }
+ cli_close(cli, fnum);
+
+ if (!cli_qpathinfo(cli, alt_name, &change, &access, &write, &size,
+ &mode)) {
+ d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
+ cli_errstr(cli));
+ return false;
+ }
+
+ return true;
+}
+
static size_t null_source(uint8_t *buf, size_t n, void *priv)
{
size_t *to_pull = (size_t *)priv;
@@ -5199,6 +5252,50 @@ static bool run_cli_echo(int dummy)
return NT_STATUS_IS_OK(status);
}
+static bool run_uid_regression_test(int dummy)
+{
+ static struct cli_state *cli;
+ int16_t old_vuid;
+ bool correct = True;
+
+ printf("starting uid regression test\n");
+
+ if (!torture_open_connection(&cli, 0)) {
+ return False;
+ }
+
+ cli_sockopt(cli, sockops);
+
+ /* Ok - now save then logoff our current user. */
+ old_vuid = cli->vuid;
+
+ if (!cli_ulogoff(cli)) {
+ d_printf("(%s) cli_ulogoff failed: %s\n",
+ __location__, cli_errstr(cli));
+ correct = false;
+ goto out;
+ }
+
+ cli->vuid = old_vuid;
+
+ /* Try an operation. */
+ if (!cli_mkdir(cli, "\\uid_reg_test")) {
+ /* We expect bad uid. */
+ if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
+ NT_STATUS_NO_SUCH_USER)) {
+ return False;
+ }
+ goto out;
+ }
+
+ cli_rmdir(cli, "\\uid_reg_test");
+
+ out:
+
+ torture_close_connection(cli);
+ return correct;
+}
+
static bool run_local_substitute(int dummy)
{
bool ok = true;
@@ -5778,6 +5875,7 @@ static struct {
{"RW3", run_readwritelarge, 0},
{"OPEN", run_opentest, 0},
{"POSIX", run_simple_posix_open_test, 0},
+ { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
#if 1
{"OPENATTR", run_openattrtest, 0},
#endif
@@ -5786,6 +5884,7 @@ static struct {
{"DELETE", run_deletetest, 0},
{"PROPERTIES", run_properties, 0},
{"MANGLE", torture_mangle, 0},
+ {"MANGLE1", run_mangle1, 0},
{"W2K", run_w2ktest, 0},
{"TRANS2SCAN", torture_trans2_scan, 0},
{"NTTRANSSCAN", torture_nttrans_scan, 0},
diff --git a/source3/utils/net.c b/source3/utils/net.c
index 7823a98219..bd5107af53 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -651,6 +651,7 @@ static struct functable net_func[] = {
{"force", 'f', POPT_ARG_NONE, &c->opt_force},
{"stdin", 'i', POPT_ARG_NONE, &c->opt_stdin},
{"timeout", 't', POPT_ARG_INT, &c->opt_timeout},
+ {"request-timeout",0,POPT_ARG_INT, &c->opt_request_timeout},
{"machine-pass",'P', POPT_ARG_NONE, &c->opt_machine_pass},
{"kerberos", 'k', POPT_ARG_NONE, &c->opt_kerberos},
{"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
diff --git a/source3/utils/net.h b/source3/utils/net.h
index 2d72756def..d88f962d41 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -43,6 +43,7 @@ struct net_context {
const char *opt_container;
int opt_flags;
int opt_timeout;
+ int opt_request_timeout;
const char *opt_target_workgroup;
int opt_machine_pass;
int opt_localgroup;
diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c
index 3fa547baf4..663c5925c7 100644
--- a/source3/utils/net_conf.c
+++ b/source3/utils/net_conf.c
@@ -340,6 +340,14 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx,
if (!W_ERROR_IS_OK(werr)) {
goto cancel;
}
+
+ werr = smbconf_transaction_start(conf_ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ d_printf("error starting transaction: %s\n",
+ win_errstr(werr));
+ goto done;
+ }
+
werr = import_process_service(c, conf_ctx, service);
if (!W_ERROR_IS_OK(werr)) {
goto cancel;
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 2651a8d034..5dd3df9a69 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -121,6 +121,7 @@ int run_rpc_command(struct net_context *c,
NTSTATUS nt_status;
DOM_SID *domain_sid;
const char *domain_name;
+ int ret = -1;
/* make use of cli_state handed over as an argument, if possible */
if (!cli_arg) {
@@ -142,15 +143,13 @@ int run_rpc_command(struct net_context *c,
if (!(mem_ctx = talloc_init("run_rpc_command"))) {
DEBUG(0, ("talloc_init() failed\n"));
- cli_shutdown(cli);
- return -1;
+ goto fail;
}
nt_status = net_get_remote_domain_sid(cli, mem_ctx, &domain_sid,
&domain_name);
if (!NT_STATUS_IS_OK(nt_status)) {
- cli_shutdown(cli);
- return -1;
+ goto fail;
}
if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
@@ -165,8 +164,7 @@ int run_rpc_command(struct net_context *c,
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
nt_errstr(nt_status) ));
- cli_shutdown(cli);
- return -1;
+ goto fail;
}
} else {
if (conn_flags & NET_FLAGS_SEAL) {
@@ -184,8 +182,7 @@ int run_rpc_command(struct net_context *c,
DEBUG(0, ("Could not initialise pipe %s. Error was %s\n",
get_pipe_name_from_iface(interface),
nt_errstr(nt_status) ));
- cli_shutdown(cli);
- return -1;
+ goto fail;
}
}
}
@@ -195,6 +192,7 @@ int run_rpc_command(struct net_context *c,
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
} else {
+ ret = 0;
DEBUG(5, ("rpc command function succedded\n"));
}
@@ -204,13 +202,14 @@ int run_rpc_command(struct net_context *c,
}
}
+fail:
/* close the connection only if it was opened here */
if (!cli_arg) {
cli_shutdown(cli);
}
talloc_destroy(mem_ctx);
- return (!NT_STATUS_IS_OK(nt_status));
+ return ret;
}
/**
@@ -6105,7 +6104,7 @@ static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
/* SamrConnect2 */
nt_status = rpccli_samr_Connect2(pipe_hnd, mem_ctx,
pipe_hnd->desthost,
- SAMR_ACCESS_OPEN_DOMAIN,
+ SAMR_ACCESS_LOOKUP_DOMAIN,
&connect_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n",
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index 1587793bdc..78bbce3dfc 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -245,7 +245,7 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
CHECK_RPC_ERR(rpccli_samr_Connect2(pipe_hnd, mem_ctx,
pipe_hnd->desthost,
SAMR_ACCESS_ENUM_DOMAINS
- | SAMR_ACCESS_OPEN_DOMAIN,
+ | SAMR_ACCESS_LOOKUP_DOMAIN,
&sam_pol),
"could not connect to SAM database");
diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index c6b6ee9e80..2915ffb809 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -521,6 +521,8 @@ NTSTATUS net_make_ipc_connection_ex(struct net_context *c ,const char *domain,
d_fprintf(stderr, "Connection failed: %s\n",
nt_errstr(nt_status));
cli = NULL;
+ } else if (c->opt_request_timeout) {
+ cli_set_timeout(cli, c->opt_request_timeout * 1000);
}
done:
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index 4cd0d55f56..8cca93f5de 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -430,14 +430,18 @@ static int process_root(int local_flags)
}
if((local_flags & LOCAL_SET_PASSWORD) && (new_passwd == NULL)) {
- struct passwd *passwd = getpwnam_alloc(NULL, user_name);
+ struct passwd *passwd;
- if (!passwd) {
- fprintf(stderr, "Cannot locate Unix account for "
- "'%s'!\n", user_name);
- exit(1);
+ 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);
}
- TALLOC_FREE(passwd);
new_passwd = prompt_for_new_password(stdin_passwd_get);