diff options
97 files changed, 2841 insertions, 1873 deletions
diff --git a/examples/logon/genlogon/genlogon.pl b/examples/logon/genlogon/genlogon.pl index 8ebf3921411..4799ac8452d 100644 --- a/examples/logon/genlogon/genlogon.pl +++ b/examples/logon/genlogon/genlogon.pl @@ -45,7 +45,7 @@ if ($ARGV[1] eq "SUPPORT" || $ARGV[0] eq "support") } # Connect shares just used by Administration staff -If ($ARGV[1] eq "ADMIN" || $ARGV[0] eq "admin") +if ($ARGV[1] eq "ADMIN" || $ARGV[0] eq "admin") { print LOGON "NET USE L: \\\\$ARGV[2]\\ADMIN\r\n"; print LOGON "NET USE K: \\\\$ARGV[2]\\MKTING\r\n"; diff --git a/source3/Makefile.in b/source3/Makefile.in index 5257b6fcac1..53fd669b4c1 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -285,9 +285,12 @@ NSS_WRAPPER_OBJ = @NSS_WRAPPER_OBJS@ TALLOC_OBJ = lib/talloc/talloc.o -LIBSAMBAUTIL_OBJ = $(TALLOC_OBJ) $(LIBREPLACE_OBJ) +LIBSAMBAUTIL_OBJ = $(TALLOC_OBJ) \ + $(LIBREPLACE_OBJ) \ + $(SOCKET_WRAPPER_OBJ) \ + $(NSS_WRAPPER_OBJ) -LIB_WITHOUT_PROTO_OBJ = $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ) $(NSS_WRAPPER_OBJ) $(TALLOC_OBJ) \ +LIB_WITHOUT_PROTO_OBJ = $(LIBSAMBAUTIL_OBJ) \ lib/messages.o librpc/gen_ndr/ndr_messaging.o lib/messages_local.o \ lib/messages_ctdbd.o lib/packet.o lib/ctdbd_conn.o lib/talloc_stack.o \ lib/interfaces.o lib/rbtree.o lib/memcache.o \ @@ -337,13 +340,13 @@ LIBADDNS_OBJ0 = libaddns/dnsrecord.o libaddns/dnsutils.o libaddns/dnssock.o \ libaddns/dnsgss.o libaddns/dnsmarshall.o LIBADDNS_OBJ = $(LIBADDNS_OBJ0) $(TALLOC_OBJ) -LIBWBCLIENT_OBJ = nsswitch/libwbclient/wbclient.o \ +LIBWBCLIENT_OBJ0 = nsswitch/libwbclient/wbclient.o \ nsswitch/libwbclient/wbc_util.o \ nsswitch/libwbclient/wbc_pwd.o \ nsswitch/libwbclient/wbc_idmap.o \ nsswitch/libwbclient/wbc_sid.o \ nsswitch/libwbclient/wbc_pam.o - +LIBWBCLIENT_OBJ = $(LIBWBCLIENT_OBJ0) $(WBCOMMON_OBJ) $(TALLOC_OBJ) $(LIBREPLACE_OBJ) LIBGPO_OBJ0 = libgpo/gpo_ldap.o libgpo/gpo_ini.o libgpo/gpo_util.o \ libgpo/gpo_fetch.o libgpo/gpo_filesync.o libgpo/gpo_sec.o @@ -500,6 +503,7 @@ VFS_CAP_OBJ = modules/vfs_cap.o VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o VFS_AFSACL_OBJ = modules/vfs_afsacl.o +VFS_EA_TDB_OBJ = modules/vfs_ea_tdb.o librpc/gen_ndr/ndr_xattr.o VFS_POSIXACL_OBJ = modules/vfs_posixacl.o VFS_AIXACL_OBJ = modules/vfs_aixacl.o modules/vfs_aixacl_util.o VFS_AIXACL2_OBJ = modules/vfs_aixacl2.o modules/vfs_aixacl_util.o modules/nfs4_acls.o @@ -668,7 +672,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(LDB_OBJ) PAM_WINBIND_OBJ = nsswitch/pam_winbind.o $(WBCOMMON_OBJ) \ - $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ) @BUILD_INIPARSER@ + $(LIBREPLACE_OBJ) @BUILD_INIPARSER@ LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \ libsmb/libsmb_cache.o \ @@ -925,7 +929,7 @@ WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ $(SECRETS_OBJ) $(POPT_LIB_OBJ) $(AFS_SETTOKEN_OBJ) $(RPC_PARSE_OBJ1) \ $(DOSERR_OBJ) lib/winbind_util.o @LIBWBCLIENT_STATIC@ -WINBIND_NSS_OBJ = $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ) @WINBIND_NSS_EXTRA_OBJS@ +WINBIND_NSS_OBJ = $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ) @WINBIND_NSS_EXTRA_OBJS@ LDB_COMMON_OBJ=lib/ldb/common/ldb.o lib/ldb/common/ldb_ldif.o \ lib/ldb/common/ldb_parse.o lib/ldb/common/ldb_msg.o lib/ldb/common/ldb_utf8.o \ @@ -963,7 +967,7 @@ LDBDEL_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbdel.o LDBMODIFY_OBJ = $(LDB_CMDLINE_OBJ) lib/ldb/tools/ldbmodify.o WINBIND_KRB5_LOCATOR_OBJ1 = nsswitch/winbind_krb5_locator.o -WINBIND_KRB5_LOCATOR_OBJ = $(WINBIND_KRB5_LOCATOR_OBJ1) $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ) +WINBIND_KRB5_LOCATOR_OBJ = $(WINBIND_KRB5_LOCATOR_OBJ1) $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ) POPT_OBJ=popt/findme.o popt/popt.o popt/poptconfig.o \ popt/popthelp.o popt/poptparse.o @@ -1057,7 +1061,7 @@ modules: SHOWFLAGS $(MODULES) ## Perl IDL Compiler IDL_FILES = unixinfo.idl lsa.idl dfs.idl echo.idl winreg.idl initshutdown.idl \ srvsvc.idl svcctl.idl eventlog.idl wkssvc.idl netlogon.idl notify.idl \ - epmapper.idl messaging.idl + epmapper.idl messaging.idl xattr.idl idl: @IDL_FILES="$(IDL_FILES)" CPP="$(CPP)" PERL="$(PERL)" \ @@ -1393,9 +1397,9 @@ bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \ $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) @WINBIND_LIBS@ -bin/libwbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ) nsswitch/wb_common.o lib/talloc/talloc.o +bin/libwbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ) @echo Linking shared library $@ - @$(SHLD_DSO) $(LIBWBCLIENT_OBJ) nsswitch/wb_common.o lib/talloc/talloc.o \ + @$(SHLD_DSO) $(LIBWBCLIENT_OBJ) \ @SONAMEFLAG@`basename $@`.$(SONAME_VER) @ln -s -f `basename $@` $@.$(SONAME_VER) @@ -1429,9 +1433,9 @@ bin/libsmbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ) $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ @SONAMEFLAG@`basename $@`.$(SONAME_VER) -bin/libsmbclient.a: $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ) +bin/libsmbclient.a: $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ0) @echo Linking non-shared library $@ - @-$(AR) -rc $@ $(LIBSMBCLIENT_OBJ) + @-$(AR) -rc $@ $(LIBSMBCLIENT_OBJ0) bin/libsmbsharemodes.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBSMBSHAREMODES_OBJ) @echo Linking shared library $@ @@ -1529,8 +1533,8 @@ bin/librpc_echo.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_ECHO_OBJ) bin/winbindd@EXEEXT@: $(BINARY_PREREQS) $(WINBINDD_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ @echo "Linking $@" @$(CC) $(FLAGS) -o $@ $(WINBINDD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ - @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \ - @WINBIND_LIBS@ + @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) \ + $(PASSDB_LIBS) @WINBIND_LIBS@ bin/vlp@EXEEXT@: $(BINARY_PREREQS) $(VLP_OBJ) @LIBWBCLIENT_SHARED@ @echo "Linking $@" @@ -1681,6 +1685,10 @@ bin/afsacl.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_AFSACL_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_AFSACL_OBJ) +bin/ea_tdb.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_EA_TDB_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(VFS_EA_TDB_OBJ) + bin/posixacl.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_POSIXACL_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_POSIXACL_OBJ) @@ -1881,9 +1889,10 @@ installlibaddns: installdirs libaddns -$(INSTALLLIBCMD_A) bin/libaddns.a $(DESTDIR)$(LIBDIR) installlibwbclient: installdirs libwbclient - @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR) $(INCLUDEDIR)/samba + @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR) -$(INSTALLLIBCMD_SH) bin/libwbclient.@SHLIBEXT@ $(DESTDIR)$(LIBDIR) - -$(INSTALLCMD) -m $(INSTALLPERMS_DATA) $(srcdir)/nsswitch/libwbclient/wbclient.h $(DESTDIR)${prefix}/include/samba + @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) ${prefix}/include + -$(INSTALLCMD) -m $(INSTALLPERMS_DATA) $(srcdir)/nsswitch/libwbclient/wbclient.h $(DESTDIR)${prefix}/include installlibnetapi: installdirs libnetapi @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR) diff --git a/source3/configure.in b/source3/configure.in index 4222d93227e..4ddc64407c8 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -707,7 +707,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_winreg rpc_initshutdown rpc_lsa_ds rpc_wkssvc rpc_svcctl2 rpc_ntsvcs rpc_net rpc_netdfs rpc_srvsvc2 rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin 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 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops" +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 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops vfs_ea_tdb" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_rpcecho" @@ -6489,6 +6489,7 @@ SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS) SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS) SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS) SMB_MODULE(vfs_afsacl, \$(VFS_AFSACL_OBJ), "bin/afsacl.$SHLIBEXT", VFS) +SMB_MODULE(vfs_ea_tdb, \$(VFS_EA_TDB_OBJ), "bin/ea_tdb.$SHLIBEXT", VFS) SMB_MODULE(vfs_posixacl, \$(VFS_POSIXACL_OBJ), "bin/posixacl.$SHLIBEXT", VFS) SMB_MODULE(vfs_aixacl, \$(VFS_AIXACL_OBJ), "bin/aixacl.$SHLIBEXT", VFS) SMB_MODULE(vfs_aixacl2, \$(VFS_AIXACL2_OBJ), "bin/aixacl2.$SHLIBEXT", VFS) @@ -6656,7 +6657,10 @@ AC_SUBST(SMBD_LIBS) AC_OUTPUT(Makefile library-versions script/findsmb smbadduser script/gen-8bit-gap.sh script/installbin.sh script/uninstallbin.sh lib/netapi/examples/Makefile - pkgconfig/smbclient.pc pkgconfig/netapi.pc pkgconfig/smbsharemodes.pc + pkgconfig/smbclient.pc + pkgconfig/wbclient.pc + pkgconfig/netapi.pc + pkgconfig/smbsharemodes.pc ) ################################################# diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index f6cf9cccb71..23a14e6757a 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -61,6 +61,7 @@ struct registry_value { typedef struct { uint32 num_values; REGISTRY_VALUE **values; + int seqnum; } REGVAL_CTR; /* container for registry subkey names */ @@ -68,6 +69,7 @@ typedef struct { typedef struct { uint32 num_subkeys; char **subkeys; + int seqnum; } REGSUBKEY_CTR; /* @@ -128,6 +130,8 @@ 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 (*values_need_update)(REGVAL_CTR *values); } REGISTRY_OPS; typedef struct { diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index 9f90b53ffab..ef6ff6db28d 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -334,22 +334,6 @@ typedef struct lsa_info_ctr typedef LSA_INFO_CTR LSA_INFO_CTR2; -/* LSA_Q_SET_INFO - LSA set info policy */ -typedef struct lsa_set_info -{ - POLICY_HND pol; /* policy handle */ - uint16 info_class; /* info class */ - LSA_INFO_CTR ctr; - -} LSA_Q_SET_INFO; - -/* LSA_R_SET_INFO - response to LSA set info policy */ -typedef struct lsa_r_set_info -{ - NTSTATUS status; /* return code */ - -} LSA_R_SET_INFO; - /* LSA_R_QUERY_INFO - response to LSA query info policy */ typedef struct lsa_r_query_info { @@ -988,25 +972,6 @@ typedef struct { /*******************************************************/ -/* LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME - LSA Query Open Trusted Domain by Name*/ -typedef struct lsa_q_open_trusted_domain_by_name -{ - POLICY_HND pol; /* policy handle */ - LSA_STRING name; /* domain name */ - uint32 access_mask; /* access mask */ - -} LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME; - -/* LSA_R_OPEN_TRUSTED_DOMAIN_BY_NAME - response to LSA Query Open Trusted Domain by Name */ -typedef struct { - POLICY_HND handle; /* trustdom policy handle */ - NTSTATUS status; /* return code */ -} LSA_R_OPEN_TRUSTED_DOMAIN_BY_NAME; - - -/*******************************************************/ - - typedef struct { POLICY_HND handle; UNISTR4 secretname; @@ -1078,140 +1043,6 @@ typedef struct { NTSTATUS status; } LSA_R_SET_SECRET; -/* LSA_Q_QUERY_TRUSTED_DOMAIN_INFO - LSA query trusted domain info */ -typedef struct lsa_query_trusted_domain_info -{ - POLICY_HND pol; /* policy handle */ - uint16 info_class; /* info class */ - -} LSA_Q_QUERY_TRUSTED_DOMAIN_INFO; - -/* LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID - LSA query trusted domain info */ -typedef struct lsa_query_trusted_domain_info_by_sid -{ - POLICY_HND pol; /* policy handle */ - DOM_SID2 dom_sid; /* domain sid */ - uint16 info_class; /* info class */ - -} LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID; - -/* LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME - LSA query trusted domain info */ -typedef struct lsa_query_trusted_domain_info_by_name -{ - POLICY_HND pol; /* policy handle */ - LSA_STRING domain_name; /* domain name */ - uint16 info_class; /* info class */ - -} LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME; - -typedef struct trusted_domain_info_name { - LSA_STRING netbios_name; -} TRUSTED_DOMAIN_INFO_NAME; - -typedef struct trusted_domain_info_posix_offset { - uint32 posix_offset; -} TRUSTED_DOMAIN_INFO_POSIX_OFFSET; - -typedef struct lsa_data_buf { - uint32 size; - uint32 offset; - uint32 length; - uint8 *data; -} LSA_DATA_BUF; - -typedef struct lsa_data_buf_hdr { - uint32 length; - uint32 size; - uint32 data_ptr; -} LSA_DATA_BUF_HDR; - - -typedef struct lsa_data_buf2 { - uint32 size; - uint8 *data; -} LSA_DATA_BUF2; - -typedef struct trusted_domain_info_password { - uint32 ptr_password; - uint32 ptr_old_password; - LSA_DATA_BUF_HDR password_hdr; - LSA_DATA_BUF_HDR old_password_hdr; - LSA_DATA_BUF password; - LSA_DATA_BUF old_password; -} TRUSTED_DOMAIN_INFO_PASSWORD; - -typedef struct trusted_domain_info_basic { - LSA_STRING netbios_name; - DOM_SID2 sid; -} TRUSTED_DOMAIN_INFO_BASIC; - -typedef struct trusted_domain_info_ex { - LSA_STRING domain_name; - LSA_STRING netbios_name; - DOM_SID2 sid; - uint32 trust_direction; - uint32 trust_type; - uint32 trust_attributes; -} TRUSTED_DOMAIN_INFO_EX; - -typedef struct trust_domain_info_buffer { - NTTIME last_update_time; - uint32 secret_type; - LSA_DATA_BUF2 data; -} LSA_TRUSTED_DOMAIN_INFO_BUFFER; - -typedef struct trusted_domain_info_auth_info { - uint32 incoming_count; - LSA_TRUSTED_DOMAIN_INFO_BUFFER incoming_current_auth_info; - LSA_TRUSTED_DOMAIN_INFO_BUFFER incoming_previous_auth_info; - uint32 outgoing_count; - LSA_TRUSTED_DOMAIN_INFO_BUFFER outgoing_current_auth_info; - LSA_TRUSTED_DOMAIN_INFO_BUFFER outgoing_previous_auth_info; -} TRUSTED_DOMAIN_INFO_AUTH_INFO; - -typedef struct trusted_domain_info_full_info { - TRUSTED_DOMAIN_INFO_EX info_ex; - TRUSTED_DOMAIN_INFO_POSIX_OFFSET posix_offset; - TRUSTED_DOMAIN_INFO_AUTH_INFO auth_info; -} TRUSTED_DOMAIN_INFO_FULL_INFO; - -typedef struct trusted_domain_info_11 { - TRUSTED_DOMAIN_INFO_EX info_ex; - LSA_DATA_BUF2 data1; -} TRUSTED_DOMAIN_INFO_11; - -typedef struct trusted_domain_info_all { - TRUSTED_DOMAIN_INFO_EX info_ex; - LSA_DATA_BUF2 data1; - TRUSTED_DOMAIN_INFO_POSIX_OFFSET posix_offset; - TRUSTED_DOMAIN_INFO_AUTH_INFO auth_info; -} TRUSTED_DOMAIN_INFO_ALL; - -/* LSA_TRUSTED_DOMAIN_INFO */ -typedef union lsa_trusted_domain_info -{ - uint16 info_class; - TRUSTED_DOMAIN_INFO_NAME name; - /* deprecated - gd - TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO controllers; */ - TRUSTED_DOMAIN_INFO_POSIX_OFFSET posix_offset; - TRUSTED_DOMAIN_INFO_PASSWORD password; - TRUSTED_DOMAIN_INFO_BASIC basic; - TRUSTED_DOMAIN_INFO_EX info_ex; - TRUSTED_DOMAIN_INFO_AUTH_INFO auth_info; - TRUSTED_DOMAIN_INFO_FULL_INFO full_info; - TRUSTED_DOMAIN_INFO_11 info11; - TRUSTED_DOMAIN_INFO_ALL info_all; - -} LSA_TRUSTED_DOMAIN_INFO; - -/* LSA_R_QUERY_TRUSTED_DOMAIN_INFO - LSA query trusted domain info */ -typedef struct r_lsa_query_trusted_domain_info -{ - LSA_TRUSTED_DOMAIN_INFO *info; - NTSTATUS status; -} LSA_R_QUERY_TRUSTED_DOMAIN_INFO; - typedef struct dom_info_kerberos { uint32 enforce_restrictions; NTTIME service_tkt_lifetime; diff --git a/source3/lib/dbwrap_rbt.c b/source3/lib/dbwrap_rbt.c index 93d73f29d13..633b695b52f 100644 --- a/source3/lib/dbwrap_rbt.c +++ b/source3/lib/dbwrap_rbt.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. Database interface wrapper around red-black trees - Copyright (C) Volker Lendecke 2007 + Copyright (C) Volker Lendecke 2007, 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@ #include "includes.h" #include "rbtree.h" +#define ALIGN(_size_) (((_size_)+15)&~15) + struct db_rbt_ctx { struct rb_root tree; }; @@ -44,6 +46,35 @@ struct db_rbt_node { }; /* + * Hide the ugly pointer calculations in a function + */ + +static struct db_rbt_node *db_rbt2node(struct rb_node *node) +{ + return (struct db_rbt_node *) + ((char *)node - offsetof(struct db_rbt_node, rb_node)); +} + +/* + * Compare two keys + */ + +static int db_rbt_compare(TDB_DATA a, TDB_DATA b) +{ + int res; + + res = memcmp(a.dptr, b.dptr, MIN(a.dsize, b.dsize)); + + if ((res < 0) || ((res == 0) && (a.dsize < b.dsize))) { + return -1; + } + if ((res > 0) || ((res == 0) && (a.dsize > b.dsize))) { + return 1; + } + return 0; +} + +/* * dissect a db_rbt_node into its implicit key and value parts */ @@ -58,9 +89,7 @@ static void db_rbt_parse_node(struct db_rbt_node *node, static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) { - struct db_rbt_rec *rec_priv = talloc_get_type_abort( - rec->private_data, struct db_rbt_rec); - + struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data; struct db_rbt_node *node; struct rb_node ** p; @@ -133,22 +162,16 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) parent = (*p); - r = (struct db_rbt_node *) - ((char *)(*p) - offsetof(struct db_rbt_node, rb_node)); + r = db_rbt2node(*p); db_rbt_parse_node(r, &search_key, &search_val); - res = memcmp(this_key.dptr, search_key.dptr, - MIN(this_key.dsize, search_key.dsize)); + res = db_rbt_compare(this_key, search_key); - if ((res < 0) - || ((res == 0) - && (this_key.dsize < search_key.dsize))) { + if (res == -1) { p = &(*p)->rb_left; } - else if ((res > 0) - || ((res == 0) - && (this_key.dsize > search_key.dsize))) { + else if (res == 1) { p = &(*p)->rb_right; } else { @@ -164,8 +187,7 @@ static NTSTATUS db_rbt_store(struct db_record *rec, TDB_DATA data, int flag) static NTSTATUS db_rbt_delete(struct db_record *rec) { - struct db_rbt_rec *rec_priv = talloc_get_type_abort( - rec->private_data, struct db_rbt_rec); + struct db_rbt_rec *rec_priv = (struct db_rbt_rec *)rec->private_data; if (rec_priv->node == NULL) { return NT_STATUS_OK; @@ -187,85 +209,128 @@ static struct db_record *db_rbt_fetch_locked(struct db_context *db_ctx, struct db_rbt_rec *rec_priv; struct db_record *result; struct rb_node *n; + size_t size; + bool found = false; + struct db_rbt_node *r = NULL; + TDB_DATA search_key = tdb_null, search_val = tdb_null; - result = talloc(mem_ctx, struct db_record); + n = ctx->tree.rb_node; - if (result == NULL) { - return NULL; + while (n != NULL) { + int res; + + r = db_rbt2node(n); + + db_rbt_parse_node(r, &search_key, &search_val); + + res = db_rbt_compare(key, search_key); + + if (res == -1) { + n = n->rb_left; + } + else if (res == 1) { + n = n->rb_right; + } + else { + found = true; + break; + } } - rec_priv = talloc(result, struct db_rbt_rec); + /* + * In this low-level routine, play tricks to reduce the number of + * tallocs to one. Not recommened for general use, but here it pays + * off. + */ - if (rec_priv == NULL) { - TALLOC_FREE(result); + size = ALIGN(sizeof(struct db_record)) + sizeof(struct db_rbt_rec); + + if (!found) { + /* + * We need to keep the key around for later store + */ + size += key.dsize; + } + + result = (struct db_record *)talloc_size(mem_ctx, size); + if (result == NULL) { return NULL; } + rec_priv = (struct db_rbt_rec *) + ((char *)result + ALIGN(sizeof(struct db_record))); rec_priv->db_ctx = ctx; result->store = db_rbt_store; result->delete_rec = db_rbt_delete; result->private_data = rec_priv; + if (found) { + rec_priv->node = r; + result->key = search_key; + result->value = search_val; + } + else { + rec_priv->node = NULL; + result->key.dptr = (uint8 *) + ((char *)rec_priv + sizeof(*rec_priv)); + result->key.dsize = key.dsize; + memcpy(result->key.dptr, key.dptr, key.dsize); + + result->value = tdb_null; + } + + return result; +} + +static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, + TDB_DATA key, TDB_DATA *data) +{ + struct db_rbt_ctx *ctx = talloc_get_type_abort( + db->private_data, struct db_rbt_ctx); + + struct rb_node *n; + bool found = false; + struct db_rbt_node *r = NULL; + TDB_DATA search_key, search_val; + uint8_t *result; + n = ctx->tree.rb_node; while (n != NULL) { - struct db_rbt_node *r; - TDB_DATA search_key, search_val; int res; - r = (struct db_rbt_node *) - ((char *)n - offsetof(struct db_rbt_node, rb_node)); + r = db_rbt2node(n); db_rbt_parse_node(r, &search_key, &search_val); - res = memcmp(key.dptr, search_key.dptr, - MIN(key.dsize, search_key.dsize)); + res = db_rbt_compare(key, search_key); - if ((res < 0) - || ((res == 0) && (key.dsize < search_key.dsize))) { + if (res == -1) { n = n->rb_left; } - else if ((res > 0) - || ((res == 0) && (key.dsize > search_key.dsize))) { + else if (res == 1) { n = n->rb_right; } else { - rec_priv->node = r; - result->key = search_key; - result->value = search_val; - return result; + found = true; + break; } } - result->key.dsize = key.dsize; - result->key.dptr = (uint8_t *)talloc_memdup( - result, key.dptr, key.dsize); - - if (result->key.dptr == NULL) { - TALLOC_FREE(result); - return NULL; + if (!found) { + *data = tdb_null; + return 0; } - rec_priv->node = NULL; - result->value.dsize = 0; - result->value.dptr = NULL; - return result; -} - -static int db_rbt_fetch(struct db_context *db, TALLOC_CTX *mem_ctx, - TDB_DATA key, TDB_DATA *data) -{ - struct db_record *rec; - - if (!(rec = db->fetch_locked(db, mem_ctx, key))) { + result = (uint8 *)talloc_memdup(mem_ctx, search_val.dptr, + search_val.dsize); + if (result == NULL) { return -1; } - data->dsize = rec->value.dsize; - data->dptr = (uint8 *)talloc_memdup(mem_ctx, rec->value.dptr, - rec->value.dsize); - TALLOC_FREE(rec); + data->dptr = result; + data->dsize = search_val.dsize; return 0; } @@ -275,6 +340,9 @@ static int db_rbt_traverse(struct db_context *db, void *private_data), void *private_data) { + /* + * Nobody uses this so far, and unused code is broken code :-) + */ return -1; } diff --git a/source3/lib/module.c b/source3/lib/module.c index fa06d14b49d..285bd9c4c07 100644 --- a/source3/lib/module.c +++ b/source3/lib/module.c @@ -57,6 +57,7 @@ static NTSTATUS do_smb_load_module(const char *module_name, bool is_probe) if (error) { DEBUG(0, ("Error trying to resolve symbol 'init_module' in %s: %s\n", module_name, error)); + sys_dlclose(handle); return NT_STATUS_UNSUCCESSFUL; } @@ -66,6 +67,7 @@ static NTSTATUS do_smb_load_module(const char *module_name, bool is_probe) if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Module '%s' initialization failed: %s\n", module_name, get_friendly_nt_error_msg(status))); + sys_dlclose(handle); } return status; diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index 0e356e0ee7c..67680ba55af 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -149,6 +149,10 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, uint8_t *buffer, uint32_t *parm_error) { + WERROR werr; + struct libnet_conf_ctx *conf_ctx; + TALLOC_CTX *mem_ctx; + struct srvsvc_NetSrvInfo1005 *info1005; if (!buffer) { @@ -167,8 +171,20 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, return WERR_NOT_SUPPORTED; } - return libnet_conf_set_global_parameter("server string", + mem_ctx = talloc_stackframe(); + werr = libnet_conf_open(mem_ctx, &conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = libnet_conf_set_global_parameter(conf_ctx, + "server string", info1005->comment); + +done: + libnet_conf_close(conf_ctx); + TALLOC_FREE(mem_ctx); + return werr; } static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx, diff --git a/source3/lib/tdb/common/freelist.c b/source3/lib/tdb/common/freelist.c index b109643f235..c086c151fa6 100644 --- a/source3/lib/tdb/common/freelist.c +++ b/source3/lib/tdb/common/freelist.c @@ -27,6 +27,12 @@ #include "tdb_private.h" +/* 'right' merges can involve O(n^2) cost when combined with a + traverse, so they are disabled until we find a way to do them in + O(1) time +*/ +#define USE_RIGHT_MERGES 0 + /* read a freelist record and check for simple errors */ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct *rec) { @@ -56,7 +62,7 @@ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct list_struct } - +#if USE_RIGHT_MERGES /* Remove an element from the freelist. Must have alloc lock. */ static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_t next) { @@ -75,6 +81,7 @@ static int remove_from_freelist(struct tdb_context *tdb, tdb_off_t off, tdb_off_ TDB_LOG((tdb, TDB_DEBUG_FATAL,"remove_from_freelist: not on list at off=%d\n", off)); return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); } +#endif /* update a record tailer (must hold allocation lock) */ @@ -93,8 +100,6 @@ static int update_tailer(struct tdb_context *tdb, tdb_off_t offset, neccessary. */ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) { - tdb_off_t right, left; - /* Allocation and tailer lock */ if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1; @@ -105,9 +110,10 @@ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) goto fail; } +#if USE_RIGHT_MERGES /* Look right first (I'm an Australian, dammit) */ - right = offset + sizeof(*rec) + rec->rec_len; - if (right + sizeof(*rec) <= tdb->map_size) { + if (offset + sizeof(*rec) + rec->rec_len + sizeof(*rec) <= tdb->map_size) { + tdb_off_t right = offset + sizeof(*rec) + rec->rec_len; struct list_struct r; if (tdb->methods->tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { @@ -122,13 +128,18 @@ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct list_struct *rec) goto left; } rec->rec_len += sizeof(r) + r.rec_len; + if (update_tailer(tdb, offset, rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } } } - left: +#endif + /* Look left */ - left = offset - sizeof(tdb_off_t); - if (left > TDB_DATA_START(tdb->header.hash_size)) { + if (offset - sizeof(tdb_off_t) > TDB_DATA_START(tdb->header.hash_size)) { + tdb_off_t left = offset - sizeof(tdb_off_t); struct list_struct l; tdb_off_t leftsize; @@ -145,7 +156,12 @@ left: left = offset - leftsize; - /* Now read in record */ + if (leftsize > offset || + left < TDB_DATA_START(tdb->header.hash_size)) { + goto update; + } + + /* Now read in the left record */ if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); goto update; @@ -153,21 +169,24 @@ left: /* If it's free, expand to include it. */ if (l.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, left, l.next) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left free failed at %u\n", left)); - goto update; - } else { - offset = left; - rec->rec_len += leftsize; + /* we now merge the new record into the left record, rather than the other + way around. This makes the operation O(1) instead of O(n). This change + prevents traverse from being O(n^2) after a lot of deletes */ + l.rec_len += sizeof(*rec) + rec->rec_len; + if (tdb_rec_write(tdb, left, &l) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_left failed at %u\n", left)); + goto fail; } + if (update_tailer(tdb, left, &l) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } + tdb_unlock(tdb, -1, F_WRLCK); + return 0; } } update: - if (update_tailer(tdb, offset, rec) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); - goto fail; - } /* Now, prepend to free list */ rec->magic = TDB_FREE_MAGIC; @@ -261,6 +280,7 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st tdb_off_t rec_ptr, last_ptr; tdb_len_t rec_len; } bestfit; + float multiplier = 1.0; if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0; @@ -295,18 +315,27 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st bestfit.rec_len = rec->rec_len; bestfit.rec_ptr = rec_ptr; bestfit.last_ptr = last_ptr; - /* consider a fit to be good enough if - we aren't wasting more than half - the space */ - if (bestfit.rec_len < 2*length) { - break; - } } } /* move to the next record */ last_ptr = rec_ptr; rec_ptr = rec->next; + + /* if we've found a record that is big enough, then + stop searching if its also not too big. The + definition of 'too big' changes as we scan + through */ + if (bestfit.rec_len > 0 && + bestfit.rec_len < length * multiplier) { + break; + } + + /* this multiplier means we only extremely rarely + search more than 50 or so records. At 50 records we + accept records up to 11 times larger than what we + want */ + multiplier *= 1.05; } if (bestfit.rec_ptr != 0) { @@ -328,3 +357,25 @@ tdb_off_t tdb_allocate(struct tdb_context *tdb, tdb_len_t length, struct list_st return 0; } + + +/* + return the size of the freelist - used to decide if we should repack +*/ +int tdb_freelist_size(struct tdb_context *tdb) +{ + tdb_off_t ptr; + int count=0; + + if (tdb_lock(tdb, -1, F_RDLCK) == -1) { + return -1; + } + + ptr = FREELIST_TOP; + while (tdb_ofs_read(tdb, ptr, &ptr) == 0 && ptr != 0) { + count++; + } + + tdb_unlock(tdb, -1, F_RDLCK); + return count; +} diff --git a/source3/lib/tdb/common/io.c b/source3/lib/tdb/common/io.c index 8ab07688837..172ab69d8c9 100644 --- a/source3/lib/tdb/common/io.c +++ b/source3/lib/tdb/common/io.c @@ -101,8 +101,8 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, off+written); } if (written == -1) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d " "len=%d (%s)\n", off, len, strerror(errno))); return TDB_ERRCODE(TDB_ERR_IO, -1); @@ -111,8 +111,8 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, "write %d bytes at %d in two attempts\n", len, off)); errno = ENOSPC; - return TDB_ERRCODE(TDB_ERR_IO, -1); - } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } } return 0; } @@ -230,7 +230,7 @@ void tdb_mmap(struct tdb_context *tdb) says to use for mmap expansion */ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t addition) { - char buf[1024]; + char buf[8192]; if (tdb->read_only || tdb->traverse_read) { tdb->ecode = TDB_ERR_RDONLY; @@ -294,7 +294,7 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad int tdb_expand(struct tdb_context *tdb, tdb_off_t size) { struct list_struct rec; - tdb_off_t offset; + tdb_off_t offset, new_size; if (tdb_lock(tdb, -1, F_WRLCK) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n")); @@ -304,9 +304,11 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) /* must know about any previous expansions by another process */ tdb->methods->tdb_oob(tdb, tdb->map_size + 1, 1); - /* always make room for at least 10 more records, and round - the database up to a multiple of the page size */ - size = TDB_ALIGN(tdb->map_size + size*10, tdb->page_size) - tdb->map_size; + /* always make room for at least 100 more records, and at + least 25% more space. Round the database up to a multiple + of the page size */ + new_size = MAX(tdb->map_size + size*100, tdb->map_size * 1.25); + size = TDB_ALIGN(new_size, tdb->page_size) - tdb->map_size; if (!(tdb->flags & TDB_INTERNAL)) tdb_munmap(tdb); diff --git a/source3/lib/tdb/common/lock.c b/source3/lib/tdb/common/lock.c index e3fe888c465..f156c0fa7b2 100644 --- a/source3/lib/tdb/common/lock.c +++ b/source3/lib/tdb/common/lock.c @@ -505,6 +505,9 @@ int tdb_chainunlock_read(struct tdb_context *tdb, TDB_DATA key) /* record lock stops delete underneath */ int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off) { + if (tdb->global_lock.count) { + return 0; + } return off ? tdb->methods->tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0, 1) : 0; } @@ -537,6 +540,10 @@ int tdb_unlock_record(struct tdb_context *tdb, tdb_off_t off) struct tdb_traverse_lock *i; uint32_t count = 0; + if (tdb->global_lock.count) { + return 0; + } + if (off == 0) return 0; for (i = &tdb->travlocks; i; i = i->next) diff --git a/source3/lib/tdb/common/open.c b/source3/lib/tdb/common/open.c index 6efa482ac2b..94140a4baa6 100644 --- a/source3/lib/tdb/common/open.c +++ b/source3/lib/tdb/common/open.c @@ -35,7 +35,7 @@ static struct tdb_context *tdbs = NULL; static unsigned int default_tdb_hash(TDB_DATA *key) { uint32_t value; /* Used to compute the hash value. */ - uint32_t i; /* Used to cycle through random values. */ + uint32_t i; /* Used to cycle through random values. */ /* Set the initial value from the key size. */ for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) @@ -90,7 +90,7 @@ static int tdb_new_database(struct tdb_context *tdb, int hash_size) size -= written; written = write(tdb->fd, newdb+written, size); if (written == size) { - ret = 0; + ret = 0; } else if (written >= 0) { /* a second incomplete write - we give up. * guessing the errno... */ @@ -152,6 +152,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, int rev = 0, locked = 0; unsigned char *vp; uint32_t vertest; + unsigned v; if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) { /* Can't log this */ @@ -213,6 +214,10 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, goto fail; /* errno set by open(2) */ } + /* on exec, don't inherit the fd */ + v = fcntl(tdb->fd, F_GETFD, 0); + fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC); + /* ensure there is only one process initialising at once */ if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get global lock on %s: %s\n", @@ -240,7 +245,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, /* its not a valid database - possibly initialise it */ if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { if (errno == 0) { - errno = EIO; /* ie bad format or something */ + errno = EIO; /* ie bad format or something */ } goto fail; } diff --git a/source3/lib/tdb/common/tdb.c b/source3/lib/tdb/common/tdb.c index 0e9d1dbd741..ea5d9ccc601 100644 --- a/source3/lib/tdb/common/tdb.c +++ b/source3/lib/tdb/common/tdb.c @@ -102,8 +102,7 @@ static tdb_off_t tdb_find(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, } /* As tdb_find, but if you succeed, keep the lock */ -tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, - uint32_t hash, int locktype, +tdb_off_t tdb_find_lock_hash(struct tdb_context *tdb, TDB_DATA key, uint32_t hash, int locktype, struct list_struct *rec) { uint32_t rec_ptr; @@ -237,14 +236,15 @@ int tdb_exists(struct tdb_context *tdb, TDB_DATA key) } /* actually delete an entry in the database given the offset */ -int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct*rec) +int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct *rec) { tdb_off_t last_ptr, i; struct list_struct lastrec; if (tdb->read_only || tdb->traverse_read) return -1; - if (tdb_write_lock_record(tdb, rec_ptr) == -1) { + if (tdb->traverse_write != 0 || + tdb_write_lock_record(tdb, rec_ptr) == -1) { /* Someone traversing here: mark it as dead */ rec->magic = TDB_DEAD_MAGIC; return tdb_rec_write(tdb, rec_ptr, rec); @@ -666,6 +666,16 @@ int tdb_get_flags(struct tdb_context *tdb) return tdb->flags; } +void tdb_add_flags(struct tdb_context *tdb, unsigned flags) +{ + tdb->flags |= flags; +} + +void tdb_remove_flags(struct tdb_context *tdb, unsigned flags) +{ + tdb->flags &= ~flags; +} + /* enable sequence number handling on an open tdb @@ -674,3 +684,62 @@ void tdb_enable_seqnum(struct tdb_context *tdb) { tdb->flags |= TDB_SEQNUM; } + + +/* + wipe the entire database, deleting all records. This can be done + very fast by using a global lock. The entire data portion of the + file becomes a single entry in the freelist. + */ +int tdb_wipe_all(struct tdb_context *tdb) +{ + int i; + tdb_off_t offset = 0; + ssize_t data_len; + + if (tdb_lockall(tdb) != 0) { + return -1; + } + + /* wipe the hashes */ + for (i=0;i<tdb->header.hash_size;i++) { + if (tdb_ofs_write(tdb, TDB_HASH_TOP(i), &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write hash %d\n", i)); + goto failed; + } + } + + /* wipe the freelist */ + if (tdb_ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write freelist\n")); + goto failed; + } + + if (tdb_ofs_write(tdb, TDB_RECOVERY_HEAD, &offset) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to write recovery head\n")); + goto failed; + } + + /* add all the rest of the file to the freelist */ + data_len = (tdb->map_size - TDB_DATA_START(tdb->header.hash_size)) - sizeof(struct list_struct); + if (data_len > 0) { + struct list_struct rec; + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = data_len; + if (tdb_free(tdb, TDB_DATA_START(tdb->header.hash_size), &rec) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to add free record\n")); + goto failed; + } + } + + if (tdb_unlockall(tdb) != 0) { + TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_wipe_all: failed to unlock\n")); + goto failed; + } + + return 0; + +failed: + tdb_unlockall(tdb); + return -1; +} diff --git a/source3/lib/tdb/common/tdb_private.h b/source3/lib/tdb/common/tdb_private.h index 58c30c1706c..63a6d04e72d 100644 --- a/source3/lib/tdb/common/tdb_private.h +++ b/source3/lib/tdb/common/tdb_private.h @@ -38,6 +38,10 @@ typedef uint32_t tdb_len_t; typedef uint32_t tdb_off_t; +#ifndef offsetof +#define offsetof(t,f) ((unsigned int)&((t *)0)->f) +#endif + #define TDB_MAGIC_FOOD "TDB file\n" #define TDB_VERSION (0x26011967 + 6) #define TDB_MAGIC (0x26011999U) @@ -54,7 +58,7 @@ typedef uint32_t tdb_off_t; #define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) #define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off_t)) #define TDB_HASHTABLE_SIZE(tdb) ((tdb->header.hash_size+1)*sizeof(tdb_off_t)) -#define TDB_DATA_START(hash_size) TDB_HASH_TOP(hash_size-1) +#define TDB_DATA_START(hash_size) (TDB_HASH_TOP(hash_size-1) + sizeof(tdb_off_t)) #define TDB_RECOVERY_HEAD offsetof(struct tdb_header, recovery_start) #define TDB_SEQNUM_OFS offsetof(struct tdb_header, sequence_number) #define TDB_PAD_BYTE 0x42 @@ -144,6 +148,7 @@ struct tdb_context { tdb_len_t map_size; /* how much space has been mapped */ int read_only; /* opened read-only */ int traverse_read; /* read-only traversal */ + int traverse_write; /* read-write traversal */ struct tdb_lock_type global_lock; int num_lockrecs; struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */ @@ -173,7 +178,6 @@ struct tdb_context { int tdb_munmap(struct tdb_context *tdb); void tdb_mmap(struct tdb_context *tdb); int tdb_lock(struct tdb_context *tdb, int list, int ltype); -int tdb_lock_nonblock(struct tdb_context *tdb, int list, int ltype); int tdb_unlock(struct tdb_context *tdb, int list, int ltype); int tdb_brlock(struct tdb_context *tdb, tdb_off_t offset, int rw_type, int lck_type, int probe, size_t len); int tdb_transaction_lock(struct tdb_context *tdb, int ltype); diff --git a/source3/lib/tdb/common/transaction.c b/source3/lib/tdb/common/transaction.c index 7eaacf7a164..0ecfb9b7ff6 100644 --- a/source3/lib/tdb/common/transaction.c +++ b/source3/lib/tdb/common/transaction.c @@ -87,12 +87,6 @@ */ -struct tdb_transaction_el { - struct tdb_transaction_el *next, *prev; - tdb_off_t offset; - tdb_len_t length; - unsigned char *data; -}; /* hold the context of any current transaction @@ -105,12 +99,12 @@ struct tdb_transaction { /* the original io methods - used to do IOs to the real db */ const struct tdb_methods *io_methods; - /* the list of transaction elements. We use a doubly linked - list with a last pointer to allow us to keep the list - ordered, with first element at the front of the list. It - needs to be doubly linked as the read/write traversals need - to be backwards, while the commit needs to be forwards */ - struct tdb_transaction_el *elements, *elements_last; + /* the list of transaction blocks. When a block is first + written to, it gets created in this list */ + uint8_t **blocks; + uint32_t num_blocks; + uint32_t block_size; /* bytes in each block */ + uint32_t last_block_size; /* number of valid bytes in the last block */ /* non-zero when an internal transaction error has occurred. All write operations will then fail until the @@ -134,52 +128,48 @@ struct tdb_transaction { static int transaction_read(struct tdb_context *tdb, tdb_off_t off, void *buf, tdb_len_t len, int cv) { - struct tdb_transaction_el *el; - - /* we need to walk the list backwards to get the most recent data */ - for (el=tdb->transaction->elements_last;el;el=el->prev) { - tdb_len_t partial; + uint32_t blk; - if (off+len <= el->offset) { - continue; - } - if (off >= el->offset + el->length) { - continue; + /* break it down into block sized ops */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_read(tdb, off, buf, len2, cv) != 0) { + return -1; } + len -= len2; + off += len2; + buf = (void *)(len2 + (char *)buf); + } - /* an overlapping read - needs to be split into up to - 2 reads and a memcpy */ - if (off < el->offset) { - partial = el->offset - off; - if (transaction_read(tdb, off, buf, partial, cv) != 0) { - goto fail; - } - len -= partial; - off += partial; - buf = (void *)(partial + (char *)buf); - } - if (off + len <= el->offset + el->length) { - partial = len; - } else { - partial = el->offset + el->length - off; - } - memcpy(buf, el->data + (off - el->offset), partial); - if (cv) { - tdb_convert(buf, len); - } - len -= partial; - off += partial; - buf = (void *)(partial + (char *)buf); - - if (len != 0 && transaction_read(tdb, off, buf, len, cv) != 0) { + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + + /* see if we have it in the block list */ + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + /* nope, do a real read */ + if (tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv) != 0) { goto fail; } - return 0; } - /* its not in the transaction elements - do a real read */ - return tdb->transaction->io_methods->tdb_read(tdb, off, buf, len, cv); + /* it is in the block list. Now check for the last block */ + if (blk == tdb->transaction->num_blocks-1) { + if (len > tdb->transaction->last_block_size) { + goto fail; + } + } + + /* now copy it out of this block */ + memcpy(buf, tdb->transaction->blocks[blk] + (off % tdb->transaction->block_size), len); + if (cv) { + tdb_convert(buf, len); + } + return 0; fail: TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_read: failed at off=%d len=%d\n", off, len)); @@ -195,12 +185,8 @@ fail: static int transaction_write(struct tdb_context *tdb, tdb_off_t off, const void *buf, tdb_len_t len) { - struct tdb_transaction_el *el, *best_el=NULL; + uint32_t blk; - if (len == 0) { - return 0; - } - /* if the write is to a hash head, then update the transaction hash heads */ if (len == sizeof(tdb_off_t) && off >= FREELIST_TOP && @@ -209,110 +195,149 @@ static int transaction_write(struct tdb_context *tdb, tdb_off_t off, memcpy(&tdb->transaction->hash_heads[chain], buf, len); } - /* first see if we can replace an existing entry */ - for (el=tdb->transaction->elements_last;el;el=el->prev) { - tdb_len_t partial; - - if (best_el == NULL && off == el->offset+el->length) { - best_el = el; - } - - if (off+len <= el->offset) { - continue; + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write(tdb, off, buf, len2) != 0) { + return -1; } - if (off >= el->offset + el->length) { - continue; + len -= len2; + off += len2; + if (buf != NULL) { + buf = (const void *)(len2 + (const char *)buf); } + } - /* an overlapping write - needs to be split into up to - 2 writes and a memcpy */ - if (off < el->offset) { - partial = el->offset - off; - if (transaction_write(tdb, off, buf, partial) != 0) { - goto fail; - } - len -= partial; - off += partial; - buf = (const void *)(partial + (const char *)buf); - } - if (off + len <= el->offset + el->length) { - partial = len; + if (len == 0) { + return 0; + } + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk) { + uint8_t **new_blocks; + /* expand the blocks array */ + if (tdb->transaction->blocks == NULL) { + new_blocks = malloc((blk+1)*sizeof(uint8_t *)); } else { - partial = el->offset + el->length - off; + new_blocks = realloc(tdb->transaction->blocks, (blk+1)*sizeof(uint8_t *)); } - memcpy(el->data + (off - el->offset), buf, partial); - len -= partial; - off += partial; - buf = (const void *)(partial + (const char *)buf); - - if (len != 0 && transaction_write(tdb, off, buf, len) != 0) { + if (new_blocks == NULL) { + tdb->ecode = TDB_ERR_OOM; goto fail; } - - return 0; + memset(&new_blocks[tdb->transaction->num_blocks], 0, + (1+(blk - tdb->transaction->num_blocks))*sizeof(uint8_t *)); + tdb->transaction->blocks = new_blocks; + tdb->transaction->num_blocks = blk+1; + tdb->transaction->last_block_size = 0; } - /* see if we can append the new entry to an existing entry */ - if (best_el && best_el->offset + best_el->length == off && - (off+len < tdb->transaction->old_map_size || - off > tdb->transaction->old_map_size)) { - unsigned char *data = best_el->data; - el = best_el; - el->data = (unsigned char *)realloc(el->data, - el->length + len); - if (el->data == NULL) { + /* allocate and fill a block? */ + if (tdb->transaction->blocks[blk] == NULL) { + tdb->transaction->blocks[blk] = (uint8_t *)calloc(tdb->transaction->block_size, 1); + if (tdb->transaction->blocks[blk] == NULL) { tdb->ecode = TDB_ERR_OOM; tdb->transaction->transaction_error = 1; - el->data = data; + return -1; + } + if (tdb->transaction->old_map_size > blk * tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size; + if (len2 + (blk * tdb->transaction->block_size) > tdb->transaction->old_map_size) { + len2 = tdb->transaction->old_map_size - (blk * tdb->transaction->block_size); + } + if (tdb->transaction->io_methods->tdb_read(tdb, blk * tdb->transaction->block_size, + tdb->transaction->blocks[blk], + len2, 0) != 0) { + SAFE_FREE(tdb->transaction->blocks[blk]); + tdb->ecode = TDB_ERR_IO; + goto fail; + } + if (blk == tdb->transaction->num_blocks-1) { + tdb->transaction->last_block_size = len2; + } + } + } + + /* overwrite part of an existing block */ + if (buf == NULL) { + memset(tdb->transaction->blocks[blk] + off, 0, len); + } else { + memcpy(tdb->transaction->blocks[blk] + off, buf, len); + } + if (blk == tdb->transaction->num_blocks-1) { + if (len + off > tdb->transaction->last_block_size) { + tdb->transaction->last_block_size = len + off; + } + } + + return 0; + +fail: + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", + (blk*tdb->transaction->block_size) + off, len)); + tdb->transaction->transaction_error = 1; + return -1; +} + + +/* + write while in a transaction - this varient never expands the transaction blocks, it only + updates existing blocks. This means it cannot change the recovery size +*/ +static int transaction_write_existing(struct tdb_context *tdb, tdb_off_t off, + const void *buf, tdb_len_t len) +{ + uint32_t blk; + + /* break it up into block sized chunks */ + while (len + (off % tdb->transaction->block_size) > tdb->transaction->block_size) { + tdb_len_t len2 = tdb->transaction->block_size - (off % tdb->transaction->block_size); + if (transaction_write_existing(tdb, off, buf, len2) != 0) { return -1; } - if (buf) { - memcpy(el->data + el->length, buf, len); - } else { - memset(el->data + el->length, TDB_PAD_BYTE, len); + len -= len2; + off += len2; + if (buf != NULL) { + buf = (const void *)(len2 + (const char *)buf); } - el->length += len; - return 0; } - /* add a new entry at the end of the list */ - el = (struct tdb_transaction_el *)malloc(sizeof(*el)); - if (el == NULL) { - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; + if (len == 0) { + return 0; } - el->next = NULL; - el->prev = tdb->transaction->elements_last; - el->offset = off; - el->length = len; - el->data = (unsigned char *)malloc(len); - if (el->data == NULL) { - free(el); - tdb->ecode = TDB_ERR_OOM; - tdb->transaction->transaction_error = 1; - return -1; + + blk = off / tdb->transaction->block_size; + off = off % tdb->transaction->block_size; + + if (tdb->transaction->num_blocks <= blk || + tdb->transaction->blocks[blk] == NULL) { + return 0; } - if (buf) { - memcpy(el->data, buf, len); + + /* overwrite part of an existing block */ + if (buf == NULL) { + memset(tdb->transaction->blocks[blk] + off, 0, len); } else { - memset(el->data, TDB_PAD_BYTE, len); + memcpy(tdb->transaction->blocks[blk] + off, buf, len); } - if (el->prev) { - el->prev->next = el; - } else { - tdb->transaction->elements = el; + if (blk == tdb->transaction->num_blocks-1) { + if (len + off > tdb->transaction->last_block_size) { + tdb->transaction->last_block_size = len + off; + } } - tdb->transaction->elements_last = el; + return 0; fail: - TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", off, len)); - tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, TDB_DEBUG_FATAL, "transaction_write: failed at off=%d len=%d\n", + (blk*tdb->transaction->block_size) + off, len)); tdb->transaction->transaction_error = 1; return -1; } + /* accelerated hash chain head search, using the cached hash heads */ @@ -419,10 +444,14 @@ int tdb_transaction_start(struct tdb_context *tdb) return -1; } + /* a page at a time seems like a reasonable compromise between compactness and efficiency */ + tdb->transaction->block_size = tdb->page_size; + /* get the transaction write lock. This is a blocking lock. As discussed with Volker, there are a number of ways we could make this async, which we will probably do in the future */ if (tdb_transaction_lock(tdb, F_WRLCK) == -1) { + SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction); return -1; } @@ -460,21 +489,12 @@ int tdb_transaction_start(struct tdb_context *tdb) tdb->transaction->io_methods = tdb->methods; tdb->methods = &transaction_methods; - /* by calling this transaction write here, we ensure that we don't grow the - transaction linked list due to hash table updates */ - if (transaction_write(tdb, FREELIST_TOP, tdb->transaction->hash_heads, - TDB_HASHTABLE_SIZE(tdb)) != 0) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_start: failed to prime hash table\n")); - tdb->ecode = TDB_ERR_IO; - tdb->methods = tdb->transaction->io_methods; - goto fail; - } - return 0; fail: tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0); tdb_transaction_unlock(tdb); + SAFE_FREE(tdb->transaction->blocks); SAFE_FREE(tdb->transaction->hash_heads); SAFE_FREE(tdb->transaction); return -1; @@ -486,6 +506,8 @@ fail: */ int tdb_transaction_cancel(struct tdb_context *tdb) { + int i; + if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_cancel: no transaction\n")); return -1; @@ -499,13 +521,13 @@ int tdb_transaction_cancel(struct tdb_context *tdb) tdb->map_size = tdb->transaction->old_map_size; - /* free all the transaction elements */ - while (tdb->transaction->elements) { - struct tdb_transaction_el *el = tdb->transaction->elements; - tdb->transaction->elements = el->next; - free(el->data); - free(el); + /* free all the transaction blocks */ + for (i=0;i<tdb->transaction->num_blocks;i++) { + if (tdb->transaction->blocks[i] != NULL) { + free(tdb->transaction->blocks[i]); + } } + SAFE_FREE(tdb->transaction->blocks); /* remove any global lock created during the transaction */ if (tdb->global_lock.count != 0) { @@ -515,7 +537,6 @@ int tdb_transaction_cancel(struct tdb_context *tdb) /* remove any locks created during the transaction */ if (tdb->num_locks != 0) { - int i; for (i=0;i<tdb->num_lockrecs;i++) { tdb_brlock(tdb,FREELIST_TOP+4*tdb->lockrecs[i].list, F_UNLCK,F_SETLKW, 0, 1); @@ -567,16 +588,24 @@ static int transaction_sync(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t */ static tdb_len_t tdb_recovery_size(struct tdb_context *tdb) { - struct tdb_transaction_el *el; tdb_len_t recovery_size = 0; + int i; recovery_size = sizeof(uint32_t); - for (el=tdb->transaction->elements;el;el=el->next) { - if (el->offset >= tdb->transaction->old_map_size) { + for (i=0;i<tdb->transaction->num_blocks;i++) { + if (i * tdb->transaction->block_size >= tdb->transaction->old_map_size) { + break; + } + if (tdb->transaction->blocks[i] == NULL) { continue; } - recovery_size += 2*sizeof(tdb_off_t) + el->length; - } + recovery_size += 2*sizeof(tdb_off_t); + if (i == tdb->transaction->num_blocks-1) { + recovery_size += tdb->transaction->last_block_size; + } else { + recovery_size += tdb->transaction->block_size; + } + } return recovery_size; } @@ -658,6 +687,10 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); return -1; } + if (transaction_write_existing(tdb, TDB_RECOVERY_HEAD, &recovery_head, sizeof(tdb_off_t)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_recovery_allocate: failed to write recovery head\n")); + return -1; + } return 0; } @@ -669,7 +702,6 @@ static int tdb_recovery_allocate(struct tdb_context *tdb, static int transaction_setup_recovery(struct tdb_context *tdb, tdb_off_t *magic_offset) { - struct tdb_transaction_el *el; tdb_len_t recovery_size; unsigned char *data, *p; const struct tdb_methods *methods = tdb->transaction->io_methods; @@ -677,6 +709,7 @@ static int transaction_setup_recovery(struct tdb_context *tdb, tdb_off_t recovery_offset, recovery_max_size; tdb_off_t old_map_size = tdb->transaction->old_map_size; uint32_t magic, tailer; + int i; /* check that the recovery area has enough space @@ -704,30 +737,43 @@ static int transaction_setup_recovery(struct tdb_context *tdb, /* build the recovery data into a single blob to allow us to do a single large write, which should be more efficient */ p = data + sizeof(*rec); - for (el=tdb->transaction->elements;el;el=el->next) { - if (el->offset >= old_map_size) { + for (i=0;i<tdb->transaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; + + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (offset >= old_map_size) { continue; } - if (el->offset + el->length > tdb->transaction->old_map_size) { + if (offset + length > tdb->transaction->old_map_size) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: transaction data over new region boundary\n")); free(data); tdb->ecode = TDB_ERR_CORRUPT; return -1; } - memcpy(p, &el->offset, 4); - memcpy(p+4, &el->length, 4); + memcpy(p, &offset, 4); + memcpy(p+4, &length, 4); if (DOCONV()) { tdb_convert(p, 8); } /* the recovery area contains the old data, not the new data, so we have to call the original tdb_read method to get it */ - if (methods->tdb_read(tdb, el->offset, p + 8, el->length, 0) != 0) { + if (methods->tdb_read(tdb, offset, p + 8, length, 0) != 0) { free(data); tdb->ecode = TDB_ERR_IO; return -1; } - p += 8 + el->length; + p += 8 + length; } /* and the tailer */ @@ -742,6 +788,12 @@ static int transaction_setup_recovery(struct tdb_context *tdb, tdb->ecode = TDB_ERR_IO; return -1; } + if (transaction_write_existing(tdb, recovery_offset, data, sizeof(*rec) + recovery_size) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery data\n")); + free(data); + tdb->ecode = TDB_ERR_IO; + return -1; + } /* as we don't have ordered writes, we have to sync the recovery data before we update the magic to indicate that the recovery @@ -763,6 +815,11 @@ static int transaction_setup_recovery(struct tdb_context *tdb, tdb->ecode = TDB_ERR_IO; return -1; } + if (transaction_write_existing(tdb, *magic_offset, &magic, sizeof(magic)) == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_setup_recovery: failed to write secondary recovery magic\n")); + tdb->ecode = TDB_ERR_IO; + return -1; + } /* ensure the recovery magic marker is on disk */ if (transaction_sync(tdb, *magic_offset, sizeof(magic)) == -1) { @@ -780,6 +837,7 @@ int tdb_transaction_commit(struct tdb_context *tdb) const struct tdb_methods *methods; tdb_off_t magic_offset = 0; uint32_t zero = 0; + int i; if (tdb->transaction == NULL) { TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_commit: no transaction\n")); @@ -793,13 +851,14 @@ int tdb_transaction_commit(struct tdb_context *tdb) return -1; } + if (tdb->transaction->nesting != 0) { tdb->transaction->nesting--; return 0; } /* check for a null transaction */ - if (tdb->transaction->elements == NULL) { + if (tdb->transaction->blocks == NULL) { tdb_transaction_cancel(tdb); return 0; } @@ -858,10 +917,21 @@ int tdb_transaction_commit(struct tdb_context *tdb) } /* perform all the writes */ - while (tdb->transaction->elements) { - struct tdb_transaction_el *el = tdb->transaction->elements; + for (i=0;i<tdb->transaction->num_blocks;i++) { + tdb_off_t offset; + tdb_len_t length; - if (methods->tdb_write(tdb, el->offset, el->data, el->length) == -1) { + if (tdb->transaction->blocks[i] == NULL) { + continue; + } + + offset = i * tdb->transaction->block_size; + length = tdb->transaction->block_size; + if (i == tdb->transaction->num_blocks-1) { + length = tdb->transaction->last_block_size; + } + + if (methods->tdb_write(tdb, offset, tdb->transaction->blocks[i], length) == -1) { TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed during commit\n")); /* we've overwritten part of the data and @@ -876,11 +946,12 @@ int tdb_transaction_commit(struct tdb_context *tdb) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_transaction_commit: write failed\n")); return -1; } - tdb->transaction->elements = el->next; - free(el->data); - free(el); + SAFE_FREE(tdb->transaction->blocks[i]); } + SAFE_FREE(tdb->transaction->blocks); + tdb->transaction->num_blocks = 0; + if (!(tdb->flags & TDB_NOSYNC)) { /* ensure the new data is on disk */ if (transaction_sync(tdb, 0, tdb->map_size) == -1) { @@ -919,6 +990,7 @@ int tdb_transaction_commit(struct tdb_context *tdb) /* use a transaction cancel to free memory and remove the transaction locks */ tdb_transaction_cancel(tdb); + return 0; } diff --git a/source3/lib/tdb/common/traverse.c b/source3/lib/tdb/common/traverse.c index 27b2cfc54a4..07b0c238587 100644 --- a/source3/lib/tdb/common/traverse.c +++ b/source3/lib/tdb/common/traverse.c @@ -241,7 +241,9 @@ int tdb_traverse(struct tdb_context *tdb, return -1; } + tdb->traverse_write++; ret = tdb_traverse_internal(tdb, fn, private_data, &tl); + tdb->traverse_write--; tdb_transaction_unlock(tdb); @@ -333,3 +335,4 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); return key; } + diff --git a/source3/lib/tdb/configure.ac b/source3/lib/tdb/configure.ac index de8fc9c2b59..1085055bc91 100644 --- a/source3/lib/tdb/configure.ac +++ b/source3/lib/tdb/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.50) AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) AC_DEFUN([SMB_ENABLE], [echo -n ""]) -AC_INIT(tdb, 1.1.0) +AC_INIT(tdb, 1.1.1) AC_CONFIG_SRCDIR([common/tdb.c]) AC_CONFIG_HEADER(include/config.h) AC_LIBREPLACE_ALL_CHECKS diff --git a/source3/lib/tdb/include/tdb.h b/source3/lib/tdb/include/tdb.h index fce6628b846..0008085de54 100644 --- a/source3/lib/tdb/include/tdb.h +++ b/source3/lib/tdb/include/tdb.h @@ -135,6 +135,8 @@ int tdb_get_seqnum(struct tdb_context *tdb); int tdb_hash_size(struct tdb_context *tdb); size_t tdb_map_size(struct tdb_context *tdb); int tdb_get_flags(struct tdb_context *tdb); +void tdb_add_flags(struct tdb_context *tdb, unsigned flag); +void tdb_remove_flags(struct tdb_context *tdb, unsigned flag); void tdb_enable_seqnum(struct tdb_context *tdb); void tdb_increment_seqnum_nonblock(struct tdb_context *tdb); @@ -153,6 +155,8 @@ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *sigptr) void tdb_dump_all(struct tdb_context *tdb); int tdb_printfreelist(struct tdb_context *tdb); int tdb_validate_freelist(struct tdb_context *tdb, int *pnum_entries); +int tdb_wipe_all(struct tdb_context *tdb); +int tdb_freelist_size(struct tdb_context *tdb); extern TDB_DATA tdb_null; diff --git a/source3/lib/winbind_util.c b/source3/lib/winbind_util.c index 3cf068a6e0d..14356b09cf7 100644 --- a/source3/lib/winbind_util.c +++ b/source3/lib/winbind_util.c @@ -201,7 +201,7 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx, *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids); for(i=0; i<num_rids; i++) { - (*names)[i] = talloc_strdup(names, namelist[i]); + (*names)[i] = talloc_strdup(*names, namelist[i]); (*types)[i] = (enum lsa_SidType)name_types[i]; } diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 500f2d455e1..9a6f1061df0 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -214,7 +214,7 @@ static bool pac_io_group_membership_array(const char *desc, static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { - uint32 garbage, i; + uint32 garbage = 0, i; if (NULL == info) return False; @@ -398,7 +398,7 @@ static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, prs_struct *ps, int depth) { - uint32 garbage; + uint32 garbage = 0; bool kerb_validation_info = True; if (NULL == info) diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4fc23956bde..e9222e84018 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -209,7 +209,8 @@ int kerberos_kinit_password_ext(const char *principal, krb5_set_real_time(ctx, time(NULL) + time_offset, 0); } - DEBUG(10,("kerberos_kinit_password: using [%s] as ccache and config [%s]\n", + DEBUG(10,("kerberos_kinit_password: as %s using [%s] as ccache and config [%s]\n", + principal, cache_name ? cache_name: krb5_cc_default_name(ctx), getenv("KRB5_CONFIG"))); diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 7040093e901..5ce7aa6b457 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -501,8 +501,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, DEBUG(3,("ads_verify_ticket: did not retrieve auth data. continuing without PAC\n")); } - if (got_auth_data && pac_data != NULL) { - + if (got_auth_data) { pac_ret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data); if (!NT_STATUS_IS_OK(pac_ret)) { DEBUG(3,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(pac_ret))); diff --git a/source3/libnet/libnet.h b/source3/libnet/libnet.h index fa24c3b40a8..d6238ca9820 100644 --- a/source3/libnet/libnet.h +++ b/source3/libnet/libnet.h @@ -21,6 +21,7 @@ #define __LIBNET_H__ #include "libnet/libnet_join.h" +#include "libnet/libnet_conf.h" #include "libnet/libnet_proto.h" #endif diff --git a/source3/libnet/libnet_conf.c b/source3/libnet/libnet_conf.c index d0ef6eb0e6b..d20e10b1416 100644 --- a/source3/libnet/libnet_conf.c +++ b/source3/libnet/libnet_conf.c @@ -21,11 +21,6 @@ #include "includes.h" #include "libnet/libnet.h" -/* - * yuck - static variable to keep track of the registry initialization. - */ -static bool registry_initialized = false; - /********************************************************************** * * Helper functions (mostly registry related) @@ -59,20 +54,21 @@ static WERROR libnet_conf_add_string_to_array(TALLOC_CTX *mem_ctx, return WERR_OK; } -static WERROR libnet_conf_reg_initialize(void) +static WERROR libnet_conf_reg_initialize(struct libnet_conf_ctx *ctx) { WERROR werr = WERR_OK; - if (registry_initialized) { - goto done; - } - if (!registry_init_regdb()) { werr = WERR_REG_IO_FAILURE; goto done; } - registry_initialized = true; + werr = ntstatus_to_werror(registry_create_admin_token(ctx, + &(ctx->token))); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1, ("Error creating admin token\n")); + goto done; + } done: return werr; @@ -82,40 +78,33 @@ done: * Open a registry key specified by "path" */ static WERROR libnet_conf_reg_open_path(TALLOC_CTX *mem_ctx, + struct libnet_conf_ctx *ctx, const char *path, uint32 desired_access, struct registry_key **key) { WERROR werr = WERR_OK; - NT_USER_TOKEN *token = NULL; - TALLOC_CTX *tmp_ctx = NULL; - if (path == NULL) { - DEBUG(1, ("Error: NULL path string given\n")); + if (ctx == NULL) { + DEBUG(1, ("Error: configuration is not open!\n")); werr = WERR_INVALID_PARAM; goto done; } - tmp_ctx = talloc_new(mem_ctx); - if (tmp_ctx == NULL) { - werr = WERR_NOMEM; - goto done; - } - - werr = libnet_conf_reg_initialize(); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(1, ("Error initializing registry: %s\n", - dos_errstr(werr))); + if (ctx->token == NULL) { + DEBUG(1, ("Error: token missing from libnet_conf_ctx. " + "was libnet_conf_open() called?\n")); + werr = WERR_INVALID_PARAM; goto done; } - werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token)); - if (W_ERROR_IS_OK(werr)) { - DEBUG(1, ("Error creating admin token\n")); + 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, token, key); + werr = reg_open_path(mem_ctx, path, desired_access, ctx->token, key); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("Error opening registry path '%s': %s\n", @@ -123,14 +112,14 @@ static WERROR libnet_conf_reg_open_path(TALLOC_CTX *mem_ctx, } done: - TALLOC_FREE(tmp_ctx); return werr; } /** * Open a subkey of KEY_SMBCONF (i.e a service) */ -static WERROR libnet_conf_reg_open_service_key(TALLOC_CTX *ctx, +static WERROR libnet_conf_reg_open_service_key(TALLOC_CTX *mem_ctx, + struct libnet_conf_ctx *ctx, const char *servicename, uint32 desired_access, struct registry_key **key) @@ -144,9 +133,10 @@ static WERROR libnet_conf_reg_open_service_key(TALLOC_CTX *ctx, goto done; } - path = talloc_asprintf(ctx, "%s\\%s", KEY_SMBCONF, servicename); + path = talloc_asprintf(mem_ctx, "%s\\%s", KEY_SMBCONF, servicename); - werr = libnet_conf_reg_open_path(ctx, path, desired_access, key); + werr = libnet_conf_reg_open_path(mem_ctx, ctx, path, desired_access, + key); done: TALLOC_FREE(path); @@ -156,11 +146,13 @@ done: /** * open the base key KEY_SMBCONF */ -static WERROR libnet_conf_reg_open_base_key(TALLOC_CTX *ctx, +static WERROR libnet_conf_reg_open_base_key(TALLOC_CTX *mem_ctx, + struct libnet_conf_ctx *ctx, uint32 desired_access, struct registry_key **key) { - return libnet_conf_reg_open_path(ctx, KEY_SMBCONF, desired_access, key); + return libnet_conf_reg_open_path(mem_ctx, ctx, KEY_SMBCONF, + desired_access, key); } /** @@ -186,7 +178,8 @@ static bool libnet_conf_value_exists(struct registry_key *key, /** * create a subkey of KEY_SMBCONF */ -static WERROR libnet_conf_reg_create_service_key(TALLOC_CTX *ctx, +static WERROR libnet_conf_reg_create_service_key(TALLOC_CTX *mem_ctx, + struct libnet_conf_ctx *ctx, const char * subkeyname, struct registry_key **newkey) { @@ -198,18 +191,18 @@ static WERROR libnet_conf_reg_create_service_key(TALLOC_CTX *ctx, /* create a new talloc ctx for creation. it will hold * the intermediate parent key (SMBCONF) for creation * and will be destroyed when leaving this function... */ - if (!(create_ctx = talloc_new(ctx))) { + if (!(create_ctx = talloc_new(mem_ctx))) { werr = WERR_NOMEM; goto done; } - werr = libnet_conf_reg_open_base_key(create_ctx, REG_KEY_WRITE, + werr = libnet_conf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE, &create_parent); if (!W_ERROR_IS_OK(werr)) { goto done; } - werr = reg_createkey(ctx, create_parent, subkeyname, + werr = reg_createkey(mem_ctx, create_parent, 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)); @@ -414,6 +407,11 @@ done: return werr; } +static int libnet_conf_destroy_ctx(struct libnet_conf_ctx *ctx) +{ + return regdb_close(); +} + /********************************************************************** * * The actual net conf api functions, that are exported. @@ -421,9 +419,60 @@ done: **********************************************************************/ /** + * Open the configuration. + * + * This should be the first function in a sequence of calls to libnet_conf + * functions: + * + * Upon success, this creates and returns the conf context + * that should be passed around in subsequent calls to the other + * libnet_conf functions. + * + * After the work with the configuration is completed, libnet_conf_close() + * should be called. + */ +WERROR libnet_conf_open(TALLOC_CTX *mem_ctx, struct libnet_conf_ctx **conf_ctx) +{ + WERROR werr = WERR_OK; + struct libnet_conf_ctx *ctx; + + if (conf_ctx == NULL) { + return WERR_INVALID_PARAM; + } + + ctx = TALLOC_ZERO_P(mem_ctx, struct libnet_conf_ctx); + if (ctx == NULL) { + return WERR_NOMEM; + } + + werr = libnet_conf_reg_initialize(ctx); + if (!W_ERROR_IS_OK(werr)) { + goto fail; + } + + talloc_set_destructor(ctx, libnet_conf_destroy_ctx); + + *conf_ctx = ctx; + return werr; + +fail: + TALLOC_FREE(ctx); + return werr; +} + +/** + * Close the configuration. + */ +void libnet_conf_close(struct libnet_conf_ctx *ctx) +{ + /* this also closes the registry (by destructor): */ + TALLOC_FREE(ctx); +} + +/** * Drop the whole configuration (restarting empty). */ -WERROR libnet_conf_drop(void) +WERROR libnet_conf_drop(struct libnet_conf_ctx *ctx) { char *path, *p; WERROR werr = WERR_OK; @@ -439,7 +488,7 @@ WERROR libnet_conf_drop(void) } p = strrchr(path, '\\'); *p = '\0'; - werr = libnet_conf_reg_open_path(mem_ctx, path, REG_KEY_WRITE, + werr = libnet_conf_reg_open_path(mem_ctx, ctx, path, REG_KEY_WRITE, &parent_key); if (!W_ERROR_IS_OK(werr)) { @@ -469,7 +518,8 @@ done: * param_names : list of lists of parameter names for each share * param_values : list of lists of parameter values for each share */ -WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares, +WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx, + struct libnet_conf_ctx *ctx, uint32_t *num_shares, char ***share_names, uint32_t **num_params, char ****param_names, char ****param_values) { @@ -496,7 +546,7 @@ WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares, goto done; } - werr = libnet_conf_get_share_names(tmp_ctx, &tmp_num_shares, + werr = libnet_conf_get_share_names(tmp_ctx, ctx, &tmp_num_shares, &tmp_share_names); if (!W_ERROR_IS_OK(werr)) { goto done; @@ -514,7 +564,8 @@ WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares, } for (count = 0; count < tmp_num_shares; count++) { - werr = libnet_conf_get_share(mem_ctx, tmp_share_names[count], + werr = libnet_conf_get_share(mem_ctx, ctx, + tmp_share_names[count], &tmp_num_params[count], &tmp_param_names[count], &tmp_param_values[count]); @@ -543,11 +594,12 @@ done: return werr; } - /** * get the list of share names defined in the configuration. */ -WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares, +WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx, + struct libnet_conf_ctx *ctx, + uint32_t *num_shares, char ***share_names) { uint32_t count; @@ -570,7 +622,7 @@ WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares, } /* make sure "global" is always listed first */ - if (libnet_conf_share_exists(GLOBAL_NAME)) { + if (libnet_conf_share_exists(ctx, GLOBAL_NAME)) { werr = libnet_conf_add_string_to_array(tmp_ctx, &tmp_share_names, 0, GLOBAL_NAME); @@ -580,8 +632,8 @@ WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares, added_count++; } - werr = libnet_conf_reg_open_base_key(tmp_ctx, SEC_RIGHTS_ENUM_SUBKEYS, - &key); + werr = libnet_conf_reg_open_base_key(tmp_ctx, ctx, + SEC_RIGHTS_ENUM_SUBKEYS, &key); if (!W_ERROR_IS_OK(werr)) { goto done; } @@ -624,14 +676,15 @@ done: /** * check if a share/service of a given name exists */ -bool libnet_conf_share_exists(const char *servicename) +bool libnet_conf_share_exists(struct libnet_conf_ctx *ctx, + const char *servicename) { bool ret = false; WERROR werr = WERR_OK; TALLOC_CTX *mem_ctx = talloc_stackframe(); struct registry_key *key = NULL; - werr = libnet_conf_reg_open_service_key(mem_ctx, servicename, + werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, servicename, REG_KEY_READ, &key); if (W_ERROR_IS_OK(werr)) { ret = true; @@ -644,18 +697,20 @@ bool libnet_conf_share_exists(const char *servicename) /** * Add a service if it does not already exist. */ -WERROR libnet_conf_create_share(const char *servicename) +WERROR libnet_conf_create_share(struct libnet_conf_ctx *ctx, + const char *servicename) { WERROR werr; TALLOC_CTX *mem_ctx = talloc_stackframe(); struct registry_key *key = NULL; - if (libnet_conf_share_exists(servicename)) { + if (libnet_conf_share_exists(ctx, servicename)) { werr = WERR_ALREADY_EXISTS; goto done; } - werr = libnet_conf_reg_create_service_key(mem_ctx, servicename, &key); + werr = libnet_conf_reg_create_service_key(mem_ctx, ctx, servicename, + &key); done: TALLOC_FREE(mem_ctx); @@ -665,14 +720,14 @@ done: /** * get a definition of a share (service) from configuration. */ -WERROR libnet_conf_get_share(TALLOC_CTX *mem_ctx, const char *servicename, - uint32_t *num_params, char ***param_names, - char ***param_values) +WERROR libnet_conf_get_share(TALLOC_CTX *mem_ctx, struct libnet_conf_ctx *ctx, + const char *servicename, uint32_t *num_params, + char ***param_names, char ***param_values) { WERROR werr = WERR_OK; struct registry_key *key = NULL; - werr = libnet_conf_reg_open_service_key(mem_ctx, servicename, + werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, servicename, REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { goto done; @@ -689,13 +744,14 @@ done: /** * delete a service from configuration */ -WERROR libnet_conf_delete_share(const char *servicename) +WERROR libnet_conf_delete_share(struct libnet_conf_ctx *ctx, + const char *servicename) { WERROR werr = WERR_OK; struct registry_key *key = NULL; - TALLOC_CTX *ctx = talloc_stackframe(); + TALLOC_CTX *mem_ctx = talloc_stackframe(); - werr = libnet_conf_reg_open_base_key(ctx, REG_KEY_WRITE, &key); + werr = libnet_conf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, &key); if (!W_ERROR_IS_OK(werr)) { goto done; } @@ -703,14 +759,15 @@ WERROR libnet_conf_delete_share(const char *servicename) werr = reg_deletekey_recursive(key, key, servicename); done: - TALLOC_FREE(ctx); + TALLOC_FREE(mem_ctx); return werr; } /** * set a configuration parameter to the value provided. */ -WERROR libnet_conf_set_parameter(const char *service, +WERROR libnet_conf_set_parameter(struct libnet_conf_ctx *ctx, + const char *service, const char *param, const char *valstr) { @@ -718,13 +775,13 @@ WERROR libnet_conf_set_parameter(const char *service, struct registry_key *key = NULL; TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!libnet_conf_share_exists(service)) { + if (!libnet_conf_share_exists(ctx, service)) { werr = WERR_NO_SUCH_SERVICE; goto done; } - werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_WRITE, - &key); + werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, service, + REG_KEY_WRITE, &key); if (!W_ERROR_IS_OK(werr)) { goto done; } @@ -737,9 +794,33 @@ done: } /** + * Set a global parameter + * (i.e. a parameter in the [global] service). + * + * This also creates [global] when it does not exist. + */ +WERROR libnet_conf_set_global_parameter(struct libnet_conf_ctx *ctx, + const char *param, const char *val) +{ + WERROR werr; + + if (!libnet_conf_share_exists(ctx, GLOBAL_NAME)) { + werr = libnet_conf_create_share(ctx, GLOBAL_NAME); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + } + werr = libnet_conf_set_parameter(ctx, GLOBAL_NAME, param, val); + +done: + return werr; +} + +/** * get the value of a configuration parameter as a string */ WERROR libnet_conf_get_parameter(TALLOC_CTX *mem_ctx, + struct libnet_conf_ctx *ctx, const char *service, const char *param, char **valstr) @@ -753,13 +834,13 @@ WERROR libnet_conf_get_parameter(TALLOC_CTX *mem_ctx, goto done; } - if (!libnet_conf_share_exists(service)) { + if (!libnet_conf_share_exists(ctx, service)) { werr = WERR_NO_SUCH_SERVICE; goto done; } - werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_READ, - &key); + werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, service, + REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { goto done; } @@ -787,19 +868,46 @@ done: } /** + * Get the value of a global parameter. + * + * Create [global] if it does not exist. + */ +WERROR libnet_conf_get_global_parameter(TALLOC_CTX *mem_ctx, + struct libnet_conf_ctx *ctx, + const char *param, + char **valstr) +{ + WERROR werr; + + if (!libnet_conf_share_exists(ctx, GLOBAL_NAME)) { + werr = libnet_conf_create_share(ctx, GLOBAL_NAME); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + } + werr = libnet_conf_get_parameter(mem_ctx, ctx, GLOBAL_NAME, param, + valstr); + +done: + return werr; +} + +/** * delete a parameter from configuration */ -WERROR libnet_conf_delete_parameter(const char *service, const char *param) +WERROR libnet_conf_delete_parameter(struct libnet_conf_ctx *ctx, + const char *service, const char *param) { struct registry_key *key = NULL; WERROR werr = WERR_OK; TALLOC_CTX *mem_ctx = talloc_stackframe(); - if (!libnet_conf_share_exists(service)) { + if (!libnet_conf_share_exists(ctx, service)) { return WERR_NO_SUCH_SERVICE; } - werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_ALL, + werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, service, + REG_KEY_ALL, &key); if (!W_ERROR_IS_OK(werr)) { goto done; @@ -817,15 +925,24 @@ done: return werr; } - -/********************************************************************** - * - * Convenience functions that are also exported. +/** + * Delete a global parameter. * - **********************************************************************/ - -WERROR libnet_conf_set_global_parameter(const char *param, const char *val) + * Create [global] if it does not exist. + */ +WERROR libnet_conf_delete_global_parameter(struct libnet_conf_ctx *ctx, + const char *param) { - return libnet_conf_set_parameter(GLOBAL_NAME, param, val); -} + WERROR werr; + + if (!libnet_conf_share_exists(ctx, GLOBAL_NAME)) { + werr = libnet_conf_create_share(ctx, GLOBAL_NAME); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + } + werr = libnet_conf_delete_parameter(ctx, GLOBAL_NAME, param); +done: + return werr; +} diff --git a/source3/libnet/libnet_conf.h b/source3/libnet/libnet_conf.h new file mode 100644 index 00000000000..b518c0e3b0a --- /dev/null +++ b/source3/libnet/libnet_conf.h @@ -0,0 +1,27 @@ +/* + * Unix SMB/CIFS implementation. + * libnet smbconf registry support + * Copyright (C) Michael Adam 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __LIBNET_CONF_H__ +#define __LIBNET_CONF_H__ + +struct libnet_conf_ctx { + NT_USER_TOKEN *token; +}; + +#endif diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 1df85ebb610..c60f4c98035 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -19,8 +19,7 @@ */ #include "includes.h" -#include "libnet/libnet_join.h" -#include "libnet/libnet_proto.h" +#include "libnet/libnet.h" /**************************************************************** ****************************************************************/ @@ -30,14 +29,14 @@ static void libnet_join_set_error_string(TALLOC_CTX *mem_ctx, const char *format, ...) { va_list args; - char *tmp = NULL; + + if (r->out.error_string) { + return; + } va_start(args, format); - tmp = talloc_vasprintf(mem_ctx, format, args); + r->out.error_string = talloc_vasprintf(mem_ctx, format, args); va_end(args); - - TALLOC_FREE(r->out.error_string); - r->out.error_string = tmp; } /**************************************************************** @@ -48,17 +47,17 @@ static void libnet_unjoin_set_error_string(TALLOC_CTX *mem_ctx, const char *format, ...) { va_list args; - char *tmp = NULL; + + if (r->out.error_string) { + return; + } va_start(args, format); - tmp = talloc_vasprintf(mem_ctx, format, args); + r->out.error_string = talloc_vasprintf(mem_ctx, format, args); va_end(args); - - TALLOC_FREE(r->out.error_string); - r->out.error_string = tmp; } -#ifdef HAVE_LDAP +#ifdef WITH_ADS /**************************************************************** ****************************************************************/ @@ -108,10 +107,6 @@ static ADS_STATUS libnet_join_connect_ads(TALLOC_CTX *mem_ctx, { ADS_STATUS status; - if (r->in.ads) { - ads_destroy(&r->in.ads); - } - status = libnet_connect_ads(r->in.domain_name, r->in.domain_name, r->in.dc_name, @@ -135,10 +130,6 @@ static ADS_STATUS libnet_unjoin_connect_ads(TALLOC_CTX *mem_ctx, { ADS_STATUS status; - if (r->in.ads) { - ads_destroy(&r->in.ads); - } - status = libnet_connect_ads(r->in.domain_name, r->in.domain_name, r->in.dc_name, @@ -426,8 +417,6 @@ static ADS_STATUS libnet_join_set_os_attributes(TALLOC_CTX *mem_ctx, return ads_gen_mod(r->in.ads, r->out.dn, mods); } -#endif /* HAVE_LDAP */ - /**************************************************************** ****************************************************************/ @@ -437,16 +426,14 @@ static bool libnet_join_create_keytab(TALLOC_CTX *mem_ctx, if (!lp_use_kerberos_keytab()) { return true; } -#ifdef HAVE_KRB5 + if (!ads_keytab_create_default(r->in.ads)) { return false; } -#endif /* HAVE_KRB5 */ + return true; } -#ifdef HAVE_KRB5 - /**************************************************************** ****************************************************************/ @@ -461,7 +448,8 @@ static bool libnet_join_derive_salting_principal(TALLOC_CTX *mem_ctx, status = ads_domain_func_level(r->in.ads, &domain_func); if (!ADS_ERR_OK(status)) { libnet_join_set_error_string(mem_ctx, r, - "Failed to determine domain functional level!"); + "failed to determine domain functional level: %s", + ads_errstr(status)); return false; } @@ -495,7 +483,51 @@ static bool libnet_join_derive_salting_principal(TALLOC_CTX *mem_ctx, return kerberos_secrets_store_des_salt(salt); } -#endif /* HAVE_KRB5 */ +/**************************************************************** +****************************************************************/ + +static ADS_STATUS libnet_join_post_processing_ads(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) +{ + ADS_STATUS status; + + status = libnet_join_set_machine_spn(mem_ctx, r); + if (!ADS_ERR_OK(status)) { + libnet_join_set_error_string(mem_ctx, r, + "failed to set machine spn: %s", + ads_errstr(status)); + return status; + } + + status = libnet_join_set_os_attributes(mem_ctx, r); + if (!ADS_ERR_OK(status)) { + libnet_join_set_error_string(mem_ctx, r, + "failed to set machine os attributes: %s", + ads_errstr(status)); + return status; + } + + status = libnet_join_set_machine_upn(mem_ctx, r); + if (!ADS_ERR_OK(status)) { + libnet_join_set_error_string(mem_ctx, r, + "failed to set machine upn: %s", + ads_errstr(status)); + return status; + } + + if (!libnet_join_derive_salting_principal(mem_ctx, r)) { + return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + } + + if (!libnet_join_create_keytab(mem_ctx, r)) { + libnet_join_set_error_string(mem_ctx, r, + "failed to create kerberos keytab"); + return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); + } + + return ADS_SUCCESS; +} +#endif /* WITH_ADS */ /**************************************************************** ****************************************************************/ @@ -630,7 +662,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, 0xe005000b, &user_pol, &user_rid); if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { - if (!(r->in.join_flags & WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED)) { + if (!(r->in.join_flags & + WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED)) { goto done; } } @@ -678,14 +711,13 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, memcpy(&pwbuf[516], md5buffer, sizeof(md5buffer)); acb_info |= ACB_PWNOEXP; -#if 0 - if ( dom_type == ND_TYPE_AD ) { + if (r->out.domain_is_ad) { #if !defined(ENCTYPE_ARCFOUR_HMAC) acb_info |= ACB_USE_DES_KEY_ONLY; #endif ;; } -#endif + ZERO_STRUCT(ctr); ZERO_STRUCT(p25); @@ -845,33 +877,48 @@ done: static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r) { WERROR werr; + struct libnet_conf_ctx *ctx; + + werr = libnet_conf_open(r, &ctx); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } if (!(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE)) { - werr = libnet_conf_set_global_parameter("security", "user"); - W_ERROR_NOT_OK_RETURN(werr); + werr = libnet_conf_set_global_parameter(ctx, "security", "user"); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } - werr = libnet_conf_set_global_parameter("workgroup", + werr = libnet_conf_set_global_parameter(ctx, "workgroup", r->in.domain_name); - return werr; + goto done; } - werr = libnet_conf_set_global_parameter("security", "domain"); - W_ERROR_NOT_OK_RETURN(werr); + werr = libnet_conf_set_global_parameter(ctx, "security", "domain"); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } - werr = libnet_conf_set_global_parameter("workgroup", + werr = libnet_conf_set_global_parameter(ctx, "workgroup", r->out.netbios_domain_name); - W_ERROR_NOT_OK_RETURN(werr); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } if (r->out.domain_is_ad) { - werr = libnet_conf_set_global_parameter("security", "ads"); - W_ERROR_NOT_OK_RETURN(werr); + werr = libnet_conf_set_global_parameter(ctx, "security", "ads"); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } - werr = libnet_conf_set_global_parameter("realm", - r->out.dns_domain_name); - W_ERROR_NOT_OK_RETURN(werr); + werr = libnet_conf_set_global_parameter(ctx, "realm", + r->out.dns_domain_name); } +done: + libnet_conf_close(ctx); return werr; } @@ -881,15 +928,25 @@ static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r) static WERROR do_unjoin_modify_vals_config(struct libnet_UnjoinCtx *r) { WERROR werr = WERR_OK; + struct libnet_conf_ctx *ctx; + + werr = libnet_conf_open(r, &ctx); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { - werr = libnet_conf_set_global_parameter("security", "user"); - W_ERROR_NOT_OK_RETURN(werr); + werr = libnet_conf_set_global_parameter(ctx, "security", "user"); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } } - libnet_conf_delete_parameter(GLOBAL_NAME, "realm"); + libnet_conf_delete_global_parameter(ctx, "realm"); +done: + libnet_conf_close(ctx); return werr; } @@ -948,6 +1005,58 @@ static WERROR do_UnjoinConfig(struct libnet_UnjoinCtx *r) /**************************************************************** ****************************************************************/ +static WERROR libnet_join_pre_processing(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) +{ + + if (!r->in.domain_name) { + return WERR_INVALID_PARAM; + } + + if (r->in.modify_config && !lp_include_registry_globals()) { + return WERR_NOT_SUPPORTED; + } + + if (IS_DC) { + return WERR_SETUP_DOMAIN_CONTROLLER; + } + + if (!secrets_init()) { + libnet_join_set_error_string(mem_ctx, r, + "Unable to open secrets database"); + return WERR_CAN_NOT_COMPLETE; + } + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + +static WERROR libnet_join_post_processing(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) +{ + WERROR werr; + + if (!W_ERROR_IS_OK(r->out.result)) { + return r->out.result; + } + + werr = do_JoinConfig(r); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { + saf_store(r->in.domain_name, r->in.dc_name); + } + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + static int libnet_destroy_JoinCtx(struct libnet_JoinCtx *r) { if (r->in.ads) { @@ -1022,28 +1131,59 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, struct libnet_JoinCtx *r) { NTSTATUS status; -#ifdef HAVE_LDAP +#ifdef WITH_ADS ADS_STATUS ads_status; +#endif /* WITH_ADS */ + + if (!r->in.dc_name) { + struct DS_DOMAIN_CONTROLLER_INFO *info; + status = dsgetdcname(mem_ctx, + NULL, + r->in.domain_name, + NULL, + NULL, + DS_DIRECTORY_SERVICE_REQUIRED | + DS_WRITABLE_REQUIRED | + DS_RETURN_DNS_NAME, + &info); + if (!NT_STATUS_IS_OK(status)) { + libnet_join_set_error_string(mem_ctx, r, + "failed to find DC: %s", + nt_errstr(status)); + return WERR_DOMAIN_CONTROLLER_NOT_FOUND; + } + r->in.dc_name = talloc_strdup(mem_ctx, + info->domain_controller_name); + W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); + } + +#ifdef WITH_ADS if (r->in.account_ou) { + ads_status = libnet_join_connect_ads(mem_ctx, r); if (!ADS_ERR_OK(ads_status)) { - return WERR_GENERAL_FAILURE; + return WERR_DEFAULT_JOIN_REQUIRED; } + ads_status = libnet_join_precreate_machine_acct(mem_ctx, r); if (!ADS_ERR_OK(ads_status)) { libnet_join_set_error_string(mem_ctx, r, "failed to precreate account in ou %s: %s", r->in.account_ou, ads_errstr(ads_status)); - return WERR_GENERAL_FAILURE; + return WERR_DEFAULT_JOIN_REQUIRED; } r->in.join_flags &= ~WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE; } -#endif /* HAVE_LDAP */ +#endif /* WITH_ADS */ + status = libnet_join_joindomain_rpc(mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { + libnet_join_set_error_string(mem_ctx, r, + "failed to join domain over rpc: %s", + nt_errstr(status)); if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { return WERR_SETUP_ALREADY_JOINED; } @@ -1054,43 +1194,14 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, return WERR_SETUP_NOT_JOINED; } -#ifdef HAVE_LDAP - ads_status = libnet_join_set_machine_spn(mem_ctx, r); - if (!ADS_ERR_OK(ads_status)) { - libnet_join_set_error_string(mem_ctx, r, - "failed to set machine spn: %s", - ads_errstr(ads_status)); - return WERR_GENERAL_FAILURE; - } - - ads_status = libnet_join_set_os_attributes(mem_ctx, r); - if (!ADS_ERR_OK(ads_status)) { - libnet_join_set_error_string(mem_ctx, r, - "failed to set machine os attributes: %s", - ads_errstr(ads_status)); - return WERR_GENERAL_FAILURE; - } - - ads_status = libnet_join_set_machine_upn(mem_ctx, r); - if (!ADS_ERR_OK(ads_status)) { - libnet_join_set_error_string(mem_ctx, r, - "failed to set machine upn: %s", - ads_errstr(ads_status)); - return WERR_GENERAL_FAILURE; - } - -#ifdef HAVE_KRB5 - if (!libnet_join_derive_salting_principal(mem_ctx, r)) { - return WERR_GENERAL_FAILURE; - } -#endif /* HAVE_KRB5 */ - -#endif /* HAVE_LDAP */ - if (!libnet_join_create_keytab(mem_ctx, r)) { - libnet_join_set_error_string(mem_ctx, r, - "failed to create kerberos keytab"); - return WERR_GENERAL_FAILURE; +#ifdef WITH_ADS + if (r->out.domain_is_ad) { + ads_status = libnet_join_post_processing_ads(mem_ctx, r); + if (!ADS_ERR_OK(ads_status)) { + return WERR_GENERAL_FAILURE; + } } +#endif /* WITH_ADS */ return WERR_OK; } @@ -1103,30 +1214,23 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx, { WERROR werr; - if (!r->in.domain_name) { - return WERR_INVALID_PARAM; - } - - if (r->in.modify_config && !lp_include_registry_globals()) { - return WERR_NOT_SUPPORTED; - } - - if (IS_DC) { - return WERR_SETUP_DOMAIN_CONTROLLER; + werr = libnet_join_pre_processing(mem_ctx, r); + if (!W_ERROR_IS_OK(werr)) { + goto done; } if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { werr = libnet_DomainJoin(mem_ctx, r); if (!W_ERROR_IS_OK(werr)) { - return werr; + goto done; } } - werr = do_JoinConfig(r); + werr = libnet_join_post_processing(mem_ctx, r); if (!W_ERROR_IS_OK(werr)) { - return werr; + goto done; } - + done: return werr; } @@ -1138,6 +1242,29 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, { NTSTATUS status; + if (!r->in.dc_name) { + struct DS_DOMAIN_CONTROLLER_INFO *info; + status = dsgetdcname(mem_ctx, + NULL, + r->in.domain_name, + NULL, + NULL, + DS_DIRECTORY_SERVICE_REQUIRED | + DS_WRITABLE_REQUIRED | + DS_RETURN_DNS_NAME, + &info); + if (!NT_STATUS_IS_OK(status)) { + libnet_unjoin_set_error_string(mem_ctx, r, + "failed to find DC: %s", + nt_errstr(status)); + return WERR_DOMAIN_CONTROLLER_NOT_FOUND; + } + + r->in.dc_name = talloc_strdup(mem_ctx, + info->domain_controller_name); + W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); + } + status = libnet_join_unjoindomain_rpc(mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { libnet_unjoin_set_error_string(mem_ctx, r, @@ -1149,7 +1276,7 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, return ntstatus_to_werror(status); } -#ifdef HAVE_LDAP +#ifdef WITH_ADS if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE) { ADS_STATUS ads_status; libnet_unjoin_connect_ads(mem_ctx, r); @@ -1160,7 +1287,8 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, ads_errstr(ads_status)); } } -#endif /* HAVE_LDAP */ +#endif /* WITH_ADS */ + libnet_join_unjoindomain_remove_secrets(mem_ctx, r); return WERR_OK; @@ -1169,27 +1297,47 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +static WERROR libnet_unjoin_pre_processing(TALLOC_CTX *mem_ctx, + struct libnet_UnjoinCtx *r) +{ + if (r->in.modify_config && !lp_include_registry_globals()) { + return WERR_NOT_SUPPORTED; + } + + if (!secrets_init()) { + libnet_unjoin_set_error_string(mem_ctx, r, + "Unable to open secrets database"); + return WERR_CAN_NOT_COMPLETE; + } + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx, struct libnet_UnjoinCtx *r) { WERROR werr; - if (r->in.modify_config && !lp_include_registry_globals()) { - return WERR_NOT_SUPPORTED; + werr = libnet_unjoin_pre_processing(mem_ctx, r); + if (!W_ERROR_IS_OK(werr)) { + goto done; } if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { werr = libnet_DomainUnjoin(mem_ctx, r); if (!W_ERROR_IS_OK(werr)) { - do_UnjoinConfig(r); - return werr; + goto done; } } werr = do_UnjoinConfig(r); if (!W_ERROR_IS_OK(werr)) { - return werr; + goto done; } + done: return werr; } diff --git a/source3/libnet/libnet_join.h b/source3/libnet/libnet_join.h index 95b965717eb..c47e8d934c1 100644 --- a/source3/libnet/libnet_join.h +++ b/source3/libnet/libnet_join.h @@ -36,6 +36,7 @@ struct libnet_JoinCtx { const char *upn; bool modify_config; struct ads_struct *ads; + bool debug; } in; struct { diff --git a/source3/librpc/gen_ndr/cli_lsa.c b/source3/librpc/gen_ndr/cli_lsa.c index 470ab3e0a5a..92ba8bdfee7 100644 --- a/source3/librpc/gen_ndr/cli_lsa.c +++ b/source3/librpc/gen_ndr/cli_lsa.c @@ -298,7 +298,7 @@ NTSTATUS rpccli_lsa_OpenPolicy(struct rpc_pipe_client *cli, NTSTATUS rpccli_lsa_QueryInfoPolicy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, - uint16_t level, + enum lsa_PolicyInfo level, union lsa_PolicyInformation *info) { struct lsa_QueryInfoPolicy r; @@ -341,12 +341,18 @@ NTSTATUS rpccli_lsa_QueryInfoPolicy(struct rpc_pipe_client *cli, } NTSTATUS rpccli_lsa_SetInfoPolicy(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + enum lsa_PolicyInfo level, + union lsa_PolicyInformation *info) { struct lsa_SetInfoPolicy r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.level = level; + r.in.info = info; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(lsa_SetInfoPolicy, &r); @@ -1988,7 +1994,7 @@ NTSTATUS rpccli_lsa_GetUserName(struct rpc_pipe_client *cli, NTSTATUS rpccli_lsa_QueryInfoPolicy2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, - uint16_t level, + enum lsa_PolicyInfo level, union lsa_PolicyInformation *info) { struct lsa_QueryInfoPolicy2 r; @@ -2031,12 +2037,18 @@ NTSTATUS rpccli_lsa_QueryInfoPolicy2(struct rpc_pipe_client *cli, } NTSTATUS rpccli_lsa_SetInfoPolicy2(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx) + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + enum lsa_PolicyInfo level, + union lsa_PolicyInformation *info) { struct lsa_SetInfoPolicy2 r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.level = level; + r.in.info = info; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(lsa_SetInfoPolicy2, &r); diff --git a/source3/librpc/gen_ndr/cli_lsa.h b/source3/librpc/gen_ndr/cli_lsa.h index ad5e60d5916..4ab8be99396 100644 --- a/source3/librpc/gen_ndr/cli_lsa.h +++ b/source3/librpc/gen_ndr/cli_lsa.h @@ -31,10 +31,13 @@ NTSTATUS rpccli_lsa_OpenPolicy(struct rpc_pipe_client *cli, NTSTATUS rpccli_lsa_QueryInfoPolicy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, - uint16_t level, + enum lsa_PolicyInfo level, union lsa_PolicyInformation *info); NTSTATUS rpccli_lsa_SetInfoPolicy(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + enum lsa_PolicyInfo level, + union lsa_PolicyInformation *info); NTSTATUS rpccli_lsa_ClearAuditLog(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx); NTSTATUS rpccli_lsa_CreateAccount(struct rpc_pipe_client *cli, @@ -212,10 +215,13 @@ NTSTATUS rpccli_lsa_GetUserName(struct rpc_pipe_client *cli, NTSTATUS rpccli_lsa_QueryInfoPolicy2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, - uint16_t level, + enum lsa_PolicyInfo level, union lsa_PolicyInformation *info); NTSTATUS rpccli_lsa_SetInfoPolicy2(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx); + TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + enum lsa_PolicyInfo level, + union lsa_PolicyInformation *info); NTSTATUS rpccli_lsa_QueryTrustedDomainInfoByName(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, diff --git a/source3/librpc/gen_ndr/dfs.h b/source3/librpc/gen_ndr/dfs.h index 58eb34f0dea..89f243b7dd4 100644 --- a/source3/librpc/gen_ndr/dfs.h +++ b/source3/librpc/gen_ndr/dfs.h @@ -6,14 +6,15 @@ #define _HEADER_netdfs #define DFS_STORAGE_STATES ( 0xf ) +enum dfs_ManagerVersion #ifndef USE_UINT_ENUMS -enum dfs_ManagerVersion { + { DFS_MANAGER_VERSION_NT4=1, DFS_MANAGER_VERSION_W2K=2, DFS_MANAGER_VERSION_W2K3=4 } #else -enum dfs_ManagerVersion { __donnot_use_enum_dfs_ManagerVersion=0x7FFFFFFF} + { __donnot_use_enum_dfs_ManagerVersion=0x7FFFFFFF} #define DFS_MANAGER_VERSION_NT4 ( 1 ) #define DFS_MANAGER_VERSION_W2K ( 2 ) #define DFS_MANAGER_VERSION_W2K3 ( 4 ) @@ -96,8 +97,9 @@ struct dfs_Info5 { uint32_t num_stores; }; +enum dfs_Target_PriorityClass #ifndef USE_UINT_ENUMS -enum dfs_Target_PriorityClass { + { DFS_INVALID_PRIORITY_CLASS=-1, DFS_SITE_COST_NORMAL_PRIORITY_CLASS=0, DFS_GLOBAL_HIGH_PRIORITY_CLASS=1, @@ -106,7 +108,7 @@ enum dfs_Target_PriorityClass { DFS_GLOBAL_LOW_PRIORITY_CLASS=4 } #else -enum dfs_Target_PriorityClass { __donnot_use_enum_dfs_Target_PriorityClass=0x7FFFFFFF} + { __donnot_use_enum_dfs_Target_PriorityClass=0x7FFFFFFF} #define DFS_INVALID_PRIORITY_CLASS ( -1 ) #define DFS_SITE_COST_NORMAL_PRIORITY_CLASS ( 0 ) #define DFS_GLOBAL_HIGH_PRIORITY_CLASS ( 1 ) @@ -180,13 +182,14 @@ struct dfs_Info200 { const char *dom_root;/* [unique,charset(UTF16)] */ }; +enum dfs_VolumeFlavor #ifndef USE_UINT_ENUMS -enum dfs_VolumeFlavor { + { DFS_VOLUME_FLAVOR_STANDALONE=0x100, DFS_VOLUME_FLAVOR_AD_BLOB=0x200 } #else -enum dfs_VolumeFlavor { __donnot_use_enum_dfs_VolumeFlavor=0x7FFFFFFF} + { __donnot_use_enum_dfs_VolumeFlavor=0x7FFFFFFF} #define DFS_VOLUME_FLAVOR_STANDALONE ( 0x100 ) #define DFS_VOLUME_FLAVOR_AD_BLOB ( 0x200 ) #endif diff --git a/source3/librpc/gen_ndr/echo.h b/source3/librpc/gen_ndr/echo.h index 4b03578cdc1..c8b5b864224 100644 --- a/source3/librpc/gen_ndr/echo.h +++ b/source3/librpc/gen_ndr/echo.h @@ -46,25 +46,27 @@ union echo_Info { struct echo_info7 info7;/* [case(7)] */ }/* [switch_type(uint16)] */; +enum echo_Enum1 #ifndef USE_UINT_ENUMS -enum echo_Enum1 { + { ECHO_ENUM1=1, ECHO_ENUM2=2 } #else -enum echo_Enum1 { __donnot_use_enum_echo_Enum1=0x7FFFFFFF} + { __donnot_use_enum_echo_Enum1=0x7FFFFFFF} #define ECHO_ENUM1 ( 1 ) #define ECHO_ENUM2 ( 2 ) #endif ; +enum echo_Enum1_32 #ifndef USE_UINT_ENUMS -enum echo_Enum1_32 { + { ECHO_ENUM1_32=1, ECHO_ENUM2_32=2 } #else -enum echo_Enum1_32 { __donnot_use_enum_echo_Enum1_32=0x7FFFFFFF} + { __donnot_use_enum_echo_Enum1_32=0x7FFFFFFF} #define ECHO_ENUM1_32 ( 1 ) #define ECHO_ENUM2_32 ( 2 ) #endif diff --git a/source3/librpc/gen_ndr/epmapper.h b/source3/librpc/gen_ndr/epmapper.h index 0fb5ed048e5..d39269b32b2 100644 --- a/source3/librpc/gen_ndr/epmapper.h +++ b/source3/librpc/gen_ndr/epmapper.h @@ -8,8 +8,9 @@ #define EPMAPPER_STATUS_NO_MORE_ENTRIES ( 0x16c9a0d6 ) #define EPMAPPER_STATUS_NO_MEMORY ( 0x16C9A012 ) #define EPMAPPER_STATUS_OK ( 0 ) +enum epm_protocol #ifndef USE_UINT_ENUMS -enum epm_protocol { + { EPM_PROTOCOL_DNET_NSP=0x04, EPM_PROTOCOL_OSI_TP4=0x05, EPM_PROTOCOL_OSI_CLNS=0x06, @@ -38,7 +39,7 @@ enum epm_protocol { EPM_PROTOCOL_NULL=0x21 } #else -enum epm_protocol { __donnot_use_enum_epm_protocol=0x7FFFFFFF} + { __donnot_use_enum_epm_protocol=0x7FFFFFFF} #define EPM_PROTOCOL_DNET_NSP ( 0x04 ) #define EPM_PROTOCOL_OSI_TP4 ( 0x05 ) #define EPM_PROTOCOL_OSI_CLNS ( 0x06 ) diff --git a/source3/librpc/gen_ndr/lsa.h b/source3/librpc/gen_ndr/lsa.h index e356b9fc78d..513d17b5df4 100644 --- a/source3/librpc/gen_ndr/lsa.h +++ b/source3/librpc/gen_ndr/lsa.h @@ -9,6 +9,8 @@ #define LSA_ENUM_TRUST_DOMAIN_MULTIPLIER ( 60 ) #define LSA_REF_DOMAIN_LIST_MULTIPLIER ( 32 ) #define LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER ( 82 ) +; + struct lsa_String { uint16_t length;/* [value(2*strlen_m(string))] */ uint16_t size;/* [value(2*strlen_m(string))] */ @@ -130,8 +132,9 @@ struct lsa_DnsDomainInfo { struct dom_sid2 *sid;/* [unique] */ }; +enum lsa_PolicyInfo #ifndef USE_UINT_ENUMS -enum lsaPolicyInfo { + { LSA_POLICY_INFO_AUDIT_LOG=1, LSA_POLICY_INFO_AUDIT_EVENTS=2, LSA_POLICY_INFO_DOMAIN=3, @@ -146,7 +149,7 @@ enum lsaPolicyInfo { LSA_POLICY_INFO_DNS=12 } #else -enum lsaPolicyInfo { __donnot_use_enum_lsaPolicyInfo=0x7FFFFFFF} + { __donnot_use_enum_lsa_PolicyInfo=0x7FFFFFFF} #define LSA_POLICY_INFO_AUDIT_LOG ( 1 ) #define LSA_POLICY_INFO_AUDIT_EVENTS ( 2 ) #define LSA_POLICY_INFO_DOMAIN ( 3 ) @@ -191,8 +194,9 @@ struct lsa_DomainList { struct lsa_DomainInfo *domains;/* [unique,size_is(count)] */ }; +enum lsa_SidType #ifndef USE_UINT_ENUMS -enum lsa_SidType { + { SID_NAME_USE_NONE=0, SID_NAME_USER=1, SID_NAME_DOM_GRP=2, @@ -205,7 +209,7 @@ enum lsa_SidType { SID_NAME_COMPUTER=9 } #else -enum lsa_SidType { __donnot_use_enum_lsa_SidType=0x7FFFFFFF} + { __donnot_use_enum_lsa_SidType=0x7FFFFFFF} #define SID_NAME_USE_NONE ( 0 ) #define SID_NAME_USER ( 1 ) #define SID_NAME_DOM_GRP ( 2 ) @@ -269,8 +273,9 @@ struct lsa_DATA_BUF2 { uint8_t *data;/* [unique,size_is(size)] */ }/* [flag(LIBNDR_PRINT_ARRAY_HEX)] */; +enum lsa_TrustDomInfoEnum #ifndef USE_UINT_ENUMS -enum lsa_TrustDomInfoEnum { + { LSA_TRUSTED_DOMAIN_INFO_NAME=1, LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO=2, LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET=3, @@ -283,7 +288,7 @@ enum lsa_TrustDomInfoEnum { LSA_TRUSTED_DOMAIN_INFO_INFO_ALL=12 } #else -enum lsa_TrustDomInfoEnum { __donnot_use_enum_lsa_TrustDomInfoEnum=0x7FFFFFFF} + { __donnot_use_enum_lsa_TrustDomInfoEnum=0x7FFFFFFF} #define LSA_TRUSTED_DOMAIN_INFO_NAME ( 1 ) #define LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO ( 2 ) #define LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET ( 3 ) @@ -405,13 +410,14 @@ struct lsa_DomainInfoEfs { uint8_t *efs_blob;/* [unique,size_is(blob_size)] */ }; +enum lsa_DomainInfoEnum #ifndef USE_UINT_ENUMS -enum lsa_DomainInfoEnum { + { LSA_DOMAIN_INFO_POLICY_EFS=2, LSA_DOMAIN_INFO_POLICY_KERBEROS=3 } #else -enum lsa_DomainInfoEnum { __donnot_use_enum_lsa_DomainInfoEnum=0x7FFFFFFF} + { __donnot_use_enum_lsa_DomainInfoEnum=0x7FFFFFFF} #define LSA_DOMAIN_INFO_POLICY_EFS ( 2 ) #define LSA_DOMAIN_INFO_POLICY_KERBEROS ( 3 ) #endif @@ -548,7 +554,7 @@ struct lsa_OpenPolicy { struct lsa_QueryInfoPolicy { struct { struct policy_handle *handle;/* [ref] */ - uint16_t level; + enum lsa_PolicyInfo level; } in; struct { @@ -561,6 +567,12 @@ struct lsa_QueryInfoPolicy { struct lsa_SetInfoPolicy { struct { + struct policy_handle *handle;/* [ref] */ + enum lsa_PolicyInfo level; + union lsa_PolicyInformation *info;/* [ref,switch_is(level)] */ + } in; + + struct { NTSTATUS result; } out; @@ -1060,7 +1072,7 @@ struct lsa_GetUserName { struct lsa_QueryInfoPolicy2 { struct { struct policy_handle *handle;/* [ref] */ - uint16_t level; + enum lsa_PolicyInfo level; } in; struct { @@ -1073,6 +1085,12 @@ struct lsa_QueryInfoPolicy2 { struct lsa_SetInfoPolicy2 { struct { + struct policy_handle *handle;/* [ref] */ + enum lsa_PolicyInfo level; + union lsa_PolicyInformation *info;/* [ref,switch_is(level)] */ + } in; + + struct { NTSTATUS result; } out; diff --git a/source3/librpc/gen_ndr/ndr_lsa.c b/source3/librpc/gen_ndr/ndr_lsa.c index ec22c9be381..eed2a8e0e32 100644 --- a/source3/librpc/gen_ndr/ndr_lsa.c +++ b/source3/librpc/gen_ndr/ndr_lsa.c @@ -1147,6 +1147,41 @@ _PUBLIC_ void ndr_print_lsa_DnsDomainInfo(struct ndr_print *ndr, const char *nam ndr->depth--; } +static enum ndr_err_code ndr_push_lsa_PolicyInfo(struct ndr_push *ndr, int ndr_flags, enum lsa_PolicyInfo r) +{ + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_lsa_PolicyInfo(struct ndr_pull *ndr, int ndr_flags, enum lsa_PolicyInfo *r) +{ + uint16_t v; + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_lsa_PolicyInfo(struct ndr_print *ndr, const char *name, enum lsa_PolicyInfo r) +{ + const char *val = NULL; + + switch (r) { + case LSA_POLICY_INFO_AUDIT_LOG: val = "LSA_POLICY_INFO_AUDIT_LOG"; break; + case LSA_POLICY_INFO_AUDIT_EVENTS: val = "LSA_POLICY_INFO_AUDIT_EVENTS"; break; + case LSA_POLICY_INFO_DOMAIN: val = "LSA_POLICY_INFO_DOMAIN"; break; + case LSA_POLICY_INFO_PD: val = "LSA_POLICY_INFO_PD"; break; + case LSA_POLICY_INFO_ACCOUNT_DOMAIN: val = "LSA_POLICY_INFO_ACCOUNT_DOMAIN"; break; + case LSA_POLICY_INFO_ROLE: val = "LSA_POLICY_INFO_ROLE"; break; + case LSA_POLICY_INFO_REPLICA: val = "LSA_POLICY_INFO_REPLICA"; break; + case LSA_POLICY_INFO_QUOTA: val = "LSA_POLICY_INFO_QUOTA"; break; + case LSA_POLICY_INFO_DB: val = "LSA_POLICY_INFO_DB"; break; + case LSA_POLICY_INFO_AUDIT_FULL_SET: val = "LSA_POLICY_INFO_AUDIT_FULL_SET"; break; + case LSA_POLICY_INFO_AUDIT_FULL_QUERY: val = "LSA_POLICY_INFO_AUDIT_FULL_QUERY"; break; + case LSA_POLICY_INFO_DNS: val = "LSA_POLICY_INFO_DNS"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + static enum ndr_err_code ndr_push_lsa_PolicyInformation(struct ndr_push *ndr, int ndr_flags, const union lsa_PolicyInformation *r) { if (ndr_flags & NDR_SCALARS) { @@ -4517,7 +4552,7 @@ static enum ndr_err_code ndr_push_lsa_QueryInfoPolicy(struct ndr_push *ndr, int return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.level)); + NDR_CHECK(ndr_push_lsa_PolicyInfo(ndr, NDR_SCALARS, r->in.level)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.info)); @@ -4545,7 +4580,7 @@ static enum ndr_err_code ndr_pull_lsa_QueryInfoPolicy(struct ndr_pull *ndr, int NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.level)); + NDR_CHECK(ndr_pull_lsa_PolicyInfo(ndr, NDR_SCALARS, &r->in.level)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); @@ -4580,7 +4615,7 @@ _PUBLIC_ void ndr_print_lsa_QueryInfoPolicy(struct ndr_print *ndr, const char *n ndr->depth++; ndr_print_policy_handle(ndr, "handle", r->in.handle); ndr->depth--; - ndr_print_uint16(ndr, "level", r->in.level); + ndr_print_lsa_PolicyInfo(ndr, "level", r->in.level); ndr->depth--; } if (flags & NDR_OUT) { @@ -4602,6 +4637,16 @@ _PUBLIC_ void ndr_print_lsa_QueryInfoPolicy(struct ndr_print *ndr, const char *n static enum ndr_err_code ndr_push_lsa_SetInfoPolicy(struct ndr_push *ndr, int flags, const struct lsa_SetInfoPolicy *r) { if (flags & NDR_IN) { + if (r->in.handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); + NDR_CHECK(ndr_push_lsa_PolicyInfo(ndr, NDR_SCALARS, r->in.level)); + if (r->in.info == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_set_switch_value(ndr, r->in.info, r->in.level)); + NDR_CHECK(ndr_push_lsa_PolicyInformation(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.info)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); @@ -4611,7 +4656,25 @@ static enum ndr_err_code ndr_push_lsa_SetInfoPolicy(struct ndr_push *ndr, int fl static enum ndr_err_code ndr_pull_lsa_SetInfoPolicy(struct ndr_pull *ndr, int flags, struct lsa_SetInfoPolicy *r) { + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_info_0; if (flags & NDR_IN) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.handle); + } + _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_PolicyInfo(ndr, NDR_SCALARS, &r->in.level)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.info); + } + _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.info, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_set_switch_value(ndr, r->in.info, r->in.level)); + NDR_CHECK(ndr_pull_lsa_PolicyInformation(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.info)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, LIBNDR_FLAG_REF_ALLOC); } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); @@ -4629,6 +4692,16 @@ _PUBLIC_ void ndr_print_lsa_SetInfoPolicy(struct ndr_print *ndr, const char *nam if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "lsa_SetInfoPolicy"); ndr->depth++; + ndr_print_ptr(ndr, "handle", r->in.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->in.handle); + ndr->depth--; + ndr_print_lsa_PolicyInfo(ndr, "level", r->in.level); + ndr_print_ptr(ndr, "info", r->in.info); + ndr->depth++; + ndr_print_set_switch_value(ndr, r->in.info, r->in.level); + ndr_print_lsa_PolicyInformation(ndr, "info", r->in.info); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { @@ -8039,7 +8112,7 @@ static enum ndr_err_code ndr_push_lsa_QueryInfoPolicy2(struct ndr_push *ndr, int return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.level)); + NDR_CHECK(ndr_push_lsa_PolicyInfo(ndr, NDR_SCALARS, r->in.level)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.info)); @@ -8067,7 +8140,7 @@ static enum ndr_err_code ndr_pull_lsa_QueryInfoPolicy2(struct ndr_pull *ndr, int NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.level)); + NDR_CHECK(ndr_pull_lsa_PolicyInfo(ndr, NDR_SCALARS, &r->in.level)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); @@ -8102,7 +8175,7 @@ _PUBLIC_ void ndr_print_lsa_QueryInfoPolicy2(struct ndr_print *ndr, const char * ndr->depth++; ndr_print_policy_handle(ndr, "handle", r->in.handle); ndr->depth--; - ndr_print_uint16(ndr, "level", r->in.level); + ndr_print_lsa_PolicyInfo(ndr, "level", r->in.level); ndr->depth--; } if (flags & NDR_OUT) { @@ -8124,6 +8197,16 @@ _PUBLIC_ void ndr_print_lsa_QueryInfoPolicy2(struct ndr_print *ndr, const char * static enum ndr_err_code ndr_push_lsa_SetInfoPolicy2(struct ndr_push *ndr, int flags, const struct lsa_SetInfoPolicy2 *r) { if (flags & NDR_IN) { + if (r->in.handle == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); + NDR_CHECK(ndr_push_lsa_PolicyInfo(ndr, NDR_SCALARS, r->in.level)); + if (r->in.info == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_set_switch_value(ndr, r->in.info, r->in.level)); + NDR_CHECK(ndr_push_lsa_PolicyInformation(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.info)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); @@ -8133,7 +8216,25 @@ static enum ndr_err_code ndr_push_lsa_SetInfoPolicy2(struct ndr_push *ndr, int f static enum ndr_err_code ndr_pull_lsa_SetInfoPolicy2(struct ndr_pull *ndr, int flags, struct lsa_SetInfoPolicy2 *r) { + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_info_0; if (flags & NDR_IN) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.handle); + } + _mem_save_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.handle, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_lsa_PolicyInfo(ndr, NDR_SCALARS, &r->in.level)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.info); + } + _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.info, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_set_switch_value(ndr, r->in.info, r->in.level)); + NDR_CHECK(ndr_pull_lsa_PolicyInformation(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.info)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, LIBNDR_FLAG_REF_ALLOC); } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); @@ -8151,6 +8252,16 @@ _PUBLIC_ void ndr_print_lsa_SetInfoPolicy2(struct ndr_print *ndr, const char *na if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "lsa_SetInfoPolicy2"); ndr->depth++; + ndr_print_ptr(ndr, "handle", r->in.handle); + ndr->depth++; + ndr_print_policy_handle(ndr, "handle", r->in.handle); + ndr->depth--; + ndr_print_lsa_PolicyInfo(ndr, "level", r->in.level); + ndr_print_ptr(ndr, "info", r->in.info); + ndr->depth++; + ndr_print_set_switch_value(ndr, r->in.info, r->in.level); + ndr_print_lsa_PolicyInformation(ndr, "info", r->in.info); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { diff --git a/source3/librpc/gen_ndr/ndr_lsa.h b/source3/librpc/gen_ndr/ndr_lsa.h index e6630d12dfa..dc100297f5e 100644 --- a/source3/librpc/gen_ndr/ndr_lsa.h +++ b/source3/librpc/gen_ndr/ndr_lsa.h @@ -204,6 +204,7 @@ void ndr_print_lsa_ModificationInfo(struct ndr_print *ndr, const char *name, con void ndr_print_lsa_AuditFullSetInfo(struct ndr_print *ndr, const char *name, const struct lsa_AuditFullSetInfo *r); void ndr_print_lsa_AuditFullQueryInfo(struct ndr_print *ndr, const char *name, const struct lsa_AuditFullQueryInfo *r); void ndr_print_lsa_DnsDomainInfo(struct ndr_print *ndr, const char *name, const struct lsa_DnsDomainInfo *r); +void ndr_print_lsa_PolicyInfo(struct ndr_print *ndr, const char *name, enum lsa_PolicyInfo r); void ndr_print_lsa_PolicyInformation(struct ndr_print *ndr, const char *name, const union lsa_PolicyInformation *r); void ndr_print_lsa_SidPtr(struct ndr_print *ndr, const char *name, const struct lsa_SidPtr *r); enum ndr_err_code ndr_push_lsa_SidArray(struct ndr_push *ndr, int ndr_flags, const struct lsa_SidArray *r); diff --git a/source3/librpc/gen_ndr/ndr_svcctl.c b/source3/librpc/gen_ndr/ndr_svcctl.c index 7da684db87c..b8d5dc186d6 100644 --- a/source3/librpc/gen_ndr/ndr_svcctl.c +++ b/source3/librpc/gen_ndr/ndr_svcctl.c @@ -197,14 +197,14 @@ static enum ndr_err_code ndr_pull_ENUM_SERVICE_STATUS(struct ndr_pull *ndr, int uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); if (r->service_name) { - struct ndr_pull_save _relative_save; - ndr_pull_save(ndr, &_relative_save); + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->service_name)); _mem_save_service_name_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->service_name, 0); NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->service_name)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_service_name_0, 0); - ndr_pull_restore(ndr, &_relative_save); + ndr->offset = _relative_save_offset; } ndr->flags = _flags_save_string; } @@ -212,14 +212,14 @@ static enum ndr_err_code ndr_pull_ENUM_SERVICE_STATUS(struct ndr_pull *ndr, int uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); if (r->display_name) { - struct ndr_pull_save _relative_save; - ndr_pull_save(ndr, &_relative_save); + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->display_name)); _mem_save_display_name_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->display_name, 0); NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->display_name)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_display_name_0, 0); - ndr_pull_restore(ndr, &_relative_save); + ndr->offset = _relative_save_offset; } ndr->flags = _flags_save_string; } diff --git a/source3/librpc/gen_ndr/ndr_wkssvc.c b/source3/librpc/gen_ndr/ndr_wkssvc.c index 3599fef352f..c3a1f706cd4 100644 --- a/source3/librpc/gen_ndr/ndr_wkssvc.c +++ b/source3/librpc/gen_ndr/ndr_wkssvc.c @@ -8606,6 +8606,7 @@ static enum ndr_err_code ndr_pull_wkssvc_NetrGetJoinableOus(struct ndr_pull *ndr TALLOC_CTX *_mem_save_unknown_0; TALLOC_CTX *_mem_save_num_ous_0; TALLOC_CTX *_mem_save_ous_1; + TALLOC_CTX *_mem_save_ous_2; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -9487,6 +9488,7 @@ static enum ndr_err_code ndr_pull_wkssvc_NetrGetJoinableOus2(struct ndr_pull *nd TALLOC_CTX *_mem_save_EncryptedPassword_0; TALLOC_CTX *_mem_save_num_ous_0; TALLOC_CTX *_mem_save_ous_1; + TALLOC_CTX *_mem_save_ous_2; if (flags & NDR_IN) { ZERO_STRUCT(r->out); diff --git a/source3/librpc/gen_ndr/ndr_xattr.c b/source3/librpc/gen_ndr/ndr_xattr.c new file mode 100644 index 00000000000..29a31a12b2c --- /dev/null +++ b/source3/librpc/gen_ndr/ndr_xattr.c @@ -0,0 +1,102 @@ +/* parser auto-generated by pidl */ + +#include "includes.h" +#include "librpc/gen_ndr/ndr_xattr.h" + +_PUBLIC_ enum ndr_err_code ndr_push_tdb_xattr(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattr *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->value)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_tdb_xattr(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattr *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->name)); + ndr->flags = _flags_save_string; + } + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->value)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_tdb_xattr(struct ndr_print *ndr, const char *name, const struct tdb_xattr *r) +{ + ndr_print_struct(ndr, name, "tdb_xattr"); + ndr->depth++; + ndr_print_string(ndr, "name", r->name); + ndr_print_DATA_BLOB(ndr, "value", r->value); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_tdb_xattrs(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattrs *r) +{ + uint32_t cntr_xattrs_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_xattrs)); + for (cntr_xattrs_0 = 0; cntr_xattrs_0 < r->num_xattrs; cntr_xattrs_0++) { + NDR_CHECK(ndr_push_tdb_xattr(ndr, NDR_SCALARS, &r->xattrs[cntr_xattrs_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_tdb_xattrs(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattrs *r) +{ + uint32_t cntr_xattrs_0; + TALLOC_CTX *_mem_save_xattrs_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_xattrs)); + NDR_PULL_ALLOC_N(ndr, r->xattrs, r->num_xattrs); + _mem_save_xattrs_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->xattrs, 0); + for (cntr_xattrs_0 = 0; cntr_xattrs_0 < r->num_xattrs; cntr_xattrs_0++) { + NDR_CHECK(ndr_pull_tdb_xattr(ndr, NDR_SCALARS, &r->xattrs[cntr_xattrs_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_xattrs_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_tdb_xattrs(struct ndr_print *ndr, const char *name, const struct tdb_xattrs *r) +{ + uint32_t cntr_xattrs_0; + ndr_print_struct(ndr, name, "tdb_xattrs"); + ndr->depth++; + ndr_print_uint32(ndr, "num_xattrs", r->num_xattrs); + ndr->print(ndr, "%s: ARRAY(%d)", "xattrs", r->num_xattrs); + ndr->depth++; + for (cntr_xattrs_0=0;cntr_xattrs_0<r->num_xattrs;cntr_xattrs_0++) { + char *idx_0=NULL; + asprintf(&idx_0, "[%d]", cntr_xattrs_0); + if (idx_0) { + ndr_print_tdb_xattr(ndr, "xattrs", &r->xattrs[cntr_xattrs_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} diff --git a/source3/librpc/gen_ndr/ndr_xattr.h b/source3/librpc/gen_ndr/ndr_xattr.h new file mode 100644 index 00000000000..a18477f3477 --- /dev/null +++ b/source3/librpc/gen_ndr/ndr_xattr.h @@ -0,0 +1,16 @@ +/* header auto-generated by pidl */ + +#include "librpc/ndr/libndr.h" +#include "librpc/gen_ndr/xattr.h" + +#ifndef _HEADER_NDR_xattr +#define _HEADER_NDR_xattr + +#define NDR_XATTR_CALL_COUNT (0) +enum ndr_err_code ndr_push_tdb_xattr(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattr *r); +enum ndr_err_code ndr_pull_tdb_xattr(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattr *r); +void ndr_print_tdb_xattr(struct ndr_print *ndr, const char *name, const struct tdb_xattr *r); +enum ndr_err_code ndr_push_tdb_xattrs(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattrs *r); +enum ndr_err_code ndr_pull_tdb_xattrs(struct ndr_pull *ndr, int ndr_flags, struct tdb_xattrs *r); +void ndr_print_tdb_xattrs(struct ndr_print *ndr, const char *name, const struct tdb_xattrs *r); +#endif /* _HEADER_NDR_xattr */ diff --git a/source3/librpc/gen_ndr/netlogon.h b/source3/librpc/gen_ndr/netlogon.h index 246748e89af..e33818257d4 100644 --- a/source3/librpc/gen_ndr/netlogon.h +++ b/source3/librpc/gen_ndr/netlogon.h @@ -14,6 +14,8 @@ #define NETLOGON_NEG_ARCFOUR ( 0x00000004 ) #define NETLOGON_NEG_128BIT ( 0x00004000 ) #define NETLOGON_NEG_SCHANNEL ( 0x40000000 ) +; + struct netr_UasInfo { const char *account_name;/* [unique,charset(UTF16)] */ uint32_t priv; @@ -188,6 +190,10 @@ struct netr_Authenticator { time_t timestamp; }/* [public] */; +enum netr_SchannelType; + +enum netr_SamDatabaseID; + struct netr_DELTA_DELETE_USER { const char *account_name;/* [unique,charset(UTF16)] */ struct lsa_String unknown1; @@ -466,8 +472,9 @@ struct netr_DELTA_SECRET { uint32_t unknown8; }; +enum netr_DeltaEnum #ifndef USE_UINT_ENUMS -enum netr_DeltaEnum { + { NETR_DELTA_DOMAIN=1, NETR_DELTA_GROUP=2, NETR_DELTA_DELETE_GROUP=3, @@ -492,7 +499,7 @@ enum netr_DeltaEnum { NETR_DELTA_MODIFY_COUNT=22 } #else -enum netr_DeltaEnum { __donnot_use_enum_netr_DeltaEnum=0x7FFFFFFF} + { __donnot_use_enum_netr_DeltaEnum=0x7FFFFFFF} #define NETR_DELTA_DOMAIN ( 1 ) #define NETR_DELTA_GROUP ( 2 ) #define NETR_DELTA_DELETE_GROUP ( 3 ) @@ -595,15 +602,16 @@ union netr_CONTROL_QUERY_INFORMATION { struct netr_NETLOGON_INFO_3 *info3;/* [unique,case(3)] */ }; +enum netr_LogonControlCode #ifndef USE_UINT_ENUMS -enum netr_LogonControlCode { + { NETLOGON_CONTROL_REDISCOVER=5, NETLOGON_CONTROL_TC_QUERY=6, NETLOGON_CONTROL_TRANSPORT_NOTIFY=7, NETLOGON_CONTROL_SET_DBFLAG=65534 } #else -enum netr_LogonControlCode { __donnot_use_enum_netr_LogonControlCode=0x7FFFFFFF} + { __donnot_use_enum_netr_LogonControlCode=0x7FFFFFFF} #define NETLOGON_CONTROL_REDISCOVER ( 5 ) #define NETLOGON_CONTROL_TC_QUERY ( 6 ) #define NETLOGON_CONTROL_TRANSPORT_NOTIFY ( 7 ) @@ -694,15 +702,16 @@ struct netr_CryptPassword { ; +enum netr_TrustType #ifndef USE_UINT_ENUMS -enum netr_TrustType { + { NETR_TRUST_TYPE_DOWNLEVEL=1, NETR_TRUST_TYPE_UPLEVEL=2, NETR_TRUST_TYPE_MIT=3, NETR_TRUST_TYPE_DCE=4 } #else -enum netr_TrustType { __donnot_use_enum_netr_TrustType=0x7FFFFFFF} + { __donnot_use_enum_netr_TrustType=0x7FFFFFFF} #define NETR_TRUST_TYPE_DOWNLEVEL ( 1 ) #define NETR_TRUST_TYPE_UPLEVEL ( 2 ) #define NETR_TRUST_TYPE_MIT ( 3 ) diff --git a/source3/librpc/gen_ndr/srvsvc.h b/source3/librpc/gen_ndr/srvsvc.h index da9715072dc..bc167bb31c9 100644 --- a/source3/librpc/gen_ndr/srvsvc.h +++ b/source3/librpc/gen_ndr/srvsvc.h @@ -11,6 +11,10 @@ #define STYPE_HIDDEN ( 0x80000000 ) #define SHARE_1005_CSC_POLICY_MASK ( 0x00000030 ) #define SHARE_1005_CSC_POLICY_SHIFT ( 4 ) +; + +; + struct srvsvc_NetCharDevInfo0 { const char *device;/* [unique,charset(UTF16)] */ }; @@ -209,8 +213,9 @@ union srvsvc_NetSessCtr { struct srvsvc_NetSessCtr502 *ctr502;/* [unique,case(502)] */ }; +enum srvsvc_ShareType #ifndef USE_UINT_ENUMS -enum srvsvc_ShareType { + { STYPE_DISKTREE=0, STYPE_DISKTREE_TEMPORARY=STYPE_DISKTREE|STYPE_TEMPORARY, STYPE_DISKTREE_HIDDEN=STYPE_DISKTREE|STYPE_HIDDEN, @@ -225,7 +230,7 @@ enum srvsvc_ShareType { STYPE_IPC_HIDDEN=STYPE_IPC|STYPE_HIDDEN } #else -enum srvsvc_ShareType { __donnot_use_enum_srvsvc_ShareType=0x7FFFFFFF} + { __donnot_use_enum_srvsvc_ShareType=0x7FFFFFFF} #define STYPE_DISKTREE ( 0 ) #define STYPE_DISKTREE_TEMPORARY ( STYPE_DISKTREE|STYPE_TEMPORARY ) #define STYPE_DISKTREE_HIDDEN ( STYPE_DISKTREE|STYPE_HIDDEN ) @@ -381,8 +386,9 @@ union srvsvc_NetShareCtr { struct srvsvc_NetShareCtr1501 *ctr1501;/* [unique,case(1501)] */ }; +enum srvsvc_PlatformId #ifndef USE_UINT_ENUMS -enum srvsvc_PlatformId { + { PLATFORM_ID_DOS=300, PLATFORM_ID_OS2=400, PLATFORM_ID_NT=500, @@ -390,7 +396,7 @@ enum srvsvc_PlatformId { PLATFORM_ID_VMS=700 } #else -enum srvsvc_PlatformId { __donnot_use_enum_srvsvc_PlatformId=0x7FFFFFFF} + { __donnot_use_enum_srvsvc_PlatformId=0x7FFFFFFF} #define PLATFORM_ID_DOS ( 300 ) #define PLATFORM_ID_OS2 ( 400 ) #define PLATFORM_ID_NT ( 500 ) diff --git a/source3/librpc/gen_ndr/svcctl.h b/source3/librpc/gen_ndr/svcctl.h index e728d51f231..f0e476c105d 100644 --- a/source3/librpc/gen_ndr/svcctl.h +++ b/source3/librpc/gen_ndr/svcctl.h @@ -70,12 +70,13 @@ struct ENUM_SERVICE_STATUS { ; +enum SERVICE_CONTROL #ifndef USE_UINT_ENUMS -enum SERVICE_CONTROL { + { FIXME=1 } #else -enum SERVICE_CONTROL { __donnot_use_enum_SERVICE_CONTROL=0x7FFFFFFF} + { __donnot_use_enum_SERVICE_CONTROL=0x7FFFFFFF} #define FIXME ( 1 ) #endif ; diff --git a/source3/librpc/gen_ndr/winreg.h b/source3/librpc/gen_ndr/winreg.h index 37a472814af..8c498963b6d 100644 --- a/source3/librpc/gen_ndr/winreg.h +++ b/source3/librpc/gen_ndr/winreg.h @@ -8,6 +8,8 @@ #ifndef _HEADER_winreg #define _HEADER_winreg +; + /* bitmap winreg_AccessMask */ #define KEY_QUERY_VALUE ( 0x00001 ) #define KEY_SET_VALUE ( 0x00002 ) @@ -20,8 +22,9 @@ ; +enum winreg_Type #ifndef USE_UINT_ENUMS -enum winreg_Type { + { REG_NONE=0, REG_SZ=1, REG_EXPAND_SZ=2, @@ -36,7 +39,7 @@ enum winreg_Type { REG_QWORD=11 } #else -enum winreg_Type { __donnot_use_enum_winreg_Type=0x7FFFFFFF} + { __donnot_use_enum_winreg_Type=0x7FFFFFFF} #define REG_NONE ( 0 ) #define REG_SZ ( 1 ) #define REG_EXPAND_SZ ( 2 ) @@ -70,14 +73,15 @@ struct winreg_SecBuf { uint8_t inherit; }; +enum winreg_CreateAction #ifndef USE_UINT_ENUMS -enum winreg_CreateAction { + { REG_ACTION_NONE=0, REG_CREATED_NEW_KEY=1, REG_OPENED_EXISTING_KEY=2 } #else -enum winreg_CreateAction { __donnot_use_enum_winreg_CreateAction=0x7FFFFFFF} + { __donnot_use_enum_winreg_CreateAction=0x7FFFFFFF} #define REG_ACTION_NONE ( 0 ) #define REG_CREATED_NEW_KEY ( 1 ) #define REG_OPENED_EXISTING_KEY ( 2 ) diff --git a/source3/librpc/gen_ndr/wkssvc.h b/source3/librpc/gen_ndr/wkssvc.h index 43f9ae6d635..b4df7c2d8fc 100644 --- a/source3/librpc/gen_ndr/wkssvc.h +++ b/source3/librpc/gen_ndr/wkssvc.h @@ -7,6 +7,8 @@ #ifndef _HEADER_wkssvc #define _HEADER_wkssvc +enum srvsvc_PlatformId; + struct wkssvc_NetWkstaInfo100 { enum srvsvc_PlatformId platform_id; const char *server_name;/* [unique,charset(UTF16)] */ @@ -415,8 +417,9 @@ struct wkssvc_NetrWorkstationStatistics { ; +enum wkssvc_NetValidateNameType #ifndef USE_UINT_ENUMS -enum wkssvc_NetValidateNameType { + { NetSetupUnknown=0, NetSetupMachine=1, NetSetupWorkgroup=2, @@ -425,7 +428,7 @@ enum wkssvc_NetValidateNameType { NetSetupDnsMachine=5 } #else -enum wkssvc_NetValidateNameType { __donnot_use_enum_wkssvc_NetValidateNameType=0x7FFFFFFF} + { __donnot_use_enum_wkssvc_NetValidateNameType=0x7FFFFFFF} #define NetSetupUnknown ( 0 ) #define NetSetupMachine ( 1 ) #define NetSetupWorkgroup ( 2 ) @@ -435,15 +438,16 @@ enum wkssvc_NetValidateNameType { __donnot_use_enum_wkssvc_NetValidateNameType=0 #endif ; +enum wkssvc_NetJoinStatus #ifndef USE_UINT_ENUMS -enum wkssvc_NetJoinStatus { + { NetSetupUnknownStatus=0, NetSetupUnjoined=1, NetSetupWorkgroupName=2, NetSetupDomainName=3 } #else -enum wkssvc_NetJoinStatus { __donnot_use_enum_wkssvc_NetJoinStatus=0x7FFFFFFF} + { __donnot_use_enum_wkssvc_NetJoinStatus=0x7FFFFFFF} #define NetSetupUnknownStatus ( 0 ) #define NetSetupUnjoined ( 1 ) #define NetSetupWorkgroupName ( 2 ) @@ -469,15 +473,16 @@ struct wkssvc_PasswordBuffer { ; +enum wkssvc_ComputerNameType #ifndef USE_UINT_ENUMS -enum wkssvc_ComputerNameType { + { NetPrimaryComputerName=0, NetAlternateComputerNames=1, NetAllComputerNames=2, NetComputerNameTypeMax=3 } #else -enum wkssvc_ComputerNameType { __donnot_use_enum_wkssvc_ComputerNameType=0x7FFFFFFF} + { __donnot_use_enum_wkssvc_ComputerNameType=0x7FFFFFFF} #define NetPrimaryComputerName ( 0 ) #define NetAlternateComputerNames ( 1 ) #define NetAllComputerNames ( 2 ) diff --git a/source3/librpc/gen_ndr/xattr.h b/source3/librpc/gen_ndr/xattr.h new file mode 100644 index 00000000000..ee30376be87 --- /dev/null +++ b/source3/librpc/gen_ndr/xattr.h @@ -0,0 +1,18 @@ +/* header auto-generated by pidl */ + +#include <stdint.h> + +#ifndef _HEADER_xattr +#define _HEADER_xattr + +struct tdb_xattr { + const char * name;/* [flag(LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM)] */ + DATA_BLOB value; +}/* [public] */; + +struct tdb_xattrs { + uint32_t num_xattrs; + struct tdb_xattr *xattrs; +}/* [public] */; + +#endif /* _HEADER_xattr */ diff --git a/source3/librpc/idl/lsa.idl b/source3/librpc/idl/lsa.idl index 556ab21af48..7daf648a63c 100644 --- a/source3/librpc/idl/lsa.idl +++ b/source3/librpc/idl/lsa.idl @@ -13,7 +13,7 @@ import "security.idl"; helpstring("Local Security Authority") ] interface lsarpc { - declare bitmap security_secinfo; + typedef bitmap security_secinfo security_secinfo; typedef [public,noejs] struct { [value(2*strlen_m(string))] uint16 length; @@ -214,7 +214,7 @@ import "security.idl"; LSA_POLICY_INFO_AUDIT_FULL_SET=10, LSA_POLICY_INFO_AUDIT_FULL_QUERY=11, LSA_POLICY_INFO_DNS=12 - } lsaPolicyInfo; + } lsa_PolicyInfo; typedef [switch_type(uint16)] union { [case(LSA_POLICY_INFO_AUDIT_LOG)] lsa_AuditLogInfo audit_log; @@ -233,13 +233,17 @@ import "security.idl"; NTSTATUS lsa_QueryInfoPolicy ( [in] policy_handle *handle, - [in] uint16 level, + [in] lsa_PolicyInfo level, [out,unique,switch_is(level)] lsa_PolicyInformation *info ); /******************/ /* Function: 0x08 */ - NTSTATUS lsa_SetInfoPolicy (); + NTSTATUS lsa_SetInfoPolicy ( + [in] policy_handle *handle, + [in] lsa_PolicyInfo level, + [in,switch_is(level)] lsa_PolicyInformation *info + ); /******************/ /* Function: 0x09 */ @@ -705,12 +709,16 @@ import "security.idl"; NTSTATUS lsa_QueryInfoPolicy2( [in] policy_handle *handle, - [in] uint16 level, + [in] lsa_PolicyInfo level, [out,unique,switch_is(level)] lsa_PolicyInformation *info ); /* Function 0x2f */ - NTSTATUS lsa_SetInfoPolicy2(); + NTSTATUS lsa_SetInfoPolicy2( + [in] policy_handle *handle, + [in] lsa_PolicyInfo level, + [in,switch_is(level)] lsa_PolicyInformation *info + ); /**********************/ /* Function 0x30 */ diff --git a/source3/librpc/idl/netlogon.idl b/source3/librpc/idl/netlogon.idl index 139975fe128..72feb2f9ed5 100644 --- a/source3/librpc/idl/netlogon.idl +++ b/source3/librpc/idl/netlogon.idl @@ -19,7 +19,7 @@ import "lsa.idl", "samr.idl", "security.idl"; interface netlogon { - declare bitmap samr_AcctFlags; + typedef bitmap samr_AcctFlags samr_AcctFlags; /*****************/ /* Function 0x00 */ @@ -279,7 +279,7 @@ interface netlogon /*****************/ /* Function 0x05 */ - declare enum netr_SchannelType; + typedef enum netr_SchannelType netr_SchannelType; NTSTATUS netr_ServerAuthenticate( [in,string,charset(UTF16)] uint16 *server_name, @@ -307,7 +307,7 @@ interface netlogon /*****************/ /* Function 0x07 */ - declare enum netr_SamDatabaseID; + typedef enum netr_SamDatabaseID netr_SamDatabaseID; typedef struct { [string,charset(UTF16)] uint16 *account_name; diff --git a/source3/librpc/idl/samr.idl b/source3/librpc/idl/samr.idl index 74081a7bf3d..afeca3edd61 100644 --- a/source3/librpc/idl/samr.idl +++ b/source3/librpc/idl/samr.idl @@ -16,7 +16,7 @@ depends(misc,lsa,security) ] interface samr { - declare bitmap security_secinfo; + typedef bitmap security_secinfo security_secinfo; /* account control (acct_flags) bits */ typedef [public,bitmap32bit] bitmap { @@ -1158,7 +1158,7 @@ /************************/ /* Function 0x3f */ - declare enum samr_RejectReason; + typedef enum samr_RejectReason samr_RejectReason; typedef struct { samr_RejectReason reason; diff --git a/source3/librpc/idl/srvsvc.idl b/source3/librpc/idl/srvsvc.idl index c054dfdb45f..c66486b29c3 100644 --- a/source3/librpc/idl/srvsvc.idl +++ b/source3/librpc/idl/srvsvc.idl @@ -14,8 +14,8 @@ import "security.idl", "svcctl.idl"; helpstring("Server Service") ] interface srvsvc { - declare bitmap svcctl_ServerType; - declare bitmap security_secinfo; + typedef bitmap svcctl_ServerType svcctl_ServerType; + typedef bitmap security_secinfo security_secinfo; /**************************/ /* srvsvc_NetCharDev */ diff --git a/source3/librpc/idl/winreg.idl b/source3/librpc/idl/winreg.idl index a0d43232680..9f316ab39b5 100644 --- a/source3/librpc/idl/winreg.idl +++ b/source3/librpc/idl/winreg.idl @@ -13,7 +13,7 @@ import "lsa.idl", "initshutdown.idl", "security.idl"; helpstring("Remote Registry Service") ] interface winreg { - declare bitmap security_secinfo; + typedef bitmap security_secinfo security_secinfo; typedef [bitmap32bit] bitmap { KEY_QUERY_VALUE = 0x00001, diff --git a/source3/librpc/idl/wkssvc.idl b/source3/librpc/idl/wkssvc.idl index dfb18e7ea82..9829379eef6 100644 --- a/source3/librpc/idl/wkssvc.idl +++ b/source3/librpc/idl/wkssvc.idl @@ -14,7 +14,7 @@ import "srvsvc.idl", "lsa.idl"; endpoint("ncacn_np:[\\pipe\\wkssvc]","ncacn_ip_tcp:","ncalrpc:") ] interface wkssvc { - declare [v1_enum] enum srvsvc_PlatformId; + typedef [v1_enum] enum srvsvc_PlatformId srvsvc_PlatformId; #define BOOL uint32 diff --git a/source3/librpc/idl/xattr.idl b/source3/librpc/idl/xattr.idl new file mode 100644 index 00000000000..ec230a4efbb --- /dev/null +++ b/source3/librpc/idl/xattr.idl @@ -0,0 +1,23 @@ +#include "idl_types.h" + +/* + IDL structures for xattrs +*/ + +[ + pointer_default(unique) +] +interface xattr +{ + /* xattrs for file systems that don't have any */ + + typedef [public] struct { + utf8string name; + DATA_BLOB value; + } tdb_xattr; + + typedef [public] struct { + uint32 num_xattrs; + tdb_xattr xattrs[num_xattrs]; + } tdb_xattrs; +} diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 0b33e435633..6b39a885f04 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -404,6 +404,9 @@ ssize_t cli_write(struct cli_state *cli, mpx = 1; } + /* Default (small) writesize. */ + writesize = (cli->max_xmit - (smb_size+32)) & ~1023; + if (write_mode == 0 && !client_is_signing_on(cli) && !cli_encryption_on(cli) && @@ -415,11 +418,11 @@ ssize_t cli_write(struct cli_state *cli, } else if (cli->capabilities & CAP_LARGE_WRITEX) { if (cli->is_samba) { writesize = CLI_SAMBA_MAX_LARGE_WRITEX_SIZE; - } else { + } else if (!client_is_signing_on(cli)) { + /* Windows restricts signed writes to max_xmit. + * Found by Volker. */ writesize = CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE; } - } else { - writesize = (cli->max_xmit - (smb_size+32)) & ~1023; } blocks = (size + (writesize-1)) / writesize; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 853fe979b77..ad999b34b4f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1422,14 +1422,13 @@ NTSTATUS resolve_ads(const char *name, resolve_hosts() when looking up DC's via SRV RR entries in DNS **********************************************************************/ -NTSTATUS internal_resolve_name(const char *name, +static NTSTATUS internal_resolve_name(const char *name, int name_type, const char *sitename, struct ip_service **return_iplist, int *return_count, const char *resolve_order) { - const char *name_resolve_list; char *tok; const char *ptr; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -1483,16 +1482,10 @@ NTSTATUS internal_resolve_name(const char *name, return NT_STATUS_INVALID_PARAMETER; } - if (!resolve_order) { - name_resolve_list = lp_name_resolve_order(); - } else { - name_resolve_list = resolve_order; - } - - if (!name_resolve_list[0]) { + if (!resolve_order[0]) { ptr = "host"; } else { - ptr = name_resolve_list; + ptr = resolve_order; } /* iterate through the name resolution backends */ diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 113b994bc72..513bb31d9da 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -836,8 +836,6 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, return NULL; } - TALLOC_FREE(data.dptr); - return lck; } @@ -1281,11 +1279,7 @@ static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok) void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok) { - /* Ensure there's no token. */ - if (lck->delete_token) { - TALLOC_FREE(lck->delete_token); /* Also deletes groups... */ - lck->delete_token = NULL; - } + TALLOC_FREE(lck->delete_token); /* Also deletes groups... */ /* Copy the new token (can be NULL). */ lck->delete_token = copy_unix_token(lck, tok); diff --git a/source3/modules/vfs_ea_tdb.c b/source3/modules/vfs_ea_tdb.c new file mode 100644 index 00000000000..8cf04d79ad9 --- /dev/null +++ b/source3/modules/vfs_ea_tdb.c @@ -0,0 +1,736 @@ +/* + * Store posix-level xattrs in a tdb + * + * Copyright (C) Volker Lendecke, 2007 + * + * 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 "librpc/gen_ndr/xattr.h" +#include "librpc/gen_ndr/ndr_xattr.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + +/* + * unmarshall tdb_xattrs + */ + +static NTSTATUS ea_tdb_pull_attrs(TALLOC_CTX *mem_ctx, + const TDB_DATA *data, + struct tdb_xattrs **presult) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + struct tdb_xattrs *result; + + if (!(result = TALLOC_ZERO_P(mem_ctx, struct tdb_xattrs))) { + return NT_STATUS_NO_MEMORY; + } + + if (data->dsize == 0) { + *presult = result; + return NT_STATUS_OK; + } + + blob = data_blob_const(data->dptr, data->dsize); + + ndr_err = ndr_pull_struct_blob( + &blob, result, result, + (ndr_pull_flags_fn_t)ndr_pull_tdb_xattrs); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("ndr_pull_tdb_xattrs failed: %s\n", + ndr_errstr(ndr_err))); + TALLOC_FREE(result); + return ndr_map_error2ntstatus(ndr_err);; + } + + *presult = result; + return NT_STATUS_OK; +} + +/* + * marshall tdb_xattrs + */ + +static NTSTATUS ea_tdb_push_attrs(TALLOC_CTX *mem_ctx, + const struct tdb_xattrs *attribs, + TDB_DATA *data) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + + ndr_err = ndr_push_struct_blob( + &blob, mem_ctx, attribs, + (ndr_push_flags_fn_t)ndr_push_tdb_xattrs); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("ndr_push_tdb_xattrs failed: %s\n", + ndr_errstr(ndr_err))); + return ndr_map_error2ntstatus(ndr_err);; + } + + *data = make_tdb_data(blob.data, blob.length); + return NT_STATUS_OK; +} + +/* + * Load tdb_xattrs for a file from the tdb + */ + +static NTSTATUS ea_tdb_load_attrs(TALLOC_CTX *mem_ctx, + struct db_context *db_ctx, + const struct file_id *id, + struct tdb_xattrs **presult) +{ + uint8 id_buf[16]; + NTSTATUS status; + TDB_DATA data; + + push_file_id_16((char *)id_buf, id); + + if (db_ctx->fetch(db_ctx, mem_ctx, + make_tdb_data(id_buf, sizeof(id_buf)), + &data) == -1) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = ea_tdb_pull_attrs(mem_ctx, &data, presult); + TALLOC_FREE(data.dptr); + return NT_STATUS_OK; +} + +/* + * fetch_lock the tdb_ea record for a file + */ + +static struct db_record *ea_tdb_lock_attrs(TALLOC_CTX *mem_ctx, + struct db_context *db_ctx, + const struct file_id *id) +{ + uint8 id_buf[16]; + push_file_id_16((char *)id_buf, id); + return db_ctx->fetch_locked(db_ctx, mem_ctx, + make_tdb_data(id_buf, sizeof(id_buf))); +} + +/* + * Save tdb_xattrs to a previously fetch_locked record + */ + +static NTSTATUS ea_tdb_save_attrs(struct db_record *rec, + const struct tdb_xattrs *attribs) +{ + TDB_DATA data; + NTSTATUS status; + + status = ea_tdb_push_attrs(talloc_tos(), attribs, &data); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("ea_tdb_push_attrs failed: %s\n", + nt_errstr(status))); + return status; + } + + status = rec->store(rec, data, 0); + + TALLOC_FREE(data.dptr); + + return status; +} + +/* + * Worker routine for getxattr and fgetxattr + */ + +static ssize_t ea_tdb_getattr(struct db_context *db_ctx, + const struct file_id *id, + const char *name, void *value, size_t size) +{ + struct tdb_xattrs *attribs; + uint32_t i; + ssize_t result = -1; + NTSTATUS status; + + status = ea_tdb_load_attrs(talloc_tos(), db_ctx, id, &attribs); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("ea_tdb_fetch_attrs failed: %s\n", + nt_errstr(status))); + errno = EINVAL; + return -1; + } + + for (i=0; i<attribs->num_xattrs; i++) { + if (strcmp(attribs->xattrs[i].name, name) == 0) { + break; + } + } + + if (i == attribs->num_xattrs) { + errno = ENOATTR; + goto fail; + } + + if (attribs->xattrs[i].value.length > size) { + errno = ERANGE; + goto fail; + } + + memcpy(value, attribs->xattrs[i].value.data, + attribs->xattrs[i].value.length); + result = attribs->xattrs[i].value.length; + + fail: + TALLOC_FREE(attribs); + return result; +} + +static ssize_t ea_tdb_getxattr(struct vfs_handle_struct *handle, + const char *path, const char *name, + void *value, size_t size) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + return ea_tdb_getattr(db, &id, name, value, size); +} + +static ssize_t ea_tdb_fgetxattr(struct vfs_handle_struct *handle, + struct files_struct *fsp, + const char *name, void *value, size_t size) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + return ea_tdb_getattr(db, &id, name, value, size); +} + +/* + * Worker routine for setxattr and fsetxattr + */ + +static int ea_tdb_setattr(struct db_context *db_ctx, + const struct file_id *id, const char *name, + const void *value, size_t size, int flags) +{ + NTSTATUS status; + struct db_record *rec; + struct tdb_xattrs *attribs; + uint32_t i; + + rec = ea_tdb_lock_attrs(talloc_tos(), db_ctx, id); + + if (rec == NULL) { + DEBUG(0, ("ea_tdb_lock_attrs failed\n")); + errno = EINVAL; + return -1; + } + + status = ea_tdb_pull_attrs(rec, &rec->value, &attribs); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("ea_tdb_fetch_attrs failed: %s\n", + nt_errstr(status))); + TALLOC_FREE(rec); + return -1; + } + + for (i=0; i<attribs->num_xattrs; i++) { + if (strcmp(attribs->xattrs[i].name, name) == 0) { + break; + } + } + + if (i == attribs->num_xattrs) { + struct tdb_xattr *tmp; + + tmp = TALLOC_REALLOC_ARRAY( + attribs, attribs->xattrs, struct tdb_xattr, + attribs->num_xattrs + 1); + + if (tmp == NULL) { + DEBUG(0, ("TALLOC_REALLOC_ARRAY failed\n")); + TALLOC_FREE(rec); + errno = ENOMEM; + return -1; + } + + attribs->xattrs = tmp; + attribs->num_xattrs += 1; + } + + attribs->xattrs[i].name = name; + attribs->xattrs[i].value.data = CONST_DISCARD(uint8 *, value); + attribs->xattrs[i].value.length = size; + + status = ea_tdb_save_attrs(rec, attribs); + + TALLOC_FREE(rec); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("save failed: %s\n", nt_errstr(status))); + return -1; + } + + return 0; +} + +static int ea_tdb_setxattr(struct vfs_handle_struct *handle, + const char *path, const char *name, + const void *value, size_t size, int flags) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + return ea_tdb_setattr(db, &id, name, value, size, flags); +} + +static int ea_tdb_fsetxattr(struct vfs_handle_struct *handle, + struct files_struct *fsp, + const char *name, const void *value, + size_t size, int flags) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + return ea_tdb_setattr(db, &id, name, value, size, flags); +} + +/* + * Worker routine for listxattr and flistxattr + */ + +static ssize_t ea_tdb_listattr(struct db_context *db_ctx, + const struct file_id *id, char *list, + size_t size) +{ + NTSTATUS status; + struct tdb_xattrs *attribs; + uint32_t i; + size_t len = 0; + + status = ea_tdb_load_attrs(talloc_tos(), db_ctx, id, &attribs); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("ea_tdb_fetch_attrs failed: %s\n", + nt_errstr(status))); + errno = EINVAL; + return -1; + } + + DEBUG(10, ("ea_tdb_listattr: Found %d xattrs\n", attribs->num_xattrs)); + + for (i=0; i<attribs->num_xattrs; i++) { + size_t tmp; + + DEBUG(10, ("ea_tdb_listattr: xattrs[i].name: %s\n", + attribs->xattrs[i].name)); + + tmp = strlen(attribs->xattrs[i].name); + + /* + * Try to protect against overflow + */ + + if (len + (tmp+1) < len) { + TALLOC_FREE(attribs); + errno = EINVAL; + return -1; + } + + /* + * Take care of the terminating NULL + */ + len += (tmp + 1); + } + + if (len > size) { + TALLOC_FREE(attribs); + errno = ERANGE; + return -1; + } + + len = 0; + + for (i=0; i<attribs->num_xattrs; i++) { + strlcpy(list+len, attribs->xattrs[i].name, + size-len); + len += (strlen(attribs->xattrs[i].name) + 1); + } + + TALLOC_FREE(attribs); + return len; +} + +static ssize_t ea_tdb_listxattr(struct vfs_handle_struct *handle, + const char *path, char *list, size_t size) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + return ea_tdb_listattr(db, &id, list, size); +} + +static ssize_t ea_tdb_flistxattr(struct vfs_handle_struct *handle, + struct files_struct *fsp, char *list, + size_t size) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + return ea_tdb_listattr(db, &id, list, size); +} + +/* + * Worker routine for removexattr and fremovexattr + */ + +static int ea_tdb_removeattr(struct db_context *db_ctx, + const struct file_id *id, const char *name) +{ + NTSTATUS status; + struct db_record *rec; + struct tdb_xattrs *attribs; + uint32_t i; + + rec = ea_tdb_lock_attrs(talloc_tos(), db_ctx, id); + + if (rec == NULL) { + DEBUG(0, ("ea_tdb_lock_attrs failed\n")); + errno = EINVAL; + return -1; + } + + status = ea_tdb_pull_attrs(rec, &rec->value, &attribs); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("ea_tdb_fetch_attrs failed: %s\n", + nt_errstr(status))); + TALLOC_FREE(rec); + return -1; + } + + for (i=0; i<attribs->num_xattrs; i++) { + if (strcmp(attribs->xattrs[i].name, name) == 0) { + break; + } + } + + if (i == attribs->num_xattrs) { + TALLOC_FREE(rec); + errno = ENOATTR; + return -1; + } + + attribs->xattrs[i] = + attribs->xattrs[attribs->num_xattrs-1]; + attribs->num_xattrs -= 1; + + if (attribs->num_xattrs == 0) { + rec->delete_rec(rec); + TALLOC_FREE(rec); + return 0; + } + + status = ea_tdb_save_attrs(rec, attribs); + + TALLOC_FREE(rec); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("save failed: %s\n", nt_errstr(status))); + return -1; + } + + return 0; +} + +static int ea_tdb_removexattr(struct vfs_handle_struct *handle, + const char *path, const char *name) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + return ea_tdb_removeattr(db, &id, name); +} + +static int ea_tdb_fremovexattr(struct vfs_handle_struct *handle, + struct files_struct *fsp, const char *name) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + return ea_tdb_removeattr(db, &id, name); +} + +/* + * Open the tdb file upon VFS_CONNECT + */ + +static bool ea_tdb_init(int snum, struct db_context **p_db) +{ + struct db_context *db; + const char *dbname; + + dbname = lp_parm_const_string(snum, "ea", "tdb", lock_path("eas.tdb")); + + if (dbname == NULL) { + errno = ENOTSUP; + return false; + } + + become_root(); + db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + unbecome_root(); + + if (db == NULL) { + errno = ENOTSUP; + return false; + } + + *p_db = db; + return true; +} + +/* + * On unlink we need to delete the tdb record + */ +static int ea_tdb_unlink(vfs_handle_struct *handle, const char *path) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + struct db_record *rec; + int ret; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + return -1; + } + + ret = SMB_VFS_NEXT_UNLINK(handle, path); + + if (ret == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + rec = ea_tdb_lock_attrs(talloc_tos(), db, &id); + + /* + * If rec == NULL there's not much we can do about it + */ + + if (rec != NULL) { + rec->delete_rec(rec); + TALLOC_FREE(rec); + } + + return 0; +} + +/* + * On rmdir we need to delete the tdb record + */ +static int ea_tdb_rmdir(vfs_handle_struct *handle, const char *path) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + struct db_record *rec; + int ret; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + return -1; + } + + ret = SMB_VFS_NEXT_RMDIR(handle, path); + + if (ret == -1) { + return -1; + } + + id = SMB_VFS_FILE_ID_CREATE(handle->conn, sbuf.st_dev, sbuf.st_ino); + + rec = ea_tdb_lock_attrs(talloc_tos(), db, &id); + + /* + * If rec == NULL there's not much we can do about it + */ + + if (rec != NULL) { + rec->delete_rec(rec); + TALLOC_FREE(rec); + } + + return 0; +} + +/* + * Destructor for the VFS private data + */ + +static void close_ea_db(void **data) +{ + struct db_context **p_db = (struct db_context **)data; + TALLOC_FREE(*p_db); +} + +static int ea_tdb_connect(vfs_handle_struct *handle, const char *service, + const char *user) +{ + fstring sname; + int res, snum; + struct db_context *db; + + res = SMB_VFS_NEXT_CONNECT(handle, service, user); + if (res < 0) { + return res; + } + + fstrcpy(sname, service); + snum = find_service(sname); + if (snum == -1) { + /* + * Should not happen, but we should not fail just *here*. + */ + return 0; + } + + if (!ea_tdb_init(snum, &db)) { + DEBUG(5, ("Could not init ea tdb\n")); + lp_do_parameter(snum, "ea support", "False"); + return 0; + } + + lp_do_parameter(snum, "ea support", "True"); + + SMB_VFS_HANDLE_SET_DATA(handle, db, close_ea_db, + struct db_context, return -1); + + return 0; +} + +/* VFS operations structure */ + +static const vfs_op_tuple ea_tdb_ops[] = { + {SMB_VFS_OP(ea_tdb_getxattr), SMB_VFS_OP_GETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_fgetxattr), SMB_VFS_OP_FGETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_setxattr), SMB_VFS_OP_SETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_fsetxattr), SMB_VFS_OP_FSETXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_listxattr), SMB_VFS_OP_LISTXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_flistxattr), SMB_VFS_OP_FLISTXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_removexattr), SMB_VFS_OP_REMOVEXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_fremovexattr), SMB_VFS_OP_FREMOVEXATTR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_unlink), SMB_VFS_OP_UNLINK, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_rmdir), SMB_VFS_OP_RMDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(ea_tdb_connect), SMB_VFS_OP_CONNECT, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_ea_tdb_init(void); +NTSTATUS vfs_ea_tdb_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "ea_tdb", + ea_tdb_ops); +} diff --git a/source3/nmbd/nmbd_incomingdgrams.c b/source3/nmbd/nmbd_incomingdgrams.c index c0aa385ff69..75ab9419c2f 100644 --- a/source3/nmbd/nmbd_incomingdgrams.c +++ b/source3/nmbd/nmbd_incomingdgrams.c @@ -257,7 +257,7 @@ void process_local_master_announce(struct subnet_record *subrec, struct packet_s uint32 servertype = IVAL(buf,23); fstring comment; unstring work_name; - struct work_record *work; + struct work_record *work = NULL; struct server_record *servrec; unstring source_name; @@ -344,7 +344,7 @@ a local master browser for workgroup %s and we think we are master. Forcing elec * This server is announcing it is going down. Remove it from the * workgroup. */ - if(!is_myname(server_name) && (work != NULL) && + if(!is_myname(server_name) && ((servrec = find_server_in_workgroup( work, server_name))!=NULL)) { remove_server_from_workgroup( work, servrec); } diff --git a/source3/nsswitch/libwbclient/wbc_err.h b/source3/nsswitch/libwbclient/wbc_err.h deleted file mode 100644 index 069f68f1895..00000000000 --- a/source3/nsswitch/libwbclient/wbc_err.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Winbind client API - - Copyright (C) Gerald (Jerry) Carter 2007 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _WBC_ERR_H -#define _WBC_ERR_H - - -/* Define error types */ - -/** - * @brief Status codes returned from wbc functions - **/ - -enum _wbcErrType { - WBC_ERR_SUCCESS = 0, /**< Successful completion **/ - WBC_ERR_NOT_IMPLEMENTED,/**< Function not implemented **/ - WBC_ERR_UNKNOWN_FAILURE,/**< General failure **/ - WBC_ERR_NO_MEMORY, /**< Memory allocation error **/ - WBC_ERR_INVALID_SID, /**< Invalid SID format **/ - WBC_ERR_INVALID_PARAM, /**< An Invalid parameter was supplied **/ - WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/ - WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/ - WBC_INVALID_RESPONSE, /**< Winbind returned an invalid response **/ - WBC_ERR_NSS_ERROR /**< NSS_STATUS error **/ -}; - -typedef enum _wbcErrType wbcErr; - -#define WBC_ERROR_IS_OK(x) ((x) == WBC_ERR_SUCCESS) - -char *wbcErrorString(wbcErr error); - -#endif /* _WBC_ERR_H */ diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h index 6b85d7e8b30..0b256d343f0 100644 --- a/source3/nsswitch/libwbclient/wbclient.h +++ b/source3/nsswitch/libwbclient/wbclient.h @@ -23,7 +23,32 @@ #define _WBCLIENT_H #include <pwd.h> -#include <nsswitch/libwbclient/wbc_err.h> +#include <grp.h> + +/* Define error types */ + +/** + * @brief Status codes returned from wbc functions + **/ + +enum _wbcErrType { + WBC_ERR_SUCCESS = 0, /**< Successful completion **/ + WBC_ERR_NOT_IMPLEMENTED,/**< Function not implemented **/ + WBC_ERR_UNKNOWN_FAILURE,/**< General failure **/ + WBC_ERR_NO_MEMORY, /**< Memory allocation error **/ + WBC_ERR_INVALID_SID, /**< Invalid SID format **/ + WBC_ERR_INVALID_PARAM, /**< An Invalid parameter was supplied **/ + WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/ + WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/ + WBC_INVALID_RESPONSE, /**< Winbind returned an invalid response **/ + WBC_ERR_NSS_ERROR /**< NSS_STATUS error **/ +}; + +typedef enum _wbcErrType wbcErr; + +#define WBC_ERROR_IS_OK(x) ((x) == WBC_ERR_SUCCESS) + +char *wbcErrorString(wbcErr error); /* * Data types used by the Winbind Client API diff --git a/source3/nsswitch/winbind_nss_config.h b/source3/nsswitch/winbind_nss_config.h index 7f0e4b92e00..64d52af771e 100644 --- a/source3/nsswitch/winbind_nss_config.h +++ b/source3/nsswitch/winbind_nss_config.h @@ -27,6 +27,14 @@ #undef SIZEOF_LONG #endif +/* + * we don't need socket wrapper + * nor nss wrapper here and we don't + * want to depend on swrap_close() + * so we better disable both + */ +#define SOCKET_WRAPPER_NOT_REPLACE +#define NSS_WRAPPER_NOT_REPLACE /* Include header files from data in config.h file */ diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 5ee1cdc0c0b..b05a42b32c4 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -1352,8 +1352,7 @@ done: tdbsam_close(); - if (new_acct) - TALLOC_FREE(new_acct); + TALLOC_FREE(new_acct); return NT_STATUS_ACCESS_DENIED; } diff --git a/source3/pkgconfig/wbclient.pc.in b/source3/pkgconfig/wbclient.pc.in new file mode 100644 index 00000000000..158fa923d61 --- /dev/null +++ b/source3/pkgconfig/wbclient.pc.in @@ -0,0 +1,13 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Samba libwbclient +Description: A library to access winbindd +Version: 0 +URL: http://www.samba.org/ +#Libs: -L@libdir@ -lwbclient +Libs: -lwbclient +Libs.private: -lwbclient +Cflags: -I@includedir@ diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 1a4a26ee6f2..bba55c0e4ac 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -5326,6 +5326,7 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) SEC_DESC_BUF *new_secdesc_ctr = NULL; SEC_DESC_BUF *old_secdesc_ctr = NULL; prs_struct ps; + bool prs_init_done = false; TALLOC_CTX *mem_ctx = NULL; TDB_DATA kbuf; WERROR status; @@ -5394,6 +5395,8 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) (uint32)ndr_size_security_descriptor(new_secdesc_ctr->sd, 0) + sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL); + prs_init_done = true; + if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr, &ps, 1)) { status = WERR_BADFUNC; @@ -5413,7 +5416,9 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr) out: - prs_mem_free(&ps); + if (prs_init_done) { + prs_mem_free(&ps); + } if (mem_ctx) talloc_destroy(mem_ctx); return status; diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index bb410e646b0..d1657c8cf60 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -1,4 +1,4 @@ -/* +/* * Unix SMB/CIFS implementation. * Virtual Windows Registry Layer * Copyright (C) Volker Lendecke 2006 @@ -7,12 +7,12 @@ * 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/>. */ @@ -27,7 +27,9 @@ static WERROR fill_value_cache(struct registry_key *key) { if (key->values != NULL) { - return WERR_OK; + if (!reg_values_need_update(key->key, key->values)) { + return WERR_OK; + } } if (!(key->values = TALLOC_ZERO_P(key, REGVAL_CTR))) { @@ -44,7 +46,9 @@ static WERROR fill_value_cache(struct registry_key *key) static WERROR fill_subkey_cache(struct registry_key *key) { if (key->subkeys != NULL) { - return WERR_OK; + if (!reg_subkeys_need_update(key->key, key->subkeys)) { + return WERR_OK; + } } if (!(key->subkeys = TALLOC_ZERO_P(key, REGSUBKEY_CTR))) { @@ -136,7 +140,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx, result = WERR_BADFILE; goto done; } - + /* check if the path really exists; failed is indicated by -1 */ /* if the subkey count failed, bail out */ @@ -149,7 +153,7 @@ static WERROR regkey_open_onelevel(TALLOC_CTX *mem_ctx, result = WERR_BADFILE; goto done; } - + TALLOC_FREE( subkeys ); if ( !regkey_access_check( key, access_desired, &key->access_granted, @@ -298,7 +302,7 @@ WERROR reg_enumvalue(TALLOC_CTX *mem_ctx, struct registry_key *key, SAFE_FREE(val); return WERR_NOMEM; } - + *pval = val; return WERR_OK; } @@ -490,7 +494,6 @@ WERROR reg_createkey(TALLOC_CTX *ctx, struct registry_key *parent, TALLOC_FREE(mem_ctx); return err; } - WERROR reg_deletekey(struct registry_key *parent, const char *path) { @@ -708,8 +711,8 @@ WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path, } /* - * Utility function to delete a registry key with all its subkeys. - * Note that reg_deletekey returns ACCESS_DENIED when called on a + * Utility function to delete a registry key with all its subkeys. + * Note that reg_deletekey returns ACCESS_DENIED when called on a * key that has subkeys. */ WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx, @@ -735,11 +738,11 @@ WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx, } while (W_ERROR_IS_OK(werr = reg_enumkey(mem_ctx, key, 0, - &subkey_name, NULL))) + &subkey_name, NULL))) { werr = reg_deletekey_recursive_internal(mem_ctx, key, subkey_name, - True); + true); if (!W_ERROR_IS_OK(werr)) { goto done; } @@ -767,12 +770,12 @@ 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_internal(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_internal(ctx, parent, path, false); } diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c index f50a41816c1..c4bfc2b6c9c 100644 --- a/source3/registry/reg_db.c +++ b/source3/registry/reg_db.c @@ -622,7 +622,15 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) } strupper_m(path); + if (tdb_read_lock_bystring_with_timeout(tdb_reg->tdb, path, 10) == -1) { + return 0; + } + dbuf = tdb_fetch_bystring(tdb_reg->tdb, path); + ctr->seqnum = regdb_get_seqnum(); + + tdb_read_unlock_bystring(tdb_reg->tdb, path); + buf = dbuf.dptr; buflen = dbuf.dsize; @@ -750,7 +758,14 @@ int regdb_fetch_values( const char* key, REGVAL_CTR *values ) return 0; } + if (tdb_read_lock_bystring_with_timeout(tdb_reg->tdb, keystr, 10) == -1) { + return 0; + } + data = tdb_fetch_bystring(tdb_reg->tdb, keystr); + values->seqnum = regdb_get_seqnum(); + + tdb_read_unlock_bystring(tdb_reg->tdb, keystr); if (!data.dptr) { /* all keys have zero values by default */ @@ -907,6 +922,16 @@ static WERROR regdb_set_secdesc(const char *key, return err; } +bool regdb_subkeys_need_update(REGSUBKEY_CTR *subkeys) +{ + return (regdb_get_seqnum() != subkeys->seqnum); +} + +bool regdb_values_need_update(REGVAL_CTR *values) +{ + return (regdb_get_seqnum() != values->seqnum); +} + /* * Table of function pointers for default access */ @@ -918,5 +943,7 @@ REGISTRY_OPS regdb_ops = { regdb_store_values, NULL, regdb_get_secdesc, - regdb_set_secdesc + regdb_set_secdesc, + regdb_subkeys_need_update, + regdb_values_need_update }; diff --git a/source3/registry/reg_frontend_hilvl.c b/source3/registry/reg_frontend_hilvl.c index a4b78b24c0e..73fcf87e17a 100644 --- a/source3/registry/reg_frontend_hilvl.c +++ b/source3/registry/reg_frontend_hilvl.c @@ -214,3 +214,32 @@ WERROR regkey_set_secdesc(REGISTRY_KEY *key, return WERR_ACCESS_DENIED; } + +/** + * 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) +{ + if (key->hook && key->hook->ops && key->hook->ops->subkeys_need_update) + { + return key->hook->ops->subkeys_need_update(subkeys); + } + + return false; +} + +/** + * Check whether the in-memory version of the values of a + * registry key needs update from disk. + */ +bool reg_values_need_update(REGISTRY_KEY *key, REGVAL_CTR *values) +{ + if (key->hook && key->hook->ops && key->hook->ops->values_need_update) + { + return key->hook->ops->values_need_update(values); + } + + return false; +} + diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c index 2ca74f7c169..5be07960024 100644 --- a/source3/registry/reg_printing.c +++ b/source3/registry/reg_printing.c @@ -1266,5 +1266,5 @@ REGISTRY_OPS printing_ops = { regprint_fetch_reg_values, regprint_store_reg_keys, regprint_store_reg_values, - NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL }; diff --git a/source3/registry/reg_shares.c b/source3/registry/reg_shares.c index 178f23e21cc..4ac6e1d1514 100644 --- a/source3/registry/reg_shares.c +++ b/source3/registry/reg_shares.c @@ -159,7 +159,7 @@ REGISTRY_OPS shares_reg_ops = { shares_value_info, shares_store_subkey, shares_store_value, - NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL }; diff --git a/source3/registry/reg_smbconf.c b/source3/registry/reg_smbconf.c index 116cde936ed..8dfb745a7e7 100644 --- a/source3/registry/reg_smbconf.c +++ b/source3/registry/reg_smbconf.c @@ -271,5 +271,7 @@ REGISTRY_OPS smbconf_reg_ops = { smbconf_store_values, smbconf_reg_access_check, smbconf_get_secdesc, - smbconf_set_secdesc + smbconf_set_secdesc, + NULL, + NULL }; diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 6abc67fc35e..77ade5cba1b 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -716,41 +716,6 @@ NTSTATUS rpccli_lsa_query_info_policy2(struct rpc_pipe_client *cli, return result; } -NTSTATUS rpccli_lsa_set_info_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint16 info_class, - LSA_INFO_CTR ctr) -{ - prs_struct qbuf, rbuf; - LSA_Q_SET_INFO q; - LSA_R_SET_INFO r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - init_q_set(&q, pol, info_class, ctr); - - CLI_DO_RPC(cli, mem_ctx, PI_LSARPC, LSA_SETINFOPOLICY, - q, r, - qbuf, rbuf, - lsa_io_q_set, - lsa_io_r_set, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - /* Return output parameters */ - - done: - - return result; -} - - /** * Enumerate list of trusted domains * @@ -1468,222 +1433,3 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); } #endif - -NTSTATUS rpccli_lsa_open_trusted_domain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, DOM_SID *dom_sid, uint32 access_mask, - POLICY_HND *trustdom_pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPEN_TRUSTED_DOMAIN q; - LSA_R_OPEN_TRUSTED_DOMAIN r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - init_lsa_q_open_trusted_domain(&q, pol, dom_sid, access_mask); - - /* Marshall data and send request */ - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENTRUSTDOM, - q, r, - qbuf, rbuf, - lsa_io_q_open_trusted_domain, - lsa_io_r_open_trusted_domain, - NT_STATUS_UNSUCCESSFUL); - - /* Return output parameters */ - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - *trustdom_pol = r.handle; - } - - return result; -} - -NTSTATUS rpccli_lsa_query_trusted_domain_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint16 info_class, - LSA_TRUSTED_DOMAIN_INFO **info) -{ - prs_struct qbuf, rbuf; - LSA_Q_QUERY_TRUSTED_DOMAIN_INFO q; - LSA_R_QUERY_TRUSTED_DOMAIN_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Marshall data and send request */ - - init_q_query_trusted_domain_info(&q, pol, info_class); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFO, - q, r, - qbuf, rbuf, - lsa_io_q_query_trusted_domain_info, - lsa_io_r_query_trusted_domain_info, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - *info = r.info; - -done: - return result; -} - -NTSTATUS rpccli_lsa_open_trusted_domain_by_name(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, const char *name, uint32 access_mask, - POLICY_HND *trustdom_pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME q; - LSA_R_OPEN_TRUSTED_DOMAIN_BY_NAME r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - init_lsa_q_open_trusted_domain_by_name(&q, pol, name, access_mask); - - /* Marshall data and send request */ - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_OPENTRUSTDOMBYNAME, - q, r, - qbuf, rbuf, - lsa_io_q_open_trusted_domain_by_name, - lsa_io_r_open_trusted_domain_by_name, - NT_STATUS_UNSUCCESSFUL); - - /* Return output parameters */ - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - *trustdom_pol = r.handle; - } - - return result; -} - - -NTSTATUS rpccli_lsa_query_trusted_domain_info_by_sid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint16 info_class, DOM_SID *dom_sid, - LSA_TRUSTED_DOMAIN_INFO **info) -{ - prs_struct qbuf, rbuf; - LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID q; - LSA_R_QUERY_TRUSTED_DOMAIN_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Marshall data and send request */ - - init_q_query_trusted_domain_info_by_sid(&q, pol, info_class, dom_sid); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYSID, - q, r, - qbuf, rbuf, - lsa_io_q_query_trusted_domain_info_by_sid, - lsa_io_r_query_trusted_domain_info, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - *info = r.info; - -done: - - return result; -} - -NTSTATUS rpccli_lsa_query_trusted_domain_info_by_name(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint16 info_class, const char *domain_name, - LSA_TRUSTED_DOMAIN_INFO **info) -{ - prs_struct qbuf, rbuf; - LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME q; - LSA_R_QUERY_TRUSTED_DOMAIN_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Marshall data and send request */ - - init_q_query_trusted_domain_info_by_name(&q, pol, info_class, domain_name); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYTRUSTDOMINFOBYNAME, - q, r, - qbuf, rbuf, - lsa_io_q_query_trusted_domain_info_by_name, - lsa_io_r_query_trusted_domain_info, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - *info = r.info; - -done: - - return result; -} - -NTSTATUS cli_lsa_query_domain_info_policy(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint16 info_class, LSA_DOM_INFO_UNION **info) -{ - prs_struct qbuf, rbuf; - LSA_Q_QUERY_DOM_INFO_POLICY q; - LSA_R_QUERY_DOM_INFO_POLICY r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Marshall data and send request */ - - init_q_query_dom_info(&q, pol, info_class); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_QUERYDOMINFOPOL, - q, r, - qbuf, rbuf, - lsa_io_q_query_dom_info, - lsa_io_r_query_dom_info, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - *info = r.info; - -done: - return result; -} - diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index 59fce4a9047..98c42833479 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -909,21 +909,6 @@ bool lsa_io_dom_query_12(const char *desc, DOM_QUERY_12 *info, prs_struct *ps, i } -/******************************************************************* - Inits an LSA_Q_QUERY_INFO structure. -********************************************************************/ - -void init_q_set(LSA_Q_SET_INFO *in, POLICY_HND *hnd, uint16 info_class, LSA_INFO_CTR ctr) -{ - DEBUG(5,("init_q_set\n")); - - in->info_class = info_class; - - in->pol = *hnd; - - in->ctr = ctr; - in->ctr.info_class = info_class; -} /******************************************************************* reads or writes a structure. @@ -1065,49 +1050,6 @@ bool lsa_io_r_query(const char *desc, LSA_R_QUERY_INFO *out, prs_struct *ps, int } /******************************************************************* - Reads or writes an LSA_Q_SET_INFO structure. -********************************************************************/ - -bool lsa_io_q_set(const char *desc, LSA_Q_SET_INFO *in, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_set"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("", &in->pol, ps, depth)) - return False; - - if(!prs_uint16("info_class", ps, depth, &in->info_class)) - return False; - - if(!lsa_io_query_info_ctr("", ps, depth, &in->ctr)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an LSA_R_SET_INFO structure. -********************************************************************/ - -bool lsa_io_r_set(const char *desc, LSA_R_SET_INFO *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_set"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} - -/******************************************************************* Inits a LSA_SID_ENUM structure. ********************************************************************/ @@ -3411,76 +3353,6 @@ bool lsa_io_q_open_trusted_domain(const char *desc, LSA_Q_OPEN_TRUSTED_DOMAIN *i /******************************************************************* - Inits an LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME structure. -********************************************************************/ - -void init_lsa_q_open_trusted_domain_by_name(LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME *q, - POLICY_HND *hnd, - const char *name, - uint32 desired_access) -{ - memcpy(&q->pol, hnd, sizeof(q->pol)); - - init_lsa_string(&q->name, name); - q->access_mask = desired_access; -} - -/******************************************************************* -********************************************************************/ - - -/******************************************************************* - Reads or writes an LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME structure. -********************************************************************/ - -bool lsa_io_q_open_trusted_domain_by_name(const char *desc, LSA_Q_OPEN_TRUSTED_DOMAIN_BY_NAME *q_o, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_open_trusted_domain_by_name"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol", &q_o->pol, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!smb_io_lsa_string("name", &q_o->name, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("access", ps, depth, &q_o->access_mask)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an LSA_R_OPEN_TRUSTED_DOMAIN_BY_NAME structure. -********************************************************************/ - -bool lsa_io_r_open_trusted_domain_by_name(const char *desc, LSA_R_OPEN_TRUSTED_DOMAIN_BY_NAME *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_open_trusted_domain_by_name"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!smb_io_pol_hnd("handle", &out->handle, ps, depth)) - return False; - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} - -/******************************************************************* ********************************************************************/ bool lsa_io_q_open_trusted_domain(const char *desc, LSA_Q_OPEN_TRUSTED_DOMAIN *q_o, prs_struct *ps, int depth) @@ -3707,351 +3579,6 @@ bool lsa_io_r_delete_object(const char *desc, LSA_R_DELETE_OBJECT *out, prs_stru } /******************************************************************* - Inits an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO structure. -********************************************************************/ - -void init_q_query_trusted_domain_info(LSA_Q_QUERY_TRUSTED_DOMAIN_INFO *q, - POLICY_HND *hnd, uint16 info_class) -{ - DEBUG(5, ("init_q_query_trusted_domain_info\n")); - - q->pol = *hnd; - q->info_class = info_class; -} - -/******************************************************************* - Inits an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME structure. -********************************************************************/ - -void init_q_query_trusted_domain_info_by_name(LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME *q, - POLICY_HND *hnd, uint16 info_class, - const char *dom_name) -{ - DEBUG(5, ("init_q_query_trusted_domain_info_by_name\n")); - - q->pol = *hnd; - init_lsa_string(&q->domain_name, dom_name ); - q->info_class = info_class; -} - -/******************************************************************* - Inits an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID structure. -********************************************************************/ - -void init_q_query_trusted_domain_info_by_sid(LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID *q, - POLICY_HND *hnd, uint16 info_class, - DOM_SID *dom_sid) -{ - DEBUG(5, ("init_q_query_trusted_domain_info_by_sid\n")); - - q->pol = *hnd; - init_dom_sid2(&q->dom_sid, dom_sid); - q->info_class = info_class; -} - -/******************************************************************* - Reads or writes an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO structure. -********************************************************************/ - -bool lsa_io_q_query_trusted_domain_info(const char *desc, - LSA_Q_QUERY_TRUSTED_DOMAIN_INFO *q_q, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_query_trusted_domain_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol", &q_q->pol, ps, depth)) - return False; - - if(!prs_uint16("info_class", ps, depth, &q_q->info_class)) - return False; - - return True; -} - - -/******************************************************************* - Reads or writes an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID structure. -********************************************************************/ - -bool lsa_io_q_query_trusted_domain_info_by_sid(const char *desc, - LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_SID *q_q, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_query_trusted_domain_info_by_sid"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol", &q_q->pol, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!smb_io_dom_sid2("dom_sid", &q_q->dom_sid, ps, depth)) - return False; - - if(!prs_uint16("info_class", ps, depth, &q_q->info_class)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME structure. -********************************************************************/ - -bool lsa_io_q_query_trusted_domain_info_by_name(const char *desc, - LSA_Q_QUERY_TRUSTED_DOMAIN_INFO_BY_NAME *q_q, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_query_trusted_domain_info_by_name"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol", &q_q->pol, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!smb_io_lsa_string("domain_name", &q_q->domain_name, ps, depth)) - return False; - - if(!prs_uint16("info_class", ps, depth, &q_q->info_class)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool smb_io_lsa_data_buf_hdr(const char *desc, LSA_DATA_BUF_HDR *buf_hdr, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "smb_io_lsa_data_buf_hdr"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("length", ps, depth, &buf_hdr->length)) - return False; - - if(!prs_uint32("size", ps, depth, &buf_hdr->size)) - return False; - - if (!prs_uint32("data_ptr", ps, depth, &buf_hdr->data_ptr)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool smb_io_lsa_data_buf(const char *desc, LSA_DATA_BUF *buf, - prs_struct *ps, int depth, int length, int size) -{ - prs_debug(ps, depth, desc, "smb_io_lsa_data_buf"); - depth++; - - if ( UNMARSHALLING(ps) && length ) { - if ( !(buf->data = PRS_ALLOC_MEM( ps, uint8, length )) ) - return False; - } - - if (!prs_uint32("size", ps, depth, &buf->size)) - return False; - - if (!prs_uint32("offset", ps, depth, &buf->offset)) - return False; - - if (!prs_uint32("length", ps, depth, &buf->length)) - return False; - - if(!prs_uint8s(False, "data", ps, depth, buf->data, length)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool lsa_io_trustdom_query_1(const char *desc, TRUSTED_DOMAIN_INFO_NAME *name, - prs_struct *ps, int depth) -{ - if (!smb_io_lsa_string("netbios_name", &name->netbios_name, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool lsa_io_trustdom_query_3(const char *desc, TRUSTED_DOMAIN_INFO_POSIX_OFFSET *posix, - prs_struct *ps, int depth) -{ - if(!prs_uint32("posix_offset", ps, depth, &posix->posix_offset)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool lsa_io_trustdom_query_4(const char *desc, TRUSTED_DOMAIN_INFO_PASSWORD *password, - prs_struct *ps, int depth) -{ - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_password", ps, depth, &password->ptr_password)) - return False; - - if(!prs_uint32("ptr_old_password", ps, depth, &password->ptr_old_password)) - return False; - - if (&password->ptr_password) { - - if (!smb_io_lsa_data_buf_hdr("password_hdr", &password->password_hdr, ps, depth)) - return False; - - if (!smb_io_lsa_data_buf("password", &password->password, ps, depth, - password->password_hdr.length, password->password_hdr.size)) - return False; - } - - if (&password->ptr_old_password) { - - if (!smb_io_lsa_data_buf_hdr("old_password_hdr", &password->old_password_hdr, ps, depth)) - return False; - - if (!smb_io_lsa_data_buf("old_password", &password->old_password, ps, depth, - password->old_password_hdr.length, password->old_password_hdr.size)) - return False; - } - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool lsa_io_trustdom_query_6(const char *desc, TRUSTED_DOMAIN_INFO_EX *info_ex, - prs_struct *ps, int depth) -{ - uint32 dom_sid_ptr; - - if (!smb_io_unihdr("domain_name_hdr", &info_ex->domain_name.hdr, ps, depth)) - return False; - - if (!smb_io_unihdr("netbios_name_hdr", &info_ex->netbios_name.hdr, ps, depth)) - return False; - - if (!prs_uint32("dom_sid_ptr", ps, depth, &dom_sid_ptr)) - return False; - - if (!prs_uint32("trust_direction", ps, depth, &info_ex->trust_direction)) - return False; - - if (!prs_uint32("trust_type", ps, depth, &info_ex->trust_type)) - return False; - - if (!prs_uint32("trust_attributes", ps, depth, &info_ex->trust_attributes)) - return False; - - if (!smb_io_unistr2("domain_name_unistring", &info_ex->domain_name.unistring, info_ex->domain_name.hdr.buffer, ps, depth)) - return False; - - if (!smb_io_unistr2("netbios_name_unistring", &info_ex->netbios_name.unistring, info_ex->netbios_name.hdr.buffer, ps, depth)) - return False; - - if (!smb_io_dom_sid2("sid", &info_ex->sid, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -static bool lsa_io_trustdom_query(const char *desc, prs_struct *ps, int depth, LSA_TRUSTED_DOMAIN_INFO *info) -{ - prs_debug(ps, depth, desc, "lsa_io_trustdom_query"); - depth++; - - if(!prs_uint16("info_class", ps, depth, &info->info_class)) - return False; - - if(!prs_align(ps)) - return False; - - switch (info->info_class) { - case 1: - if(!lsa_io_trustdom_query_1("name", &info->name, ps, depth)) - return False; - break; - case 3: - if(!lsa_io_trustdom_query_3("posix_offset", &info->posix_offset, ps, depth)) - return False; - break; - case 4: - if(!lsa_io_trustdom_query_4("password", &info->password, ps, depth)) - return False; - break; - case 6: - if(!lsa_io_trustdom_query_6("info_ex", &info->info_ex, ps, depth)) - return False; - break; - default: - DEBUG(0,("unsupported info-level: %d\n", info->info_class)); - return False; - } - - return True; -} - -/******************************************************************* - Reads or writes an LSA_R_QUERY_TRUSTED_DOMAIN_INFO structure. -********************************************************************/ - -bool lsa_io_r_query_trusted_domain_info(const char *desc, - LSA_R_QUERY_TRUSTED_DOMAIN_INFO *r_q, - prs_struct *ps, int depth) -{ - if (r_q == NULL) - return False; - - prs_debug(ps, depth, desc, "lsa_io_r_query_trusted_domain_info"); - depth++; - - if (!prs_pointer("trustdom", ps, depth, (void*)&r_q->info, - sizeof(LSA_TRUSTED_DOMAIN_INFO), - (PRS_POINTER_CAST)lsa_io_trustdom_query) ) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_ntstatus("status", ps, depth, &r_q->status)) - return False; - - return True; -} - -/******************************************************************* Inits an LSA_Q_QUERY_DOM_INFO_POLICY structure. ********************************************************************/ diff --git a/source3/rpc_server/srv_dfs_nt.c b/source3/rpc_server/srv_dfs_nt.c index 690ddd60d68..29538a304f6 100644 --- a/source3/rpc_server/srv_dfs_nt.c +++ b/source3/rpc_server/srv_dfs_nt.c @@ -133,10 +133,10 @@ WERROR _dfs_Remove(pipes_struct *p, struct dfs_Remove *r) altpath = talloc_asprintf(ctx, "%s\\%s", r->in.servername, r->in.sharename); - strlower_m(altpath); if (!altpath) { return WERR_NOMEM; } + strlower_m(altpath); DEBUG(5,("init_reply_dfs_remove: Request to remove %s -> %s\\%s.\n", r->in.dfs_entry_path, r->in.servername, r->in.sharename)); } diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c index b30a7f87926..849ec9c4eb8 100644 --- a/source3/rpc_server/srv_wkssvc_nt.c +++ b/source3/rpc_server/srv_wkssvc_nt.c @@ -22,8 +22,7 @@ /* This is the implementation of the wks interface. */ #include "includes.h" -#include "libnet/libnet_join.h" -#include "libnet/libnet_proto.h" +#include "libnet/libnet.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index d54f67264a9..7743269ce0e 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -893,25 +893,15 @@ static NTSTATUS cmd_lsa_query_secobj(struct rpc_pipe_client *cli, return result; } -static void display_trust_dom_info_1(TRUSTED_DOMAIN_INFO_NAME *n) -{ - printf("NetBIOS Name:\t%s\n", unistr2_static(&n->netbios_name.unistring)); -} - -static void display_trust_dom_info_3(TRUSTED_DOMAIN_INFO_POSIX_OFFSET *p) -{ - printf("Posix Offset:\t%08x (%d)\n", p->posix_offset, p->posix_offset); -} - -static void display_trust_dom_info_4(TRUSTED_DOMAIN_INFO_PASSWORD *p, const char *password) +static void display_trust_dom_info_4(struct lsa_TrustDomainInfoPassword *p, const char *password) { char *pwd, *pwd_old; - DATA_BLOB data = data_blob(NULL, p->password.length); - DATA_BLOB data_old = data_blob(NULL, p->old_password.length); + DATA_BLOB data = data_blob(NULL, p->password->length); + DATA_BLOB data_old = data_blob(NULL, p->old_password->length); - memcpy(data.data, p->password.data, p->password.length); - memcpy(data_old.data, p->old_password.data, p->old_password.length); + memcpy(data.data, p->password->data, p->password->length); + memcpy(data_old.data, p->old_password->data, p->old_password->length); pwd = decrypt_trustdom_secret(password, &data); pwd_old = decrypt_trustdom_secret(password, &data_old); @@ -926,36 +916,20 @@ static void display_trust_dom_info_4(TRUSTED_DOMAIN_INFO_PASSWORD *p, const char data_blob_free(&data_old); } -static void display_trust_dom_info_6(TRUSTED_DOMAIN_INFO_EX *i) -{ - printf("Domain Name:\t\t%s\n", unistr2_static(&i->domain_name.unistring)); - printf("NetBIOS Name:\t\t%s\n", unistr2_static(&i->netbios_name.unistring)); - printf("SID:\t\t\t%s\n", sid_string_tos(&i->sid.sid)); - printf("Trust Direction:\t0x%08x\n", i->trust_direction); - printf("Trust Type:\t\t0x%08x\n", i->trust_type); - printf("Trust Attributes:\t0x%08x\n", i->trust_attributes); -} - - -static void display_trust_dom_info(LSA_TRUSTED_DOMAIN_INFO *info, uint32 info_class, const char *pass) +static void display_trust_dom_info(union lsa_TrustedDomainInfo *info, + enum lsa_TrustDomInfoEnum info_class, + const char *pass) { switch (info_class) { - case 1: - display_trust_dom_info_1(&info->name); - break; - case 3: - display_trust_dom_info_3(&info->posix_offset); - break; - case 4: - display_trust_dom_info_4(&info->password, pass); - break; - case 6: - display_trust_dom_info_6(&info->info_ex); - break; - default: - printf("unsupported info-class: %d\n", info_class); - break; + case LSA_TRUSTED_DOMAIN_INFO_PASSWORD: + display_trust_dom_info_4(&info->password, pass); + break; + default: + NDR_PRINT_UNION_DEBUG(lsa_TrustedDomainInfo, + info_class, info); + break; } + } static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli, @@ -966,9 +940,8 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_SID dom_sid; uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED; - LSA_TRUSTED_DOMAIN_INFO *info; - - uint32 info_class = 1; + union lsa_TrustedDomainInfo info; + enum lsa_TrustDomInfoEnum info_class = 1; if (argc > 3 || argc < 2) { printf("Usage: %s [sid] [info_class]\n", argv[0]); @@ -986,13 +959,15 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_query_trusted_domain_info_by_sid(cli, mem_ctx, &pol, - info_class, &dom_sid, &info); - + result = rpccli_lsa_QueryTrustedDomainInfoBySid(cli, mem_ctx, + &pol, + &dom_sid, + info_class, + &info); if (!NT_STATUS_IS_OK(result)) goto done; - display_trust_dom_info(info, info_class, cli->pwd.password); + display_trust_dom_info(&info, info_class, cli->pwd.password); done: if (&pol) @@ -1001,6 +976,11 @@ static NTSTATUS cmd_lsa_query_trustdominfobysid(struct rpc_pipe_client *cli, return result; } +static void init_lsa_String(struct lsa_String *name, const char *s) +{ + name->string = s; +} + static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -1008,8 +988,9 @@ static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli, POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED; - LSA_TRUSTED_DOMAIN_INFO *info; - uint32 info_class = 1; + union lsa_TrustedDomainInfo info; + enum lsa_TrustDomInfoEnum info_class = 1; + struct lsa_String trusted_domain; if (argc > 3 || argc < 2) { printf("Usage: %s [name] [info_class]\n", argv[0]); @@ -1024,13 +1005,17 @@ static NTSTATUS cmd_lsa_query_trustdominfobyname(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_query_trusted_domain_info_by_name(cli, mem_ctx, &pol, - info_class, argv[1], &info); + init_lsa_String(&trusted_domain, argv[1]); + result = rpccli_lsa_QueryTrustedDomainInfoByName(cli, mem_ctx, + &pol, + trusted_domain, + info_class, + &info); if (!NT_STATUS_IS_OK(result)) goto done; - display_trust_dom_info(info, info_class, cli->pwd.password); + display_trust_dom_info(&info, info_class, cli->pwd.password); done: if (&pol) @@ -1046,9 +1031,9 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli, POLICY_HND pol, trustdom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 access_mask = SEC_RIGHTS_MAXIMUM_ALLOWED; - LSA_TRUSTED_DOMAIN_INFO *info; + union lsa_TrustedDomainInfo info; DOM_SID dom_sid; - uint32 info_class = 1; + enum lsa_TrustDomInfoEnum info_class = 1; if (argc > 3 || argc < 2) { printf("Usage: %s [sid] [info_class]\n", argv[0]); @@ -1066,20 +1051,25 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - - result = rpccli_lsa_open_trusted_domain(cli, mem_ctx, &pol, - &dom_sid, access_mask, &trustdom_pol); + + result = rpccli_lsa_OpenTrustedDomain(cli, mem_ctx, + &pol, + &dom_sid, + access_mask, + &trustdom_pol); if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_query_trusted_domain_info(cli, mem_ctx, &trustdom_pol, - info_class, &info); + result = rpccli_lsa_QueryTrustedDomainInfo(cli, mem_ctx, + &trustdom_pol, + info_class, + &info); if (!NT_STATUS_IS_OK(result)) goto done; - display_trust_dom_info(info, info_class, cli->pwd.password); + display_trust_dom_info(&info, info_class, cli->pwd.password); done: if (&pol) diff --git a/source3/script/fix_bool.pl b/source3/script/fix_bool.pl new file mode 100755 index 00000000000..c09645de7c0 --- /dev/null +++ b/source3/script/fix_bool.pl @@ -0,0 +1,19 @@ +#!/usr/bin/perl -w + +open(INFILE, "$ARGV[0]") || die $@; +open(OUTFILE, ">$ARGV[0].new") || die $@; + +while (<INFILE>) { + $_ =~ s/True/true/; + $_ =~ s/False/false/; + print OUTFILE "$_"; +} + +close(INFILE); +close(OUTFILE); + +rename("$ARGV[0].new", "$ARGV[0]") || die @_; + +exit(0); + + diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh index 86abb15ed1d..08bfdf601c8 100755 --- a/source3/script/tests/selftest.sh +++ b/source3/script/tests/selftest.sh @@ -186,6 +186,7 @@ cat >$SERVERCONFFILE<<EOF map hidden = yes map system = yes create mask = 755 + vfs objects = $BINDIR/ea_tdb.so [hideunread] copy = tmp hide unreadable = yes diff --git a/source3/script/tests/test_local_s3.sh b/source3/script/tests/test_local_s3.sh index 6117106c8a3..fd8f98ccabb 100755 --- a/source3/script/tests/test_local_s3.sh +++ b/source3/script/tests/test_local_s3.sh @@ -21,6 +21,6 @@ testit "replacetort" $VALGRIND $BINDIR/replacetort || \ failed=`expr $failed + 1` testit "tdbtorture" $VALGRIND $BINDIR/tdbtorture || \ - failed=`expr $failed +1` + failed=`expr $failed + 1` testok $0 $failed diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh index 9f672897acb..0b4a52d4b50 100755 --- a/source3/script/tests/test_posix_s3.sh +++ b/source3/script/tests/test_posix_s3.sh @@ -47,7 +47,7 @@ unix="UNIX-INFO2" tests="$base $raw $rpc $unix" skipped="BASE-CHARSET BASE-DELAYWRITE BASE-TCONDEV" -skipped="$skipped RAW-ACLS RAW-COMPOSITE RAW-CONTEXT RAW-EAS" +skipped="$skipped RAW-ACLS RAW-COMPOSITE RAW-CONTEXT" skipped="$skipped RAW-IOCTL" skipped="$skipped RAW-QFILEINFO RAW-QFSINFO RAW-SEARCH" skipped="$skipped RAW-SFILEINFO RAW-STREAMS" diff --git a/source3/script/tests/test_wbinfo_s3.sh b/source3/script/tests/test_wbinfo_s3.sh index 6a8faa1f87e..01eed6ead68 100755 --- a/source3/script/tests/test_wbinfo_s3.sh +++ b/source3/script/tests/test_wbinfo_s3.sh @@ -35,6 +35,8 @@ tests="$tests:--name-to-sid=$username" #Didn't pass yet# tests="$tests:--user-info=$username" tests="$tests:--user-groups=$username" +failed=0 + OLDIFS=$IFS NEWIFS=$':' IFS=$NEWIFS diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index c8175f77ace..9c25f69c975 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -451,7 +451,6 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) int ret = 0; files_struct *fsp = aio_ex->fsp; char *outbuf = aio_ex->outbuf; - const char *inbuf = aio_ex->inbuf; ssize_t numtowrite = aio_ex->acb.aio_nbytes; ssize_t nwritten = SMB_VFS_AIO_RETURN(fsp,&aio_ex->acb); diff --git a/source3/smbd/close.c b/source3/smbd/close.c index f67a4ad6683..4c385d76118 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -252,6 +252,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, DEBUG(5,("close_remove_share_mode: file %s. " "Change user to uid %u\n", + fsp->fsp_name, (unsigned int)lck->delete_token->uid)); if (!push_sec_ctx()) { diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 04e3167e77a..ca6f8bfd8dc 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -142,8 +142,7 @@ static void dptr_idle(struct dptr_struct *dptr) { if (dptr->dir_hnd) { DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum)); - CloseDir(dptr->dir_hnd); - dptr->dir_hnd = NULL; + TALLOC_FREE(dptr->dir_hnd); } } @@ -192,7 +191,9 @@ static struct dptr_struct *dptr_get(int key, bool forclose) if (dirhandles_open >= MAX_OPEN_DIRECTORIES) dptr_idleoldest(); DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); - if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path, dptr->wcard, dptr->attr))) { + if (!(dptr->dir_hnd = OpenDir( + NULL, dptr->conn, dptr->path, + dptr->wcard, dptr->attr))) { DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path, strerror(errno))); return False; @@ -263,9 +264,7 @@ static void dptr_close_internal(struct dptr_struct *dptr) bitmap_clear(dptr_bmap, dptr->dnum - 1); - if (dptr->dir_hnd) { - CloseDir(dptr->dir_hnd); - } + TALLOC_FREE(dptr->dir_hnd); /* Lanman 2 specific code */ SAFE_FREE(dptr->wcard); @@ -411,7 +410,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, return status; } - dir_hnd = OpenDir(conn, path, wcard, attr); + dir_hnd = OpenDir(NULL, conn, path, wcard, attr); if (!dir_hnd) { return map_nt_error_from_unix(errno); } @@ -425,7 +424,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, dptr = SMB_MALLOC_P(struct dptr_struct); if(!dptr) { DEBUG(0,("malloc fail in dptr_create.\n")); - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return NT_STATUS_NO_MEMORY; } @@ -455,7 +454,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, if(dptr->dnum == -1 || dptr->dnum > 254) { DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum)); SAFE_FREE(dptr); - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return NT_STATUS_TOO_MANY_OPENED_FILES; } } @@ -485,7 +484,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, if(dptr->dnum == -1 || dptr->dnum < 255) { DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum)); SAFE_FREE(dptr); - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return NT_STATUS_TOO_MANY_OPENED_FILES; } } @@ -504,7 +503,7 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, if (!dptr->wcard) { bitmap_clear(dptr_bmap, dptr->dnum - 1); SAFE_FREE(dptr); - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return NT_STATUS_NO_MEMORY; } if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { @@ -533,7 +532,8 @@ NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, int dptr_CloseDir(struct dptr_struct *dptr) { DLIST_REMOVE(dirptrs, dptr); - return CloseDir(dptr->dir_hnd); + TALLOC_FREE(dptr->dir_hnd); + return 0; } void dptr_SeekDir(struct dptr_struct *dptr, long offset) @@ -1113,72 +1113,53 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, const char * return True; } +static int smb_Dir_destructor(struct smb_Dir *dirp) +{ + if (dirp->dir) { + SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); + } + dirhandles_open--; + return 0; +} + /******************************************************************* Open a directory. ********************************************************************/ -struct smb_Dir *OpenDir(connection_struct *conn, const char *name, const char *mask, uint32 attr) +struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, + const char *name, const char *mask, uint32 attr) { - struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir); + struct smb_Dir *dirp = TALLOC_ZERO_P(mem_ctx, struct smb_Dir); if (!dirp) { return NULL; } - ZERO_STRUCTP(dirp); dirp->conn = conn; dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); - dirp->dir_path = SMB_STRDUP(name); + dirp->dir_path = talloc_strdup(dirp, name); if (!dirp->dir_path) { goto fail; } + + dirhandles_open++; + talloc_set_destructor(dirp, smb_Dir_destructor); + dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); if (!dirp->dir) { - DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, strerror(errno) )); + DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, + strerror(errno) )); goto fail; } - dirhandles_open++; return dirp; fail: - - if (dirp) { - if (dirp->dir) { - SMB_VFS_CLOSEDIR(conn,dirp->dir); - } - SAFE_FREE(dirp->dir_path); - SAFE_FREE(dirp->name_cache); - SAFE_FREE(dirp); - } + TALLOC_FREE(dirp); return NULL; } - -/******************************************************************* - Close a directory. -********************************************************************/ - -int CloseDir(struct smb_Dir *dirp) -{ - int i, ret = 0; - - if (dirp->dir) { - ret = SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); - } - SAFE_FREE(dirp->dir_path); - if (dirp->name_cache) { - for (i = 0; i < dirp->name_cache_size; i++) { - SAFE_FREE(dirp->name_cache[i].name); - } - } - SAFE_FREE(dirp->name_cache); - SAFE_FREE(dirp); - dirhandles_open--; - return ret; -} - /******************************************************************* Read from a directory. Also return current offset. Don't check for veto or invisible files. @@ -1290,8 +1271,8 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset) } if (dirp->name_cache == NULL) { - dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, - dirp->name_cache_size); + dirp->name_cache = TALLOC_ZERO_ARRAY( + dirp, struct name_cache_entry, dirp->name_cache_size); if (dirp->name_cache == NULL) { return; @@ -1301,8 +1282,8 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset) dirp->name_cache_index = (dirp->name_cache_index+1) % dirp->name_cache_size; e = &dirp->name_cache[dirp->name_cache_index]; - SAFE_FREE(e->name); - e->name = SMB_STRDUP(name); + TALLOC_FREE(e->name); + e->name = talloc_strdup(dirp, name); e->offset = offset; } @@ -1359,7 +1340,8 @@ NTSTATUS can_delete_directory(struct connection_struct *conn, NTSTATUS status = NT_STATUS_OK; long dirpos = 0; const char *dname; - struct smb_Dir *dir_hnd = OpenDir(conn, dirname, NULL, 0); + struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, dirname, + NULL, 0); if (!dir_hnd) { return map_nt_error_from_unix(errno); @@ -1383,7 +1365,7 @@ NTSTATUS can_delete_directory(struct connection_struct *conn, status = NT_STATUS_DIRECTORY_NOT_EMPTY; break; } - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return status; } diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 5ae193fb46b..be4960cab81 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -778,7 +778,7 @@ static bool scan_directory(connection_struct *conn, const char *path, } /* open the directory */ - if (!(cur_dir = OpenDir(conn, path, NULL, 0))) { + if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); TALLOC_FREE(unmangled_name); return(False); @@ -809,7 +809,7 @@ static bool scan_directory(connection_struct *conn, const char *path, /* we've found the file, change it's name and return */ *found_name = talloc_strdup(ctx,dname); TALLOC_FREE(unmangled_name); - CloseDir(cur_dir); + TALLOC_FREE(cur_dir); if (!*found_name) { errno = ENOMEM; return False; @@ -819,7 +819,7 @@ static bool scan_directory(connection_struct *conn, const char *path, } TALLOC_FREE(unmangled_name); - CloseDir(cur_dir); + TALLOC_FREE(cur_dir); errno = ENOENT; return False; } diff --git a/source3/smbd/mangle_hash2.c b/source3/smbd/mangle_hash2.c index 9643506aea7..a9b94aabc38 100644 --- a/source3/smbd/mangle_hash2.c +++ b/source3/smbd/mangle_hash2.c @@ -396,7 +396,7 @@ static bool lookup_name_from_8_3(TALLOC_CTX *ctx, TALLOC_FREE(prefix); - if (!pp_out) { + if (!*pp_out) { M_DEBUG(0,("talloc_fail")); return False; } diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index 5c26cac2192..55009ce0b1c 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -235,6 +235,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter, return NT_STATUS_NO_MEMORY; } + ZERO_STRUCT(e); e.path = fullpath; e.filter = filter; e.subdir_filter = 0; diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 59699dfbd0f..9d48bcc98b5 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -598,12 +598,6 @@ static NTSTATUS open_mode_check(connection_struct *conn, } *file_existed = True; - - if (is_stat_open(access_mask)) { - /* Stat open that doesn't trigger oplock breaks or share mode - * checks... ! JRA. */ - return NT_STATUS_OK; - } /* A delete on close prohibits everything */ @@ -611,6 +605,12 @@ static NTSTATUS open_mode_check(connection_struct *conn, return NT_STATUS_DELETE_PENDING; } + if (is_stat_open(access_mask)) { + /* Stat open that doesn't trigger oplock breaks or share mode + * checks... ! JRA. */ + return NT_STATUS_OK; + } + /* * Check if the share modes will give us access. */ @@ -1761,14 +1761,16 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, the kernel refuses the operations then the kernel is wrong. note that GPFS supports it as well - jmcd */ - ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access); - if(ret_flock == -1 ){ + if (fsp->fh->fd != -1) { + ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access); + if(ret_flock == -1 ){ - TALLOC_FREE(lck); - fd_close(fsp); - file_free(fsp); - - return NT_STATUS_SHARING_VIOLATION; + TALLOC_FREE(lck); + fd_close(fsp); + file_free(fsp); + + return NT_STATUS_SHARING_VIOLATION; + } } /* diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 2d3cf7fbd8d..a5bdb966503 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -2085,7 +2085,7 @@ void smbd_process(void) run_events(smbd_event_context(), 0, NULL, NULL); - while (!receive_message_or_smb(NULL, &inbuf, &inbuf_len, + while (!receive_message_or_smb(talloc_tos(), &inbuf, &inbuf_len, select_timeout, &unread_bytes, &encrypted)) { diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 8149f5aeb66..e2316ef1200 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2410,7 +2410,8 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, return status; } - dir_hnd = OpenDir(conn, directory, mask, dirtype); + dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, + dirtype); if (dir_hnd == NULL) { return map_nt_error_from_unix(errno); } @@ -2448,7 +2449,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, status = check_name(conn, fname); if (!NT_STATUS_IS_OK(status)) { - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return status; } @@ -2464,7 +2465,7 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req, TALLOC_FREE(fname); } - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); } if (count == 0 && NT_STATUS_IS_OK(status)) { @@ -4901,7 +4902,8 @@ static bool recursive_rmdir(TALLOC_CTX *ctx, const char *dname = NULL; bool ret = True; long offset = 0; - struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0); + struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, directory, + NULL, 0); if(dir_hnd == NULL) return False; @@ -4949,7 +4951,7 @@ static bool recursive_rmdir(TALLOC_CTX *ctx, } TALLOC_FREE(fullname); } - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); return ret; } @@ -4997,7 +4999,8 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, */ const char *dname; long dirpos = 0; - struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0); + struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, + directory, NULL, 0); if(dir_hnd == NULL) { errno = ENOTEMPTY; @@ -5010,7 +5013,7 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, if (!is_visible_file(conn, directory, dname, &st, False)) continue; if(!IS_VETO_PATH(conn, dname)) { - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); errno = ENOTEMPTY; goto err; } @@ -5055,7 +5058,7 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, } TALLOC_FREE(fullname); } - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); /* Retry the rmdir */ ret = SMB_VFS_RMDIR(conn,directory); } @@ -5751,7 +5754,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, return status; } - dir_hnd = OpenDir(conn, directory, mask, attrs); + dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, attrs); if (dir_hnd == NULL) { return map_nt_error_from_unix(errno); } @@ -5851,7 +5854,7 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, TALLOC_FREE(fname); TALLOC_FREE(destname); } - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); if (count == 0 && NT_STATUS_IS_OK(status)) { status = map_nt_error_from_unix(errno); @@ -6325,7 +6328,7 @@ void reply_copy(struct smb_request *req) return; } - dir_hnd = OpenDir(conn, directory, mask, 0); + dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, 0); if (dir_hnd == NULL) { status = map_nt_error_from_unix(errno); reply_nterror(req, status); @@ -6357,7 +6360,7 @@ void reply_copy(struct smb_request *req) directory, dname); if (!fname) { - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBcopy); return; @@ -6368,7 +6371,7 @@ void reply_copy(struct smb_request *req) continue; } if (!destname) { - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBcopy); return; @@ -6376,7 +6379,7 @@ void reply_copy(struct smb_request *req) status = check_name(conn, fname); if (!NT_STATUS_IS_OK(status)) { - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); reply_nterror(req, status); END_PROFILE(SMBcopy); return; @@ -6384,7 +6387,7 @@ void reply_copy(struct smb_request *req) status = check_name(conn, destname); if (!NT_STATUS_IS_OK(status)) { - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); reply_nterror(req, status); END_PROFILE(SMBcopy); return; @@ -6400,7 +6403,7 @@ void reply_copy(struct smb_request *req) TALLOC_FREE(fname); TALLOC_FREE(destname); } - CloseDir(dir_hnd); + TALLOC_FREE(dir_hnd); } if (count == 0) { diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index bc1d26faca2..aee8e498e9d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -259,7 +259,7 @@ static void reply_spnego_kerberos(struct smb_request *req, fstring user; int sess_vuid = req->vuid; NTSTATUS ret = NT_STATUS_OK; - PAC_DATA *pac_data; + PAC_DATA *pac_data = NULL; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; DATA_BLOB session_key = data_blob_null; @@ -271,7 +271,6 @@ static void reply_spnego_kerberos(struct smb_request *req, PAC_LOGON_INFO *logon_info = NULL; ZERO_STRUCT(ticket); - ZERO_STRUCT(pac_data); ZERO_STRUCT(ap_rep); ZERO_STRUCT(ap_rep_wrapped); ZERO_STRUCT(response); diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 80f6ba9001a..0a9020bcfd2 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1294,14 +1294,13 @@ static bool net_derive_salting_principal( TALLOC_CTX *ctx, ADS_STRUCT *ads ) #if defined(WITH_DNS_UPDATES) #include "dns.h" DNS_ERROR DoDNSUpdate(char *pszServerName, - const char *pszDomainName, - const char *pszHostName, - const struct in_addr *iplist, int num_addrs ); - + const char *pszDomainName, const char *pszHostName, + const struct sockaddr_storage *sslist, + size_t num_addrs ); static NTSTATUS net_update_dns_internal(TALLOC_CTX *ctx, ADS_STRUCT *ads, const char *machine_name, - const struct in_addr *addrs, + const struct sockaddr_storage *addrs, int num_addrs) { struct dns_rr_ns *nameservers = NULL; @@ -1390,7 +1389,7 @@ done: static NTSTATUS net_update_dns(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads) { int num_addrs; - struct in_addr *iplist = NULL; + struct sockaddr_storage *iplist = NULL; fstring machine_name; NTSTATUS status; diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c index 38cdeacc112..26ed41b2a05 100644 --- a/source3/utils/net_conf.c +++ b/source3/utils/net_conf.c @@ -31,9 +31,11 @@ #include "utils/net.h" #include "libnet/libnet.h" -/* +/********************************************************************** + * * usage functions - */ + * + **********************************************************************/ static int net_conf_list_usage(int argc, const char **argv) { @@ -109,10 +111,16 @@ static int net_conf_delparm_usage(int argc, const char **argv) } -/* +/********************************************************************** + * * Helper functions - */ + * + **********************************************************************/ +/** + * This formats an in-memory smbconf parameter to a string. + * The result string is allocated with talloc. + */ static char *parm_valstr(TALLOC_CTX *ctx, struct parm_struct *parm, struct share_params *share) { @@ -187,7 +195,12 @@ static char *parm_valstr(TALLOC_CTX *ctx, struct parm_struct *parm, return valstr; } +/** + * This functions imports a configuration that has previously + * been loaded with lp_load() to registry. + */ static int import_process_service(TALLOC_CTX *ctx, + struct libnet_conf_ctx *conf_ctx, struct share_params *share) { int ret = -1; @@ -210,12 +223,16 @@ static int import_process_service(TALLOC_CTX *ctx, if (opt_testmode) { d_printf("[%s]\n", servicename); } else { - if (libnet_conf_share_exists(servicename)) { - werr = libnet_conf_delete_share(servicename); + if (libnet_conf_share_exists(conf_ctx, servicename)) { + werr = libnet_conf_delete_share(conf_ctx, servicename); if (!W_ERROR_IS_OK(werr)) { goto done; } } + werr = libnet_conf_create_share(conf_ctx, servicename); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } } while ((parm = lp_next_parameter(share->service, &pnum, 0))) @@ -232,7 +249,8 @@ static int import_process_service(TALLOC_CTX *ctx, if (opt_testmode) { d_printf("\t%s = %s\n", parm->label, valstr); } else { - werr = libnet_conf_set_parameter(servicename, + werr = libnet_conf_set_parameter(conf_ctx, + servicename, parm->label, valstr); if (!W_ERROR_IS_OK(werr)) { @@ -257,7 +275,10 @@ done: return ret; } -/* return true iff there are nondefault globals */ +/** + * Return true iff there are nondefault globals in the + * currently loaded configuration. + */ static bool globals_exist(void) { int i = 0; @@ -271,11 +292,15 @@ static bool globals_exist(void) return false; } -/* - * the conf functions - */ -static int net_conf_list(int argc, const char **argv) +/********************************************************************** + * + * the main conf functions + * + **********************************************************************/ + +static int net_conf_list(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { WERROR werr = WERR_OK; int ret = -1; @@ -294,9 +319,8 @@ static int net_conf_list(int argc, const char **argv) goto done; } - werr = libnet_conf_get_config(ctx, &num_shares, &share_names, - &num_params, ¶m_names, - ¶m_values); + werr = libnet_conf_get_config(ctx, conf_ctx, &num_shares, &share_names, + &num_params, ¶m_names, ¶m_values); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error getting config: %s\n", dos_errstr(werr)); @@ -322,7 +346,8 @@ done: return ret; } -static int net_conf_import(int argc, const char **argv) +static int net_conf_import(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { int ret = -1; const char *filename = NULL; @@ -369,7 +394,7 @@ static int net_conf_import(int argc, const char **argv) strequal(servicename, GLOBAL_NAME)) { service_found = true; - if (import_process_service(ctx, &global_share) != 0) { + if (import_process_service(ctx, conf_ctx, &global_share) != 0) { goto done; } } @@ -388,7 +413,7 @@ static int net_conf_import(int argc, const char **argv) || strequal(servicename, lp_servicename(share->service))) { service_found = true; - if (import_process_service(ctx, share)!= 0) { + if (import_process_service(ctx, conf_ctx, share)!= 0) { goto done; } } @@ -408,7 +433,8 @@ done: return ret; } -static int net_conf_listshares(int argc, const char **argv) +static int net_conf_listshares(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { WERROR werr = WERR_OK; int ret = -1; @@ -423,7 +449,8 @@ static int net_conf_listshares(int argc, const char **argv) goto done; } - werr = libnet_conf_get_share_names(ctx, &num_shares, &share_names); + werr = libnet_conf_get_share_names(ctx, conf_ctx, &num_shares, + &share_names); if (!W_ERROR_IS_OK(werr)) { goto done; } @@ -440,7 +467,8 @@ done: return ret; } -static int net_conf_drop(int argc, const char **argv) +static int net_conf_drop(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { int ret = -1; WERROR werr; @@ -450,7 +478,7 @@ static int net_conf_drop(int argc, const char **argv) goto done; } - werr = libnet_conf_drop(); + werr = libnet_conf_drop(conf_ctx); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error deleting configuration: %s\n", dos_errstr(werr)); @@ -463,7 +491,8 @@ done: return ret; } -static int net_conf_showshare(int argc, const char **argv) +static int net_conf_showshare(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { int ret = -1; WERROR werr = WERR_OK; @@ -483,7 +512,7 @@ static int net_conf_showshare(int argc, const char **argv) sharename = argv[0]; - werr = libnet_conf_get_share(ctx, sharename, &num_params, + werr = libnet_conf_get_share(ctx, conf_ctx, sharename, &num_params, ¶m_names, ¶m_values); if (!W_ERROR_IS_OK(werr)) { d_printf("error getting share parameters: %s\n", @@ -511,7 +540,8 @@ done: * This is a high level utility function of the net conf utility, * not a direct frontend to the libnet_conf API. */ -static int net_conf_addshare(int argc, const char **argv) +static int net_conf_addshare(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { int ret = -1; WERROR werr = WERR_OK; @@ -599,7 +629,7 @@ static int net_conf_addshare(int argc, const char **argv) goto done; } - if (libnet_conf_share_exists(sharename)) { + if (libnet_conf_share_exists(conf_ctx, sharename)) { d_fprintf(stderr, "ERROR: share %s already exists.\n", sharename); goto done; @@ -634,7 +664,7 @@ static int net_conf_addshare(int argc, const char **argv) * create the share */ - werr = libnet_conf_create_share(sharename); + werr = libnet_conf_create_share(conf_ctx, sharename); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error creating share %s: %s\n", sharename, dos_errstr(werr)); @@ -645,7 +675,7 @@ static int net_conf_addshare(int argc, const char **argv) * fill the share with parameters */ - werr = libnet_conf_set_parameter(sharename, "path", path); + werr = libnet_conf_set_parameter(conf_ctx, sharename, "path", path); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting parameter %s: %s\n", "path", dos_errstr(werr)); @@ -653,7 +683,8 @@ static int net_conf_addshare(int argc, const char **argv) } if (comment != NULL) { - werr = libnet_conf_set_parameter(sharename, "comment", comment); + werr = libnet_conf_set_parameter(conf_ctx, sharename, "comment", + comment); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting parameter %s: %s\n", "comment", dos_errstr(werr)); @@ -661,14 +692,16 @@ static int net_conf_addshare(int argc, const char **argv) } } - werr = libnet_conf_set_parameter(sharename, "guest ok", guest_ok); + werr = libnet_conf_set_parameter(conf_ctx, sharename, "guest ok", + guest_ok); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting parameter %s: %s\n", "'guest ok'", dos_errstr(werr)); goto done; } - werr = libnet_conf_set_parameter(sharename, "writeable", writeable); + werr = libnet_conf_set_parameter(conf_ctx, sharename, "writeable", + writeable); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting parameter %s: %s\n", "writeable", dos_errstr(werr)); @@ -682,7 +715,8 @@ done: return ret; } -static int net_conf_delshare(int argc, const char **argv) +static int net_conf_delshare(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { int ret = -1; const char *sharename = NULL; @@ -694,7 +728,7 @@ static int net_conf_delshare(int argc, const char **argv) } sharename = argv[0]; - werr = libnet_conf_delete_share(sharename); + werr = libnet_conf_delete_share(conf_ctx, sharename); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error deleting share %s: %s\n", sharename, dos_errstr(werr)); @@ -706,7 +740,8 @@ done: return ret; } -static int net_conf_setparm(int argc, const char **argv) +static int net_conf_setparm(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { int ret = -1; WERROR werr = WERR_OK; @@ -722,8 +757,8 @@ static int net_conf_setparm(int argc, const char **argv) param = strdup_lower(argv[1]); value_str = argv[2]; - if (!libnet_conf_share_exists(service)) { - werr = libnet_conf_create_share(service); + if (!libnet_conf_share_exists(conf_ctx, service)) { + werr = libnet_conf_create_share(conf_ctx, service); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error creating share '%s': %s\n", service, dos_errstr(werr)); @@ -731,7 +766,7 @@ static int net_conf_setparm(int argc, const char **argv) } } - werr = libnet_conf_set_parameter(service, param, value_str); + werr = libnet_conf_set_parameter(conf_ctx, service, param, value_str); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting value '%s': %s\n", @@ -747,7 +782,8 @@ done: return ret; } -static int net_conf_getparm(int argc, const char **argv) +static int net_conf_getparm(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { int ret = -1; WERROR werr = WERR_OK; @@ -765,7 +801,7 @@ static int net_conf_getparm(int argc, const char **argv) service = strdup_lower(argv[0]); param = strdup_lower(argv[1]); - werr = libnet_conf_get_parameter(ctx, service, param, &valstr); + werr = libnet_conf_get_parameter(ctx, conf_ctx, service, param, &valstr); if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) { d_fprintf(stderr, @@ -793,7 +829,8 @@ done: return ret; } -static int net_conf_delparm(int argc, const char **argv) +static int net_conf_delparm(struct libnet_conf_ctx *conf_ctx, + int argc, const char **argv) { int ret = -1; WERROR werr = WERR_OK; @@ -807,7 +844,7 @@ static int net_conf_delparm(int argc, const char **argv) service = strdup_lower(argv[0]); param = strdup_lower(argv[1]); - werr = libnet_conf_delete_parameter(service, param); + werr = libnet_conf_delete_parameter(conf_ctx, service, param); if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) { d_fprintf(stderr, @@ -833,6 +870,78 @@ done: return ret; } + +/********************************************************************** + * + * Wrapper and net_conf_run_function mechanism. + * + **********************************************************************/ + +/** + * Wrapper function to call the main conf functions. + * The wrapper calls handles opening and closing of the + * configuration. + */ +static int net_conf_wrap_function(int (*fn)(struct libnet_conf_ctx *, + int, const char **), + int argc, const char **argv) +{ + WERROR werr; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + struct libnet_conf_ctx *conf_ctx; + int ret = -1; + + werr = libnet_conf_open(mem_ctx, &conf_ctx); + + if (!W_ERROR_IS_OK(werr)) { + return -1; + } + + ret = fn(conf_ctx, argc, argv); + + libnet_conf_close(conf_ctx); + + return ret; +} + +/* + * We need a functable struct of our own, because the + * functions are called through a wrapper that handles + * the opening and closing of the configuration, and so on. + */ +struct conf_functable { + const char *funcname; + int (*fn)(struct libnet_conf_ctx *ctx, int argc, const char **argv); + const char *helptext; +}; + +/** + * This imitates net_run_function2 but calls the main functions + * through the wrapper net_conf_wrap_function(). + */ +static int net_conf_run_function(int argc, const char **argv, + const char *whoami, + struct conf_functable *table) +{ + int i; + + if (argc != 0) { + for (i=0; table[i].funcname; i++) { + if (StrCaseCmp(argv[0], table[i].funcname) == 0) + return net_conf_wrap_function(table[i].fn, + argc-1, + argv+1); + } + } + + for (i=0; table[i].funcname; i++) { + d_printf("%s %-15s %s\n", whoami, table[i].funcname, + table[i].helptext); + } + + return -1; +} + /* * Entry-point for all the CONF functions. */ @@ -840,7 +949,7 @@ done: int net_conf(int argc, const char **argv) { int ret = -1; - struct functable2 func[] = { + struct conf_functable func_table[] = { {"list", net_conf_list, "Dump the complete configuration in smb.conf like format."}, {"import", net_conf_import, @@ -864,7 +973,7 @@ int net_conf(int argc, const char **argv) {NULL, NULL, NULL} }; - ret = net_run_function2(argc, argv, "net conf", func); + ret = net_conf_run_function(argc, argv, "net conf", func_table); return ret; } diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c index 44a0b46e4ea..fb6644d6b24 100644 --- a/source3/utils/net_dns.c +++ b/source3/utils/net_dns.c @@ -32,7 +32,8 @@ DNS_ERROR DoDNSUpdate(char *pszServerName, const char *pszDomainName, const char *pszHostName, - const struct sockaddr_storage *sslist, size_t num_addrs ); + const struct sockaddr_storage *sslist, + size_t num_addrs ); /********************************************************************* *********************************************************************/ diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 155cda64dfe..2bd867fff3f 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -5850,24 +5850,30 @@ static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd, const char *trusted_dom_name) { NTSTATUS nt_status; - LSA_TRUSTED_DOMAIN_INFO *info; + union lsa_TrustedDomainInfo info; char *cleartextpwd = NULL; DATA_BLOB data; - nt_status = rpccli_lsa_query_trusted_domain_info_by_sid(pipe_hnd, mem_ctx, pol, 4, &dom_sid, &info); - + nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx, + pol, + &dom_sid, + LSA_TRUSTED_DOMAIN_INFO_PASSWORD, + &info); if (NT_STATUS_IS_ERR(nt_status)) { DEBUG(0,("Could not query trusted domain info. Error was %s\n", nt_errstr(nt_status))); goto done; } - data = data_blob(NULL, info->password.password.length); + data = data_blob(NULL, info.password.password->length); - memcpy(data.data, info->password.password.data, info->password.password.length); - data.length = info->password.password.length; - - cleartextpwd = decrypt_trustdom_secret(pipe_hnd->cli->pwd.password, &data); + memcpy(data.data, + info.password.password->data, + info.password.password->length); + data.length = info.password.password->length; + + cleartextpwd = decrypt_trustdom_secret(pipe_hnd->cli->pwd.password, + &data); if (cleartextpwd == NULL) { DEBUG(0,("retrieved NULL password\n")); diff --git a/source3/utils/net_rpc_audit.c b/source3/utils/net_rpc_audit.c index b7fda2b8e37..50bd555f16e 100644 --- a/source3/utils/net_rpc_audit.c +++ b/source3/utils/net_rpc_audit.c @@ -1,21 +1,21 @@ -/* - Samba Unix/Linux SMB client library - Distributed SMB/CIFS Server Management Utility +/* + Samba Unix/Linux SMB client library + Distributed SMB/CIFS Server Management Utility Copyright (C) 2006 Guenther Deschner 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 "utils/net.h" @@ -54,29 +54,26 @@ static void print_auditing_category(const char *policy, const char *value) pad_len = col_len - strlen(policy); padding[pad_len] = 0; do padding[--pad_len] = ' '; while (pad_len > 0); - + d_printf("\t%s%s%s\n", policy, padding, value); } - /******************************************************************** ********************************************************************/ static NTSTATUS rpc_audit_get_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - LSA_INFO_CTR dom; + union lsa_PolicyInformation info; int i; - - uint32 info_class = 2; - uint32 audit_category; + uint32_t audit_category; if (argc < 1 || argc > 2) { d_printf("insufficient arguments\n"); @@ -89,7 +86,7 @@ static NTSTATUS rpc_audit_get_internal(const DOM_SID *domain_sid, return NT_STATUS_INVALID_PARAMETER; } - result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, + result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); @@ -97,15 +94,16 @@ static NTSTATUS rpc_audit_get_internal(const DOM_SID *domain_sid, goto done; } - result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, - info_class, - &dom); + result = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, + &pol, + LSA_POLICY_INFO_AUDIT_EVENTS, + &info); if (!NT_STATUS_IS_OK(result)) { goto done; } - for (i=0; i < dom.info.id2.count1; i++) { + for (i=0; i < info.audit_events.count; i++) { const char *val = NULL, *policy = NULL; @@ -113,14 +111,15 @@ static NTSTATUS rpc_audit_get_internal(const DOM_SID *domain_sid, continue; } - val = audit_policy_str(mem_ctx, dom.info.id2.auditsettings[i]); + val = audit_policy_str(mem_ctx, info.audit_events.settings[i]); policy = audit_description_str(i); print_auditing_category(policy, val); } done: if (!NT_STATUS_IS_OK(result)) { - d_printf("failed to get auditing policy: %s\n", nt_errstr(result)); + d_printf("failed to get auditing policy: %s\n", + nt_errstr(result)); } return result; @@ -130,19 +129,17 @@ static NTSTATUS rpc_audit_get_internal(const DOM_SID *domain_sid, ********************************************************************/ static NTSTATUS rpc_audit_set_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - LSA_INFO_CTR dom; - - uint32 info_class = 2; - uint32 audit_policy, audit_category; + union lsa_PolicyInformation info; + uint32_t audit_policy, audit_category; if (argc < 2 || argc > 3) { d_printf("insufficient arguments\n"); @@ -170,7 +167,7 @@ static NTSTATUS rpc_audit_set_internal(const DOM_SID *domain_sid, return NT_STATUS_INVALID_PARAMETER; } - result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, + result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); @@ -178,29 +175,32 @@ static NTSTATUS rpc_audit_set_internal(const DOM_SID *domain_sid, goto done; } - result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, - info_class, - &dom); + result = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, + &pol, + LSA_POLICY_INFO_AUDIT_EVENTS, + &info); if (!NT_STATUS_IS_OK(result)) { goto done; } - dom.info.id2.auditsettings[audit_category] = audit_policy; + info.audit_events.settings[audit_category] = audit_policy; + + result = rpccli_lsa_SetInfoPolicy(pipe_hnd, mem_ctx, + &pol, + LSA_POLICY_INFO_AUDIT_EVENTS, + &info); - result = rpccli_lsa_set_info_policy(pipe_hnd, mem_ctx, &pol, - info_class, - dom); if (!NT_STATUS_IS_OK(result)) { goto done; } - result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, - info_class, - &dom); - + result = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, + &pol, + LSA_POLICY_INFO_AUDIT_EVENTS, + &info); { - const char *val = audit_policy_str(mem_ctx, dom.info.id2.auditsettings[audit_category]); + const char *val = audit_policy_str(mem_ctx, info.audit_events.settings[audit_category]); const char *policy = audit_description_str(audit_category); print_auditing_category(policy, val); } @@ -209,11 +209,14 @@ static NTSTATUS rpc_audit_set_internal(const DOM_SID *domain_sid, if (!NT_STATUS_IS_OK(result)) { d_printf("failed to set audit policy: %s\n", nt_errstr(result)); } - + return result; } -static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd, +/******************************************************************** +********************************************************************/ + +static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, int argc, const char **argv, @@ -221,11 +224,9 @@ static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd, { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - LSA_INFO_CTR dom; - - uint32 info_class = 2; + union lsa_PolicyInformation info; - result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, + result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); @@ -233,19 +234,20 @@ static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd, goto done; } - result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, - info_class, - &dom); - + result = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, + &pol, + LSA_POLICY_INFO_AUDIT_EVENTS, + &info); if (!NT_STATUS_IS_OK(result)) { goto done; } - dom.info.id2.auditing_enabled = enable; + info.audit_events.auditing_mode = enable; - result = rpccli_lsa_set_info_policy(pipe_hnd, mem_ctx, &pol, - info_class, - dom); + result = rpccli_lsa_SetInfoPolicy(pipe_hnd, mem_ctx, + &pol, + LSA_POLICY_INFO_AUDIT_EVENTS, + &info); if (!NT_STATUS_IS_OK(result)) { goto done; @@ -253,59 +255,60 @@ static NTSTATUS rpc_audit_enable_internal_ext(struct rpc_pipe_client *pipe_hnd, done: if (!NT_STATUS_IS_OK(result)) { - d_printf("failed to %s audit policy: %s\n", enable ? "enable":"disable", - nt_errstr(result)); + d_printf("failed to %s audit policy: %s\n", + enable ? "enable":"disable", nt_errstr(result)); } return result; } + /******************************************************************** ********************************************************************/ static NTSTATUS rpc_audit_disable_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv) { - return rpc_audit_enable_internal_ext(pipe_hnd, mem_ctx, argc, argv, False); + return rpc_audit_enable_internal_ext(pipe_hnd, mem_ctx, argc, argv, + false); } /******************************************************************** ********************************************************************/ static NTSTATUS rpc_audit_enable_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv) { - return rpc_audit_enable_internal_ext(pipe_hnd, mem_ctx, argc, argv, True); + return rpc_audit_enable_internal_ext(pipe_hnd, mem_ctx, argc, argv, + true); } /******************************************************************** ********************************************************************/ static NTSTATUS rpc_audit_list_internal(const DOM_SID *domain_sid, - const char *domain_name, + const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, int argc, const char **argv) { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - LSA_INFO_CTR dom; + union lsa_PolicyInformation info; int i; - uint32 info_class = 2; - - result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, + result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); @@ -313,53 +316,52 @@ static NTSTATUS rpc_audit_list_internal(const DOM_SID *domain_sid, goto done; } - result = rpccli_lsa_query_info_policy_new(pipe_hnd, mem_ctx, &pol, - info_class, - &dom); - + result = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, + &pol, + LSA_POLICY_INFO_AUDIT_EVENTS, + &info); if (!NT_STATUS_IS_OK(result)) { goto done; } printf("Auditing:\t\t"); - switch (dom.info.id2.auditing_enabled) { - case True: + switch (info.audit_events.auditing_mode) { + case true: printf("Enabled"); break; - case False: + case false: printf("Disabled"); break; default: - printf("unknown (%d)", dom.info.id2.auditing_enabled); + printf("unknown (%d)", info.audit_events.auditing_mode); break; } printf("\n"); - printf("Auditing categories:\t%d\n", dom.info.id2.count1); + printf("Auditing categories:\t%d\n", info.audit_events.count); printf("Auditing settings:\n"); - for (i=0; i < dom.info.id2.count1; i++) { - const char *val = audit_policy_str(mem_ctx, dom.info.id2.auditsettings[i]); + for (i=0; i < info.audit_events.count; i++) { + const char *val = audit_policy_str(mem_ctx, info.audit_events.settings[i]); const char *policy = audit_description_str(i); print_auditing_category(policy, val); } done: if (!NT_STATUS_IS_OK(result)) { - d_printf("failed to list auditing policies: %s\n", nt_errstr(result)); + d_printf("failed to list auditing policies: %s\n", + nt_errstr(result)); } return result; } - - /******************************************************************** ********************************************************************/ static int rpc_audit_get(int argc, const char **argv) { - return run_rpc_command(NULL, PI_LSARPC, 0, + return run_rpc_command(NULL, PI_LSARPC, 0, rpc_audit_get_internal, argc, argv); } @@ -368,7 +370,7 @@ static int rpc_audit_get(int argc, const char **argv) static int rpc_audit_set(int argc, const char **argv) { - return run_rpc_command(NULL, PI_LSARPC, 0, + return run_rpc_command(NULL, PI_LSARPC, 0, rpc_audit_set_internal, argc, argv); } @@ -377,7 +379,7 @@ static int rpc_audit_set(int argc, const char **argv) static int rpc_audit_enable(int argc, const char **argv) { - return run_rpc_command(NULL, PI_LSARPC, 0, + return run_rpc_command(NULL, PI_LSARPC, 0, rpc_audit_enable_internal, argc, argv); } @@ -386,7 +388,7 @@ static int rpc_audit_enable(int argc, const char **argv) static int rpc_audit_disable(int argc, const char **argv) { - return run_rpc_command(NULL, PI_LSARPC, 0, + return run_rpc_command(NULL, PI_LSARPC, 0, rpc_audit_disable_internal, argc, argv); } @@ -395,14 +397,14 @@ static int rpc_audit_disable(int argc, const char **argv) static int rpc_audit_list(int argc, const char **argv) { - return run_rpc_command(NULL, PI_LSARPC, 0, + return run_rpc_command(NULL, PI_LSARPC, 0, rpc_audit_list_internal, argc, argv); } /******************************************************************** ********************************************************************/ -int net_rpc_audit(int argc, const char **argv) +int net_rpc_audit(int argc, const char **argv) { struct functable func[] = { {"get", rpc_audit_get}, @@ -412,9 +414,9 @@ int net_rpc_audit(int argc, const char **argv) {"list", rpc_audit_list}, {NULL, NULL} }; - + if (argc) return net_run_function(argc, argv, func, net_help_audit); - + return net_help_audit(argc, argv); } diff --git a/source3/utils/net_rpc_rights.c b/source3/utils/net_rpc_rights.c index 23be8859e03..5f222b8c7e9 100644 --- a/source3/utils/net_rpc_rights.c +++ b/source3/utils/net_rpc_rights.c @@ -28,9 +28,9 @@ static NTSTATUS sid_to_name(struct rpc_pipe_client *pipe_hnd, fstring name) { POLICY_HND pol; - enum lsa_SidType *sid_types; + enum lsa_SidType *sid_types = NULL; NTSTATUS result; - char **domains, **names; + char **domains = NULL, **names = NULL; result = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); @@ -202,7 +202,7 @@ static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd, NTSTATUS result; uint32 enum_context=0; uint32 pref_max_length=0x1000; - DOM_SID *sids; + DOM_SID *sids = NULL; uint32 count=0; int i; fstring name; diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 7e2771c9003..6a702fc0cfa 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1163,6 +1163,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, char *principal; DATA_BLOB ap_rep; DATA_BLOB session_key; + PAC_DATA *pac_data = NULL; if ( request.negTokenInit.mechToken.data == NULL ) { DEBUG(1, ("Client did not provide Kerberos data\n")); @@ -1177,7 +1178,7 @@ static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, status = ads_verify_ticket(mem_ctx, lp_realm(), 0, &request.negTokenInit.mechToken, - &principal, NULL, &ap_rep, + &principal, &pac_data, &ap_rep, &session_key, True); talloc_destroy(mem_ctx); diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index f5e12264471..34ba0498e0a 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -308,7 +308,7 @@ NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain, { char **domains; char **names; - enum lsa_SidType *types; + enum lsa_SidType *types = NULL; NTSTATUS result; struct rpc_pipe_client *cli; POLICY_HND lsa_policy; |