diff options
author | Andrew Bartlett <abartlet@samba.org> | 2009-04-20 16:53:02 +0200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2009-04-20 16:53:02 +0200 |
commit | 6c9caed48187a0d18becf59ab636af44cbe521b0 (patch) | |
tree | c47170169077be6f8ae60aed739803ab4ba861b7 /source3 | |
parent | 53765c81f726a8c056cc4e57004592dd489975c9 (diff) | |
parent | 31120c9eacafd93e0f2c6b0f906af21adadd318a (diff) | |
download | samba-6c9caed48187a0d18becf59ab636af44cbe521b0.tar.gz samba-6c9caed48187a0d18becf59ab636af44cbe521b0.tar.bz2 samba-6c9caed48187a0d18becf59ab636af44cbe521b0.zip |
Merge commit 'origin/master' into libcli-auth-merge-without-netlogond
Diffstat (limited to 'source3')
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(¬ify->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); |