diff options
Diffstat (limited to 'source3')
112 files changed, 3219 insertions, 3452 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 73b2989421..6aabcf0c8d 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -340,7 +340,7 @@ UTIL_OBJ = ../lib/util/rbtree.o ../lib/util/signal.o ../lib/util/time.o \ ../lib/util/params.o ../lib/util/talloc_stack.o \ ../lib/util/genrand.o ../lib/util/util_net.o \ ../lib/util/become_daemon.o ../lib/util/system.o \ - ../lib/util/tevent_unix.o + ../lib/util/tevent_unix.o ../lib/util/tevent_ntstatus.o CRYPTO_OBJ = ../lib/crypto/crc32.o ../lib/crypto/md5.o \ ../lib/crypto/hmacmd5.o ../lib/crypto/arcfour.o \ @@ -366,11 +366,12 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/substitute.o lib/dbwrap_util.o \ lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \ lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \ - lib/iconv.o lib/pam_errors.o intl/lang_tdb.o lib/conn_tdb.o \ - lib/adt_tree.o lib/gencache.o \ + lib/iconv.o lib/pam_errors.o intl/lang_tdb.o \ + lib/conn_tdb.o lib/adt_tree.o lib/gencache.o \ lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \ lib/ldap_escape.o @CHARSET_STATIC@ \ - lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o \ + lib/secdesc.o lib/util_seaccess.o ../libcli/security/secace.o \ + ../libcli/security/secacl.o \ libads/krb5_errs.o lib/system_smbd.o lib/audit.o $(LIBNDR_OBJ) \ lib/file_id.o lib/idmap_cache.o \ ../libcli/security/dom_sid.o @@ -671,8 +672,8 @@ VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o VFS_SMB_TRAFFIC_ANALYZER_OBJ = modules/vfs_smb_traffic_analyzer.o VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \ - modules/onefs_open.o modules/onefs_streams.o modules/onefs_dir.c \ - modules/onefs_cbrl.o modules/onefs_notify.o + modules/onefs_open.o modules/onefs_streams.o modules/onefs_dir.o \ + modules/onefs_cbrl.o modules/onefs_notify.o modules/onefs_config.o VFS_ONEFS_SHADOW_COPY_OBJ = modules/vfs_onefs_shadow_copy.o modules/onefs_shadow_copy.o PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o PERFCOUNT_TEST_OBJ = modules/perfcount_test.o @@ -689,7 +690,7 @@ AUTH_SAM_OBJ = auth/auth_sam.o AUTH_SERVER_OBJ = auth/auth_server.o AUTH_UNIX_OBJ = auth/auth_unix.o AUTH_WINBIND_OBJ = auth/auth_winbind.o -AUTH_ONEFS_WB_OBJ = auth/auth_onefs_wb.o +AUTH_WBC_OBJ = auth/auth_wbc.o AUTH_SCRIPT_OBJ = auth/auth_script.o AUTH_NETLOGOND_OBJ = auth/auth_netlogond.o @@ -2207,7 +2208,7 @@ installliblua:: installdirs liblua @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR) -$(INSTALLLIBCMD_SH) $(LIBLUA_SHARED_TARGET_SONAME) $(DESTDIR)$(LIBDIR) @rm -f $(DESTDIR)$(LIBDIR)/`basename $(LIBLUA_SHARED_TARGET)` - -if test -e $(LIBLUA_SHARED_TARGET_SONAME) ; then \ + -if test -f $(LIBLUA_SHARED_TARGET_SONAME) ; then \ ln -f -s `basename $(LIBLUA_SHARED_TARGET_SONAME)` \ $(DESTDIR)$(LIBDIR)/`basename $(LIBLUA_SHARED_TARGET)` ; \ fi @@ -2355,9 +2356,9 @@ bin/winbind.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WINBIND_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(AUTH_WINBIND_OBJ) -bin/onefs_wb.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_ONEFS_WB_OBJ) +bin/wbc.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WBC_OBJ) @echo "Building plugin $@" - @$(SHLD_MODULE) $(AUTH_ONEFS_WB_OBJ) + @$(SHLD_MODULE) $(AUTH_WBC_OBJ) bin/unix.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_UNIX_OBJ) @echo "Building plugin $@" @@ -2375,9 +2376,9 @@ bin/tdbsam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_tdb.o @echo "Building plugin $@" @$(SHLD_MODULE) passdb/pdb_tdb.o -bin/onefs_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_onefs_sam.o +bin/wbc_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_wbc_sam.o @echo "Building plugin $@" - @$(SHLD_MODULE) passdb/pdb_onefs_sam.o + @$(SHLD_MODULE) passdb/pdb_wbc_sam.o bin/smbpasswd.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_smbpasswd.o @echo "Building plugin $@" diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 1f00e22a3c..c39aa8501d 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -806,7 +806,7 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info) } /* - * Create an artificial NT token given just a username. (Initially indended + * Create an artificial NT token given just a username. (Initially intended * for force user) * * We go through lookup_name() to avoid problems we had with 'winbind use @@ -859,12 +859,6 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, goto done; } - if (!sid_to_uid(&user_sid, uid)) { - DEBUG(1, ("sid_to_uid for %s (%s) failed\n", - username, sid_string_dbg(&user_sid))); - goto done; - } - if (sid_check_is_in_our_domain(&user_sid)) { bool ret; @@ -922,6 +916,12 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, unix_user: + if (!sid_to_uid(&user_sid, uid)) { + DEBUG(1, ("sid_to_uid for %s (%s) failed\n", + username, sid_string_dbg(&user_sid))); + goto done; + } + uid_to_unix_users_sid(*uid, &user_sid); pass = getpwuid_alloc(tmp_ctx, *uid); diff --git a/source3/auth/auth_onefs_wb.c b/source3/auth/auth_wbc.c index 49de6966b0..580c8b550d 100644 --- a/source3/auth/auth_onefs_wb.c +++ b/source3/auth/auth_wbc.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. - Winbind authentication mechnism, customized for onefs + Winbind client authentication mechanism designed to defer all + authentication to the winbind daemon. Copyright (C) Tim Potter 2000 Copyright (C) Andrew Bartlett 2001 - 2002 @@ -21,6 +22,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +/* This auth module is very similar to auth_winbind with 3 distinct + * differences. + * + * 1) Does not fallback to another auth module if winbindd is unavailable + * 2) Does not validate the domain of the user + * 3) Handles unencrypted passwords + * + * The purpose of this module is to defer all authentication decisions (ie: + * local user vs NIS vs LDAP vs AD; encrypted vs plaintext) to the wbc + * compatible daemon. This centeralizes all authentication decisions to a + * single provider. + * + * This auth backend is most useful when used in conjunction with pdb_wbc_sam. + */ + #include "includes.h" #undef DBGC_CLASS @@ -28,7 +44,7 @@ /* Authenticate a user with a challenge/response */ -static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context, +static NTSTATUS check_wbc_security(const struct auth_context *auth_context, void *my_private_data, TALLOC_CTX *mem_ctx, const auth_usersupplied_info *user_info, @@ -58,7 +74,7 @@ static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context, user_info->internal_username)); params.level = WBC_AUTH_USER_LEVEL_PLAIN; - params.password.plaintext = user_info->plaintext_password.data; + params.password.plaintext = (char *)user_info->plaintext_password.data; } else { DEBUG(3,("Checking encrypted password for %s.\n", user_info->internal_username)); @@ -116,19 +132,19 @@ static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context, } /* module initialisation */ -static NTSTATUS auth_init_onefs_wb(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +static NTSTATUS auth_init_wbc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { return NT_STATUS_NO_MEMORY; } - (*auth_method)->name = "onefs_wb"; - (*auth_method)->auth = check_onefs_wb_security; + (*auth_method)->name = "wbc"; + (*auth_method)->auth = check_wbc_security; return NT_STATUS_OK; } -NTSTATUS auth_onefs_wb_init(void) +NTSTATUS auth_wbc_init(void) { - return smb_register_auth(AUTH_INTERFACE_VERSION, "onefs_wb", auth_init_onefs_wb); + return smb_register_auth(AUTH_INTERFACE_VERSION, "wbc", auth_init_wbc); } diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index ae8a7fd186..8623d3c04b 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -649,7 +649,9 @@ static int parse_options(char ** optionsp, int * filesys_flags) } else if (strncmp(data, "exec", 4) == 0) { *filesys_flags &= ~MS_NOEXEC; } else if (strncmp(data, "guest", 5) == 0) { - got_password=1; + user_name = (char *)calloc(1, 1); + got_user = 1; + got_password = 1; } else if (strncmp(data, "ro", 2) == 0) { *filesys_flags |= MS_RDONLY; } else if (strncmp(data, "rw", 2) == 0) { diff --git a/source3/configure.in b/source3/configure.in index bd3d4af40b..e48ff34554 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -414,7 +414,7 @@ AC_SUBST(DYNEXP) dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" +default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer" @@ -1088,7 +1088,7 @@ echo $samba_cv_HAVE_ONEFS if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS]) default_shared_modules="$default_shared_modules vfs_onefs vfs_onefs_shadow_copy perfcount_onefs" - default_static_modules="$default_static_modules auth_onefs_wb pdb_onefs_sam" + default_static_modules="$default_static_modules" ONEFS_LIBS="-lisi_acl -lisi_ecs -lisi_event -lisi_util" # Need to also add general libs for oplocks support save_LIBS="$save_LIBS -lisi_ecs -lisi_event -lisi_util -ldevstat" @@ -4723,35 +4723,6 @@ SMB_LIBRARY(addns, 0, no, [undefined API]) ################################################# -# check to see if we should set the protected madvise flag, -# which will keep smbd alive in low memory conditions -AC_MSG_CHECKING(whether to protect smbd from being killed in low memory) -AC_ARG_WITH(madvise-protect, -[AS_HELP_STRING([--with-madvise-protect], [Include low memory madvise protection (default=no)])], -[ case "$withval" in - yes) - AC_TRY_COMPILE([ - #include <sys/mman.h> - ],[ - int a = MADV_PROTECT; - ], - [samba_cv_madvise_protect=yes], - [samba_cv_madvise_protect=no]) - if test x"$samba_cv_madvise_protect" = x"yes"; then - AC_MSG_RESULT(yes) - AC_DEFINE(WITH_MADVISE_PROTECTED,1,[Whether to include low memory protection support]) - else - AC_MSG_ERROR(Low memory protection supporte requires availability of MADVISE_PROTECT flag.) - fi - ;; - *) - AC_MSG_RESULT(no) - ;; - esac ], - AC_MSG_RESULT(no) -) - -################################################# # these tests are taken from the GNU fileutils package AC_CHECKING(how to get filesystem space usage) space=no @@ -6130,7 +6101,7 @@ SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o passdb/pdb_nds.o, "bin/ldapsam.$SHLIBEXT" [ PASSDB_LIBS="$PASSDB_LIBS $LDAP_LIBS" ] ) SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB) SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB) -SMB_MODULE(pdb_onefs_sam, passdb/pdb_onefs_sam.o, "bin/onefs_sam.$SHLIBEXT", PDB) +SMB_MODULE(pdb_wbc_sam, passdb/pdb_wbc_sam.o, "bin/wbc_sam.$SHLIBEXT", PDB) SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o) @@ -6173,7 +6144,7 @@ SMB_SUBSYSTEM(CHARSET,lib/iconv.o) SMB_MODULE(auth_sam, \$(AUTH_SAM_OBJ), "bin/sam.$SHLIBEXT", AUTH) SMB_MODULE(auth_unix, \$(AUTH_UNIX_OBJ), "bin/unix.$SHLIBEXT", AUTH) SMB_MODULE(auth_winbind, \$(AUTH_WINBIND_OBJ), "bin/winbind.$SHLIBEXT", AUTH) -SMB_MODULE(auth_onefs_wb, \$(AUTH_ONEFS_WB_OBJ), "bin/onefs_wb.$SHLIBEXT", AUTH) +SMB_MODULE(auth_wbc, \$(AUTH_WBC_OBJ), "bin/wbc.$SHLIBEXT", AUTH) SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH) SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH) SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH) diff --git a/source3/include/charset.h b/source3/include/charset.h deleted file mode 100644 index 1c2a5fb5f0..0000000000 --- a/source3/include/charset.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - Unix SMB/CIFS implementation. - charset defines - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jelmer Vernooij 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -struct smb_iconv_convenience; - -/* this defines the charset types used in samba */ -typedef enum {CH_UTF16LE=0, CH_UTF16=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4, CH_UTF16BE=5} charset_t; - -#define NUM_CHARSETS 6 - -/* - * for each charset we have a function that pushes from that charset to a ucs2 - * buffer, and a function that pulls from ucs2 buffer to that charset. - * */ - -struct charset_functions { - const char *name; - size_t (*pull)(void *, const char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft); - size_t (*push)(void *, const char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft); - struct charset_functions *prev, *next; -}; - -/* - * This is auxiliary struct used by source/script/gen-8-bit-gap.sh script - * during generation of an encoding table for charset module - * */ - -struct charset_gap_table { - uint16 start; - uint16 end; - int32 idx; -}; - -/* - * Define stub for charset module which implements 8-bit encoding with gaps. - * Encoding tables for such module should be produced from glibc's CHARMAPs - * using script source/script/gen-8bit-gap.sh - * CHARSETNAME is CAPITALIZED charset name - * - * */ -#define SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CHARSETNAME) \ -static size_t CHARSETNAME ## _push(void *cd, const char **inbuf, size_t *inbytesleft, \ - char **outbuf, size_t *outbytesleft) \ -{ \ - while (*inbytesleft >= 2 && *outbytesleft >= 1) { \ - int i; \ - int done = 0; \ - \ - uint16 ch = SVAL(*inbuf,0); \ - \ - for (i=0; from_idx[i].start != 0xffff; i++) { \ - if ((from_idx[i].start <= ch) && (from_idx[i].end >= ch)) { \ - ((unsigned char*)(*outbuf))[0] = from_ucs2[from_idx[i].idx+ch]; \ - (*inbytesleft) -= 2; \ - (*outbytesleft) -= 1; \ - (*inbuf) += 2; \ - (*outbuf) += 1; \ - done = 1; \ - break; \ - } \ - } \ - if (!done) { \ - errno = EINVAL; \ - return -1; \ - } \ - \ - } \ - \ - if (*inbytesleft == 1) { \ - errno = EINVAL; \ - return -1; \ - } \ - \ - if (*inbytesleft > 1) { \ - errno = E2BIG; \ - return -1; \ - } \ - \ - return 0; \ -} \ - \ -static size_t CHARSETNAME ## _pull(void *cd, const char **inbuf, size_t *inbytesleft, \ - char **outbuf, size_t *outbytesleft) \ -{ \ - while (*inbytesleft >= 1 && *outbytesleft >= 2) { \ - *(uint16*)(*outbuf) = to_ucs2[((unsigned char*)(*inbuf))[0]]; \ - (*inbytesleft) -= 1; \ - (*outbytesleft) -= 2; \ - (*inbuf) += 1; \ - (*outbuf) += 2; \ - } \ - \ - if (*inbytesleft > 0) { \ - errno = E2BIG; \ - return -1; \ - } \ - \ - return 0; \ -} \ - \ -struct charset_functions CHARSETNAME ## _functions = \ - {#CHARSETNAME, CHARSETNAME ## _pull, CHARSETNAME ## _push}; \ - \ -NTSTATUS charset_ ## CHARSETNAME ## _init(void); \ -NTSTATUS charset_ ## CHARSETNAME ## _init(void) \ -{ \ - return smb_register_charset(& CHARSETNAME ## _functions); \ -} \ - diff --git a/source3/include/dbwrap.h b/source3/include/dbwrap.h index aad4ccd721..16f10cc125 100644 --- a/source3/include/dbwrap.h +++ b/source3/include/dbwrap.h @@ -46,6 +46,10 @@ struct db_context { int (*transaction_start)(struct db_context *db); int (*transaction_commit)(struct db_context *db); int (*transaction_cancel)(struct db_context *db); + int (*parse_record)(struct db_context *db, TDB_DATA key, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data); void *private_data; bool persistent; }; diff --git a/source3/include/includes.h b/source3/include/includes.h index 80d7bfc6cf..b48a75526a 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -577,22 +577,20 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); #include "../talloc/talloc.h" #include "event.h" +#include "../lib/util/tevent_unix.h" +#include "../lib/util/tevent_ntstatus.h" #include "../lib/util/data_blob.h" #include "../lib/util/time.h" #include "../lib/util/asn1.h" -/* And a little extension. Abort on type mismatch */ -#define talloc_get_type_abort(ptr, type) \ - (type *)talloc_check_name_abort(ptr, #type) - #include "ads.h" #include "ads_dns.h" #include "interfaces.h" #include "trans2.h" #include "../libcli/util/error.h" #include "ntioctl.h" -#include "charset.h" +#include "../lib/util/charset/charset.h" #include "dynconfig.h" #include "util_getent.h" #include "debugparse.h" @@ -701,6 +699,8 @@ enum flush_reason_enum { #ifndef NO_PROTO_H #include "proto.h" #endif +#include "libcli/security/secace.h" +#include "libcli/security/secacl.h" #if defined(HAVE_POSIX_ACLS) #include "modules/vfs_posixacl.h" diff --git a/source3/include/proto.h b/source3/include/proto.h index 9366607995..78110161c5 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -336,6 +336,7 @@ int bitmap_find(struct bitmap *bm, unsigned ofs); /* The following definitions come from lib/charcnv.c */ +NTSTATUS smb_register_charset(struct charset_functions *funcs); char lp_failed_convert_char(void); void lazy_initialize_conv(void); void gfree_charcnv(void); @@ -347,7 +348,7 @@ bool convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, void const *src, size_t srclen, void *dst, size_t *converted_size, bool allow_bad_conv); bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, - void const *src, size_t srclen, void *dst, + void const *src, size_t srclen, void **dst, size_t *converted_size, bool allow_bad_conv); size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen); char *strdup_upper(const char *s); @@ -528,15 +529,6 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time int gencache_lock_entry( const char *key ); void gencache_unlock_entry( const char *key ); -/* The following definitions come from lib/iconv.c */ - -NTSTATUS smb_register_charset(struct charset_functions *funcs) ; -size_t smb_iconv(smb_iconv_t cd, - const char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft); -smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode); -int smb_iconv_close (smb_iconv_t cd); - /* The following definitions come from lib/interface.c */ bool ismyaddr(const struct sockaddr *ip); @@ -659,28 +651,6 @@ ssize_t sys_recvfile(int fromfd, size_t count); ssize_t drain_socket(int sockfd, size_t count); -/* The following definitions come from lib/secace.c */ - -bool sec_ace_object(uint8 type); -void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src); -void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, enum security_ace_type type, - uint32 mask, uint8 flag); -NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask); -NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask); -NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, uint32 *num, DOM_SID *sid); -bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2); -int nt_ace_inherit_comp( SEC_ACE *a1, SEC_ACE *a2); -int nt_ace_canon_comp( SEC_ACE *a1, SEC_ACE *a2); -void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces); -bool token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace); - -/* The following definitions come from lib/secacl.c */ - -SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, enum security_acl_revision revision, - int num_aces, SEC_ACE *ace_list); -SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src); -bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2); - /* The following definitions come from lib/secdesc.c */ bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2); @@ -1203,7 +1173,6 @@ bool mask_match_search(const char *string, const char *pattern, bool is_case_sen bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive); bool unix_wild_match(const char *pattern, const char *string); bool name_to_fqdn(fstring fqdn, const char *name); -void *talloc_check_name_abort(const void *ptr, const char *name); void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob); uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options); pid_t procid_to_pid(const struct server_id *proc); @@ -1261,6 +1230,7 @@ NTSTATUS merge_nt_token(TALLOC_CTX *mem_ctx, const struct nt_user_token *token_1, const struct nt_user_token *token_2, struct nt_user_token **token_out); +bool token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace); /* The following definitions come from lib/util_pw.c */ @@ -1423,12 +1393,12 @@ int open_socket_in(int type, bool rebind); NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port, int timeout, int *pfd); -struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const struct sockaddr_storage *pss, - uint16_t port, - int timeout); -NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd); +struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const struct sockaddr_storage *pss, + uint16_t port, + int timeout); +NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd); struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct timeval wait_time, @@ -4693,6 +4663,10 @@ NTSTATUS pdb_nds_init(void); NTSTATUS pdb_smbpasswd_init(void) ; +/* The following definitions come from passdb/pdb_wbc_sam.c */ + +NTSTATUS pdb_wbc_sam_init(void); + /* The following definitions come from passdb/pdb_tdb.c */ bool init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen); @@ -5045,12 +5019,15 @@ WERROR init_registry_data(void); WERROR regdb_init(void); WERROR regdb_open( void ); int regdb_close( void ); +WERROR regdb_transaction_start(void); +WERROR regdb_transaction_commit(void); +WERROR regdb_transaction_cancel(void); int regdb_get_seqnum(void); -bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr); -int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr); +bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr); +int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr); int regdb_fetch_values( const char* key, REGVAL_CTR *values ); bool regdb_store_values( const char *key, REGVAL_CTR *values ); -bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys); +bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys); bool regdb_values_need_update(REGVAL_CTR *values); /* The following definitions come from registry/reg_backend_hkpt_params.c */ @@ -5086,9 +5063,11 @@ void reghook_dump_cache( int debuglevel ); /* The following definitions come from registry/reg_dispatcher.c */ -bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ); +bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys ); bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ); -int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr ); +WERROR create_reg_subkey(REGISTRY_KEY *key, const char *subkey); +WERROR delete_reg_subkey(REGISTRY_KEY *key, const char *subkey); +int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr ); int fetch_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ); bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted, const struct nt_user_token *token ); @@ -5096,7 +5075,7 @@ WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key, struct security_descriptor **psecdesc); WERROR regkey_set_secdesc(REGISTRY_KEY *key, struct security_descriptor *psecdesc); -bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys); +bool reg_subkeys_need_update(REGISTRY_KEY *key, struct regsubkey_ctr *subkeys); bool reg_values_need_update(REGISTRY_KEY *key, REGVAL_CTR *values); /* The following definitions come from registry/reg_eventlog.c */ @@ -5122,11 +5101,14 @@ WERROR registry_init_smbconf(const char *keyname); /* The following definitions come from registry/reg_objects.c */ -WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ); -int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ); -bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ); -int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr ); -char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index ); +WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr); +WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum); +int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr); +WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ); +WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ); +bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ); +int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr ); +char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32 key_index ); int regval_ctr_numvals( REGVAL_CTR *ctr ); REGISTRY_VALUE* dup_registry_value( REGISTRY_VALUE *val ); void free_registry_value( REGISTRY_VALUE *val ); @@ -5476,33 +5458,38 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, union spoolss_DriverInfo *info, uint32_t *server_major_version, uint32_t *server_minor_version); +WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct spoolss_SetPrinterInfoCtr *info_ctr); +WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t level, + uint32_t offered, + union spoolss_PrinterInfo *info); +WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t job_id, + uint32_t level, + uint32_t offered, + union spoolss_JobInfo *info); WERROR rpccli_spoolss_enum_printers(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr); WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, uint32 *num_ports, PORT_INFO_CTR *ctr); -WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr); -WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr, uint32 command); WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, uint32 *num_drivers, PRINTER_DRIVER_CTR *ctr); -WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 level, PRINTER_INFO_CTR*ctr); WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *handle, int level, uint32 *num_forms, FORM_1 **forms); WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, uint32 firstjob, uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr); -WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 jobid, uint32 level, - JOB_INFO_CTR *ctr); WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, const char *valuename, REGISTRY_VALUE *value); @@ -5804,17 +5791,7 @@ bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int bool spoolss_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); -bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u ); bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode); -bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, - const char *srv_name, const char* clientname, const char* user_name, - uint32 level, PRINTER_INFO_CTR *ctr); -bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, - PRINTER_INFO_2 *info); -bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, - PRINTER_INFO_3 *info); -bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, - PRINTER_INFO_7 *info); bool make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, const POLICY_HND *handle, const char *valuename, uint32 size); @@ -5884,19 +5861,6 @@ bool spoolss_io_q_enumprinters(const char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_ bool spoolss_io_r_enumprinters(const char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth); bool spoolss_io_r_getprinter(const char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth); bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth); -bool make_spoolss_q_getprinter( - TALLOC_CTX *mem_ctx, - SPOOL_Q_GETPRINTER *q_u, - const POLICY_HND *hnd, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered -); -bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, - const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, - uint32 command); -bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth); -bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth); bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth); bool make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, uint32 firstjob, @@ -5916,17 +5880,7 @@ bool spoolss_io_q_enumforms(const char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct bool spoolss_io_r_enumforms(const char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth); bool spoolss_io_r_enumports(const char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth); bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth); -bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth); -bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth); -bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth); -bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, - prs_struct *ps, int depth); bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 *src); -bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, - NT_PRINTER_INFO_LEVEL_2 *d); bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); bool spoolss_io_q_enumprintprocessors(const char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth); bool spoolss_io_r_enumprintprocdatatypes(const char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth); @@ -5966,9 +5920,6 @@ bool spoolss_io_r_enumprinterdataex(const char *desc, SPOOL_R_ENUMPRINTERDATAEX bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, uint32 level, RPC_BUFFER *buffer, uint32 offered); -bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, - uint32 jobid, uint32 level, RPC_BUFFER *buffer, - uint32 offered); /* The following definitions come from rpc_server/srv_eventlog_lib.c */ @@ -6540,6 +6491,7 @@ files_struct *file_find_fsp(files_struct *orig_fsp); files_struct *file_find_di_first(struct file_id id); files_struct *file_find_di_next(files_struct *start_fsp); files_struct *file_find_print(void); +bool file_find_subpath(files_struct *dir_fsp); void file_sync_all(connection_struct *conn); void file_free(struct smb_request *req, files_struct *fsp); files_struct *file_fnum(uint16 fnum); diff --git a/source3/include/reg_db.h b/source3/include/reg_db.h index 92448ae543..5cafa0a5fb 100644 --- a/source3/include/reg_db.h +++ b/source3/include/reg_db.h @@ -26,5 +26,6 @@ #define REG_VALUE_PREFIX "SAMBA_REGVAL" #define REG_SECDESC_PREFIX "SAMBA_SECDESC" +#define REG_SORTED_SUBKEYS_PREFIX "SAMBA_SORTED_SUBKEYS" #endif /* _REG_DB_H */ diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index d9159dd464..a03ac1bff4 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -66,11 +66,7 @@ typedef struct { /* container for registry subkey names */ -typedef struct { - uint32 num_subkeys; - char **subkeys; - int seqnum; -} REGSUBKEY_CTR; +struct regsubkey_ctr; /* * @@ -132,9 +128,11 @@ typedef struct { typedef struct { /* functions for enumerating subkeys and values */ - int (*fetch_subkeys)( const char *key, REGSUBKEY_CTR *subkeys); + int (*fetch_subkeys)( const char *key, struct regsubkey_ctr *subkeys); int (*fetch_values) ( const char *key, REGVAL_CTR *val ); - bool (*store_subkeys)( const char *key, REGSUBKEY_CTR *subkeys ); + bool (*store_subkeys)( const char *key, struct regsubkey_ctr *subkeys ); + WERROR (*create_subkey)(const char *key, const char *subkey); + WERROR (*delete_subkey)(const char *key, const char *subkey); bool (*store_values)( const char *key, REGVAL_CTR *val ); bool (*reg_access_check)( const char *keyname, uint32 requested, uint32 *granted, @@ -143,7 +141,7 @@ typedef struct { struct security_descriptor **psecdesc); WERROR (*set_secdesc)(const char *key, struct security_descriptor *sec_desc); - bool (*subkeys_need_update)(REGSUBKEY_CTR *subkeys); + bool (*subkeys_need_update)(struct regsubkey_ctr *subkeys); bool (*values_need_update)(REGVAL_CTR *values); } REGISTRY_OPS; @@ -164,7 +162,7 @@ typedef struct _RegistryKey { struct registry_key { REGISTRY_KEY *key; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; REGVAL_CTR *values; struct nt_user_token *token; }; diff --git a/source3/include/regfio.h b/source3/include/regfio.h index 63516a358d..0e957d51e5 100644 --- a/source3/include/regfio.h +++ b/source3/include/regfio.h @@ -214,7 +214,7 @@ int regfio_close( REGF_FILE *r ); REGF_NK_REC* regfio_rootkey( REGF_FILE *file ); REGF_NK_REC* regfio_fetch_subkey( REGF_FILE *file, REGF_NK_REC *nk ); REGF_NK_REC* regfio_write_key ( REGF_FILE *file, const char *name, - REGVAL_CTR *values, REGSUBKEY_CTR *subkeys, + REGVAL_CTR *values, struct regsubkey_ctr *subkeys, SEC_DESC *sec_desc, REGF_NK_REC *parent ); diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h index a1cfad9003..c74d621f35 100644 --- a/source3/include/rpc_secdes.h +++ b/source3/include/rpc_secdes.h @@ -39,9 +39,6 @@ #define SEC_RIGHTS_RESET_PASSWD SEC_RIGHTS_EXTENDED #define SEC_RIGHTS_FULL_CTRL 0xf01ff -#define SEC_ACE_OBJECT_PRESENT 0x00000001 /* thanks for Jim McDonough <jmcd@us.ibm.com> */ -#define SEC_ACE_OBJECT_INHERITED_PRESENT 0x00000002 - /* * New Windows 2000 bits. */ @@ -72,7 +69,6 @@ /* SEC_ACE */ typedef struct security_ace SEC_ACE; -#define SEC_ACE_HEADER_SIZE (2 * sizeof(uint8) + sizeof(uint16) + sizeof(uint32)) #ifndef ACL_REVISION #define ACL_REVISION 0x3 @@ -81,7 +77,6 @@ typedef struct security_ace SEC_ACE; #ifndef _SEC_ACL /* SEC_ACL */ typedef struct security_acl SEC_ACL; -#define SEC_ACL_HEADER_SIZE (2 * sizeof(uint16) + sizeof(uint32)) #define _SEC_ACL #endif diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 48609a3cd6..2b4a036ce8 100644 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -121,41 +121,10 @@ #define SPL_XCV_MONITOR_LOCALMON ",XcvMonitor Local Port" #define SPL_XCV_MONITOR_TCPMON ",XcvMonitor Standard TCP/IP Port" - -#define PRINTER_STATUS_OK 0x00000000 -#define JOB_ACCESS_READ 0x00000020 - -/* JOB status codes. */ - -#define JOB_STATUS_QUEUED 0x0000 -#define JOB_STATUS_PAUSED 0x0001 -#define JOB_STATUS_ERROR 0x0002 -#define JOB_STATUS_DELETING 0x0004 -#define JOB_STATUS_SPOOLING 0x0008 -#define JOB_STATUS_PRINTING 0x0010 -#define JOB_STATUS_OFFLINE 0x0020 -#define JOB_STATUS_PAPEROUT 0x0040 -#define JOB_STATUS_PRINTED 0x0080 -#define JOB_STATUS_DELETED 0x0100 -#define JOB_STATUS_BLOCKED 0x0200 -#define JOB_STATUS_USER_INTERVENTION 0x0400 - /* Notify field types */ -#define NOTIFY_ONE_VALUE 1 /* Notify data is stored in value1 */ -#define NOTIFY_TWO_VALUE 2 /* Notify data is stored in value2 */ -#define NOTIFY_POINTER 3 /* Data is a pointer to a buffer */ -#define NOTIFY_STRING 4 /* Data is a pointer to a buffer w/length */ -#define NOTIFY_SECDESC 5 /* Data is a security descriptor */ - #define PRINTER_NOTIFY_TYPE 0x00 #define JOB_NOTIFY_TYPE 0x01 -#define PRINT_TABLE_END 0xFF - -#define MAX_PRINTER_NOTIFY 26 -#define MAX_JOB_NOTIFY 24 - -#define MAX_NOTIFY_TYPE_FOR_NOW 26 #define PRINTER_NOTIFY_SERVER_NAME 0x00 #define PRINTER_NOTIFY_PRINTER_NAME 0x01 @@ -261,25 +230,6 @@ PRINTER_MESSAGE_INFO; #define DRIVER_MAX_VERSION 4 -/* this struct is undocumented */ -/* thanks to the ddk ... */ -typedef struct { - uint32 size; /* length of user_name & client_name + 2? */ - UNISTR2 *client_name; - UNISTR2 *user_name; - uint32 build; - uint32 major; - uint32 minor; - uint32 processor; -} SPOOL_USER_1; - -typedef struct { - uint32 level; - union { - SPOOL_USER_1 *user1; - } user; -} SPOOL_USER_CTR; - /* * Devicemode structure */ @@ -343,19 +293,6 @@ PRINTER_DEFAULT; /********************************************/ -typedef struct s_header_type -{ - uint32 type; - union - { - uint32 value; - UNISTR string; - } - data; -} -HEADER_TYPE; - - typedef struct spool_q_getprinterdata { POLICY_HND handle; @@ -488,11 +425,6 @@ typedef struct printer_info_6 } PRINTER_INFO_6; -#define SPOOL_DS_PUBLISH 1 -#define SPOOL_DS_UPDATE 2 -#define SPOOL_DS_UNPUBLISH 4 -#define SPOOL_DS_PENDING 0x80000000 - typedef struct printer_info_7 { UNISTR guid; /* text form of printer guid */ @@ -872,115 +804,8 @@ typedef struct spool_r_enumforms } SPOOL_R_ENUMFORMS; -typedef struct spool_printer_info_level_1 -{ - uint32 flags; - uint32 description_ptr; - uint32 name_ptr; - uint32 comment_ptr; - UNISTR2 description; - UNISTR2 name; - UNISTR2 comment; -} SPOOL_PRINTER_INFO_LEVEL_1; - -typedef struct spool_printer_info_level_2 -{ - uint32 servername_ptr; - uint32 printername_ptr; - uint32 sharename_ptr; - uint32 portname_ptr; - uint32 drivername_ptr; - uint32 comment_ptr; - uint32 location_ptr; - uint32 devmode_ptr; - uint32 sepfile_ptr; - uint32 printprocessor_ptr; - uint32 datatype_ptr; - uint32 parameters_ptr; - uint32 secdesc_ptr; - uint32 attributes; - uint32 priority; - uint32 default_priority; - uint32 starttime; - uint32 untiltime; - uint32 status; - uint32 cjobs; - uint32 averageppm; - UNISTR2 servername; - UNISTR2 printername; - UNISTR2 sharename; - UNISTR2 portname; - UNISTR2 drivername; - UNISTR2 comment; - UNISTR2 location; - UNISTR2 sepfile; - UNISTR2 printprocessor; - UNISTR2 datatype; - UNISTR2 parameters; -} -SPOOL_PRINTER_INFO_LEVEL_2; - -typedef struct spool_printer_info_level_3 -{ - uint32 secdesc_ptr; -} -SPOOL_PRINTER_INFO_LEVEL_3; - -typedef struct spool_printer_info_level_7 -{ - uint32 guid_ptr; - uint32 action; - UNISTR2 guid; -} -SPOOL_PRINTER_INFO_LEVEL_7; - -typedef struct spool_printer_info_level -{ - uint32 level; - uint32 info_ptr; - SPOOL_PRINTER_INFO_LEVEL_1 *info_1; - SPOOL_PRINTER_INFO_LEVEL_2 *info_2; - SPOOL_PRINTER_INFO_LEVEL_3 *info_3; - SPOOL_PRINTER_INFO_LEVEL_7 *info_7; -} -SPOOL_PRINTER_INFO_LEVEL; - -typedef struct spool_q_setprinter -{ - POLICY_HND handle; - uint32 level; - SPOOL_PRINTER_INFO_LEVEL info; - SEC_DESC_BUF *secdesc_ctr; - DEVMODE_CTR devmode_ctr; - - uint32 command; - -} -SPOOL_Q_SETPRINTER; - -typedef struct spool_r_setprinter -{ - WERROR status; -} -SPOOL_R_SETPRINTER; - /********************************************/ -typedef struct { - UNISTR2 *server_name; - uint32 level; - SPOOL_PRINTER_INFO_LEVEL info; - DEVMODE_CTR devmode_ctr; - SEC_DESC_BUF *secdesc_ctr; - uint32 user_switch; - SPOOL_USER_CTR user_ctr; -} SPOOL_Q_ADDPRINTEREX; - -typedef struct { - POLICY_HND handle; - WERROR status; -} SPOOL_R_ADDPRINTEREX; - typedef struct spool_q_enumprintprocessors { uint32 name_ptr; diff --git a/source3/include/smb.h b/source3/include/smb.h index f02088731d..a0140fe081 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -149,8 +149,6 @@ typedef union unid_t { * smb_ucs2_t is *always* in little endian format. */ -typedef uint16 smb_ucs2_t; - #ifdef WORDS_BIGENDIAN #define UCS2_SHIFT 8 #else @@ -167,10 +165,6 @@ typedef uint16 smb_ucs2_t; #define COPY_UCS2_CHAR(dest,src) (((unsigned char *)(dest))[0] = ((unsigned char *)(src))[0],\ ((unsigned char *)(dest))[1] = ((unsigned char *)(src))[1], (dest)) -/* Large data type for manipulating uint32 unicode codepoints */ -typedef uint32 codepoint_t; -#define INVALID_CODEPOINT ((codepoint_t)-1) - /* pipe string names */ #define PIPE_LANMAN "\\PIPE\\LANMAN" @@ -579,6 +573,12 @@ typedef struct connection_struct { */ struct auth_serversupplied_info *server_info; + /* + * If the "force group" parameter is set, this is the primary gid that + * may be used in the users token, depending on the vuid using this tid. + */ + gid_t force_group_gid; + char client_address[INET6_ADDRSTRLEN]; /* String version of client IP address. */ uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */ @@ -1831,18 +1831,6 @@ struct unix_error_map { #define SAFE_NETBIOS_CHARS ". -_" -/* generic iconv conversion structure */ -typedef struct _smb_iconv_t { - size_t (*direct)(void *cd, const char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft); - size_t (*pull)(void *cd, const char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft); - size_t (*push)(void *cd, const char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft); - void *cd_direct, *cd_pull, *cd_push; - char *from_name, *to_name; -} *smb_iconv_t; - /* The maximum length of a trust account password. Used when we randomly create it, 15 char passwords exceed NT4's max password length */ diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index 131416b685..f9a0436546 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -75,6 +75,10 @@ enum profile_stats_values #define syscall_open_count __profile_stats_value(PR_VALUE_SYSCALL_OPEN, count) #define syscall_open_time __profile_stats_value(PR_VALUE_SYSCALL_OPEN, time) + PR_VALUE_SYSCALL_CREATEFILE, +#define syscall_createfile_count __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, count) +#define syscall_createfile_time __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, time) + PR_VALUE_SYSCALL_CLOSE, #define syscall_close_count __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, count) #define syscall_close_time __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, time) @@ -111,6 +115,10 @@ enum profile_stats_values #define syscall_rename_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME, count) #define syscall_rename_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME, time) + PR_VALUE_SYSCALL_RENAME_AT, +#define syscall_rename_at_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, count) +#define syscall_rename_at_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, time) + PR_VALUE_SYSCALL_FSYNC, #define syscall_fsync_count __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, count) #define syscall_fsync_time __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, time) @@ -215,6 +223,26 @@ enum profile_stats_values #define syscall_set_quota_count __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, count) #define syscall_set_quota_time __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, time) + PR_VALUE_SYSCALL_GET_SD, +#define syscall_get_sd_count __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, count) +#define syscall_get_sd_time __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, time) + + PR_VALUE_SYSCALL_SET_SD, +#define syscall_set_sd_count __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, count) +#define syscall_set_sd_time __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, time) + + PR_VALUE_SYSCALL_BRL_LOCK, +#define syscall_brl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, count) +#define syscall_brl_lock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, time) + + PR_VALUE_SYSCALL_BRL_UNLOCK, +#define syscall_brl_unlock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, count) +#define syscall_brl_unlock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, time) + + PR_VALUE_SYSCALL_BRL_CANCEL, +#define syscall_brl_cancel_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, count) +#define syscall_brl_cancel_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, time) + /* counters for individual SMB types */ PR_VALUE_SMBMKDIR, #define SMBmkdir_count __profile_stats_value(PR_VALUE_SMBMKDIR, count) diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index c3b345142f..81cb9a5094 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -763,7 +763,7 @@ bool convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to, * converted. */ bool convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to, - void const *src, size_t srclen, void *dst, + void const *src, size_t srclen, void **dst, size_t *converted_size, bool allow_bad_conv) { void **dest = (void **)dst; diff --git a/source3/lib/dbwrap.c b/source3/lib/dbwrap.c index a57b7c97a5..5e7ce6099f 100644 --- a/source3/lib/dbwrap.c +++ b/source3/lib/dbwrap.c @@ -42,6 +42,29 @@ static int dbwrap_fallback_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, return 0; } +/* + * Fall back using fetch if no genuine parse operation is provided + */ + +static int dbwrap_fallback_parse_record(struct db_context *db, TDB_DATA key, + int (*parser)(TDB_DATA key, + TDB_DATA data, + void *private_data), + void *private_data) +{ + TDB_DATA data; + int res; + + res = db->fetch(db, talloc_tos(), key, &data); + if (res != 0) { + return res; + } + + res = parser(key, data, private_data); + TALLOC_FREE(data.dptr); + return res; +} + /** * open a database */ @@ -101,6 +124,9 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx, if ((result != NULL) && (result->fetch == NULL)) { result->fetch = dbwrap_fallback_fetch; } + if ((result != NULL) && (result->parse_record == NULL)) { + result->parse_record = dbwrap_fallback_parse_record; + } return result; } diff --git a/source3/lib/dbwrap_ctdb.c b/source3/lib/dbwrap_ctdb.c index 03667ff355..4a5bf6d81a 100644 --- a/source3/lib/dbwrap_ctdb.c +++ b/source3/lib/dbwrap_ctdb.c @@ -121,9 +121,9 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx, { struct ctdb_rec_data *r; size_t m_size, r_size; - struct ctdb_marshall_buffer *m2; + struct ctdb_marshall_buffer *m2 = NULL; - r = db_ctdb_marshall_record(mem_ctx, reqid, key, header, data); + r = db_ctdb_marshall_record(talloc_tos(), reqid, key, header, data); if (r == NULL) { talloc_free(m); return NULL; @@ -133,7 +133,7 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx, m = (struct ctdb_marshall_buffer *)talloc_zero_size( mem_ctx, offsetof(struct ctdb_marshall_buffer, data)); if (m == NULL) { - return NULL; + goto done; } m->db_id = db_id; } @@ -145,15 +145,15 @@ static struct ctdb_marshall_buffer *db_ctdb_marshall_add(TALLOC_CTX *mem_ctx, mem_ctx, m, m_size + r_size); if (m2 == NULL) { talloc_free(m); - return NULL; + goto done; } memcpy(m_size + (uint8_t *)m2, r, r_size); - talloc_free(r); - m2->count++; +done: + talloc_free(r); return m2; } diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 6e09627223..cf4faa25b9 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -131,12 +131,12 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) */ } - node = (struct db_rbt_node *)SMB_MALLOC( + node = (struct db_rbt_node *)talloc_size(rec_priv->db_ctx, offsetof(struct db_rbt_node, data) + rec->key.dsize + data.dsize); if (node == NULL) { - SAFE_FREE(rec_priv->node); + TALLOC_FREE(rec_priv->node); return NT_STATUS_NO_MEMORY; } @@ -148,7 +148,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) db_rbt_parse_node(node, &this_key, &this_val); memcpy(this_key.dptr, rec->key.dptr, node->keysize); - SAFE_FREE(rec_priv->node); + TALLOC_FREE(rec_priv->node); memcpy(this_val.dptr, data.dptr, node->valuesize); @@ -194,7 +194,7 @@ static NTSTATUS db_rbt_delete(struct db_record *rec) } rb_erase(&rec_priv->node->rb_node, &rec_priv->db_ctx->tree); - SAFE_FREE(rec_priv->node); + TALLOC_FREE(rec_priv->node); return NT_STATUS_OK; } diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c index b5eb1881d4..c71e073b41 100644 --- a/source3/lib/dbwrap_tdb.c +++ b/source3/lib/dbwrap_tdb.c @@ -176,6 +176,17 @@ static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, return 0; } +static int db_tdb_parse(struct db_context *db, TDB_DATA key, + int (*parser)(TDB_DATA key, TDB_DATA data, + void *private_data), + void *private_data) +{ + struct db_tdb_ctx *ctx = talloc_get_type_abort( + db->private_data, struct db_tdb_ctx); + + return tdb_parse_record(ctx->wtdb->tdb, key, parser, private_data); +} + static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag) { struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data, @@ -351,6 +362,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx, result->fetch = db_tdb_fetch; result->traverse = db_tdb_traverse; result->traverse_read = db_tdb_traverse_read; + result->parse_record = db_tdb_parse; result->get_seqnum = db_tdb_get_seqnum; result->get_flags = db_tdb_get_flags; result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0); diff --git a/source3/lib/display_sec.c b/source3/lib/display_sec.c index 636639c11d..fe1ae77edd 100644 --- a/source3/lib/display_sec.c +++ b/source3/lib/display_sec.c @@ -155,13 +155,13 @@ void display_sec_ace_flags(uint8_t flags) ****************************************************************************/ static void disp_sec_ace_object(struct security_ace_object *object) { - if (object->flags & SEC_ACE_OBJECT_PRESENT) { - printf("Object type: SEC_ACE_OBJECT_PRESENT\n"); + if (object->flags & SEC_ACE_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_OBJECT_TYPE_PRESENT\n"); printf("Object GUID: %s\n", GUID_string(talloc_tos(), &object->type.type)); } - if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { - printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n"); + if (object->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT\n"); printf("Object GUID: %s\n", GUID_string(talloc_tos(), &object->inherited_type.inherited_type)); } diff --git a/source3/lib/events.c b/source3/lib/events.c index 44b4562757..f875e0dc0c 100644 --- a/source3/lib/events.c +++ b/source3/lib/events.c @@ -282,12 +282,13 @@ static void s3_event_debug(void *context, enum tevent_debug_level level, samba_level = 2; break; case TEVENT_DEBUG_TRACE: - samba_level = 5; + samba_level = 10; break; }; - vasprintf(&s, fmt, ap); - if (!s) return; + if (vasprintf(&s, fmt, ap) == -1) { + return; + } DEBUG(samba_level, ("s3_event: %s", s)); free(s); } diff --git a/source3/lib/fault.c b/source3/lib/fault.c index 8c4a45bbc9..efd1dddfd4 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. Critical Fault handling Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Tim Prouty 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -87,6 +88,128 @@ void fault_setup(void (*fn)(void *)) #endif } +/** + * Build up the default corepath as "<logbase>/cores/<progname>" + */ +static char *get_default_corepath(const char *logbase, const char *progname) +{ + char *tmp_corepath; + + /* Setup core dir in logbase. */ + tmp_corepath = talloc_asprintf(NULL, "%s/cores", logbase); + if (!tmp_corepath) + return NULL; + + if ((mkdir(tmp_corepath, 0700) == -1) && errno != EEXIST) + goto err_out; + + if (chmod(tmp_corepath, 0700) == -1) + goto err_out; + + talloc_free(tmp_corepath); + + /* Setup progname-specific core subdir */ + tmp_corepath = talloc_asprintf(NULL, "%s/cores/%s", logbase, progname); + if (!tmp_corepath) + return NULL; + + if (mkdir(tmp_corepath, 0700) == -1 && errno != EEXIST) + goto err_out; + + if (chown(tmp_corepath, getuid(), getgid()) == -1) + goto err_out; + + if (chmod(tmp_corepath, 0700) == -1) + goto err_out; + + return tmp_corepath; + + err_out: + talloc_free(tmp_corepath); + return NULL; +} + +/** + * Get the FreeBSD corepath. + * + * On FreeBSD the current working directory is ignored when creating a core + * file. Instead the core directory is controlled via sysctl. This consults + * the value of "kern.corefile" so the correct corepath can be printed out + * before dump_core() calls abort. + */ +#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME)) +static char *get_freebsd_corepath(void) +{ + char *tmp_corepath = NULL; + char *end = NULL; + size_t len = 128; + int ret; + + /* Loop with increasing sizes so we don't allocate too much. */ + do { + if (len > 1024) { + goto err_out; + } + + tmp_corepath = (char *)talloc_realloc(NULL, tmp_corepath, + char, len); + if (!tmp_corepath) { + return NULL; + } + + ret = sysctlbyname("kern.corefile", tmp_corepath, &len, NULL, + 0); + if (ret == -1) { + if (errno != ENOMEM) { + DEBUG(0, ("sysctlbyname failed getting " + "kern.corefile %s\n", + strerror(errno))); + goto err_out; + } + + /* Not a large enough array, try a bigger one. */ + len = len << 1; + } + } while (ret == -1); + + /* Strip off the common filename expansion */ + if ((end = strrchr_m(tmp_corepath, '/'))) { + *end = '\0'; + } + + return tmp_corepath; + + err_out: + if (tmp_corepath) { + talloc_free(tmp_corepath); + } + return NULL; +} +#endif + +/** + * Try getting system-specific corepath if one exists. + * + * If the system doesn't define a corepath, then the default is used. + */ +static char *get_corepath(const char *logbase, const char *progname) +{ + char *tmp_corepath = NULL; + + /* @todo: Add support for the linux corepath. */ +#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME)) + tmp_corepath = get_freebsd_corepath(); +#endif + + /* If this has been set correctly, we're done. */ + if (tmp_corepath) { + return tmp_corepath; + } + + /* Fall back to the default. */ + return get_default_corepath(logbase, progname); +} + /******************************************************************* make all the preparations to safely dump a core file ********************************************************************/ @@ -104,7 +227,7 @@ void dump_core_setup(const char *progname) *end = '\0'; } } else { - /* We will end up here is the log file is given on the command + /* We will end up here if the log file is given on the command * line by the -l option but the "log file" option is not set * in smb.conf. */ @@ -115,49 +238,13 @@ void dump_core_setup(const char *progname) SMB_ASSERT(progname != NULL); - if (asprintf(&corepath, "%s/cores", logbase) < 0) { - SAFE_FREE(logbase); - return; - } - if (mkdir(corepath,0700) == -1) { - if (errno != EEXIST) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; - } - } - if (chmod(corepath,0700) == -1) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; - } - - SAFE_FREE(corepath); - if (asprintf(&corepath, "%s/cores/%s", - logbase, progname) < 0) { - SAFE_FREE(logbase); - return; - } - if (mkdir(corepath,0700) == -1) { - if (errno != EEXIST) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; - } - } - - if (chown(corepath,getuid(),getgid()) == -1) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; - } - if (chmod(corepath,0700) == -1) { - SAFE_FREE(corepath); - SAFE_FREE(logbase); - return; + corepath = get_corepath(logbase, progname); + if (!corepath) { + DEBUG(0, ("Unable to setup corepath for %s: %s\n", progname, + strerror(errno))); + goto out; } - SAFE_FREE(logbase); #ifdef HAVE_GETRLIMIT #ifdef RLIMIT_CORE @@ -184,6 +271,8 @@ void dump_core_setup(const char *progname) /* FIXME: if we have a core-plus-pid facility, configurably set * this up here. */ + out: + SAFE_FREE(logbase); } void dump_core(void) diff --git a/source3/lib/iconv.c b/source3/lib/iconv.c index 3ceb637b8e..44500542f2 100644 --- a/source3/lib/iconv.c +++ b/source3/lib/iconv.c @@ -207,12 +207,12 @@ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode) from = charsets; to = charsets; - ret = SMB_MALLOC_P(struct _smb_iconv_t); + ret = SMB_MALLOC_P(struct smb_iconv_s); if (!ret) { errno = ENOMEM; return (smb_iconv_t)-1; } - memset(ret, 0, sizeof(struct _smb_iconv_t)); + memset(ret, 0, sizeof(struct smb_iconv_s)); ret->from_name = SMB_STRDUP(fromcode); ret->to_name = SMB_STRDUP(tocode); diff --git a/source3/lib/secace.c b/source3/lib/secace.c deleted file mode 100644 index 878fac252b..0000000000 --- a/source3/lib/secace.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Unix SMB/Netbios implementation. - * SEC_ACE handling functions - * Copyright (C) Andrew Tridgell 1992-1998, - * Copyright (C) Jeremy R. Allison 1995-2003. - * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - * Copyright (C) Paul Ashton 1997-1998. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "includes.h" - -/******************************************************************* - Check if ACE has OBJECT type. -********************************************************************/ - -bool sec_ace_object(uint8 type) -{ - if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || - type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || - type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || - type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) { - return True; - } - return False; -} - -/******************************************************************* - copy a SEC_ACE structure. -********************************************************************/ -void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src) -{ - ace_dest->type = ace_src->type; - ace_dest->flags = ace_src->flags; - ace_dest->size = ace_src->size; - ace_dest->access_mask = ace_src->access_mask; - ace_dest->object = ace_src->object; - sid_copy(&ace_dest->trustee, &ace_src->trustee); -} - -/******************************************************************* - Sets up a SEC_ACE structure. -********************************************************************/ - -void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, enum security_ace_type type, - uint32_t mask, uint8 flag) -{ - t->type = type; - t->flags = flag; - t->size = ndr_size_dom_sid(sid, NULL, 0) + 8; - t->access_mask = mask; - - ZERO_STRUCTP(&t->trustee); - sid_copy(&t->trustee, sid); -} - -/******************************************************************* - adds new SID with its permissions to ACE list -********************************************************************/ - -NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask) -{ - unsigned int i = 0; - - if (!ctx || !pp_new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER; - - *num += 1; - - if((pp_new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0) - return NT_STATUS_NO_MEMORY; - - for (i = 0; i < *num - 1; i ++) - sec_ace_copy(&(*pp_new)[i], &old[i]); - - (*pp_new)[i].type = SEC_ACE_TYPE_ACCESS_ALLOWED; - (*pp_new)[i].flags = 0; - (*pp_new)[i].size = SEC_ACE_HEADER_SIZE + ndr_size_dom_sid(sid, NULL, 0); - (*pp_new)[i].access_mask = mask; - sid_copy(&(*pp_new)[i].trustee, sid); - return NT_STATUS_OK; -} - -/******************************************************************* - modify SID's permissions at ACL -********************************************************************/ - -NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask) -{ - unsigned int i = 0; - - if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER; - - for (i = 0; i < num; i ++) { - if (sid_compare(&ace[i].trustee, sid) == 0) { - ace[i].access_mask = mask; - return NT_STATUS_OK; - } - } - return NT_STATUS_NOT_FOUND; -} - -/******************************************************************* - delete SID from ACL -********************************************************************/ - -NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, uint32 *num, DOM_SID *sid) -{ - unsigned int i = 0; - unsigned int n_del = 0; - - if (!ctx || !pp_new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER; - - if (*num) { - if((pp_new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0) - return NT_STATUS_NO_MEMORY; - } else { - pp_new[0] = NULL; - } - - for (i = 0; i < *num; i ++) { - if (sid_compare(&old[i].trustee, sid) != 0) - sec_ace_copy(&(*pp_new)[i], &old[i]); - else - n_del ++; - } - if (n_del == 0) - return NT_STATUS_NOT_FOUND; - else { - *num -= n_del; - return NT_STATUS_OK; - } -} - -/******************************************************************* - Compares two SEC_ACE structures -********************************************************************/ - -bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2) -{ - /* Trivial case */ - - if (!s1 && !s2) { - return True; - } - - if (!s1 || !s2) { - return False; - } - - /* Check top level stuff */ - - if (s1->type != s2->type || s1->flags != s2->flags || - s1->access_mask != s2->access_mask) { - return False; - } - - /* Check SID */ - - if (!sid_equal(&s1->trustee, &s2->trustee)) { - return False; - } - - return True; -} - -int nt_ace_inherit_comp( SEC_ACE *a1, SEC_ACE *a2) -{ - int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE; - int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE; - - if (a1_inh == a2_inh) - return 0; - - if (!a1_inh && a2_inh) - return -1; - return 1; -} - -/******************************************************************* - Comparison function to apply the order explained below in a group. -*******************************************************************/ - -int nt_ace_canon_comp( SEC_ACE *a1, SEC_ACE *a2) -{ - if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) && - (a2->type != SEC_ACE_TYPE_ACCESS_DENIED)) - return -1; - - if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) && - (a1->type != SEC_ACE_TYPE_ACCESS_DENIED)) - return 1; - - /* Both access denied or access allowed. */ - - /* 1. ACEs that apply to the object itself */ - - if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) && - (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY)) - return -1; - else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) && - (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY)) - return 1; - - /* 2. ACEs that apply to a subobject of the object, such as - * a property set or property. */ - - if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) && - !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT))) - return -1; - else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) && - !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT))) - return 1; - - return 0; -} - -/******************************************************************* - Functions to convert a SEC_DESC ACE DACL list into canonical order. - JRA. - ---- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp - -The following describes the preferred order: - - To ensure that noninherited ACEs have precedence over inherited ACEs, - place all noninherited ACEs in a group before any inherited ACEs. - This ordering ensures, for example, that a noninherited access-denied ACE - is enforced regardless of any inherited ACE that allows access. - - Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows: - 1. Access-denied ACEs that apply to the object itself - 2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property - 3. Access-allowed ACEs that apply to the object itself - 4. Access-allowed ACEs that apply to a subobject of the object" - -********************************************************************/ - -void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces) -{ - unsigned int i; - - if (!srclist || num_aces == 0) - return; - - /* Sort so that non-inherited ACE's come first. */ - qsort( srclist, num_aces, sizeof(srclist[0]), QSORT_CAST nt_ace_inherit_comp); - - /* Find the boundary between non-inherited ACEs. */ - for (i = 0; i < num_aces; i++ ) { - SEC_ACE *curr_ace = &srclist[i]; - - if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE) - break; - } - - /* i now points at entry number of the first inherited ACE. */ - - /* Sort the non-inherited ACEs. */ - if (i) - qsort( srclist, i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp); - - /* Now sort the inherited ACEs. */ - if (num_aces - i) - qsort( &srclist[i], num_aces - i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp); -} - -/******************************************************************* - Check if this ACE has a SID in common with the token. -********************************************************************/ - -bool token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace) -{ - size_t i; - - for (i = 0; i < token->num_sids; i++) { - if (sid_equal(&ace->trustee, &token->user_sids[i])) - return True; - } - - return False; -} diff --git a/source3/lib/secacl.c b/source3/lib/secacl.c deleted file mode 100644 index 5e82242e1b..0000000000 --- a/source3/lib/secacl.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Unix SMB/Netbios implementation. - * SEC_ACL handling routines - * Copyright (C) Andrew Tridgell 1992-1998, - * Copyright (C) Jeremy R. Allison 1995-2003. - * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - * Copyright (C) Paul Ashton 1997-1998. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "includes.h" - -/******************************************************************* - Create a SEC_ACL structure. -********************************************************************/ - -SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, enum security_acl_revision revision, - int num_aces, SEC_ACE *ace_list) -{ - SEC_ACL *dst; - int i; - - if((dst = TALLOC_ZERO_P(ctx,SEC_ACL)) == NULL) - return NULL; - - dst->revision = revision; - dst->num_aces = num_aces; - dst->size = SEC_ACL_HEADER_SIZE; - - /* Now we need to return a non-NULL address for the ace list even - if the number of aces required is zero. This is because there - is a distinct difference between a NULL ace and an ace with zero - entries in it. This is achieved by checking that num_aces is a - positive number. */ - - if ((num_aces) && - ((dst->aces = TALLOC_ARRAY(ctx, SEC_ACE, num_aces)) - == NULL)) { - return NULL; - } - - for (i = 0; i < num_aces; i++) { - dst->aces[i] = ace_list[i]; /* Structure copy. */ - dst->size += ace_list[i].size; - } - - return dst; -} - -/******************************************************************* - Duplicate a SEC_ACL structure. -********************************************************************/ - -SEC_ACL *dup_sec_acl(TALLOC_CTX *ctx, SEC_ACL *src) -{ - if(src == NULL) - return NULL; - - return make_sec_acl(ctx, src->revision, src->num_aces, src->aces); -} - -/******************************************************************* - Compares two SEC_ACL structures -********************************************************************/ - -bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2) -{ - unsigned int i, j; - - /* Trivial cases */ - - if (!s1 && !s2) return True; - if (!s1 || !s2) return False; - - /* Check top level stuff */ - - if (s1->revision != s2->revision) { - DEBUG(10, ("sec_acl_equal(): revision differs (%d != %d)\n", - s1->revision, s2->revision)); - return False; - } - - if (s1->num_aces != s2->num_aces) { - DEBUG(10, ("sec_acl_equal(): num_aces differs (%d != %d)\n", - s1->revision, s2->revision)); - return False; - } - - /* The ACEs could be in any order so check each ACE in s1 against - each ACE in s2. */ - - for (i = 0; i < s1->num_aces; i++) { - bool found = False; - - for (j = 0; j < s2->num_aces; j++) { - if (sec_ace_equal(&s1->aces[i], &s2->aces[j])) { - found = True; - break; - } - } - - if (!found) return False; - } - - return True; -} diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index e36fa8a2a1..ae6a41151d 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -23,7 +23,7 @@ #define INCLUDES_VALNAME "includes" struct reg_private_data { - NT_USER_TOKEN *token; + struct registry_key *base_key; bool open; /* did _we_ open the registry? */ }; @@ -72,54 +72,6 @@ static bool smbconf_reg_valname_valid(const char *valname) } /** - * Open a registry key specified by "path" - */ -static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx, - struct smbconf_ctx *ctx, - const char *path, - uint32 desired_access, - struct registry_key **key) -{ - WERROR werr = WERR_OK; - - if (ctx == NULL) { - DEBUG(1, ("Error: configuration is not open!\n")); - werr = WERR_INVALID_PARAM; - goto done; - } - - if (rpd(ctx)->token == NULL) { - DEBUG(1, ("Error: token missing from smbconf_ctx. " - "was smbconf_init() called?\n")); - werr = WERR_INVALID_PARAM; - goto done; - } - - werr = ctx->ops->open_conf(ctx); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(1, ("Error opening the registry.\n")); - goto done; - } - - if (path == NULL) { - DEBUG(1, ("Error: NULL path string given\n")); - werr = WERR_INVALID_PARAM; - goto done; - } - - werr = reg_open_path(mem_ctx, path, desired_access, rpd(ctx)->token, - key); - - if (!W_ERROR_IS_OK(werr)) { - DEBUG(5, ("Error opening registry path '%s': %s\n", - path, win_errstr(werr))); - } - -done: - return werr; -} - -/** * Open a subkey of the base key (i.e a service) */ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx, @@ -128,40 +80,23 @@ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx, uint32 desired_access, struct registry_key **key) { - WERROR werr = WERR_OK; - char *path = NULL; + WERROR werr; if (servicename == NULL) { - path = talloc_strdup(mem_ctx, ctx->path); - } else { - path = talloc_asprintf(mem_ctx, "%s\\%s", ctx->path, - servicename); - } - if (path == NULL) { - werr = WERR_NOMEM; - goto done; + *key = rpd(ctx)->base_key; + return WERR_OK; } + werr = reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename, + desired_access, key); - werr = smbconf_reg_open_path(mem_ctx, ctx, path, desired_access, key); + if (W_ERROR_EQUAL(werr, WERR_BADFILE)) { + werr = WERR_NO_SUCH_SERVICE; + } -done: - talloc_free(path); return werr; } /** - * open the base key - */ -static WERROR smbconf_reg_open_base_key(TALLOC_CTX *mem_ctx, - struct smbconf_ctx *ctx, - uint32 desired_access, - struct registry_key **key) -{ - return smbconf_reg_open_path(mem_ctx, ctx, ctx->path, desired_access, - key); -} - -/** * check if a value exists in a given registry key */ static bool smbconf_value_exists(struct registry_key *key, const char *param) @@ -189,7 +124,6 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, struct registry_key **newkey) { WERROR werr = WERR_OK; - struct registry_key *create_parent = NULL; TALLOC_CTX *create_ctx; enum winreg_CreateAction action = REG_ACTION_NONE; @@ -198,13 +132,7 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, * and will be destroyed when leaving this function... */ create_ctx = talloc_stackframe(); - werr = smbconf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE, - &create_parent); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - werr = reg_createkey(mem_ctx, create_parent, subkeyname, + werr = reg_createkey(mem_ctx, rpd(ctx)->base_key, subkeyname, REG_KEY_WRITE, newkey, &action); if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) { DEBUG(10, ("Key '%s' already exists.\n", subkeyname)); @@ -215,7 +143,6 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, subkeyname, win_errstr(werr))); } -done: talloc_free(create_ctx); return werr; } @@ -608,6 +535,7 @@ done: static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) { WERROR werr = WERR_OK; + struct nt_user_token *token; if (path == NULL) { path = KEY_SMBCONF; @@ -620,8 +548,7 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) ctx->data = TALLOC_ZERO_P(ctx, struct reg_private_data); - werr = ntstatus_to_werror(registry_create_admin_token(ctx, - &(rpd(ctx)->token))); + werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token)); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("Error creating admin token\n")); goto done; @@ -633,6 +560,19 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path) goto done; } + werr = ctx->ops->open_conf(ctx); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("Error opening the registry.\n")); + goto done; + } + + werr = reg_open_path(ctx, ctx->path, + SEC_RIGHTS_ENUM_SUBKEYS | REG_KEY_WRITE, + token, &rpd(ctx)->base_key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + done: return werr; } @@ -723,6 +663,13 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx) struct registry_key *new_key = NULL; TALLOC_CTX* mem_ctx = talloc_stackframe(); enum winreg_CreateAction action; + struct nt_user_token *token; + + werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token)); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("Error creating admin token\n")); + goto done; + } path = talloc_strdup(mem_ctx, ctx->path); if (path == NULL) { @@ -731,8 +678,8 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx) } p = strrchr(path, '\\'); *p = '\0'; - werr = smbconf_reg_open_path(mem_ctx, ctx, path, REG_KEY_WRITE, - &parent_key); + werr = reg_open_path(mem_ctx, path, REG_KEY_WRITE, token, + &parent_key); if (!W_ERROR_IS_OK(werr)) { goto done; @@ -765,7 +712,6 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, uint32_t added_count = 0; TALLOC_CTX *tmp_ctx = NULL; WERROR werr = WERR_OK; - struct registry_key *key = NULL; char *subkey_name = NULL; char **tmp_share_names = NULL; @@ -777,13 +723,8 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, tmp_ctx = talloc_stackframe(); /* if there are values in the base key, return NULL as share name */ - werr = smbconf_reg_open_base_key(tmp_ctx, ctx, - SEC_RIGHTS_ENUM_SUBKEYS, &key); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - if (smbconf_reg_key_has_values(key)) { + if (smbconf_reg_key_has_values(rpd(ctx)->base_key)) { werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names, 0, NULL); if (!W_ERROR_IS_OK(werr)) { @@ -803,7 +744,8 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx, } for (count = 0; - werr = reg_enumkey(tmp_ctx, key, count, &subkey_name, NULL), + werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count, + &subkey_name, NULL), W_ERROR_IS_OK(werr); count++) { @@ -865,18 +807,16 @@ static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx, const char *servicename) { WERROR werr; - TALLOC_CTX *mem_ctx = talloc_stackframe(); struct registry_key *key = NULL; if (servicename == NULL) { - werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, - &key); - } else { - werr = smbconf_reg_create_service_key(mem_ctx, ctx, - servicename, &key); + return WERR_OK; } - talloc_free(mem_ctx); + werr = smbconf_reg_create_service_key(talloc_tos(), ctx, + servicename, &key); + + talloc_free(key); return werr; } @@ -934,21 +874,15 @@ static WERROR smbconf_reg_delete_share(struct smbconf_ctx *ctx, const char *servicename) { WERROR werr = WERR_OK; - struct registry_key *key = NULL; TALLOC_CTX *mem_ctx = talloc_stackframe(); - werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, &key); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - if (servicename != NULL) { - werr = reg_deletekey_recursive(key, key, servicename); + werr = reg_deletekey_recursive(mem_ctx, rpd(ctx)->base_key, + servicename); } else { - werr = smbconf_reg_delete_values(key); + werr = smbconf_reg_delete_values(rpd(ctx)->base_key); } -done: talloc_free(mem_ctx); return werr; } @@ -1137,6 +1071,21 @@ done: return werr; } +static WERROR smbconf_reg_transaction_start(struct smbconf_ctx *ctx) +{ + return regdb_transaction_start(); +} + +static WERROR smbconf_reg_transaction_commit(struct smbconf_ctx *ctx) +{ + return regdb_transaction_commit(); +} + +static WERROR smbconf_reg_transaction_cancel(struct smbconf_ctx *ctx) +{ + return regdb_transaction_cancel(); +} + struct smbconf_ops smbconf_ops_reg = { .init = smbconf_reg_init, .shutdown = smbconf_reg_shutdown, @@ -1157,6 +1106,9 @@ struct smbconf_ops smbconf_ops_reg = { .get_includes = smbconf_reg_get_includes, .set_includes = smbconf_reg_set_includes, .delete_includes = smbconf_reg_delete_includes, + .transaction_start = smbconf_reg_transaction_start, + .transaction_commit = smbconf_reg_transaction_commit, + .transaction_cancel = smbconf_reg_transaction_cancel, }; diff --git a/source3/lib/util.c b/source3/lib/util.c index 89f7be8e6c..ec794ca74e 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -899,13 +899,6 @@ bool reinit_after_fork(struct messaging_context *msg_ctx, * numbers as each other */ set_need_random_reseed(); -#ifdef WITH_MADVISE_PROTECTED - /* Protect parent process from being killed by kernel when system - * memory is low. Child processes can still be killed */ - if(!parent_longlived) - madvise(NULL,0,MADV_PROTECT); -#endif - /* tdb needs special fork handling */ if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) { DEBUG(0,("tdb_reopen_all failed.\n")); diff --git a/source3/lib/util_nttoken.c b/source3/lib/util_nttoken.c index 774ef498b7..76e7402422 100644 --- a/source3/lib/util_nttoken.c +++ b/source3/lib/util_nttoken.c @@ -115,3 +115,19 @@ NTSTATUS merge_nt_token(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } + +/******************************************************************* + Check if this ACE has a SID in common with the token. +********************************************************************/ + +bool token_sid_in_ace(const NT_USER_TOKEN *token, const struct security_ace *ace) +{ + size_t i; + + for (i = 0; i < token->num_sids; i++) { + if (sid_equal(&ace->trustee, &token->user_sids[i])) + return true; + } + + return false; +} diff --git a/source3/lib/util_reg_api.c b/source3/lib/util_reg_api.c index 8f28e9c282..9313193f10 100644 --- a/source3/lib/util_reg_api.c +++ b/source3/lib/util_reg_api.c @@ -92,7 +92,7 @@ WERROR registry_pull_value(TALLOC_CTX *mem_ctx, } if (!convert_string_talloc(value, CH_UTF16LE, CH_UNIX, tmp, - length+2, &value->v.sz.str, + length+2, (void **)&value->v.sz.str, &value->v.sz.len, False)) { SAFE_FREE(tmp); err = WERR_INVALID_PARAM; diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 83e8a9d355..3604be369f 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -967,20 +967,20 @@ static int open_socket_out_state_destructor(struct open_socket_out_state *s) Create an outgoing socket. timeout is in milliseconds. **************************************************************************/ -struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const struct sockaddr_storage *pss, - uint16_t port, - int timeout) +struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const struct sockaddr_storage *pss, + uint16_t port, + int timeout) { char addr[INET6_ADDRSTRLEN]; - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *result, *subreq; struct open_socket_out_state *state; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct open_socket_out_state)) { + result = tevent_req_create(mem_ctx, &state, + struct open_socket_out_state); + if (result == NULL) { return NULL; } state->ev = ev; @@ -996,7 +996,8 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, } talloc_set_destructor(state, open_socket_out_state_destructor); - if (!async_req_set_timeout(result, ev, timeval_set(0, timeout*1000))) { + if (!tevent_req_set_endtime( + result, ev, timeval_current_ofs(0, timeout*1000))) { goto fail; } @@ -1030,18 +1031,14 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, || !tevent_req_set_endtime( subreq, state->ev, timeval_current_ofs(0, state->wait_nsec))) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - subreq->async.fn = open_socket_out_connected; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, open_socket_out_connected, result); return result; post_status: - if (!async_post_ntstatus(result, ev, status)) { - goto fail; - } - return result; + tevent_req_nterror(result, status); + return tevent_req_post(result, ev); fail: TALLOC_FREE(result); return NULL; @@ -1049,17 +1046,17 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx, static void open_socket_out_connected(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); - struct open_socket_out_state *state = talloc_get_type_abort( - req->private_data, struct open_socket_out_state); + struct tevent_req *req = + tevent_req_callback_data(subreq, struct tevent_req); + struct open_socket_out_state *state = + tevent_req_data(req, struct open_socket_out_state); int ret; int sys_errno; ret = async_connect_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == 0) { - async_req_done(req); + tevent_req_done(req); return; } @@ -1082,39 +1079,38 @@ static void open_socket_out_connected(struct tevent_req *subreq) subreq = async_connect_send(state, state->ev, state->fd, (struct sockaddr *)&state->ss, state->salen); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } if (!tevent_req_set_endtime( subreq, state->ev, timeval_current_ofs(0, state->wait_nsec))) { - async_req_error(req, ENOMEM); + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } - subreq->async.fn = open_socket_out_connected; - subreq->async.private_data = req; + tevent_req_set_callback(subreq, open_socket_out_connected, req); return; } #ifdef EISCONN if (sys_errno == EISCONN) { - async_req_done(req); + tevent_req_done(req); return; } #endif /* real error */ - async_req_error(req, sys_errno); + tevent_req_nterror(req, map_nt_error_from_unix(sys_errno)); } -NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd) +NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd) { - struct open_socket_out_state *state = talloc_get_type_abort( - req->private_data, struct open_socket_out_state); - int err; + struct open_socket_out_state *state = + tevent_req_data(req, struct open_socket_out_state); + NTSTATUS status; - if (async_req_is_errno(req, &err)) { - return map_nt_error_from_unix(err); + if (tevent_req_is_nterror(req, &status)) { + return status; } *pfd = state->fd; state->fd = -1; @@ -1126,7 +1122,7 @@ NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port, { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; - struct async_req *req; + struct tevent_req *req; NTSTATUS status = NT_STATUS_NO_MEMORY; ev = event_context_init(frame); @@ -1138,10 +1134,10 @@ NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port, if (req == NULL) { goto fail; } - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); + if (!tevent_req_poll(req, ev)) { + status = NT_STATUS_INTERNAL_ERROR; + goto fail; } - status = open_socket_out_recv(req, pfd); fail: TALLOC_FREE(frame); @@ -1157,7 +1153,7 @@ struct open_socket_out_defer_state { }; static void open_socket_out_defer_waited(struct async_req *subreq); -static void open_socket_out_defer_connected(struct async_req *subreq); +static void open_socket_out_defer_connected(struct tevent_req *subreq); struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx, struct event_context *ev, @@ -1204,6 +1200,7 @@ static void open_socket_out_defer_waited(struct async_req *subreq) subreq->async.priv, struct async_req); struct open_socket_out_defer_state *state = talloc_get_type_abort( req->private_data, struct open_socket_out_defer_state); + struct tevent_req *subreq2; bool ret; ret = async_wait_recv(subreq); @@ -1213,19 +1210,18 @@ static void open_socket_out_defer_waited(struct async_req *subreq) return; } - subreq = open_socket_out_send(state, state->ev, &state->ss, - state->port, state->timeout); - if (async_req_nomem(subreq, req)) { + subreq2 = open_socket_out_send(state, state->ev, &state->ss, + state->port, state->timeout); + if (async_req_nomem(subreq2, req)) { return; } - subreq->async.fn = open_socket_out_defer_connected; - subreq->async.priv = req; + tevent_req_set_callback(subreq2, open_socket_out_defer_connected, req); } -static void open_socket_out_defer_connected(struct async_req *subreq) +static void open_socket_out_defer_connected(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct open_socket_out_defer_state *state = talloc_get_type_abort( req->private_data, struct open_socket_out_defer_state); NTSTATUS status; diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 9358061797..b9ccb83e55 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -36,118 +36,6 @@ const char toupper_ascii_fast_table[128] = { }; /** - * @file - * @brief String utilities. - **/ - -static bool next_token_internal_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep, - bool ltrim) -{ - char *s; - char *saved_s; - char *pbuf; - bool quoted; - size_t len=1; - - *pp_buff = NULL; - if (!ptr) { - return(false); - } - - s = (char *)*ptr; - - /* default to simple separators */ - if (!sep) { - sep = " \t\n\r"; - } - - /* find the first non sep char, if left-trimming is requested */ - if (ltrim) { - while (*s && strchr_m(sep,*s)) { - s++; - } - } - - /* nothing left? */ - if (!*s) { - return false; - } - - /* When restarting we need to go from here. */ - saved_s = s; - - /* Work out the length needed. */ - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if (*s == '\"') { - quoted = !quoted; - } else { - len++; - } - } - - /* We started with len = 1 so we have space for the nul. */ - *pp_buff = TALLOC_ARRAY(ctx, char, len); - if (!*pp_buff) { - return false; - } - - /* copy over the token */ - pbuf = *pp_buff; - s = saved_s; - for (quoted = false; *s && - (quoted || !strchr_m(sep,*s)); s++) { - if ( *s == '\"' ) { - quoted = !quoted; - } else { - *pbuf++ = *s; - } - } - - *ptr = (*s) ? s+1 : s; - *pbuf = 0; - - return true; -} - -#if 0 -/* - * Get the next token from a string, return false if none found. Handles - * double-quotes. This version trims leading separator characters before - * looking for a token. - */ -bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize) -{ - return next_token_internal(ptr, buff, sep, bufsize, true); -} -#endif - -bool next_token_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true); -} - -/* - * Get the next token from a string, return false if none found. Handles - * double-quotes. This version does not trim leading separator characters - * before looking for a token. - */ - -bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, - const char **ptr, - char **pp_buff, - const char *sep) -{ - return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false); -} - -/** * Case insensitive string compararison. * * iconv does not directly give us a way to compare strings in diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c index a5adf8f108..222b64667c 100644 --- a/source3/lib/wb_reqtrans.c +++ b/source3/lib/wb_reqtrans.c @@ -103,8 +103,7 @@ struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx, goto nomem; } - subreq->async.fn = wb_req_read_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_req_read_done, result); return result; nomem: TALLOC_FREE(result); @@ -140,8 +139,8 @@ static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data) static void wb_req_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct req_read_state *state = talloc_get_type_abort( req->private_data, struct req_read_state); int err; @@ -213,8 +212,7 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = wb_req_write_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_req_write_done, result); return result; fail: @@ -224,8 +222,8 @@ struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx, static void wb_req_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); int err; ssize_t ret; @@ -266,8 +264,7 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto nomem; } - subreq->async.fn = wb_resp_read_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_resp_read_done, result); return result; nomem: @@ -288,13 +285,13 @@ static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data) return -1; } } - return resp->length - 4; + return resp->length - buflen; } static void wb_resp_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct resp_read_state *state = talloc_get_type_abort( req->private_data, struct resp_read_state); uint8_t *buf; @@ -367,8 +364,7 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = wb_resp_write_done; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wb_resp_write_done, result); return result; fail: @@ -378,8 +374,8 @@ struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx, static void wb_resp_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); int err; ssize_t ret; diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c index b8d55a944a..7034e668ed 100644 --- a/source3/lib/wbclient.c +++ b/source3/lib/wbclient.c @@ -224,8 +224,7 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto nomem; } - subreq->async.fn = wbc_connect_connected; - subreq->async.private_data = result; + tevent_req_set_callback(subreq, wbc_connect_connected, result); if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) { goto nomem; @@ -245,8 +244,8 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx, static void wbc_connect_connected(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); int res, err; res = async_connect_recv(subreq, &err); diff --git a/source3/libads/disp_sec.c b/source3/libads/disp_sec.c index a5e04a4a6c..3bf0b6f7a7 100644 --- a/source3/libads/disp_sec.c +++ b/source3/libads/disp_sec.c @@ -112,15 +112,15 @@ static void ads_disp_sec_ace_object(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct security_ace_object *object) { - if (object->flags & SEC_ACE_OBJECT_PRESENT) { - printf("Object type: SEC_ACE_OBJECT_PRESENT\n"); + if (object->flags & SEC_ACE_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_OBJECT_TYPE_PRESENT\n"); printf("Object GUID: %s (%s)\n", GUID_string(mem_ctx, &object->type.type), ads_interprete_guid_from_object(ads, mem_ctx, &object->type.type)); } - if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) { - printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n"); + if (object->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { + printf("Object type: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT\n"); printf("Object GUID: %s (%s)\n", GUID_string(mem_ctx, &object->inherited_type.inherited_type), ads_interprete_guid_from_object(ads, mem_ctx, diff --git a/source3/libgpo/gpo_ini.c b/source3/libgpo/gpo_ini.c index aa8f7c7770..edca85530b 100644 --- a/source3/libgpo/gpo_ini.c +++ b/source3/libgpo/gpo_ini.c @@ -83,7 +83,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx, } if (!convert_string_talloc(mem_ctx, CH_UTF16LE, CH_UNIX, data_in, n, - &data_out, &converted_size, False)) + (void **)&data_out, &converted_size, False)) { status = NT_STATUS_INVALID_BUFFER_SIZE; goto out; diff --git a/source3/libgpo/gpo_sec.c b/source3/libgpo/gpo_sec.c index 42ab72a99b..c72bb26732 100644 --- a/source3/libgpo/gpo_sec.c +++ b/source3/libgpo/gpo_sec.c @@ -38,12 +38,12 @@ static bool gpo_sd_check_agp_object_guid(const struct security_ace_object *objec } switch (object->flags) { - case SEC_ACE_OBJECT_PRESENT: + case SEC_ACE_OBJECT_TYPE_PRESENT: if (GUID_equal(&object->type.type, &ext_right_apg_guid)) { return True; } - case SEC_ACE_OBJECT_INHERITED_PRESENT: + case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: if (GUID_equal(&object->inherited_type.inherited_type, &ext_right_apg_guid)) { return True; diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 20f7b97745..117178f376 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -50,12 +50,6 @@ #define LIBNET_UNJOIN_OUT_DUMP_CTX(ctx, r) \ LIBNET_UNJOIN_DUMP_CTX(ctx, r, NDR_OUT) -#define W_ERROR_NOT_OK_GOTO_DONE(x) do { \ - if (!W_ERROR_IS_OK(x)) {\ - goto done;\ - }\ -} while (0) - /**************************************************************** ****************************************************************/ diff --git a/source3/modules/gpfs.c b/source3/modules/gpfs.c index 16599005b9..9fc4524654 100644 --- a/source3/modules/gpfs.c +++ b/source3/modules/gpfs.c @@ -26,6 +26,7 @@ static bool gpfs_share_modes; static bool gpfs_leases; +static bool gpfs_getrealfilename; static int (*gpfs_set_share_fn)(int fd, unsigned int allow, unsigned int deny); static int (*gpfs_set_lease_fn)(int fd, unsigned int leaseType); @@ -139,7 +140,8 @@ int smbd_gpfs_putacl(char *pathname, int flags, void *acl) int smbd_gpfs_get_realfilename_path(char *pathname, char *filenamep, int *buflen) { - if (gpfs_get_realfilename_path_fn == NULL) { + if ((!gpfs_getrealfilename) + || (gpfs_get_realfilename_path_fn == NULL)) { errno = ENOSYS; return -1; } @@ -208,6 +210,8 @@ void init_gpfs(void) gpfs_share_modes = lp_parm_bool(-1, "gpfs", "sharemodes", True); gpfs_leases = lp_parm_bool(-1, "gpfs", "leases", True); + gpfs_getrealfilename = lp_parm_bool(-1, "gpfs", "getrealfilename", + True); return; } diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h index 418e13d9d2..ebeece40ad 100644 --- a/source3/modules/onefs.h +++ b/source3/modules/onefs.h @@ -21,112 +21,6 @@ #ifndef _ONEFS_H #define _ONEFS_H -#include "includes.h" -#include "oplock_onefs.h" -#include <sys/isi_acl.h> - -/* OneFS Module smb.conf parameters and defaults */ - -/** -* Specifies when ACLs presented to Windows should be canonicalized -* into the ordering which Explorer expects. -*/ -enum onefs_acl_wire_format -{ - ACL_FORMAT_RAW, /**< Never canonicalize */ - ACL_FORMAT_WINDOWS_SD, /**< Only canonicalize synthetic ACLs */ - ACL_FORMAT_ALWAYS /**< Always canonicalize */ -}; - -#define PARM_ONEFS_TYPE "onefs" -#define PARM_ACL_WIRE_FORMAT "acl wire format" -#define PARM_ACL_WIRE_FORMAT_DEFAULT ACL_FORMAT_WINDOWS_SD -#define PARM_ALLOW_EXECUTE_ALWAYS "allow execute always" -#define PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT false -#define PARM_ATIME_NOW "atime now files" -#define PARM_ATIME_NOW_DEFAULT NULL -#define PARM_ATIME_STATIC "atime static files" -#define PARM_ATIME_STATIC_DEFAULT NULL -#define PARM_ATIME_SLOP "atime now slop" -#define PARM_ATIME_SLOP_DEFAULT 0 -#define PARM_ATOMIC_SENDFILE "atomic sendfile" -#define PARM_ATOMIC_SENDFILE_DEFAULT true -#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control" -#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true -#define PARM_CTIME_NOW "ctime now files" -#define PARM_CTIME_NOW_DEFAULT NULL -#define PARM_CTIME_SLOP "ctime now slop" -#define PARM_CTIME_SLOP_DEFAULT 0 -#define PARM_IGNORE_SACLS "ignore sacls" -#define PARM_IGNORE_SACLS_DEFAULT false -#define PARM_MTIME_NOW "mtime now files" -#define PARM_MTIME_NOW_DEFAULT NULL -#define PARM_MTIME_STATIC "mtime static files" -#define PARM_MTIME_STATIC_DEFAULT NULL -#define PARM_MTIME_SLOP "mtime now slop" -#define PARM_MTIME_SLOP_DEFAULT 0 -#define PARM_USE_READDIRPLUS "use readdirplus" -#define PARM_USE_READDIRPLUS_DEFAULT true -#define PARM_SENDFILE_LARGE_READS "sendfile large reads" -#define PARM_SENDFILE_LARGE_READS_DEFAULT false -#define PARM_SENDFILE_SAFE "sendfile safe" -#define PARM_SENDFILE_SAFE_DEFAULT true -#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE "simple file sharing compatibility mode" -#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false -#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE "unmappable sids deny everyone" -#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT false -#define PARM_UNMAPPABLE_SIDS_IGNORE "ignore unmappable sids" -#define PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT false -#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST "unmappable sids ignore list" -#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT NULL - -#define IS_CTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->ctime_now_list,(conn)->case_sensitive)) -#define IS_MTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->mtime_now_list,(conn)->case_sensitive)) -#define IS_ATIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->atime_now_list,(conn)->case_sensitive)) -#define IS_MTIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->mtime_static_list,(conn)->case_sensitive)) -#define IS_ATIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ - (cfg)->atime_static_list,(conn)->case_sensitive)) - -/* - * Store some commonly evaluated parameters to avoid loadparm pain. - */ - -#define ONEFS_VFS_CONFIG_INITIALIZED 0x00010000 - -#define ONEFS_VFS_CONFIG_FAKETIMESTAMPS 0x00000001 - -struct onefs_vfs_config -{ - int32 init_flags; - - /* data for fake timestamps */ - int atime_slop; - int ctime_slop; - int mtime_slop; - - /* Per-share list of files to fake the create time for. */ - name_compare_entry *ctime_now_list; - - /* Per-share list of files to fake the modification time for. */ - name_compare_entry *mtime_now_list; - - /* Per-share list of files to fake the access time for. */ - name_compare_entry *atime_now_list; - - /* Per-share list of files to fake the modification time for. */ - name_compare_entry *mtime_static_list; - - /* The access time will equal the create time. */ - /* The modification time will equal the create time.*/ - - /* Per-share list of files to fake the access time for. */ - name_compare_entry *atime_static_list; -}; - /* * vfs interface handlers */ @@ -233,15 +127,13 @@ NTSTATUS onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, /* * Utility functions */ +struct ifs_security_descriptor; NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, struct ifs_security_descriptor *sd, int snum); NTSTATUS onefs_split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname, char **pbase, char **pstream); -bool onefs_get_config(int snum, int config_type, - struct onefs_vfs_config *cfg); - int onefs_rdp_add_dir_state(connection_struct *conn, SMB_STRUCT_DIR *dirp); /* diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 7bc4a1728f..6f23d608d4 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -19,10 +19,13 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" #include <isi_acl/isi_acl_util.h> #include <ifs/ifs_syscalls.h> +#include <sys/isi_acl.h> const struct enum_list enum_onefs_acl_wire_format[] = { {ACL_FORMAT_RAW, "No Format"}, @@ -273,9 +276,6 @@ onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl, if (aclu_initialize_acl(acl, aces, num_aces)) goto err_free; - if (aclu_initialize_acl(acl, aces, num_aces)) - goto err_free; - /* Currently aclu_initialize_acl should copy the aces over, allowing * us to immediately free */ free(aces); @@ -614,6 +614,8 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, bool fopened = false; NTSTATUS status = NT_STATUS_OK; + START_PROFILE(syscall_get_sd); + *ppdesc = NULL; DEBUG(5, ("Getting sd for file %s. security_info=%u\n", @@ -753,6 +755,9 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, DEBUG(5, ("Finished retrieving/canonicalizing SD!\n")); /* FALLTHROUGH */ out: + + END_PROFILE(syscall_get_sd); + if (alloced && sd) { if (new_aces_alloced && sd->dacl->aces) SAFE_FREE(sd->dacl->aces); @@ -888,18 +893,20 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) { struct ifs_security_descriptor sd = {}; - int fd; + int fd = -1; bool fopened = false; NTSTATUS status; + START_PROFILE(syscall_set_sd); + DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name )); status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd, SNUM(handle->conn)); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("SD initialization failure: %s", nt_errstr(status))); - return status; + DEBUG(3, ("SD initialization failure: %s\n", nt_errstr(status))); + goto out; } fd = fsp->fh->fd; @@ -938,6 +945,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, /* FALLTHROUGH */ out: + END_PROFILE(syscall_set_sd); + if (fopened) close(fd); diff --git a/source3/modules/onefs_cbrl.c b/source3/modules/onefs_cbrl.c index a860023764..7311e1961e 100644 --- a/source3/modules/onefs_cbrl.c +++ b/source3/modules/onefs_cbrl.c @@ -18,6 +18,7 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" #include <ifs/ifs_syscalls.h> @@ -255,6 +256,8 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, struct onefs_cbrl_blr_state *bs; NTSTATUS status; + START_PROFILE(syscall_brl_lock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type != UNLOCK_LOCK); @@ -301,10 +304,13 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, /* ASYNC still in progress: The process_* calls will keep * calling even if we haven't gotten the lock. Keep erroring * without calling ifs_cbrl, or getting/setting an id. */ - if (bs->state == ONEFS_CBRL_ASYNC) + if (bs->state == ONEFS_CBRL_ASYNC) { goto failure; - else if (bs->state == ONEFS_CBRL_ERROR) + } + else if (bs->state == ONEFS_CBRL_ERROR) { + END_PROFILE(syscall_brl_lock); return NT_STATUS_NO_MEMORY; + } SMB_ASSERT(bs->state == ONEFS_CBRL_NONE); async = true; @@ -343,6 +349,9 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, } failure: + + END_PROFILE(syscall_brl_lock); + /* Failure - error or async. */ plock->context.smbpid = (uint32) ONEFS_BLOCKING_PID; @@ -355,6 +364,9 @@ failure: return status; success: + + END_PROFILE(syscall_brl_lock); + /* Success. */ onefs_cbrl_enumerate_blq("onefs_brl_unlock_windows"); DEBUG(10, ("returning NT_STATUS_OK.\n")); @@ -371,6 +383,8 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, int error; int fd = br_lck->fsp->fh->fd; + START_PROFILE(syscall_brl_unlock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type == UNLOCK_LOCK); @@ -378,6 +392,9 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, 0, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_unlock); + if (error) { DEBUG(10, ("returning false.\n")); return false; @@ -404,6 +421,8 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, int fd = br_lck->fsp->fh->fd; struct onefs_cbrl_blr_state *bs; + START_PROFILE(syscall_brl_cancel); + SMB_ASSERT(plock); SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(blr); @@ -416,6 +435,7 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, if (bs->state == ONEFS_CBRL_DONE) { /* No-op. */ DEBUG(10, ("State=DONE, returning true\n")); + END_PROFILE(syscall_brl_cancel); return true; } @@ -427,6 +447,9 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, bs->id, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_cancel); + if (error) { DEBUG(10, ("returning false\n")); bs->state = ONEFS_CBRL_ERROR; diff --git a/source3/modules/onefs_config.c b/source3/modules/onefs_config.c new file mode 100644 index 0000000000..06f4b16ac1 --- /dev/null +++ b/source3/modules/onefs_config.c @@ -0,0 +1,276 @@ +/* + * Unix SMB/CIFS implementation. + * Support for OneFS + * + * Copyright (C) Todd Stecher, 2009 + * Copyright (C) Tim Prouty, 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "includes.h" +#include "onefs_config.h" + +#include <ifs/ifs_syscalls.h> + +#define ONEFS_DATA_FASTBUF 10 + +struct onefs_vfs_share_config vfs_share_config[ONEFS_DATA_FASTBUF]; +struct onefs_vfs_share_config *pvfs_share_config; + +static void onefs_load_faketimestamp_config(struct connection_struct *conn, + struct onefs_vfs_share_config *cfg) +{ + const char **parm; + int snum = SNUM(conn); + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW, + PARM_ATIME_NOW_DEFAULT); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->atime_now_list,*parm); + } + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_CTIME_NOW, + PARM_CTIME_NOW_DEFAULT); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->ctime_now_list,*parm); + } + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_NOW, + PARM_MTIME_NOW_DEFAULT); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->mtime_now_list,*parm); + } + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_STATIC, + PARM_ATIME_STATIC_DEFAULT); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->atime_static_list,*parm); + } + + parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_STATIC, + PARM_MTIME_STATIC_DEFAULT); + + if (parm) { + cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; + set_namearray(&cfg->mtime_static_list,*parm); + } + + cfg->atime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_ATIME_SLOP, + PARM_ATIME_SLOP_DEFAULT); + cfg->ctime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_CTIME_SLOP, + PARM_CTIME_SLOP_DEFAULT); + cfg->mtime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_MTIME_SLOP, + PARM_MTIME_SLOP_DEFAULT); +} + +/** + * Set onefs-specific vfs global config parameters. + * + * Since changes in these parameters require calling syscalls, we only want to + * call them when the configuration actually changes. + */ +static void onefs_load_global_config(connection_struct *conn) +{ + static struct onefs_vfs_global_config global_config; + bool dot_snap_child_accessible; + bool dot_snap_child_visible; + bool dot_snap_root_accessible; + bool dot_snap_root_visible; + bool dot_snap_tilde; + bool reconfig_dso = false; + bool reconfig_tilde = false; + + /* Check if this is the first time setting the config options. */ + if (!(global_config.init_flags & ONEFS_VFS_CONFIG_INITIALIZED)) { + global_config.init_flags |= ONEFS_VFS_CONFIG_INITIALIZED; + + /* Set process encoding */ + onefs_sys_config_enc(); + + reconfig_dso = true; + reconfig_tilde = true; + } + + /* Get the dot snap options from the conf. */ + dot_snap_child_accessible = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_CHILD_ACCESSIBLE, + PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT); + dot_snap_child_visible = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_CHILD_VISIBLE, + PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT); + dot_snap_root_accessible = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_ROOT_ACCESSIBLE, + PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT); + dot_snap_root_visible = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_ROOT_VISIBLE, + PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT); + dot_snap_tilde = + lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, + PARM_DOT_SNAP_TILDE, + PARM_DOT_SNAP_TILDE_DEFAULT); + + /* Check if any of the dot snap options need updating. */ + if (dot_snap_child_accessible != + global_config.dot_snap_child_accessible) { + global_config.dot_snap_child_accessible = + dot_snap_child_accessible; + reconfig_dso = true; + } + if (dot_snap_child_visible != + global_config.dot_snap_child_visible) { + global_config.dot_snap_child_visible = + dot_snap_child_visible; + reconfig_dso = true; + } + if (dot_snap_root_accessible != + global_config.dot_snap_root_accessible) { + global_config.dot_snap_root_accessible = + dot_snap_root_accessible; + reconfig_dso = true; + } + if (dot_snap_root_visible != + global_config.dot_snap_root_visible) { + global_config.dot_snap_root_visible = + dot_snap_root_visible; + reconfig_dso = true; + } + if (dot_snap_tilde != global_config.dot_snap_tilde) { + global_config.dot_snap_tilde = dot_snap_tilde; + reconfig_tilde = true; + } + + /* If a dot snap option has changed update the process. */ + if (reconfig_dso) { + onefs_sys_config_snap_opt(&global_config); + } + + /* If the dot snap tilde option has changed update the process. */ + if (reconfig_tilde) { + onefs_sys_config_tilde(&global_config); + } +} + +int onefs_load_config(connection_struct *conn) +{ + int snum = SNUM(conn); + int share_count = lp_numservices(); + + /* Share config */ + if (!pvfs_share_config) { + + if (share_count <= ONEFS_DATA_FASTBUF) + pvfs_share_config = vfs_share_config; + else { + pvfs_share_config = + SMB_MALLOC_ARRAY(struct onefs_vfs_share_config, + share_count); + if (!pvfs_share_config) { + errno = ENOMEM; + return -1; + } + + memset(pvfs_share_config, 0, + (sizeof(struct onefs_vfs_share_config) * + share_count)); + } + } + + if ((pvfs_share_config[snum].init_flags & + ONEFS_VFS_CONFIG_INITIALIZED) == 0) { + pvfs_share_config[snum].init_flags = + ONEFS_VFS_CONFIG_INITIALIZED; + onefs_load_faketimestamp_config(conn, + &pvfs_share_config[snum]); + } + + /* Global config */ + onefs_load_global_config(conn); + + return 0; +} + +bool onefs_get_config(int snum, int config_type, + struct onefs_vfs_share_config *cfg) +{ + if (vfs_share_config[snum].init_flags & config_type) + *cfg = vfs_share_config[snum]; + else + return false; + + return true; +} + + +/** + * Set the per-process encoding, ignoring errors. + */ +void onefs_sys_config_enc(void) +{ + int ret; + + ret = enc_set_proc(ENC_UTF8); + if (ret) { + DEBUG(0, ("Setting process encoding failed: %s", + strerror(errno))); + } +} + +/** + * Set the per-process .snpashot directory options, ignoring errors. + */ +void onefs_sys_config_snap_opt(struct onefs_vfs_global_config *global_config) +{ + struct ifs_dotsnap_options dso; + int ret; + + dso.per_proc = 1; + dso.sub_accessible = global_config->dot_snap_child_accessible; + dso.sub_visible = global_config->dot_snap_child_visible; + dso.root_accessible = global_config->dot_snap_root_accessible; + dso.root_visible = global_config->dot_snap_root_visible; + + ret = ifs_set_dotsnap_options(&dso); + if (ret) { + DEBUG(0, ("Setting snapshot visibility/accessibility " + "failed: %s", strerror(errno))); + } +} + +/** + * Set the per-process flag saying whether or not to accept ~snapshot + * as an alternative name for .snapshot directories. + */ +void onefs_sys_config_tilde(struct onefs_vfs_global_config *global_config) +{ + int ret; + + ret = ifs_tilde_snapshot(global_config->dot_snap_tilde); + if (ret) { + DEBUG(0, ("Setting snapshot tilde failed: %s", + strerror(errno))); + } +} diff --git a/source3/modules/onefs_config.h b/source3/modules/onefs_config.h new file mode 100644 index 0000000000..f0f48e6379 --- /dev/null +++ b/source3/modules/onefs_config.h @@ -0,0 +1,160 @@ +/* + * Unix SMB/CIFS implementation. + * OneFS vfs module configuration and defaults + * + * Copyright (C) Steven Danneman, 2008 + * Copyright (C) Tim Prouty, 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _ONEFS_CONFIG_H +#define _ONEFS_CONFIG_H + +/** +* Specifies when ACLs presented to Windows should be canonicalized +* into the ordering which Explorer expects. +*/ +enum onefs_acl_wire_format +{ + ACL_FORMAT_RAW, /**< Never canonicalize */ + ACL_FORMAT_WINDOWS_SD, /**< Only canonicalize synthetic ACLs */ + ACL_FORMAT_ALWAYS /**< Always canonicalize */ +}; + +#define PARM_ONEFS_TYPE "onefs" +#define PARM_ACL_WIRE_FORMAT "acl wire format" +#define PARM_ACL_WIRE_FORMAT_DEFAULT ACL_FORMAT_WINDOWS_SD +#define PARM_ALLOW_EXECUTE_ALWAYS "allow execute always" +#define PARM_ALLOW_EXECUTE_ALWAYS_DEFAULT false +#define PARM_ATIME_NOW "atime now files" +#define PARM_ATIME_NOW_DEFAULT NULL +#define PARM_ATIME_STATIC "atime static files" +#define PARM_ATIME_STATIC_DEFAULT NULL +#define PARM_ATIME_SLOP "atime now slop" +#define PARM_ATIME_SLOP_DEFAULT 0 +#define PARM_ATOMIC_SENDFILE "atomic sendfile" +#define PARM_ATOMIC_SENDFILE_DEFAULT true +#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL "creator owner gets full control" +#define PARM_CREATOR_OWNER_GETS_FULL_CONTROL_DEFAULT true +#define PARM_CTIME_NOW "ctime now files" +#define PARM_CTIME_NOW_DEFAULT NULL +#define PARM_CTIME_SLOP "ctime now slop" +#define PARM_CTIME_SLOP_DEFAULT 0 +#define PARM_DOT_SNAP_CHILD_ACCESSIBLE "dot snap child accessible" +#define PARM_DOT_SNAP_CHILD_ACCESSIBLE_DEFAULT true +#define PARM_DOT_SNAP_CHILD_VISIBLE "dot snap child visible" +#define PARM_DOT_SNAP_CHILD_VISIBLE_DEFAULT false +#define PARM_DOT_SNAP_ROOT_ACCESSIBLE "dot snap root accessible" +#define PARM_DOT_SNAP_ROOT_ACCESSIBLE_DEFAULT true +#define PARM_DOT_SNAP_ROOT_VISIBLE "dot snap root visible" +#define PARM_DOT_SNAP_ROOT_VISIBLE_DEFAULT true +#define PARM_DOT_SNAP_TILDE "dot snap tilde" +#define PARM_DOT_SNAP_TILDE_DEFAULT true +#define PARM_IGNORE_SACLS "ignore sacls" +#define PARM_IGNORE_SACLS_DEFAULT false +#define PARM_IGNORE_STREAMS "ignore streams" +#define PARM_IGNORE_STREAMS_DEFAULT false +#define PARM_MTIME_NOW "mtime now files" +#define PARM_MTIME_NOW_DEFAULT NULL +#define PARM_MTIME_STATIC "mtime static files" +#define PARM_MTIME_STATIC_DEFAULT NULL +#define PARM_MTIME_SLOP "mtime now slop" +#define PARM_MTIME_SLOP_DEFAULT 0 +#define PARM_USE_READDIRPLUS "use readdirplus" +#define PARM_USE_READDIRPLUS_DEFAULT true +#define PARM_SENDFILE_LARGE_READS "sendfile large reads" +#define PARM_SENDFILE_LARGE_READS_DEFAULT false +#define PARM_SENDFILE_SAFE "sendfile safe" +#define PARM_SENDFILE_SAFE_DEFAULT true +#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE "simple file sharing compatibility mode" +#define PARM_SIMPLE_FILE_SHARING_COMPATIBILITY_MODE_DEFAULT false +#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE "unmappable sids deny everyone" +#define PARM_UNMAPPABLE_SIDS_DENY_EVERYONE_DEFAULT false +#define PARM_UNMAPPABLE_SIDS_IGNORE "ignore unmappable sids" +#define PARM_UNMAPPABLE_SIDS_IGNORE_DEFAULT false +#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST "unmappable sids ignore list" +#define PARM_UNMAPPABLE_SIDS_IGNORE_LIST_DEFAULT NULL + +#define IS_CTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->ctime_now_list,(conn)->case_sensitive)) +#define IS_MTIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->mtime_now_list,(conn)->case_sensitive)) +#define IS_ATIME_NOW_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->atime_now_list,(conn)->case_sensitive)) +#define IS_MTIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->mtime_static_list,(conn)->case_sensitive)) +#define IS_ATIME_STATIC_PATH(conn,cfg,path) ((conn) && is_in_path((path),\ + (cfg)->atime_static_list,(conn)->case_sensitive)) + +/* + * Store some commonly evaluated parameters to avoid loadparm pain. + */ + +#define ONEFS_VFS_CONFIG_INITIALIZED 0x00010000 + +#define ONEFS_VFS_CONFIG_FAKETIMESTAMPS 0x00000001 + +struct onefs_vfs_share_config +{ + uint32_t init_flags; + + /* data for fake timestamps */ + int atime_slop; + int ctime_slop; + int mtime_slop; + + /* Per-share list of files to fake the create time for. */ + name_compare_entry *ctime_now_list; + + /* Per-share list of files to fake the modification time for. */ + name_compare_entry *mtime_now_list; + + /* Per-share list of files to fake the access time for. */ + name_compare_entry *atime_now_list; + + /* Per-share list of files to fake the modification time for. */ + name_compare_entry *mtime_static_list; + + /* The access time will equal the create time. */ + /* The modification time will equal the create time.*/ + + /* Per-share list of files to fake the access time for. */ + name_compare_entry *atime_static_list; +}; + +struct onefs_vfs_global_config +{ + uint32_t init_flags; + + /* Snapshot options */ + bool dot_snap_child_accessible; + bool dot_snap_child_visible; + bool dot_snap_root_accessible; + bool dot_snap_root_visible; + bool dot_snap_tilde; +}; + +int onefs_load_config(connection_struct *conn); + +bool onefs_get_config(int snum, int config_type, + struct onefs_vfs_share_config *cfg); + +void onefs_sys_config_enc(void); + +void onefs_sys_config_snap_opt(struct onefs_vfs_global_config *global_config); + +void onefs_sys_config_tilde(struct onefs_vfs_global_config *global_config); + +#endif /* _ONEFS_CONFIG_H */ diff --git a/source3/modules/onefs_dir.c b/source3/modules/onefs_dir.c index 83622b2bcd..68a58b3bb2 100644 --- a/source3/modules/onefs_dir.c +++ b/source3/modules/onefs_dir.c @@ -19,7 +19,9 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" #include <ifs/ifs_syscalls.h> diff --git a/source3/modules/onefs_notify.c b/source3/modules/onefs_notify.c index 40f690876d..3455afd4ab 100644 --- a/source3/modules/onefs_notify.c +++ b/source3/modules/onefs_notify.c @@ -33,6 +33,7 @@ * CompletionFilter and WatchTree of open SMB requests, and return notify * events back to the proper SMB requests */ +#include "includes.h" #include "onefs.h" #include <ifs/ifs_types.h> diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index 382ecc60a3..d3ba0ac979 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -32,7 +32,10 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" +#include "oplock_onefs.h" #include "smbd/globals.h" extern const struct generic_mapping file_generic_mapping; @@ -193,7 +196,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp, &base, &stream); } /* It's a stream, so pass in the base_fd */ - if (stream != NULL) { + if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) { SMB_ASSERT(fsp->base_fsp); /* diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 9616ca48d5..05b36d7d3c 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -19,7 +19,10 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" + #include <sys/isi_enc.h> /* @@ -160,18 +163,26 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, char *nbase = NULL; char *nsname = NULL; + START_PROFILE(syscall_rename_at); + frame = talloc_stackframe(); ret = onefs_is_stream(oldname, &obase, &osname, &old_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } ret = onefs_is_stream(newname, &nbase, &nsname, &new_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } if (!old_is_stream && !new_is_stream) { - return SMB_VFS_NEXT_RENAME(handle, oldname, newname); + ret = SMB_VFS_NEXT_RENAME(handle, oldname, newname); + END_PROFILE(syscall_rename_at); + return ret; } dir_fd = get_stream_dir_fd(handle->conn, obase, NULL); @@ -192,6 +203,8 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, } done: + END_PROFILE(syscall_rename_at); + saved_errno = errno; if (dir_fd >= 0) { close(dir_fd); @@ -220,7 +233,7 @@ static void merge_stat(SMB_STRUCT_STAT *stream_sbuf, static void onefs_adjust_stat_time(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf) { - struct onefs_vfs_config cfg; + struct onefs_vfs_share_config cfg; struct timeval tv_now = {0, 0}; bool static_mtime = False; bool static_atime = False; @@ -658,6 +671,11 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, state.streams = NULL; state.num_streams = 0; + if (lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE, + PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) { + goto out; + } + /* Add the default stream. */ if (S_ISREG(sbuf.st_mode)) { if (!add_one_stream(mem_ctx, @@ -689,7 +707,7 @@ NTSTATUS onefs_streaminfo(vfs_handle_struct *handle, return state.status; } } - + out: *num_streams = state.num_streams; *streams = state.streams; return NT_STATUS_OK; diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 76df006d82..b8b059bce9 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -18,10 +18,14 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#include "includes.h" #include "onefs.h" +#include "onefs_config.h" +#include "oplock_onefs.h" #include <ifs/ifs_syscalls.h> #include <isi_acl/isi_acl_util.h> +#include <sys/isi_acl.h> /* * Initialize the sm_lock struct before passing it to ifs_createfile. @@ -95,6 +99,8 @@ int onefs_sys_create_file(connection_struct *conn, uint32_t onefs_dos_attributes; struct ifs_createfile_flags cf_flags = CF_FLAGS_NONE; + START_PROFILE(syscall_createfile); + /* Setup security descriptor and get secinfo. */ if (sd != NULL) { NTSTATUS status; @@ -196,6 +202,7 @@ int onefs_sys_create_file(connection_struct *conn, } out: + END_PROFILE(syscall_createfile); aclu_free_sd(pifs_sd, false); return ret_fd; @@ -307,6 +314,8 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, bool atomic = false; ssize_t ret = 0; + START_PROFILE_BYTES(syscall_sendfile, count); + if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_ATOMIC_SENDFILE, PARM_ATOMIC_SENDFILE_DEFAULT)) { @@ -320,6 +329,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* If the sendfile wasn't atomic, we're done. */ if (!atomic) { DEBUG(10, ("non-atomic sendfile read %ul bytes", ret)); + END_PROFILE(syscall_sendfile); return ret; } @@ -391,6 +401,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* Handle case 1: short read -> truncated file. */ if (ret == 0) { + END_PROFILE(syscall_sendfile); return ret; } @@ -402,6 +413,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, PARM_SENDFILE_LARGE_READS_DEFAULT)) { DEBUG(3, ("Not attempting non-atomic large sendfile: " "%lu bytes\n", count)); + END_PROFILE(syscall_sendfile); return 0; } @@ -421,6 +433,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, DEBUG(1, ("error on non-atomic large sendfile " "(%lu bytes): %s\n", count, strerror(errno))); + END_PROFILE(syscall_sendfile); return ret; } @@ -439,9 +452,11 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_SENDFILE_SAFE, PARM_SENDFILE_SAFE_DEFAULT)) { + END_PROFILE(syscall_sendfile); return -1; } + END_PROFILE(syscall_sendfile); return ret; } @@ -455,6 +470,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, count, strerror(errno))); } + END_PROFILE(syscall_sendfile); return ret; } @@ -509,10 +525,13 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, off_t rbytes; off_t wbytes; + START_PROFILE_BYTES(syscall_recvfile, count); + DEBUG(10,("onefs_recvfile: from = %d, to = %d, offset=%llu, count = " "%lu\n", fromfd, tofd, offset, count)); if (count == 0) { + END_PROFILE(syscall_recvfile); return 0; } @@ -624,6 +643,9 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, ret = total_wbytes; out: + + END_PROFILE(syscall_recvfile); + /* Make sure we always try to drain the socket. */ if (!socket_drained && count - total_rbytes) { int saved_errno = errno; diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c index 909de9d7c8..a77f6d60f4 100644 --- a/source3/modules/vfs_acl_tdb.c +++ b/source3/modules/vfs_acl_tdb.c @@ -186,20 +186,26 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, TDB_DATA data; struct file_id id; struct db_context *db; + int ret = -1; SMB_STRUCT_STAT sbuf; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return NT_STATUS_INTERNAL_DB_CORRUPTION); if (fsp && fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } + ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) { - return map_nt_error_from_unix(errno); + if (fsp && fsp->posix_open) { + ret = SMB_VFS_LSTAT(handle->conn, name, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, name, &sbuf); } } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); /* For backwards compatibility only store the dev/inode. */ @@ -270,6 +276,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, TDB_DATA data; struct db_context *db; struct db_record *rec; + int ret = -1; DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", (unsigned int)pblob->length, fsp->fsp_name)); @@ -278,14 +285,19 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, return NT_STATUS_INTERNAL_DB_CORRUPTION); if (fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } + ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf) == -1) { - return map_nt_error_from_unix(errno); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(handle->conn, fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf); } } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); /* For backwards compatibility only store the dev/inode. */ @@ -316,6 +328,7 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, SMB_STRUCT_STAT sbuf; struct db_context *db; struct db_record *rec; + int ret = -1; DEBUG(10,("store_acl_blob_pathname: storing blob " "length %u on file %s\n", @@ -324,7 +337,13 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return NT_STATUS_INTERNAL_DB_CORRUPTION); - if (SMB_VFS_STAT(handle->conn, fname, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + } + + if (ret == -1) { return map_nt_error_from_unix(errno); } @@ -494,7 +513,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + if (fsp && fsp->posix_open) { + ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + } } if (ret == -1) { return map_nt_error_from_unix(errno); @@ -583,11 +606,17 @@ static int unlink_acl_tdb(vfs_handle_struct *handle, const char *path) { SMB_STRUCT_STAT sbuf; struct db_context *db; - int ret; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, path, &sbuf); + } + + if (ret == -1) { return -1; } @@ -626,11 +655,17 @@ static int rmdir_acl_tdb(vfs_handle_struct *handle, const char *path) SMB_STRUCT_STAT sbuf; struct db_context *db; - int ret; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, path, &sbuf); + } + + if (ret == -1) { return -1; } @@ -728,7 +763,11 @@ static NTSTATUS fset_nt_acl_tdb(vfs_handle_struct *handle, files_struct *fsp, return NT_STATUS_OK; } if (fsp->is_directory || fsp->fh->fd == -1) { - ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); } @@ -813,11 +852,17 @@ static int sys_acl_set_file_tdb(vfs_handle_struct *handle, { SMB_STRUCT_STAT sbuf; struct db_context *db; - int ret; + int ret = -1; SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); - if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, path, &sbuf); + } + + if (ret == -1) { return -1; } @@ -848,7 +893,11 @@ static int sys_acl_set_fd_tdb(vfs_handle_struct *handle, SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); if (fsp->is_directory || fsp->fh->fd == -1) { - ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); } diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index 7c78b506f0..49e4899879 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -381,7 +381,11 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + if (fsp && fsp->posix_open) { + ret = SMB_VFS_LSTAT(handle->conn,fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + } } if (ret == -1) { return map_nt_error_from_unix(errno); @@ -559,7 +563,11 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, return NT_STATUS_OK; } if (fsp->is_directory || fsp->fh->fd == -1) { - ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } } else { ret = SMB_VFS_FSTAT(fsp, &sbuf); } diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 1d7cdba014..3c061ece79 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -96,6 +96,11 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle, TALLOC_FREE(full_path); + if ((result == -1) && (errno == ENOSYS)) { + return SMB_VFS_NEXT_GET_REAL_FILENAME( + handle, path, name, mem_ctx, found_name); + } + if (result == -1) { DEBUG(10, ("smbd_gpfs_get_realfilename_path returned %s\n", strerror(errno))); diff --git a/source3/modules/vfs_onefs.c b/source3/modules/vfs_onefs.c index 60c2c977a4..2ec6e069c3 100644 --- a/source3/modules/vfs_onefs.c +++ b/source3/modules/vfs_onefs.c @@ -20,122 +20,21 @@ #include "includes.h" #include "onefs.h" +#include "onefs_config.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS -#define ONEFS_DATA_FASTBUF 10 - -struct onefs_vfs_config share_config[ONEFS_DATA_FASTBUF]; -struct onefs_vfs_config *pshare_config; - -static void onefs_load_faketimestamp_config(struct vfs_handle_struct *handle, - struct onefs_vfs_config *cfg) -{ - const char **parm; - int snum = SNUM(handle->conn); - - parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_NOW, - PARM_ATIME_NOW_DEFAULT); - - if (parm) { - cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; - set_namearray(&cfg->atime_now_list,*parm); - } - - parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_CTIME_NOW, - PARM_CTIME_NOW_DEFAULT); - - if (parm) { - cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; - set_namearray(&cfg->ctime_now_list,*parm); - } - - parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_NOW, - PARM_MTIME_NOW_DEFAULT); - - if (parm) { - cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; - set_namearray(&cfg->mtime_now_list,*parm); - } - - parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_ATIME_STATIC, - PARM_ATIME_STATIC_DEFAULT); - - if (parm) { - cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; - set_namearray(&cfg->atime_static_list,*parm); - } - - parm = lp_parm_string_list(snum, PARM_ONEFS_TYPE, PARM_MTIME_STATIC, - PARM_MTIME_STATIC_DEFAULT); - - if (parm) { - cfg->init_flags |= ONEFS_VFS_CONFIG_FAKETIMESTAMPS; - set_namearray(&cfg->mtime_static_list,*parm); - } - - cfg->atime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_ATIME_SLOP, - PARM_ATIME_SLOP_DEFAULT); - cfg->ctime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_CTIME_SLOP, - PARM_CTIME_SLOP_DEFAULT); - cfg->mtime_slop = lp_parm_int(snum, PARM_ONEFS_TYPE, PARM_MTIME_SLOP, - PARM_MTIME_SLOP_DEFAULT); -} - - -static int onefs_load_config(struct vfs_handle_struct *handle) -{ - int snum = SNUM(handle->conn); - int share_count = lp_numservices(); - - if (!pshare_config) { - - if (share_count <= ONEFS_DATA_FASTBUF) - pshare_config = share_config; - else { - pshare_config = - SMB_MALLOC_ARRAY(struct onefs_vfs_config, - share_count); - if (!pshare_config) { - errno = ENOMEM; - return -1; - } - - memset(pshare_config, 0, - (sizeof(struct onefs_vfs_config) * share_count)); - } - } - - if ((pshare_config[snum].init_flags & - ONEFS_VFS_CONFIG_INITIALIZED) == 0) { - pshare_config[snum].init_flags = - ONEFS_VFS_CONFIG_INITIALIZED; - onefs_load_faketimestamp_config(handle, - &pshare_config[snum]); - } - - return 0; -} - -bool onefs_get_config(int snum, int config_type, - struct onefs_vfs_config *cfg) -{ - if (share_config[snum].init_flags & config_type) - *cfg = share_config[snum]; - else - return false; - - return true; -} - static int onefs_connect(struct vfs_handle_struct *handle, const char *service, const char *user) { - int ret = onefs_load_config(handle); + int ret; - if (ret) + ret = onefs_load_config(handle->conn); + if (ret) { + DEBUG(3, ("Load config failed: %s\n", strerror(errno))); return ret; + } return SMB_VFS_NEXT_CONNECT(handle, service, user); } @@ -323,7 +222,14 @@ static int onefs_ntimes(vfs_handle_struct *handle, const char *fname, static uint32_t onefs_fs_capabilities(struct vfs_handle_struct *handle) { - return SMB_VFS_NEXT_FS_CAPABILITIES(handle) | FILE_NAMED_STREAMS; + uint32_t result = 0; + + if (!lp_parm_bool(SNUM(handle->conn), PARM_ONEFS_TYPE, + PARM_IGNORE_STREAMS, PARM_IGNORE_STREAMS_DEFAULT)) { + result |= FILE_NAMED_STREAMS; + } + + return result | SMB_VFS_NEXT_FS_CAPABILITIES(handle); } static vfs_op_tuple onefs_ops[] = { diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index 9329be7a9c..023d2b9ec0 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -494,7 +494,13 @@ static int streams_depot_unlink(vfs_handle_struct *handle, const char *fname) * We potentially need to delete the per-inode streams directory */ - if (SMB_VFS_NEXT_STAT(handle, fname, &sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_NEXT_LSTAT(handle, fname, &sbuf); + } else { + ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + } + + if (ret == -1) { return -1; } @@ -678,7 +684,11 @@ static NTSTATUS streams_depot_streaminfo(vfs_handle_struct *handle, if (is_ntfs_stream_name(fname)) { return NT_STATUS_INVALID_PARAMETER; } - ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_NEXT_LSTAT(handle, fname, &sbuf); + } else { + ret = SMB_VFS_NEXT_STAT(handle, fname, &sbuf); + } } if (ret == -1) { diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c index 77ffff5fb5..3d5478d7a2 100644 --- a/source3/modules/vfs_streams_xattr.c +++ b/source3/modules/vfs_streams_xattr.c @@ -135,6 +135,7 @@ static bool streams_xattr_recheck(struct stream_io *sio) static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf) { + int ret = -1; struct stream_io *io = (struct stream_io *) VFS_FETCH_FSP_EXTENSION(handle, fsp); @@ -148,7 +149,13 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, return -1; } - if (SMB_VFS_STAT(handle->conn, io->base, sbuf) == -1) { + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, io->base, sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, io->base, sbuf); + } + + if (ret == -1) { return -1; } @@ -719,7 +726,11 @@ static NTSTATUS streams_xattr_streaminfo(vfs_handle_struct *handle, if (is_ntfs_stream_name(fname)) { return NT_STATUS_INVALID_PARAMETER; } - ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + if (lp_posix_pathnames()) { + ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn, fname, &sbuf); + } } if (ret == -1) { diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 89c706d874..f49a1bc4c9 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4668,7 +4668,9 @@ static int max_open_files(void) #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)) { - struct rlimit rl = {}; + struct rlimit rl; + + ZERO_STRUCT(rl); if (getrlimit(RLIMIT_NOFILE, &rl) == 0) rlimit_max = rl.rlim_cur; diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index 53845117e2..9c20042a62 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -1308,13 +1308,20 @@ void uid_to_sid(DOM_SID *psid, uid_t uid) if (!ret || expired) { /* Not in cache. Ask winbindd. */ if (!winbind_uid_to_sid(psid, uid)) { - if (!winbind_ping()) { - legacy_uid_to_sid(psid, uid); - return; - } + /* + * We shouldn't return the NULL SID + * here if winbind was running and + * couldn't map, as winbind will have + * added a negative entry that will + * cause us to go though the + * legacy_uid_to_sid() + * function anyway in the case above + * the next time we ask. + */ + DEBUG(5, ("uid_to_sid: winbind failed to find a sid " + "for uid %u\n", uid)); - DEBUG(5, ("uid_to_sid: winbind failed to find a sid for uid %u\n", - uid)); + legacy_uid_to_sid(psid, uid); return; } } @@ -1354,13 +1361,20 @@ void gid_to_sid(DOM_SID *psid, gid_t gid) if (!ret || expired) { /* Not in cache. Ask winbindd. */ if (!winbind_gid_to_sid(psid, gid)) { - if (!winbind_ping()) { - legacy_gid_to_sid(psid, gid); - return; - } + /* + * We shouldn't return the NULL SID + * here if winbind was running and + * couldn't map, as winbind will have + * added a negative entry that will + * cause us to go though the + * legacy_gid_to_sid() + * function anyway in the case above + * the next time we ask. + */ + DEBUG(5, ("gid_to_sid: winbind failed to find a sid " + "for gid %u\n", gid)); - DEBUG(5, ("gid_to_sid: winbind failed to find a sid for gid %u\n", - gid)); + legacy_gid_to_sid(psid, gid); return; } } diff --git a/source3/passdb/pdb_onefs_sam.c b/source3/passdb/pdb_wbc_sam.c index 51b8618aad..d2c7fda293 100644 --- a/source3/passdb/pdb_onefs_sam.c +++ b/source3/passdb/pdb_wbc_sam.c @@ -1,6 +1,8 @@ /* Unix SMB/CIFS implementation. - Password and authentication handling for wbclient + + Password and authentication handling by wbclient + Copyright (C) Andrew Bartlett 2002 Copyright (C) Jelmer Vernooij 2002 Copyright (C) Simo Sorce 2003 @@ -21,12 +23,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +/* This passdb module retrieves full passdb information for local users and + * groups from a wbclient compatible daemon. + * + * The purpose of this module is to defer all SAM authorization information + * storage and retrieval to a wbc compatible daemon. + * + * This passdb backend is most useful when used in conjunction with auth_wbc. + * + * A few current limitations of this module are: + * - read only interface + * - no privileges + */ + #include "includes.h" /*************************************************************************** Default implementations of some functions. ****************************************************************************/ -static NTSTATUS _pdb_onefs_sam_getsampw(struct pdb_methods *methods, +static NTSTATUS _pdb_wbc_sam_getsampw(struct pdb_methods *methods, struct samu *user, const struct passwd *pwd) { @@ -44,29 +59,29 @@ static NTSTATUS _pdb_onefs_sam_getsampw(struct pdb_methods *methods, return result; } -static NTSTATUS pdb_onefs_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) +static NTSTATUS pdb_wbc_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) { - return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwnam(sname)); + return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwnam(sname)); } -static NTSTATUS pdb_onefs_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) +static NTSTATUS pdb_wbc_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) { - return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwsid(sid)); + return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwsid(sid)); } -static bool pdb_onefs_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, +static bool pdb_wbc_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, DOM_SID *sid) { return winbind_uid_to_sid(sid, uid); } -static bool pdb_onefs_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, +static bool pdb_wbc_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, DOM_SID *sid) { return winbind_gid_to_sid(sid, gid); } -static bool pdb_onefs_sam_sid_to_id(struct pdb_methods *methods, +static bool pdb_wbc_sam_sid_to_id(struct pdb_methods *methods, const DOM_SID *sid, union unid_t *id, enum lsa_SidType *type) { @@ -82,7 +97,7 @@ static bool pdb_onefs_sam_sid_to_id(struct pdb_methods *methods, return true; } -static NTSTATUS pdb_onefs_sam_enum_group_members(struct pdb_methods *methods, +static NTSTATUS pdb_wbc_sam_enum_group_members(struct pdb_methods *methods, TALLOC_CTX *mem_ctx, const DOM_SID *group, uint32 **pp_member_rids, @@ -91,7 +106,7 @@ static NTSTATUS pdb_onefs_sam_enum_group_members(struct pdb_methods *methods, return NT_STATUS_NOT_IMPLEMENTED; } -static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods, +static NTSTATUS pdb_wbc_sam_enum_group_memberships(struct pdb_methods *methods, TALLOC_CTX *mem_ctx, struct samu *user, DOM_SID **pp_sids, @@ -100,10 +115,12 @@ static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods { size_t i; const char *username = pdb_get_username(user); + uint32_t num_groups; - if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { + if (!winbind_get_groups(mem_ctx, username, &num_groups, pp_gids)) { return NT_STATUS_NO_SUCH_USER; } + *p_num_groups = num_groups; if (*p_num_groups == 0) { smb_panic("primary group missing"); @@ -123,7 +140,7 @@ static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods return NT_STATUS_OK; } -static NTSTATUS pdb_onefs_sam_lookup_rids(struct pdb_methods *methods, +static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods, const DOM_SID *domain_sid, int num_rids, uint32 *rids, @@ -164,23 +181,23 @@ done: return result; } -static NTSTATUS pdb_onefs_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value) +static NTSTATUS pdb_wbc_sam_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value) { return NT_STATUS_UNSUCCESSFUL; } -static NTSTATUS pdb_onefs_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) +static NTSTATUS pdb_wbc_sam_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value) { return NT_STATUS_UNSUCCESSFUL; } -static bool pdb_onefs_sam_search_groups(struct pdb_methods *methods, +static bool pdb_wbc_sam_search_groups(struct pdb_methods *methods, struct pdb_search *search) { return false; } -static bool pdb_onefs_sam_search_aliases(struct pdb_methods *methods, +static bool pdb_wbc_sam_search_aliases(struct pdb_methods *methods, struct pdb_search *search, const DOM_SID *sid) { @@ -188,7 +205,7 @@ static bool pdb_onefs_sam_search_aliases(struct pdb_methods *methods, return false; } -static bool pdb_onefs_sam_get_trusteddom_pw(struct pdb_methods *methods, +static bool pdb_wbc_sam_get_trusteddom_pw(struct pdb_methods *methods, const char *domain, char **pwd, DOM_SID *sid, @@ -198,7 +215,7 @@ static bool pdb_onefs_sam_get_trusteddom_pw(struct pdb_methods *methods, } -static bool pdb_onefs_sam_set_trusteddom_pw(struct pdb_methods *methods, +static bool pdb_wbc_sam_set_trusteddom_pw(struct pdb_methods *methods, const char *domain, const char *pwd, const DOM_SID *sid) @@ -206,13 +223,13 @@ static bool pdb_onefs_sam_set_trusteddom_pw(struct pdb_methods *methods, return false; } -static bool pdb_onefs_sam_del_trusteddom_pw(struct pdb_methods *methods, +static bool pdb_wbc_sam_del_trusteddom_pw(struct pdb_methods *methods, const char *domain) { return false; } -static NTSTATUS pdb_onefs_sam_enum_trusteddoms(struct pdb_methods *methods, +static NTSTATUS pdb_wbc_sam_enum_trusteddoms(struct pdb_methods *methods, TALLOC_CTX *mem_ctx, uint32 *num_domains, struct trustdom_info ***domains) @@ -230,7 +247,7 @@ static bool _make_group_map(struct pdb_methods *methods, const char *domain, con return true; } -static NTSTATUS pdb_onefs_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, +static NTSTATUS pdb_wbc_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, DOM_SID sid) { NTSTATUS result = NT_STATUS_OK; @@ -269,7 +286,7 @@ done: return result; } -static NTSTATUS pdb_onefs_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, +static NTSTATUS pdb_wbc_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, gid_t gid) { NTSTATUS result = NT_STATUS_OK; @@ -309,7 +326,7 @@ done: return result; } -static NTSTATUS pdb_onefs_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, +static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, const char *name) { NTSTATUS result = NT_STATUS_OK; @@ -347,7 +364,7 @@ done: return result; } -static NTSTATUS pdb_onefs_sam_enum_group_mapping(struct pdb_methods *methods, +static NTSTATUS pdb_wbc_sam_enum_group_mapping(struct pdb_methods *methods, const DOM_SID *sid, enum lsa_SidType sid_name_use, GROUP_MAP **pp_rmap, size_t *p_num_entries, bool unix_only) @@ -355,21 +372,21 @@ static NTSTATUS pdb_onefs_sam_enum_group_mapping(struct pdb_methods *methods, return NT_STATUS_NOT_IMPLEMENTED; } -static NTSTATUS pdb_onefs_sam_get_aliasinfo(struct pdb_methods *methods, +static NTSTATUS pdb_wbc_sam_get_aliasinfo(struct pdb_methods *methods, const DOM_SID *sid, struct acct_info *info) { return NT_STATUS_NOT_IMPLEMENTED; } -static NTSTATUS pdb_onefs_sam_enum_aliasmem(struct pdb_methods *methods, +static NTSTATUS pdb_wbc_sam_enum_aliasmem(struct pdb_methods *methods, const DOM_SID *alias, DOM_SID **pp_members, size_t *p_num_members) { return NT_STATUS_NOT_IMPLEMENTED; } -static NTSTATUS pdb_onefs_sam_alias_memberships(struct pdb_methods *methods, +static NTSTATUS pdb_wbc_sam_alias_memberships(struct pdb_methods *methods, TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid, const DOM_SID *members, @@ -384,7 +401,7 @@ static NTSTATUS pdb_onefs_sam_alias_memberships(struct pdb_methods *methods, return NT_STATUS_OK; } -static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char *location) +static NTSTATUS pdb_init_wbc_sam(struct pdb_methods **pdb_method, const char *location) { NTSTATUS result; @@ -392,34 +409,34 @@ static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char * return result; } - (*pdb_method)->name = "onefs_sam"; - - (*pdb_method)->getsampwnam = pdb_onefs_sam_getsampwnam; - (*pdb_method)->getsampwsid = pdb_onefs_sam_getsampwsid; - - (*pdb_method)->getgrsid = pdb_onefs_sam_getgrsid; - (*pdb_method)->getgrgid = pdb_onefs_sam_getgrgid; - (*pdb_method)->getgrnam = pdb_onefs_sam_getgrnam; - (*pdb_method)->enum_group_mapping = pdb_onefs_sam_enum_group_mapping; - (*pdb_method)->enum_group_members = pdb_onefs_sam_enum_group_members; - (*pdb_method)->enum_group_memberships = pdb_onefs_sam_enum_group_memberships; - (*pdb_method)->get_aliasinfo = pdb_onefs_sam_get_aliasinfo; - (*pdb_method)->enum_aliasmem = pdb_onefs_sam_enum_aliasmem; - (*pdb_method)->enum_alias_memberships = pdb_onefs_sam_alias_memberships; - (*pdb_method)->lookup_rids = pdb_onefs_sam_lookup_rids; - (*pdb_method)->get_account_policy = pdb_onefs_sam_get_account_policy; - (*pdb_method)->set_account_policy = pdb_onefs_sam_set_account_policy; - (*pdb_method)->uid_to_sid = pdb_onefs_sam_uid_to_sid; - (*pdb_method)->gid_to_sid = pdb_onefs_sam_gid_to_sid; - (*pdb_method)->sid_to_id = pdb_onefs_sam_sid_to_id; - - (*pdb_method)->search_groups = pdb_onefs_sam_search_groups; - (*pdb_method)->search_aliases = pdb_onefs_sam_search_aliases; - - (*pdb_method)->get_trusteddom_pw = pdb_onefs_sam_get_trusteddom_pw; - (*pdb_method)->set_trusteddom_pw = pdb_onefs_sam_set_trusteddom_pw; - (*pdb_method)->del_trusteddom_pw = pdb_onefs_sam_del_trusteddom_pw; - (*pdb_method)->enum_trusteddoms = pdb_onefs_sam_enum_trusteddoms; + (*pdb_method)->name = "wbc_sam"; + + (*pdb_method)->getsampwnam = pdb_wbc_sam_getsampwnam; + (*pdb_method)->getsampwsid = pdb_wbc_sam_getsampwsid; + + (*pdb_method)->getgrsid = pdb_wbc_sam_getgrsid; + (*pdb_method)->getgrgid = pdb_wbc_sam_getgrgid; + (*pdb_method)->getgrnam = pdb_wbc_sam_getgrnam; + (*pdb_method)->enum_group_mapping = pdb_wbc_sam_enum_group_mapping; + (*pdb_method)->enum_group_members = pdb_wbc_sam_enum_group_members; + (*pdb_method)->enum_group_memberships = pdb_wbc_sam_enum_group_memberships; + (*pdb_method)->get_aliasinfo = pdb_wbc_sam_get_aliasinfo; + (*pdb_method)->enum_aliasmem = pdb_wbc_sam_enum_aliasmem; + (*pdb_method)->enum_alias_memberships = pdb_wbc_sam_alias_memberships; + (*pdb_method)->lookup_rids = pdb_wbc_sam_lookup_rids; + (*pdb_method)->get_account_policy = pdb_wbc_sam_get_account_policy; + (*pdb_method)->set_account_policy = pdb_wbc_sam_set_account_policy; + (*pdb_method)->uid_to_sid = pdb_wbc_sam_uid_to_sid; + (*pdb_method)->gid_to_sid = pdb_wbc_sam_gid_to_sid; + (*pdb_method)->sid_to_id = pdb_wbc_sam_sid_to_id; + + (*pdb_method)->search_groups = pdb_wbc_sam_search_groups; + (*pdb_method)->search_aliases = pdb_wbc_sam_search_aliases; + + (*pdb_method)->get_trusteddom_pw = pdb_wbc_sam_get_trusteddom_pw; + (*pdb_method)->set_trusteddom_pw = pdb_wbc_sam_set_trusteddom_pw; + (*pdb_method)->del_trusteddom_pw = pdb_wbc_sam_del_trusteddom_pw; + (*pdb_method)->enum_trusteddoms = pdb_wbc_sam_enum_trusteddoms; (*pdb_method)->private_data = NULL; (*pdb_method)->free_private_data = NULL; @@ -427,7 +444,7 @@ static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char * return NT_STATUS_OK; } -NTSTATUS pdb_onefs_sam_init(void) +NTSTATUS pdb_wbc_sam_init(void) { - return smb_register_passdb(PASSDB_INTERFACE_VERSION, "onefs_sam", pdb_init_onefs_sam); + return smb_register_passdb(PASSDB_INTERFACE_VERSION, "wbc_sam", pdb_init_wbc_sam); } diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index bbe8ebc2bc..d8658e9280 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -1381,7 +1381,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr goto error_exit; } old_create_time = st.st_mtime; - DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time)); + DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", + (long)old_create_time)); } } close_file(NULL, fsp, NORMAL_CLOSE); @@ -1432,7 +1433,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr goto error_exit; } new_create_time = st.st_mtime; - DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time)); + DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", + (long)new_create_time)); } } close_file(NULL, fsp, NORMAL_CLOSE); @@ -3423,8 +3425,8 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) goto done; switch (action) { - case SPOOL_DS_PUBLISH: - case SPOOL_DS_UPDATE: + case DSPRINT_PUBLISH: + case DSPRINT_UPDATE: /* set the DsSpooler info and attributes */ if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) { win_rc = WERR_NOMEM; @@ -3433,7 +3435,7 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED; break; - case SPOOL_DS_UNPUBLISH: + case DSPRINT_UNPUBLISH: printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED; break; default: @@ -3467,11 +3469,11 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) } switch (action) { - case SPOOL_DS_PUBLISH: - case SPOOL_DS_UPDATE: + case DSPRINT_PUBLISH: + case DSPRINT_UPDATE: win_rc = nt_printer_publish_ads(ads, printer); break; - case SPOOL_DS_UNPUBLISH: + case DSPRINT_UNPUBLISH: win_rc = nt_printer_unpublish_ads(ads, printer); break; } diff --git a/source3/printing/printfsp.c b/source3/printing/printfsp.c index b485711f91..243b8ea03b 100644 --- a/source3/printing/printfsp.c +++ b/source3/printing/printfsp.c @@ -88,7 +88,6 @@ NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn, void print_fsp_end(files_struct *fsp, enum file_close_type close_type) { uint32 jobid; - fstring sharename; if (fsp->fh->private_options & FILE_DELETE_ON_CLOSE) { /* @@ -102,7 +101,7 @@ void print_fsp_end(files_struct *fsp, enum file_close_type close_type) string_free(&fsp->fsp_name); } - if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) { + if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) { DEBUG(3,("print_fsp_end: Unable to convert RAP jobid %u to print jobid.\n", (unsigned int)fsp->rap_print_jobid )); return; diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 7179184b73..fc3667ea3a 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -117,7 +117,9 @@ bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid) if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) { struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr; - fstrcpy( sharename, jinfo->sharename ); + if (sharename != NULL) { + fstrcpy( sharename, jinfo->sharename ); + } *pjobid = jinfo->jobid; DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n", (unsigned int)*pjobid, (unsigned int)rap_jobid)); @@ -447,7 +449,7 @@ static const struct { { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT }, { LPQ_PRINTED, JOB_STATUS_PRINTED }, { LPQ_DELETED, JOB_STATUS_DELETED }, - { LPQ_BLOCKED, JOB_STATUS_BLOCKED }, + { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ }, { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION }, { -1, 0 } }; diff --git a/source3/profile/profile.c b/source3/profile/profile.c index bdbd805718..6d2d5ae06d 100644 --- a/source3/profile/profile.c +++ b/source3/profile/profile.c @@ -290,6 +290,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_rmdir", /* PR_VALUE_SYSCALL_RMDIR */ "syscall_closedir", /* PR_VALUE_SYSCALL_CLOSEDIR */ "syscall_open", /* PR_VALUE_SYSCALL_OPEN */ + "syscall_createfile", /* PR_VALUE_SYSCALL_CREATEFILE */ "syscall_close", /* PR_VALUE_SYSCALL_CLOSE */ "syscall_read", /* PR_VALUE_SYSCALL_READ */ "syscall_pread", /* PR_VALUE_SYSCALL_PREAD */ @@ -299,6 +300,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_sendfile", /* PR_VALUE_SYSCALL_SENDFILE */ "syscall_recvfile", /* PR_VALUE_SYSCALL_RECVFILE */ "syscall_rename", /* PR_VALUE_SYSCALL_RENAME */ + "syscall_rename_at", /* PR_VALUE_SYSCALL_RENAME_AT */ "syscall_fsync", /* PR_VALUE_SYSCALL_FSYNC */ "syscall_stat", /* PR_VALUE_SYSCALL_STAT */ "syscall_fstat", /* PR_VALUE_SYSCALL_FSTAT */ @@ -323,6 +325,11 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_realpath", /* PR_VALUE_SYSCALL_REALPATH */ "syscall_get_quota", /* PR_VALUE_SYSCALL_GET_QUOTA */ "syscall_set_quota", /* PR_VALUE_SYSCALL_SET_QUOTA */ + "syscall_get_sd", /* PR_VALUE_SYSCALL_GET_SD */ + "syscall_set_sd", /* PR_VALUE_SYSCALL_SET_SD */ + "syscall_brl_lock", /* PR_VALUE_SYSCALL_BRL_LOCK */ + "syscall_brl_unlock", /* PR_VALUE_SYSCALL_BRL_UNLOCK */ + "syscall_brl_cancel", /* PR_VALUE_SYSCALL_BRL_CANCEL */ "SMBmkdir", /* PR_VALUE_SMBMKDIR */ "SMBrmdir", /* PR_VALUE_SMBRMDIR */ "SMBopen", /* PR_VALUE_SMBOPEN */ diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index a5f3935821..67767a2e56 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -94,15 +94,16 @@ static WERROR fill_value_cache(struct registry_key *key) static WERROR fill_subkey_cache(struct registry_key *key) { + WERROR werr; + if (key->subkeys != NULL) { if (!reg_subkeys_need_update(key->key, key->subkeys)) { return WERR_OK; } } - if (!(key->subkeys = TALLOC_ZERO_P(key, REGSUBKEY_CTR))) { - return WERR_NOMEM; - } + werr = regsubkey_ctr_init(key, &(key->subkeys)); + W_ERROR_NOT_OK_RETURN(werr); if (fetch_reg_keys(key->key, key->subkeys) == -1) { TALLOC_FREE(key->subkeys); @@ -127,7 +128,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx, WERROR result = WERR_OK; struct registry_key *regkey; REGISTRY_KEY *key; - REGSUBKEY_CTR *subkeys = NULL; + struct regsubkey_ctr *subkeys = NULL; DEBUG(7,("regkey_open_onelevel: name = [%s]\n", name)); @@ -193,8 +194,8 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx, /* check if the path really exists; failed is indicated by -1 */ /* if the subkey count failed, bail out */ - if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) { - result = WERR_NOMEM; + result = regsubkey_ctr_init(key, &subkeys); + if (!W_ERROR_IS_OK(result)) { goto done; } @@ -308,11 +309,13 @@ WERROR reg_enumkey(TALLOC_CTX *mem_ctx, struct registry_key *key, return err; } - if (idx >= key->subkeys->num_subkeys) { + if (idx >= regsubkey_ctr_numkeys(key->subkeys)) { return WERR_NO_MORE_ITEMS; } - if (!(*name = talloc_strdup(mem_ctx, key->subkeys->subkeys[idx]))) { + if (!(*name = talloc_strdup(mem_ctx, + regsubkey_ctr_specific_key(key->subkeys, idx)))) + { return WERR_NOMEM; } @@ -406,11 +409,12 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys, } max_len = 0; - for (i=0; i<key->subkeys->num_subkeys; i++) { - max_len = MAX(max_len, strlen(key->subkeys->subkeys[i])); + for (i=0; i< regsubkey_ctr_numkeys(key->subkeys); i++) { + max_len = MAX(max_len, + strlen(regsubkey_ctr_specific_key(key->subkeys, i))); } - *num_subkeys = key->subkeys->num_subkeys; + *num_subkeys = regsubkey_ctr_numkeys(key->subkeys); *max_subkeylen = max_len; *max_subkeysize = 0; /* Class length? */ @@ -520,14 +524,8 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent, err = fill_subkey_cache(create_parent); if (!W_ERROR_IS_OK(err)) goto done; - err = regsubkey_ctr_addkey(create_parent->subkeys, path); - if (!W_ERROR_IS_OK(err)) goto done; - - if (!store_reg_keys(create_parent->key, create_parent->subkeys)) { - TALLOC_FREE(create_parent->subkeys); - err = WERR_REG_IO_FAILURE; - goto done; - } + err = create_reg_subkey(key->key, path); + W_ERROR_NOT_OK_GOTO_DONE(err); /* * Now open the newly created key @@ -546,40 +544,36 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent, WERROR reg_deletekey(struct registry_key *parent, const char *path) { WERROR err; - TALLOC_CTX *mem_ctx; char *name, *end; - int num_subkeys; struct registry_key *tmp_key, *key; + TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!(mem_ctx = talloc_init("reg_createkey"))) return WERR_NOMEM; - - if (!(name = talloc_strdup(mem_ctx, path))) { + name = talloc_strdup(mem_ctx, path); + if (name == NULL) { err = WERR_NOMEM; - goto error; + goto done; } /* check if the key has subkeys */ err = reg_openkey(mem_ctx, parent, name, REG_KEY_READ, &key); - if (!W_ERROR_IS_OK(err)) { - goto error; - } - if (!W_ERROR_IS_OK(err = fill_subkey_cache(key))) { - goto error; - } - if (key->subkeys->num_subkeys > 0) { + W_ERROR_NOT_OK_GOTO_DONE(err); + + err = fill_subkey_cache(key); + W_ERROR_NOT_OK_GOTO_DONE(err); + + if (regsubkey_ctr_numkeys(key->subkeys) > 0) { err = WERR_ACCESS_DENIED; - goto error; + goto done; } /* no subkeys - proceed with delete */ - if ((end = strrchr(name, '\\')) != NULL) { + end = strrchr(name, '\\'); + if (end != NULL) { *end = '\0'; err = reg_openkey(mem_ctx, parent, name, SEC_RIGHTS_CREATE_SUBKEY, &tmp_key); - if (!W_ERROR_IS_OK(err)) { - goto error; - } + W_ERROR_NOT_OK_GOTO_DONE(err); parent = tmp_key; name = end+1; @@ -587,31 +581,12 @@ WERROR reg_deletekey(struct registry_key *parent, const char *path) if (name[0] == '\0') { err = WERR_INVALID_PARAM; - goto error; - } - - if (!W_ERROR_IS_OK(err = fill_subkey_cache(parent))) { - goto error; - } - - num_subkeys = parent->subkeys->num_subkeys; - - if (regsubkey_ctr_delkey(parent->subkeys, name) == num_subkeys) { - err = WERR_BADFILE; - goto error; - } - - if (!store_reg_keys(parent->key, parent->subkeys)) { - TALLOC_FREE(parent->subkeys); - err = WERR_REG_IO_FAILURE; - goto error; + goto done; } - regkey_set_secdesc(key->key, NULL); - - err = WERR_OK; + err = delete_reg_subkey(parent->key, name); - error: +done: TALLOC_FREE(mem_ctx); return err; } @@ -726,7 +701,7 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, REGF_NK_REC *subkey; REGISTRY_KEY registry_key; REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; int i; char *path = NULL; WERROR result = WERR_OK; @@ -748,10 +723,8 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, /* now start parsing the values and subkeys */ - subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); - if (subkeys == NULL) { - return WERR_NOMEM; - } + result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); + W_ERROR_NOT_OK_RETURN(result); values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); if (values == NULL) { @@ -767,7 +740,7 @@ static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, (key->values[i].data_size & ~VK_DATA_IN_OFFSET)); } - /* copy subkeys into the REGSUBKEY_CTR */ + /* copy subkeys into the struct regsubkey_ctr */ key->subkey_index = 0; while ((subkey = regfio_fetch_subkey( regfile, key ))) { @@ -861,7 +834,7 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, { REGF_NK_REC *key; REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; int i, num_subkeys; char *key_tmp = NULL; char *keyname, *parentpath; @@ -909,10 +882,8 @@ static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, /* lookup the values and subkeys */ - subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); - if (subkeys == NULL) { - return WERR_NOMEM; - } + result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); + W_ERROR_NOT_OK_RETURN(result); values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); if (values == NULL) { @@ -1091,6 +1062,7 @@ static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx, WERROR werr = WERR_OK; struct registry_key *key; char *subkey_name = NULL; + uint32 i; mem_ctx = talloc_new(ctx); if (mem_ctx == NULL) { @@ -1104,25 +1076,21 @@ static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx, goto done; } - while (W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, 0, - &subkey_name, NULL))) - { + werr = fill_subkey_cache(key); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + /* + * loop from top to bottom for perfomance: + * this way, we need to rehash the regsubkey containers less + */ + for (i = regsubkey_ctr_numkeys(key->subkeys) ; i > 0; i--) { + subkey_name = regsubkey_ctr_specific_key(key->subkeys, i-1); werr = reg_deletekey_recursive_internal(mem_ctx, key, - subkey_name, - true); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - } - if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { - DEBUG(1, ("reg_deletekey_recursive_internal: " - "Error enumerating subkeys: %s\n", - win_errstr(werr))); - goto done; + subkey_name, + true); + W_ERROR_NOT_OK_GOTO_DONE(werr); } - werr = WERR_OK; - if (del_key) { /* now delete the actual key */ werr = reg_deletekey(parent, path); @@ -1133,18 +1101,57 @@ done: return werr; } +static WERROR reg_deletekey_recursive_trans(TALLOC_CTX *ctx, + struct registry_key *parent, + const char *path, + bool del_key) +{ + WERROR werr; + + werr = regdb_transaction_start(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("reg_deletekey_recursive_trans: " + "error starting transaction: %s\n", + win_errstr(werr))); + return werr; + } + + werr = reg_deletekey_recursive_internal(ctx, parent, path, del_key); + + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " failed to delete key '%s' from key " + "'%s': %s\n", path, parent->key->name, + win_errstr(werr))); + werr = regdb_transaction_cancel(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("reg_deletekey_recursive_trans: " + "error cancelling transaction: %s\n", + win_errstr(werr))); + } + } else { + werr = regdb_transaction_commit(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("reg_deletekey_recursive_trans: " + "error committing transaction: %s\n", + win_errstr(werr))); + } + } + + return werr; +} + WERROR reg_deletekey_recursive(TALLOC_CTX *ctx, struct registry_key *parent, const char *path) { - return reg_deletekey_recursive_internal(ctx, parent, path, true); + return reg_deletekey_recursive_trans(ctx, parent, path, true); } WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx, struct registry_key *parent, const char *path) { - return reg_deletekey_recursive_internal(ctx, parent, path, false); + return reg_deletekey_recursive_trans(ctx, parent, path, false); } #if 0 diff --git a/source3/registry/reg_backend_current_version.c b/source3/registry/reg_backend_current_version.c index 04cc0ebfa7..f76840ee22 100644 --- a/source3/registry/reg_backend_current_version.c +++ b/source3/registry/reg_backend_current_version.c @@ -70,7 +70,7 @@ static int current_version_fetch_values(const char *key, REGVAL_CTR *values) } static int current_version_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 8ef83a19a1..30f1db9c53 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -103,7 +103,7 @@ static WERROR init_registry_key_internal(const char *add_path) char *remaining = NULL; char *keyname; char *subkeyname; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; const char *p, *p2; DEBUG(6, ("init_registry_key: Adding [%s]\n", add_path)); @@ -167,9 +167,9 @@ static WERROR init_registry_key_internal(const char *add_path) * since we are about to update the record. * We just want any subkeys already present */ - if (!(subkeys = TALLOC_ZERO_P(frame, REGSUBKEY_CTR))) { + werr = regsubkey_ctr_init(frame, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("talloc() failure!\n")); - werr = WERR_NOMEM; goto fail; } @@ -482,6 +482,24 @@ int regdb_close( void ) return 0; } +WERROR regdb_transaction_start(void) +{ + return (regdb->transaction_start(regdb) == 0) ? + WERR_OK : WERR_REG_IO_FAILURE; +} + +WERROR regdb_transaction_commit(void) +{ + return (regdb->transaction_commit(regdb) == 0) ? + WERR_OK : WERR_REG_IO_FAILURE; +} + +WERROR regdb_transaction_cancel(void) +{ + return (regdb->transaction_cancel(regdb) == 0) ? + WERR_OK : WERR_REG_IO_FAILURE; +} + /*********************************************************************** return the tdb sequence number of the registry tdb. this is an indicator for the content of the registry @@ -492,13 +510,97 @@ int regdb_get_seqnum(void) return regdb->get_seqnum(regdb); } + +static WERROR regdb_delete_key_with_prefix(const char *keyname, + const char *prefix) +{ + char *path; + WERROR werr = WERR_NOMEM; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + if (keyname == NULL) { + werr = WERR_INVALID_PARAM; + goto done; + } + + if (prefix == NULL) { + path = discard_const_p(char, keyname); + } else { + path = talloc_asprintf(mem_ctx, "%s/%s", prefix, keyname); + if (path == NULL) { + goto done; + } + } + + path = normalize_reg_path(mem_ctx, path); + if (path == NULL) { + goto done; + } + + werr = ntstatus_to_werror(dbwrap_delete_bystring(regdb, path)); + + /* treat "not" found" as ok */ + if (W_ERROR_EQUAL(werr, WERR_NOT_FOUND)) { + werr = WERR_OK; + } + +done: + talloc_free(mem_ctx); + return werr; +} + + +static WERROR regdb_delete_values(const char *keyname) +{ + return regdb_delete_key_with_prefix(keyname, REG_VALUE_PREFIX); +} + +static WERROR regdb_delete_secdesc(const char *keyname) +{ + return regdb_delete_key_with_prefix(keyname, REG_SECDESC_PREFIX); +} + +static WERROR regdb_delete_subkeylist(const char *keyname) +{ + return regdb_delete_key_with_prefix(keyname, NULL); +} + +static WERROR regdb_delete_key_lists(const char *keyname) +{ + WERROR werr; + + werr = regdb_delete_values(keyname); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", + REG_VALUE_PREFIX, keyname, win_errstr(werr))); + goto done; + } + + werr = regdb_delete_secdesc(keyname); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " Deleting %s/%s failed: %s\n", + REG_SECDESC_PREFIX, keyname, win_errstr(werr))); + goto done; + } + + werr = regdb_delete_subkeylist(keyname); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, (__location__ " Deleting %s failed: %s\n", + keyname, win_errstr(werr))); + goto done; + } + +done: + return werr; +} + /*********************************************************************** Add subkey strings to the registry tdb under a defined key fmt is the same format as tdb_pack except this function only supports fstrings ***********************************************************************/ -static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr) +static bool regdb_store_keys_internal(const char *key, struct regsubkey_ctr *ctr) { TDB_DATA dbuf; uint8 *buffer = NULL; @@ -578,6 +680,16 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr) goto done; } + /* + * Delete a sorted subkey cache for regdb_key_exists, will be + * recreated automatically + */ + keyname = talloc_asprintf(ctx, "%s/%s", REG_SORTED_SUBKEYS_PREFIX, + keyname); + if (keyname != NULL) { + dbwrap_delete_bystring(regdb, keyname); + } + done: TALLOC_FREE(ctx); SAFE_FREE(buffer); @@ -589,14 +701,14 @@ done: do not currently exist ***********************************************************************/ -bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) +bool regdb_store_keys(const char *key, struct regsubkey_ctr *ctr) { - int num_subkeys, i; + int num_subkeys, old_num_subkeys, i; char *path = NULL; - REGSUBKEY_CTR *subkeys = NULL, *old_subkeys = NULL; + struct regsubkey_ctr *subkeys = NULL, *old_subkeys = NULL; char *oldkeyname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); - NTSTATUS status; + WERROR werr; if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { goto fail; @@ -607,23 +719,28 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) * changed */ - if (!(old_subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) { + werr = regsubkey_ctr_init(ctx, &old_subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); return false; } regdb_fetch_keys(key, old_subkeys); - if ((ctr->num_subkeys && old_subkeys->num_subkeys) && - (ctr->num_subkeys == old_subkeys->num_subkeys)) { - - for (i = 0; i<ctr->num_subkeys; i++) { - if (strcmp(ctr->subkeys[i], - old_subkeys->subkeys[i]) != 0) { + num_subkeys = regsubkey_ctr_numkeys(ctr); + old_num_subkeys = regsubkey_ctr_numkeys(old_subkeys); + if ((num_subkeys && old_num_subkeys) && + (num_subkeys == old_num_subkeys)) { + + for (i = 0; i < num_subkeys; i++) { + if (strcmp(regsubkey_ctr_specific_key(ctr, i), + regsubkey_ctr_specific_key(old_subkeys, i)) + != 0) + { break; } } - if (i == ctr->num_subkeys) { + if (i == num_subkeys) { /* * Nothing changed, no point to even start a tdb * transaction @@ -644,7 +761,8 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) * Re-fetch the old keys inside the transaction */ - if (!(old_subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) { + werr = regsubkey_ctr_init(ctx, &old_subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); goto cancel; } @@ -686,66 +804,14 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) continue; } - /* (a) Delete the value list for this key */ - - path = talloc_asprintf(ctx, "%s/%s/%s", - REG_VALUE_PREFIX, - key, - oldkeyname ); - if (!path) { - goto cancel; - } - path = normalize_reg_path(ctx, path); - if (!path) { - goto cancel; - } - /* Ignore errors here, we might have no values around */ - dbwrap_delete_bystring(regdb, path); - TALLOC_FREE(path); - - /* (b) Delete the secdesc for this key */ - - path = talloc_asprintf(ctx, "%s/%s/%s", - REG_SECDESC_PREFIX, - key, - oldkeyname ); - if (!path) { - goto cancel; - } - path = normalize_reg_path(ctx, path); + path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname); if (!path) { goto cancel; } - status = dbwrap_delete_bystring(regdb, path); - /* Don't fail if there are no values around. */ - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) - { - DEBUG(1, ("Deleting %s failed: %s\n", path, - nt_errstr(status))); - goto cancel; - } - TALLOC_FREE(path); - /* (c) Delete the list of subkeys of this key */ + werr = regdb_delete_key_lists(path); + W_ERROR_NOT_OK_GOTO(werr, cancel); - path = talloc_asprintf(ctx, "%s/%s", key, oldkeyname); - if (!path) { - goto cancel; - } - path = normalize_reg_path(ctx, path); - if (!path) { - goto cancel; - } - status = dbwrap_delete_bystring(regdb, path); - /* Don't fail if the subkey record was not found. */ - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) - { - DEBUG(1, ("Deleting %s failed: %s\n", path, - nt_errstr(status))); - goto cancel; - } TALLOC_FREE(path); } @@ -764,7 +830,8 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) num_subkeys = regsubkey_ctr_numkeys(ctr); if (num_subkeys == 0) { - if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR)) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); goto cancel; } @@ -785,7 +852,8 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) if (!path) { goto cancel; } - if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR)) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("regdb_store_keys: talloc() failure!\n")); goto cancel; } @@ -822,6 +890,139 @@ fail: return false; } +static WERROR regdb_create_subkey(const char *key, const char *subkey) +{ + WERROR werr; + struct regsubkey_ctr *subkeys; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + werr = WERR_NOT_FOUND; + goto done; + } + + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + if (regdb_fetch_keys(key, subkeys) < 0) { + werr = WERR_REG_IO_FAILURE; + goto done; + } + + if (regsubkey_ctr_key_exists(subkeys, subkey)) { + werr = WERR_OK; + goto done; + } + + talloc_free(subkeys); + + werr = regdb_transaction_start(); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + if (regdb_fetch_keys(key, subkeys) < 0) { + werr = WERR_REG_IO_FAILURE; + goto cancel; + } + + werr = regsubkey_ctr_addkey(subkeys, subkey); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + if (!regdb_store_keys_internal(key, subkeys)) { + DEBUG(0, (__location__ " failed to store new subkey list for " + "parent key %s\n", key)); + werr = WERR_REG_IO_FAILURE; + goto cancel; + } + + werr = regdb_transaction_commit(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to commit transaction: %s\n", + win_errstr(werr))); + } + + goto done; + +cancel: + werr = regdb_transaction_cancel(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to cancel transaction: %s\n", + win_errstr(werr))); + } + +done: + talloc_free(mem_ctx); + return werr; +} + +static WERROR regdb_delete_subkey(const char *key, const char *subkey) +{ + WERROR werr, werr2; + struct regsubkey_ctr *subkeys; + char *path; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + + if (!regdb_key_is_base_key(key) && !regdb_key_exists(key)) { + werr = WERR_NOT_FOUND; + goto done; + } + + path = talloc_asprintf(mem_ctx, "%s/%s", key, subkey); + if (path == NULL) { + werr = WERR_NOMEM; + goto done; + } + + if (!regdb_key_exists(path)) { + werr = WERR_OK; + goto done; + } + + werr = regdb_transaction_start(); + W_ERROR_NOT_OK_GOTO_DONE(werr); + + werr = regdb_delete_key_lists(path); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + werr = regsubkey_ctr_init(mem_ctx, &subkeys); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + if (regdb_fetch_keys(key, subkeys) < 0) { + werr = WERR_REG_IO_FAILURE; + goto cancel; + } + + werr = regsubkey_ctr_delkey(subkeys, subkey); + W_ERROR_NOT_OK_GOTO(werr, cancel); + + if (!regdb_store_keys_internal(key, subkeys)) { + DEBUG(0, (__location__ " failed to store new subkey_list for " + "parent key %s\n", key)); + werr = WERR_REG_IO_FAILURE; + goto cancel; + } + + werr = regdb_transaction_commit(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, (__location__ " failed to commit transaction: %s\n", + win_errstr(werr))); + } + + goto done; + +cancel: + werr2 = regdb_transaction_cancel(); + if (!W_ERROR_IS_OK(werr2)) { + DEBUG(0, (__location__ " failed to cancel transaction: %s\n", + win_errstr(werr2))); + } + +done: + talloc_free(mem_ctx); + return werr; +} static TDB_DATA regdb_fetch_key_internal(TALLOC_CTX *mem_ctx, const char *key) { @@ -871,6 +1072,223 @@ done: return ret; } +/* + * regdb_key_exists() is a very frequent operation. It can be quite + * time-consuming to fully fetch the parent's subkey list, talloc_strdup all + * subkeys and then compare the keyname linearly to all the parent's subkeys. + * + * The following code tries to make this operation as efficient as possible: + * Per registry key we create a list of subkeys that is very efficient to + * search for existence of a subkey. Its format is: + * + * 4 bytes num_subkeys + * 4*num_subkey bytes offset into the string array + * then follows a sorted list of subkeys in uppercase + * + * This record is created by create_sorted_subkeys() on demand if it does not + * exist. scan_parent_subkeys() uses regdb->parse_record to search the sorted + * list, the parsing code and the binary search can be found in + * parent_subkey_scanner. The code uses parse_record() to avoid a memcpy of + * the potentially large subkey record. + * + * The sorted subkey record is deleted in regdb_store_keys_internal and + * recreated on demand. + */ + +static int cmp_keynames(const void *p1, const void *p2) +{ + return StrCaseCmp(*((char **)p1), *((char **)p2)); +} + +static bool create_sorted_subkeys(const char *key, const char *sorted_keyname) +{ + char **sorted_subkeys; + struct regsubkey_ctr *ctr; + bool result = false; + NTSTATUS status; + char *buf; + char *p; + int i, res; + size_t len; + int num_subkeys; + WERROR werr; + + if (regdb->transaction_start(regdb) != 0) { + DEBUG(0, ("create_sorted_subkeys: transaction_start " + "failed\n")); + return false; + } + + werr = regsubkey_ctr_init(talloc_tos(), &ctr); + if (!W_ERROR_IS_OK(werr)) { + goto fail; + } + + res = regdb_fetch_keys(key, ctr); + if (res == -1) { + goto fail; + } + + num_subkeys = regsubkey_ctr_numkeys(ctr); + sorted_subkeys = talloc_array(ctr, char *, num_subkeys); + if (sorted_subkeys == NULL) { + goto fail; + } + + len = 4 + 4*num_subkeys; + + for (i = 0; i < num_subkeys; i++) { + sorted_subkeys[i] = talloc_strdup_upper(sorted_subkeys, + regsubkey_ctr_specific_key(ctr, i)); + if (sorted_subkeys[i] == NULL) { + goto fail; + } + len += strlen(sorted_subkeys[i])+1; + } + + qsort(sorted_subkeys, num_subkeys, sizeof(char *), cmp_keynames); + + buf = talloc_array(ctr, char, len); + if (buf == NULL) { + goto fail; + } + p = buf + 4 + 4*num_subkeys; + + SIVAL(buf, 0, num_subkeys); + + for (i=0; i < num_subkeys; i++) { + ptrdiff_t offset = p - buf; + SIVAL(buf, 4 + 4*i, offset); + strlcpy(p, sorted_subkeys[i], len-offset); + p += strlen(sorted_subkeys[i]) + 1; + } + + status = dbwrap_store_bystring( + regdb, sorted_keyname, make_tdb_data((uint8_t *)buf, len), + TDB_REPLACE); + if (!NT_STATUS_IS_OK(status)) { + /* + * Don't use a "goto fail;" here, this would commit the broken + * transaction. See below for an explanation. + */ + if (regdb->transaction_cancel(regdb) == -1) { + DEBUG(0, ("create_sorted_subkeys: transaction_cancel " + "failed\n")); + } + TALLOC_FREE(ctr); + return false; + } + + result = true; + fail: + /* + * We only get here via the "goto fail" when we did not write anything + * yet. Using transaction_commit even in a failure case is necessary + * because this (disposable) call might be nested in other + * transactions. Doing a cancel here would destroy the possibility of + * a transaction_commit for transactions that we might be wrapped in. + */ + if (regdb->transaction_commit(regdb) == -1) { + DEBUG(0, ("create_sorted_subkeys: transaction_start " + "failed\n")); + goto fail; + } + + TALLOC_FREE(ctr); + return result; +} + +struct scan_subkey_state { + char *name; + bool scanned; + bool found; +}; + +static int parent_subkey_scanner(TDB_DATA key, TDB_DATA data, + void *private_data) +{ + struct scan_subkey_state *state = + (struct scan_subkey_state *)private_data; + uint32_t num_subkeys; + uint32_t l, u; + + if (data.dsize < sizeof(uint32_t)) { + return -1; + } + + state->scanned = true; + state->found = false; + + tdb_unpack(data.dptr, data.dsize, "d", &num_subkeys); + + l = 0; + u = num_subkeys; + + while (l < u) { + uint32_t idx = (l+u)/2; + char *s = (char *)data.dptr + IVAL(data.dptr, 4 + 4*idx); + int comparison = strcmp(state->name, s); + + if (comparison < 0) { + u = idx; + } else if (comparison > 0) { + l = idx + 1; + } else { + state->found = true; + return 0; + } + } + return 0; +} + +static bool scan_parent_subkeys(const char *parent, const char *name) +{ + char *path = NULL; + char *key = NULL; + struct scan_subkey_state state = { 0, }; + bool result = false; + int res; + + state.name = NULL; + + path = normalize_reg_path(talloc_tos(), parent); + if (path == NULL) { + goto fail; + } + + key = talloc_asprintf(talloc_tos(), "%s/%s", + REG_SORTED_SUBKEYS_PREFIX, path); + if (key == NULL) { + goto fail; + } + + state.name = talloc_strdup_upper(talloc_tos(), name); + if (state.name == NULL) { + goto fail; + } + state.scanned = false; + + res = regdb->parse_record(regdb, string_term_tdb_data(key), + parent_subkey_scanner, &state); + + if (state.scanned) { + result = state.found; + } else { + if (!create_sorted_subkeys(path, key)) { + goto fail; + } + res = regdb->parse_record(regdb, string_term_tdb_data(key), + parent_subkey_scanner, &state); + if ((res == 0) && (state.scanned)) { + result = state.found; + } + } + + fail: + TALLOC_FREE(path); + TALLOC_FREE(state.name); + return result; +} /** * Check for the existence of a key. @@ -907,26 +1325,8 @@ static bool regdb_key_exists(const char *key) value = regdb_fetch_key_internal(mem_ctx, path); ret = (value.dptr != NULL); } else { - /* get the list of subkeys of the parent key */ - uint32 num_items, len, i; - fstring subkeyname; - *p = '\0'; - p++; - value = regdb_fetch_key_internal(mem_ctx, path); - if (value.dptr == NULL) { - goto done; - } - - len = tdb_unpack(value.dptr, value.dsize, "d", &num_items); - for (i = 0; i < num_items; i++) { - len += tdb_unpack(value.dptr +len, value.dsize -len, - "f", &subkeyname); - if (strequal(subkeyname, p)) { - ret = true; - goto done; - } - } + ret = scan_parent_subkeys(path, p+1); } done: @@ -940,8 +1340,9 @@ done: released by the caller. ***********************************************************************/ -int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) +int regdb_fetch_keys(const char *key, struct regsubkey_ctr *ctr) { + WERROR werr; uint32 num_items; uint8 *buf; uint32 buflen, len; @@ -957,7 +1358,10 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) goto done; } - ctr->seqnum = regdb_get_seqnum(); + werr = regsubkey_ctr_set_seqnum(ctr, regdb_get_seqnum()); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } value = regdb_fetch_key_internal(frame, key); @@ -972,35 +1376,12 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) buflen = value.dsize; len = tdb_unpack( buf, buflen, "d", &num_items); - /* - * The following code breaks the abstraction that reg_objects.c sets - * up with regsubkey_ctr_addkey(). But if we use that with the current - * data structure of ctr->subkeys being an unsorted array, we end up - * with an O(n^2) algorithm for retrieving keys from the tdb - * file. This is pretty pointless, as we have to trust the data - * structure on disk not to have duplicates anyway. The alternative to - * breaking this abstraction would be to set up a more sophisticated - * data structure in REGSUBKEY_CTR. - * - * This makes "net conf list" for a registry with >1000 shares - * actually usable :-) - */ - - ctr->subkeys = talloc_array(ctr, char *, num_items); - if (ctr->subkeys == NULL) { - DEBUG(5, ("regdb_fetch_keys: could not allocate subkeys\n")); - goto done; - } - ctr->num_subkeys = num_items; - for (i=0; i<num_items; i++) { len += tdb_unpack(buf+len, buflen-len, "f", subkeyname); - ctr->subkeys[i] = talloc_strdup(ctr->subkeys, subkeyname); - if (ctr->subkeys[i] == NULL) { - DEBUG(5, ("regdb_fetch_keys: could not allocate " - "subkeyname\n")); - TALLOC_FREE(ctr->subkeys); - ctr->num_subkeys = 0; + werr = regsubkey_ctr_addkey(ctr, subkeyname); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey " + "failed: %s\n", win_errstr(werr))); goto done; } } @@ -1238,7 +1619,6 @@ static WERROR regdb_set_secdesc(const char *key, { TALLOC_CTX *mem_ctx = talloc_stackframe(); char *tdbkey; - NTSTATUS status; WERROR err = WERR_NOMEM; TDB_DATA tdbdata; @@ -1255,36 +1635,27 @@ static WERROR regdb_set_secdesc(const char *key, if (secdesc == NULL) { /* assuming a delete */ - status = dbwrap_trans_delete_bystring(regdb, tdbkey); - if (NT_STATUS_IS_OK(status)) { - err = WERR_OK; - } else { - err = ntstatus_to_werror(status); - } + err = ntstatus_to_werror(dbwrap_trans_delete_bystring(regdb, + tdbkey)); goto done; } err = ntstatus_to_werror(marshall_sec_desc(mem_ctx, secdesc, &tdbdata.dptr, &tdbdata.dsize)); - if (!W_ERROR_IS_OK(err)) { - goto done; - } + W_ERROR_NOT_OK_GOTO_DONE(err); - status = dbwrap_trans_store_bystring(regdb, tdbkey, tdbdata, 0); - if (!NT_STATUS_IS_OK(status)) { - err = ntstatus_to_werror(status); - goto done; - } + err = ntstatus_to_werror(dbwrap_trans_store_bystring(regdb, tdbkey, + tdbdata, 0)); done: TALLOC_FREE(mem_ctx); return err; } -bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys) +bool regdb_subkeys_need_update(struct regsubkey_ctr *subkeys) { - return (regdb_get_seqnum() != subkeys->seqnum); + return (regdb_get_seqnum() != regsubkey_ctr_get_seqnum(subkeys)); } bool regdb_values_need_update(REGVAL_CTR *values) @@ -1301,6 +1672,8 @@ REGISTRY_OPS regdb_ops = { .fetch_values = regdb_fetch_values, .store_subkeys = regdb_store_keys, .store_values = regdb_store_values, + .create_subkey = regdb_create_subkey, + .delete_subkey = regdb_delete_subkey, .get_secdesc = regdb_get_secdesc, .set_secdesc = regdb_set_secdesc, .subkeys_need_update = regdb_subkeys_need_update, diff --git a/source3/registry/reg_backend_hkpt_params.c b/source3/registry/reg_backend_hkpt_params.c index 2ed5e78e1c..c67f7b3ea4 100644 --- a/source3/registry/reg_backend_hkpt_params.c +++ b/source3/registry/reg_backend_hkpt_params.c @@ -59,7 +59,7 @@ static int hkpt_params_fetch_values(const char *key, REGVAL_CTR *regvals) } static int hkpt_params_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_netlogon_params.c b/source3/registry/reg_backend_netlogon_params.c index 71f88144c8..17abf038a6 100644 --- a/source3/registry/reg_backend_netlogon_params.c +++ b/source3/registry/reg_backend_netlogon_params.c @@ -46,7 +46,7 @@ static int netlogon_params_fetch_values(const char *key, REGVAL_CTR *regvals) } static int netlogon_params_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_perflib.c b/source3/registry/reg_backend_perflib.c index 999bca2682..e23c87efe8 100644 --- a/source3/registry/reg_backend_perflib.c +++ b/source3/registry/reg_backend_perflib.c @@ -95,7 +95,7 @@ static int perflib_fetch_values(const char *key, REGVAL_CTR *regvals) } static int perflib_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_printing.c b/source3/registry/reg_backend_printing.c index 5c1e6eb543..192bc78e09 100644 --- a/source3/registry/reg_backend_printing.c +++ b/source3/registry/reg_backend_printing.c @@ -42,8 +42,8 @@ struct reg_dyn_tree { const char *path; /* callbscks for fetch/store operations */ - int ( *fetch_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); - bool (*store_subkeys) ( const char *path, REGSUBKEY_CTR *subkeys ); + int ( *fetch_subkeys) ( const char *path, struct regsubkey_ctr *subkeys ); + bool (*store_subkeys) ( const char *path, struct regsubkey_ctr *subkeys ); int (*fetch_values) ( const char *path, REGVAL_CTR *values ); bool (*store_values) ( const char *path, REGVAL_CTR *values ); }; @@ -77,7 +77,7 @@ static const char *dos_basename(const char *path) ********************************************************************* *********************************************************************/ -static int key_forms_fetch_keys(const char *key, REGSUBKEY_CTR *subkeys) +static int key_forms_fetch_keys(const char *key, struct regsubkey_ctr *subkeys) { char *p = reg_remaining_path(talloc_tos(), key + strlen(KEY_FORMS)); @@ -196,7 +196,7 @@ static char *strip_printers_prefix(const char *key) /********************************************************************* *********************************************************************/ -static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) { int n_services = lp_numservices(); int snum; @@ -275,7 +275,7 @@ done: keyname is the sharename and not the printer name. *********************************************************************/ -static bool add_printers_by_registry( REGSUBKEY_CTR *subkeys ) +static bool add_printers_by_registry( struct regsubkey_ctr *subkeys ) { int i, num_keys, snum; char *printername; @@ -310,7 +310,7 @@ static bool add_printers_by_registry( REGSUBKEY_CTR *subkeys ) /********************************************************************** *********************************************************************/ -static bool key_printers_store_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys ) { char *printers_key; char *printername, *printerdatakey; @@ -738,7 +738,7 @@ static bool key_printers_store_values( const char *key, REGVAL_CTR *values ) ********************************************************************* *********************************************************************/ -static int key_driver_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) { const char *environments[] = { "Windows 4.0", @@ -1085,7 +1085,7 @@ static int key_driver_fetch_values( const char *key, REGVAL_CTR *values ) ********************************************************************* *********************************************************************/ -static int key_print_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static int key_print_fetch_keys( const char *key, struct regsubkey_ctr *subkeys ) { int key_len = strlen(key); @@ -1192,7 +1192,7 @@ static int match_registry_path(const char *key) /*********************************************************************** **********************************************************************/ -static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static int regprint_fetch_reg_keys( const char *key, struct regsubkey_ctr *subkeys ) { int i = match_registry_path( key ); @@ -1208,7 +1208,7 @@ static int regprint_fetch_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) /********************************************************************** *********************************************************************/ -static bool regprint_store_reg_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static bool regprint_store_reg_keys( const char *key, struct regsubkey_ctr *subkeys ) { int i = match_registry_path( key ); diff --git a/source3/registry/reg_backend_prod_options.c b/source3/registry/reg_backend_prod_options.c index 7ac5c5b4b9..3e9d32cd97 100644 --- a/source3/registry/reg_backend_prod_options.c +++ b/source3/registry/reg_backend_prod_options.c @@ -59,7 +59,7 @@ static int prod_options_fetch_values(const char *key, REGVAL_CTR *regvals) } static int prod_options_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_backend_shares.c b/source3/registry/reg_backend_shares.c index ee9e5dc5a1..a30ae34b4e 100644 --- a/source3/registry/reg_backend_shares.c +++ b/source3/registry/reg_backend_shares.c @@ -66,7 +66,7 @@ static char* trim_reg_path( const char *path ) Caller is responsible for freeing memory to **subkeys *********************************************************************/ -static int shares_subkey_info( const char *key, REGSUBKEY_CTR *subkey_ctr ) +static int shares_subkey_info( const char *key, struct regsubkey_ctr *subkey_ctr ) { char *path; bool top_level = False; @@ -134,7 +134,7 @@ static int shares_value_info( const char *key, REGVAL_CTR *val ) (for now at least) *********************************************************************/ -static bool shares_store_subkey( const char *key, REGSUBKEY_CTR *subkeys ) +static bool shares_store_subkey( const char *key, struct regsubkey_ctr *subkeys ) { return False; } diff --git a/source3/registry/reg_backend_smbconf.c b/source3/registry/reg_backend_smbconf.c index 2e4a5f1c1d..8e1bbcab6f 100644 --- a/source3/registry/reg_backend_smbconf.c +++ b/source3/registry/reg_backend_smbconf.c @@ -25,16 +25,26 @@ extern REGISTRY_OPS regdb_ops; /* these are the default */ -static int smbconf_fetch_keys( const char *key, REGSUBKEY_CTR *subkey_ctr ) +static int smbconf_fetch_keys( const char *key, struct regsubkey_ctr *subkey_ctr ) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } -static bool smbconf_store_keys( const char *key, REGSUBKEY_CTR *subkeys ) +static bool smbconf_store_keys( const char *key, struct regsubkey_ctr *subkeys ) { return regdb_ops.store_subkeys(key, subkeys); } +static WERROR smbconf_create_subkey(const char *key, const char *subkey) +{ + return regdb_ops.create_subkey(key, subkey); +} + +static WERROR smbconf_delete_subkey(const char *key, const char *subkey) +{ + return regdb_ops.delete_subkey(key, subkey); +} + static int smbconf_fetch_values( const char *key, REGVAL_CTR *val ) { return regdb_ops.fetch_values(key, val); @@ -79,6 +89,8 @@ REGISTRY_OPS smbconf_reg_ops = { .fetch_values = smbconf_fetch_values, .store_subkeys = smbconf_store_keys, .store_values = smbconf_store_values, + .create_subkey = smbconf_create_subkey, + .delete_subkey = smbconf_delete_subkey, .reg_access_check = smbconf_reg_access_check, .get_secdesc = smbconf_get_secdesc, .set_secdesc = smbconf_set_secdesc, diff --git a/source3/registry/reg_backend_tcpip_params.c b/source3/registry/reg_backend_tcpip_params.c index db7df5dd8f..a6aa2fc2ea 100644 --- a/source3/registry/reg_backend_tcpip_params.c +++ b/source3/registry/reg_backend_tcpip_params.c @@ -56,7 +56,7 @@ static int tcpip_params_fetch_values(const char *key, REGVAL_CTR *regvals) } static int tcpip_params_fetch_subkeys(const char *key, - REGSUBKEY_CTR *subkey_ctr) + struct regsubkey_ctr *subkey_ctr) { return regdb_ops.fetch_subkeys(key, subkey_ctr); } diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index c160622054..f8c382536f 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -80,7 +80,7 @@ static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd) High level wrapper function for storing registry subkeys ***********************************************************************/ -bool store_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys ) +bool store_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkeys ) { if (key->ops && key->ops->store_subkeys) return key->ops->store_subkeys(key->name, subkeys); @@ -100,12 +100,30 @@ bool store_reg_values( REGISTRY_KEY *key, REGVAL_CTR *val ) return false; } +WERROR create_reg_subkey(REGISTRY_KEY *key, const char *subkey) +{ + if (key->ops && key->ops->create_subkey) { + return key->ops->create_subkey(key->name, subkey); + } + + return WERR_NOT_SUPPORTED; +} + +WERROR delete_reg_subkey(REGISTRY_KEY *key, const char *subkey) +{ + if (key->ops && key->ops->delete_subkey) { + return key->ops->delete_subkey(key->name, subkey); + } + + return WERR_NOT_SUPPORTED; +} + /*********************************************************************** High level wrapper function for enumerating registry subkeys Initialize the TALLOC_CTX if necessary ***********************************************************************/ -int fetch_reg_keys( REGISTRY_KEY *key, REGSUBKEY_CTR *subkey_ctr ) +int fetch_reg_keys( REGISTRY_KEY *key, struct regsubkey_ctr *subkey_ctr ) { int result = -1; @@ -143,7 +161,6 @@ bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted, SEC_DESC *sec_desc; NTSTATUS status; WERROR err; - TALLOC_CTX *mem_ctx; /* use the default security check if the backend has not defined its * own */ @@ -153,30 +170,20 @@ bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted, granted, token); } - /* - * The secdesc routines can't yet cope with a NULL talloc ctx sanely. - */ - - if (!(mem_ctx = talloc_init("regkey_access_check"))) { - return false; - } - - err = regkey_get_secdesc(mem_ctx, key, &sec_desc); + err = regkey_get_secdesc(talloc_tos(), key, &sec_desc); if (!W_ERROR_IS_OK(err)) { - TALLOC_FREE(mem_ctx); return false; } se_map_generic( &requested, ®_generic_map ); status =se_access_check(sec_desc, token, requested, granted); + TALLOC_FREE(sec_desc); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(mem_ctx); return false; } - TALLOC_FREE(mem_ctx); return NT_STATUS_IS_OK(status); } @@ -216,7 +223,7 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key, * Check whether the in-memory version of the subkyes of a * registry key needs update from disk. */ -bool reg_subkeys_need_update(REGISTRY_KEY *key, REGSUBKEY_CTR *subkeys) +bool reg_subkeys_need_update(REGISTRY_KEY *key, struct regsubkey_ctr *subkeys) { if (key->ops && key->ops->subkeys_need_update) { diff --git a/source3/registry/reg_eventlog.c b/source3/registry/reg_eventlog.c index 8994acf107..c02318beac 100644 --- a/source3/registry/reg_eventlog.c +++ b/source3/registry/reg_eventlog.c @@ -35,16 +35,18 @@ bool eventlog_init_keys(void) const char **elogs = lp_eventlog_list(); char *evtlogpath = NULL; char *evtfilepath = NULL; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; REGVAL_CTR *values; uint32 uiMaxSize; uint32 uiRetention; uint32 uiCategoryCount; UNISTR2 data; TALLOC_CTX *ctx = talloc_tos(); + WERROR werr; while (elogs && *elogs) { - if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } @@ -70,7 +72,8 @@ bool eventlog_init_keys(void) DEBUG( 5, ( "Adding key of [%s] to path of [%s]\n", *elogs, evtlogpath ) ); - if (!(subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR))) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } @@ -197,7 +200,7 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, const char **elogs = lp_eventlog_list( ); char **wrklist, **wp; char *evtlogpath = NULL; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; REGVAL_CTR *values; REGISTRY_VALUE *rval; UNISTR2 data; @@ -207,6 +210,7 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, int i; int numsources; TALLOC_CTX *ctx = talloc_tos(); + WERROR werr; if (!elogs) { return False; @@ -315,7 +319,8 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, TALLOC_FREE(values); TALLOC_FREE(wrklist); /* */ - if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } @@ -342,7 +347,8 @@ bool eventlog_add_source( const char *eventlog, const char *sourcename, /* now allocate room for the source's subkeys */ - if ( !( subkeys = TALLOC_ZERO_P(ctx, REGSUBKEY_CTR ) ) ) { + werr = regsubkey_ctr_init(ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG( 0, ( "talloc() failure!\n" ) ); return False; } diff --git a/source3/registry/reg_objects.c b/source3/registry/reg_objects.c index 47122ccad2..b975ced324 100644 --- a/source3/registry/reg_objects.c +++ b/source3/registry/reg_objects.c @@ -24,25 +24,135 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY +struct regsubkey_ctr { + uint32_t num_subkeys; + char **subkeys; + struct db_context *subkeys_hash; + int seqnum; +}; + /********************************************************************** - Note that the REGSUB_CTR and REGVAL_CTR objects *must* be talloc()'d - since the methods use the object pointer as the talloc context for - internal private data. + Note that the struct regsubkey_ctr and REGVAL_CTR objects *must* be + talloc()'d since the methods use the object pointer as the talloc + context for internal private data. - There is no longer a regXXX_ctr_intit() and regXXX_ctr_destroy() + There is no longer a regval_ctr_intit() and regval_ctr_destroy() pair of functions. Simply TALLOC_ZERO_P() and TALLOC_FREE() the object. **********************************************************************/ +WERROR regsubkey_ctr_init(TALLOC_CTX *mem_ctx, struct regsubkey_ctr **ctr) +{ + if (ctr == NULL) { + return WERR_INVALID_PARAM; + } + + *ctr = talloc_zero(mem_ctx, struct regsubkey_ctr); + if (*ctr == NULL) { + return WERR_NOMEM; + } + + (*ctr)->subkeys_hash = db_open_rbt(*ctr); + if ((*ctr)->subkeys_hash == NULL) { + talloc_free(*ctr); + return WERR_NOMEM; + } + + return WERR_OK; +} + +WERROR regsubkey_ctr_set_seqnum(struct regsubkey_ctr *ctr, int seqnum) +{ + if (ctr == NULL) { + return WERR_INVALID_PARAM; + } + + ctr->seqnum = seqnum; + + return WERR_OK; +} + +int regsubkey_ctr_get_seqnum(struct regsubkey_ctr *ctr) +{ + if (ctr == NULL) { + return -1; + } + + return ctr->seqnum; +} + +static WERROR regsubkey_ctr_hash_keyname(struct regsubkey_ctr *ctr, + const char *keyname, + uint32 idx) +{ + WERROR werr; + + werr = ntstatus_to_werror(dbwrap_store_bystring(ctr->subkeys_hash, + keyname, + make_tdb_data((uint8 *)&idx, + sizeof(idx)), + TDB_REPLACE)); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("error hashing new key '%s' in container: %s\n", + keyname, win_errstr(werr))); + } + + return werr; +} + +static WERROR regsubkey_ctr_unhash_keyname(struct regsubkey_ctr *ctr, + const char *keyname) +{ + WERROR werr; + + werr = ntstatus_to_werror(dbwrap_delete_bystring(ctr->subkeys_hash, + keyname)); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("error unhashing key '%s' in container: %s\n", + keyname, win_errstr(werr))); + } + + return werr; +} + +static WERROR regsubkey_ctr_index_for_keyname(struct regsubkey_ctr *ctr, + const char *keyname, + uint32 *idx) +{ + TDB_DATA data; + + if ((ctr == NULL) || (keyname == NULL)) { + return WERR_INVALID_PARAM; + } + + data = dbwrap_fetch_bystring(ctr->subkeys_hash, ctr, keyname); + if (data.dptr == NULL) { + return WERR_NOT_FOUND; + } + + if (data.dsize != sizeof(*idx)) { + talloc_free(data.dptr); + return WERR_INVALID_DATATYPE; + } + + if (idx != NULL) { + *idx = *(uint32 *)data.dptr; + } + + talloc_free(data.dptr); + return WERR_OK; +} + /*********************************************************************** Add a new key to the array **********************************************************************/ -WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ) +WERROR regsubkey_ctr_addkey( struct regsubkey_ctr *ctr, const char *keyname ) { char **newkeys; + WERROR werr; if ( !keyname ) { return WERR_OK; @@ -68,6 +178,10 @@ WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ) */ return WERR_NOMEM; } + + werr = regsubkey_ctr_hash_keyname(ctr, keyname, ctr->num_subkeys); + W_ERROR_NOT_OK_RETURN(werr); + ctr->num_subkeys++; return WERR_OK; @@ -77,57 +191,64 @@ WERROR regsubkey_ctr_addkey( REGSUBKEY_CTR *ctr, const char *keyname ) Delete a key from the array **********************************************************************/ -int regsubkey_ctr_delkey( REGSUBKEY_CTR *ctr, const char *keyname ) +WERROR regsubkey_ctr_delkey( struct regsubkey_ctr *ctr, const char *keyname ) { - int i; + WERROR werr; + uint32 idx, j; - if ( !keyname ) - return ctr->num_subkeys; + if (keyname == NULL) { + return WERR_INVALID_PARAM; + } /* make sure the keyname is actually already there */ - for ( i=0; i<ctr->num_subkeys; i++ ) { - if ( strequal( ctr->subkeys[i], keyname ) ) - break; - } + werr = regsubkey_ctr_index_for_keyname(ctr, keyname, &idx); + W_ERROR_NOT_OK_RETURN(werr); - if ( i == ctr->num_subkeys ) - return ctr->num_subkeys; + werr = regsubkey_ctr_unhash_keyname(ctr, keyname); + W_ERROR_NOT_OK_RETURN(werr); /* update if we have any keys left */ ctr->num_subkeys--; - if ( i < ctr->num_subkeys ) - memmove(&ctr->subkeys[i], &ctr->subkeys[i+1], - sizeof(char*) * (ctr->num_subkeys-i)); + if (idx < ctr->num_subkeys) { + memmove(&ctr->subkeys[idx], &ctr->subkeys[idx+1], + sizeof(char *) * (ctr->num_subkeys - idx)); + + /* we have to re-hash rest of the array... :-( */ + for (j = idx; j < ctr->num_subkeys; j++) { + werr = regsubkey_ctr_hash_keyname(ctr, ctr->subkeys[j], j); + W_ERROR_NOT_OK_RETURN(werr); + } + } - return ctr->num_subkeys; + return WERR_OK; } /*********************************************************************** Check for the existance of a key **********************************************************************/ -bool regsubkey_ctr_key_exists( REGSUBKEY_CTR *ctr, const char *keyname ) +bool regsubkey_ctr_key_exists( struct regsubkey_ctr *ctr, const char *keyname ) { - int i; + WERROR werr; if (!ctr->subkeys) { return False; } - for ( i=0; i<ctr->num_subkeys; i++ ) { - if ( strequal( ctr->subkeys[i],keyname ) ) - return True; + werr = regsubkey_ctr_index_for_keyname(ctr, keyname, NULL); + if (!W_ERROR_IS_OK(werr)) { + return false; } - return False; + return true; } /*********************************************************************** How many keys does the container hold ? **********************************************************************/ -int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr ) +int regsubkey_ctr_numkeys( struct regsubkey_ctr *ctr ) { return ctr->num_subkeys; } @@ -136,7 +257,7 @@ int regsubkey_ctr_numkeys( REGSUBKEY_CTR *ctr ) Retreive a specific key string **********************************************************************/ -char* regsubkey_ctr_specific_key( REGSUBKEY_CTR *ctr, uint32 key_index ) +char* regsubkey_ctr_specific_key( struct regsubkey_ctr *ctr, uint32_t key_index ) { if ( ! (key_index < ctr->num_subkeys) ) return NULL; diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c index 5395f225f1..d002bd72e7 100644 --- a/source3/registry/regfio.c +++ b/source3/registry/regfio.c @@ -1693,7 +1693,7 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 ) *******************************************************************/ REGF_NK_REC* regfio_write_key( REGF_FILE *file, const char *name, - REGVAL_CTR *values, REGSUBKEY_CTR *subkeys, + REGVAL_CTR *values, struct regsubkey_ctr *subkeys, SEC_DESC *sec_desc, REGF_NK_REC *parent ) { REGF_NK_REC *nk; diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 19e9aae0f8..d76d20c962 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -137,6 +137,149 @@ WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli, return werror; } +/********************************************************************** + convencience wrapper around rpccli_spoolss_AddPrinterEx +**********************************************************************/ + +WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct spoolss_SetPrinterInfoCtr *info_ctr) +{ + WERROR result; + NTSTATUS status; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + struct spoolss_UserLevelCtr userlevel_ctr; + struct spoolss_UserLevel1 level1; + struct policy_handle handle; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + + level1.size = 28; + level1.build = 1381; + level1.major = 2; + level1.minor = 0; + level1.processor = 0; + level1.client = talloc_asprintf(mem_ctx, "\\\\%s", global_myname()); + W_ERROR_HAVE_NO_MEMORY(level1.client); + level1.user = cli->auth->user_name; + + userlevel_ctr.level = 1; + userlevel_ctr.user_info.level1 = &level1; + + status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx, + cli->srv_name_slash, + info_ctr, + &devmode_ctr, + &secdesc_ctr, + &userlevel_ctr, + &handle, + &result); + return result; +} + +/********************************************************************** + convencience wrapper around rpccli_spoolss_GetPrinter +**********************************************************************/ + +WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t level, + uint32_t offered, + union spoolss_PrinterInfo *info) +{ + NTSTATUS status; + WERROR werror; + DATA_BLOB buffer; + uint32_t needed; + + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + } + + status = rpccli_spoolss_GetPrinter(cli, mem_ctx, + handle, + level, + (offered > 0) ? &buffer : NULL, + offered, + info, + &needed, + &werror); + + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + + status = rpccli_spoolss_GetPrinter(cli, mem_ctx, + handle, + level, + &buffer, + offered, + info, + &needed, + &werror); + } + + return werror; +} + +/********************************************************************** + convencience wrapper around rpccli_spoolss_GetJob +**********************************************************************/ + +WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t job_id, + uint32_t level, + uint32_t offered, + union spoolss_JobInfo *info) +{ + NTSTATUS status; + WERROR werror; + uint32_t needed; + DATA_BLOB buffer; + + if (offered > 0) { + buffer = data_blob_talloc_zero(mem_ctx, offered); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + } + + status = rpccli_spoolss_GetJob(cli, mem_ctx, + handle, + job_id, + level, + (offered > 0) ? &buffer : NULL, + offered, + info, + &needed, + &werror); + + if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { + offered = needed; + buffer = data_blob_talloc_zero(mem_ctx, needed); + W_ERROR_HAVE_NO_MEMORY(buffer.data); + + status = rpccli_spoolss_GetJob(cli, mem_ctx, + handle, + job_id, + level, + &buffer, + offered, + info, + &needed, + &werror); + } + + return werror; +} + + /********************************************************************* Decode various spoolss rpc's and info levels ********************************************************************/ @@ -271,38 +414,6 @@ static bool decode_printer_info_3(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, /********************************************************************** **********************************************************************/ -static bool decode_printer_info_7(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, - uint32 returned, PRINTER_INFO_7 **info) -{ - uint32 i; - PRINTER_INFO_7 *inf; - - if (returned) { - inf=TALLOC_ARRAY(mem_ctx, PRINTER_INFO_7, returned); - if (!inf) { - return False; - } - memset(inf, 0, returned*sizeof(PRINTER_INFO_7)); - } else { - inf = NULL; - } - - prs_set_offset(&buffer->prs,0); - - for (i=0; i<returned; i++) { - if (!smb_io_printer_info_7("", buffer, &inf[i], 0)) { - return False; - } - } - - *info=inf; - return True; -} - - -/********************************************************************** -**********************************************************************/ - static bool decode_port_info_1(TALLOC_CTX *mem_ctx, RPC_BUFFER *buffer, uint32 returned, PORT_INFO_1 **info) { @@ -691,116 +802,6 @@ WERROR rpccli_spoolss_enum_ports(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_getprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTER in; - SPOOL_R_GETPRINTER out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - /* Initialise input parameters */ - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinter, - spoolss_io_r_getprinter, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getprinter( mem_ctx, &in, pol, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETPRINTER, - in, out, - qbuf, rbuf, - spoolss_io_q_getprinter, - spoolss_io_r_getprinter, - WERR_GENERAL_FAILURE ); - } - - if ( !W_ERROR_IS_OK(out.status) ) - return out.status; - - switch (level) { - case 0: - if (!decode_printer_info_0(mem_ctx, out.buffer, 1, &ctr->printers_0)) { - return WERR_GENERAL_FAILURE; - } - break; - case 1: - if (!decode_printer_info_1(mem_ctx, out.buffer, 1, &ctr->printers_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_printer_info_2(mem_ctx, out.buffer, 1, &ctr->printers_2)) { - return WERR_GENERAL_FAILURE; - } - break; - case 3: - if (!decode_printer_info_3(mem_ctx, out.buffer, 1, &ctr->printers_3)) { - return WERR_GENERAL_FAILURE; - } - break; - case 7: - if (!decode_printer_info_7(mem_ctx, out.buffer, 1, &ctr->printers_7)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - -WERROR rpccli_spoolss_setprinter(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr, uint32 command) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTER in; - SPOOL_R_SETPRINTER out; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - make_spoolss_q_setprinter( mem_ctx, &in, pol, level, ctr, command ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_SETPRINTER, - in, out, - qbuf, rbuf, - spoolss_io_q_setprinter, - spoolss_io_r_setprinter, - WERR_GENERAL_FAILURE ); - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 level, const char *env, @@ -886,41 +887,6 @@ WERROR rpccli_spoolss_enumprinterdrivers (struct rpc_pipe_client *cli, /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_addprinterex (struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 level, PRINTER_INFO_CTR*ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTEREX in; - SPOOL_R_ADDPRINTEREX out; - fstring server, client, user; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - slprintf(client, sizeof(fstring)-1, "\\\\%s", global_myname()); - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - - strupper_m(client); - strupper_m(server); - - fstrcpy (user, cli->auth->user_name); - - make_spoolss_q_addprinterex( mem_ctx, &in, server, client, - user, level, ctr); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_ADDPRINTEREX, - in, out, - qbuf, rbuf, - spoolss_io_q_addprinterex, - spoolss_io_r_addprinterex, - WERR_GENERAL_FAILURE ); - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_enumforms(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *handle, int level, uint32 *num_forms, FORM_1 **forms) @@ -1051,73 +1017,6 @@ WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, /********************************************************************** **********************************************************************/ -WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 jobid, uint32 level, - JOB_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETJOB in; - SPOOL_R_GETJOB out; - RPC_BUFFER buffer; - uint32 offered; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - offered = 0; - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB, - in, out, - qbuf, rbuf, - spoolss_io_q_getjob, - spoolss_io_r_getjob, - WERR_GENERAL_FAILURE ); - - if ( W_ERROR_EQUAL( out.status, WERR_MORE_DATA ) ) { - offered = out.needed; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - if (!rpcbuf_init(&buffer, offered, mem_ctx)) - return WERR_NOMEM; - make_spoolss_q_getjob( &in, hnd, jobid, level, &buffer, offered ); - - CLI_DO_RPC_WERR( cli, mem_ctx, &syntax_spoolss, SPOOLSS_GETJOB, - in, out, - qbuf, rbuf, - spoolss_io_q_getjob, - spoolss_io_r_getjob, - WERR_GENERAL_FAILURE ); - } - - if (!W_ERROR_IS_OK(out.status)) - return out.status; - - switch(level) { - case 1: - if (!decode_jobs_1(mem_ctx, out.buffer, 1, &ctr->job.job_info_1)) { - return WERR_GENERAL_FAILURE; - } - break; - case 2: - if (!decode_jobs_2(mem_ctx, out.buffer, 1, &ctr->job.job_info_2)) { - return WERR_GENERAL_FAILURE; - } - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - return out.status; -} - -/********************************************************************** -**********************************************************************/ - WERROR rpccli_spoolss_getprinterdata(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, const char *valuename, REGISTRY_VALUE *value) @@ -1359,5 +1258,4 @@ WERROR rpccli_spoolss_enumprinterkey(struct rpc_pipe_client *cli, TALLOC_CTX *me return out.status; } - /** @} **/ diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index c0fa41b0de..b1d9d8fbe1 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -35,6 +35,12 @@ static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state * return 0; } +struct rpc_sock_read_state { + ssize_t received; +}; + +static void rpc_sock_read_done(struct tevent_req *subreq); + static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, uint8_t *data, size_t size, @@ -42,25 +48,61 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - return async_recv(mem_ctx, ev, sock_transp->fd, data, size, 0); + struct async_req *result; + struct tevent_req *subreq; + struct rpc_sock_read_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct rpc_sock_read_state)) { + return NULL; + } + + subreq = async_recv_send(state, ev, sock_transp->fd, data, size, 0); + if (subreq == NULL) { + goto fail; + } + tevent_req_set_callback(subreq, rpc_sock_read_done, result); + return result; + fail: + TALLOC_FREE(result); + return NULL; } -static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) +static void rpc_sock_read_done(struct tevent_req *subreq) { - ssize_t received; - int sys_errno; + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); + struct rpc_sock_read_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_read_state); + int err; - received = async_syscall_result_ssize_t(req, &sys_errno); - if (received == -1) { - return map_nt_error_from_unix(sys_errno); + state->received = async_recv_recv(subreq, &err); + if (state->received == -1) { + async_req_nterror(req, map_nt_error_from_unix(err)); + return; } - if (received == 0) { - return NT_STATUS_END_OF_FILE; + async_req_done(req); +} + +static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) +{ + struct rpc_sock_read_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_read_state); + NTSTATUS status; + + if (async_req_is_nterror(req, &status)) { + return status; } - *preceived = received; + *preceived = state->received; return NT_STATUS_OK; } +struct rpc_sock_write_state { + ssize_t sent; +}; + +static void rpc_sock_write_done(struct tevent_req *subreq); + static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, struct event_context *ev, const uint8_t *data, size_t size, @@ -68,19 +110,51 @@ static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - return async_send(mem_ctx, ev, sock_transp->fd, data, size, 0); + struct async_req *result; + struct tevent_req *subreq; + struct rpc_sock_write_state *state; + + if (!async_req_setup(mem_ctx, &result, &state, + struct rpc_sock_write_state)) { + return NULL; + } + subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0); + if (subreq == NULL) { + goto fail; + } + tevent_req_set_callback(subreq, rpc_sock_write_done, result); + return result; + fail: + TALLOC_FREE(result); + return NULL; +} + +static void rpc_sock_write_done(struct tevent_req *subreq) +{ + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); + struct rpc_sock_write_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_write_state); + int err; + + state->sent = async_send_recv(subreq, &err); + if (state->sent == -1) { + async_req_nterror(req, map_nt_error_from_unix(err)); + return; + } + async_req_done(req); } static NTSTATUS rpc_sock_write_recv(struct async_req *req, ssize_t *psent) { - ssize_t sent; - int sys_errno; + struct rpc_sock_write_state *state = talloc_get_type_abort( + req->private_data, struct rpc_sock_write_state); + NTSTATUS status; - sent = async_syscall_result_ssize_t(req, &sys_errno); - if (sent == -1) { - return map_nt_error_from_unix(sys_errno); + if (async_req_is_nterror(req, &status)) { + return status; } - *psent = sent; + *psent = state->sent; return NT_STATUS_OK; } diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c index 23c9610381..91d8591a05 100644 --- a/source3/rpc_parse/parse_sec.c +++ b/source3/rpc_parse/parse_sec.c @@ -73,11 +73,11 @@ static bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, if (!prs_uint32("obj_flags", ps, depth, &psa->object.object.flags)) return False; - if (psa->object.object.flags & SEC_ACE_OBJECT_PRESENT) + if (psa->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) if (!smb_io_uuid("obj_guid", &psa->object.object.type.type, ps,depth)) return False; - if (psa->object.object.flags & SEC_ACE_OBJECT_INHERITED_PRESENT) + if (psa->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) if (!smb_io_uuid("inh_guid", &psa->object.object.inherited_type.inherited_type, ps,depth)) return False; diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index 12c7af49cf..78c041f863 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -71,78 +71,6 @@ bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime) } /******************************************************************* -********************************************************************/ - -bool spool_io_user_level_1( const char *desc, prs_struct *ps, int depth, SPOOL_USER_1 *q_u ) -{ - prs_debug(ps, depth, desc, ""); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("size", ps, depth, &q_u->size)) - return False; - - if (!prs_io_unistr2_p("", ps, depth, &q_u->client_name)) - return False; - if (!prs_io_unistr2_p("", ps, depth, &q_u->user_name)) - return False; - - if (!prs_uint32("build", ps, depth, &q_u->build)) - return False; - if (!prs_uint32("major", ps, depth, &q_u->major)) - return False; - if (!prs_uint32("minor", ps, depth, &q_u->minor)) - return False; - if (!prs_uint32("processor", ps, depth, &q_u->processor)) - return False; - - if (!prs_io_unistr2("", ps, depth, q_u->client_name)) - return False; - if (!prs_align(ps)) - return False; - - if (!prs_io_unistr2("", ps, depth, q_u->user_name)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth) -{ - if (q_u==NULL) - return False; - - prs_debug(ps, depth, desc, "spool_io_user_level"); - depth++; - - if (!prs_align(ps)) - return False; - - if (!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - switch ( q_u->level ) - { - case 1: - if ( !prs_pointer( "" , ps, depth, (void*)&q_u->user.user1, - sizeof(SPOOL_USER_1), (PRS_POINTER_CAST)spool_io_user_level_1 )) - { - return False; - } - break; - default: - return False; - } - - return True; -} - -/******************************************************************* * read or write a DEVICEMODE struct. * on reading allocate memory for the private member ********************************************************************/ @@ -331,220 +259,6 @@ bool spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE } /******************************************************************* - Read or write a DEVICEMODE container -********************************************************************/ - -static bool spoolss_io_devmode_cont(const char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth) -{ - if (dm_c==NULL) - return False; - - prs_debug(ps, depth, desc, "spoolss_io_devmode_cont"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_uint32("size", ps, depth, &dm_c->size)) - return False; - - if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr)) - return False; - - if (dm_c->size==0 || dm_c->devmode_ptr==0) { - if (UNMARSHALLING(ps)) - /* if while reading there is no DEVMODE ... */ - dm_c->devmode=NULL; - return True; - } - - /* so we have a DEVICEMODE to follow */ - if (UNMARSHALLING(ps)) { - DEBUG(9,("Allocating memory for spoolss_io_devmode\n")); - dm_c->devmode=PRS_ALLOC_MEM(ps,DEVICEMODE,1); - if(dm_c->devmode == NULL) - return False; - } - - /* this is bad code, shouldn't be there */ - if (!prs_uint32("size", ps, depth, &dm_c->size)) - return False; - - if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode)) - return False; - - return True; -} - -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_addprinterex( TALLOC_CTX *mem_ctx, SPOOL_Q_ADDPRINTEREX *q_u, - const char *srv_name, const char* clientname, const char* user_name, - uint32 level, PRINTER_INFO_CTR *ctr) -{ - DEBUG(5,("make_spoolss_q_addprinterex\n")); - - if (!ctr || !ctr->printers_2) - return False; - - ZERO_STRUCTP(q_u); - - q_u->server_name = TALLOC_P( mem_ctx, UNISTR2 ); - if (!q_u->server_name) { - return False; - } - init_unistr2(q_u->server_name, srv_name, UNI_FLAGS_NONE); - - q_u->level = level; - - q_u->info.level = level; - q_u->info.info_ptr = (ctr->printers_2!=NULL)?1:0; - switch (level) { - case 2: - /* init q_u->info.info2 from *info */ - if (!make_spoolss_printer_info_2(mem_ctx, &q_u->info.info_2, ctr->printers_2)) { - DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n")); - return False; - } - break; - default : - break; - } - - q_u->user_switch=1; - - q_u->user_ctr.level = 1; - q_u->user_ctr.user.user1 = TALLOC_P( talloc_tos(), SPOOL_USER_1 ); - if (!q_u->user_ctr.user.user1) { - return False; - } - q_u->user_ctr.user.user1->build = 1381; - q_u->user_ctr.user.user1->major = 2; - q_u->user_ctr.user.user1->minor = 0; - q_u->user_ctr.user.user1->processor = 0; - - q_u->user_ctr.user.user1->client_name = TALLOC_P( mem_ctx, UNISTR2 ); - if (!q_u->user_ctr.user.user1->client_name) { - return False; - } - q_u->user_ctr.user.user1->user_name = TALLOC_P( mem_ctx, UNISTR2 ); - if (!q_u->user_ctr.user.user1->user_name) { - return False; - } - init_unistr2(q_u->user_ctr.user.user1->client_name, clientname, UNI_STR_TERMINATE); - init_unistr2(q_u->user_ctr.user.user1->user_name, user_name, UNI_STR_TERMINATE); - - q_u->user_ctr.user.user1->size = q_u->user_ctr.user.user1->user_name->uni_str_len + - q_u->user_ctr.user.user1->client_name->uni_str_len + 2; - - return True; -} - -/******************************************************************* -create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct -*******************************************************************/ - -bool make_spoolss_printer_info_2(TALLOC_CTX *ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, - PRINTER_INFO_2 *info) -{ - - SPOOL_PRINTER_INFO_LEVEL_2 *inf; - - /* allocate the necessary memory */ - if (!(inf=TALLOC_P(ctx, SPOOL_PRINTER_INFO_LEVEL_2))) { - DEBUG(0,("make_spoolss_printer_info_2: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n")); - return False; - } - - inf->servername_ptr = (info->servername.buffer!=NULL)?1:0; - inf->printername_ptr = (info->printername.buffer!=NULL)?1:0; - inf->sharename_ptr = (info->sharename.buffer!=NULL)?1:0; - inf->portname_ptr = (info->portname.buffer!=NULL)?1:0; - inf->drivername_ptr = (info->drivername.buffer!=NULL)?1:0; - inf->comment_ptr = (info->comment.buffer!=NULL)?1:0; - inf->location_ptr = (info->location.buffer!=NULL)?1:0; - inf->devmode_ptr = (info->devmode!=NULL)?1:0; - inf->sepfile_ptr = (info->sepfile.buffer!=NULL)?1:0; - inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0; - inf->datatype_ptr = (info->datatype.buffer!=NULL)?1:0; - inf->parameters_ptr = (info->parameters.buffer!=NULL)?1:0; - inf->secdesc_ptr = (info->secdesc!=NULL)?1:0; - inf->attributes = info->attributes; - inf->priority = info->priority; - inf->default_priority = info->defaultpriority; - inf->starttime = info->starttime; - inf->untiltime = info->untiltime; - inf->cjobs = info->cjobs; - inf->averageppm = info->averageppm; - init_unistr2_from_unistr(inf, &inf->servername, &info->servername); - init_unistr2_from_unistr(inf, &inf->printername, &info->printername); - init_unistr2_from_unistr(inf, &inf->sharename, &info->sharename); - init_unistr2_from_unistr(inf, &inf->portname, &info->portname); - init_unistr2_from_unistr(inf, &inf->drivername, &info->drivername); - init_unistr2_from_unistr(inf, &inf->comment, &info->comment); - init_unistr2_from_unistr(inf, &inf->location, &info->location); - init_unistr2_from_unistr(inf, &inf->sepfile, &info->sepfile); - init_unistr2_from_unistr(inf, &inf->printprocessor, &info->printprocessor); - init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype); - init_unistr2_from_unistr(inf, &inf->parameters, &info->parameters); - init_unistr2_from_unistr(inf, &inf->datatype, &info->datatype); - - *spool_info2 = inf; - - return True; -} - -/******************************************************************* -create a SPOOL_PRINTER_INFO_3 struct from a PRINTER_INFO_3 struct -*******************************************************************/ - -bool make_spoolss_printer_info_3(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3 **spool_info3, - PRINTER_INFO_3 *info) -{ - - SPOOL_PRINTER_INFO_LEVEL_3 *inf; - - /* allocate the necessary memory */ - if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_3))) { - DEBUG(0,("make_spoolss_printer_info_3: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_3 sruct!\n")); - return False; - } - - inf->secdesc_ptr = (info->secdesc!=NULL)?1:0; - - *spool_info3 = inf; - - return True; -} - -/******************************************************************* -create a SPOOL_PRINTER_INFO_7 struct from a PRINTER_INFO_7 struct -*******************************************************************/ - -bool make_spoolss_printer_info_7(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7 **spool_info7, - PRINTER_INFO_7 *info) -{ - - SPOOL_PRINTER_INFO_LEVEL_7 *inf; - - /* allocate the necessary memory */ - if (!(inf=TALLOC_P(mem_ctx, SPOOL_PRINTER_INFO_LEVEL_7))) { - DEBUG(0,("make_spoolss_printer_info_7: Unable to allocate SPOOL_PRINTER_INFO_LEVEL_7 struct!\n")); - return False; - } - - inf->guid_ptr = (info->guid.buffer!=NULL)?1:0; - inf->action = info->action; - init_unistr2_from_unistr(inf, &inf->guid, &info->guid); - - *spool_info7 = inf; - - return True; -} - -/******************************************************************* * make a structure. ********************************************************************/ @@ -2291,211 +2005,6 @@ bool spoolss_io_q_getprinter(const char *desc, SPOOL_Q_GETPRINTER *q_u, prs_stru } /******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_getprinter( - TALLOC_CTX *mem_ctx, - SPOOL_Q_GETPRINTER *q_u, - const POLICY_HND *hnd, - uint32 level, - RPC_BUFFER *buffer, - uint32 offered -) -{ - if (q_u == NULL) - { - return False; - } - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - q_u->level=level; - q_u->buffer=buffer; - q_u->offered=offered; - - return True; -} - -/******************************************************************* - * init a structure. - ********************************************************************/ -bool make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, - const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, - uint32 command) -{ - SEC_DESC *secdesc; - DEVICEMODE *devmode; - - if (!q_u || !info) - return False; - - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - q_u->level = level; - q_u->info.level = level; - q_u->info.info_ptr = 1; /* Info is != NULL, see above */ - switch (level) { - - /* There's no such thing as a setprinter level 1 */ - - case 2: - secdesc = info->printers_2->secdesc; - devmode = info->printers_2->devmode; - - make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2); -#if 1 /* JERRY TEST */ - q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF); - if (!q_u->secdesc_ctr) - return False; - q_u->secdesc_ctr->sd = secdesc; - q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0; - - q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0; - q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0; - q_u->devmode_ctr.devmode = devmode; -#else - q_u->secdesc_ctr = NULL; - - q_u->devmode_ctr.devmode_ptr = 0; - q_u->devmode_ctr.size = 0; - q_u->devmode_ctr.devmode = NULL; -#endif - break; - case 3: - secdesc = info->printers_3->secdesc; - - make_spoolss_printer_info_3 (mem_ctx, &q_u->info.info_3, info->printers_3); - - q_u->secdesc_ctr = SMB_MALLOC_P(SEC_DESC_BUF); - if (!q_u->secdesc_ctr) - return False; - q_u->secdesc_ctr->sd_size = (secdesc) ? sizeof(SEC_DESC) + (2*sizeof(uint32)) : 0; - q_u->secdesc_ctr->sd = secdesc; - - break; - case 7: - make_spoolss_printer_info_7 (mem_ctx, &q_u->info.info_7, info->printers_7); - break; - - default: - DEBUG(0,("make_spoolss_q_setprinter: Unknown info level [%d]\n", level)); - break; - } - - - q_u->command = command; - - return True; -} - - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_setprinter(const char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_setprinter"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* - Marshall/unmarshall a SPOOL_Q_SETPRINTER struct. -********************************************************************/ - -bool spoolss_io_q_setprinter(const char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth) -{ - uint32 ptr_sec_desc = 0; - - prs_debug(ps, depth, desc, "spoolss_io_q_setprinter"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("printer handle", &q_u->handle ,ps, depth)) - return False; - if(!prs_uint32("level", ps, depth, &q_u->level)) - return False; - - /* check for supported levels and structures we know about */ - - switch ( q_u->level ) { - case 0: - case 2: - case 3: - case 7: - /* supported levels */ - break; - default: - DEBUG(0,("spoolss_io_q_setprinter: unsupported printer info level [%d]\n", - q_u->level)); - return True; - } - - - if(!spool_io_printer_info_level("", &q_u->info, ps, depth)) - return False; - - if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - switch (q_u->level) - { - case 2: - { - ptr_sec_desc = q_u->info.info_2->secdesc_ptr; - break; - } - case 3: - { - /* FIXME ! Our parsing here is wrong I think, - * but for a level3 it makes no sense for - * ptr_sec_desc to be NULL. JRA. Based on - * a Vista sniff from Martin Zielinski <mz@seh.de>. - */ - if (UNMARSHALLING(ps)) { - ptr_sec_desc = 1; - } else { - ptr_sec_desc = q_u->info.info_3->secdesc_ptr; - } - break; - } - } - if (ptr_sec_desc) - { - if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth)) - return False; - } else { - uint32 dummy = 0; - - /* Parse a NULL security descriptor. This should really - happen inside the sec_io_desc_buf() function. */ - - prs_debug(ps, depth, "", "sec_io_desc_buf"); - if (!prs_uint32("size", ps, depth + 1, &dummy)) - return False; - if (!prs_uint32("ptr", ps, depth + 1, &dummy)) - return False; - } - - if(!prs_uint32("command", ps, depth, &q_u->command)) - return False; - - return True; -} - -/******************************************************************* ********************************************************************/ bool spoolss_io_r_enumjobs(const char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth) @@ -2791,316 +2300,6 @@ bool spoolss_io_q_enumports(const char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct } /******************************************************************* - Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure. -********************************************************************/ - -bool spool_io_printer_info_level_1(const char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_1"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("flags", ps, depth, &il->flags)) - return False; - if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr)) - return False; - if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr)) - return False; - if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr)) - return False; - - if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_PRINTER_INFO_LEVEL_3 structure. -********************************************************************/ - -bool spool_io_printer_info_level_3(const char *desc, SPOOL_PRINTER_INFO_LEVEL_3 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr)) - return False; - - return True; -} - -/******************************************************************* - Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure. -********************************************************************/ - -bool spool_io_printer_info_level_2(const char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr)) - return False; - if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr)) - return False; - if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr)) - return False; - if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr)) - return False; - - if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr)) - return False; - if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr)) - return False; - if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr)) - return False; - if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr)) - return False; - if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr)) - return False; - if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr)) - return False; - if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr)) - return False; - if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr)) - return False; - if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr)) - return False; - - if(!prs_uint32("attributes", ps, depth, &il->attributes)) - return False; - if(!prs_uint32("priority", ps, depth, &il->priority)) - return False; - if(!prs_uint32("default_priority", ps, depth, &il->default_priority)) - return False; - if(!prs_uint32("starttime", ps, depth, &il->starttime)) - return False; - if(!prs_uint32("untiltime", ps, depth, &il->untiltime)) - return False; - if(!prs_uint32("status", ps, depth, &il->status)) - return False; - if(!prs_uint32("cjobs", ps, depth, &il->cjobs)) - return False; - if(!prs_uint32("averageppm", ps, depth, &il->averageppm)) - return False; - - if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth)) - return False; - if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth)) - return False; - - return True; -} - -bool spool_io_printer_info_level_7(const char *desc, SPOOL_PRINTER_INFO_LEVEL_7 *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level_7"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("guid_ptr", ps, depth, &il->guid_ptr)) - return False; - if(!prs_uint32("action", ps, depth, &il->action)) - return False; - - if(!smb_io_unistr2("servername", &il->guid, il->guid_ptr, ps, depth)) - return False; - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spool_io_printer_info_level(const char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spool_io_printer_info_level"); - depth++; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("level", ps, depth, &il->level)) - return False; - if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr)) - return False; - - /* if no struct inside just return */ - if (il->info_ptr==0) { - if (UNMARSHALLING(ps)) { - il->info_1=NULL; - il->info_2=NULL; - } - return True; - } - - switch (il->level) { - /* - * level 0 is used by setprinter when managing the queue - * (hold, stop, start a queue) - */ - case 0: - break; - /* DOCUMENT ME!!! What is level 1 used for? */ - case 1: - { - if (UNMARSHALLING(ps)) { - if ((il->info_1=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_1,1)) == NULL) - return False; - } - if (!spool_io_printer_info_level_1("", il->info_1, ps, depth)) - return False; - break; - } - /* - * level 2 is used by addprinter - * and by setprinter when updating printer's info - */ - case 2: - if (UNMARSHALLING(ps)) { - if ((il->info_2=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_2,1)) == NULL) - return False; - } - if (!spool_io_printer_info_level_2("", il->info_2, ps, depth)) - return False; - break; - /* DOCUMENT ME!!! What is level 3 used for? */ - case 3: - { - if (UNMARSHALLING(ps)) { - if ((il->info_3=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_3,1)) == NULL) - return False; - } - if (!spool_io_printer_info_level_3("", il->info_3, ps, depth)) - return False; - break; - } - case 7: - if (UNMARSHALLING(ps)) - if ((il->info_7=PRS_ALLOC_MEM(ps,SPOOL_PRINTER_INFO_LEVEL_7,1)) == NULL) - return False; - if (!spool_io_printer_info_level_7("", il->info_7, ps, depth)) - return False; - break; - } - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_q_addprinterex(const char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth) -{ - uint32 ptr_sec_desc = 0; - - prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_io_unistr2_p("ptr", ps, depth, &q_u->server_name)) - return False; - if (!prs_io_unistr2("servername", ps, depth, q_u->server_name)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("info_level", ps, depth, &q_u->level)) - return False; - - if(!spool_io_printer_info_level("", &q_u->info, ps, depth)) - return False; - - if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - switch (q_u->level) { - case 2: - ptr_sec_desc = q_u->info.info_2->secdesc_ptr; - break; - case 3: - ptr_sec_desc = q_u->info.info_3->secdesc_ptr; - break; - } - if (ptr_sec_desc) { - if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth)) - return False; - } else { - uint32 dummy = 0; - - /* Parse a NULL security descriptor. This should really - happen inside the sec_io_desc_buf() function. */ - - prs_debug(ps, depth, "", "sec_io_desc_buf"); - if (!prs_uint32("size", ps, depth + 1, &dummy)) - return False; - if (!prs_uint32("ptr", ps, depth + 1, &dummy)) - return False; - } - - if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch)) - return False; - if(!spool_io_user_level("", &q_u->user_ctr, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool spoolss_io_r_addprinterex(const char *desc, SPOOL_R_ADDPRINTEREX *r_u, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex"); - depth++; - - if(!smb_io_pol_hnd("printer handle",&r_u->handle,ps,depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* make a BUFFER5 struct from a uint16* ******************************************************************/ @@ -3125,37 +2324,6 @@ bool make_spoolss_buffer5(TALLOC_CTX *mem_ctx, BUFFER5 *buf5, uint32 len, uint16 } /******************************************************************* - ********************************************************************/ - -bool uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, - NT_PRINTER_INFO_LEVEL_2 *d) -{ - DEBUG(7,("Converting from UNICODE to ASCII\n")); - - d->attributes=uni->attributes; - d->priority=uni->priority; - d->default_priority=uni->default_priority; - d->starttime=uni->starttime; - d->untiltime=uni->untiltime; - d->status=uni->status; - d->cjobs=uni->cjobs; - - unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)); - unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)); - unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)); - unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)); - unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)); - unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)); - unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)); - unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)); - unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)); - unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)); - unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)); - - return True; -} - -/******************************************************************* ********************************************************************/ bool spoolss_io_r_enumprintprocessors(const char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth) @@ -3931,20 +3099,3 @@ bool make_spoolss_q_enumforms(SPOOL_Q_ENUMFORMS *q_u, POLICY_HND *handle, return True; } - -/******************************************************************* - * init a structure. - ********************************************************************/ - -bool make_spoolss_q_getjob(SPOOL_Q_GETJOB *q_u, POLICY_HND *handle, - uint32 jobid, uint32 level, RPC_BUFFER *buffer, - uint32 offered) -{ - memcpy(&q_u->handle, handle, sizeof(POLICY_HND)); - q_u->jobid = jobid; - q_u->level = level; - q_u->buffer = buffer; - q_u->offered = offered; - - return True; -} diff --git a/source3/rpc_server/srv_eventlog_lib.c b/source3/rpc_server/srv_eventlog_lib.c index edd1cfacb8..f83c4fc3b8 100644 --- a/source3/rpc_server/srv_eventlog_lib.c +++ b/source3/rpc_server/srv_eventlog_lib.c @@ -936,7 +936,7 @@ NTSTATUS evlog_tdb_entry_to_evt_entry(TALLOC_CTX *mem_ctx, size_t len; if (!convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, t->sid.data, t->sid.length, - &sid_str, &len, false)) { + (void **)&sid_str, &len, false)) { return NT_STATUS_INVALID_SID; } if (len > 0) { diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 33e89c8acb..a5d059c06a 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1247,14 +1247,13 @@ static void np_write_trigger(struct async_req *req) if (async_req_nomem(subreq, req)) { return; } - subreq->async.fn = np_write_done; - subreq->async.private_data = req; + tevent_req_set_callback(subreq, np_write_done, req); } static void np_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct np_write_state *state = talloc_get_type_abort( req->private_data, struct np_write_state); ssize_t received; @@ -1398,14 +1397,13 @@ static void np_read_trigger(struct async_req *req) if (async_req_nomem(subreq, req)) { return; } - subreq->async.fn = np_read_done; - subreq->async.private_data = req; + tevent_req_set_callback(subreq, np_read_done, req); } static void np_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.private_data, struct async_req); + struct async_req *req = + tevent_req_callback_data(subreq, struct async_req); struct np_read_state *state = talloc_get_type_abort( req->private_data, struct np_read_state); ssize_t received; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 62301c001b..814f406e87 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -110,7 +110,7 @@ static int nt_printj_status(int v) case LPQ_DELETED: return JOB_STATUS_DELETED; case LPQ_BLOCKED: - return JOB_STATUS_BLOCKED; + return JOB_STATUS_BLOCKED_DEVQ; case LPQ_USER_INTERVENTION: return JOB_STATUS_USER_INTERVENTION; } @@ -3486,7 +3486,6 @@ static const struct s_notify_info_data_table notify_info_data_table[] = { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages }, { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed }, { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size }, -{ PRINT_TABLE_END, 0x0, NULL, 0x0, NULL }, }; /******************************************************************* @@ -3519,7 +3518,7 @@ static bool search_notify(enum spoolss_NotifyType type, { int i; - for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) { + for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) { if (notify_info_data_table[i].type == type && notify_info_data_table[i].field == field && notify_info_data_table[i].fn != NULL) { @@ -4354,10 +4353,10 @@ static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p strupper_m(guid_str); init_unistr(&printer->guid, guid_str); SAFE_FREE(guid_str); - printer->action = SPOOL_DS_PUBLISH; + printer->action = DSPRINT_PUBLISH; } else { init_unistr(&printer->guid, ""); - printer->action = SPOOL_DS_UNPUBLISH; + printer->action = DSPRINT_UNPUBLISH; } return True; @@ -6619,6 +6618,10 @@ WERROR _spoolss_AddJob(pipes_struct *p, /* this is what a NT server returns for AddJob. AddJob must fail on * non-local printers */ + if (r->in.level != 1) { + return WERR_UNKNOWN_LEVEL; + } + return WERR_INVALID_PARAM; } @@ -8180,28 +8183,21 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p, return WERR_INVALID_PARAM; } - if (r->in.offered > MAX_RPC_DATA_SIZE) { - return WERR_INVALID_PARAM; - } - - DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n")); + DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n", + r->in.level)); *r->out.needed = 0; - switch (r->in.level) { - case 1: - werror = getprinterdriverdir_level_1(p->mem_ctx, - r->in.server, - r->in.environment, - &r->out.info->info1, - r->in.offered, - r->out.needed); - if (!W_ERROR_IS_OK(werror)) { - TALLOC_FREE(r->out.info); - } - break; - default: - return WERR_UNKNOWN_LEVEL; + /* r->in.level is ignored */ + + werror = getprinterdriverdir_level_1(p->mem_ctx, + r->in.server, + r->in.environment, + &r->out.info->info1, + r->in.offered, + r->out.needed); + if (!W_ERROR_IS_OK(werror)) { + TALLOC_FREE(r->out.info); } return werror; @@ -9834,28 +9830,21 @@ WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p, return WERR_INVALID_PARAM; } - if (r->in.offered > MAX_RPC_DATA_SIZE) { - return WERR_INVALID_PARAM; - } - - DEBUG(5,("_spoolss_GetPrintProcessorDirectory\n")); + DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n", + r->in.level)); *r->out.needed = 0; - switch (r->in.level) { - case 1: - result = getprintprocessordirectory_level_1(p->mem_ctx, - r->in.server, - r->in.environment, - &r->out.info->info1, - r->in.offered, - r->out.needed); - if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(r->out.info); - } - break; - default: - result = WERR_UNKNOWN_LEVEL; + /* r->in.level is ignored */ + + result = getprintprocessordirectory_level_1(p->mem_ctx, + r->in.server, + r->in.environment, + &r->out.info->info1, + r->in.offered, + r->out.needed); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(r->out.info); } return result; diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 9955d2d3fa..45df488018 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -1107,6 +1107,49 @@ static NTSTATUS cmd_netlogon_database_redo(struct rpc_pipe_client *cli, return status; } +static NTSTATUS cmd_netlogon_capabilities(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + union netr_Capabilities capabilities; + uint32_t level = 1; + + if (argc > 2) { + fprintf(stderr, "Usage: %s <level>\n", argv[0]); + return NT_STATUS_OK; + } + + if (argc == 2) { + level = atoi(argv[1]); + } + +#if 0 + netlogon_creds_client_step(cli->dc, &credential); +#else + ZERO_STRUCT(credential); +#endif + + status = rpccli_netr_LogonGetCapabilities(cli, mem_ctx, + cli->desthost, + global_myname(), + &credential, + &return_authenticator, + level, + &capabilities); +#if 0 + if (!netlogon_creds_client_check(cli->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } +#endif + + return status; +} + /* List of commands exported by this module */ struct cmd_set netlogon_commands[] = { @@ -1134,6 +1177,7 @@ struct cmd_set netlogon_commands[] = { { "netrenumtrusteddomainsex", RPC_RTYPE_WERROR, NULL, cmd_netlogon_enumtrusteddomainsex, &ndr_table_netlogon.syntax_id, NULL, "Enumerate trusted domains", "" }, { "getdcsitecoverage", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcsitecoverage, &ndr_table_netlogon.syntax_id, NULL, "Get the Site-Coverage from a DC", "" }, { "database_redo", RPC_RTYPE_NTSTATUS, cmd_netlogon_database_redo, NULL, &ndr_table_netlogon.syntax_id, NULL, "Replicate single object from a DC", "" }, + { "capabilities", RPC_RTYPE_NTSTATUS, cmd_netlogon_capabilities, NULL, &ndr_table_netlogon.syntax_id, NULL, "Return Capabilities", "" }, { NULL } }; diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 31977e9554..936c2081f3 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -789,7 +789,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, struct samr_SamArray *dom_users = NULL; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; uint32 acb_mask = ACB_NORMAL; - bool got_connect_pol = False, got_domain_pol = False; if ((argc < 1) || (argc > 3)) { printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]); @@ -811,8 +810,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_connect_pol = True; - /* Get domain policy handle */ result = rpccli_samr_OpenDomain(cli, mem_ctx, @@ -824,8 +821,6 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_domain_pol = True; - /* Enumerate domain users */ start_idx = 0; @@ -852,10 +847,10 @@ static NTSTATUS cmd_samr_enum_dom_users(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_domain_pol) + if (is_valid_policy_hnd(&domain_pol)) rpccli_samr_Close(cli, mem_ctx, &domain_pol); - if (got_connect_pol) + if (is_valid_policy_hnd(&connect_pol)) rpccli_samr_Close(cli, mem_ctx, &connect_pol); return result; @@ -872,7 +867,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, uint32 start_idx, size, num_dom_groups, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; struct samr_SamArray *dom_groups = NULL; - bool got_connect_pol = False, got_domain_pol = False; if ((argc < 1) || (argc > 2)) { printf("Usage: %s [access_mask]\n", argv[0]); @@ -891,8 +885,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_connect_pol = True; - /* Get domain policy handle */ result = rpccli_samr_OpenDomain(cli, mem_ctx, @@ -904,8 +896,6 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_domain_pol = True; - /* Enumerate domain groups */ start_idx = 0; @@ -930,10 +920,10 @@ static NTSTATUS cmd_samr_enum_dom_groups(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_domain_pol) + if (is_valid_policy_hnd(&domain_pol)) rpccli_samr_Close(cli, mem_ctx, &domain_pol); - if (got_connect_pol) + if (is_valid_policy_hnd(&connect_pol)) rpccli_samr_Close(cli, mem_ctx, &connect_pol); return result; @@ -950,7 +940,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, uint32 start_idx, size, num_als_groups, i; uint32 access_mask = MAXIMUM_ALLOWED_ACCESS; struct samr_SamArray *als_groups = NULL; - bool got_connect_pol = False, got_domain_pol = False; if ((argc < 2) || (argc > 3)) { printf("Usage: %s builtin|domain [access mask]\n", argv[0]); @@ -969,8 +958,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_connect_pol = True; - /* Get domain policy handle */ result = get_domain_handle(cli, mem_ctx, argv[1], @@ -982,8 +969,6 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - got_domain_pol = True; - /* Enumerate alias groups */ start_idx = 0; @@ -1008,10 +993,10 @@ static NTSTATUS cmd_samr_enum_als_groups(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_domain_pol) + if (is_valid_policy_hnd(&domain_pol)) rpccli_samr_Close(cli, mem_ctx, &domain_pol); - if (got_connect_pol) + if (is_valid_policy_hnd(&connect_pol)) rpccli_samr_Close(cli, mem_ctx, &connect_pol); return result; @@ -1027,7 +1012,6 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 start_idx, size, num_entries, i; uint32 access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - bool got_connect_pol = false; struct samr_SamArray *sam = NULL; if ((argc < 1) || (argc > 2)) { @@ -1049,8 +1033,6 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, goto done; } - got_connect_pol = true; - /* Enumerate alias groups */ start_idx = 0; @@ -1075,7 +1057,7 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)); done: - if (got_connect_pol) { + if (is_valid_policy_hnd(&connect_pol)) { rpccli_samr_Close(cli, mem_ctx, &connect_pol); } diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 17ff818de6..5b55ac3e2a 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -283,12 +283,10 @@ static void display_print_info_3(PRINTER_INFO_3 *i3) /**************************************************************************** ****************************************************************************/ -static void display_print_info_7(PRINTER_INFO_7 *i7) +static void display_print_info7(struct spoolss_PrinterInfo7 *r) { - fstring guid = ""; - rpcstr_pull(guid, i7->guid.buffer,sizeof(guid), -1, STR_TERMINATE); - printf("\tguid:[%s]\n", guid); - printf("\taction:[0x%x]\n", i7->action); + printf("\tguid:[%s]\n", r->guid); + printf("\taction:[0x%x]\n", r->action); } @@ -469,10 +467,13 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; + NTSTATUS status; uint32 info_level = 2; - bool opened_hnd = False; - PRINTER_INFO_CTR ctr; + union spoolss_PrinterInfo info; + struct spoolss_SetPrinterInfoCtr info_ctr; const char *printername, *comment = NULL; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; if (argc == 1 || argc > 3) { printf("Usage: %s printername comment\n", argv[0]); @@ -485,6 +486,9 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, comment = argv[2]; } + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); /* get a printer handle */ @@ -495,26 +499,36 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + info_level, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; /* Modify the comment. */ - init_unistr(&ctr.printers_2->comment, comment); - ctr.printers_2->devmode = NULL; - ctr.printers_2->secdesc = NULL; + info.info2.comment = comment; + info.info2.secdesc = NULL; + info.info2.devmode = NULL; - result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0); + info_ctr.level = 2; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; + + status = rpccli_spoolss_SetPrinter(cli, mem_ctx, + &pol, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (W_ERROR_IS_OK(result)) printf("Success in setting comment.\n"); done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -529,11 +543,17 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; + NTSTATUS status; uint32 info_level = 2; - bool opened_hnd = False; - PRINTER_INFO_CTR ctr; + union spoolss_PrinterInfo info; const char *printername, *new_printername = NULL; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); if (argc == 1 || argc > 3) { printf("Usage: %s printername new_printername\n", argv[0]); @@ -556,25 +576,35 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + info_level, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; /* Modify the printername. */ - init_unistr(&ctr.printers_2->printername, new_printername); - ctr.printers_2->devmode = NULL; - ctr.printers_2->secdesc = NULL; - - result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, info_level, &ctr, 0); + info.info2.printername = new_printername; + info.info2.devmode = NULL; + info.info2.secdesc = NULL; + + info_ctr.level = info_level; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; + + status = rpccli_spoolss_SetPrinter(cli, mem_ctx, + &pol, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (W_ERROR_IS_OK(result)) printf("Success in setting printername.\n"); done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -590,9 +620,8 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, POLICY_HND pol; WERROR result; uint32 info_level = 1; - bool opened_hnd = False; - PRINTER_INFO_CTR ctr; const char *printername; + union spoolss_PrinterInfo info; if (argc == 1 || argc > 3) { printf("Usage: %s <printername> [level]\n", argv[0]); @@ -615,18 +644,19 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, info_level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + info_level, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; /* Display printer info */ - switch (info_level) { +#if 0 /* FIXME GD */ case 0: display_print_info_0(ctr.printers_0); break; @@ -639,16 +669,16 @@ static WERROR cmd_spoolss_getprinter(struct rpc_pipe_client *cli, case 3: display_print_info_3(ctr.printers_3); break; +#endif case 7: - display_print_info_7(ctr.printers_7); + display_print_info7(&info.info7); break; default: printf("unknown info level %d\n", info_level); break; } - done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -724,7 +754,6 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; - bool opened_hnd = False; fstring printername; const char *valuename; REGISTRY_VALUE value; @@ -753,8 +782,6 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ result = rpccli_spoolss_getprinterdata(cli, mem_ctx, &pol, valuename, &value); @@ -769,7 +796,7 @@ static WERROR cmd_spoolss_getprinterdata(struct rpc_pipe_client *cli, done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -785,7 +812,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, POLICY_HND pol; WERROR result; NTSTATUS status; - bool opened_hnd = False; fstring printername; const char *valuename, *keyname; REGISTRY_VALUE value; @@ -821,8 +847,6 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ status = rpccli_spoolss_GetPrinterDataEx(cli, mem_ctx, @@ -870,7 +894,7 @@ static WERROR cmd_spoolss_getprinterdataex(struct rpc_pipe_client *cli, display_reg_value(value); done: - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -1058,7 +1082,6 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, POLICY_HND pol; WERROR werror; uint32 info_level = 3; - bool opened_hnd = False; const char *printername; uint32 i; bool success = False; @@ -1090,8 +1113,6 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, return werror; } - opened_hnd = True; - /* loop through and print driver info level for each architecture */ for (i=0; archi_table[i].long_archi!=NULL; i++) { @@ -1133,7 +1154,7 @@ static WERROR cmd_spoolss_getdriver(struct rpc_pipe_client *cli, /* Cleanup */ - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); if ( success ) @@ -1489,14 +1510,8 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli, int argc, const char **argv) { WERROR result; - NTSTATUS status; struct spoolss_SetPrinterInfoCtr info_ctr; struct spoolss_SetPrinterInfo2 info2; - struct policy_handle handle; - struct spoolss_DevmodeContainer devmode_ctr; - struct sec_desc_buf sd; - struct spoolss_UserLevelCtr userlevel_ctr; - struct spoolss_UserLevel1 level1; /* parse the command arguments */ if (argc != 5) @@ -1506,9 +1521,7 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli, } /* Fill in the DRIVER_INFO_2 struct */ - ZERO_STRUCT(devmode_ctr); ZERO_STRUCT(info2); - ZERO_STRUCT(sd); info2.printername = argv[1]; info2.drivername = argv[3]; @@ -1536,25 +1549,8 @@ static WERROR cmd_spoolss_addprinterex(struct rpc_pipe_client *cli, info_ctr.level = 2; info_ctr.info.info2 = &info2; - level1.size = 28; /* wild guess */ - level1.build = 1381; - level1.major = 2; - level1.minor = 0; - level1.processor = 0; - level1.client = global_myname(); - level1.user = cli->auth->user_name; - - userlevel_ctr.level = 1; - userlevel_ctr.user_info.level1 = &level1; - - status = rpccli_spoolss_AddPrinterEx(cli, mem_ctx, - cli->srv_name_slash, - &info_ctr, - &devmode_ctr, - &sd, - &userlevel_ctr, - &handle, - &result); + result = rpccli_spoolss_addprinterex(cli, mem_ctx, + &info_ctr); if (W_ERROR_IS_OK(result)) printf ("Printer %s successfully installed.\n", argv[1]); @@ -1570,11 +1566,16 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, { POLICY_HND pol; WERROR result; + NTSTATUS status; uint32 level = 2; - bool opened_hnd = False; - PRINTER_INFO_CTR ctr; - PRINTER_INFO_2 info2; const char *printername; + union spoolss_PrinterInfo info; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); /* parse the command arguments */ if (argc != 3) @@ -1594,15 +1595,13 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - /* Get printer info */ - ZERO_STRUCT (info2); - ctr.printers_2 = &info2; - - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, level, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + level, + 0, + &info); if (!W_ERROR_IS_OK(result)) { printf ("Unable to retrieve printer information!\n"); goto done; @@ -1610,10 +1609,20 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, /* Set the printer driver */ - init_unistr(&ctr.printers_2->drivername, argv[2]); - - result = rpccli_spoolss_setprinter(cli, mem_ctx, &pol, level, &ctr, 0); + info.info2.drivername = argv[2]; + info.info2.devmode = NULL; + info.info2.secdesc = NULL; + info_ctr.level = 2; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info.info2; + + status = rpccli_spoolss_SetPrinter(cli, mem_ctx, + &pol, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (!W_ERROR_IS_OK(result)) { printf("SetPrinter call failed!\n"); goto done;; @@ -1624,7 +1633,7 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, done: /* Cleanup */ - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -1808,14 +1817,15 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; union spoolss_AddFormInfo info; struct spoolss_AddFormInfo1 info1; + struct spoolss_AddFormInfo2 info2; + uint32_t level = 1; /* Parse the command arguments */ - if (argc != 3) { - printf ("Usage: %s <printer> <formname>\n", argv[0]); + if (argc < 3 || argc > 5) { + printf ("Usage: %s <printer> <formname> [level]\n", argv[0]); return WERR_OK; } @@ -1830,32 +1840,58 @@ static WERROR cmd_spoolss_addform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Dummy up some values for the form data */ - info1.flags = FORM_USER; - info1.form_name = argv[2]; - info1.size.width = 100; - info1.size.height = 100; - info1.area.left = 0; - info1.area.top = 10; - info1.area.right = 20; - info1.area.bottom = 30; + if (argc == 4) { + level = atoi(argv[3]); + } - info.info1 = &info1; + switch (level) { + case 1: + info1.flags = FORM_USER; + info1.form_name = argv[2]; + info1.size.width = 100; + info1.size.height = 100; + info1.area.left = 0; + info1.area.top = 10; + info1.area.right = 20; + info1.area.bottom = 30; + + info.info1 = &info1; + + break; + case 2: + info2.flags = FORM_USER; + info2.form_name = argv[2]; + info2.size.width = 100; + info2.size.height = 100; + info2.area.left = 0; + info2.area.top = 10; + info2.area.right = 20; + info2.area.bottom = 30; + info2.keyword = argv[2]; + info2.string_type = SPOOLSS_FORM_STRING_TYPE_NONE; + info2.mui_dll = NULL; + info2.ressource_id = 0; + info2.display_name = argv[2]; + info2.lang_id = 0; + + info.info2 = &info2; + + break; + } /* Add the form */ status = rpccli_spoolss_AddForm(cli, mem_ctx, &handle, - 1, + level, info, &werror); done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -1871,7 +1907,6 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; union spoolss_AddFormInfo info; struct spoolss_AddFormInfo1 info1; @@ -1893,8 +1928,6 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Dummy up some values for the form data */ info1.flags = FORM_PRINTER; @@ -1918,7 +1951,7 @@ static WERROR cmd_spoolss_setform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c &werror); done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -1980,6 +2013,28 @@ static void display_form_info1(struct spoolss_FormInfo1 *r) /**************************************************************************** ****************************************************************************/ +static void display_form_info2(struct spoolss_FormInfo2 *r) +{ + printf("%s\n" \ + "\tflag: %s (%d)\n" \ + "\twidth: %d, length: %d\n" \ + "\tleft: %d, right: %d, top: %d, bottom: %d\n", + r->form_name, get_form_flag(r->flags), r->flags, + r->size.width, r->size.height, + r->area.left, r->area.right, + r->area.top, r->area.bottom); + printf("\tkeyword: %s\n", r->keyword); + printf("\tstring_type: 0x%08x\n", r->string_type); + printf("\tmui_dll: %s\n", r->mui_dll); + printf("\tressource_id: 0x%08x\n", r->ressource_id); + printf("\tdisplay_name: %s\n", r->display_name); + printf("\tlang_id: %d\n", r->lang_id); + printf("\n"); +} + +/**************************************************************************** +****************************************************************************/ + static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { @@ -1987,16 +2042,16 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; DATA_BLOB buffer; uint32_t offered = 0; union spoolss_FormInfo info; uint32_t needed; + uint32_t level = 1; /* Parse the command arguments */ - if (argc != 3) { - printf ("Usage: %s <printer> <formname>\n", argv[0]); + if (argc < 3 || argc > 5) { + printf ("Usage: %s <printer> <formname> [level]\n", argv[0]); return WERR_OK; } @@ -2011,26 +2066,28 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; + if (argc == 4) { + level = atoi(argv[3]); + } /* Get the form */ status = rpccli_spoolss_GetForm(cli, mem_ctx, &handle, argv[2], - 1, + level, NULL, offered, &info, &needed, &werror); if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) { - buffer = data_blob_talloc(mem_ctx, NULL, needed); + buffer = data_blob_talloc_zero(mem_ctx, needed); offered = needed; status = rpccli_spoolss_GetForm(cli, mem_ctx, &handle, argv[2], - 1, + level, &buffer, offered, &info, @@ -2042,9 +2099,17 @@ static WERROR cmd_spoolss_getform(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c return werror; } - display_form_info1(&info.info1); + switch (level) { + case 1: + display_form_info1(&info.info1); + break; + case 2: + display_form_info2(&info.info2); + break; + } + done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -2061,7 +2126,6 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, WERROR werror; NTSTATUS status; const char *printername; - bool got_handle = False; /* Parse the command arguments */ @@ -2081,8 +2145,6 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Delete the form */ status = rpccli_spoolss_DeleteForm(cli, mem_ctx, @@ -2094,7 +2156,7 @@ static WERROR cmd_spoolss_deleteform(struct rpc_pipe_client *cli, } done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -2110,7 +2172,6 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, POLICY_HND handle; WERROR werror; const char *printername; - bool got_handle = False; uint32 num_forms, level = 1, i; FORM_1 *forms; @@ -2132,8 +2193,6 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(werror)) goto done; - got_handle = True; - /* Enumerate forms */ werror = rpccli_spoolss_enumforms(cli, mem_ctx, &handle, level, &num_forms, &forms); @@ -2150,7 +2209,7 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, } done: - if (got_handle) + if (is_valid_policy_hnd(&handle)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL); return werror; @@ -2166,9 +2225,7 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, WERROR result; const char *printername; POLICY_HND pol; - bool opened_hnd = False; - PRINTER_INFO_CTR ctr; - PRINTER_INFO_0 info; + union spoolss_PrinterInfo info; REGISTRY_VALUE value; TALLOC_CTX *tmp_ctx = talloc_stackframe(); @@ -2216,17 +2273,16 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - opened_hnd = True; - - ctr.printers_0 = &info; - - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + 0, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; printf("%s\n", current_timestring(tmp_ctx, True)); - printf("\tchange_id (before set)\t:[0x%x]\n", info.change_id); + printf("\tchange_id (before set)\t:[0x%x]\n", info.info0.change_id); /* Set the printer data */ @@ -2306,18 +2362,21 @@ static WERROR cmd_spoolss_setprinterdata(struct rpc_pipe_client *cli, } printf("\tSetPrinterData succeeded [%s: %s]\n", argv[3], argv[4]); - result = rpccli_spoolss_getprinter(cli, mem_ctx, &pol, 0, &ctr); - + result = rpccli_spoolss_getprinter(cli, mem_ctx, + &pol, + 0, + 0, + &info); if (!W_ERROR_IS_OK(result)) goto done; printf("%s\n", current_timestring(tmp_ctx, True)); - printf("\tchange_id (after set)\t:[0x%x]\n", info.change_id); + printf("\tchange_id (after set)\t:[0x%x]\n", info.info0.change_id); done: /* cleanup */ TALLOC_FREE(tmp_ctx); - if (opened_hnd) + if (is_valid_policy_hnd(&pol)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &pol, NULL); return result; @@ -2368,13 +2427,53 @@ static void display_job_info_2(JOB_INFO_2 *job) /**************************************************************************** ****************************************************************************/ +static void display_job_info1(struct spoolss_JobInfo1 *r) +{ + printf("%d: jobid[%d]: %s %s %s %d/%d pages\n", r->position, r->job_id, + r->user_name, r->document_name, r->text_status, r->pages_printed, + r->total_pages); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_job_info2(struct spoolss_JobInfo2 *r) +{ + printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d bytes\n", + r->position, r->job_id, + r->user_name, r->document_name, r->text_status, r->pages_printed, + r->total_pages, r->size); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_job_info3(struct spoolss_JobInfo3 *r) +{ + printf("jobid[%d], next_jobid[%d]\n", + r->job_id, r->next_job_id); +} + +/**************************************************************************** +****************************************************************************/ + +static void display_job_info4(struct spoolss_JobInfo4 *r) +{ + printf("%d: jobid[%d]: %s %s %s %d/%d pages, %d/%d bytes\n", + r->position, r->job_id, + r->user_name, r->document_name, r->text_status, r->pages_printed, + r->total_pages, r->size, r->size_high); +} + +/**************************************************************************** +****************************************************************************/ + static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { WERROR result; uint32 level = 1, num_jobs, i; - bool got_hnd = False; const char *printername; POLICY_HND hnd; JOB_INFO_CTR ctr; @@ -2398,8 +2497,6 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - got_hnd = True; - /* Enumerate ports */ result = rpccli_spoolss_enumjobs(cli, mem_ctx, &hnd, level, 0, 1000, @@ -2423,7 +2520,7 @@ static WERROR cmd_spoolss_enum_jobs(struct rpc_pipe_client *cli, } done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; @@ -2432,13 +2529,89 @@ done: /**************************************************************************** ****************************************************************************/ +static WERROR cmd_spoolss_get_job(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + WERROR result; + const char *printername; + struct policy_handle hnd; + uint32_t job_id; + uint32_t level = 1; + union spoolss_JobInfo info; + + if (argc < 3 || argc > 4) { + printf("Usage: %s printername job_id [level]\n", argv[0]); + return WERR_OK; + } + + job_id = atoi(argv[2]); + + if (argc == 4) { + level = atoi(argv[3]); + } + + /* Open printer handle */ + + RPCCLIENT_PRINTERNAME(printername, cli, argv[1]); + + result = rpccli_spoolss_openprinter_ex(cli, mem_ctx, + printername, + SEC_FLAG_MAXIMUM_ALLOWED, + &hnd); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* Enumerate ports */ + + result = rpccli_spoolss_getjob(cli, mem_ctx, + &hnd, + job_id, + level, + 0, + &info); + + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + switch (level) { + case 1: + display_job_info1(&info.info1); + break; + case 2: + display_job_info2(&info.info2); + break; + case 3: + display_job_info3(&info.info3); + break; + case 4: + display_job_info4(&info.info4); + break; + default: + d_printf("unknown info level %d\n", level); + break; + } + +done: + if (is_valid_policy_hnd(&hnd)) { + rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); + } + + return result; +} + + +/**************************************************************************** +****************************************************************************/ + static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { WERROR result; uint32 i=0, val_needed, data_needed; - bool got_hnd = False; const char *printername; POLICY_HND hnd; @@ -2458,8 +2631,6 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - got_hnd = True; - /* Enumerate data */ result = rpccli_spoolss_enumprinterdata(cli, mem_ctx, &hnd, i, 0, 0, @@ -2477,7 +2648,7 @@ static WERROR cmd_spoolss_enum_data( struct rpc_pipe_client *cli, result = W_ERROR(ERRsuccess); done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; @@ -2492,7 +2663,6 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, { WERROR result; uint32 i; - bool got_hnd = False; const char *printername; const char *keyname = NULL; POLICY_HND hnd; @@ -2516,8 +2686,6 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - got_hnd = True; - /* Enumerate subkeys */ if ( !(ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) ) @@ -2535,7 +2703,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, TALLOC_FREE( ctr ); done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; @@ -2549,7 +2717,6 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, const char **argv) { WERROR result; - bool got_hnd = False; const char *printername; const char *keyname = NULL; POLICY_HND hnd; @@ -2576,8 +2743,6 @@ static WERROR cmd_spoolss_enum_printerkey( struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) goto done; - got_hnd = True; - /* Enumerate subkeys */ result = rpccli_spoolss_enumprinterkey(cli, mem_ctx, &hnd, keyname, &keylist, NULL); @@ -2601,7 +2766,7 @@ done: SAFE_FREE(keylist); - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; @@ -2617,7 +2782,6 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, const char *printername; const char *clientname; POLICY_HND hnd; - bool got_hnd = False; WERROR result; NTSTATUS status; struct spoolss_NotifyOption option; @@ -2641,8 +2805,6 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, goto done; } - got_hnd = True; - /* Create spool options */ option.version = 2; @@ -2694,7 +2856,7 @@ static WERROR cmd_spoolss_rffpcnex(struct rpc_pipe_client *cli, } done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(cli, mem_ctx, &hnd, NULL); return result; @@ -2706,12 +2868,16 @@ done: static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, struct rpc_pipe_client *cli2, POLICY_HND *hnd2 ) { - PRINTER_INFO_CTR ctr1, ctr2; + union spoolss_PrinterInfo info1, info2; WERROR werror; TALLOC_CTX *mem_ctx = talloc_init("compare_printer"); printf("Retrieving printer propertiesfor %s...", cli1->desthost); - werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 2, &ctr1); + werror = rpccli_spoolss_getprinter(cli1, mem_ctx, + hnd1, + 2, + 0, + &info1); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); @@ -2720,7 +2886,11 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, printf("ok\n"); printf("Retrieving printer properties for %s...", cli2->desthost); - werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 2, &ctr2); + werror = rpccli_spoolss_getprinter(cli2, mem_ctx, + hnd2, + 2, + 0, + &info2); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); @@ -2739,7 +2909,7 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, struct rpc_pipe_client *cli2, POLICY_HND *hnd2 ) { - PRINTER_INFO_CTR ctr1, ctr2; + union spoolss_PrinterInfo info1, info2; WERROR werror; TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc"); SEC_DESC *sd1, *sd2; @@ -2747,7 +2917,11 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("Retrieving printer security for %s...", cli1->desthost); - werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 3, &ctr1); + werror = rpccli_spoolss_getprinter(cli1, mem_ctx, + hnd1, + 3, + 0, + &info1); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); result = False; @@ -2756,7 +2930,11 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("ok\n"); printf("Retrieving printer security for %s...", cli2->desthost); - werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 3, &ctr2); + werror = rpccli_spoolss_getprinter(cli2, mem_ctx, + hnd2, + 3, + 0, + &info2); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); result = False; @@ -2767,14 +2945,8 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("++ "); - if ( (ctr1.printers_3 != ctr2.printers_3) && (!ctr1.printers_3 || !ctr2.printers_3) ) { - printf("NULL PRINTER_INFO_3!\n"); - result = False; - goto done; - } - - sd1 = ctr1.printers_3->secdesc; - sd2 = ctr2.printers_3->secdesc; + sd1 = info1.info3.secdesc; + sd2 = info2.info3.secdesc; if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) { printf("NULL secdesc!\n"); @@ -2905,6 +3077,7 @@ struct cmd_set spoolss_commands[] = { { "enumdataex", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_data_ex, &syntax_spoolss, NULL, "Enumerate printer data for a key", "" }, { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printerkey, &syntax_spoolss, NULL, "Enumerate printer keys", "" }, { "enumjobs", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_jobs, &syntax_spoolss, NULL, "Enumerate print jobs", "" }, + { "getjob", RPC_RTYPE_WERROR, NULL, cmd_spoolss_get_job, &syntax_spoolss, NULL, "Get print job", "" }, { "enumports", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_ports, &syntax_spoolss, NULL, "Enumerate printer ports", "" }, { "enumdrivers", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_drivers, &syntax_spoolss, NULL, "Enumerate installed printer drivers", "" }, { "enumprinters", RPC_RTYPE_WERROR, NULL, cmd_spoolss_enum_printers, &syntax_spoolss, NULL, "Enumerate printers", "" }, diff --git a/source3/services/services_db.c b/source3/services/services_db.c index ef975cfbc4..7a4b90c7cf 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -332,14 +332,14 @@ static void fill_service_values( const char *name, REGVAL_CTR *values ) /******************************************************************** ********************************************************************/ -static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, +static void add_new_svc_name( REGISTRY_KEY *key_parent, struct regsubkey_ctr *subkeys, const char *name ) { REGISTRY_KEY *key_service = NULL, *key_secdesc = NULL; WERROR wresult; char *path = NULL; REGVAL_CTR *values = NULL; - REGSUBKEY_CTR *svc_subkeys = NULL; + struct regsubkey_ctr *svc_subkeys = NULL; SEC_DESC *sd = NULL; DATA_BLOB sd_blob; NTSTATUS status; @@ -366,7 +366,8 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* add the 'Security' key */ - if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, REGSUBKEY_CTR )) ) { + wresult = regsubkey_ctr_init(key_service, &svc_subkeys); + if (!W_ERROR_IS_OK(wresult)) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); TALLOC_FREE( key_service ); return; @@ -444,7 +445,7 @@ void svcctl_init_keys( void ) { const char **service_list = lp_svcctl_list(); int i; - REGSUBKEY_CTR *subkeys = NULL; + struct regsubkey_ctr *subkeys = NULL; REGISTRY_KEY *key = NULL; WERROR wresult; @@ -461,7 +462,8 @@ void svcctl_init_keys( void ) /* lookup the available subkeys */ - if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) { + wresult = regsubkey_ctr_init(key, &subkeys); + if (!W_ERROR_IS_OK(wresult)) { DEBUG(0,("svcctl_init_keys: talloc() failed!\n")); TALLOC_FREE( key ); return; diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 78b8123680..d23b509af2 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -471,6 +471,7 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) SMB_STRUCT_STAT sbuf; struct smb_file_time ft; NTSTATUS status; + int ret = -1; ZERO_STRUCT(sbuf); ZERO_STRUCT(ft); @@ -485,15 +486,19 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp) /* Ensure we have a valid stat struct for the source. */ if (fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } + ret = SMB_VFS_FSTAT(fsp, &sbuf); } else { - if (SMB_VFS_STAT(fsp->conn,fsp->fsp_name,&sbuf) == -1) { - return map_nt_error_from_unix(errno); + if (fsp->posix_open) { + ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name,&sbuf); + } else { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name,&sbuf); } } + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + if (!VALID_STAT(sbuf)) { /* if it doesn't seem to be a real file */ return NT_STATUS_OK; @@ -581,6 +586,13 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, */ saved_status4 = update_write_time_on_close(fsp); + if (NT_STATUS_EQUAL(saved_status4, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + /* Someone renamed the file or a parent directory containing + * this file. We can't do anything about this, we don't have + * an "update timestamp by fd" call in POSIX. Eat the error. */ + + saved_status4 = NT_STATUS_OK; + } if (NT_STATUS_IS_OK(status)) { if (!NT_STATUS_IS_OK(saved_status1)) { diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 4b467b0312..a52f2d2e96 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -140,6 +140,7 @@ find_again: return NULL; } conn->cnum = i; + conn->force_group_gid = (gid_t)-1; bitmap_set(bmap, i); diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index fe7ba1cc46..abffcd2f4f 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -34,6 +34,11 @@ bool can_access_file_acl(struct connection_struct *conn, uint32_t access_granted; struct security_descriptor *secdesc = NULL; + if (conn->server_info->utok.uid == 0 || conn->admin_user) { + /* I'm sorry sir, I didn't know you were root... */ + return true; + } + status = SMB_VFS_GET_NT_ACL(conn, fname, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index a9a97a2d14..adf664b396 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -256,10 +256,9 @@ ssize_t write_file(struct smb_request *req, int write_path = -1; if (fsp->print_file) { - fstring sharename; uint32 jobid; - if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) { + if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) { DEBUG(3,("write_file: Unable to map RAP jobid %u to jobid.\n", (unsigned int)fsp->rap_print_jobid )); errno = EBADF; diff --git a/source3/smbd/files.c b/source3/smbd/files.c index efaadffc06..36e80a086a 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -356,6 +356,49 @@ files_struct *file_find_print(void) } /**************************************************************************** + Find any fsp open with a pathname below that of an already open path. +****************************************************************************/ + +bool file_find_subpath(files_struct *dir_fsp) +{ + files_struct *fsp; + size_t dlen; + char *d_fullname = talloc_asprintf(talloc_tos(), + "%s/%s", + dir_fsp->conn->connectpath, + dir_fsp->fsp_name); + + if (!d_fullname) { + return false; + } + + dlen = strlen(d_fullname); + + for (fsp=Files;fsp;fsp=fsp->next) { + char *d1_fullname; + + if (fsp == dir_fsp) { + continue; + } + + d1_fullname = talloc_asprintf(talloc_tos(), + "%s/%s", + fsp->conn->connectpath, + fsp->fsp_name); + + if (strnequal(d_fullname, d1_fullname, dlen)) { + TALLOC_FREE(d_fullname); + TALLOC_FREE(d1_fullname); + return true; + } + TALLOC_FREE(d1_fullname); + } + + TALLOC_FREE(d_fullname); + return false; +} + +/**************************************************************************** Sync open files on a connection. ****************************************************************************/ diff --git a/source3/smbd/open.c b/source3/smbd/open.c index a42705adb6..acd347520d 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -76,6 +76,15 @@ static NTSTATUS check_open_rights(struct connection_struct *conn, *access_granted = 0; + if (conn->server_info->utok.uid == 0 || conn->admin_user) { + /* I'm sorry sir, I didn't know you were root... */ + *access_granted = access_mask; + if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { + *access_granted |= FILE_GENERIC_ALL; + } + return NT_STATUS_OK; + } + status = SMB_VFS_GET_NT_ACL(conn, fname, (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | @@ -2457,6 +2466,25 @@ static NTSTATUS open_directory(connection_struct *conn, fname, access_mask, &access_granted); + + /* Were we trying to do a directory open + * for delete and didn't get DELETE + * access (only) ? Check if the + * directory allows DELETE_CHILD. + * See here: + * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx + * for details. */ + + if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) && + (access_mask & DELETE_ACCESS) && + (access_granted == DELETE_ACCESS) && + can_delete_file_in_directory(conn, fname))) { + DEBUG(10,("open_directory: overrode ACCESS_DENIED " + "on directory %s\n", + fname )); + status = NT_STATUS_OK; + } + if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("open_directory: check_open_rights on " "file %s failed with %s\n", diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index b30ef23c0e..22e4c1aad7 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2214,6 +2214,16 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp, } if (S_ISDIR(pst->st_mode)) { + if (fsp->posix_open) { + return NT_STATUS_OK; + } + + /* If no pathnames are open below this + directory, allow the rename. */ + + if (file_find_subpath(fsp)) { + return NT_STATUS_ACCESS_DENIED; + } return NT_STATUS_OK; } @@ -2808,9 +2818,9 @@ static void send_file_readbraw(connection_struct *conn, } return; } -#endif normal_readbraw: +#endif outbuf = TALLOC_ARRAY(NULL, char, nread+4); if (!outbuf) { diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 346e8973de..538e04938e 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -730,7 +730,7 @@ void reload_printers(void) DEBUG(3, ("removing stale printer %s\n", pname)); if (is_printer_published(NULL, snum, NULL)) - nt_printer_publish(NULL, snum, SPOOL_DS_UNPUBLISH); + nt_printer_publish(NULL, snum, DSPRINT_UNPUBLISH); del_a_printer(pname); lp_killservice(snum); } diff --git a/source3/smbd/service.c b/source3/smbd/service.c index dcdd69f997..eb16a2601e 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -833,6 +833,14 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, *pstatus = status; return NULL; } + + /* + * We need to cache this gid, to use within + * change_to_user() separately from the conn->server_info + * struct. We only use conn->server_info directly if + * "force_user" was set. + */ + conn->force_group_gid = conn->server_info->utok.gid; } conn->vuid = (vuser != NULL) ? vuser->vuid : UID_FIELD_INVALID; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 759e520866..ee1dda98b2 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4972,6 +4972,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, ****************************************************************************/ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, + files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 dosmode) @@ -4980,6 +4981,14 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + if (fsp) { + if (fsp->base_fsp) { + fname = fsp->base_fsp->fsp_name; + } else { + fname = fsp->fsp_name; + } + } + if (dosmode) { if (S_ISDIR(psbuf->st_mode)) { dosmode |= aDIR; @@ -5723,12 +5732,11 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, /* Set the attributes */ dosmode = IVAL(pdata,32); - status = smb_set_file_dosmode(conn, fname, psbuf, dosmode); + status = smb_set_file_dosmode(conn, fsp, fname, psbuf, dosmode); if (!NT_STATUS_IS_OK(status)) { return status; } - /* access time */ ft.atime = interpret_long_date(pdata+8); @@ -6415,6 +6423,8 @@ static NTSTATUS smb_posix_open(connection_struct *conn, create_disp = FILE_OVERWRITE_IF; } else if((wire_open_mode & SMB_O_CREAT) == SMB_O_CREAT) { create_disp = FILE_OPEN_IF; + } else if ((wire_open_mode & (SMB_O_CREAT | SMB_O_EXCL | SMB_O_TRUNC)) == 0) { + create_disp = FILE_OPEN; } else { DEBUG(5,("smb_posix_open: invalid create mode 0x%x\n", (unsigned int)wire_open_mode )); diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 4f059bdb59..f8c55b1b8f 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -254,6 +254,8 @@ bool change_to_user(connection_struct *conn, uint16 vuid) if((group_c = *lp_force_group(snum))) { + SMB_ASSERT(conn->force_group_gid != (gid_t)-1); + if(group_c == '+') { /* @@ -266,15 +268,18 @@ bool change_to_user(connection_struct *conn, uint16 vuid) int i; for (i = 0; i < num_groups; i++) { if (group_list[i] - == conn->server_info->utok.gid) { - gid = conn->server_info->utok.gid; + == conn->force_group_gid) { + conn->server_info->utok.gid = + conn->force_group_gid; + gid = conn->force_group_gid; gid_to_sid(&conn->server_info->ptok ->user_sids[1], gid); break; } } } else { - gid = conn->server_info->utok.gid; + conn->server_info->utok.gid = conn->force_group_gid; + gid = conn->force_group_gid; gid_to_sid(&conn->server_info->ptok->user_sids[1], gid); } diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c index 0c2cd24fb2..38a2553e53 100644 --- a/source3/utils/net_conf.c +++ b/source3/utils/net_conf.c @@ -338,11 +338,11 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx, servicename, &service); if (!W_ERROR_IS_OK(werr)) { - goto done; + goto cancel; } werr = import_process_service(c, conf_ctx, service); if (!W_ERROR_IS_OK(werr)) { - goto done; + goto cancel; } } else { struct smbconf_service **services = NULL; @@ -352,24 +352,72 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx, &num_shares, &services); if (!W_ERROR_IS_OK(werr)) { - goto done; + goto cancel; } if (!c->opt_testmode) { werr = smbconf_drop(conf_ctx); if (!W_ERROR_IS_OK(werr)) { - goto done; + goto cancel; } } + + /* + * Wrap the importing of shares into a transaction, + * but only 100 at a time, in order to serve memory. + * The allocated memory accumulates across the actions + * within the transaction, and for me, some 1500 + * imported shares, the MAX_TALLOC_SIZE of 256 MB + * was exceeded. + */ + werr = smbconf_transaction_start(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error starting transaction: %s\n", + win_errstr(werr)); + goto done; + } + for (sidx = 0; sidx < num_shares; sidx++) { werr = import_process_service(c, conf_ctx, services[sidx]); if (!W_ERROR_IS_OK(werr)) { + goto cancel; + } + + if (sidx % 100) { + continue; + } + + werr = smbconf_transaction_commit(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error committing transaction: %s\n", + win_errstr(werr)); + goto done; + } + werr = smbconf_transaction_start(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error starting transaction: %s\n", + win_errstr(werr)); goto done; } } } - ret = 0; + werr = smbconf_transaction_commit(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error committing transaction: %s\n", + win_errstr(werr)); + } else { + ret = 0; + } + + goto done; + +cancel: + werr = smbconf_transaction_cancel(conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + d_printf("error cancelling transaction: %s\n", + win_errstr(werr)); + } done: TALLOC_FREE(mem_ctx); diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index 17df69597f..8116764d9b 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -775,13 +775,16 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, - PRINTER_INFO_CTR *ctr) + union spoolss_PrinterInfo *info) { WERROR result; /* getprinter call */ - result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx, hnd, level, ctr); - + result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx, + hnd, + level, + 0, /* offered */ + info); if (!W_ERROR_IS_OK(result)) { printf("cannot get printer-info: %s\n", win_errstr(result)); return false; @@ -794,12 +797,64 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 level, - PRINTER_INFO_CTR *ctr) + union spoolss_PrinterInfo *info) { WERROR result; + NTSTATUS status; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); /* setprinter call */ - result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, hnd, level, ctr, 0); + + info_ctr.level = level; + switch (level) { + case 0: + info_ctr.info.info0 = (struct spoolss_SetPrinterInfo0 *)&info->info0; + break; + case 1: + info_ctr.info.info1 = (struct spoolss_SetPrinterInfo1 *)&info->info1; + break; + case 2: + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info->info2; + break; + case 3: + info_ctr.info.info3 = (struct spoolss_SetPrinterInfo3 *)&info->info3; + break; + case 4: + info_ctr.info.info4 = (struct spoolss_SetPrinterInfo4 *)&info->info4; + break; + case 5: + info_ctr.info.info5 = (struct spoolss_SetPrinterInfo5 *)&info->info5; + break; + case 6: + info_ctr.info.info6 = (struct spoolss_SetPrinterInfo6 *)&info->info6; + break; + case 7: + info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info->info7; + break; +#if 0 /* FIXME GD */ + case 8: + info_ctr.info.info8 = (struct spoolss_SetPrinterInfo8 *)&info->info8; + break; + case 9: + info_ctr.info.info9 = (struct spoolss_SetPrinterInfo9 *)&info->info9; + break; +#endif + default: + break; /* FIXME */ + } + + status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx, + hnd, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); if (!W_ERROR_IS_OK(result)) { printf("cannot set printer-info: %s\n", win_errstr(result)); @@ -1027,6 +1082,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, { POLICY_HND hnd; + union spoolss_PrinterInfo info; /* no arguments given, enumerate all printers */ if (argc == 0) { @@ -1039,6 +1095,8 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, goto out; } + /* FIXME GD */ + return false; /* argument given, get a single printer by name */ if (!net_spoolss_open_printer_ex(pipe_hnd, mem_ctx, argv[0], @@ -1047,7 +1105,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, &hnd)) return false; - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, ctr)) { + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return false; } @@ -1216,9 +1274,12 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ uint32 i, num_printers; uint32 level = 7; char *printername, *sharename; - PRINTER_INFO_CTR ctr, ctr_pub; + PRINTER_INFO_CTR ctr; + union spoolss_PrinterInfo info; + struct spoolss_SetPrinterInfoCtr info_ctr; + struct spoolss_DevmodeContainer devmode_ctr; + struct sec_desc_buf secdesc_ctr; POLICY_HND hnd; - bool got_hnd = false; WERROR result; const char *action_str; @@ -1246,21 +1307,19 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ PRINTER_ALL_ACCESS, pipe_hnd->auth->user_name, &hnd)) goto done; - got_hnd = true; - /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; /* check action and set string */ switch (action) { - case SPOOL_DS_PUBLISH: + case DSPRINT_PUBLISH: action_str = "published"; break; - case SPOOL_DS_UPDATE: + case DSPRINT_UPDATE: action_str = "updated"; break; - case SPOOL_DS_UNPUBLISH: + case DSPRINT_UNPUBLISH: action_str = "unpublished"; break; default: @@ -1269,9 +1328,21 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ break; } - ctr_pub.printers_7->action = action; + info.info7.action = action; + info_ctr.level = 7; + info_ctr.info.info7 = (struct spoolss_SetPrinterInfo7 *)&info.info7; + + ZERO_STRUCT(devmode_ctr); + ZERO_STRUCT(secdesc_ctr); + + nt_status = rpccli_spoolss_SetPrinter(pipe_hnd, mem_ctx, + &hnd, + &info_ctr, + &devmode_ctr, + &secdesc_ctr, + 0, /* command */ + &result); - result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub, 0); if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) != W_ERROR_V(WERR_IO_PENDING))) { printf("cannot set printer-info: %s\n", win_errstr(result)); goto done; @@ -1283,7 +1354,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ nt_status = NT_STATUS_OK; done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return nt_status; @@ -1298,7 +1369,7 @@ NTSTATUS rpc_printer_publish_publish_internals(struct net_context *c, int argc, const char **argv) { - return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_PUBLISH); + return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_PUBLISH); } NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c, @@ -1310,7 +1381,7 @@ NTSTATUS rpc_printer_publish_unpublish_internals(struct net_context *c, int argc, const char **argv) { - return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_UNPUBLISH); + return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UNPUBLISH); } NTSTATUS rpc_printer_publish_update_internals(struct net_context *c, @@ -1322,7 +1393,7 @@ NTSTATUS rpc_printer_publish_update_internals(struct net_context *c, int argc, const char **argv) { - return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, SPOOL_DS_UPDATE); + return rpc_printer_publish_internals_args(pipe_hnd, mem_ctx, argc, argv, DSPRINT_UPDATE); } /** @@ -1355,10 +1426,9 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, uint32 i, num_printers; uint32 level = 7; char *printername, *sharename; - char *guid; PRINTER_INFO_CTR ctr, ctr_pub; + union spoolss_PrinterInfo info; POLICY_HND hnd; - bool got_hnd = false; int state; if (!get_printer_info(pipe_hnd, mem_ctx, 2, argc, argv, &num_printers, &ctr)) @@ -1387,32 +1457,25 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, PRINTER_ALL_ACCESS, cli->user_name, &hnd)) goto done; - got_hnd = true; - /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd, level, &info)) goto done; - rpcstr_pull_talloc(mem_ctx, - &guid, - ctr_pub.printers_7->guid.buffer, - -1, - STR_TERMINATE); - if (!guid) { + if (!info.info7.guid) { goto done; } - state = ctr_pub.printers_7->action; + state = info.info7.action; switch (state) { - case SPOOL_DS_PUBLISH: + case DSPRINT_PUBLISH: printf("printer [%s] is published", sharename); if (c->opt_verbose) - printf(", guid: %s", guid); + printf(", guid: %s", info.info7.guid); printf("\n"); break; - case SPOOL_DS_UNPUBLISH: + case DSPRINT_UNPUBLISH: printf("printer [%s] is unpublished\n", sharename); break; - case SPOOL_DS_UPDATE: + case DSPRINT_UPDATE: printf("printer [%s] is currently updating\n", sharename); break; default: @@ -1424,7 +1487,7 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, nt_status = NT_STATUS_OK; done: - if (got_hnd) + if (is_valid_policy_hnd(&hnd)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd, NULL); return nt_status; @@ -1464,12 +1527,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, uint32 num_printers; uint32 level = 2; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum; + PRINTER_INFO_CTR ctr_src, ctr_enum; struct cli_state *cli_dst = NULL; + union spoolss_PrinterInfo info_src, info_dst; ZERO_STRUCT(ctr_src); @@ -1530,47 +1592,41 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; /* check for existing src printer */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &ctr_src)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, 3, &info_src)) goto done; /* Copy Security Descriptor */ /* copy secdesc (info level 2) */ - ctr_dst.printers_2->devmode = NULL; - ctr_dst.printers_2->secdesc = dup_sec_desc(mem_ctx, ctr_src.printers_3->secdesc); + info_dst.info2.devmode = NULL; + info_dst.info2.secdesc = dup_sec_desc(mem_ctx, info_src.info3.secdesc); if (c->opt_verbose) - display_sec_desc(ctr_dst.printers_2->secdesc); + display_sec_desc(info_dst.info2.secdesc); - if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &ctr_dst)) + if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) goto done; DEBUGADD(1,("\tSetPrinter of SECDESC succeeded\n")); /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } @@ -1579,11 +1635,11 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, done: - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); } @@ -1625,11 +1681,10 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, uint32 num_printers; uint32 level = 1; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_enum, ctr_dst; + PRINTER_INFO_CTR ctr_enum; + union spoolss_PrinterInfo info_dst; uint32 num_forms; FORM_1 *forms; struct cli_state *cli_dst = NULL; @@ -1686,19 +1741,13 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - - /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - - /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) goto done; /* finally migrate forms */ @@ -1758,14 +1807,12 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } @@ -1773,10 +1820,10 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, done: - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { @@ -1816,14 +1863,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, uint32 num_printers; uint32 level = 3; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; bool got_src_driver_share = false; bool got_dst_driver_share = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; union spoolss_DriverInfo drv_info_src; PRINTER_INFO_CTR info_ctr_enum, info_ctr_dst; + union spoolss_PrinterInfo info_dst; struct cli_state *cli_dst = NULL; struct cli_state *cli_share_src = NULL; struct cli_state *cli_share_dst = NULL; @@ -1900,10 +1946,8 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) goto done; @@ -1914,9 +1958,6 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, &hnd_src)) goto done; - got_hnd_src = true; - - /* in a first step call getdriver for each shared printer (per arch) to get a list of all files that have to be copied */ @@ -1965,9 +2006,9 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, } /* setdriver dst */ - init_unistr(&info_ctr_dst.printers_2->drivername, drivername); + info_dst.info2.drivername = drivername; - if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_ctr_dst)) { + if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 2, &info_dst)) { nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -1976,15 +2017,13 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, drivername, printername)); /* close dst */ - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } /* close src */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } } @@ -1992,10 +2031,10 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, done: - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { @@ -2043,13 +2082,13 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; uint32 i = 0, num_printers; uint32 level = 2; - PRINTER_INFO_CTR ctr_src, ctr_dst, ctr_enum; + PRINTER_INFO_CTR ctr_enum; + union spoolss_PrinterInfo info_dst, info_src; struct cli_state *cli_dst = NULL; POLICY_HND hnd_dst, hnd_src; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; + struct spoolss_SetPrinterInfoCtr info_ctr; DEBUG(3,("copying printers\n")); @@ -2100,19 +2139,16 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, PRINTER_ALL_ACCESS, cli->user_name, &hnd_dst)) { DEBUG(1,("could not open printer: %s\n", sharename)); - } else { - got_hnd_dst = true; } /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &ctr_dst)) { + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) { printf ("could not get printer, creating printer.\n"); } else { DEBUG(1,("printer already exists: %s\n", sharename)); /* close printer handle here - dst only, not got src yet. */ - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } continue; } @@ -2125,16 +2161,20 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - /* getprinter on the src server */ - if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &ctr_src)) + if (!net_spoolss_getprinter(pipe_hnd, mem_ctx, &hnd_src, level, &info_src)) goto done; /* copy each src printer to a dst printer 1:1, maybe some values have to be changed though */ d_printf("creating printer: %s\n", printername); - result = rpccli_spoolss_addprinterex (pipe_hnd_dst, mem_ctx, level, &ctr_src); + + info_ctr.level = level; + info_ctr.info.info2 = (struct spoolss_SetPrinterInfo2 *)&info_src.info2; + + result = rpccli_spoolss_addprinterex(pipe_hnd_dst, + mem_ctx, + &info_ctr); if (W_ERROR_IS_OK(result)) d_printf ("printer [%s] successfully added.\n", printername); @@ -2146,24 +2186,22 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, } /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } nt_status = NT_STATUS_OK; done: - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { @@ -2208,11 +2246,10 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, uint32 num_printers, val_needed, data_needed; uint32 level = 2; char *printername, *sharename; - bool got_hnd_src = false; - bool got_hnd_dst = false; struct rpc_pipe_client *pipe_hnd_dst = NULL; POLICY_HND hnd_src, hnd_dst; - PRINTER_INFO_CTR ctr_enum, ctr_dst, ctr_dst_publish; + PRINTER_INFO_CTR ctr_enum; + union spoolss_PrinterInfo info_dst_publish, info_dst; REGVAL_CTR *reg_ctr; struct cli_state *cli_dst = NULL; char *devicename = NULL, *unc_name = NULL, *url = NULL; @@ -2221,6 +2258,8 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, uint16 *keylist = NULL, *curkey; ZERO_STRUCT(ctr_enum); + /* FIXME GD */ + ZERO_STRUCT(info_dst_publish); DEBUG(3,("copying printer settings\n")); @@ -2280,44 +2319,39 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, MAXIMUM_ALLOWED_ACCESS, cli->user_name, &hnd_src)) goto done; - got_hnd_src = true; - - /* open dst printer handle */ if (!net_spoolss_open_printer_ex(pipe_hnd_dst, mem_ctx, sharename, PRINTER_ALL_ACCESS, cli_dst->user_name, &hnd_dst)) goto done; - got_hnd_dst = true; - - /* check for existing dst printer */ if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, - level, &ctr_dst)) + level, &info_dst)) goto done; +#if 0 /* FIXME GD */ /* STEP 1: COPY DEVICE-MODE and other PRINTER_INFO_2-attributes */ - ctr_dst.printers_2 = &ctr_enum.printers_2[i]; + info_dst.info2 = &ctr_enum.printers_2[i]; /* why is the port always disconnected when the printer is correctly installed (incl. driver ???) */ - init_unistr( &ctr_dst.printers_2->portname, SAMBA_PRINTER_PORT_NAME); + info_dst.info2.portname = SAMBA_PRINTER_PORT_NAME; /* check if printer is published */ if (ctr_enum.printers_2[i].attributes & PRINTER_ATTRIBUTE_PUBLISHED) { /* check for existing dst printer */ - if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish)) + if (!net_spoolss_getprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish)) goto done; - ctr_dst_publish.printers_7->action = SPOOL_DS_PUBLISH; + info_dst_publish.info7.action = DSPRINT_PUBLISH; /* ignore false from setprinter due to WERR_IO_PENDING */ - net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &ctr_dst_publish); + net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, 7, &info_dst_publish); DEBUG(3,("republished printer\n")); } @@ -2325,14 +2359,14 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, if (ctr_enum.printers_2[i].devmode != NULL) { /* copy devmode (info level 2) */ - ctr_dst.printers_2->devmode = (DEVICEMODE *) + info_dst.info2.devmode = (DEVICEMODE *) TALLOC_MEMDUP(mem_ctx, ctr_enum.printers_2[i].devmode, sizeof(DEVICEMODE)); /* do not copy security descriptor (we have another * command for that) */ - ctr_dst.printers_2->secdesc = NULL; + info_dst.info2.secdesc = NULL; #if 0 if (asprintf(&devicename, "\\\\%s\\%s", longname, @@ -2345,12 +2379,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, devicename); #endif if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, - level, &ctr_dst)) + level, &info_dst)) goto done; DEBUGADD(1,("\tSetPrinter of DEVICEMODE succeeded\n")); } - +#endif /* STEP 2: COPY REGISTRY VALUES */ /* please keep in mind that samba parse_spools gives horribly @@ -2529,14 +2563,12 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, SAFE_FREE(keylist); /* close printer handles here */ - if (got_hnd_src) { + if (is_valid_policy_hnd(&hnd_src)) { rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - got_hnd_src = false; } - if (got_hnd_dst) { + if (is_valid_policy_hnd(&hnd_dst)) { rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); - got_hnd_dst = false; } } @@ -2548,10 +2580,10 @@ done: SAFE_FREE(url); SAFE_FREE(unc_name); - if (got_hnd_src) + if (is_valid_policy_hnd(&hnd_src)) rpccli_spoolss_ClosePrinter(pipe_hnd, mem_ctx, &hnd_src, NULL); - if (got_hnd_dst) + if (is_valid_policy_hnd(&hnd_dst)) rpccli_spoolss_ClosePrinter(pipe_hnd_dst, mem_ctx, &hnd_dst, NULL); if (cli_dst) { diff --git a/source3/utils/net_rpc_registry.c b/source3/utils/net_rpc_registry.c index 005e3ca556..00c827928e 100644 --- a/source3/utils/net_rpc_registry.c +++ b/source3/utils/net_rpc_registry.c @@ -971,12 +971,15 @@ static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, { REGF_NK_REC *key, *subkey; REGVAL_CTR *values = NULL; - REGSUBKEY_CTR *subkeys = NULL; + struct regsubkey_ctr *subkeys = NULL; int i; char *path = NULL; + WERROR werr; - if ( !( subkeys = TALLOC_ZERO_P( infile->mem_ctx, REGSUBKEY_CTR )) ) { - DEBUG(0,("write_registry_tree: talloc() failed!\n")); + werr = regsubkey_ctr_init(infile->mem_ctx, &subkeys); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("write_registry_tree: regsubkey_ctr_init failed: " + "%s\n", win_errstr(werr))); return false; } @@ -993,7 +996,7 @@ static bool write_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) ); } - /* copy subkeys into the REGSUBKEY_CTR */ + /* copy subkeys into the struct regsubkey_ctr */ while ( (subkey = regfio_fetch_subkey( infile, nk )) ) { regsubkey_ctr_addkey( subkeys, subkey->keyname ); diff --git a/source3/utils/profiles.c b/source3/utils/profiles.c index bbbaaf089f..0ac93dedeb 100644 --- a/source3/utils/profiles.c +++ b/source3/utils/profiles.c @@ -118,9 +118,10 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, REGF_NK_REC *key, *subkey; SEC_DESC *new_sd; REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; + struct regsubkey_ctr *subkeys; int i; char *path; + WERROR werr; /* swap out the SIDs in the security descriptor */ @@ -132,7 +133,8 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, verbose_output("ACL for %s%s%s\n", parentpath, parent ? "\\" : "", nk->keyname); swap_sid_in_acl( new_sd, &old_sid, &new_sid ); - if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) { + werr = regsubkey_ctr_init(NULL, &subkeys); + if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("copy_registry_tree: talloc() failure!\n")); return False; } @@ -150,7 +152,7 @@ static bool copy_registry_tree( REGF_FILE *infile, REGF_NK_REC *nk, (const char *)nk->values[i].data, (nk->values[i].data_size & ~VK_DATA_IN_OFFSET) ); } - /* copy subkeys into the REGSUBKEY_CTR */ + /* copy subkeys into the struct regsubkey_ctr */ while ( (subkey = regfio_fetch_subkey( infile, nk )) ) { regsubkey_ctr_addkey( subkeys, subkey->keyname ); diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c index b22e5af94a..5c29ba0b22 100644 --- a/source3/winbindd/idmap_ad.c +++ b/source3/winbindd/idmap_ad.c @@ -304,6 +304,11 @@ static NTSTATUS idmap_ad_unixids_to_sids(struct idmap_domain *dom, struct id_map char *u_filter = NULL; char *g_filter = NULL; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + /* Only do query if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; @@ -516,6 +521,11 @@ static NTSTATUS idmap_ad_sids_to_unixids(struct idmap_domain *dom, struct id_map int i; char *sidstr; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + /* Only do query if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; diff --git a/source3/winbindd/idmap_adex/idmap_adex.c b/source3/winbindd/idmap_adex/idmap_adex.c index 7e186ca8a1..e2fcda83d3 100644 --- a/source3/winbindd/idmap_adex/idmap_adex.c +++ b/source3/winbindd/idmap_adex/idmap_adex.c @@ -159,6 +159,11 @@ static NTSTATUS _idmap_adex_get_sid_from_id(struct NTSTATUS nt_status; struct likewise_cell *cell; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + nt_status = _idmap_adex_init(dom, NULL); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; @@ -207,6 +212,11 @@ static NTSTATUS _idmap_adex_get_id_from_sid(struct NTSTATUS nt_status; struct likewise_cell *cell; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + nt_status = _idmap_adex_init(dom, NULL); if (!NT_STATUS_IS_OK(nt_status)) return nt_status; diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c index 7dd94aede0..42830720f3 100644 --- a/source3/winbindd/idmap_hash/idmap_hash.c +++ b/source3/winbindd/idmap_hash/idmap_hash.c @@ -160,6 +160,11 @@ static NTSTATUS unixids_to_sids(struct idmap_domain *dom, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + nt_status = be_init(dom, NULL); BAIL_ON_NTSTATUS_ERROR(nt_status); @@ -206,6 +211,11 @@ static NTSTATUS sids_to_unixids(struct idmap_domain *dom, NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + nt_status = be_init(dom, NULL); BAIL_ON_NTSTATUS_ERROR(nt_status); diff --git a/source3/winbindd/idmap_ldap.c b/source3/winbindd/idmap_ldap.c index c86a5023d0..7224589076 100644 --- a/source3/winbindd/idmap_ldap.c +++ b/source3/winbindd/idmap_ldap.c @@ -935,6 +935,10 @@ static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom, multi = True; } + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + again: if (multi) { @@ -1156,6 +1160,10 @@ static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom, multi = True; } + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + again: if (multi) { diff --git a/source3/winbindd/idmap_nss.c b/source3/winbindd/idmap_nss.c index 156fdc7cc9..f50e6172ba 100644 --- a/source3/winbindd/idmap_nss.c +++ b/source3/winbindd/idmap_nss.c @@ -44,6 +44,11 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma TALLOC_CTX *ctx; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_new(dom); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); @@ -130,6 +135,11 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma TALLOC_CTX *ctx; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_new(dom); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); diff --git a/source3/winbindd/idmap_rid.c b/source3/winbindd/idmap_rid.c index 9d1898708c..359bbfd411 100644 --- a/source3/winbindd/idmap_rid.c +++ b/source3/winbindd/idmap_rid.c @@ -171,6 +171,11 @@ static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context); ctx = talloc_new(dom); @@ -205,6 +210,11 @@ static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context); ctx = talloc_new(dom); diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c index 3a64979f33..22c17578e6 100644 --- a/source3/winbindd/idmap_tdb.c +++ b/source3/winbindd/idmap_tdb.c @@ -775,6 +775,11 @@ static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); for (i = 0; ids[i]; i++) { @@ -813,6 +818,11 @@ static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); for (i = 0; ids[i]; i++) { diff --git a/source3/winbindd/idmap_tdb2.c b/source3/winbindd/idmap_tdb2.c index fb90dd097e..b2723270eb 100644 --- a/source3/winbindd/idmap_tdb2.c +++ b/source3/winbindd/idmap_tdb2.c @@ -655,6 +655,11 @@ static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_m NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); for (i = 0; ids[i]; i++) { @@ -692,6 +697,11 @@ static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_m NTSTATUS ret; int i; + /* initialize the status to avoid suprise */ + for (i = 0; ids[i]; i++) { + ids[i]->status = ID_UNKNOWN; + } + ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); for (i = 0; ids[i]; i++) { |