diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-03-05 19:42:15 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-03-05 19:42:15 +0100 |
commit | 63036a6f3380652c0cb54627bdeabcd212fa2f8c (patch) | |
tree | 90194f23cb1e6ca483e7773233c326a9b705f85f /source3 | |
parent | d41d580c600e3228ff8fee5c16c47580f661a240 (diff) | |
parent | 932c287a406048759fa1ac4bf86e29d96991ded1 (diff) | |
download | samba-63036a6f3380652c0cb54627bdeabcd212fa2f8c.tar.gz samba-63036a6f3380652c0cb54627bdeabcd212fa2f8c.tar.bz2 samba-63036a6f3380652c0cb54627bdeabcd212fa2f8c.zip |
Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into v3-2-test
(This used to be commit 3482cd9b0e81bbc801f1cec33fca82fc45a3ddef)
Diffstat (limited to 'source3')
294 files changed, 38741 insertions, 30934 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index e0bb772f0e..cfe0095612 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -18,7 +18,7 @@ datarootdir=@datarootdir@ selftest_prefix=@selftest_prefix@ smbtorture4_path=@smbtorture4_path@ -LIBS=@LIBS@ @LIBTALLOC_LIBS@ +LIBS=@LIBS@ CC=@CC@ SHLD=@SHLD@ LIB_PATH_VAR=@LIB_PATH_VAR@ @@ -102,6 +102,7 @@ NSSINFOLIBDIR = $(LIBDIR)/nss_info CHARSETLIBDIR = $(LIBDIR)/charset AUTHLIBDIR = $(LIBDIR)/auth CONFIGLIBDIR = $(LIBDIR)/config +GPEXTLIBDIR = $(LIBDIR)/gpext CONFIGDIR = @configdir@ VARDIR = @localstatedir@ MANDIR = @mandir@ @@ -144,11 +145,21 @@ PIDDIR = @piddir@ LIBTALLOC_SHARED_TARGET=@LIBTALLOC_SHARED_TARGET@ LIBTALLOC_STATIC_TARGET=@LIBTALLOC_STATIC_TARGET@ LIBTALLOC=$(LIBTALLOC_STATIC_TARGET) @LIBTALLOC_SHARED@ + +LIBTDB_SHARED_TARGET=@LIBTDB_SHARED_TARGET@ +LIBTDB_STATIC_TARGET=@LIBTDB_STATIC_TARGET@ +LIBTDB=$(LIBTDB_STATIC_TARGET) @LIBTDB_SHARED@ +LIBTDB_SYMS=exports/libtdb.syms +LIBTDB_HEADERS=@tdbdir@/include/tdb.h + LIBSMBCLIENT=bin/libsmbclient.a @LIBSMBCLIENT_SHARED@ LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@ LIBADDNS=bin/libaddns.a @LIBADDNS_SHARED@ LIBWBCLIENT=@LIBWBCLIENT_SHARED@ -LIBNETAPI=bin/libnetapi.a @LIBNETAPI_SHARED@ + +LIBNETAPI_SHARED_TARGET=@LIBNETAPI_SHARED_TARGET@ +LIBNETAPI_STATIC_TARGET=@LIBNETAPI_STATIC_TARGET@ +LIBNETAPI=$(LIBNETAPI_STATIC_TARGET) @LIBNETAPI_SHARED@ FLAGS1 = $(CFLAGS) @FLAGS1@ @SAMBA_CPPFLAGS@ $(CPPFLAGS) FLAGS2 = @@ -198,15 +209,15 @@ TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \ bin/pdbtest@EXEEXT@ bin/talloctort@EXEEXT@ bin/replacetort@EXEEXT@ \ bin/tdbtorture@EXEEXT@ -BIN_PROGS = @EXTRA_BIN_PROGS@ @SMBMOUNT_PROGS@ \ +BIN_PROGS = @EXTRA_BIN_PROGS@ \ $(BIN_PROGS1) $(BIN_PROGS2) $(BIN_PROGS3) $(BIN_PROGS4) EVERYTHING_PROGS = bin/debug2html@EXEEXT@ bin/smbfilter@EXEEXT@ \ bin/talloctort@EXEEXT@ bin/replacetort@EXEEXT@ \ bin/log2pcap@EXEEXT@ bin/sharesec@EXEEXT@ bin/ndrdump@EXEEXT@ \ - bin/vlp@EXEEXT@ + bin/vlp@EXEEXT@ bin/smbiconv@EXEEXT@ -SHLIBS = libtalloc @LIBWBCLIENT@ @LIBSMBCLIENT@ @LIBSMBSHAREMODES@ @LIBADDNS@ @LIBNETAPI@ +SHLIBS = libtalloc libtdb @LIBWBCLIENT@ @LIBSMBCLIENT@ @LIBSMBSHAREMODES@ @LIBADDNS@ libnetapi PAM_MODULES = @PAM_MODULES@ @@ -221,21 +232,21 @@ IDMAP_MODULES = @IDMAP_MODULES@ CHARSET_MODULES = @CHARSET_MODULES@ AUTH_MODULES = @AUTH_MODULES@ NSS_INFO_MODULES = @NSS_INFO_MODULES@ +GPEXT_MODULES = @GPEXT_MODULES@ MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) \ - $(CHARSET_MODULES) $(AUTH_MODULES) $(NSS_INFO_MODULES) + $(CHARSET_MODULES) $(AUTH_MODULES) $(NSS_INFO_MODULES) \ + $(GPEXT_MODULES) ###################################################################### # object file lists ###################################################################### -TDBBASE_OBJ = lib/tdb/common/tdb.o lib/tdb/common/dump.o lib/tdb/common/error.o \ - lib/tdb/common/freelist.o lib/tdb/common/freelistcheck.o \ - lib/tdb/common/io.o lib/tdb/common/lock.o \ - lib/tdb/common/open.o lib/tdb/common/transaction.o \ - lib/tdb/common/traverse.o +LIBTDB_OBJ0 = @TDB_OBJS@ +LIBTDB_OBJ = $(LIBTDB_OBJ0) $(LIBREPLACE_OBJ) -TDB_OBJ = $(TDBBASE_OBJ) lib/util_tdb.o \ - lib/dbwrap.o lib/dbwrap_tdb.o lib/dbwrap_ctdb.o lib/dbwrap_rbt.o +TDB_OBJ = lib/util_tdb.o \ + lib/dbwrap.o lib/dbwrap_tdb.o lib/dbwrap_ctdb.o \ + lib/dbwrap_rbt.o @LIBTDB_STATIC@ SMBLDAP_OBJ = @SMBLDAP@ @SMBLDAPUTIL@ @@ -281,7 +292,8 @@ LIBNDR_GEN_OBJ = librpc/gen_ndr/ndr_wkssvc.o \ librpc/gen_ndr/ndr_samr.o \ librpc/gen_ndr/ndr_dssetup.o \ librpc/gen_ndr/ndr_notify.o \ - librpc/gen_ndr/ndr_xattr.o + librpc/gen_ndr/ndr_xattr.o \ + librpc/gen_ndr/ndr_ntsvcs.o RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o @@ -289,7 +301,11 @@ RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o # that requires knowledge of security contexts RPC_PARSE_OBJ1 = $(RPC_PARSE_OBJ0) rpc_parse/parse_sec.o -RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o rpc_parse/parse_net.o rpc_parse/parse_srv.o +RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o rpc_parse/parse_srv.o +RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o rpc_parse/parse_srv.o \ + rpc_client/init_netlogon.o \ + rpc_client/init_lsa.o \ + rpc_client/init_srvsvc.o LIBREPLACE_OBJ = @LIBREPLACE_OBJS@ @@ -300,7 +316,7 @@ TALLOC_OBJ = @TALLOC_OBJS@ LIBTALLOC_OBJ0 = $(TALLOC_OBJ) -LIBTALLOC_OBJ = $(LIBTALLOC_OBJ0) +LIBTALLOC_OBJ = $(LIBTALLOC_OBJ0) $(LIBREPLACE_OBJ) LIBSAMBAUTIL_OBJ = @LIBTALLOC_STATIC@ \ $(LIBREPLACE_OBJ) \ @@ -347,7 +363,7 @@ READLINE_OBJ = lib/readline.o POPT_LIB_OBJ = lib/popt_common.o PARAM_WITHOUT_REG_OBJ = dynconfig.o param/loadparm.o param/params.o param/util.o lib/sharesec.o lib/ldap_debug_handler.o -PARAM_REG_ADD_OBJ = $(UTIL_REG_API_OBJ) +PARAM_REG_ADD_OBJ = $(REG_SMBCONF_OBJ) $(LIBNET_CONF_OBJ) $(PRIVILEGES_BASIC_OBJ) PARAM_OBJ = $(PARAM_WITHOUT_REG_OBJ) $(PARAM_REG_ADD_OBJ) KRBCLIENT_OBJ = libads/kerberos.o libads/ads_status.o @@ -362,10 +378,16 @@ LIBWBCLIENT_OBJ0 = nsswitch/libwbclient/wbclient.o \ nsswitch/libwbclient/wbc_idmap.o \ nsswitch/libwbclient/wbc_sid.o \ nsswitch/libwbclient/wbc_pam.o -LIBWBCLIENT_OBJ = $(LIBWBCLIENT_OBJ0) $(WBCOMMON_OBJ) @LIBTALLOC_STATIC@ $(LIBREPLACE_OBJ) +LIBWBCLIENT_OBJ = $(LIBWBCLIENT_OBJ0) \ + $(WBCOMMON_OBJ) \ + @LIBTALLOC_STATIC@ $(LIBREPLACE_OBJ) + +GPEXT_OBJ = libgpo/gpext/gpext.o @GPEXT_STATIC@ 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 + libgpo/gpo_fetch.o libgpo/gpo_filesync.o libgpo/gpo_sec.o \ + libgpo/gpo_reg.o \ + $(GPEXT_OBJ) LIBGPO_OBJ = $(LIBGPO_OBJ0) LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o \ @@ -375,7 +397,9 @@ LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o \ libads/disp_sec.o libads/ads_utils.o libads/ldap_utils.o \ libads/cldap.o libads/ldap_schema.o libads/util.o libads/ndr.o -LIBADS_SERVER_OBJ = libads/kerberos_verify.o libads/authdata.o +LIBADS_SERVER_OBJ = libads/kerberos_verify.o libads/authdata.o \ + librpc/ndr/ndr_krb5pac.o \ + librpc/gen_ndr/ndr_krb5pac.o SECRETS_OBJ = passdb/secrets.o passdb/machine_sid.o @@ -403,8 +427,7 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \ $(RPC_CLIENT_OBJ1) rpc_client/cli_reg.o $(RPC_CLIENT_OBJ) \ rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \ rpc_client/cli_svcctl.o \ - rpc_client/init_samr.o \ - rpc_client/init_lsa.o + rpc_client/init_samr.o LIBMSRPC_GEN_OBJ = librpc/gen_ndr/cli_lsa.o \ librpc/gen_ndr/cli_dfs.o \ @@ -418,6 +441,7 @@ LIBMSRPC_GEN_OBJ = librpc/gen_ndr/cli_lsa.o \ librpc/gen_ndr/cli_netlogon.o \ librpc/gen_ndr/cli_samr.o \ librpc/gen_ndr/cli_dssetup.o \ + librpc/gen_ndr/cli_ntsvcs.o \ $(LIBNDR_GEN_OBJ) \ $(RPCCLIENT_NDR_OBJ) @@ -426,53 +450,52 @@ LIBMSRPC_GEN_OBJ = librpc/gen_ndr/cli_lsa.o \ # UTIL_REG_OBJ = lib/util_reg.o UTIL_REG_API_OBJ = lib/util_reg_api.o + REG_INIT_SMBCONF_OBJ = registry/reg_init_smbconf.o +REG_INIT_FULL_OBJ = registry/reg_init_full.o REGFIO_OBJ = registry/regfio.o REGOBJS_OBJ = registry/reg_objects.o -REGISTRY_BACKENDS = registry/reg_backend_printing.o \ - registry/reg_backend_db.o \ - registry/reg_backend_smbconf.o \ - registry/reg_backend_shares.o \ - registry/reg_backend_netlogon_params.o \ - registry/reg_backend_prod_options.o \ - registry/reg_backend_tcpip_params.o \ - registry/reg_backend_hkpt_params.o \ - registry/reg_backend_current_version.o \ - registry/reg_backend_perflib.o - - -REGISTRY_OBJ = registry/reg_init_full.o registry/reg_cachehook.o \ - registry/reg_eventlog.o \ - registry/reg_util.o registry/reg_perfcount.o \ - registry/reg_util_legacy.o \ - registry/reg_api.o \ +REG_BACKENDS_BASE_OBJ = registry/reg_backend_db.o + +REG_BACKENDS_SMBCONF_OBJ = registry/reg_backend_smbconf.o + +REG_BACKENDS_EXTRA_OBJ = registry/reg_backend_printing.o \ + registry/reg_backend_shares.o \ + registry/reg_backend_netlogon_params.o \ + registry/reg_backend_prod_options.o \ + registry/reg_backend_tcpip_params.o \ + registry/reg_backend_hkpt_params.o \ + registry/reg_backend_current_version.o \ + registry/reg_backend_perflib.o + +REG_BASE_OBJ = registry/reg_api.o \ registry/reg_dispatcher.o \ - $(REGISTRY_BACKENDS) \ + registry/reg_cachehook.o \ + $(REGFIO_OBJ) \ + $(REGOBJS_OBJ) \ + registry/reg_util.o \ $(UTIL_REG_API_OBJ) \ - $(REG_INIT_SMBCONF_OBJ) - -# objects to be used when not all of the registry code should be -# loaded but only the portion needed by reg_api, typically for -# using smbconf (registry) - full access -REG_API_OBJ = registry/reg_api.o \ - registry/reg_dispatcher.o \ - registry/reg_backend_smbconf.o \ - registry/reg_backend_db.o \ - registry/reg_util.o \ - \ - registry/reg_cachehook.o \ - \ - lib/util_nttoken.o \ - $(UTIL_REG_API_OBJ) \ - $(REG_INIT_SMBCONF_OBJ) - - -RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o - -RPC_NETLOG_OBJ = rpc_server/srv_netlog.o rpc_server/srv_netlog_nt.o \ + lib/util_nttoken.o \ + $(REG_BACKENDS_BASE_OBJ) + +REG_SMBCONF_OBJ = $(REG_BASE_OBJ) \ + $(REG_BACKENDS_SMBCONF_OBJ) \ + $(REG_INIT_SMBCONF_OBJ) + +REG_FULL_OBJ = $(REG_SMBCONF_OBJ) \ + $(REG_BACKENDS_EXTRA_OBJ) \ + $(REG_INIT_FULL_OBJ) \ + registry/reg_eventlog.o \ + registry/reg_perfcount.o \ + registry/reg_util_legacy.o + + +RPC_LSA_OBJ = rpc_server/srv_lsa_nt.o librpc/gen_ndr/srv_lsa.o + +RPC_NETLOG_OBJ = rpc_server/srv_netlog_nt.o \ librpc/gen_ndr/srv_netlogon.o RPC_SAMR_OBJ = rpc_server/srv_samr_nt.o \ @@ -482,8 +505,7 @@ RPC_SAMR_OBJ = rpc_server/srv_samr_nt.o \ RPC_INITSHUTDOWN_OBJ = librpc/gen_ndr/srv_initshutdown.o rpc_server/srv_initshutdown_nt.o RPC_REG_OBJ = rpc_server/srv_winreg_nt.o \ - librpc/gen_ndr/srv_winreg.o \ - $(REGFIO_OBJ) + librpc/gen_ndr/srv_winreg.o RPC_DSSETUP_OBJ = rpc_server/srv_dssetup_nt.o librpc/gen_ndr/srv_dssetup.o @@ -498,7 +520,8 @@ RPC_SVCCTL_OBJ = rpc_server/srv_svcctl.o rpc_server/srv_svcctl_nt.o \ services/svc_netlogon.o services/svc_winreg.o \ services/svc_wins.o -RPC_NTSVCS_OBJ = rpc_server/srv_ntsvcs.o rpc_server/srv_ntsvcs_nt.o +RPC_NTSVCS_OBJ = rpc_server/srv_ntsvcs.o rpc_server/srv_ntsvcs_nt.o \ + librpc/gen_ndr/srv_ntsvcs.o RPC_DFS_OBJ = librpc/gen_ndr/srv_dfs.o rpc_server/srv_dfs_nt.o @@ -514,22 +537,26 @@ RPC_ECHO_OBJ = rpc_server/srv_echo_nt.o librpc/gen_ndr/srv_echo.o RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ) -RPC_PARSE_OBJ = rpc_parse/parse_lsa.o $(RPC_PARSE_OBJ2) \ +RPC_PARSE_OBJ = $(RPC_PARSE_OBJ2) \ rpc_parse/parse_spoolss.o \ rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o \ - rpc_parse/parse_ntsvcs.o rpc_parse/parse_svcctl.o $(REGOBJS_OBJ) + rpc_parse/parse_ntsvcs.o rpc_parse/parse_svcctl.o RPC_CLIENT_OBJ = rpc_client/cli_pipe.o LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o +PRIVILEGES_BASIC_OBJ = lib/privileges_basic.o + +PRIVILEGES_OBJ = lib/privileges.o + PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \ passdb/util_wellknown.o passdb/util_builtin.o passdb/pdb_compat.o \ passdb/util_unixsids.o passdb/lookup_sid.o \ passdb/login_cache.o @PDB_STATIC@ \ - lib/account_pol.o lib/privileges.o lib/privileges_basic.o \ + lib/account_pol.o $(PRIVILEGES_OBJ) \ lib/util_nscd.o lib/winbind_util.o DEVEL_HELP_WEIRD_OBJ = modules/weird.o @@ -541,7 +568,7 @@ GROUPDB_OBJ = groupdb/mapping.o groupdb/mapping_tdb.o groupdb/mapping_ldb.o PROFILE_OBJ = profile/profile.o PROFILES_OBJ = utils/profiles.o \ - $(REGFIO_OBJ) $(REGOBJS_OBJ) $(ERRORMAP_OBJ) \ + $(ERRORMAP_OBJ) \ $(RPC_PARSE_OBJ1) $(PARAM_OBJ) $(LIBSAMBA_OBJ) \ $(DOSERR_OBJ) $(LIB_OBJ) $(LIB_DUMMY_OBJ) \ $(POPT_LIB_OBJ) $(SECRETS_OBJ) @@ -584,6 +611,7 @@ VFS_NOTIFY_FAM_OBJ = modules/vfs_notify_fam.o VFS_READAHEAD_OBJ = modules/vfs_readahead.o VFS_TSMSM_OBJ = modules/vfs_tsmsm.o VFS_FILEID_OBJ = modules/vfs_fileid.o +VFS_AIO_FORK_OBJ = modules/vfs_aio_fork.o VFS_SYNCOPS_OBJ = modules/vfs_syncops.o PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o @@ -601,7 +629,6 @@ AUTH_WINBIND_OBJ = auth/auth_winbind.o AUTH_SCRIPT_OBJ = auth/auth_script.o AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/token_util.o \ - lib/util_nttoken.o \ auth/auth_compat.o auth/auth_ntlmssp.o \ $(PLAINTEXT_AUTH_OBJ) $(SLCACHE_OBJ) $(DCUTIL_OBJ) @@ -640,9 +667,9 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ - $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \ - $(BUILDOPT_OBJ) $(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) \ - $(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@ + $(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \ + $(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) @LIBWBCLIENT_STATIC@ \ + $(PRIVILEGES_BASIC_OBJ) PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \ printing/print_cups.o printing/print_generic.o \ @@ -700,7 +727,8 @@ SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \ TESTPARM_OBJ = utils/testparm.o \ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ - $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) + $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) \ + $(ERRORMAP_OBJ) PASSWD_UTIL_OBJ = utils/passwd_util.o @@ -708,17 +736,16 @@ SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSWD_UTIL_OBJ) $(PASSCHANGE_OBJ) \ $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) @LIBWBCLIENT_STATIC@ \ $(GROUPDB_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) \ - $(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) $(LDB_OBJ) + $(LIBMSRPC_GEN_OBJ) $(LIBMSRPC_OBJ) $(LDB_OBJ) PDBEDIT_OBJ = utils/pdbedit.o $(PASSWD_UTIL_OBJ) $(PARAM_OBJ) $(PASSDB_OBJ) @LIBWBCLIENT_STATIC@ \ $(LIBSAMBA_OBJ) $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) \ $(SECRETS_OBJ) $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) libsmb/asn1.o \ $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) $(LDB_OBJ) $(ERRORMAP_OBJ) -SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ) +SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ0) @LIBWBCLIENT_STATIC@ DISPLAY_SEC_OBJ= lib/display_sec.o -DISPLAY_DSDCINFO_OBJ= lib/display_dsdcinfo.o RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \ @@ -726,8 +753,8 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_dfs.o \ rpcclient/cmd_dssetup.o rpcclient/cmd_echo.o \ rpcclient/cmd_shutdown.o rpcclient/cmd_test.o \ - rpcclient/cmd_wkssvc.o \ - $(DISPLAY_SEC_OBJ) $(DISPLAY_DSDCINFO_OBJ) + rpcclient/cmd_wkssvc.o rpcclient/cmd_ntsvcs.o \ + $(DISPLAY_SEC_OBJ) RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) \ @@ -739,14 +766,27 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ PAM_WINBIND_OBJ = nsswitch/pam_winbind.o $(WBCOMMON_OBJ) \ $(LIBREPLACE_OBJ) @BUILD_INIPARSER@ -LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \ - libsmb/libsmb_cache.o \ - $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ - $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ - $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(RPC_PARSE_OBJ) \ - $(SECRETS_OBJ) $(PASSDB_OBJ) @LIBWBCLIENT_STATIC@ $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(LDB_OBJ) - -LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o $(TDBBASE_OBJ) +LIBSMBCLIENT_OBJ0 = \ + libsmb/libsmb_cache.o \ + libsmb/libsmb_compat.o \ + libsmb/libsmb_context.o \ + libsmb/libsmb_dir.o \ + libsmb/libsmb_file.o \ + libsmb/libsmb_misc.o \ + libsmb/libsmb_path.o \ + libsmb/libsmb_printjob.o \ + libsmb/libsmb_server.o \ + libsmb/libsmb_stat.o \ + libsmb/libsmb_xattr.o \ + libsmb/libsmb_setget.o \ + $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ + $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ + $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(RPC_PARSE_OBJ) \ + $(SECRETS_OBJ) $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(LDB_OBJ) + +LIBSMBCLIENT_OBJ = $(LIBSMBCLIENT_OBJ0) @LIBWBCLIENT_STATIC@ + +LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o @LIBTDB_STATIC@ # This shared library is intended for linking with unit test programs # to test Samba internals. It's called libbigballofmud.so to @@ -775,17 +815,19 @@ LIBNETAPI_OBJ1 = lib/netapi/netapi.o \ lib/netapi/getdc.o LIBNETAPI_OBJ = $(LIBNETAPI_OBJ1) $(LIBNET_OBJ) \ - $(REG_API_OBJ) \ + $(REG_SMBCONF_OBJ) \ $(PARAM_WITHOUT_REG_OBJ) $(LIB_NONSMBD_OBJ) \ $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(RPC_PARSE_OBJ) \ $(SECRETS_OBJ) $(PASSDB_OBJ) @LIBWBCLIENT_STATIC@ $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(LDB_OBJ) \ - $(DCUTIL_OBJ) $(LIBADS_OBJ) + $(DCUTIL_OBJ) $(LIBADS_OBJ) $(PRIVILEGES_BASIC_OBJ) -LIBNET_OBJ = libnet/libnet_conf.o libnet/libnet_join.o \ +LIBNET_CONF_OBJ = libnet/libnet_conf.o + +LIBNET_OBJ = $(LIBNET_CONF_OBJ) libnet/libnet_join.o \ librpc/gen_ndr/ndr_libnet_join.o -NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_domain.o utils/net_help.o \ +NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_help.o \ utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \ utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \ utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \ @@ -802,22 +844,15 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_WITHOUT_REG_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \ - $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(REGFIO_OBJ) $(READLINE_OBJ) \ + $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(READLINE_OBJ) \ $(LDB_OBJ) $(LIBGPO_OBJ) @BUILD_INIPARSER@ $(DISPLAY_SEC_OBJ) \ - $(REG_API_OBJ) $(DISPLAY_DSDCINFO_OBJ) $(LIBNETAPI_OBJ1) $(LIBNET_OBJ) \ - $(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@ + $(REG_SMBCONF_OBJ) @LIBNETAPI_STATIC@ $(LIBNET_OBJ) \ + $(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@ \ + $(PRIVILEGES_BASIC_OBJ) CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) -MOUNT_OBJ = client/smbmount.o \ - $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) - -MNT_OBJ = client/smbmnt.o $(VERSION_OBJ) $(LIBREPLACE_OBJ) $(SOCKET_WRAPPER_OBJ) - -UMOUNT_OBJ = client/smbumount.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ - $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) - CIFS_MOUNT_OBJ = client/mount.cifs.o CIFS_UMOUNT_OBJ = client/umount.cifs.o @@ -825,7 +860,8 @@ CIFS_UMOUNT_OBJ = client/umount.cifs.o CIFS_SPNEGO_OBJ = client/cifs.spnego.o NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(LIBNMB_OBJ) $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) \ - $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ) + $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ) \ + $(ERRORMAP_OBJ) SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/utable.o \ torture/denytest.o torture/mangle_test.o @@ -852,7 +888,7 @@ PDBTEST_OBJ = torture/pdbtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ VFSTEST_OBJ = torture/cmd_vfs.o torture/vfstest.o $(SMBD_OBJ_BASE) $(READLINE_OBJ) -SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ) +SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(DOSERR_OBJ) $(RPC_PARSE_OBJ1) $(ERRORMAP_OBJ) LOG2PCAP_OBJ = utils/log2pcaphex.o @@ -873,21 +909,22 @@ SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ EVTLOGADM_OBJ0 = utils/eventlogadm.o -EVTLOGADM_OBJ = $(EVTLOGADM_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(REGOBJS_OBJ) \ +EVTLOGADM_OBJ = $(EVTLOGADM_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ $(ERRORMAP_OBJ) $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(DOSERR_OBJ) \ $(SECRETS_OBJ) \ - registry/reg_eventlog.o rpc_server/srv_eventlog_lib.o registry/reg_util.o \ - registry/reg_backend_db.o + registry/reg_eventlog.o rpc_server/srv_eventlog_lib.o SHARESEC_OBJ0 = utils/sharesec.o -SHARESEC_OBJ = $(SHARESEC_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(REGOBJS_OBJ) \ +SHARESEC_OBJ = $(SHARESEC_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ $(ERRORMAP_OBJ) $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(DOSERR_OBJ) \ $(POPT_LIB_OBJ) $(SECRETS_OBJ) TALLOCTORT_OBJ = @tallocdir@/testsuite.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \ - $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) $(LIBSAMBA_OBJ) $(SECRETS_OBJ) + $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) $(LIBSAMBA_OBJ) $(SECRETS_OBJ) \ + $(ERRORMAP_OBJ) REPLACETORT_OBJ = lib/replace/test/testsuite.o \ + lib/replace/test/getifaddrs.o \ lib/replace/test/os2_delete.o \ lib/replace/test/strptime.o \ $(LIBREPLACE_OBJ) @@ -895,7 +932,8 @@ REPLACETORT_OBJ = lib/replace/test/testsuite.o \ NDRDUMP_OBJ = librpc/tools/ndrdump.o \ $(PARAM_OBJ) $(LIBNDR_GEN_OBJ) \ $(LIBSAMBA_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \ - $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) $(SECRETS_OBJ) + $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) $(SECRETS_OBJ) \ + $(ERRORMAP_OBJ) DEBUG2HTML_OBJ = utils/debug2html.o utils/debugparse.o @@ -908,18 +946,19 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) $(LIBNDR_OBJ) $(LIBNDR_GEN_OBJ) \ $(LIBMSRPC_OBJ) \ $(LIB_WITH_PROTO_OBJ) \ $(RPC_PIPE_OBJ) $(RPC_PARSE_OBJ) $(KRBCLIENT_OBJ) \ - $(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \ + $(AUTH_OBJ) $(PARAM_WITHOUT_REG_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \ $(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \ $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \ - $(AUTH_SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \ + $(AUTH_SAM_OBJ) $(REG_FULL_OBJ) $(POPT_LIB_OBJ) \ $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) $(RPC_DSSETUP_OBJ) \ $(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \ $(RPC_ECHO_OBJ) $(RPC_SVCCTL_OBJ) $(RPC_EVENTLOG_OBJ) $(SMBLDAP_OBJ) \ - $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ) $(RPC_UNIXINFO_OBJ) \ + $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ) \ $(RPC_NTSVCS_OBJ) $(RPC_INITSHUTDOWN_OBJ) \ utils/passwd_util.o $(LIBGPO_OBJ) $(NSS_INFO_OBJ) \ - $(RPCCLIENT_NDR_OBJ) $(DISPLAY_DSDCINFO_OBJ) + $(RPCCLIENT_NDR_OBJ) \ + $(PRIVILEGES_BASIC_OBJ) WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) \ $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ) @@ -972,7 +1011,8 @@ WINBINDD_OBJ = \ 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 $(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@ + $(DOSERR_OBJ) lib/winbind_util.o $(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@ \ + $(ERRORMAP_OBJ) WINBIND_NSS_OBJ = $(WBCOMMON_OBJ) $(LIBREPLACE_OBJ) @WINBIND_NSS_EXTRA_OBJS@ @@ -1001,7 +1041,7 @@ LDB_CMDLINE_OBJ = $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \ $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \ - $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(REGFIO_OBJ) $(READLINE_OBJ) \ + $(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(READLINE_OBJ) \ $(LDB_OBJ) lib/ldb/tools/cmdline.o @@ -1020,16 +1060,16 @@ POPT_OBJ=popt/findme.o popt/popt.o popt/poptconfig.o \ INIPARSER_OBJ = iniparser_build/iniparser.o iniparser_build/dictionary.o \ iniparser_build/strlib.o -TDBBACKUP_OBJ = lib/tdb/tools/tdbbackup.o $(LIBREPLACE_OBJ) \ - $(TDBBASE_OBJ) $(SOCKET_WRAPPER_OBJ) +TDBBACKUP_OBJ = @tdbdir@/tools/tdbbackup.o $(LIBREPLACE_OBJ) \ + @LIBTDB_STATIC@ $(SOCKET_WRAPPER_OBJ) -TDBTOOL_OBJ = lib/tdb/tools/tdbtool.o $(TDBBASE_OBJ) $(LIBREPLACE_OBJ) \ +TDBTOOL_OBJ = @tdbdir@/tools/tdbtool.o @LIBTDB_STATIC@ $(LIBREPLACE_OBJ) \ $(SOCKET_WRAPPER_OBJ) -TDBDUMP_OBJ = lib/tdb/tools/tdbdump.o $(TDBBASE_OBJ) $(LIBREPLACE_OBJ) \ +TDBDUMP_OBJ = @tdbdir@/tools/tdbdump.o @LIBTDB_STATIC@ $(LIBREPLACE_OBJ) \ $(SOCKET_WRAPPER_OBJ) -TDBTORTURE_OBJ = lib/tdb/tools/tdbtorture.o $(TDBBASE_OBJ) $(LIBREPLACE_OBJ) \ +TDBTORTURE_OBJ = @tdbdir@/tools/tdbtorture.o @LIBTDB_STATIC@ $(LIBREPLACE_OBJ) \ $(SOCKET_WRAPPER_OBJ) @@ -1037,10 +1077,13 @@ NTLM_AUTH_OBJ1 = utils/ntlm_auth.o utils/ntlm_auth_diagnostics.o NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \ - libads/kerberos_verify.o $(SECRETS_OBJ) $(SERVER_MUTEX_OBJ) \ - libads/authdata.o $(RPC_PARSE_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ - $(SMBLDAP_OBJ) $(DOSERR_OBJ) rpc_parse/parse_net.o $(LIBNMB_OBJ) \ - $(LDB_OBJ) $(ERRORMAP_OBJ) $(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@ + $(SECRETS_OBJ) $(SERVER_MUTEX_OBJ) $(LIBADS_SERVER_OBJ) \ + $(RPC_PARSE_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ + $(SMBLDAP_OBJ) $(DOSERR_OBJ) $(LIBNMB_OBJ) \ + $(LDB_OBJ) $(ERRORMAP_OBJ) $(WBCOMMON_OBJ) @LIBWBCLIENT_STATIC@ \ + librpc/gen_ndr/ndr_samr.o \ + librpc/gen_ndr/ndr_lsa.o \ + librpc/gen_ndr/ndr_netlogon.o VLP_OBJ1 = ../testsuite/printing/vlp.o $(RPC_CLIENT_OBJ1) $(RPC_PARSE_OBJ2) $(RPC_CLIENT_OBJ) @@ -1061,6 +1104,8 @@ nss_modules : $(NSS_MODULES) pam_modules : $(PAM_MODULES) +gpext_modules : SHOWFLAGS $(GPEXT_MODULES) + pam_smbpass : SHOWFLAGS bin/pam_smbpass.@SHLIBEXT@ pam_winbind : SHOWFLAGS bin/pam_winbind.@SHLIBEXT@ @@ -1105,10 +1150,10 @@ modules: SHOWFLAGS $(MODULES) ##################################################################### ## Perl IDL Compiler -IDL_FILES = unixinfo.idl lsa.idl dfs.idl echo.idl winreg.idl initshutdown.idl \ +IDL_FILES = 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 xattr.idl misc.idl samr.idl security.idl \ - dssetup.idl + dssetup.idl krb5pac.idl ntsvcs.idl idl: @IDL_FILES="$(IDL_FILES)" CPP="$(CPP)" PERL="$(PERL)" \ @@ -1221,61 +1266,57 @@ bin/.dummy: dir=bin $(MAKEDIR); fi @: >> $@ || : > $@ # what a fancy emoticon! -bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBWBCLIENT_SHARED@ @BUILD_POPT@ +bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @BUILD_POPT@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \ $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) \ - @POPTLIBS@ @SMBD_LIBS@ @WINBIND_LIBS@ + @POPTLIBS@ @SMBD_LIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ \ + @WINBIND_LIBS@ -bin/nmbd@EXEEXT@: $(BINARY_PREREQS) $(NMBD_OBJ) @BUILD_POPT@ +bin/nmbd@EXEEXT@: $(BINARY_PREREQS) $(NMBD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ - @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @POPTLIBS@ \ + $(KRB5LIBS) $(LDAP_LIBS) -bin/swat@EXEEXT@: $(BINARY_PREREQS) $(SWAT_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/swat@EXEEXT@: $(BINARY_PREREQS) $(SWAT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINT_LIBS) \ $(AUTH_LIBS) $(LIBS) $(PASSDB_LIBS) @POPTLIBS@ $(KRB5LIBS) \ - $(LDAP_LIBS) @WINBIND_LIBS@ + $(LDAP_LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/rpcclient@EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(PASSDB_LIBS) $(RPCCLIENT_OBJ) \ $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \ - $(KRB5LIBS) $(LDAP_LIBS) @WINBIND_LIBS@ + $(KRB5LIBS) $(LDAP_LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ \ + @WINBIND_LIBS@ -bin/smbclient@EXEEXT@: $(BINARY_PREREQS) $(CLIENT_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/smbclient@EXEEXT@: $(BINARY_PREREQS) $(CLIENT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) \ $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \ - $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) $(DNSSD_LIBS) @WINBIND_LIBS@ + $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) $(DNSSD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/net@EXEEXT@: $(BINARY_PREREQS) $(NET_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/net@EXEEXT@: $(BINARY_PREREQS) $(NET_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) \ - $(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) @INIPARSERLIBS@ @WINBIND_LIBS@ - -bin/profiles@EXEEXT@: $(BINARY_PREREQS) $(PROFILES_OBJ) @BUILD_POPT@ - @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(PROFILES_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(LDAP_LIBS) @POPTLIBS@ - -bin/smbspool@EXEEXT@: $(BINARY_PREREQS) $(CUPS_OBJ) @BUILD_POPT@ - @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ - -bin/smbmount@EXEEXT@: $(BINARY_PREREQS) $(MOUNT_OBJ) @BUILD_POPT@ - @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ + $(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) \ + @INIPARSERLIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ \ + @LIBNETAPI_LIBS@ -bin/smbmnt@EXEEXT@: $(BINARY_PREREQS) $(MNT_OBJ) @BUILD_POPT@ +bin/profiles@EXEEXT@: $(BINARY_PREREQS) $(PROFILES_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(MNT_OBJ) $(DYNEXP) $(LDFLAGS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(PROFILES_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ + $(LDAP_LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/smbumount@EXEEXT@: $(BINARY_PREREQS) $(UMOUNT_OBJ) @BUILD_POPT@ +bin/smbspool@EXEEXT@: $(BINARY_PREREQS) $(CUPS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ + $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ bin/mount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_MOUNT_OBJ) @BUILD_POPT@ @echo Linking $@ @@ -1285,164 +1326,203 @@ bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ) @BUILD_POPT@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) @POPTLIBS@ -bin/cifs.spnego@EXEEXT@: $(BINARY_PREREQS) $(CIFS_SPNEGO_OBJ) $(LIBSMBCLIENT_OBJ) @BUILD_POPT@ +bin/cifs.spnego@EXEEXT@: $(BINARY_PREREQS) $(CIFS_SPNEGO_OBJ) $(LIBSMBCLIENT_OBJ0) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(CIFS_SPNEGO_OBJ) $(DYNEXP) $(LDFLAGS) -lkeyutils $(LIBS) \ - $(LIBSMBCLIENT_OBJ) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ @LIBWBCLIENT_SHARED@ + @$(CC) $(FLAGS) -o $@ $(CIFS_SPNEGO_OBJ) $(DYNEXP) $(LDFLAGS) \ + -lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ0) $(KRB5LIBS) \ + $(LDAP_LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ @LIBWBCLIENT_SHARED@ \ + @LIBTDB_LIBS@ -bin/testparm@EXEEXT@: $(BINARY_PREREQS) $(TESTPARM_OBJ) @BUILD_POPT@ +bin/testparm@EXEEXT@: $(BINARY_PREREQS) $(TESTPARM_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ + $(LDAP_LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/smbstatus@EXEEXT@: $(BINARY_PREREQS) $(STATUS_OBJ) @BUILD_POPT@ +bin/smbstatus@EXEEXT@: $(BINARY_PREREQS) $(STATUS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(LDAP_LIBS) \ - @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ + $(LDAP_LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/smbcontrol@EXEEXT@: $(BINARY_PREREQS) $(SMBCONTROL_OBJ) @BUILD_POPT@ +bin/smbcontrol@EXEEXT@: $(BINARY_PREREQS) $(SMBCONTROL_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ @$(CC) -DUSING_SMBCONTROL $(FLAGS) -o $@ \ - $(SMBCONTROL_OBJ) $(DYNEXP) $(LDFLAGS) \ - $(LIBS) $(LDAP_LIBS) @LIBUNWIND_PTRACE@ @POPTLIBS@ + $(SMBCONTROL_OBJ) $(DYNEXP) $(LDFLAGS) \ + $(LIBS) $(LDAP_LIBS) @LIBUNWIND_PTRACE@ @POPTLIBS@ \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/smbtree@EXEEXT@: $(BINARY_PREREQS) $(SMBTREE_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/smbtree@EXEEXT@: $(BINARY_PREREQS) $(SMBTREE_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) \ - $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/smbpasswd@EXEEXT@: $(BINARY_PREREQS) $(SMBPASSWD_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/smbpasswd@EXEEXT@: $(BINARY_PREREQS) $(SMBPASSWD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(PASSDB_LIBS) \ - $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) @WINBIND_LIBS@ + $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/pdbedit@EXEEXT@: $(BINARY_PREREQS) $(PDBEDIT_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/pdbedit@EXEEXT@: $(BINARY_PREREQS) $(PDBEDIT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(PDBEDIT_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ - @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS) @WINBIND_LIBS@ + @POPTLIBS@ $(PASSDB_LIBS) $(LDAP_LIBS) @LIBTALLOC_LIBS@ \ + @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/smbget@EXEEXT@: $(BINARY_PREREQS) $(SMBGET_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/smbget@EXEEXT@: $(BINARY_PREREQS) $(SMBGET_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(SMBGET_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ - @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ +bin/nmblookup@EXEEXT@: $(BINARY_PREREQS) $(NMBLOOKUP_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDB_LIBS) $(KRB5LIBS) $(LDAP_LIBS) + @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ + @POPTLIBS@ $(LDAP_LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/nmblookup@EXEEXT@: $(BINARY_PREREQS) $(NMBLOOKUP_OBJ) @BUILD_POPT@ +bin/smbtorture@EXEEXT@: $(BINARY_PREREQS) $(SMBTORTURE_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(LDAP_LIBS) + @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) \ + $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ \ + @LIBTDB_LIBS@ -bin/smbtorture@EXEEXT@: $(BINARY_PREREQS) $(SMBTORTURE_OBJ) @BUILD_POPT@ - @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ - -bin/talloctort@EXEEXT@: $(BINARY_PREREQS) $(TALLOCTORT_OBJ) @BUILD_POPT@ +bin/talloctort@EXEEXT@: $(BINARY_PREREQS) $(TALLOCTORT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(TALLOCTORT_OBJ) $(LDFLAGS) \ - $(DYNEXP) $(LIBS) $(LDAP_LIBS) @POPTLIBS@ + $(DYNEXP) $(LIBS) $(LDAP_LIBS) @POPTLIBS@ \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/replacetort@EXEEXT@: $(REPLACETORT_OBJ) @BUILD_POPT@ +bin/replacetort@EXEEXT@: $(REPLACETORT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(REPLACETORT_OBJ) $(LDFLAGS) \ - $(DYNEXP) $(LIBS) @POPTLIBS@ + $(DYNEXP) $(LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ -bin/masktest@EXEEXT@: $(BINARY_PREREQS) $(MASKTEST_OBJ) @BUILD_POPT@ +bin/masktest@EXEEXT@: $(BINARY_PREREQS) $(MASKTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(DYNEXP) \ + $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/msgtest@EXEEXT@: $(BINARY_PREREQS) $(MSGTEST_OBJ) @BUILD_POPT@ +bin/msgtest@EXEEXT@: $(BINARY_PREREQS) $(MSGTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(DYNEXP) \ + $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/smbcacls@EXEEXT@: $(BINARY_PREREQS) $(SMBCACLS_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/smbcacls@EXEEXT@: $(BINARY_PREREQS) $(SMBCACLS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ \ - $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + @$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) \ + $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/smbcquotas@EXEEXT@: $(BINARY_PREREQS) $(SMBCQUOTAS_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/smbcquotas@EXEEXT@: $(BINARY_PREREQS) $(SMBCQUOTAS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ \ - $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + @$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) \ + $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/eventlogadm@EXEEXT@: $(BINARY_PREREQS) $(EVTLOGADM_OBJ) @BUILD_POPT@ +bin/eventlogadm@EXEEXT@: $(BINARY_PREREQS) $(EVTLOGADM_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(EVTLOGADM_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(EVTLOGADM_OBJ) $(DYNEXP) $(LDFLAGS) \ + $(LIBS) $(LDAP_LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/sharesec@EXEEXT@: $(BINARY_PREREQS) $(SHARESEC_OBJ) @BUILD_POPT@ +bin/sharesec@EXEEXT@: $(BINARY_PREREQS) $(SHARESEC_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SHARESEC_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(SHARESEC_OBJ) $(DYNEXP) $(LDFLAGS) \ + $(LIBS) $(LDAP_LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/locktest@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST_OBJ) @BUILD_POPT@ +bin/locktest@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(DYNEXP) \ + $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/nsstest@EXEEXT@: $(BINARY_PREREQS) $(NSSTEST_OBJ) @BUILD_POPT@ +bin/nsstest@EXEEXT@: $(BINARY_PREREQS) $(NSSTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(DYNEXP) \ + $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/pdbtest@EXEEXT@: $(BINARY_PREREQS) $(PDBTEST_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/pdbtest@EXEEXT@: $(BINARY_PREREQS) $(PDBTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(PDBTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@ @LIBWBCLIENT_SHARED@ + @$(CC) $(FLAGS) -o $@ $(PDBTEST_OBJ) $(LDFLAGS) $(DYNEXP) \ + $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \ + @POPTLIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @LIBWBCLIENT_SHARED@ -bin/vfstest@EXEEXT@: $(BINARY_PREREQS) $(VFSTEST_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/vfstest@EXEEXT@: $(BINARY_PREREQS) $(VFSTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(ACL_LIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) @SMBD_LIBS@ $(NSCD_LIBS) @LIBWBCLIENT_SHARED@ + @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \ + $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \ + $(ACL_LIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) \ + @SMBD_LIBS@ $(NSCD_LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ \ + @LIBWBCLIENT_SHARED@ -bin/smbiconv@EXEEXT@: $(BINARY_PREREQS) $(SMBICONV_OBJ) @BUILD_POPT@ +bin/smbiconv@EXEEXT@: $(BINARY_PREREQS) $(SMBICONV_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBICONV_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(SMBICONV_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \ + $(TERMLIBS) $(DYNEXP) $(LIBS) $(LDAP_LIBS) @POPTLIBS@ \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/log2pcap@EXEEXT@: $(BINARY_PREREQS) $(LOG2PCAP_OBJ) @BUILD_POPT@ +bin/log2pcap@EXEEXT@: $(BINARY_PREREQS) $(LOG2PCAP_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LOG2PCAP_OBJ) $(LDFLAGS) $(DYNEXP) @POPTLIBS@ $(LIBS) + @$(CC) $(FLAGS) -o $@ $(LOG2PCAP_OBJ) $(LDFLAGS) $(DYNEXP) \ + @POPTLIBS@ $(LIBS) @LIBTALLOC_LIBS@ -bin/locktest2@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST2_OBJ) @BUILD_POPT@ +bin/locktest2@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST2_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(DYNEXP) \ + $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/ndrdump@EXEEXT@: $(BINARY_PREREQS) $(NDRDUMP_OBJ) @BUILD_POPT@ +bin/ndrdump@EXEEXT@: $(BINARY_PREREQS) $(NDRDUMP_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(NDRDUMP_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ - @POPTLIBS@ @LDAP_LIBS@ + @POPTLIBS@ @LDAP_LIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/debug2html@EXEEXT@: $(BINARY_PREREQS) $(DEBUG2HTML_OBJ) @BUILD_POPT@ +bin/debug2html@EXEEXT@: $(BINARY_PREREQS) $(DEBUG2HTML_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) + @$(CC) $(FLAGS) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(DYNEXP) \ + $(LIBS) @LIBTALLOC_LIBS@ -bin/smbfilter@EXEEXT@: $(BINARY_PREREQS) $(SMBFILTER_OBJ) @BUILD_POPT@ +bin/smbfilter@EXEEXT@: $(BINARY_PREREQS) $(SMBFILTER_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ + @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) \ + $(KRB5LIBS) $(LDAP_LIBS) @POPTLIBS@ \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/ldbedit: $(BINARY_PREREQS) $(LDBEDIT_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/ldbedit: $(BINARY_PREREQS) $(LDBEDIT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LDBEDIT_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ - @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \ - $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + @$(CC) $(FLAGS) -o $@ $(LDBEDIT_OBJ) $(DYNEXP) $(LDFLAGS) \ + $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) \ + $(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/ldbsearch: $(BINARY_PREREQS) $(LDBSEARCH_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/ldbsearch: $(BINARY_PREREQS) $(LDBSEARCH_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LDBSEARCH_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ - @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \ - $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + @$(CC) $(FLAGS) -o $@ $(LDBSEARCH_OBJ) $(DYNEXP) $(LDFLAGS) \ + $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) \ + $(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/ldbadd: $(BINARY_PREREQS) $(LDBADD_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/ldbadd: $(BINARY_PREREQS) $(LDBADD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LDBADD_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ - @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \ - $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) \ + $(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/ldbmodify: $(BINARY_PREREQS) $(LDBMODIFY_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/ldbmodify: $(BINARY_PREREQS) $(LDBMODIFY_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LDBMODIFY_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ - @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \ - $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) \ + $(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LDBDEL_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ - @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \ - $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + @POPTLIBS@ $(KRB5LIBS) $(UUID_LIBS) $(LDAP_LIBS) \ + $(PASSDB_LIBS) $(TERMLDFLAGS) $(TERMLIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ $(LIBTALLOC_SHARED_TARGET): $(BINARY_PREREQS) $(LIBTALLOC_OBJ) @echo Linking shared library $@ @@ -1454,6 +1534,21 @@ $(LIBTALLOC_STATIC_TARGET): $(BINARY_PREREQS) $(LIBTALLOC_OBJ0) @echo Linking non-shared library $@ @-$(AR) -rc $@ $(LIBTALLOC_OBJ0) +MKSYMS_SH = $(srcdir)/script/mksyms.sh + +$(LIBTDB_SYMS): $(LIBTDB_HEADERS) + @$(MKSYMS_SH) $(AWK) $@ $(LIBTDB_HEADERS) + +$(LIBTDB_SHARED_TARGET): $(BINARY_PREREQS) $(LIBTDB_OBJ) $(LIBTDB_SYMS) + @echo Linking shared library $@ + @$(SHLD_DSO) $(LIBTDB_OBJ) \ + @SONAMEFLAG@`basename $@`.$(SONAME_VER) + @ln -s -f `basename $@` $@.$(SONAME_VER) + +$(LIBTDB_STATIC_TARGET): $(BINARY_PREREQS) $(LIBTDB_OBJ0) + @echo Linking non-shared library $@ + @-$(AR) -rc $@ $(LIBTDB_OBJ0) + bin/libwbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ) @LIBTALLOC_SHARED@ @echo Linking shared library $@ @$(SHLD_DSO) @LIBTALLOC_LIBS@ $(LIBWBCLIENT_OBJ) \ @@ -1464,39 +1559,43 @@ bin/libwbclient.a: $(BINARY_PREREQS) $(LIBWBCLIENT_OBJ0) $(WBCOMMON_OBJ) @echo Linking non-shared library $@ @-$(AR) -rc $@ $(LIBWBCLIENT_OBJ0) $(WBCOMMON_OBJ) -bin/libaddns.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBADDNS_OBJ) +bin/libaddns.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBADDNS_OBJ) @LIBTALLOC_SHARED@ @echo Linking shared library $@ @$(SHLD_DSO) $(LIBADDNS_OBJ) $(LIBS) \ - $(KRB5LIBS) $(UUID_LIBS)\ + $(KRB5LIBS) $(UUID_LIBS) @LIBTALLOC_LIBS@ \ @SONAMEFLAG@`basename $@`.$(SONAME_VER) bin/libaddns.a: $(BINARY_PREREQS) $(LIBADDNS_OBJ) @echo Linking non-shared library $@ @-$(AR) -rc $@ $(LIBADDNS_OBJ) -bin/libnetapi.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBNETAPI_OBJ) @LIBWBCLIENT_SHARED@ +$(LIBNETAPI_SHARED_TARGET): $(BINARY_PREREQS) $(LIBNETAPI_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking shared library $@ - @$(SHLD_DSO) $(LIBNETAPI_OBJ) @LIBWBCLIENT_SHARED@ $(LIBS) \ + @$(SHLD_DSO) $(LIBNETAPI_OBJ) \ + @LIBTALLOC_LIBS@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ $(LIBS) \ $(LDAP_LIBS) $(KRB5LIBS) $(NSCD_LIBS) \ @SONAMEFLAG@`basename $@`.$(SONAME_VER) + @ln -s -f `basename $@` $@.$(SONAME_VER) -bin/libnetapi.a: $(BINARY_PREREQS) $(LIBNETAPI_OBJ) +$(LIBNETAPI_STATIC_TARGET): $(BINARY_PREREQS) $(LIBNETAPI_OBJ1) @echo Linking non-shared library $@ - @-$(AR) -rc $@ $(LIBNETAPI_OBJ) + @-$(AR) -rc $@ $(LIBNETAPI_OBJ1) -bin/libsmbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ) @LIBWBCLIENT_SHARED@ +bin/libsmbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking shared library $@ - @$(SHLD_DSO) $(LIBSMBCLIENT_OBJ) @LIBWBCLIENT_SHARED@ $(LIBS) \ + @$(SHLD_DSO) $(LIBSMBCLIENT_OBJ) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @LIBWBCLIENT_SHARED@ $(LIBS) \ $(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) +bin/libsmbsharemodes.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBSMBSHAREMODES_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking shared library $@ - @$(SHLD_DSO) $(LIBSMBSHAREMODES_OBJ) $(LIBS) \ + @$(SHLD_DSO) $(LIBSMBSHAREMODES_OBJ) \ + $(LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ \ $(KRB5LIBS) $(LDAP_LIBS) \ @SONAMEFLAG@`basename $@`.$(SONAME_VER) @@ -1505,9 +1604,10 @@ bin/libsmbsharemodes.a: $(BINARY_PREREQS) $(LIBSMBSHAREMODES_OBJ) @-$(AR) -rc $@ $(LIBSMBSHAREMODES_OBJ) # This is probably wrong for anything other than the GNU linker. -bin/libbigballofmud.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBBIGBALLOFMUD_OBJ) +bin/libbigballofmud.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBBIGBALLOFMUD_OBJ) @LIBTALLOC_SHARED@ @echo Linking shared library $@ - @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_OBJ) $(LIBS) \ + @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_OBJ) \ + $(LIBS) @LIBTALLOC_LIBS@ \ $(PASSDB_LIBS) $(IDMAP_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \ @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR) ln -snf libbigballofmud.so bin/libbigballofmud.so.0 @@ -1518,6 +1618,7 @@ bin/libbigballofmud.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBBIGBALLOFMUD_OBJ) # library. libtalloc: $(LIBTALLOC) +libtdb: $(LIBTDB) libsmbclient: $(LIBSMBCLIENT) libsmbsharemodes: $(LIBSMBSHAREMODES) libaddns: $(LIBADDNS) @@ -1536,10 +1637,6 @@ bin/librpc_samr.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_SAMR_OBJ) @echo "Linking $@" @$(SHLD_MODULE) $(RPC_SAMR_OBJ) -bin/librpc_unixinfo.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_UNIXINFO_OBJ) - @echo "Linking $@" - @$(SHLD_MODULE) $(RPC_UNIXINFO_OBJ) - bin/librpc_srvsvc.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_SVC_OBJ) @echo "Linking $@" @$(SHLD_MODULE) $(RPC_SVC_OBJ) @@ -1588,26 +1685,29 @@ bin/librpc_echo.@SHLIBEXT@: $(BINARY_PREREQS) $(RPC_ECHO_OBJ) @echo "Linking $@" @$(SHLD_MODULE) $(RPC_ECHO_OBJ) -bin/winbindd@EXEEXT@: $(BINARY_PREREQS) $(WINBINDD_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/winbindd@EXEEXT@: $(BINARY_PREREQS) $(WINBINDD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo "Linking $@" @$(CC) $(FLAGS) -o $@ $(WINBINDD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) \ - $(PASSDB_LIBS) @WINBIND_LIBS@ + $(PASSDB_LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/vlp@EXEEXT@: $(BINARY_PREREQS) $(VLP_OBJ) @LIBWBCLIENT_SHARED@ +bin/vlp@EXEEXT@: $(BINARY_PREREQS) $(VLP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo "Linking $@" - @$(CC) $(FLAGS) -o $@ $(VLP_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \ - $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) @LIBWBCLIENT_SHARED@ + @$(CC) $(FLAGS) -o $@ $(VLP_OBJ) $(LDFLAGS) $(DYNEXP) \ + $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \ + $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @LIBWBCLIENT_SHARED@ @WINBIND_NSS@: $(BINARY_PREREQS) $(WINBIND_NSS_OBJ) @echo "Linking $@" @$(SHLD) $(WINBIND_NSS_LDSHFLAGS) -o $@ $(WINBIND_NSS_OBJ) \ - @WINBIND_NSS_EXTRA_LIBS@ @WINBIND_NSS_PTHREAD@ @SONAMEFLAG@`basename $@`@NSSSONAMEVERSIONSUFFIX@ + @WINBIND_NSS_EXTRA_LIBS@ @WINBIND_NSS_PTHREAD@ \ + @SONAMEFLAG@`basename $@`@NSSSONAMEVERSIONSUFFIX@ -@WINBIND_WINS_NSS@: $(BINARY_PREREQS) $(WINBIND_WINS_NSS_OBJ) +@WINBIND_WINS_NSS@: $(BINARY_PREREQS) $(WINBIND_WINS_NSS_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo "Linking $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_WINS_NSS_OBJ) \ - $(LDAP_LIBS) $(KRB5LIBS) $(LIBS) \ + $(LDAP_LIBS) $(KRB5LIBS) $(LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ \ @SONAMEFLAG@`basename $@`@NSSSONAMEVERSIONSUFFIX@ bin/winbind_krb5_locator.@SHLIBEXT@: $(BINARY_PREREQS) $(WINBIND_KRB5_LOCATOR_OBJ) @@ -1831,55 +1931,75 @@ bin/fileid.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_FILEID_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_FILEID_OBJ) +bin/aio_fork.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_AIO_FORK_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(VFS_AIO_FORK_OBJ) + +bin/registry.@SHLIBEXT@: $(BINARY_PREREQS) libgpo/gpext/registry.o + @echo "Building plugin $@" + @$(SHLD_MODULE) libgpo/gpext/registry.o + ######################################################### ## IdMap NSS plugins ## None here right now ######################################################### -bin/wbinfo@EXEEXT@: $(BINARY_PREREQS) $(WBINFO_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ +bin/wbinfo@EXEEXT@: $(BINARY_PREREQS) $(WBINFO_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(WBINFO_OBJ) $(DYNEXP) $(LIBS) \ - $(LDAP_LIBS) @POPTLIBS@ @WINBIND_LIBS@ + $(LDAP_LIBS) @POPTLIBS@ @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ \ + @WINBIND_LIBS@ bin/ntlm_auth@EXEEXT@: $(BINARY_PREREQS) $(NTLM_AUTH_OBJ) $(PARAM_OBJ) \ - $(LIB_NONSMBD_OBJ) @BUILD_POPT@ @LIBWBCLIENT_SHARED@ + $(LIB_NONSMBD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(DYNEXP) $(NTLM_AUTH_OBJ) \ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBS) \ - @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) @WINBIND_LIBS@ + @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/pam_smbpass.@SHLIBEXT@: $(BINARY_PREREQS) $(PAM_SMBPASS_OBJ) +bin/pam_smbpass.@SHLIBEXT@: $(BINARY_PREREQS) $(PAM_SMBPASS_OBJ) @LIBTALLOC_SHARED@ @echo "Linking shared library $@" - @$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_OBJ) -lpam $(DYNEXP) $(LIBS) $(LDAP_LIBS) $(KRB5LIBS) $(NSCD_LIBS) + @$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_OBJ) -lpam $(DYNEXP) \ + $(LIBS) $(LDAP_LIBS) $(KRB5LIBS) $(NSCD_LIBS) \ + @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ @WINBIND_LIBS@ -bin/tdbbackup@EXEEXT@: $(BINARY_PREREQS) $(TDBBACKUP_OBJ) +bin/tdbbackup@EXEEXT@: $(BINARY_PREREQS) $(TDBBACKUP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBBACKUP_OBJ) + @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(TDBBACKUP_OBJ) $(DYNEXP) \ + $(LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/tdbtool@EXEEXT@: $(BINARY_PREREQS) $(TDBTOOL_OBJ) +bin/tdbtool@EXEEXT@: $(BINARY_PREREQS) $(TDBTOOL_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBTOOL_OBJ) + @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(TDBTOOL_OBJ) $(DYNEXP) \ + $(LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/tdbdump@EXEEXT@: $(BINARY_PREREQS) $(TDBDUMP_OBJ) +bin/tdbdump@EXEEXT@: $(BINARY_PREREQS) $(TDBDUMP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBDUMP_OBJ) + @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(TDBDUMP_OBJ) $(DYNEXP) \ + $(LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/tdbtorture@EXEEXT@: $(BINARY_PREREQS) $(TDBTORTURE_OBJ) +bin/tdbtorture@EXEEXT@: $(BINARY_PREREQS) $(TDBTORTURE_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @echo Linking $@ - @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBTORTURE_OBJ) + @$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(TDBTORTURE_OBJ) $(DYNEXP) \ + $(LIBS) @LIBTALLOC_LIBS@ @LIBTDB_LIBS@ -bin/t_strcmp@EXEEXT@: $(BINARY_PREREQS) bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o - $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) torture/t_strcmp.o -L ./bin -lbigballofmud +bin/t_strcmp@EXEEXT@: $(BINARY_PREREQS) @LIBTALLOC_SHARED@ bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o + $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) @LIBTALLOC_LIBS@ \ + torture/t_strcmp.o -L ./bin -lbigballofmud -bin/t_strstr@EXEEXT@: $(BINARY_PREREQS) bin/libbigballofmud.@SHLIBEXT@ torture/t_strstr.o - $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) torture/t_strstr.o -L ./bin -lbigballofmud +bin/t_strstr@EXEEXT@: $(BINARY_PREREQS) @LIBTALLOC_SHARED@ bin/libbigballofmud.@SHLIBEXT@ torture/t_strstr.o + $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) @LIBTALLOC_LIBS@ \ + torture/t_strstr.o -L ./bin -lbigballofmud -bin/t_strappend@EXEEXT@: $(BINARY_PREREQS) bin/libbigballofmud.@SHLIBEXT@ torture/t_strappend.o - $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) torture/t_strappend.o -L ./bin -lbigballofmud +bin/t_strappend@EXEEXT@: $(BINARY_PREREQS) @LIBTALLOC_SHARED@ bin/libbigballofmud.@SHLIBEXT@ torture/t_strappend.o + $(CC) $(FLAGS) -o $@ $(DYNEXP) $(LIBS) @LIBTALLOC_LIBS@ \ + torture/t_strappend.o -L ./bin -lbigballofmud bin/t_stringoverflow@EXEEXT@: $(BINARY_PREREQS) bin/libbigballofmud.@SHLIBEXT@ torture/t_stringoverflow.o - $(CC) $(FLAGS) -o $@ $(DYNEXP) torture/t_stringoverflow.o -L./bin -lbigballofmud + $(CC) $(FLAGS) -o $@ $(DYNEXP) torture/t_stringoverflow.o \ + -L./bin -lbigballofmud bin/timelimit@EXEEXT@: script/tests/timelimit.o @echo Linking $@ @@ -1888,8 +2008,9 @@ bin/timelimit@EXEEXT@: script/tests/timelimit.o install: installservers installbin @INSTALL_CIFSMOUNT@ @INSTALL_CIFSSPNEGO@ installman \ installscripts installdat installmodules @SWAT_INSTALL_TARGETS@ \ installlibtalloc \ + installlibtdb \ @INSTALL_LIBSMBCLIENT@ @INSTALL_PAM_MODULES@ \ - @INSTALL_LIBSMBSHAREMODES@ @INSTALL_LIBWBCLIENT@ @INSTALL_LIBNETAPI@ + @INSTALL_LIBSMBSHAREMODES@ @INSTALL_LIBWBCLIENT@ installlibnetapi install-everything: install installmodules @@ -1928,6 +2049,7 @@ installmodules: modules installdirs @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(NSSINFOLIBDIR) $(NSS_INFO_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(CHARSETLIBDIR) $(CHARSET_MODULES) @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(AUTHLIBDIR) $(AUTH_MODULES) + @$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(GPEXTLIBDIR) $(GPEXT_MODULES) @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(PDBLIBDIR) ldapsam.@SHLIBEXT@ NDS_ldapsam.@SHLIBEXT@ @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(PDBLIBDIR) ldapsam.@SHLIBEXT@ NDS_ldapsam_compat.@SHLIBEXT@ @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(PDBLIBDIR) ldapsam.@SHLIBEXT@ ldapsam_compat.@SHLIBEXT@ @@ -1963,6 +2085,13 @@ installlibtalloc: installdirs libtalloc @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) ${prefix}/include -$(INSTALLCMD) -m $(INSTALLPERMS_DATA) @tallocdir@/talloc.h $(DESTDIR)${prefix}/include +installlibtdb: installdirs libtdb + @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR) + -$(INSTALLLIBCMD_SH) $(LIBTDB_SHARED_TARGET) $(DESTDIR)$(LIBDIR) + -$(INSTALLLIBCMD_A) $(LIBTDB_STATIC_TARGET) $(DESTDIR)$(LIBDIR) + @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) ${prefix}/include + -$(INSTALLCMD) -m $(INSTALLPERMS_DATA) $(LIBTDB_HEADERS) $(DESTDIR)${prefix}/include + installlibsmbsharemodes: installdirs libsmbsharemodes @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR) -$(INSTALLLIBCMD_SH) bin/libsmbsharemodes.@SHLIBEXT@ $(DESTDIR)$(LIBDIR) @@ -1982,8 +2111,8 @@ installlibwbclient: installdirs libwbclient installlibnetapi: installdirs libnetapi @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(LIBDIR) - -$(INSTALLLIBCMD_SH) bin/libnetapi.@SHLIBEXT@ $(DESTDIR)$(LIBDIR) - -$(INSTALLLIBCMD_A) bin/libnetapi.a $(DESTDIR)$(LIBDIR) + -$(INSTALLLIBCMD_SH) $(LIBNETAPI_SHARED_TARGET) $(DESTDIR)$(LIBDIR) + -$(INSTALLLIBCMD_A) $(LIBNETAPI_STATIC_TARGET) $(DESTDIR)$(LIBDIR) -$(INSTALLCMD) -m $(INSTALLPERMS_DATA) $(srcdir)/lib/netapi/netapi.h $(DESTDIR)${prefix}/include installpammodules: $(PAM_MODULES) @@ -2000,8 +2129,7 @@ revert: @$(SHELL) $(srcdir)/script/revert.sh $(BINDIR) $(BIN_PROGS) $(SCRIPTS) installman: installdirs - @SMBMOUNT_PROGS="@SMBMOUNT_PROGS@" $(SHELL) \ - $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) C "@ROFF@" + @$(SHELL) $(srcdir)/script/installman.sh $(DESTDIR)$(MANDIR) $(srcdir) C "@ROFF@" .PHONY: showlayout @@ -2020,7 +2148,7 @@ showlayout: @echo " swatdir: $(SWATDIR)" -uninstall: uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSSPNEGO@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibtalloc @UNINSTALL_LIBSMBCLIENT@ @UNINSTALL_PAM_MODULES@ @UNINSTALL_LIBSMBSHAREMODES@ @UNINSTALL_LIBNETAPI@ +uninstall: uninstallman uninstallservers uninstallbin @UNINSTALL_CIFSMOUNT@ @UNINSTALL_CIFSSPNEGO@ uninstallscripts uninstalldat uninstallswat uninstallmodules uninstalllibtalloc uninstalllibtdb @UNINSTALL_LIBSMBCLIENT@ @UNINSTALL_PAM_MODULES@ @UNINSTALL_LIBSMBSHAREMODES@ uninstalllibnetapi uninstallman: @$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) C @@ -2044,6 +2172,7 @@ uninstallmodules: @$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(IDMAPLIBDIR) $(IDMAP_MODULES) @$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(CHARSETLIBDIR) $(CHARSET_MODULES) @$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(AUTHLIBDIR) $(AUTH_MODULES) + @$(SHELL) $(srcdir)/script/uninstallmodules.sh $(INSTALLPERMS_BIN) $(DESTDIR) $(prefix) $(GPEXTLIBDIR) $(GPEXT_MODULES) uninstallscripts: @$(SHELL) $(srcdir)/script/uninstallscripts.sh $(INSTALLPERMS_BIN) $(DESTDIR)$(BINDIR) $(SCRIPTS) @@ -2095,7 +2224,8 @@ clean: delheaders $(LIBTALLOC) $(LIBSMBCLIENT) $(LIBADDNS) \ $(LIBSMBSHAREMODES) $(EVERYTHING_PROGS) $(LIBNETAPI) \ bin/libwbclient.so.0 bin/timelimit \ - .headers.stamp */src/*.o proto_exists + .headers.stamp */src/*.o proto_exists \ + $(LIBTDB_SYMS) -rm -rf t_dir # Making this target will just make sure that the prototype files @@ -2258,7 +2388,7 @@ test_pam_modules: pam_modules ## test: all torture timelimit @echo Running Test suite - @LIB_PATH_VAR=$(LIB_PATH_VAR) PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix}/st all "${smbtorture4_path}" + @LIB_PATH_VAR=$(LIB_PATH_VAR) PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all "${smbtorture4_path}" valgrindtest: all torture timelimit @echo Running Test suite with valgrind @@ -2266,5 +2396,5 @@ valgrindtest: all torture timelimit NMBD_VALGRIND="xterm -n nmbd -e valgrind -q --db-attach=yes --num-callers=30" \ WINBINDD_VALGRIND="xterm -n winbindd -e valgrind -q --db-attach=yes --num-callers=30" \ SMBD_VALGRIND="xterm -n smbd -e valgrind -q --db-attach=yes --num-callers=30" \ - VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/st/valgrind.log" \ - PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix}/st all "${smbtorture4_path}" + VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ + PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all "${smbtorture4_path}" diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 40a2985600..df51966f4c 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -189,7 +189,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, struct sockaddr_storage *dc_ss) { - NET_USER_INFO_3 info3; + struct netr_SamInfo3 *info3 = NULL; struct cli_state *cli = NULL; struct rpc_pipe_client *netlogon_pipe = NULL; NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS; @@ -227,8 +227,6 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, saf_store( domain, cli->desthost ); - ZERO_STRUCT(info3); - /* * If this call succeeds, we now have lots of info about the user * in the info3 structure. @@ -267,7 +265,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, user_info->smb_name, domain, server_info, - &info3); + info3); if (NT_STATUS_IS_OK(nt_status)) { if (user_info->was_mapped) { @@ -281,12 +279,14 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, if ( !NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("PAM account restriction prevents user login\n")); cli_shutdown(cli); + TALLOC_FREE(info3); return nt_status; } } } - netsamlogon_cache_store( user_info->smb_name, &info3 ); + netsamlogon_cache_store(user_info->smb_name, info3); + TALLOC_FREE(info3); } /* Note - once the cli stream is shutdown the mem_ctx used diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index 526f2c93df..ed66d0db0a 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -186,8 +186,13 @@ NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { - TALLOC_CTX *mem_ctx = (*auth_ntlmssp_state)->mem_ctx; + TALLOC_CTX *mem_ctx; + + if (*auth_ntlmssp_state == NULL) { + return; + } + mem_ctx = (*auth_ntlmssp_state)->mem_ctx; if ((*auth_ntlmssp_state)->ntlmssp_state) { ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state); } diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index ce47e94eb5..a95a59ea46 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -1422,7 +1422,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, const char *sent_nt_username, const char *domain, auth_serversupplied_info **server_info, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 *info3) { char zeros[16]; @@ -1446,23 +1446,25 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, matches. */ - sid_copy(&user_sid, &info3->dom_sid.sid); - if (!sid_append_rid(&user_sid, info3->user_rid)) { + sid_copy(&user_sid, info3->base.domain_sid); + if (!sid_append_rid(&user_sid, info3->base.rid)) { return NT_STATUS_INVALID_PARAMETER; } - sid_copy(&group_sid, &info3->dom_sid.sid); - if (!sid_append_rid(&group_sid, info3->group_rid)) { + sid_copy(&group_sid, info3->base.domain_sid); + if (!sid_append_rid(&group_sid, info3->base.primary_gid)) { return NT_STATUS_INVALID_PARAMETER; } - if (!(nt_username = unistr2_to_ascii_talloc(mem_ctx, &(info3->uni_user_name)))) { + nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string); + if (!nt_username) { /* If the server didn't give us one, just use the one we sent * them */ nt_username = sent_nt_username; } - if (!(nt_domain = unistr2_to_ascii_talloc(mem_ctx, &(info3->uni_logon_dom)))) { + nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string); + if (!nt_domain) { /* If the server didn't give us one, just use the one we sent * them */ nt_domain = domain; @@ -1527,50 +1529,50 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, TALLOC_FREE(sam_account); return NT_STATUS_UNSUCCESSFUL; } - + if (!pdb_set_fullname(sam_account, - unistr2_static(&(info3->uni_full_name)), + info3->base.full_name.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_logon_script(sam_account, - unistr2_static(&(info3->uni_logon_script)), + info3->base.logon_script.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_profile_path(sam_account, - unistr2_static(&(info3->uni_profile_path)), + info3->base.profile_path.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_homedir(sam_account, - unistr2_static(&(info3->uni_home_dir)), + info3->base.home_directory.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_dir_drive(sam_account, - unistr2_static(&(info3->uni_dir_drive)), + info3->base.home_drive.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } - if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) { + if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_pass_last_set_time( sam_account, - nt_time_to_unix(info3->pass_last_set_time), + nt_time_to_unix(info3->base.last_password_change), PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; @@ -1578,7 +1580,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, if (!pdb_set_pass_can_change_time( sam_account, - nt_time_to_unix(info3->pass_can_change_time), + nt_time_to_unix(info3->base.allow_password_change), PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; @@ -1586,7 +1588,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, if (!pdb_set_pass_must_change_time( sam_account, - nt_time_to_unix(info3->pass_must_change_time), + nt_time_to_unix(info3->base.force_password_change), PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; @@ -1624,27 +1626,260 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, return nt_status; } - result->login_server = unistr2_to_ascii_talloc(result, - &(info3->uni_logon_srv)); + result->login_server = talloc_strdup(result, + info3->base.logon_server.string); + + /* ensure we are never given NULL session keys */ + + ZERO_STRUCT(zeros); + + if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) { + result->user_session_key = data_blob_null; + } else { + result->user_session_key = data_blob_talloc( + result, info3->base.key.key, + sizeof(info3->base.key.key)); + } + + if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) { + result->lm_session_key = data_blob_null; + } else { + result->lm_session_key = data_blob_talloc( + result, info3->base.LMSessKey.key, + sizeof(info3->base.LMSessKey.key)); + } + + result->was_mapped = username_was_mapped; + + *server_info = result; + + return NT_STATUS_OK; +} + +/***************************************************************************** + Make a server_info struct from the wbcAuthUserInfo returned by a domain logon +******************************************************************************/ + +NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx, + const char *sent_nt_username, + const char *domain, + const struct wbcAuthUserInfo *info, + auth_serversupplied_info **server_info) +{ + char zeros[16]; + + NTSTATUS nt_status = NT_STATUS_OK; + char *found_username = NULL; + const char *nt_domain; + const char *nt_username; + struct samu *sam_account = NULL; + DOM_SID user_sid; + DOM_SID group_sid; + bool username_was_mapped; + uint32_t i; + + uid_t uid = (uid_t)-1; + gid_t gid = (gid_t)-1; + + auth_serversupplied_info *result; + + result = make_server_info(NULL); + if (result == NULL) { + DEBUG(4, ("make_server_info failed!\n")); + return NT_STATUS_NO_MEMORY; + } + + /* + Here is where we should check the list of + trusted domains, and verify that the SID + matches. + */ + + memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid)); + memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid)); + + if (info->account_name) { + nt_username = talloc_strdup(result, info->account_name); + } else { + /* If the server didn't give us one, just use the one we sent + * them */ + nt_username = talloc_strdup(result, sent_nt_username); + } + if (!nt_username) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (info->domain_name) { + nt_domain = talloc_strdup(result, info->domain_name); + } else { + /* If the server didn't give us one, just use the one we sent + * them */ + nt_domain = talloc_strdup(result, domain); + } + if (!nt_domain) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + /* try to fill the SAM account.. If getpwnam() fails, then try the + add user script (2.2.x behavior). + + We use the _unmapped_ username here in an attempt to provide + consistent username mapping behavior between kerberos and NTLM[SSP] + authentication in domain mode security. I.E. Username mapping + should be applied to the fully qualified username + (e.g. DOMAIN\user) and not just the login name. Yes this means we + called map_username() unnecessarily in make_user_info_map() but + that is how the current code is designed. Making the change here + is the least disruptive place. -- jerry */ + + if ( !(sam_account = samu_new( result )) ) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + /* this call will try to create the user if necessary */ + + nt_status = fill_sam_account(result, nt_domain, sent_nt_username, + &found_username, &uid, &gid, sam_account, + &username_was_mapped); + + /* if we still don't have a valid unix account check for + 'map to guest = bad uid' */ + + if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE( result ); + if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) { + make_server_info_guest(server_info); + return NT_STATUS_OK; + } + return nt_status; + } + + if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_pass_last_set_time( + sam_account, + nt_time_to_unix(info->pass_last_set_time), + PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_pass_can_change_time( + sam_account, + nt_time_to_unix(info->pass_can_change_time), + PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_pass_must_change_time( + sam_account, + nt_time_to_unix(info->pass_must_change_time), + PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + /* save this here to _net_sam_logon() doesn't fail (it assumes a + valid struct samu) */ + + result->sam_account = sam_account; + result->unix_name = talloc_strdup(result, found_username); + + result->login_server = talloc_strdup(result, info->logon_server); + + /* Fill in the unix info we found on the way */ + + result->uid = uid; + result->gid = gid; + + /* Create a 'combined' list of all SIDs we might want in the SD */ + + result->num_sids = info->num_sids - 2; + result->sids = talloc_array(result, DOM_SID, result->num_sids); + if (result->sids == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i < result->num_sids; i++) { + memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i])); + } /* ensure we are never given NULL session keys */ ZERO_STRUCT(zeros); - if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) { + if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) { result->user_session_key = data_blob_null; } else { result->user_session_key = data_blob_talloc( - result, info3->user_sess_key, - sizeof(info3->user_sess_key)); + result, info->user_session_key, + sizeof(info->user_session_key)); } - if (memcmp(info3->lm_sess_key, zeros, 8) == 0) { + if (memcmp(info->lm_session_key, zeros, 8) == 0) { result->lm_session_key = data_blob_null; } else { result->lm_session_key = data_blob_talloc( - result, info3->lm_sess_key, - sizeof(info3->lm_sess_key)); + result, info->lm_session_key, + sizeof(info->lm_session_key)); } result->was_mapped = username_was_mapped; diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c index b24aa3a75b..26a1b7f101 100644 --- a/source3/auth/auth_winbind.c +++ b/source3/auth/auth_winbind.c @@ -25,31 +25,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response *response, NET_USER_INFO_3 *info3) -{ - uint8 *info3_ndr; - size_t len = response->length - sizeof(struct winbindd_response); - prs_struct ps; - if (len > 0) { - info3_ndr = (uint8 *)response->extra_data.data; - if (!prs_init(&ps, len, mem_ctx, UNMARSHALL)) { - return NT_STATUS_NO_MEMORY; - } - prs_copy_data_in(&ps, (char *)info3_ndr, len); - prs_set_offset(&ps,0); - if (!net_io_user_info3("", info3, &ps, 1, 3, False)) { - DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - prs_mem_free(&ps); - - return NT_STATUS_OK; - } else { - DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n")); - return NT_STATUS_UNSUCCESSFUL; - } -} - /* Authenticate a user with a challenge/response */ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, @@ -58,11 +33,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info) { - struct winbindd_request request; - struct winbindd_response response; - NSS_STATUS result; NTSTATUS nt_status; - NET_USER_INFO_3 info3; + wbcErr wbc_status; + struct wbcAuthUserParams params; + struct wbcAuthUserInfo *info = NULL; + struct wbcAuthErrorInfo *err = NULL; if (!user_info) { return NT_STATUS_INVALID_PARAMETER; @@ -82,36 +57,34 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, /* Send off request */ - ZERO_STRUCT(request); - ZERO_STRUCT(response); + params.account_name = user_info->smb_name; + params.domain_name = user_info->domain; + params.workstation_name = user_info->wksta_name; - request.flags = WBFLAG_PAM_INFO3_NDR; + params.flags = 0; + params.parameter_control= user_info->logon_parameters; - request.data.auth_crap.logon_parameters = user_info->logon_parameters; + params.level = WBC_AUTH_USER_LEVEL_RESPONSE; - fstrcpy(request.data.auth_crap.user, user_info->smb_name); - fstrcpy(request.data.auth_crap.domain, user_info->domain); - fstrcpy(request.data.auth_crap.workstation, user_info->wksta_name); + memcpy(params.password.response.challenge, + auth_context->challenge.data, + sizeof(params.password.response.challenge)); - memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal)); - - request.data.auth_crap.lm_resp_len = MIN(user_info->lm_resp.length, - sizeof(request.data.auth_crap.lm_resp)); - request.data.auth_crap.nt_resp_len = MIN(user_info->nt_resp.length, - sizeof(request.data.auth_crap.nt_resp)); - - memcpy(request.data.auth_crap.lm_resp, user_info->lm_resp.data, - request.data.auth_crap.lm_resp_len); - memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data, - request.data.auth_crap.nt_resp_len); + params.password.response.nt_length = user_info->nt_resp.length; + params.password.response.nt_data = user_info->nt_resp.data; + params.password.response.lm_length = user_info->lm_resp.length; + params.password.response.lm_data = user_info->lm_resp.data; /* we are contacting the privileged pipe */ become_root(); - result = winbindd_priv_request_response(WINBINDD_PAM_AUTH_CRAP, - &request, &response); + wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); unbecome_root(); - if ( result == NSS_STATUS_UNAVAIL ) { + if (wbc_status == WBC_ERR_NO_MEMORY) { + return NT_STATUS_NO_MEMORY; + } + + if (wbc_status == WBC_ERR_WINBIND_NOT_AVAILABLE) { struct auth_methods *auth_method = (struct auth_methods *)my_private_data; @@ -123,27 +96,29 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, DEBUG(0,("check_winbind_security: ERROR! my_private_data == NULL!\n")); } - nt_status = NT_STATUS(response.data.auth.nt_status); - - if (result == NSS_STATUS_SUCCESS && response.extra_data.data) { - if (NT_STATUS_IS_OK(nt_status)) { - if (NT_STATUS_IS_OK(nt_status = get_info3_from_ndr(mem_ctx, &response, &info3))) { - nt_status = make_server_info_info3(mem_ctx, - user_info->smb_name, user_info->domain, - server_info, &info3); - } - - if (NT_STATUS_IS_OK(nt_status)) { - if (user_info->was_mapped) { - (*server_info)->was_mapped = user_info->was_mapped; - } - } - } - } else if (NT_STATUS_IS_OK(nt_status)) { - nt_status = NT_STATUS_NO_LOGON_SERVERS; + if (wbc_status == WBC_ERR_AUTH_ERROR) { + nt_status = NT_STATUS(err->nt_status); + wbcFreeMemory(err); + return nt_status; + } + + if (!WBC_ERROR_IS_OK(wbc_status)) { + return NT_STATUS_LOGON_FAILURE; + } + + nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, + user_info->smb_name, + user_info->domain, + info, server_info); + wbcFreeMemory(info); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + if (user_info->was_mapped) { + (*server_info)->was_mapped = user_info->was_mapped; } - SAFE_FREE(response.extra_data.data); return nt_status; } diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index 79f402a7d4..e73d90859c 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -37,6 +37,7 @@ #include <string.h> #include <mntent.h> #include <fcntl.h> +#include <limits.h> #define MOUNT_CIFS_VERSION_MAJOR "1" #define MOUNT_CIFS_VERSION_MINOR "11" @@ -62,8 +63,6 @@ #define MS_BIND 4096 #endif -#define MAX_UNC_LEN 1024 - #define CONST_DISCARD(type, ptr) ((type) ((void *) (ptr))) const char *thisprogram; @@ -75,6 +74,7 @@ static int got_ip = 0; static int got_unc = 0; static int got_uid = 0; static int got_gid = 0; +static int free_share_name = 0; static char * user_name = NULL; static char * mountpassword = NULL; char * domain_name = NULL; @@ -205,8 +205,10 @@ static int open_cred_file(char * file_name) /* go past equals sign */ temp_val++; for(length = 0;length<4087;length++) { - if(temp_val[length] == '\n') + if ((temp_val[length] == '\n') + || (temp_val[length] == '\0')) { break; + } } if(length > 4086) { printf("mount.cifs failed due to malformed username in credentials file"); @@ -229,8 +231,10 @@ static int open_cred_file(char * file_name) /* go past equals sign */ temp_val++; for(length = 0;length<65;length++) { - if(temp_val[length] == '\n') + if ((temp_val[length] == '\n') + || (temp_val[length] == '\0')) { break; + } } if(length > 64) { printf("mount.cifs failed: password in credentials file too long\n"); @@ -258,8 +262,10 @@ static int open_cred_file(char * file_name) if(verboseflag) printf("\nDomain %s\n",temp_val); for(length = 0;length<65;length++) { - if(temp_val[length] == '\n') - break; + if ((temp_val[length] == '\n') + || (temp_val[length] == '\0')) { + break; + } } if(length > 64) { printf("mount.cifs failed: domain in credentials file too long\n"); @@ -831,27 +837,17 @@ static char * check_for_domain(char **ppuser) return domainnm; } -/* replace all occurances of "from" in a string with "to" */ -static void replace_char(char *string, char from, char to) -{ - while (string) { - string = strchr(string, from); - if (string) - *string = to; - } -} - /* Note that caller frees the returned buffer if necessary */ static char * parse_server(char ** punc_name) { char * unc_name = *punc_name; - int length = strnlen(unc_name, MAX_UNC_LEN); + int length = strnlen(unc_name,1024); char * share; char * ipaddress_string = NULL; struct hostent * host_entry = NULL; struct in_addr server_ipaddr; - if(length > (MAX_UNC_LEN - 1)) { + if(length > 1023) { printf("mount error: UNC name too long"); return NULL; } @@ -870,6 +866,7 @@ static char * parse_server(char ** punc_name) /* check for nfs syntax ie server:share */ share = strchr(unc_name,':'); if(share) { + free_share_name = 1; *punc_name = (char *)malloc(length+3); if(*punc_name == NULL) { /* put the original string back if @@ -877,9 +874,9 @@ static char * parse_server(char ** punc_name) *punc_name = unc_name; return NULL; } + *share = '/'; strncpy((*punc_name)+2,unc_name,length); - free(unc_name); unc_name = *punc_name; unc_name[length+2] = 0; goto continue_unc_parsing; @@ -890,21 +887,18 @@ static char * parse_server(char ** punc_name) } } else { continue_unc_parsing: - unc_name[0] = '\\'; - unc_name[1] = '\\'; + unc_name[0] = '/'; + unc_name[1] = '/'; unc_name += 2; - - /* convert any '/' in unc to '\\' */ - replace_char(unc_name, '/', '\\'); - - if ((share = strchr(unc_name,'\\'))) { + if ((share = strchr(unc_name, '/')) || + (share = strchr(unc_name,'\\'))) { *share = 0; /* temporarily terminate the string */ share += 1; if(got_ip == 0) { host_entry = gethostbyname(unc_name); } - *(share - 1) = '\\'; /* put delimiter back */ - if ((prefixpath = strchr(share, '\\'))) { + *(share - 1) = '/'; /* put the slash back */ + if ((prefixpath = strchr(share, '/'))) { *prefixpath = 0; /* permanently terminate the string */ if (!strlen(++prefixpath)) prefixpath = NULL; /* this needs to be done explicitly */ @@ -969,25 +963,6 @@ static struct option longopts[] = { { NULL, 0, NULL, 0 } }; -/* convert a string to uppercase. return false if the string - * wasn't ASCII or was a NULL ptr */ -static int -uppercase_string(char *string) -{ - if (!string) - return 0; - - while (*string) { - /* check for unicode */ - if ((unsigned char) string[0] & 0x80) - return 0; - *string = toupper((unsigned char) *string); - string++; - } - - return 1; -} - int main(int argc, char ** argv) { int c; @@ -1000,7 +975,6 @@ int main(int argc, char ** argv) char * options = NULL; char * resolved_path = NULL; char * temp; - char * dev_name; int rc; int rsize = 0; int wsize = 0; @@ -1037,16 +1011,8 @@ int main(int argc, char ** argv) printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname); #endif */ if(argc > 2) { - dev_name = argv[1]; - share_name = strndup(argv[1], MAX_UNC_LEN); - if (share_name == NULL) { - fprintf(stderr, "%s: %s", argv[0], strerror(ENOMEM)); - exit(1); - } + share_name = argv[1]; mountpoint = argv[2]; - } else { - mount_cifs_usage(); - exit(1); } /* add sharename in opts string as unc= parm */ @@ -1186,7 +1152,7 @@ int main(int argc, char ** argv) } } - if((argc < 3) || (dev_name == NULL) || (mountpoint == NULL)) { + if((argc < 3) || (share_name == NULL) || (mountpoint == NULL)) { mount_cifs_usage(); exit(1); } @@ -1344,12 +1310,10 @@ mount_retry: } if(verboseflag) printf("\nmount.cifs kernel mount options %s \n",options); - - /* convert all '\\' to '/' so that /proc/mounts looks pretty */ - replace_char(dev_name, '\\', '/'); - - if(mount(dev_name, mountpoint, "cifs", flags, options)) { + if(mount(share_name, mountpoint, "cifs", flags, options)) { /* remember to kill daemon on error */ + char * tmp; + switch (errno) { case 0: printf("mount failed but no error number set\n"); @@ -1360,9 +1324,12 @@ mount_retry: case ENXIO: if(retry == 0) { retry = 1; - if (uppercase_string(dev_name) && - uppercase_string(share_name) && - uppercase_string(prefixpath)) { + tmp = share_name; + while (*tmp && !(((unsigned char)tmp[0]) & 0x80)) { + *tmp = toupper((unsigned char)*tmp); + tmp++; + } + if(!*tmp) { printf("retrying with upper case share name\n"); goto mount_retry; } @@ -1376,7 +1343,7 @@ mount_retry: } else { pmntfile = setmntent(MOUNTED, "a+"); if(pmntfile) { - mountent.mnt_fsname = dev_name; + mountent.mnt_fsname = share_name; mountent.mnt_dir = mountpoint; mountent.mnt_type = CONST_DISCARD(char *,"cifs"); mountent.mnt_opts = (char *)malloc(220); @@ -1436,6 +1403,8 @@ mount_exit: free(resolved_path); } - free(share_name); + if(free_share_name) { + free(share_name); + } return rc; } diff --git a/source3/client/smbmnt.c b/source3/client/smbmnt.c deleted file mode 100644 index 198faca173..0000000000 --- a/source3/client/smbmnt.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * smbmnt.c - * - * Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke - * extensively modified by Tridge - * - * 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/>. - * - */ - -#define SMBMOUNT_MALLOC 1 - -#include "includes.h" - -#include <mntent.h> -#include <sys/utsname.h> - -#include <asm/types.h> -#include <asm/posix_types.h> -#include <linux/smb.h> -#include <linux/smb_mount.h> -#include <asm/unistd.h> - -#ifndef MS_MGC_VAL -/* This may look strange but MS_MGC_VAL is what we are looking for and - is what we need from <linux/fs.h> under libc systems and is - provided in standard includes on glibc systems. So... We - switch on what we need... */ -#include <linux/fs.h> -#endif - -static uid_t mount_uid; -static gid_t mount_gid; -static int mount_ro; -static unsigned mount_fmask; -static unsigned mount_dmask; -static int user_mount; -static char *options; - -static void -help(void) -{ - printf("\n"); - printf("Usage: smbmnt mount-point [options]\n"); - printf("Version %s\n\n",SAMBA_VERSION_STRING); - printf("-s share share name on server\n" - "-r mount read-only\n" - "-u uid mount as uid\n" - "-g gid mount as gid\n" - "-f mask permission mask for files\n" - "-d mask permission mask for directories\n" - "-o options name=value, list of options\n" - "-h print this help text\n"); -} - -static int -parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share) -{ - int opt; - - while ((opt = getopt (argc, argv, "s:u:g:rf:d:o:")) != EOF) - { - switch (opt) - { - case 's': - *share = optarg; - break; - case 'u': - if (!user_mount) { - mount_uid = strtol(optarg, NULL, 0); - } - break; - case 'g': - if (!user_mount) { - mount_gid = strtol(optarg, NULL, 0); - } - break; - case 'r': - mount_ro = 1; - break; - case 'f': - mount_fmask = strtol(optarg, NULL, 8); - break; - case 'd': - mount_dmask = strtol(optarg, NULL, 8); - break; - case 'o': - options = optarg; - break; - default: - return -1; - } - } - return 0; - -} - -static char * -fullpath(const char *p) -{ - char path[PATH_MAX+1]; - - if (strlen(p) > PATH_MAX) { - return NULL; - } - - if (realpath(p, path) == NULL) { - fprintf(stderr,"Failed to find real path for mount point %s: %s\n", - p, strerror(errno)); - exit(1); - } - return strdup(path); -} - -/* Check whether user is allowed to mount on the specified mount point. If it's - OK then we change into that directory - this prevents race conditions */ -static int mount_ok(char *mount_point) -{ - struct stat st; - - if (chdir(mount_point) != 0) { - return -1; - } - - if (stat(".", &st) != 0) { - return -1; - } - - if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - return -1; - } - - if ((getuid() != 0) && - ((getuid() != st.st_uid) || - ((st.st_mode & S_IRWXU) != S_IRWXU))) { - errno = EPERM; - return -1; - } - - return 0; -} - -/* Tries to mount using the appropriate format. For 2.2 the struct, - for 2.4 the ascii version. */ -static int -do_mount(char *share_name, unsigned int flags, struct smb_mount_data *data) -{ - char *opts; - struct utsname uts; - char *release, *major, *minor; - char *data1, *data2; - int ret; - char *saveptr = NULL; - - if (asprintf(&opts, - "version=7,uid=%d,gid=%d,file_mode=0%o,dir_mode=0%o,%s", - mount_uid, mount_gid, data->file_mode, - data->dir_mode,options) < 0) { - return -1; - } - - uname(&uts); - release = uts.release; - major = strtok_r(release, ".", &saveptr); - minor = strtok_r(NULL, ".", &saveptr); - if (major && minor && atoi(major) == 2 && atoi(minor) < 4) { - /* < 2.4, assume struct */ - data1 = (char *) data; - data2 = opts; - } else { - /* >= 2.4, assume ascii but fall back on struct */ - data1 = opts; - data2 = (char *) data; - } - - if (mount(share_name, ".", "smbfs", flags, data1) == 0) { - SAFE_FREE(opts); - return 0; - } - ret = mount(share_name, ".", "smbfs", flags, data2); - SAFE_FREE(opts); - return ret; -} - - int main(int argc, char *argv[]) -{ - char *mount_point, *share_name = NULL; - FILE *mtab; - int fd; - unsigned int flags; - struct smb_mount_data data; - struct mntent ment; - - memset(&data, 0, sizeof(struct smb_mount_data)); - - if (argc < 2) { - help(); - exit(1); - } - - if (argv[1][0] == '-') { - help(); - exit(1); - } - - if (getuid() != 0) { - user_mount = 1; - } - - if (geteuid() != 0) { - fprintf(stderr, "smbmnt must be installed suid root for direct user mounts (%d,%d)\n", getuid(), geteuid()); - exit(1); - } - - mount_uid = getuid(); - mount_gid = getgid(); - mount_fmask = umask(0); - umask(mount_fmask); - mount_fmask = ~mount_fmask; - - mount_point = fullpath(argv[1]); - - argv += 1; - argc -= 1; - - if (mount_ok(mount_point) != 0) { - fprintf(stderr, "cannot mount on %s: %s\n", - mount_point, strerror(errno)); - exit(1); - } - - data.version = SMB_MOUNT_VERSION; - - /* getuid() gives us the real uid, who may umount the fs */ - data.mounted_uid = getuid(); - - if (parse_args(argc, argv, &data, &share_name) != 0) { - help(); - return -1; - } - - data.uid = mount_uid; // truncates to 16-bits here!!! - data.gid = mount_gid; - data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_fmask; - data.dir_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_dmask; - - if (mount_dmask == 0) { - data.dir_mode = data.file_mode; - if ((data.dir_mode & S_IRUSR) != 0) - data.dir_mode |= S_IXUSR; - if ((data.dir_mode & S_IRGRP) != 0) - data.dir_mode |= S_IXGRP; - if ((data.dir_mode & S_IROTH) != 0) - data.dir_mode |= S_IXOTH; - } - - flags = MS_MGC_VAL | MS_NOSUID | MS_NODEV; - - if (mount_ro) flags |= MS_RDONLY; - - if (do_mount(share_name, flags, &data) < 0) { - switch (errno) { - case ENODEV: - fprintf(stderr, "ERROR: smbfs filesystem not supported by the kernel\n"); - break; - default: - perror("mount error"); - } - fprintf(stderr, "Please refer to the smbmnt(8) manual page\n"); - return -1; - } - - ment.mnt_fsname = share_name ? share_name : (char *)"none"; - ment.mnt_dir = mount_point; - ment.mnt_type = (char *)"smbfs"; - ment.mnt_opts = (char *)""; - ment.mnt_freq = 0; - ment.mnt_passno= 0; - - mount_point = ment.mnt_dir; - - if (mount_point == NULL) - { - fprintf(stderr, "Mount point too long\n"); - return -1; - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) - { - fprintf(stderr, "Can't get "MOUNTED"~ lock file"); - return 1; - } - close(fd); - - if ((mtab = setmntent(MOUNTED, "a+")) == NULL) - { - fprintf(stderr, "Can't open " MOUNTED); - return 1; - } - - if (addmntent(mtab, &ment) == 1) - { - fprintf(stderr, "Can't write mount entry"); - return 1; - } - if (fchmod(fileno(mtab), 0644) == -1) - { - fprintf(stderr, "Can't set perms on "MOUNTED); - return 1; - } - endmntent(mtab); - - if (unlink(MOUNTED"~") == -1) - { - fprintf(stderr, "Can't remove "MOUNTED"~"); - return 1; - } - - return 0; -} diff --git a/source3/client/smbmount.c b/source3/client/smbmount.c deleted file mode 100644 index ee4b180a89..0000000000 --- a/source3/client/smbmount.c +++ /dev/null @@ -1,1047 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMBFS mount program - Copyright (C) Andrew Tridgell 1999 - - 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 <mntent.h> -#include <asm/types.h> -#include <linux/smb_fs.h> - -extern bool in_client; -extern char *optarg; -extern int optind; - -static char *credentials; -static fstring my_netbios_name; -static char *password; -static char *username; -static fstring workgroup; -static char *mpoint; -static char *service; -static char *options; - -static struct sockaddr_storage dest_ip; -static bool have_ip; -static int smb_port = 0; -static bool got_user; -static bool got_pass; -static uid_t mount_uid; -static gid_t mount_gid; -static int mount_ro; -static unsigned mount_fmask; -static unsigned mount_dmask; -static bool use_kerberos; -/* TODO: Add code to detect smbfs version in kernel */ -static bool status32_smbfs = False; -static bool smbfs_has_unicode = False; -static bool smbfs_has_lfs = False; - -static void usage(void); - -static void exit_parent(int sig) -{ - /* parent simply exits when child says go... */ - exit(0); -} - -static void daemonize(void) -{ - int j, status; - pid_t child_pid; - - signal( SIGTERM, exit_parent ); - - if ((child_pid = sys_fork()) < 0) { - DEBUG(0,("could not fork\n")); - } - - if (child_pid > 0) { - while( 1 ) { - j = waitpid( child_pid, &status, 0 ); - if( j < 0 ) { - if( EINTR == errno ) { - continue; - } - status = errno; - } - break; - } - - /* If we get here - the child exited with some error status */ - if (WIFSIGNALED(status)) - exit(128 + WTERMSIG(status)); - else - exit(WEXITSTATUS(status)); - } - - signal( SIGTERM, SIG_DFL ); - chdir("/"); -} - -static void close_our_files(int client_fd) -{ - int i; - struct rlimit limits; - - getrlimit(RLIMIT_NOFILE,&limits); - for (i = 0; i< limits.rlim_max; i++) { - if (i == client_fd) - continue; - close(i); - } -} - -static void usr1_handler(int x) -{ - return; -} - - -/***************************************************** -return a connection to a server -*******************************************************/ -static struct cli_state *do_connection(char *the_service) -{ - struct cli_state *c; - struct nmb_name called, calling; - char *server_n; - struct sockaddr_storage ip; - char *server; - char *share; - const char *c_username; - const char *c_password; - TALLOC_CTX *ctx = talloc_tos(); - - if (the_service[0] != '\\' || the_service[1] != '\\') { - usage(); - exit(1); - } - - server = talloc_strdup(ctx, the_service+2); - if (!server) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - share = strchr_m(server,'\\'); - if (!share) { - usage(); - exit(1); - } - *share = 0; - share++; - - server_n = server; - - make_nmb_name(&calling, my_netbios_name, 0x0); - make_nmb_name(&called , server, 0x20); - - again: - zero_addr(&ip); - if (have_ip) ip = dest_ip; - - /* have to open a new connection */ - if (!(c=cli_initialise()) || (cli_set_port(c, smb_port) != smb_port) || - !NT_STATUS_IS_OK(cli_connect(c, server_n, &ip))) { - DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n)); - if (c) { - cli_shutdown(c); - } - return NULL; - } - - /* SPNEGO doesn't work till we get NTSTATUS error support */ - /* But it is REQUIRED for kerberos authentication */ - if(!use_kerberos) c->use_spnego = False; - - /* The kernel doesn't yet know how to sign it's packets */ - c->sign_info.allow_smb_signing = False; - - /* Use kerberos authentication if specified */ - c->use_kerberos = use_kerberos; - - if (!cli_session_request(c, &calling, &called)) { - char *p; - DEBUG(0,("%d: session request to %s failed (%s)\n", - sys_getpid(), called.name, cli_errstr(c))); - cli_shutdown(c); - if ((p=strchr_m(called.name, '.'))) { - *p = 0; - goto again; - } - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } - return NULL; - } - - DEBUG(4,("%d: session request ok\n", sys_getpid())); - - if (!cli_negprot(c)) { - DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid())); - cli_shutdown(c); - return NULL; - } - - if (!got_pass) { - char *pass = getpass("Password: "); - if (pass) { - password = talloc_strdup(talloc_tos(), pass); - if (!password) { - return NULL; - } - } - } - - /* This should be right for current smbfs. Future versions will support - large files as well as unicode and oplocks. */ - c->capabilities &= ~(CAP_NT_SMBS | CAP_NT_FIND | CAP_LEVEL_II_OPLOCKS); - if (!smbfs_has_lfs) - c->capabilities &= ~CAP_LARGE_FILES; - if (!smbfs_has_unicode) - c->capabilities &= ~CAP_UNICODE; - if (!status32_smbfs) { - c->capabilities &= ~CAP_STATUS32; - c->force_dos_errors = True; - } - - c_password = password ? password : ""; - c_username = username ? username : ""; - - if (!NT_STATUS_IS_OK(cli_session_setup(c, - c_username, - c_password, strlen(c_password), - c_password, strlen(c_password), - workgroup))) { - /* if a password was not supplied then try again with a - null username */ - if (c_password[0] || !c_username[0] || - !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, workgroup))) { - DEBUG(0,("%d: session setup failed: %s\n", - sys_getpid(), cli_errstr(c))); - cli_shutdown(c); - return NULL; - } - DEBUG(0,("Anonymous login successful\n")); - } - - DEBUG(4,("%d: session setup ok\n", sys_getpid())); - - if (!cli_send_tconX(c, share, "?????", - c_password, strlen(c_password)+1)) { - DEBUG(0,("%d: tree connect failed: %s\n", - sys_getpid(), cli_errstr(c))); - cli_shutdown(c); - return NULL; - } - - DEBUG(4,("%d: tconx ok\n", sys_getpid())); - - got_pass = True; - - return c; -} - -/**************************************************************************** -unmount smbfs (this is a bailout routine to clean up if a reconnect fails) - Code blatently stolen from smbumount.c - -mhw- -****************************************************************************/ -static void smb_umount(char *mount_point) -{ - int fd; - struct mntent *mnt; - FILE* mtab; - FILE* new_mtab; - - /* Programmers Note: - This routine only gets called to the scene of a disaster - to shoot the survivors... A connection that was working - has now apparently failed. We have an active mount point - (presumably) that we need to dump. If we get errors along - the way - make some noise, but we are already turning out - the lights to exit anyways... - */ - if (umount(mount_point) != 0) { - DEBUG(0,("%d: Could not umount %s: %s\n", - sys_getpid(), mount_point, strerror(errno))); - return; - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) { - DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid())); - return; - } - - close(fd); - - if ((mtab = setmntent(MOUNTED, "r")) == NULL) { - DEBUG(0,("%d: Can't open " MOUNTED ": %s\n", - sys_getpid(), strerror(errno))); - return; - } - -#define MOUNTED_TMP MOUNTED".tmp" - - if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { - DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n", - sys_getpid(), strerror(errno))); - endmntent(mtab); - return; - } - - while ((mnt = getmntent(mtab)) != NULL) { - if (strcmp(mnt->mnt_dir, mount_point) != 0) { - addmntent(new_mtab, mnt); - } - } - - endmntent(mtab); - - if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { - DEBUG(0,("%d: Error changing mode of %s: %s\n", - sys_getpid(), MOUNTED_TMP, strerror(errno))); - return; - } - - endmntent(new_mtab); - - if (rename(MOUNTED_TMP, MOUNTED) < 0) { - DEBUG(0,("%d: Cannot rename %s to %s: %s\n", - sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno))); - return; - } - - if (unlink(MOUNTED"~") == -1) { - DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid())); - return; - } -} - - -/* - * Call the smbfs ioctl to install a connection socket, - * then wait for a signal to reconnect. Note that we do - * not exit after open_sockets() or send_login() errors, - * as the smbfs mount would then have no way to recover. - */ -static void send_fs_socket(char *the_service, char *mount_point, struct cli_state *c) -{ - int fd, closed = 0, res = 1; - pid_t parentpid = getppid(); - struct smb_conn_opt conn_options; - - memset(&conn_options, 0, sizeof(conn_options)); - - while (1) { - if ((fd = open(mount_point, O_RDONLY)) < 0) { - DEBUG(0,("mount.smbfs[%d]: can't open %s\n", - sys_getpid(), mount_point)); - break; - } - - conn_options.fd = c->fd; - conn_options.protocol = c->protocol; - conn_options.case_handling = SMB_CASE_DEFAULT; - conn_options.max_xmit = c->max_xmit; - conn_options.server_uid = c->vuid; - conn_options.tid = c->cnum; - conn_options.secmode = c->sec_mode; - conn_options.rawmode = 0; - conn_options.sesskey = c->sesskey; - conn_options.maxraw = 0; - conn_options.capabilities = c->capabilities; - conn_options.serverzone = c->serverzone/60; - - res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options); - if (res != 0) { - DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n", - sys_getpid(), res)); - close(fd); - break; - } - - if (parentpid) { - /* Ok... We are going to kill the parent. Now - is the time to break the process group... */ - setsid(); - /* Send a signal to the parent to terminate */ - kill(parentpid, SIGTERM); - parentpid = 0; - } - - close(fd); - - /* This looks wierd but we are only closing the userspace - side, the connection has already been passed to smbfs and - it has increased the usage count on the socket. - - If we don't do this we will "leak" sockets and memory on - each reconnection we have to make. */ - c->smb_rw_error = SMB_DO_NOT_DO_TDIS; - cli_shutdown(c); - c = NULL; - - if (!closed) { - /* close the name cache so that close_our_files() doesn't steal its FD */ - namecache_shutdown(); - - /* redirect stdout & stderr since we can't know that - the library functions we use are using DEBUG. */ - if ( (fd = open("/dev/null", O_WRONLY)) < 0) - DEBUG(2,("mount.smbfs: can't open /dev/null\n")); - close_our_files(fd); - if (fd >= 0) { - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - close(fd); - } - - /* here we are no longer interactive */ - set_remote_machine_name("smbmount", False); /* sneaky ... */ - setup_logging("mount.smbfs", False); - reopen_logs(); - DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid())); - - closed = 1; - } - - /* Wait for a signal from smbfs ... but don't continue - until we actually get a new connection. */ - while (!c) { - CatchSignal(SIGUSR1, &usr1_handler); - pause(); - DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid())); - c = do_connection(the_service); - } - } - - smb_umount(mount_point); - DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid())); - exit(1); -} - - -/** - * Mount a smbfs - **/ - -#define NUM_ARGS 20 - -static void init_mount(void) -{ - char mount_point[PATH_MAX+1]; - TALLOC_CTX *ctx = talloc_tos(); - char *svc2; - struct cli_state *c; - const char *args[NUM_ARGS]; - int i, status; - - if (realpath(mpoint, mount_point) == NULL) { - fprintf(stderr, "Could not resolve mount point %s\n", mpoint); - return; - } - - - c = do_connection(service); - if (!c) { - fprintf(stderr,"SMB connection failed\n"); - exit(1); - } - - /* - Set up to return as a daemon child and wait in the parent - until the child say it's ready... - */ - daemonize(); - - svc2 = talloc_strdup(ctx, service); - if (!svc2) { - fprintf(stderr, "Out of memory.\n"); - exit(ENOMEM); - } - string_replace(svc2, '\\','/'); - string_replace(svc2, ' ','_'); - - memset(args, 0, sizeof(args[0])*NUM_ARGS); - - i=0; - args[i++] = "smbmnt"; - - args[i++] = mount_point; - args[i++] = "-s"; - args[i++] = svc2; - - if (mount_ro && i < NUM_ARGS-2) { - args[i++] = "-r"; - } - if (mount_uid && i < NUM_ARGS-3) { - args[i++] = "-u"; - args[i] = talloc_asprintf(ctx, "%d", mount_uid); - if (!args[i]) { - fprintf(stderr, "Out of memory.\n"); - exit(ENOMEM); - } - i++; - } - if (mount_gid && i < NUM_ARGS-3) { - args[i++] = "-g"; - args[i] = talloc_asprintf(ctx, "%d", mount_gid); - if (!args[i]) { - fprintf(stderr, "Out of memory.\n"); - exit(ENOMEM); - } - i++; - } - if (mount_fmask && i < NUM_ARGS-3) { - args[i++] = "-f"; - args[i] = talloc_asprintf(ctx, "0%o", mount_fmask); - if (!args[i]) { - fprintf(stderr, "Out of memory.\n"); - exit(ENOMEM); - } - i++; - } - if (mount_dmask && i < NUM_ARGS-3) { - args[i++] = "-d"; - args[i] = talloc_asprintf(ctx, "0%o", mount_dmask); - if (!args[i]) { - fprintf(stderr, "Out of memory.\n"); - exit(ENOMEM); - } - i++; - } - if (options && i < NUM_ARGS-3) { - args[i++] = "-o"; - args[i++] = options; - } - - if (sys_fork() == 0) { - char *smbmnt_path; - - asprintf(&smbmnt_path, "%s/smbmnt", get_dyn_BINDIR()); - - if (file_exist(smbmnt_path, NULL)) { - execv(smbmnt_path, (char * const *)args); - fprintf(stderr, - "smbfs/init_mount: execv of %s failed. Error was %s.", - smbmnt_path, strerror(errno)); - } else { - execvp("smbmnt", (char * const *)args); - fprintf(stderr, - "smbfs/init_mount: execv of %s failed. Error was %s.", - "smbmnt", strerror(errno)); - } - free(smbmnt_path); - exit(1); - } - - if (waitpid(-1, &status, 0) == -1) { - fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) ); - /* FIXME: do some proper error handling */ - exit(1); - } - - if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { - fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status)); - /* FIXME: do some proper error handling */ - exit(1); - } else if (WIFSIGNALED(status)) { - fprintf(stderr, "smbmnt killed by signal %d\n", WTERMSIG(status)); - exit(1); - } - - /* Ok... This is the rubicon for that mount point... At any point - after this, if the connections fail and can not be reconstructed - for any reason, we will have to unmount the mount point. There - is no exit from the next call... - */ - send_fs_socket(service, mount_point, c); -} - - -/**************************************************************************** -get a password from a a file or file descriptor -exit on failure (from smbclient, move to libsmb or shared .c file?) -****************************************************************************/ - -static void get_password_file(void) -{ - int fd = -1; - char *p; - bool close_it = False; - char *spec = NULL; - TALLOC_CTX *ctx = talloc_tos(); - char pass[128]; - - if ((p = getenv("PASSWD_FD")) != NULL) { - spec = talloc_asprintf(ctx, - "descriptor %s", - p); - if (!spec) { - fprintf(stderr, "Out of memory.\n"); - exit(ENOMEM); - } - fd = atoi(p); - close_it = False; - } else if ((p = getenv("PASSWD_FILE")) != NULL) { - fd = sys_open(p, O_RDONLY, 0); - spec = talloc_strdup(ctx, p); - if (!spec) { - fprintf(stderr, "Out of memory.\n"); - exit(ENOMEM); - } - if (fd < 0) { - fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n", - spec, strerror(errno)); - exit(1); - } - close_it = True; - } - - for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */ - p && p - pass < sizeof(pass);) { - switch (read(fd, p, 1)) { - case 1: - if (*p != '\n' && *p != '\0') { - *++p = '\0'; /* advance p, and null-terminate pass */ - break; - } - case 0: - if (p - pass) { - *p = '\0'; /* null-terminate it, just in case... */ - p = NULL; /* then force the loop condition to become false */ - break; - } else { - fprintf(stderr, "Error reading password from file %s: %s\n", - spec, "empty password\n"); - exit(1); - } - - default: - fprintf(stderr, "Error reading password from file %s: %s\n", - spec, strerror(errno)); - exit(1); - } - } - password = talloc_strdup(ctx, pass); - if (close_it) - close(fd); -} - -/**************************************************************************** -get username and password from a credentials file -exit on failure (from smbclient, move to libsmb or shared .c file?) -****************************************************************************/ - -static void read_credentials_file(const char *filename) -{ - FILE *auth; - fstring buf; - uint16 len = 0; - char *ptr, *val, *param; - - if ((auth=sys_fopen(filename, "r")) == NULL) - { - /* fail if we can't open the credentials file */ - DEBUG(0,("ERROR: Unable to open credentials file!\n")); - exit (-1); - } - - while (!feof(auth)) - { - /* get a line from the file */ - if (!fgets (buf, sizeof(buf), auth)) - continue; - len = strlen(buf); - - if ((len) && (buf[len-1]=='\n')) - { - buf[len-1] = '\0'; - len--; - } - if (len == 0) - continue; - - /* break up the line into parameter & value. - will need to eat a little whitespace possibly */ - param = buf; - if (!(ptr = strchr (buf, '='))) - continue; - val = ptr+1; - *ptr = '\0'; - - /* eat leading white space */ - while ((*val!='\0') && ((*val==' ') || (*val=='\t'))) - val++; - - if (strwicmp("password", param) == 0) - { - password = talloc_strdup(talloc_tos(),val); - got_pass = True; - } - else if (strwicmp("username", param) == 0) { - username = talloc_strdup(talloc_tos(), val); - } - - memset(buf, 0, sizeof(buf)); - } - fclose(auth); -} - - -/**************************************************************************** -usage on the program -****************************************************************************/ -static void usage(void) -{ - printf("Usage: mount.smbfs service mountpoint [-o options,...]\n"); - - printf("Version %s\n\n",SAMBA_VERSION_STRING); - - printf("Please be aware that smbfs is deprecated in favor of " - "cifs\n\n"); - - printf( -"Options:\n\ - username=<arg> SMB username\n\ - password=<arg> SMB password\n\ - credentials=<filename> file with username/password\n\ - krb use kerberos (active directory)\n\ - netbiosname=<arg> source NetBIOS name\n\ - uid=<arg> mount uid or username\n\ - gid=<arg> mount gid or groupname\n\ - port=<arg> remote SMB port number\n\ - fmask=<arg> file umask\n\ - dmask=<arg> directory umask\n\ - debug=<arg> debug level\n\ - ip=<arg> destination host or IP address\n\ - workgroup=<arg> workgroup on destination\n\ - sockopt=<arg> TCP socket options\n\ - scope=<arg> NetBIOS scope\n\ - iocharset=<arg> Linux charset (iso8859-1, utf8)\n\ - codepage=<arg> server codepage (cp850)\n\ - unicode use unicode when communicating with server\n\ - lfs large file system support\n\ - ttl=<arg> dircache time to live\n\ - guest don't prompt for a password\n\ - ro mount read-only\n\ - rw mount read-write\n\ -\n\ -This command is designed to be run from within /bin/mount by giving\n\ -the option '-t smbfs'. For example:\n\ - mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\ -"); -} - - -/**************************************************************************** - Argument parsing for mount.smbfs interface - mount will call us like this: - mount.smbfs device mountpoint -o <options> - - <options> is never empty, containing at least rw or ro - ****************************************************************************/ -static void parse_mount_smb(int argc, char **argv) -{ - int opt; - char *opts; - char *opteq; - int val; - char *saveptr = NULL; - TALLOC_CTX *ctx = talloc_tos(); - - /* FIXME: This function can silently fail if the arguments are - * not in the expected order. - - > The arguments syntax of smbmount 2.2.3a (smbfs of Debian stable) - > requires that one gives "-o" before further options like username=... - > . Without -o, the username=.. setting is *silently* ignored. I've - > spent about an hour trying to find out why I couldn't log in now.. - - */ - - - if (argc < 2 || argv[1][0] == '-') { - usage(); - exit(1); - } - - service = talloc_strdup(ctx, argv[1]); - if (!service) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - mpoint = talloc_strdup(ctx, argv[2]); - if (!mpoint) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - - /* Convert any '/' characters in the service name to - '\' characters */ - string_replace(service, '/','\\'); - argc -= 2; - argv += 2; - - opt = getopt(argc, argv, "o:"); - if(opt != 'o') { - return; - } - - options = talloc_strdup(ctx, ""); - if (!options) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - - /* - * option parsing from nfsmount.c (util-linux-2.9u) - */ - for (opts = strtok_r(optarg, ",", &saveptr); opts; - opts = strtok_r(NULL, ",", &saveptr)) { - DEBUG(3, ("opts: %s\n", opts)); - if ((opteq = strchr_m(opts, '='))) { - val = atoi(opteq + 1); - *opteq = '\0'; - - if (!strcmp(opts, "username") || - !strcmp(opts, "logon")) { - char *lp; - got_user = True; - username = talloc_strdup(ctx, opteq+1); - if (!username) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - if ((lp=strchr_m(username,'%'))) { - *lp = 0; - password = talloc_strdup(ctx, lp+1); - if (!password) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - got_pass = True; - memset(strchr_m(opteq+1,'%')+1,'X',strlen(password)); - } - if ((lp=strchr_m(username,'/'))) { - *lp = 0; - fstrcpy(workgroup,lp+1); - } - } else if(!strcmp(opts, "passwd") || - !strcmp(opts, "password")) { - password = talloc_strdup(ctx,opteq+1); - if (!password) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - got_pass = True; - memset(opteq+1,'X',strlen(password)); - } else if(!strcmp(opts, "credentials")) { - credentials = talloc_strdup(ctx,opteq+1); - if (!credentials) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - } else if(!strcmp(opts, "netbiosname")) { - fstrcpy(my_netbios_name,opteq+1); - } else if(!strcmp(opts, "uid")) { - mount_uid = nametouid(opteq+1); - } else if(!strcmp(opts, "gid")) { - mount_gid = nametogid(opteq+1); - } else if(!strcmp(opts, "port")) { - smb_port = val; - } else if(!strcmp(opts, "fmask")) { - mount_fmask = strtol(opteq+1, NULL, 8); - } else if(!strcmp(opts, "dmask")) { - mount_dmask = strtol(opteq+1, NULL, 8); - } else if(!strcmp(opts, "debug")) { - DEBUGLEVEL = val; - } else if(!strcmp(opts, "ip")) { - if (!interpret_string_addr(&dest_ip, opteq+1, - 0)) { - fprintf(stderr,"Can't resolve address %s\n", opteq+1); - exit(1); - } - have_ip = True; - } else if(!strcmp(opts, "workgroup")) { - fstrcpy(workgroup,opteq+1); - } else if(!strcmp(opts, "sockopt")) { - lp_do_parameter(-1, "socket options", opteq+1); - } else if(!strcmp(opts, "scope")) { - set_global_scope(opteq+1); - } else { - options = talloc_asprintf_append(options, - "%s=%s,", - opts, opteq+1); - if (!options) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - } - } else { - val = 1; - if(!strcmp(opts, "nocaps")) { - fprintf(stderr, "Unhandled option: %s\n", opteq+1); - exit(1); - } else if(!strcmp(opts, "guest")) { - password = talloc_strdup(talloc_tos(), ""); - if (!password) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - got_pass = True; - } else if(!strcmp(opts, "krb")) { -#ifdef HAVE_KRB5 - - use_kerberos = True; - if(!status32_smbfs) - fprintf(stderr, "Warning: kerberos support will only work for samba servers\n"); -#else - fprintf(stderr,"No kerberos support compiled in\n"); - exit(1); -#endif - } else if(!strcmp(opts, "rw")) { - mount_ro = 0; - } else if(!strcmp(opts, "ro")) { - mount_ro = 1; - } else if(!strcmp(opts, "unicode")) { - smbfs_has_unicode = True; - } else if(!strcmp(opts, "lfs")) { - smbfs_has_lfs = True; - } else { - options = talloc_asprintf_append(options, - "%s,", - opts); - if (!options) { - fprintf(stderr,"Out of memory\n"); - exit(ENOMEM); - } - } - } - } - - if (!service || !*service) { - usage(); - exit(1); - } - - if (options && *options && options[strlen(options)-1] == ',') { - options[strlen(options)-1] = '\0'; /* remove trailing , */ - DEBUG(3,("passthrough options '%s'\n", options)); - } -} - -/**************************************************************************** - main program -****************************************************************************/ - int main(int argc,char *argv[]) -{ - TALLOC_CTX *frame = talloc_stackframe(); - char *p; - - DEBUGLEVEL = 1; - - load_case_tables(); - - /* here we are interactive, even if run from autofs */ - setup_logging("mount.smbfs",True); - -#if 0 /* JRA - Urban says not needed ? */ - /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default - is to not announce any unicode capabilities as current smbfs does - not support it. */ - p = getenv("CLI_FORCE_ASCII"); - if (p && !strcmp(p, "false")) - unsetenv("CLI_FORCE_ASCII"); - else - setenv("CLI_FORCE_ASCII", "true", 1); -#endif - - in_client = True; /* Make sure that we tell lp_load we are */ - - if (getenv("USER")) { - username = talloc_strdup(frame, getenv("USER")); - if (!username) { - exit(ENOMEM); - } - - if ((p=strchr_m(username,'%'))) { - *p = 0; - password = talloc_strdup(frame, p+1); - if (!password) { - exit(ENOMEM); - } - got_pass = True; - memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password)); - } - strupper_m(username); - } - - if (getenv("PASSWD")) { - password = talloc_strdup(frame, getenv("PASSWD")); - if (!password) { - exit(ENOMEM); - } - got_pass = True; - } - - if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) { - get_password_file(); - got_pass = True; - } - - if ((!username || *username == 0) && getenv("LOGNAME")) { - username = talloc_strdup(frame, getenv("LOGNAME")); - if (!username) { - exit(ENOMEM); - } - } - - if (!lp_load(get_dyn_CONFIGFILE(),True,False,False,True)) { - fprintf(stderr, "Can't load %s - run testparm to debug it\n", - get_dyn_CONFIGFILE()); - } - - parse_mount_smb(argc, argv); - - if (use_kerberos && !got_user) { - got_pass = True; - } - - if (credentials && *credentials != 0) { - read_credentials_file(credentials); - } - - DEBUG(3,("mount.smbfs started (version %s)\n", SAMBA_VERSION_STRING)); - - if (*workgroup == 0) { - fstrcpy(workgroup,lp_workgroup()); - } - - load_interfaces(); - if (!*my_netbios_name) { - fstrcpy(my_netbios_name, myhostname()); - } - strupper_m(my_netbios_name); - - init_mount(); - TALLOC_FREE(frame); - return 0; -} diff --git a/source3/client/smbumount.c b/source3/client/smbumount.c deleted file mode 100644 index e74c31299c..0000000000 --- a/source3/client/smbumount.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * smbumount.c - * - * Copyright (C) 1995-1998 by Volker Lendecke - * - */ - -#define SMBMOUNT_MALLOC 1 - -#include "includes.h" - -#include <mntent.h> - -#include <asm/types.h> -#include <asm/posix_types.h> -#include <linux/smb.h> -#include <linux/smb_mount.h> -#include <linux/smb_fs.h> - -/* This is a (hopefully) temporary hack due to the fact that - sizeof( uid_t ) != sizeof( __kernel_uid_t ) under glibc. - This may change in the future and smb.h may get fixed in the - future. In the mean time, it's ugly hack time - get over it. -*/ -#undef SMB_IOC_GETMOUNTUID -#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t) - -#ifndef O_NOFOLLOW -#define O_NOFOLLOW 0400000 -#endif - -static void -usage(void) -{ - printf("usage: smbumount mountpoint\n\n"); - printf("Please be aware that smbfs is deprecated in favor of " - "cifs\n"); -} - -static int -umount_ok(const char *mount_point) -{ - /* we set O_NOFOLLOW to prevent users playing games with symlinks to - umount filesystems they don't own */ - int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0); - __kernel_uid32_t mount_uid; - - if (fid == -1) { - fprintf(stderr, "Could not open %s: %s\n", - mount_point, strerror(errno)); - return -1; - } - - if (ioctl(fid, SMB_IOC_GETMOUNTUID32, &mount_uid) != 0) { - __kernel_uid_t mount_uid16; - if (ioctl(fid, SMB_IOC_GETMOUNTUID, &mount_uid16) != 0) { - fprintf(stderr, "%s probably not smb-filesystem\n", - mount_point); - return -1; - } - mount_uid = mount_uid16; - } - - if ((getuid() != 0) - && (mount_uid != getuid())) { - fprintf(stderr, "You are not allowed to umount %s\n", - mount_point); - return -1; - } - - close(fid); - return 0; -} - -/* Make a canonical pathname from PATH. Returns a freshly malloced string. - It is up the *caller* to ensure that the PATH is sensible. i.e. - canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.'' - is not a legal pathname for ``/dev/fd0'' Anything we cannot parse - we return unmodified. */ -static char * -canonicalize (char *path) -{ - char *canonical = (char*)malloc (PATH_MAX + 1); - - if (!canonical) { - fprintf(stderr, "Error! Not enough memory!\n"); - return NULL; - } - - if (strlen(path) > PATH_MAX) { - fprintf(stderr, "Mount point string too long\n"); - return NULL; - } - - if (path == NULL) - return NULL; - - if (realpath (path, canonical)) - return canonical; - - strncpy (canonical, path, PATH_MAX); - canonical[PATH_MAX] = '\0'; - return canonical; -} - - -int -main(int argc, char *argv[]) -{ - int fd; - char* mount_point; - struct mntent *mnt; - FILE* mtab; - FILE* new_mtab; - TALLOC_CTX *frame = talloc_stackframe(); - - if (argc != 2) { - usage(); - exit(1); - } - - if (geteuid() != 0) { - fprintf(stderr, "smbumount must be installed suid root\n"); - exit(1); - } - - mount_point = canonicalize(argv[1]); - - if (mount_point == NULL) - { - exit(1); - } - - if (umount_ok(mount_point) != 0) { - exit(1); - } - - if (umount(mount_point) != 0) { - fprintf(stderr, "Could not umount %s: %s\n", - mount_point, strerror(errno)); - exit(1); - } - - if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) - { - fprintf(stderr, "Can't get "MOUNTED"~ lock file"); - return 1; - } - close(fd); - - if ((mtab = setmntent(MOUNTED, "r")) == NULL) { - fprintf(stderr, "Can't open " MOUNTED ": %s\n", - strerror(errno)); - return 1; - } - -#define MOUNTED_TMP MOUNTED".tmp" - - if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { - fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n", - strerror(errno)); - endmntent(mtab); - return 1; - } - - while ((mnt = getmntent(mtab)) != NULL) { - if (strcmp(mnt->mnt_dir, mount_point) != 0) { - addmntent(new_mtab, mnt); - } - } - - endmntent(mtab); - - if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { - fprintf(stderr, "Error changing mode of %s: %s\n", - MOUNTED_TMP, strerror(errno)); - exit(1); - } - - endmntent(new_mtab); - - if (rename(MOUNTED_TMP, MOUNTED) < 0) { - fprintf(stderr, "Cannot rename %s to %s: %s\n", - MOUNTED, MOUNTED_TMP, strerror(errno)); - exit(1); - } - - if (unlink(MOUNTED"~") == -1) - { - fprintf(stderr, "Can't remove "MOUNTED"~"); - return 1; - } - - TALLOC_FREE(frame); - return 0; -} diff --git a/source3/configure.in b/source3/configure.in index f3187aa915..056c0f8049 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -15,260 +15,11 @@ case "$PATH" in ;; esac -SMB_VERSION_STRING=`cat $srcdir/include/version.h | grep 'SAMBA_VERSION_OFFICIAL_STRING' | cut -d '"' -f2` -echo "SAMBA VERSION: ${SMB_VERSION_STRING}" - -SAMBA_VERSION_GIT_COMMIT_FULLREV=`cat $srcdir/include/version.h | grep 'SAMBA_VERSION_GIT_COMMIT_FULLREV' | cut -d ' ' -f3- | cut -d '"' -f2` -if test -n "${SAMBA_VERSION_GIT_COMMIT_FULLREV}";then - echo "BUILD COMMIT REVISION: ${SAMBA_VERSION_GIT_COMMIT_FULLREV}" -fi -SAMBA_VERSION_GIT_COMMIT_DATE=`cat $srcdir/include/version.h | grep 'SAMBA_VERSION_GIT_COMMIT_DATE' | cut -d ' ' -f3-` -if test -n "${SAMBA_VERSION_GIT_COMMIT_DATE}";then - echo "BUILD COMMIT DATE: ${SAMBA_VERSION_GIT_COMMIT_DATE}" -fi -SAMBA_VERSION_GIT_COMMIT_TIME=`cat $srcdir/include/version.h | grep 'SAMBA_VERSION_GIT_COMMIT_TIME' | cut -d ' ' -f3-` -if test -n "${SAMBA_VERSION_GIT_COMMIT_TIME}";then - echo "BUILD COMMIT TIME: ${SAMBA_VERSION_GIT_COMMIT_TIME}" - - # just to keep the build-farm gui happy for now... - echo "BUILD REVISION: ${SAMBA_VERSION_GIT_COMMIT_TIME}" -fi - -AC_LIBREPLACE_LOCATION_CHECKS - -AC_DISABLE_STATIC -AC_ENABLE_SHARED - -################################################# -# Directory handling stuff to support both the -# legacy SAMBA directories and FHS compliant -# ones... -AC_PREFIX_DEFAULT(/usr/local/samba) - -rootsbindir="\${SBINDIR}" -lockdir="\${VARDIR}/locks" -piddir="\${VARDIR}/locks" -test "${mandir}" || mandir="\${prefix}/man" -logfilebase="\${VARDIR}" -privatedir="\${prefix}/private" -test "${libdir}" || libdir="\${prefix}/lib" -pammodulesdir="\${LIBDIR}/security" -configdir="\${LIBDIR}" -swatdir="\${prefix}/swat" -codepagedir="\${LIBDIR}" -statedir="\${LOCKDIR}" -cachedir="\${LOCKDIR}" - -AC_ARG_WITH(fhs, -[AS_HELP_STRING([--with-fhs],[Use FHS-compliant paths (default=no)])], -[ case "$withval" in - yes) - lockdir="\${VARDIR}/lib/samba" - piddir="\${VARDIR}/run" - mandir="\${prefix}/share/man" - logfilebase="\${VARDIR}/log/samba" - privatedir="\${CONFIGDIR}/private" - test "${libdir}" || libdir="\${prefix}/lib/samba" - configdir="\${sysconfdir}/samba" - swatdir="\${DATADIR}/samba/swat" - codepagedir="\${LIBDIR}" - statedir="\${VARDIR}/lib/samba" - cachedir="\${VARDIR}/lib/samba" - AC_DEFINE(FHS_COMPATIBLE, 1, [Whether to use fully FHS-compatible paths]) - ;; - esac]) - -################################################# -# set private directory location -AC_ARG_WITH(privatedir, -[AS_HELP_STRING([--with-privatedir=DIR], [Where to put smbpasswd ($ac_default_prefix/private)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody calls it without argument - # - AC_MSG_WARN([--with-privatedir called without argument - will use default]) - ;; - * ) - privatedir="$withval" - ;; - esac]) - -################################################# -# set root sbin directory location -AC_ARG_WITH(rootsbindir, -[AS_HELP_STRING([--with-rootsbindir=DIR], [Which directory to use for root sbin ($ac_default_prefix/sbin)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody calls it without argument - # - AC_MSG_WARN([--with-rootsbindir called without argument - will use default]) - ;; - * ) - rootsbindir="$withval" - ;; - esac]) - -################################################# -# set lock directory location -AC_ARG_WITH(lockdir, -[AS_HELP_STRING([--with-lockdir=DIR], [Where to put lock files ($ac_default_prefix/var/locks)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody calls it without argument - # - AC_MSG_WARN([--with-lockdir called without argument - will use default]) - ;; - * ) - lockdir="$withval" - ;; - esac]) - -################################################# -# set pid directory location -AC_ARG_WITH(piddir, -[AS_HELP_STRING([--with-piddir=DIR], [Where to put pid files ($ac_default_prefix/var/locks)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody calls it without argument - # - AC_MSG_WARN([--with-piddir called without argument - will use default]) - ;; - * ) - piddir="$withval" - ;; - esac]) - -################################################# -# set SWAT directory location -AC_ARG_WITH(swatdir, -[AS_HELP_STRING([--with-swatdir=DIR], [Where to put SWAT files ($ac_default_prefix/swat)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody does it - # - AC_MSG_WARN([--with-swatdir called without argument - will use default]) - ;; - * ) - swatdir="$withval" - ;; - esac]) - -################################################# -# set configuration directory location -AC_ARG_WITH(configdir, -[AS_HELP_STRING([--with-configdir=DIR], [Where to put configuration files ($libdir)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody does it - # - AC_MSG_WARN([--with-configdir called without argument - will use default]) - ;; - * ) - configdir="$withval" - ;; - esac]) - -################################################# -# set log directory location -AC_ARG_WITH(logfilebase, -[AS_HELP_STRING([--with-logfilebase=DIR], [Where to put log files ($VARDIR)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody does it - # - AC_MSG_WARN([--with-logfilebase called without argument - will use default]) - ;; - * ) - logfilebase="$withval" - ;; - esac]) - - -################################################# -# set ctdb source directory location -AC_ARG_WITH(ctdb, -[AS_HELP_STRING([--with-ctdb=DIR], [Where to find ctdb sources])], -[ case "$withval" in - yes|no) - AC_MSG_WARN([--with-ctdb called without argument]) - ;; - * ) - ctdbdir="$withval" - ;; - esac]) - -################################################# -# set lib directory location -AC_ARG_WITH(libdir, -[AS_HELP_STRING([--with-libdir=DIR], [Where to put libdir ($libdir)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody does it - # - AC_MSG_WARN([--with-libdir without argument - will use default]) - ;; - * ) - libdir="$withval" - ;; - esac]) - -################################################# -# set PAM modules directory location -AC_ARG_WITH(pammodulesdir, -[AS_HELP_STRING([--with-pammodulesdir=DIR], [Which directory to use for PAM modules ($ac_default_prefix/$libdir/security)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody calls it without argument - # - AC_MSG_WARN([--with-pammodulesdir called without argument - will use default]) - ;; - * ) - pammodulesdir="$withval" - ;; - esac]) +builddir=`pwd` +AC_SUBST(builddir) -################################################# -# set man directory location -AC_ARG_WITH(mandir, -[AS_HELP_STRING([--with-mandir=DIR], [Where to put man pages ($mandir)])], -[ case "$withval" in - yes|no) - # - # Just in case anybody does it - # - AC_MSG_WARN([--with-mandir without argument - will use default]) - ;; - * ) - mandir="$withval" - ;; - esac]) - -AC_ARG_WITH(cfenc, -[AS_HELP_STRING([--with-cfenc=HEADERDIR], [Use internal CoreFoundation encoding API for optimization (Mac OS X/Darwin only)])], -[ -# May be in source $withval/CoreFoundation/StringEncodings.subproj. -# Should have been in framework $withval/CoreFoundation.framework/Headers. -for d in \ - $withval/CoreFoundation/StringEncodings.subproj \ - $withval/StringEncodings.subproj \ - $withval/CoreFoundation.framework/Headers \ - $withval/Headers \ - $withval -do - if test -r $d/CFStringEncodingConverter.h; then - ln -sfh $d include/CoreFoundation - fi -done -]) +m4_include(m4/samba_version.m4) +m4_include(m4/check_path.m4) AC_LIBREPLACE_CC_CHECKS @@ -276,14 +27,30 @@ m4_include(lib/talloc/libtalloc.m4) TALLOC_OBJS="" for obj in ${TALLOC_OBJ}; do - TALLOC_OBJS="${TALLOCOBJS} ${tallocdir}/${obj}" + TALLOC_OBJS="${TALLOC_OBJS} ${tallocdir}/${obj}" done AC_SUBST(TALLOC_OBJS) +# TODO: These should come from m4_include(lib/tdb/libtdb.m4) +# but currently this fails: things have to get merged from s4. +tdbdir="lib/tdb" +AC_SUBST(tdbdir) +TDB_CFLAGS="-I$tdbdir/include" +AC_SUBST(TDB_CFLAGS) +TDB_OBJ="common/tdb.o common/dump.o common/transaction.o common/error.o common/traverse.o" +TDB_OBJ="$TDB_OBJ common/freelist.o common/freelistcheck.o common/io.o common/lock.o common/open.o" +AC_SUBST(TDB_OBJ) + +TDB_OBJS="" +for obj in ${TDB_OBJ}; do + TDB_OBJS="${TDB_OBJS} ${tdbdir}/${obj}" +done +AC_SUBST(TDB_OBJS) + SAMBA_CPPFLAGS="-Iinclude -I${srcdir-.}/include -I. -I${srcdir-.}" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/lib/replace" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TALLOC_CFLAGS}" -SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/lib/tdb/include" +SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} ${TDB_CFLAGS}" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/libaddns" SAMBA_CPPFLAGS="${SAMBA_CPPFLAGS} -I${srcdir-.}/librpc" @@ -294,21 +61,6 @@ if test "x${srcdir-.}" != "x."; then SAMBA_CPPFLAGS=`echo ${SAMBA_CPPFLAGS} | sed -e "s;${srcdir};\$\(srcdir\);g"` fi -AC_SUBST(configdir) -AC_SUBST(lockdir) -AC_SUBST(piddir) -AC_SUBST(logfilebase) -AC_SUBST(ctdbdir) -AC_SUBST(privatedir) -AC_SUBST(swatdir) -AC_SUBST(bindir) -AC_SUBST(sbindir) -AC_SUBST(codepagedir) -AC_SUBST(statedir) -AC_SUBST(cachedir) -AC_SUBST(rootsbindir) -AC_SUBST(pammodulesdir) - dnl Unique-to-Samba variables we'll be playing with. AC_SUBST(SAMBA_CPPFLAGS) AC_SUBST(SHELL) @@ -331,12 +83,6 @@ AC_SUBST(UNINSTALL_LIBADDNS) AC_SUBST(LIBADDNS_SHARED) AC_SUBST(LIBADDNS) -AC_SUBST(LIBTALLOC_STATIC_TARGET) -AC_SUBST(LIBTALLOC_SHARED_TARGET) -AC_SUBST(LIBTALLOC_SHARED) -AC_SUBST(LIBTALLOC_STATIC) -AC_SUBST(LIBTALLOC_LIBS) - AC_SUBST(INSTALL_LIBWBCLIENT) AC_SUBST(UNINSTALL_LIBWBCLIENT) AC_SUBST(LIBWBCLIENT_SHARED) @@ -354,10 +100,7 @@ AC_SUBST(INSTALL_LIBSMBSHAREMODES) AC_SUBST(UNINSTALL_LIBSMBSHAREMODES) AC_SUBST(LIBSMBSHAREMODES_SHARED) AC_SUBST(LIBSMBSHAREMODES) -AC_SUBST(INSTALL_LIBNETAPI) -AC_SUBST(UNINSTALL_LIBNETAPI) -AC_SUBST(LIBNETAPI_SHARED) -AC_SUBST(LIBNETAPI) + AC_SUBST(PRINT_LIBS) AC_SUBST(AUTH_LIBS) AC_SUBST(ACL_LIBS) @@ -366,12 +109,12 @@ AC_SUBST(IDMAP_LIBS) AC_SUBST(KRB5_LIBS) AC_SUBST(UUID_LIBS) AC_SUBST(LDAP_LIBS) +AC_SUBST(GPEXT_LIBS) AC_SUBST(PAM_MODULES) AC_SUBST(INSTALL_PAM_MODULES) AC_SUBST(UNINSTALL_PAM_MODULES) AC_SUBST(NSS_MODULES) AC_SUBST(EXTRA_BIN_PROGS) -AC_SUBST(SMBMOUNT_PROGS) AC_SUBST(CIFSMOUNT_PROGS) AC_SUBST(INSTALL_CIFSMOUNT) AC_SUBST(UNINSTALL_CIFSMOUNT) @@ -383,14 +126,6 @@ AC_SUBST(EXTRA_ALL_TARGETS) AC_SUBST(CONFIG_LIBS) AC_SUBST(NSCD_LIBS) -## check for --enable-debug first before checking CFLAGS before -## so that we don't mix -O and -g -AC_ARG_ENABLE(debug, -[AS_HELP_STRING([--enable-debug], [Turn on compiler debugging information (default=no)])], - [if eval "test x$enable_debug = xyes"; then - CFLAGS="${CFLAGS} -g" - fi]) - # compile with optimization and without debugging by default, but # allow people to set their own preference. # do this here since AC_CACHE_CHECK apparently sets the CFLAGS to "-g -O2" @@ -399,74 +134,18 @@ AC_ARG_ENABLE(debug, if test "x$CFLAGS" = x; then CFLAGS="-O" fi +if test "x$debug" = "xyes" ; then + CFLAGS="${CFLAGS} -g" +else + CFLAGS="-O" +fi CFLAGS="${CFLAGS} -D_SAMBA_BUILD_=3" m4_include(lib/socket_wrapper/config.m4) m4_include(lib/nss_wrapper/config.m4) -SWAT_SBIN_TARGETS='bin/swat$(EXEEXT)' -SWAT_INSTALL_TARGETS=installswat - -AC_ARG_ENABLE(swat, -[AS_HELP_STRING([--enable-swat], [Build the SWAT tool (default=yes)])], -[ - case "$enable_swat" in - no) - SWAT_SBIN_TARGETS='' - SWAT_INSTALL_TARGETS='' - ;; - esac -]) - -AC_SUBST(SWAT_SBIN_TARGETS) -AC_SUBST(SWAT_INSTALL_TARGETS) - -################################################# -# set prefix for 'make test' -selftest_prefix="./" -AC_SUBST(selftest_prefix) -AC_ARG_WITH(selftest-prefix, -[AS_HELP_STRING([--with-selftest-prefix=DIR], [The prefix where make test will be run ($selftest_prefix)])], -[ case "$withval" in - yes|no) - AC_MSG_WARN([--with-selftest-prefix called without argument - will use default]) - ;; - * ) - selftest_prefix="$withval" - ;; - esac -]) - -################################################# -# set path of samba4's smbtorture -smbtorture4_path="" -AC_SUBST(smbtorture4_path) -AC_ARG_WITH(smbtorture4_path, -[AS_HELP_STRING([--with-smbtorture4-path=PATH], [The path to a samba4 smbtorture for make test (none)])], -[ case "$withval" in - yes|no) - AC_MSG_ERROR([--with-smbtorture4-path should take a path]) - ;; - * ) - smbtorture4_path="$withval" - if test -z "$smbtorture4_path" -a ! -f $smbtorture4_path; then - AC_MSG_ERROR(['$smbtorture_path' does not exist!]) - fi - ;; - esac -]) - -AC_ARG_ENABLE(developer, [AS_HELP_STRING([--enable-developer], [Turn on developer warnings and debugging (default=no)])], - [if eval "test x$enable_developer = xyes"; then - developer=yes - fi]) - -AC_ARG_ENABLE(krb5developer, [AS_HELP_STRING([--enable-krb5developer], [Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)])], - [if eval "test x$enable_krb5developer = xyes"; then - developer=yes - krb5_developer=yes - fi]) +m4_include(m4/swat.m4) # Probe the gcc version for extra CFLAGS. We always stash these in # DEVELOPER_CFLAGS, so that you can turn them on and off with a simple @@ -720,10 +399,10 @@ AC_SUBST(DYNEXP) dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup 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" +default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl2 rpc_ntsvcs2 rpc_netlogon 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 vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops vfs_xattr_tdb vfs_streams_xattr" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_rpcecho" @@ -955,8 +634,13 @@ exit(1); esac +SAVE_CPPFLAGS="${CPPFLAGS}" +CPPFLAGS="${CPPFLAGS} ${SAMBA_CONFIGURE_CPPFLAGS}" + AC_LIBREPLACE_BROKEN_CHECKS +CPPFLAGS="${SAVE_CPPFLAGS}" + LIBREPLACE_DIR=`echo ${libreplacedir} | sed -e "s;${srcdir};;" -e "s;^/;;"` LIBREPLACE_OBJS="" @@ -1057,13 +741,8 @@ AC_TYPE_SIZE_T AC_TYPE_PID_T AC_STRUCT_ST_RDEV AC_DIRENT_D_OFF -AC_CHECK_TYPE(ino_t,unsigned) -AC_CHECK_TYPE(loff_t,off_t) -AC_CHECK_TYPE(offset_t,loff_t) AC_CHECK_TYPE(ssize_t, int) AC_CHECK_TYPE(wchar_t, unsigned short) -AC_CHECK_TYPE(comparison_fn_t, -[AC_DEFINE(HAVE_COMPARISON_FN_T, 1,[Whether or not we have comparison_fn_t])]) ############################################ # for cups support we need libcups, and a handful of header files @@ -1128,9 +807,59 @@ AC_CACHE_CHECK([for unix domain sockets],samba_cv_unixsocket, [ ], samba_cv_unixsocket=yes,samba_cv_unixsocket=no)]) if test x"$samba_cv_unixsocket" = x"yes"; then - AC_DEFINE(HAVE_UNIXSOCKET,1,[If we need to build with unixscoket support]) + AC_DEFINE(HAVE_UNIXSOCKET,1,[If we need to build with unixsocket support]) +fi + +############################################# +# check for fd passing struct via msg_control +AC_CACHE_CHECK([for fd passing via msg_control],samba_cv_msghdr_msg_control, [ + AC_TRY_COMPILE([ +#include <sys/types.h> +#include <stdlib.h> +#include <stddef.h> +#include <sys/socket.h> +#include <sys/un.h>], +[ + struct msghdr msg; + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof(int))]; + } control_un; + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof(control_un.control); +], + samba_cv_msghdr_msg_control=yes,samba_cv_msghdr_msg_control=no)]) +if test x"$samba_cv_msghdr_msg_control" = x"yes"; then + AC_DEFINE(HAVE_MSGHDR_MSG_CONTROL,1, + [If we can use msg_control for passing file descriptors]) +fi + +############################################# +# check for fd passing struct via msg_acctrights +AC_CACHE_CHECK([for fd passing via msg_acctrights], + samba_cv_msghdr_msg_acctrights, [ + AC_TRY_COMPILE([ +#include <sys/types.h> +#include <stdlib.h> +#include <stddef.h> +#include <sys/socket.h> +#include <sys/un.h>], +[ + struct msghdr msg; + int fd; + msg.msg_acctrights = (caddr_t) &fd; + msg.msg_acctrightslen = sizeof(fd); +], + samba_cv_msghdr_msg_acctrights=yes,samba_cv_msghdr_msg_acctrights=no)]) +if test x"$samba_cv_msghdr_msg_acctrights" = x"yes"; then + AC_DEFINE(HAVE_MSGHDR_MSG_ACCTRIGHTS,1, + [If we can use msg_acctrights for passing file descriptors]) fi +AC_CHECK_FUNCS(dirfd) +if test x"$ac_cv_func_dirfd" = x"yes"; then + default_shared_modules="$default_shared_modules vfs_syncops" +fi AC_CACHE_CHECK([for sig_atomic_t type],samba_cv_sig_atomic_t, [ AC_TRY_COMPILE([ @@ -1172,10 +901,6 @@ fi AC_HAVE_DECL(errno, [#include <errno.h>]) AC_HAVE_DECL(setresuid, [#include <unistd.h>]) AC_HAVE_DECL(setresgid, [#include <unistd.h>]) -AC_HAVE_DECL(asprintf, [#include <stdio.h>]) -AC_HAVE_DECL(vasprintf, [#include <stdio.h>]) -AC_HAVE_DECL(vsnprintf, [#include <stdio.h>]) -AC_HAVE_DECL(snprintf, [#include <stdio.h>]) # and glibc has setresuid under linux but the function does # nothing until kernel 2.1.44! very dumb. @@ -1327,7 +1052,7 @@ AC_CHECK_FUNCS(waitpid getcwd strdup strndup strnlen strerror chown fchown lchow AC_CHECK_FUNCS(strtol strtoll strtoul strtoull strtouq __strtoull) AC_CHECK_FUNCS(fstat strchr utime utimes chflags) AC_CHECK_FUNCS(getrlimit fsync fdatasync memset strlcpy strlcat setpgid) -AC_CHECK_FUNCS(memmove vsnprintf snprintf asprintf vasprintf setsid glob strpbrk pipe crypt16 getauthuid) +AC_CHECK_FUNCS(memmove setsid glob strpbrk pipe crypt16 getauthuid) AC_CHECK_FUNCS(strftime sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent) AC_CHECK_FUNCS(initgroups select poll rdchk getgrnam getgrent pathconf realpath) AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate chsize stat64 fstat64) @@ -1757,6 +1482,9 @@ case "$host_os" in ;; esac +AC_DISABLE_STATIC +AC_ENABLE_SHARED + # Set defaults PIE_CFLAGS="" PIE_LDFLAGS="" @@ -1880,7 +1608,7 @@ DSO_EXPORTS="" ;; *aix*) AC_DEFINE(AIX,1,[Whether the host os is aix]) BLDSHARED="true" - LDSHFLAGS="-Wl,-G,-bexpall,-bbigtoc" + LDSHFLAGS="-Wl,-G,-bexpfull,-bbigtoc" DYNEXP="-Wl,-brtl,-bexpfull,-bbigtoc" PICFLAG="-O2" # as AIX code is always position independent... @@ -1971,7 +1699,9 @@ DSO_EXPORTS="" *darwin*) AC_DEFINE(DARWINOS,1,[Whether the host os is Darwin/MacOSX]) BLDSHARED="true" - LDSHFLAGS="-bundle -flat_namespace -undefined suppress" + LDSHFLAGS="-dynamiclib -flat_namespace -undefined suppress" + CFLAGS="$CFLAGS -fno-common" + SHLD="\${CC}" SHLIBEXT="dylib" MODULE_EXPORTS="-exported_symbols_list \$(srcdir)/exports/modules-darwin.syms" SHLIBEXT="dylib" @@ -1996,6 +1726,10 @@ if test "$enable_shared" = yes -a "${ac_cv_gnu_ld_version_script}" = yes; then DSO_EXPORTS=\$\(DSO_EXPORTS_CMD\) fi +if test x"$BLDSHARED" = x"true" ; then + LDFLAGS="$LDFLAGS -L./bin" +fi + AC_MSG_RESULT($BLDSHARED) AC_MSG_CHECKING([LDFLAGS]) @@ -2288,54 +2022,6 @@ if test x"$samba_cv_WITH_PROFILE" = x"yes"; then fi -AC_CACHE_CHECK([for va_copy],samba_cv_HAVE_VA_COPY,[ -AC_TRY_LINK([#include <stdarg.h> -va_list ap1,ap2;], [va_copy(ap1,ap2);], -samba_cv_HAVE_VA_COPY=yes, -samba_cv_HAVE_VA_COPY=no)]) -if test x"$samba_cv_HAVE_VA_COPY" = x"yes"; then - AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available]) -else - AC_CACHE_CHECK([for __va_copy],samba_cv_HAVE___VA_COPY,[ - AC_TRY_LINK([#include <stdarg.h> - va_list ap1,ap2;], [__va_copy(ap1,ap2);], - samba_cv_HAVE___VA_COPY=yes, - samba_cv_HAVE___VA_COPY=no)]) - if test x"$samba_cv_HAVE___VA_COPY" = x"yes"; then - AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available]) - fi -fi - -AC_CACHE_CHECK([for C99 vsnprintf],samba_cv_HAVE_C99_VSNPRINTF,[ -AC_TRY_RUN([ -#include <sys/types.h> -#include <stdarg.h> -void foo(const char *format, ...) { - va_list ap; - int len; - char buf[5]; - - va_start(ap, format); - len = vsnprintf(buf, 0, format, ap); - va_end(ap); - if (len != 5) exit(1); - - va_start(ap, format); - len = vsnprintf(0, 0, format, ap); - va_end(ap); - if (len != 5) exit(1); - - if (snprintf(buf, 3, "hello") != 5 || strcmp(buf, "he") != 0) exit(1); - - exit(0); -} -main() { foo("hello"); } -], -samba_cv_HAVE_C99_VSNPRINTF=yes,samba_cv_HAVE_C99_VSNPRINTF=no,samba_cv_HAVE_C99_VSNPRINTF=cross)]) -if test x"$samba_cv_HAVE_C99_VSNPRINTF" = x"yes"; then - AC_DEFINE(HAVE_C99_VSNPRINTF,1,[Whether there is a C99 compliant vsnprintf]) -fi - AC_CACHE_CHECK([for broken readdir name],samba_cv_HAVE_BROKEN_READDIR_NAME,[ AC_TRY_RUN([#include <sys/types.h> #include <dirent.h> @@ -2711,7 +2397,7 @@ fi AC_CACHE_CHECK([for inotify support],samba_cv_HAVE_INOTIFY,[ AC_CHECK_HEADERS(linux/inotify.h asm/unistd.h) -AC_CHECK_FUNC(inotify_init) +AC_CHECK_FUNCS(inotify_init) AC_HAVE_DECL(__NR_inotify_init, [#include <asm/unistd.h>]) ], samba_cv_HAVE_INOTIFY=yes, @@ -2946,148 +2632,12 @@ if test x"$samba_cv_HAVE_BROKEN_GETGROUPS" = x"yes"; then AC_DEFINE(HAVE_BROKEN_GETGROUPS,1,[Whether getgroups is broken]) fi -AC_CACHE_CHECK([for secure mkstemp],samba_cv_HAVE_SECURE_MKSTEMP,[ -AC_TRY_RUN([#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -main() { - struct stat st; - char tpl[20]="/tmp/test.XXXXXX"; - int fd = mkstemp(tpl); - if (fd == -1) exit(1); - unlink(tpl); - if (fstat(fd, &st) != 0) exit(1); - if ((st.st_mode & 0777) != 0600) exit(1); - exit(0); -}], -samba_cv_HAVE_SECURE_MKSTEMP=yes, -samba_cv_HAVE_SECURE_MKSTEMP=no, -samba_cv_HAVE_SECURE_MKSTEMP=cross)]) -if test x"$samba_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then - AC_DEFINE(HAVE_SECURE_MKSTEMP,1,[Whether mkstemp is secure]) -fi - -AC_CACHE_CHECK([for broken readdir],samba_cv_HAVE_BROKEN_READDIR,[ - AC_TRY_RUN([#include "${srcdir-.}/tests/os2_delete.c"], - [samba_cv_HAVE_BROKEN_READDIR=no], - [samba_cv_HAVE_BROKEN_READDIR=yes], - [samba_cv_HAVE_BROKEN_READDIR="assuming not"])]) - -if test x"$samba_cv_HAVE_BROKEN_READDIR" = x"yes"; then -AC_CACHE_CHECK([for replacing readdir],samba_cv_REPLACE_READDIR,[ - AC_TRY_RUN([ -#include "${srcdir-.}/lib/repdir.c" -#include "${srcdir-.}/tests/os2_delete.c"], - samba_cv_REPLACE_READDIR=yes,samba_cv_REPLACE_READDIR=no)]) -fi - -if test x"$samba_cv_REPLACE_READDIR" = x"yes"; then - AC_DEFINE(REPLACE_READDIR,1,[replace readdir]) -fi - SMB_CHECK_SYSCONF(_SC_NGROUPS_MAX) SMB_CHECK_SYSCONF(_SC_NPROC_ONLN) SMB_CHECK_SYSCONF(_SC_NPROCESSORS_ONLN) SMB_CHECK_SYSCONF(_SC_PAGESIZE) AC_CHECK_FUNCS(getpagesize) -dnl test for getifaddrs and freeifaddrs -AC_CACHE_CHECK([for getifaddrs and freeifaddrs],samba_cv_HAVE_GETIFADDRS,[ -AC_TRY_COMPILE([ -#include <sys/socket.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <ifaddrs.h> -#include <netdb.h>], -[ -struct ifaddrs *ifp = NULL; -int ret = getifaddrs (&ifp); -freeifaddrs(ifp); -], -samba_cv_HAVE_GETIFADDRS=yes,samba_cv_HAVE_GETIFADDRS=no)]) -if test x"$samba_cv_HAVE_GETIFADDRS" = x"yes"; then - AC_DEFINE(HAVE_GETIFADDRS,1,[Whether the system has getifaddrs]) - AC_DEFINE(HAVE_FREEIFADDRS,1,[Whether the system has freeifaddrs]) -fi - -################## -# look for a method of finding the list of network interfaces -iface=no; -AC_CACHE_CHECK([for iface getifaddrs],samba_cv_HAVE_IFACE_GETIFADDRS,[ -SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS ${SAMBA_CONFIGURE_CPPFLAGS}" -AC_TRY_RUN([ -#define NO_CONFIG_H 1 -#define HAVE_IFACE_GETIFADDRS 1 -#define AUTOCONF_TEST 1 -#include "${srcdir-.}/lib/replace/replace.c" -#include "${srcdir-.}/lib/interfaces.c"], - samba_cv_HAVE_IFACE_GETIFADDRS=yes,samba_cv_HAVE_IFACE_GETIFADDRS=no,samba_cv_HAVE_IFACE_GETIFADDRS=cross)]) -CPPFLAGS="$SAVE_CPPFLAGS" -if test x"$samba_cv_HAVE_IFACE_GETIFADDRS" = x"yes"; then - iface=yes;AC_DEFINE(HAVE_IFACE_GETIFADDRS,1,[Whether iface getifaddrs is available]) -fi - -if test $iface = no; then -AC_CACHE_CHECK([for iface ifconf],samba_cv_HAVE_IFACE_IFCONF,[ -SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS ${SAMBA_CONFIGURE_CPPFLAGS}" -AC_TRY_RUN([ -#define NO_CONFIG_H 1 -#define HAVE_IFACE_IFCONF 1 -#define AUTOCONF_TEST 1 -#define SOCKET_WRAPPER_NOT_REPLACE -#include "${srcdir-.}/lib/replace/replace.c" -#include "${srcdir-.}/lib/interfaces.c"], - samba_cv_HAVE_IFACE_IFCONF=yes,samba_cv_HAVE_IFACE_IFCONF=no,samba_cv_HAVE_IFACE_IFCONF=cross)]) -CPPFLAGS="$SAVE_CPPFLAGS" -if test x"$samba_cv_HAVE_IFACE_IFCONF" = x"yes"; then - iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF,1,[Whether iface ifconf is available]) -fi -fi - -if test $iface = no; then -AC_CACHE_CHECK([for iface ifreq],samba_cv_HAVE_IFACE_IFREQ,[ -SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS ${SAMBA_CONFIGURE_CPPFLAGS}" -AC_TRY_RUN([ -#define NO_CONFIG_H 1 -#define HAVE_IFACE_IFREQ 1 -#define AUTOCONF_TEST 1 -#define SOCKET_WRAPPER_NOT_REPLACE -#include "${srcdir-.}/lib/replace/replace.c" -#include "${srcdir-.}/lib/replace/getaddrinfo.c" -#include "${srcdir-.}/lib/replace/snprintf.c" -#include "${srcdir-.}/lib/interfaces.c"], - samba_cv_HAVE_IFACE_IFREQ=yes,samba_cv_HAVE_IFACE_IFREQ=no,samba_cv_HAVE_IFACE_IFREQ=cross)]) -CPPFLAGS="$SAVE_CPPFLAGS" -if test x"$samba_cv_HAVE_IFACE_IFREQ" = x"yes"; then - iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ,1,[Whether iface ifreq is available]) -fi -fi - -if test $iface = no; then -AC_CACHE_CHECK([for iface AIX],samba_cv_HAVE_IFACE_AIX,[ -SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS ${SAMBA_CONFIGURE_CPPFLAGS}" -AC_TRY_RUN([ -#define NO_CONFIG_H 1 -#define HAVE_IFACE_AIX 1 -#define AUTOCONF_TEST 1 -#undef _XOPEN_SOURCE_EXTENDED -#define SOCKET_WRAPPER_NOT_REPLACE -#include "${srcdir-.}/lib/replace/replace.c" -#include "${srcdir-.}/lib/replace/snprintf.c" -#include "${srcdir-.}/lib/interfaces.c"], - samba_cv_HAVE_IFACE_AIX=yes,samba_cv_HAVE_IFACE_AIX=no,samba_cv_HAVE_IFACE_AIX=cross)]) -CPPFLAGS="$SAVE_CPPFLAGS" -if test x"$samba_cv_HAVE_IFACE_AIX" = x"yes"; then - iface=yes;AC_DEFINE(HAVE_IFACE_AIX,1,[Whether iface AIX is available]) -fi -fi - dnl test for ipv6 AC_CACHE_CHECK([for ipv6 support],samba_cv_HAVE_IPV6,[ AC_TRY_COMPILE([ @@ -3183,13 +2733,6 @@ if test x"$samba_cv_DARWIN_INITGROUPS" = x"yes" ; then [Whether to use the Darwin-specific initgroups system call]) fi -AC_CACHE_CHECK([for working mmap],samba_cv_HAVE_MMAP,[ -AC_TRY_RUN([#include "${srcdir-.}/tests/shared_mmap.c"], - samba_cv_HAVE_MMAP=yes,samba_cv_HAVE_MMAP=no,samba_cv_HAVE_MMAP=cross)]) -if test x"$samba_cv_HAVE_MMAP" = x"yes"; then - AC_DEFINE(HAVE_MMAP,1,[Whether mmap works]) -fi - AC_CACHE_CHECK([for fcntl locking],samba_cv_HAVE_FCNTL_LOCK,[ AC_TRY_RUN([#include "${srcdir-.}/tests/fcntl_lock.c"], samba_cv_HAVE_FCNTL_LOCK=yes,samba_cv_HAVE_FCNTL_LOCK=no,samba_cv_HAVE_FCNTL_LOCK=cross)]) @@ -4480,31 +4023,6 @@ AC_ARG_WITH(automount, ) ################################################# -# check for smbmount support -AC_MSG_CHECKING(whether to use smbmount) -AC_ARG_WITH(smbmount, -[AS_HELP_STRING([--with-smbmount], [Include smbmount (Linux only) support (default=no)])], -[ case "$withval" in - yes) - case "$host_os" in - *linux*) - AC_MSG_RESULT(yes) - AC_DEFINE(WITH_SMBMOUNT,1,[Whether to build smbmount]) - SMBMOUNT_PROGS="bin/smbmount bin/smbmnt bin/smbumount" - ;; - *) - AC_MSG_ERROR(not on a linux system!) - ;; - esac - ;; - *) - AC_MSG_RESULT(no) - ;; - esac ], - AC_MSG_RESULT(no) -) - -################################################# # check for mount- and umount.cifs support CIFSMOUNT_PROGS="" INSTALL_CIFSMOUNT="" @@ -5127,6 +4645,31 @@ if test $enable_static = yes; then fi ################################################# +# --disable-shared-libs +# can be used to disable the internal use of shared libs altogether +# (this only has an effect when building shared libs is enabled) +# +USESHARED=false +AC_SUBST(USESHARED) + +AC_MSG_CHECKING(whether to use shared libraries internally) +AC_ARG_ENABLE([shared-libs], + AS_HELP_STRING([--enable-shared-libs], + [Use shared libraries internally (default=yes)]), + [enable_shared_libs=$enableval], + [enable_shared_libs=yes]) + +if test x"$enable_shared_libs" != x"no" ; then + USESHARED=$BLDSHARED +fi + +AC_MSG_RESULT([$USESHARED]) + +if test x"$enable_shared_libs" = x"yes" -a x"$BLDSHARED" != x"true" ; then + AC_MSG_WARN([--enable-shared-libs: no support for shared libraries]) +fi + +################################################# # --with-static-libs=LIBS: # link (internal) libs dynamically or statically? # @@ -5139,7 +4682,7 @@ fi # appears in the --with-static-libs configure option. # # Example: -# --with-static-libs=talloc makes use of libtalloc.a instead +# --with-static-libs=libtalloc makes use of libtalloc.a instead # of linking the dynamic variant with -ltalloc. # # NOTE: This option only affects libraries that we do not only build @@ -5154,99 +4697,15 @@ AC_ARG_WITH([static-libs], [AS_IF([test $withval], [for lib in `echo $withval | sed -e 's/,/ /g'` ; do [lib=`echo $lib | tr '[a-z]' '[A-Z]'`] - eval LIB_$lib=STATIC + eval LINK_$lib=STATIC done], [])], []) -################################################# -# should we build libtalloc? -LIBTALLOC_SHARED_TARGET=bin/libtalloc.$SHLIBEXT -LIBTALLOC_STATIC_TARGET=bin/libtalloc.a -LIBTALLOC_SHARED= -LIBTALLOC_STATIC= -LIBTALLOC_LIBS= - -AC_MSG_CHECKING(whether to build the libtalloc shared library) -AC_ARG_WITH(libtalloc, -[AS_HELP_STRING([--with-libtalloc], - [Build the libtalloc shared library (default=yes if shared libs supported)])], -[ -case "$withval" in - *) - AC_MSG_RESULT(no) - ;; - yes) - samba_cv_with_libtalloc=yes - ;; -esac -], -[ -# if unspecified, default is to build it if possible. -samba_cv_with_libtalloc=yes -] -) - -if test x"$samba_cv_with_libtalloc" = "xyes" -a $BLDSHARED = true; then - LIBTALLOC_SHARED=$LIBTALLOC_SHARED_TARGET - AC_MSG_RESULT(yes) - if test x"$LIB_TALLOC" = "xSTATIC" ; then - LIBTALLOC_STATIC=$LIBTALLOC_STATIC_TARGET - else - LIBTALLOC_LIBS=-ltalloc - fi -else - enable_static=yes - AC_MSG_RESULT(no shared library support -- will supply static library) -fi -if test $enable_static = yes; then - LIBTALLOC_STATIC=$LIBTALLOC_STATIC_TARGET -fi +SMB_LIBRARY(talloc) +SMB_LIBRARY(tdb) +SMB_LIBRARY(netapi) -################################################# -# should we build libnetapi? -INSTALL_LIBNETAPI= -UNINSTALL_LIBNETAPI= -LIBNETAPI_SHARED= -LIBNETAPI= -AC_MSG_CHECKING(whether to build the libnetapi shared library) -AC_ARG_WITH(libnetapi, -[AS_HELP_STRING([--with-libnetapi], [Build the libnetapi shared library (default=yes if shared libs supported)])], -[ case "$withval" in - *) - AC_MSG_RESULT(no) - ;; - yes) - if test $BLDSHARED = true; then - LIBNETAPI_SHARED=bin/libnetapi.$SHLIBEXT - LIBNETAPI=libnetapi - AC_MSG_RESULT(yes) - else - enable_static=yes - AC_MSG_RESULT(no shared library support -- will supply static library) - fi - if test $enable_static = yes; then - LIBNETAPI=libnetapi - fi - INSTALL_LIBNETAPI=installlibnetapi - UNINSTALL_LIBNETAPI=uninstalllibnetapi - ;; - esac ], -[ -# if unspecified, default is to build it if possible. - if test $BLDSHARED = true; then - LIBNETAPI_SHARED=bin/libnetapi.$SHLIBEXT - LIBNETAPI=libnetapi - AC_MSG_RESULT(yes) - else - enable_static=yes - AC_MSG_RESULT(no shared library support -- will supply static library) - fi - if test $enable_static = yes; then - LIBNETAPI=libnetapi - fi] - INSTALL_LIBNETAPI=installlibnetapi -) ################################################# # should we build libaddns? @@ -6267,13 +5726,11 @@ if test x"$HAVE_WINBIND" = x"no"; then WINBIND_WINS_NSS="" fi -BUILD_LIBWBCLIENT_SHARED=yes - -AC_ARG_ENABLE(libwbclient-shared, -[AS_HELP_STRING([--enable-libwbclient-shared], [Build libwbclient as shared object (default=yes, \"no\" only for --enable-developer)])], - [if eval "test x$enable_developer = xyes -a x$enable_libwbclient_shared = xno" ; then - BUILD_LIBWBCLIENT_SHARED=no - fi]) +if test x"$enable_developer" = x"yes" -a x"$LINK_LIBWBCLIENT" = x"STATIC" ; then + BUILD_LIBWBCLIENT_SHARED=no +else + BUILD_LIBWBCLIENT_SHARED=yes +fi if test $BLDSHARED = true -a x"$HAVE_WINBIND" = x"yes" -a x"$BUILD_LIBWBCLIENT_SHARED" = x"yes"; then NSS_MODULES="${WINBIND_NSS} ${WINBIND_WINS_NSS}" @@ -6284,7 +5741,6 @@ if test $BLDSHARED = true -a x"$HAVE_WINBIND" = x"yes" -a x"$BUILD_LIBWBCLIENT_S INSTALL_LIBWBCLIENT=installlibwbclient UNINSTALL_LIBWBCLIENT=uninstalllibwbclient WINBIND_LIBS="-lwbclient" - LDFLAGS="$LDFLAGS -L./bin" else LIBWBCLIENT_STATIC=bin/libwbclient.a fi @@ -6540,14 +5996,14 @@ SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB) SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o) -SMB_MODULE(rpc_lsa, \$(RPC_LSA_OBJ), "bin/librpc_lsarpc.$SHLIBEXT", RPC) +SMB_MODULE(rpc_lsarpc, \$(RPC_LSA_OBJ), "bin/librpc_lsarpc.$SHLIBEXT", RPC) SMB_MODULE(rpc_winreg, \$(RPC_REG_OBJ), "bin/librpc_winreg.$SHLIBEXT", RPC) SMB_MODULE(rpc_initshutdown, \$(RPC_INITSHUTDOWN_OBJ), "bin/librpc_initshutdown.$SHLIBEXT", RPC) SMB_MODULE(rpc_dssetup, \$(RPC_DSSETUP_OBJ), "bin/librpc_dssetup.$SHLIBEXT", RPC) SMB_MODULE(rpc_wkssvc, \$(RPC_WKS_OBJ), "bin/librpc_wkssvc.$SHLIBEXT", RPC) SMB_MODULE(rpc_svcctl2, \$(RPC_SVCCTL_OBJ), "bin/librpc_svcctl2.$SHLIBEXT", RPC) -SMB_MODULE(rpc_ntsvcs, \$(RPC_NTSVCS_OBJ), "bin/librpc_ntsvcs.$SHLIBEXT", RPC) -SMB_MODULE(rpc_net, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC) +SMB_MODULE(rpc_ntsvcs2, \$(RPC_NTSVCS_OBJ), "bin/librpc_ntsvcs2.$SHLIBEXT", RPC) +SMB_MODULE(rpc_netlogon, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC) SMB_MODULE(rpc_netdfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC) SMB_MODULE(rpc_srvsvc2, \$(RPC_SVC_OBJ), "bin/librpc_svcsvc2.$SHLIBEXT", RPC) SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC) @@ -6615,6 +6071,7 @@ SMB_MODULE(vfs_gpfs, \$(VFS_GPFS_OBJ), "bin/gpfs.$SHLIBEXT", VFS) SMB_MODULE(vfs_readahead, \$(VFS_READAHEAD_OBJ), "bin/readahead.$SHLIBEXT", VFS) SMB_MODULE(vfs_tsmsm, \$(VFS_TSMSM_OBJ), "bin/tsmsm.$SHLIBEXT", VFS) SMB_MODULE(vfs_fileid, \$(VFS_FILEID_OBJ), "bin/fileid.$SHLIBEXT", VFS) +SMB_MODULE(vfs_aio_fork, \$(VFS_AIO_FORK_OBJ), "bin/aio_fork.$SHLIBEXT", VFS) SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS) SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS) SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", VFS) @@ -6622,6 +6079,9 @@ SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", V SMB_SUBSYSTEM(VFS,smbd/vfs.o) +SMB_MODULE(gpext_registry, libgpo/gpext/registry.o, "bin/registry.$SHLIBEXT", GPEXT) +SMB_SUBSYSTEM(GPEXT, libgpo/gpext/gpext.o) + AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules]) ################################################# @@ -6757,9 +6217,6 @@ if test x"$krb5_developer" = x"yes" -o x"$developer" = x"yes"; then CFLAGS="${CFLAGS} \$(DEVELOPER_CFLAGS)" fi -builddir=`pwd` -AC_SUBST(builddir) - # Stuff the smbd-only libraries at the end of the smbd link # path (if we have them). SMBD_LIBS="$samba_dmapi_libs" diff --git a/source3/exports/libtalloc.syms b/source3/exports/libtalloc.syms index eb34bfc012..87f1c5c63e 100644 --- a/source3/exports/libtalloc.syms +++ b/source3/exports/libtalloc.syms @@ -1,3 +1,6 @@ { - global: *; + global: + talloc_*; + _talloc_*; + local: *; }; diff --git a/source3/include/ads.h b/source3/include/ads.h index d1047bbdc2..d5ce88babe 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -319,11 +319,6 @@ typedef void **ADS_MODLIST; #define ADS_DNS_DOMAIN 0x40000000 /* DomainName is a DNS name */ #define ADS_DNS_FOREST 0x80000000 /* DnsForestName is a DNS name */ -/* DomainControllerAddressType */ -#define ADS_INET_ADDRESS 0x00000001 -#define ADS_NETBIOS_ADDRESS 0x00000002 - - /* ads auth control flags */ #define ADS_AUTH_DISABLE_KERBEROS 0x01 #define ADS_AUTH_NO_BIND 0x02 diff --git a/source3/include/authdata.h b/source3/include/authdata.h index 8125f05639..59f07fb42d 100644 --- a/source3/include/authdata.h +++ b/source3/include/authdata.h @@ -19,7 +19,7 @@ */ #ifndef _AUTHDATA_H -#define _AUTHDATA_H +#define _AUTHDATA_H #include "rpc_misc.h" #include "rpc_netlogon.h" @@ -37,136 +37,4 @@ #define KRB5_AUTHDATA_IF_RELEVANT 1 #endif - -typedef struct pac_logon_name { - NTTIME logon_time; - uint16 len; - uint8 *username; /* Actually always little-endian. might not be null terminated, so not UNISTR */ -} PAC_LOGON_NAME; - -typedef struct pac_signature_data { - uint32 type; - RPC_DATA_BLOB signature; /* this not the on-wire-format (!) */ -} PAC_SIGNATURE_DATA; - -typedef struct group_membership { - uint32 rid; - uint32 attrs; -} GROUP_MEMBERSHIP; - -typedef struct group_membership_array { - uint32 count; - GROUP_MEMBERSHIP *group_membership; -} GROUP_MEMBERSHIP_ARRAY; - -#if 0 /* Unused, replaced by NET_USER_INFO_3 - Guenther */ - -typedef struct krb_sid_and_attrs { - uint32 sid_ptr; - uint32 attrs; - DOM_SID2 *sid; -} KRB_SID_AND_ATTRS; - -typedef struct krb_sid_and_attr_array { - uint32 count; - KRB_SID_AND_ATTRS *krb_sid_and_attrs; -} KRB_SID_AND_ATTR_ARRAY; - - -/* This is awfully similar to a samr_user_info_23, but not identical. - Many of the field names have been swiped from there, because it is - so similar that they are likely the same, but many have been verified. - Some are in a different order, though... */ -typedef struct pac_logon_info { - NTTIME logon_time; /* logon time */ - NTTIME logoff_time; /* logoff time */ - NTTIME kickoff_time; /* kickoff time */ - NTTIME pass_last_set_time; /* password last set time */ - NTTIME pass_can_change_time; /* password can change time */ - NTTIME pass_must_change_time; /* password must change time */ - - UNIHDR hdr_user_name; /* user name unicode string header */ - UNIHDR hdr_full_name; /* user's full name unicode string header */ - UNIHDR hdr_logon_script; /* these last 4 appear to be in a different */ - UNIHDR hdr_profile_path; /* order than in the info23 */ - UNIHDR hdr_home_dir; - UNIHDR hdr_dir_drive; - - uint16 logon_count; /* number of times user has logged onto domain */ - uint16 bad_password_count; /* samba4 idl */ - - uint32 user_rid; - uint32 group_rid; - uint32 group_count; - uint32 group_membership_ptr; - uint32 user_flags; - - uint8 session_key[16]; /* samba4 idl */ - UNIHDR hdr_dom_controller; - UNIHDR hdr_dom_name; - - uint32 ptr_dom_sid; - - uint8 lm_session_key[8]; /* samba4 idl */ - uint32 acct_flags; /* samba4 idl */ - uint32 unknown[7]; - - uint32 sid_count; - uint32 ptr_extra_sids; - - uint32 ptr_res_group_dom_sid; - uint32 res_group_count; - uint32 ptr_res_groups; - - UNISTR2 uni_user_name; /* user name unicode string header */ - UNISTR2 uni_full_name; /* user's full name unicode string header */ - UNISTR2 uni_logon_script; /* these last 4 appear to be in a different*/ - UNISTR2 uni_profile_path; /* order than in the info23 */ - UNISTR2 uni_home_dir; - UNISTR2 uni_dir_drive; - UNISTR2 uni_dom_controller; - UNISTR2 uni_dom_name; - DOM_SID2 dom_sid; - GROUP_MEMBERSHIP_ARRAY groups; - KRB_SID_AND_ATTR_ARRAY extra_sids; - DOM_SID2 res_group_dom_sid; - GROUP_MEMBERSHIP_ARRAY res_groups; - -} PAC_LOGON_INFO; -#endif - -typedef struct pac_logon_info { - NET_USER_INFO_3 info3; - DOM_SID2 res_group_dom_sid; - GROUP_MEMBERSHIP_ARRAY res_groups; - -} PAC_LOGON_INFO; - -typedef struct pac_info_ctr -{ - union - { - PAC_LOGON_INFO *logon_info; - PAC_SIGNATURE_DATA *srv_cksum; - PAC_SIGNATURE_DATA *privsrv_cksum; - PAC_LOGON_NAME *logon_name; - } pac; -} PAC_INFO_CTR; - -typedef struct pac_buffer { - uint32 type; - uint32 size; - uint32 offset; - uint32 offsethi; - PAC_INFO_CTR *ctr; - uint32 pad; -} PAC_BUFFER; - -typedef struct pac_data { - uint32 num_buffers; - uint32 version; - PAC_BUFFER *pac_buffer; -} PAC_DATA; - - #endif diff --git a/source3/include/byteorder.h b/source3/include/byteorder.h index 32138a89ce..9ced9cea3a 100644 --- a/source3/include/byteorder.h +++ b/source3/include/byteorder.h @@ -167,4 +167,10 @@ it also defines lots of intermediate macros, just ignore those :-) #define ALIGN4(p,base) ((p) + ((4 - (PTR_DIFF((p), (base)) & 3)) & 3)) #define ALIGN2(p,base) ((p) + ((2 - (PTR_DIFF((p), (base)) & 1)) & 1)) +/* 64 bit macros */ +#define BVAL(p, ofs) (IVAL(p,ofs) | (((uint64_t)IVAL(p,(ofs)+4)) << 32)) +#define BVALS(p, ofs) ((int64_t)BVAL(p,ofs)) +#define SBVAL(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,((uint64_t)(v))>>32)) +#define SBVALS(p, ofs, v) (SBVAL(p,ofs,(uint64_t)v)) + #endif /* _BYTEORDER_H */ diff --git a/source3/include/client.h b/source3/include/client.h index f8adf567de..d29a2e7341 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -82,7 +82,12 @@ struct rpc_pipe_client { }; /* Transport encryption state. */ -enum smb_trans_enc_type { SMB_TRANS_ENC_NTLM, SMB_TRANS_ENC_GSS }; +enum smb_trans_enc_type { + SMB_TRANS_ENC_NTLM +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + , SMB_TRANS_ENC_GSS +#endif +}; #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) struct smb_tran_enc_state_gss { diff --git a/source3/include/gpo.h b/source3/include/gpo.h index 9b1a672640..bf5ff6a598 100644 --- a/source3/include/gpo.h +++ b/source3/include/gpo.h @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. * Group Policy Object Support - * Copyright (C) Guenther Deschner 2005-2007 + * Copyright (C) Guenther Deschner 2005-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 @@ -22,7 +22,8 @@ enum GPO_LINK_TYPE { GP_LINK_MACHINE = 1, GP_LINK_SITE = 2, GP_LINK_DOMAIN = 3, - GP_LINK_OU = 4 + GP_LINK_OU = 4, + GP_LINK_LOCAL = 5 /* for convenience */ }; /* GPO_OPTIONS */ @@ -33,6 +34,17 @@ enum GPO_LINK_TYPE { #define GPO_LIST_FLAG_MACHINE 0x00000001 #define GPO_LIST_FLAG_SITEONLY 0x00000002 +/* following flags from http://support.microsoft.com/kb/312164/EN-US/ */ +#define GPO_INFO_FLAG_MACHINE 0x00000001 +#define GPO_INFO_FLAG_BACKGROUND 0x00000010 +#define GPO_INFO_FLAG_SLOWLINK 0x00000020 +#define GPO_INFO_FLAG_VERBOSE 0x00000040 +#define GPO_INFO_FLAG_NOCHANGES 0x00000080 +#define GPO_INFO_FLAG_LINKTRANSITION 0x00000100 +#define GPO_INFO_FLAG_LOGRSOP_TRANSITION 0x00000200 +#define GPO_INFO_FLAG_FORCED_REFRESH 0x00000400 +#define GPO_INFO_FLAG_SAFEMODE_BOOT 0x00000800 + #define GPO_VERSION_USER(x) (x >> 16) #define GPO_VERSION_MACHINE(x) (x & 0xffff) @@ -88,11 +100,59 @@ struct GP_EXT { char **extensions_guid; char **snapins; char **snapins_guid; + struct GP_EXT *next, *prev; }; #define GPO_CACHE_DIR "gpo_cache" #define GPT_INI "GPT.INI" +#define GPO_REFRESH_INTERVAL 60*90 + +#define GPO_REG_STATE_MACHINE "State\\Machine" + +enum gp_reg_action { + GP_REG_ACTION_NONE = 0, + GP_REG_ACTION_ADD_VALUE = 1, + GP_REG_ACTION_ADD_KEY = 2, + GP_REG_ACTION_DEL_VALUES = 3, + GP_REG_ACTION_DEL_VALUE = 4, + GP_REG_ACTION_DEL_ALL_VALUES = 5, + GP_REG_ACTION_DEL_KEYS = 6, + GP_REG_ACTION_SEC_KEY_SET = 7, + GP_REG_ACTION_SEC_KEY_RESET = 8 +}; + +struct gp_registry_entry { + enum gp_reg_action action; + const char *key; + const char *value; + struct registry_value *data; +}; + +struct gp_registry_value { + const char *value; + struct registry_value *data; +}; + +struct gp_registry_entry2 { + enum gp_reg_action action; + const char *key; + size_t num_values; + struct gp_registry_value **values; +}; + +struct gp_registry_entries { + size_t num_entries; + struct gp_registry_entry **entries; +}; + +struct gp_registry_context { + const struct nt_user_token *token; + const char *path; + struct registry_key *curr_key; +}; #define GP_EXT_GUID_SECURITY "827D319E-6EAC-11D2-A4EA-00C04F79F83A" #define GP_EXT_GUID_REGISTRY "35378EAC-683F-11D2-A89A-00C04FBBCFA2" #define GP_EXT_GUID_SCRIPTS "42B5FAAE-6536-11D2-AE5A-0000F87571E3" + +#include "libgpo/gpext/gpext.h" diff --git a/source3/include/includes.h b/source3/include/includes.h index 041c431a58..c54afd8933 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -698,7 +698,6 @@ typedef char fstring[FSTRING_LEN]; #include "rpc_netlogon.h" #include "reg_objects.h" #include "reg_db.h" -#include "rpc_samr.h" #include "rpc_srvsvc.h" #include "rpc_spoolss.h" #include "rpc_eventlog.h" @@ -1170,15 +1169,15 @@ bool kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, k void kerberos_free_data_contents(krb5_context context, krb5_data *pdata); NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx, DATA_BLOB *pac_data_blob, - krb5_context context, + krb5_context context, krb5_keyblock *service_keyblock, krb5_const_principal client_principal, time_t tgs_authtime, - PAC_DATA **pac_data); + struct PAC_DATA **pac_data_out); void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum, - PAC_SIGNATURE_DATA *sig); + struct PAC_SIGNATURE_DATA *sig); krb5_error_code smb_krb5_verify_checksum(krb5_context context, - krb5_keyblock *keyblock, + const krb5_keyblock *keyblock, krb5_keyusage usage, krb5_checksum *cksum, uint8 *data, @@ -1206,7 +1205,6 @@ bool smb_krb5_principal_compare_any_realm(krb5_context context, krb5_const_principal princ2); int cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, const char *ccname, time_t *tgs_expire); -PAC_LOGON_INFO *get_logon_info_from_pac(PAC_DATA *pac_data); krb5_error_code smb_krb5_renew_ticket(const char *ccache_string, const char *client_string, const char *service_string, time_t *expire_time); krb5_error_code kpasswd_err_to_krb5_err(krb5_error_code res_code); krb5_error_code smb_krb5_gen_netbios_krb5_address(smb_krb5_addresses **kerb_addr); @@ -1289,4 +1287,9 @@ void exit_server_fault(void) NORETURN_ATTRIBUTE ; #include "libnscd.h" #endif +#if defined(HAVE_IPV6) +void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss, + struct in6_addr ip); +#endif + #endif /* _INCLUDES_H */ diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h index 6c7dc80da8..6930812b29 100644 --- a/source3/include/libsmb_internal.h +++ b/source3/include/libsmb_internal.h @@ -1,12 +1,71 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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" + + #ifndef _LIBSMB_INTERNAL_H_ #define _LIBSMB_INTERNAL_H_ +#include "../include/libsmbclient.h" + #define SMBC_MAX_NAME 1023 #define SMBC_FILE_MODE (S_IFREG | 0444) #define SMBC_DIR_MODE (S_IFDIR | 0555) +/* + * DOS Attribute values (used internally) + */ +typedef struct DOS_ATTR_DESC { + int mode; + SMB_OFF_T size; + time_t create_time; + time_t access_time; + time_t write_time; + time_t change_time; + SMB_INO_T inode; +} DOS_ATTR_DESC; + + +/* + * Internal flags for extended attributes + */ -#include "include/libsmbclient.h" +/* internal mode values */ +#define SMBC_XATTR_MODE_ADD 1 +#define SMBC_XATTR_MODE_REMOVE 2 +#define SMBC_XATTR_MODE_REMOVE_ALL 3 +#define SMBC_XATTR_MODE_SET 4 +#define SMBC_XATTR_MODE_CHOWN 5 +#define SMBC_XATTR_MODE_CHGRP 6 + +#define CREATE_ACCESS_READ READ_CONTROL_ACCESS + +/*We should test for this in configure ... */ +#ifndef ENOTSUP +#define ENOTSUP EOPNOTSUPP +#endif struct _SMBCSRV { @@ -46,12 +105,13 @@ struct _SMBCFILE { }; -struct smbc_internal_data { +/* + * Context structure + */ +struct SMBC_internal_data { - /* - * Is this handle initialized ? - */ - bool _initialized; + /* True when this handle is initialized */ + bool initialized; /* dirent pointer location * @@ -64,22 +124,22 @@ struct smbc_internal_data { * According to <linux/limits.h>, NAME_MAX is 255. Is it longer * anyplace else? */ - char _dirent[1024]; + char dirent[1024]; /* * server connection list */ - SMBCSRV * _servers; + SMBCSRV * servers; /* * open file/dir list */ - SMBCFILE * _files; + SMBCFILE * files; /* * Log to standard error instead of the more typical standard output */ - bool _debug_stderr; + bool debug_stderr; /* * Support "Create Time" in get/set with the *xattr() functions, if @@ -88,33 +148,389 @@ struct smbc_internal_data { * CREATE_TIME. Default is FALSE, i.e. to use the old-style shorter * names and to not support CREATE time, for backward compatibility. */ - bool _full_time_names; + bool full_time_names; /* * The share mode of a file being opened. To match POSIX semantics * (and maintain backward compatibility), DENY_NONE is the default. */ - smbc_share_mode _share_mode; + smbc_share_mode share_mode; /* * Authentication function which includes the context. This will be * used if set; otherwise context->callbacks.auth_fn() will be used. */ - smbc_get_auth_data_with_context_fn _auth_fn_with_context; + smbc_get_auth_data_with_context_fn auth_fn_with_context; /* * An opaque (to this library) user data handle which can be set * and retrieved with smbc_option_set() and smbc_option_get(). */ - void * _user_data; + void * user_data; /* * Should we attempt UNIX smb encryption ? * Set to 0 if we should never attempt, set to 1 if * encryption requested, set to 2 if encryption required. */ - int _smb_encryption_level; + smbc_smb_encrypt_level smb_encryption_level; + + struct smbc_server_cache * server_cache; + + /* POSIX emulation functions */ + struct + { +#if 0 /* Left in libsmbclient.h for backward compatibility */ + smbc_open_fn open_fn; + smbc_creat_fn creat_fn; + smbc_read_fn read_fn; + smbc_write_fn write_fn; + smbc_unlink_fn unlink_fn; + smbc_rename_fn rename_fn; + smbc_lseek_fn lseek_fn; + smbc_stat_fn stat_fn; + smbc_fstat_fn fstat_fn; +#endif + smbc_ftruncate_fn ftruncate_fn; +#if 0 /* Left in libsmbclient.h for backward compatibility */ + smbc_close_fn close_fn; + smbc_opendir_fn opendir_fn; + smbc_closedir_fn closedir_fn; + smbc_readdir_fn readdir_fn; + smbc_getdents_fn getdents_fn; + smbc_mkdir_fn mkdir_fn; + smbc_rmdir_fn rmdir_fn; + smbc_telldir_fn telldir_fn; + smbc_lseekdir_fn lseekdir_fn; + smbc_fstatdir_fn fstatdir_fn; + smbc_chmod_fn chmod_fn; + smbc_utimes_fn utimes_fn; + smbc_setxattr_fn setxattr_fn; + smbc_getxattr_fn getxattr_fn; + smbc_removexattr_fn removexattr_fn; + smbc_listxattr_fn listxattr_fn; +#endif + } posix_emu; + +#if 0 /* Left in libsmbclient.h for backward compatibility */ + /* Printing-related functions */ + struct + { + smbc_print_file_fn print_file_fn; + smbc_open_print_job_fn open_print_job_fn; + smbc_list_print_jobs_fn list_print_jobs_fn; + smbc_unlink_print_job_fn unlink_print_job_fn; + } printing; +#endif + +#if 0 /* None available yet */ + /* SMB high-level functions */ + struct + { + } smb; + +#endif }; +/* Functions in libsmb_cache.c */ +int +SMBC_add_cached_server(SMBCCTX * context, + SMBCSRV * newsrv, + const char * server, + const char * share, + const char * workgroup, + const char * username); + +SMBCSRV * +SMBC_get_cached_server(SMBCCTX * context, + const char * server, + const char * share, + const char * workgroup, + const char * user); + +int +SMBC_remove_cached_server(SMBCCTX * context, + SMBCSRV * server); + +int +SMBC_purge_cached_servers(SMBCCTX * context); + + +/* Functions in libsmb_dir.c */ +int +SMBC_check_options(char *server, + char *share, + char *path, + char *options); + +SMBCFILE * +SMBC_opendir_ctx(SMBCCTX *context, + const char *fname); + +int +SMBC_closedir_ctx(SMBCCTX *context, + SMBCFILE *dir); + +struct smbc_dirent * +SMBC_readdir_ctx(SMBCCTX *context, + SMBCFILE *dir); + +int +SMBC_getdents_ctx(SMBCCTX *context, + SMBCFILE *dir, + struct smbc_dirent *dirp, + int count); + +int +SMBC_mkdir_ctx(SMBCCTX *context, + const char *fname, + mode_t mode); + +int +SMBC_rmdir_ctx(SMBCCTX *context, + const char *fname); + +off_t +SMBC_telldir_ctx(SMBCCTX *context, + SMBCFILE *dir); + +int +SMBC_lseekdir_ctx(SMBCCTX *context, + SMBCFILE *dir, + off_t offset); + +int +SMBC_fstatdir_ctx(SMBCCTX *context, + SMBCFILE *dir, + struct stat *st); + +int +SMBC_chmod_ctx(SMBCCTX *context, + const char *fname, + mode_t newmode); + +int +SMBC_utimes_ctx(SMBCCTX *context, + const char *fname, + struct timeval *tbuf); + +int +SMBC_unlink_ctx(SMBCCTX *context, + const char *fname); + +int +SMBC_rename_ctx(SMBCCTX *ocontext, + const char *oname, + SMBCCTX *ncontext, + const char *nname); + + +/* Functions in libsmb_file.c */ +SMBCFILE * +SMBC_open_ctx(SMBCCTX *context, + const char *fname, + int flags, + mode_t mode); + +SMBCFILE * +SMBC_creat_ctx(SMBCCTX *context, + const char *path, + mode_t mode); + +ssize_t +SMBC_read_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count); + +ssize_t +SMBC_write_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count); + +int +SMBC_close_ctx(SMBCCTX *context, + SMBCFILE *file); + +bool +SMBC_getatr(SMBCCTX * context, + SMBCSRV *srv, + char *path, + uint16 *mode, + SMB_OFF_T *size, + struct timespec *create_time_ts, + struct timespec *access_time_ts, + struct timespec *write_time_ts, + struct timespec *change_time_ts, + SMB_INO_T *ino); + +bool +SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, + time_t create_time, + time_t access_time, + time_t write_time, + time_t change_time, + uint16 mode); + +off_t +SMBC_lseek_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t offset, + int whence); + +int +SMBC_ftruncate_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t length); + + +/* Functions in libsmb_misc.c */ +int +SMBC_dlist_contains(SMBCFILE * list, SMBCFILE *p); + +int +SMBC_errno(SMBCCTX *context, + struct cli_state *c); + + +/* Functions in libsmb_path.c */ +int +SMBC_urldecode(char *dest, + char *src, + size_t max_dest_len); + +int +SMBC_urlencode(char *dest, + char *src, + int max_dest_len); + +int +SMBC_parse_path(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *fname, + char **pp_workgroup, + char **pp_server, + char **pp_share, + char **pp_path, + char **pp_user, + char **pp_password, + char **pp_options); + + +/* Functions in libsmb_printjob.c */ +SMBCFILE * +SMBC_open_print_job_ctx(SMBCCTX *context, + const char *fname); + +int +SMBC_print_file_ctx(SMBCCTX *c_file, + const char *fname, + SMBCCTX *c_print, + const char *printq); + +int +SMBC_list_print_jobs_ctx(SMBCCTX *context, + const char *fname, + smbc_list_print_job_fn fn); + +int +SMBC_unlink_print_job_ctx(SMBCCTX *context, + const char *fname, + int id); + + +/* Functions in libsmb_server.c */ +int +SMBC_check_server(SMBCCTX * context, + SMBCSRV * server); + +int +SMBC_remove_unused_server(SMBCCTX * context, + SMBCSRV * srv); + +void +SMBC_call_auth_fn(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password); + +void +SMBC_get_auth_data(const char *server, const char *share, + char *workgroup_buf, int workgroup_buf_len, + char *username_buf, int username_buf_len, + char *password_buf, int password_buf_len); + +SMBCSRV * +SMBC_find_server(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password); + +SMBCSRV * +SMBC_server(TALLOC_CTX *ctx, + SMBCCTX *context, + bool connect_if_not_found, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password); + +SMBCSRV * +SMBC_attr_server(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password); + + +/* Functions in libsmb_stat.c */ +int +SMBC_stat_ctx(SMBCCTX *context, + const char *fname, + struct stat *st); + +int +SMBC_fstat_ctx(SMBCCTX *context, + SMBCFILE *file, + struct stat *st); + + +/* Functions in libsmb_xattr.c */ +int +SMBC_setxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size, + int flags); + +int +SMBC_getxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size); + +int +SMBC_removexattr_ctx(SMBCCTX *context, + const char *fname, + const char *name); + +int +SMBC_listxattr_ctx(SMBCCTX *context, + const char *fname, + char *list, + size_t size); + #endif diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index 07242f7956..2e38944d65 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -5,7 +5,7 @@ Copyright (C) Richard Sharpe 2000 Copyright (C) John Terpsra 2000 Copyright (C) Tom Jansen (Ninja ISD) 2002 - Copyright (C) Derrell Lipman 2003 + Copyright (C) Derrell Lipman 2003-2008 This program is free software; you can redistribute it and/or modify @@ -25,6 +25,13 @@ #ifndef SMBCLIENT_H_INCLUDED #define SMBCLIENT_H_INCLUDED +#undef DEPRECATED_SMBC_INTERFACE +#if ! defined(__LIBSMBCLIENT_INTERNAL__) && defined(__GNUC__) +# define DEPRECATED_SMBC_INTERFACE __attribute__ ((deprecated)) +#else +# define DEPRECATED_SMBC_INTERFACE +#endif + #ifdef __cplusplus extern "C" { #endif @@ -142,7 +149,7 @@ struct smbc_dirent /* * Valid values for the option "open_share_mode", when calling - * smbc_option_set() + * smbc_setOptionOpenShareMode() */ typedef enum smbc_share_mode { @@ -155,6 +162,21 @@ typedef enum smbc_share_mode } smbc_share_mode; +/** + * Values for option SMB Encryption Level, as set and retrieved with + * smbc_setOptionSmbEncryptionLevel() and smbc_getOptionSmbEncryptionLevel() + */ +typedef enum smbc_smb_encrypt_level +{ + SMBC_ENCRYPTLEVEL_NONE = 0, + SMBC_ENCRYPTLEVEL_REQUEST = 1, + SMBC_ENCRYPTLEVEL_REQUIRE = 2 +} smbc_smb_encrypt_level; + + +typedef int smbc_bool; + + #ifndef ENOATTR # define ENOATTR ENOENT /* No such attribute */ #endif @@ -213,6 +235,21 @@ typedef struct _SMBCFILE SMBCFILE; typedef struct _SMBCCTX SMBCCTX; +/* + * Flags for SMBCCTX->flags + * + * NEW CODE SHOULD NOT DIRECTLY MANIPULATE THE CONTEXT STRUCTURE. + * Instead, use: + * smbc_setOptionUseKerberos() + * smbc_getOptionUseKerberos() + * smbc_setOptionFallbackAfterKerberos() + * smbc_getOptionFallbackAFterKerberos() + * smbc_setOptionNoAutoAnonymousLogin() + * smbc_getOptionNoAutoAnonymousLogin() + */ +# define SMB_CTX_FLAG_USE_KERBEROS (1 << 0) +# define SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS (1 << 1) +# define SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON (1 << 2) @@ -389,207 +426,556 @@ typedef int (*smbc_remove_cached_srv_fn)(SMBCCTX * c, SMBCSRV *srv); typedef int (*smbc_purge_cached_fn) (SMBCCTX * c); -/**@ingroup structure - * Structure that contains a client context information - * This structure is know as SMBCCTX + +/***************************************** + * Getters and setters for CONFIGURATION * + *****************************************/ + +/** Get the debug level */ +int +smbc_getDebug(SMBCCTX *c); + +/** Set the debug level */ +void +smbc_setDebug(SMBCCTX *c, int debug); + +/** Get the netbios name used for making connections */ +char * +smbc_getNetbiosName(SMBCCTX *c); + +/** Set the netbios name used for making connections */ +void +smbc_setNetbiosName(SMBCCTX *c, char * netbios_name); + +/** Get the workgroup used for making connections */ +char * +smbc_getWorkgroup(SMBCCTX *c); + +/** Set the workgroup used for making connections */ +void smbc_setWorkgroup(SMBCCTX *c, char * workgroup); + +/** Get the username used for making connections */ +char * +smbc_getUser(SMBCCTX *c); + +/** Set the username used for making connections */ +void +smbc_setUser(SMBCCTX *c, char * user); + +/** + * Get the timeout used for waiting on connections and response data + * (in milliseconds) */ -struct _SMBCCTX { - /** debug level - */ - int debug; - - /** netbios name used for making connections - */ - char * netbios_name; +int +smbc_getTimeout(SMBCCTX *c); - /** workgroup name used for making connections - */ - char * workgroup; +/** + * Set the timeout used for waiting on connections and response data + * (in milliseconds) + */ +void +smbc_setTimeout(SMBCCTX *c, int timeout); - /** username used for making connections - */ - char * user; - /** timeout used for waiting on connections / response data (in milliseconds) - */ - int timeout; - /** callable functions for files: - * For usage and return values see the smbc_* functions - */ - SMBCFILE * (*open) (SMBCCTX *c, const char *fname, int flags, mode_t mode); - SMBCFILE * (*creat) (SMBCCTX *c, const char *path, mode_t mode); - ssize_t (*read) (SMBCCTX *c, SMBCFILE *file, void *buf, size_t count); - ssize_t (*write) (SMBCCTX *c, SMBCFILE *file, void *buf, size_t count); - int (*unlink) (SMBCCTX *c, const char *fname); - int (*rename) (SMBCCTX *ocontext, const char *oname, - SMBCCTX *ncontext, const char *nname); - off_t (*lseek) (SMBCCTX *c, SMBCFILE * file, off_t offset, int whence); - int (*stat) (SMBCCTX *c, const char *fname, struct stat *st); - int (*fstat) (SMBCCTX *c, SMBCFILE *file, struct stat *st); - int (*close_fn) (SMBCCTX *c, SMBCFILE *file); - - /** callable functions for dirs - */ - SMBCFILE * (*opendir) (SMBCCTX *c, const char *fname); - int (*closedir)(SMBCCTX *c, SMBCFILE *dir); - struct smbc_dirent * (*readdir)(SMBCCTX *c, SMBCFILE *dir); - int (*getdents)(SMBCCTX *c, SMBCFILE *dir, - struct smbc_dirent *dirp, int count); - int (*mkdir) (SMBCCTX *c, const char *fname, mode_t mode); - int (*rmdir) (SMBCCTX *c, const char *fname); - off_t (*telldir) (SMBCCTX *c, SMBCFILE *dir); - int (*lseekdir)(SMBCCTX *c, SMBCFILE *dir, off_t offset); - int (*fstatdir)(SMBCCTX *c, SMBCFILE *dir, struct stat *st); - int (*chmod)(SMBCCTX *c, const char *fname, mode_t mode); - int (*utimes)(SMBCCTX *c, - const char *fname, struct timeval *tbuf); - int (*setxattr)(SMBCCTX *context, - const char *fname, - const char *name, - const void *value, - size_t size, - int flags); - int (*getxattr)(SMBCCTX *context, - const char *fname, - const char *name, - const void *value, - size_t size); - int (*removexattr)(SMBCCTX *context, - const char *fname, - const char *name); - int (*listxattr)(SMBCCTX *context, - const char *fname, - char *list, - size_t size); +/*********************************** + * Getters and setters for OPTIONS * + ***********************************/ - /** callable functions for printing - */ - int (*print_file)(SMBCCTX *c_file, const char *fname, - SMBCCTX *c_print, const char *printq); - SMBCFILE * (*open_print_job)(SMBCCTX *c, const char *fname); - int (*list_print_jobs)(SMBCCTX *c, const char *fname, smbc_list_print_job_fn fn); - int (*unlink_print_job)(SMBCCTX *c, const char *fname, int id); +/** Get whether to log to standard error instead of standard output */ +smbc_bool +smbc_getOptionDebugToStderr(SMBCCTX *c); +/** Set whether to log to standard error instead of standard output */ +void +smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b); - /* - ** Callbacks - * These callbacks _always_ have to be initialized because they will - * not be checked at dereference for increased speed. - */ - struct _smbc_callbacks { - /** authentication function callback: called upon auth requests - */ - smbc_get_auth_data_fn auth_fn; - - /** check if a server is still good - */ - smbc_check_server_fn check_server_fn; +/** + * Get whether to use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also setting/getting + * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME + * was supposed to be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +smbc_bool +smbc_getOptionFullTimeNames(SMBCCTX *c); - /** remove a server if unused - */ - smbc_remove_unused_server_fn remove_unused_server_fn; +/** + * Set whether to use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also setting/getting + * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME + * was supposed to be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +void +smbc_setOptionFullTimeNames(SMBCCTX *c, smbc_bool b); - /** Cache subsystem - * For an example cache system see samba/source/libsmb/libsmb_cache.c - * Cache subsystem functions follow. - */ +/** + * Get the share mode to use for files opened with SMBC_open_ctx(). The + * default is SMBC_SHAREMODE_DENY_NONE. + */ +smbc_share_mode +smbc_getOptionOpenShareMode(SMBCCTX *c); - /** server cache addition - */ - smbc_add_cached_srv_fn add_cached_srv_fn; +/** + * Set the share mode to use for files opened with SMBC_open_ctx(). The + * default is SMBC_SHAREMODE_DENY_NONE. + */ +void +smbc_setOptionOpenShareMode(SMBCCTX *c, smbc_share_mode share_mode); - /** server cache lookup - */ - smbc_get_cached_srv_fn get_cached_srv_fn; +/** Retrieve a previously saved user data handle */ +void * +smbc_getOptionUserData(SMBCCTX *c); - /** server cache removal - */ - smbc_remove_cached_srv_fn remove_cached_srv_fn; - - /** server cache purging, try to remove all cached servers (disconnect) - */ - smbc_purge_cached_fn purge_cached_fn; - } callbacks; +/** Save a user data handle */ +void +smbc_setOptionUserData(SMBCCTX *c, void *user_data); +/** Get the encoded value for encryption level. */ +smbc_smb_encrypt_level +smbc_getOptionSmbEncryptionLevel(SMBCCTX *c); - /** Space to store private data of the server cache. - */ - struct smbc_server_cache * server_cache; +/** Set the encoded value for encryption level. */ +void +smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level); - int flags; - - /** user options selections that apply to this session - */ - struct _smbc_options { +/** + * Get from how many local master browsers should the list of workgroups be + * retrieved. It can take up to 12 minutes or longer after a server becomes a + * local master browser, for it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client never knows + * which local master browser will be found first, the one which is found + * first and used to retrieve a browse list may have an incomplete or empty + * browse list. By requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small networks (few + * workgroups), it is recommended that this value be set to 0, causing the + * browse lists from all found local master browsers to be retrieved and + * merged. For networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ +int +smbc_getOptionBrowseMaxLmbCount(SMBCCTX *c); - /* - * From how many local master browsers should the list of - * workgroups be retrieved? It can take up to 12 minutes or - * longer after a server becomes a local master browser, for - * it to have the entire browse list (the list of - * workgroups/domains) from an entire network. Since a client - * never knows which local master browser will be found first, - * the one which is found first and used to retrieve a browse - * list may have an incomplete or empty browse list. By - * requesting the browse list from multiple local master - * browsers, a more complete list can be generated. For small - * networks (few workgroups), it is recommended that this - * value be set to 0, causing the browse lists from all found - * local master browsers to be retrieved and merged. For - * networks with many workgroups, a suitable value for this - * variable is probably somewhere around 3. (Default: 3). - */ - int browse_max_lmb_count; - - /* - * There is a difference in the desired return strings from - * smbc_readdir() depending upon whether the filenames are to - * be displayed to the user, or whether they are to be - * appended to the path name passed to smbc_opendir() to call - * a further smbc_ function (e.g. open the file with - * smbc_open()). In the former case, the filename should be - * in "human readable" form. In the latter case, the smbc_ - * functions expect a URL which must be url-encoded. Those - * functions decode the URL. If, for example, smbc_readdir() - * returned a file name of "abc%20def.txt", passing a path - * with this file name attached to smbc_open() would cause - * smbc_open to attempt to open the file "abc def.txt" since - * the %20 is decoded into a space. - * - * Set this option to True if the names returned by - * smbc_readdir() should be url-encoded such that they can be - * passed back to another smbc_ call. Set it to False if the - * names returned by smbc_readdir() are to be presented to the - * user. - * - * For backwards compatibility, this option defaults to False. - */ - int urlencode_readdir_entries; - - /* - * Some Windows versions appear to have a limit to the number - * of concurrent SESSIONs and/or TREE CONNECTions. In - * one-shot programs (i.e. the program runs and then quickly - * ends, thereby shutting down all connections), it is - * probably reasonable to establish a new connection for each - * share. In long-running applications, the limitation can be - * avoided by using only a single connection to each server, - * and issuing a new TREE CONNECT when the share is accessed. - */ - int one_share_per_server; - } options; - - /** INTERNAL DATA - * do _NOT_ touch this from your program ! - */ - struct smbc_internal_data * internal; -}; +/** + * Set from how many local master browsers should the list of workgroups be + * retrieved. It can take up to 12 minutes or longer after a server becomes a + * local master browser, for it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client never knows + * which local master browser will be found first, the one which is found + * first and used to retrieve a browse list may have an incomplete or empty + * browse list. By requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small networks (few + * workgroups), it is recommended that this value be set to 0, causing the + * browse lists from all found local master browsers to be retrieved and + * merged. For networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ +void +smbc_setOptionBrowseMaxLmbCount(SMBCCTX *c, int count); + +/** + * Get whether to url-encode readdir entries. + * + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ +smbc_bool +smbc_getOptionUrlEncodeReaddirEntries(SMBCCTX *c); + +/** + * Set whether to url-encode readdir entries. + * + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ +void +smbc_setOptionUrlEncodeReaddirEntries(SMBCCTX *c, smbc_bool b); + +/** + * Get whether to use the same connection for all shares on a server. + * + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ +smbc_bool +smbc_getOptionOneSharePerServer(SMBCCTX *c); + +/** + * Set whether to use the same connection for all shares on a server. + * + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ +void +smbc_setOptionOneSharePerServer(SMBCCTX *c, smbc_bool b); + +/** Get whether to enable use of kerberos */ +smbc_bool +smbc_getOptionUseKerberos(SMBCCTX *c); + +/** Set whether to enable use of kerberos */ +void +smbc_setOptionUseKerberos(SMBCCTX *c, smbc_bool b); + +/** Get whether to fallback after kerberos */ +smbc_bool +smbc_getOptionFallbackAfterKerberos(SMBCCTX *c); + +/** Set whether to fallback after kerberos */ +void +smbc_setOptionFallbackAfterKerberos(SMBCCTX *c, smbc_bool b); + +/** Get whether to automatically select anonymous login */ +smbc_bool +smbc_getOptionNoAutoAnonymousLogin(SMBCCTX *c); + +/** Set whether to automatically select anonymous login */ +void +smbc_setOptionNoAutoAnonymousLogin(SMBCCTX *c, smbc_bool b); + + + +/************************************* + * Getters and setters for FUNCTIONS * + *************************************/ + +/** Get the function for obtaining authentication data */ +smbc_get_auth_data_fn smbc_getFunctionAuthData(SMBCCTX *c); + +/** Set the function for obtaining authentication data */ +void smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn); + +/** Get the new-style authentication function which includes the context. */ +smbc_get_auth_data_with_context_fn +smbc_getFunctionAuthDataWithContext(SMBCCTX *c); + +/** Set the new-style authentication function which includes the context. */ +void +smbc_setFunctionAuthDataWithContext(SMBCCTX *c, + smbc_get_auth_data_with_context_fn fn); + +/** Get the function for checking if a server is still good */ +smbc_check_server_fn smbc_getFunctionCheckServer(SMBCCTX *c); + +/** Set the function for checking if a server is still good */ +void smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn); + +/** Get the function for removing a server if unused */ +smbc_remove_unused_server_fn smbc_getFunctionRemoveUnusedServer(SMBCCTX *c); + +/** Set the function for removing a server if unused */ +void smbc_setFunctionRemoveUnusedServer(SMBCCTX *c, + smbc_remove_unused_server_fn fn); + +/** Get the function for adding a cached server */ +smbc_add_cached_srv_fn smbc_getFunctionAddCachedServer(SMBCCTX *c); + +/** Set the function for adding a cached server */ +void smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn); + +/** Get the function for server cache lookup */ +smbc_get_cached_srv_fn smbc_getFunctionGetCachedServer(SMBCCTX *c); + +/** Set the function for server cache lookup */ +void smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn); + +/** Get the function for server cache removal */ +smbc_remove_cached_srv_fn smbc_getFunctionRemoveCachedServer(SMBCCTX *c); + +/** Set the function for server cache removal */ +void smbc_setFunctionRemoveCachedServer(SMBCCTX *c, + smbc_remove_cached_srv_fn fn); + +/** + * Get the function for server cache purging. This function tries to + * remove all cached servers (e.g. on disconnect) + */ +smbc_purge_cached_fn smbc_getFunctionPurgeCachedServers(SMBCCTX *c); + +/** + * Set the function for server cache purging. This function tries to + * remove all cached servers (e.g. on disconnect) + */ +void smbc_setFunctionPurgeCachedServers(SMBCCTX *c, + smbc_purge_cached_fn fn); + +/** Get the function to store private data of the server cache */ +struct smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c); + +/** Set the function to store private data of the server cache */ +void smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache); + + + +/***************************************************************** + * Callable functions for files. * + * Each callable has a function signature typedef, a declaration * + * for the getter, and a declaration for the setter. * + *****************************************************************/ + +typedef SMBCFILE * (*smbc_open_fn)(SMBCCTX *c, + const char *fname, + int flags, + mode_t mode); +smbc_open_fn smbc_getFunctionOpen(SMBCCTX *c); +void smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn); + +typedef SMBCFILE * (*smbc_creat_fn)(SMBCCTX *c, + const char *path, + mode_t mode); +smbc_creat_fn smbc_getFunctionCreat(SMBCCTX *c); +void smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn); + +typedef ssize_t (*smbc_read_fn)(SMBCCTX *c, + SMBCFILE *file, + void *buf, + size_t count); +smbc_read_fn smbc_getFunctionRead(SMBCCTX *c); +void smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn); + +typedef ssize_t (*smbc_write_fn)(SMBCCTX *c, + SMBCFILE *file, + void *buf, + size_t count); +smbc_write_fn smbc_getFunctionWrite(SMBCCTX *c); +void smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn); + +typedef int (*smbc_unlink_fn)(SMBCCTX *c, + const char *fname); +smbc_unlink_fn smbc_getFunctionUnlink(SMBCCTX *c); +void smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn); + +typedef int (*smbc_rename_fn)(SMBCCTX *ocontext, + const char *oname, + SMBCCTX *ncontext, + const char *nname); +smbc_rename_fn smbc_getFunctionRename(SMBCCTX *c); +void smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn); + +typedef off_t (*smbc_lseek_fn)(SMBCCTX *c, + SMBCFILE * file, + off_t offset, + int whence); +smbc_lseek_fn smbc_getFunctionLseek(SMBCCTX *c); +void smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn); + +typedef int (*smbc_stat_fn)(SMBCCTX *c, + const char *fname, + struct stat *st); +smbc_stat_fn smbc_getFunctionStat(SMBCCTX *c); +void smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn); + +typedef int (*smbc_fstat_fn)(SMBCCTX *c, + SMBCFILE *file, + struct stat *st); +smbc_fstat_fn smbc_getFunctionFstat(SMBCCTX *c); +void smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn); + +typedef int (*smbc_ftruncate_fn)(SMBCCTX *c, + SMBCFILE *f, + off_t size); +smbc_ftruncate_fn smbc_getFunctionFtruncate(SMBCCTX *c); +void smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn); + +typedef int (*smbc_close_fn)(SMBCCTX *c, + SMBCFILE *file); +smbc_close_fn smbc_getFunctionClose(SMBCCTX *c); +void smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn); + + + +/***************************************************************** + * Callable functions for directories. * + * Each callable has a function signature typedef, a declaration * + * for the getter, and a declaration for the setter. * + *****************************************************************/ + +typedef SMBCFILE * (*smbc_opendir_fn)(SMBCCTX *c, + const char *fname); +smbc_opendir_fn smbc_getFunctionOpendir(SMBCCTX *c); +void smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn); + +typedef int (*smbc_closedir_fn)(SMBCCTX *c, + SMBCFILE *dir); +smbc_closedir_fn smbc_getFunctionClosedir(SMBCCTX *c); +void smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn); + +typedef struct smbc_dirent * (*smbc_readdir_fn)(SMBCCTX *c, + SMBCFILE *dir); +smbc_readdir_fn smbc_getFunctionReaddir(SMBCCTX *c); +void smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn); + +typedef int (*smbc_getdents_fn)(SMBCCTX *c, + SMBCFILE *dir, + struct smbc_dirent *dirp, + int count); +smbc_getdents_fn smbc_getFunctionGetdents(SMBCCTX *c); +void smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn); + +typedef int (*smbc_mkdir_fn)(SMBCCTX *c, + const char *fname, + mode_t mode); +smbc_mkdir_fn smbc_getFunctionMkdir(SMBCCTX *c); +void smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn); + +typedef int (*smbc_rmdir_fn)(SMBCCTX *c, + const char *fname); +smbc_rmdir_fn smbc_getFunctionRmdir(SMBCCTX *c); +void smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn); + +typedef off_t (*smbc_telldir_fn)(SMBCCTX *c, + SMBCFILE *dir); +smbc_telldir_fn smbc_getFunctionTelldir(SMBCCTX *c); +void smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn); + +typedef int (*smbc_lseekdir_fn)(SMBCCTX *c, + SMBCFILE *dir, + off_t offset); +smbc_lseekdir_fn smbc_getFunctionLseekdir(SMBCCTX *c); +void smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn); + +typedef int (*smbc_fstatdir_fn)(SMBCCTX *c, + SMBCFILE *dir, + struct stat *st); +smbc_fstatdir_fn smbc_getFunctionFstatdir(SMBCCTX *c); +void smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn); + + + +/***************************************************************** + * Callable functions applicable to both files and directories. * + * Each callable has a function signature typedef, a declaration * + * for the getter, and a declaration for the setter. * + *****************************************************************/ + +typedef int (*smbc_chmod_fn)(SMBCCTX *c, + const char *fname, + mode_t mode); +smbc_chmod_fn smbc_getFunctionChmod(SMBCCTX *c); +void smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn); + +typedef int (*smbc_utimes_fn)(SMBCCTX *c, + const char *fname, + struct timeval *tbuf); +smbc_utimes_fn smbc_getFunctionUtimes(SMBCCTX *c); +void smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn); + +typedef int (*smbc_setxattr_fn)(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size, + int flags); +smbc_setxattr_fn smbc_getFunctionSetxattr(SMBCCTX *c); +void smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn); + +typedef int (*smbc_getxattr_fn)(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size); +smbc_getxattr_fn smbc_getFunctionGetxattr(SMBCCTX *c); +void smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn); + +typedef int (*smbc_removexattr_fn)(SMBCCTX *context, + const char *fname, + const char *name); +smbc_removexattr_fn smbc_getFunctionRemovexattr(SMBCCTX *c); +void smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn); + +typedef int (*smbc_listxattr_fn)(SMBCCTX *context, + const char *fname, + char *list, + size_t size); +smbc_listxattr_fn smbc_getFunctionListxattr(SMBCCTX *c); +void smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn); + + + +/***************************************************************** + * Callable functions for printing. * + * Each callable has a function signature typedef, a declaration * + * for the getter, and a declaration for the setter. * + *****************************************************************/ + +typedef int (*smbc_print_file_fn)(SMBCCTX *c_file, + const char *fname, + SMBCCTX *c_print, + const char *printq); +smbc_print_file_fn smbc_getFunctionPrintFile(SMBCCTX *c); +void smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn); + +typedef SMBCFILE * (*smbc_open_print_job_fn)(SMBCCTX *c, + const char *fname); +smbc_open_print_job_fn smbc_getFunctionOpenPrintJob(SMBCCTX *c); +void smbc_setFunctionOpenPrintJob(SMBCCTX *c, + smbc_open_print_job_fn fn); + +typedef int (*smbc_list_print_jobs_fn)(SMBCCTX *c, + const char *fname, + smbc_list_print_job_fn fn); +smbc_list_print_jobs_fn smbc_getFunctionListPrintJobs(SMBCCTX *c); +void smbc_setFunctionListPrintJobs(SMBCCTX *c, + smbc_list_print_jobs_fn fn); + +typedef int (*smbc_unlink_print_job_fn)(SMBCCTX *c, + const char *fname, + int id); +smbc_unlink_print_job_fn smbc_getFunctionUnlinkPrintJob(SMBCCTX *c); +void smbc_setFunctionUnlinkPrintJob(SMBCCTX *c, + smbc_unlink_print_job_fn fn); -/* Flags for SMBCCTX->flags */ -#define SMB_CTX_FLAG_USE_KERBEROS (1 << 0) -#define SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS (1 << 1) -#define SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON (1 << 2) /* don't try to do automatic anon login */ /**@ingroup misc * Create a new SBMCCTX (a context). @@ -630,35 +1016,16 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx); /**@ingroup misc - * Each time the context structure is changed, we have binary backward - * compatibility issues. Instead of modifying the public portions of the - * context structure to add new options, instead, we put them in the internal - * portion of the context structure and provide a set function for these new - * options. - * - * @param context A pointer to a SMBCCTX obtained from smbc_new_context() - * - * @param option_name - * The name of the option for which the value is to be set - * - * @param option_value - * The new value of the option being set * + * @deprecated. Use smbc_setOption*() functions instead. */ void smbc_option_set(SMBCCTX *context, char *option_name, ... /* option_value */); + /* - * Retrieve the current value of an option - * - * @param context A pointer to a SMBCCTX obtained from smbc_new_context() - * - * @param option_name - * The name of the option for which the value is to be - * retrieved - * - * @return The value of the specified option. + * @deprecated. Use smbc_getOption*() functions instead. */ void * smbc_option_get(SMBCCTX *context, @@ -1193,6 +1560,26 @@ int smbc_stat(const char *url, struct stat *st); int smbc_fstat(int fd, struct stat *st); +/**@ingroup attribute + * Truncate a file given a file descriptor + * + * @param fd Open file handle from smbc_open() or smbc_creat() + * + * @param size size to truncate the file to + * + * @return EBADF filedes is bad. + * - EACCES Permission denied. + * - EBADF fd is not a valid file descriptor + * - EINVAL Problems occurred in the underlying routines + * or smbc_init not called. + * - ENOMEM Out of memory + * + * @see , Unix ftruncate() + * + */ +int smbc_ftruncate(int fd, off_t size); + + /**@ingroup attribue * Change the ownership of a file or directory. * @@ -2190,5 +2577,232 @@ smbc_version(void); } #endif +/** + * @ingroup structure + * Structure that contains a client context information + * This structure is known as SMBCCTX + * + * DO NOT DIRECTLY MANIPULATE THE CONTEXT STRUCTURE! The data in the context + * structure should all be considered private to the library. It remains here + * only for backward compatibility. + * + * See the comments herein for use of the setter and getter functions which + * should now be used for manipulating these values. New features, functions, + * etc., are not added here but rather in _internal where they are not + * directly visible to applications. This makes it much easier to maintain + * ABI compatibility. + */ +struct _SMBCCTX +{ + /** + * debug level + * + * DEPRECATED: + * Use smbc_getDebug() and smbc_setDebug() + */ + int debug DEPRECATED_SMBC_INTERFACE; + + /** + * netbios name used for making connections + * + * DEPRECATED: + * Use smbc_getNetbiosName() and smbc_setNetbiosName() + */ + char * netbios_name DEPRECATED_SMBC_INTERFACE; + + /** + * workgroup name used for making connections + * + * DEPRECATED: + * Use smbc_getWorkgroup() and smbc_setWorkgroup() + */ + char * workgroup DEPRECATED_SMBC_INTERFACE; + + /** + * username used for making connections + * + * DEPRECATED: + * Use smbc_getUser() and smbc_setUser() + */ + char * user DEPRECATED_SMBC_INTERFACE; + + /** + * timeout used for waiting on connections / response data (in + * milliseconds) + * + * DEPRECATED: + * Use smbc_getTimeout() and smbc_setTimeout() + */ + int timeout DEPRECATED_SMBC_INTERFACE; + + /** + * callable functions for files: + * For usage and return values see the SMBC_* functions + * + * DEPRECATED: + * + * Use smbc_getFunction*() and smbc_setFunction*(), e.g. + * smbc_getFunctionOpen(), smbc_setFunctionUnlink(), etc. + */ + smbc_open_fn open DEPRECATED_SMBC_INTERFACE; + smbc_creat_fn creat DEPRECATED_SMBC_INTERFACE; + smbc_read_fn read DEPRECATED_SMBC_INTERFACE; + smbc_write_fn write DEPRECATED_SMBC_INTERFACE; + smbc_unlink_fn unlink DEPRECATED_SMBC_INTERFACE; + smbc_rename_fn rename DEPRECATED_SMBC_INTERFACE; + smbc_lseek_fn lseek DEPRECATED_SMBC_INTERFACE; + smbc_stat_fn stat DEPRECATED_SMBC_INTERFACE; + smbc_fstat_fn fstat DEPRECATED_SMBC_INTERFACE; +#if 0 /* internal */ + smbc_ftruncate_fn ftruncate_fn; +#endif + smbc_close_fn close_fn DEPRECATED_SMBC_INTERFACE; + smbc_opendir_fn opendir DEPRECATED_SMBC_INTERFACE; + smbc_closedir_fn closedir DEPRECATED_SMBC_INTERFACE; + smbc_readdir_fn readdir DEPRECATED_SMBC_INTERFACE; + smbc_getdents_fn getdents DEPRECATED_SMBC_INTERFACE; + smbc_mkdir_fn mkdir DEPRECATED_SMBC_INTERFACE; + smbc_rmdir_fn rmdir DEPRECATED_SMBC_INTERFACE; + smbc_telldir_fn telldir DEPRECATED_SMBC_INTERFACE; + smbc_lseekdir_fn lseekdir DEPRECATED_SMBC_INTERFACE; + smbc_fstatdir_fn fstatdir DEPRECATED_SMBC_INTERFACE; + smbc_chmod_fn chmod DEPRECATED_SMBC_INTERFACE; + smbc_utimes_fn utimes DEPRECATED_SMBC_INTERFACE; + smbc_setxattr_fn setxattr DEPRECATED_SMBC_INTERFACE; + smbc_getxattr_fn getxattr DEPRECATED_SMBC_INTERFACE; + smbc_removexattr_fn removexattr DEPRECATED_SMBC_INTERFACE; + smbc_listxattr_fn listxattr DEPRECATED_SMBC_INTERFACE; + + /* Printing-related functions */ + smbc_print_file_fn print_file DEPRECATED_SMBC_INTERFACE; + smbc_open_print_job_fn open_print_job DEPRECATED_SMBC_INTERFACE; + smbc_list_print_jobs_fn list_print_jobs DEPRECATED_SMBC_INTERFACE; + smbc_unlink_print_job_fn unlink_print_job DEPRECATED_SMBC_INTERFACE; + + /* + ** Callbacks + * + * DEPRECATED: + * + * See the comment above each field, for the getter and setter + * functions that should now be used. + */ + struct _smbc_callbacks + { + /** + * authentication function callback: called upon auth requests + * + * DEPRECATED: + * Use smbc_getFunctionAuthData(), smbc_setFunctionAuthData() + */ + smbc_get_auth_data_fn auth_fn DEPRECATED_SMBC_INTERFACE; + + /** + * check if a server is still good + * + * DEPRECATED: + * Use smbc_getFunctionCheckServer(), + * smbc_setFunctionCheckServer() + */ + smbc_check_server_fn check_server_fn DEPRECATED_SMBC_INTERFACE; + + /** + * remove a server if unused + * + * DEPRECATED: + * Use smbc_getFunctionRemoveUnusedServer(), + * smbc_setFunctionCheckServer() + */ + smbc_remove_unused_server_fn remove_unused_server_fn DEPRECATED_SMBC_INTERFACE; + + /** Cache subsystem + * + * For an example cache system see + * samba/source/libsmb/libsmb_cache.c + * + * Cache subsystem * functions follow. + */ + + /** + * server cache addition + * + * DEPRECATED: + * Use smbc_getFunctionAddCachedServer(), + * smbc_setFunctionAddCachedServer() + */ + smbc_add_cached_srv_fn add_cached_srv_fn DEPRECATED_SMBC_INTERFACE; + + /** + * server cache lookup + * + * DEPRECATED: + * Use smbc_getFunctionGetCachedServer(), + * smbc_setFunctionGetCachedServer() + */ + smbc_get_cached_srv_fn get_cached_srv_fn DEPRECATED_SMBC_INTERFACE; + + /** + * server cache removal + * + * DEPRECATED: + * Use smbc_getFunctionRemoveCachedServer(), + * smbc_setFunctionRemoveCachedServer() + */ + smbc_remove_cached_srv_fn remove_cached_srv_fn DEPRECATED_SMBC_INTERFACE; + + /** + * server cache purging, try to remove all cached servers + * (disconnect) + * + * DEPRECATED: + * Use smbc_getFunctionPurgeCachedServers(), + * smbc_setFunctionPurgeCachedServers() + */ + smbc_purge_cached_fn purge_cached_fn DEPRECATED_SMBC_INTERFACE; + } callbacks; + + /** + * Space where the private data of the server cache used to be + * + * DEPRECATED: + * Use smbc_getServerCacheData(), smbc_setServerCacheData() + */ + void * reserved DEPRECATED_SMBC_INTERFACE; + + /* + * Very old configuration options. + * + * DEPRECATED: + * Use one of the following functions instead: + * smbc_setOptionUseKerberos() + * smbc_getOptionUseKerberos() + * smbc_setOptionFallbackAfterKerberos() + * smbc_getOptionFallbackAfterKerberos() + * smbc_setOptionNoAutoAnonymousLogin() + * smbc_getOptionNoAutoAnonymousLogin() + */ + int flags DEPRECATED_SMBC_INTERFACE; + + /** + * user options selections that apply to this session + * + * NEW OPTIONS ARE NOT ADDED HERE! + * + * DEPRECATED: + * To set and retrieve options, use the smbc_setOption*() and + * smbc_getOption*() functions. + */ + struct _smbc_options { + int browse_max_lmb_count DEPRECATED_SMBC_INTERFACE; + int urlencode_readdir_entries DEPRECATED_SMBC_INTERFACE; + int one_share_per_server DEPRECATED_SMBC_INTERFACE; + } options DEPRECATED_SMBC_INTERFACE; + + /** INTERNAL DATA + * do _NOT_ touch this from your program ! + */ + struct SMBC_internal_data * internal; +}; + #endif /* SMBCLIENT_H_INCLUDED */ diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 6537d5a7fb..b89b0fea3a 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -135,9 +135,9 @@ struct handle_list { /* Domain controller authentication protocol info */ struct dcinfo { uint32 sequence; /* "timestamp" from client. */ - DOM_CHAL seed_chal; - DOM_CHAL clnt_chal; /* Client credential */ - DOM_CHAL srv_chal; /* Server credential */ + struct netr_Credential seed_chal; + struct netr_Credential clnt_chal; /* Client credential */ + struct netr_Credential srv_chal; /* Server credential */ unsigned char sess_key[16]; /* Session key - 8 bytes followed by 8 zero bytes */ unsigned char mach_pw[16]; /* md4(machine password) */ diff --git a/source3/include/reg_objects.h b/source3/include/reg_objects.h index 3df701f61c..1d0d0d4996 100644 --- a/source3/include/reg_objects.h +++ b/source3/include/reg_objects.h @@ -105,9 +105,16 @@ typedef struct { #define KEY_CURRENT_VERSION "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion" #define KEY_PERFLIB "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib" #define KEY_PERFLIB_009 "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009" +#define KEY_GROUP_POLICY "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Group Policy" +#define KEY_WINLOGON "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon" #define KEY_SMBCONF "HKLM\\SOFTWARE\\Samba\\smbconf" +#define KEY_SAMBA_GROUP_POLICY "HKLM\\SOFTWARE\\Samba\\Group Policy" #define KEY_TREE_ROOT "" +#define KEY_GP_MACHINE_POLICY "HKLM\\Software\\Policies" +#define KEY_GP_MACHINE_WIN_POLICY "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies" +#define KEY_GP_USER_POLICY "HKCU\\Software\\Policies" +#define KEY_GP_USER_WIN_POLICY "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies" /* * Registry key types * Most keys are going to be GENERIC -- may need a better name? diff --git a/source3/include/rpc_brs.h b/source3/include/rpc_brs.h deleted file mode 100644 index 62ee86050f..0000000000 --- a/source3/include/rpc_brs.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1999 - Copyright (C) Luke Kenneth Casson Leighton 1996-1999 - - 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 _RPC_BRS_H /* _RPC_BRS_H */ -#define _RPC_BRS_H - - -/* brssvc pipe */ -#define BRS_QUERY_INFO 0x02 - - -/* BRS_Q_QUERY_INFO - probably a capabilities request */ -typedef struct q_brs_query_info_info -{ - uint32 ptr_srv_name; /* pointer (to server name?) */ - UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */ - - uint16 switch_value1; /* info level 100 (0x64) */ - /* align */ - uint16 switch_value2; /* info level 100 (0x64) */ - - uint32 ptr; - uint32 pad1; - uint32 pad2; - -} BRS_Q_QUERY_INFO; - - -/* BRS_INFO_100 - level 100 info */ -typedef struct brs_info_100_info -{ - uint32 pad1; - uint32 ptr2; - uint32 pad2; - uint32 pad3; - -} BRS_INFO_100; - - -/* BRS_R_QUERY_INFO - probably a capabilities request */ -typedef struct r_brs_query_info_info -{ - uint16 switch_value1; /* 100 (0x64) - switch value */ - /* align */ - uint16 switch_value2; /* info level 100 (0x64) */ - - /* for now, only level 100 is supported. this should be an enum container */ - uint32 ptr_1; /* pointer 1 */ - - union - { - BRS_INFO_100 *brs100; /* browser info level 100 */ - void *id; - - } info; - - NTSTATUS status; /* return status */ - -} BRS_R_QUERY_INFO; - -#endif /* _RPC_BRS_H */ - diff --git a/source3/include/rpc_client.h b/source3/include/rpc_client.h index c560fd0909..e1ebb2509d 100644 --- a/source3/include/rpc_client.h +++ b/source3/include/rpc_client.h @@ -34,6 +34,7 @@ #include "librpc/gen_ndr/cli_samr.h" #include "librpc/gen_ndr/cli_netlogon.h" #include "librpc/gen_ndr/cli_dssetup.h" +#include "librpc/gen_ndr/cli_ntsvcs.h" /* macro to expand cookie-cutter code in cli_xxx() using rpc_api_pipe_req() */ diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index 724a980b45..b4021afd0a 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -23,547 +23,37 @@ #ifndef _RPC_LSA_H /* _RPC_LSA_H */ #define _RPC_LSA_H -/* Opcodes available on PIPE_LSARPC */ - -#define LSA_CLOSE 0x00 -#define LSA_DELETE 0x01 -#define LSA_ENUM_PRIVS 0x02 -#define LSA_QUERYSECOBJ 0x03 -#define LSA_SETSECOBJ 0x04 -#define LSA_CHANGEPASSWORD 0x05 -#define LSA_OPENPOLICY 0x06 -#define LSA_QUERYINFOPOLICY 0x07 -#define LSA_SETINFOPOLICY 0x08 -#define LSA_CLEARAUDITLOG 0x09 -#define LSA_CREATEACCOUNT 0x0a -#define LSA_ENUM_ACCOUNTS 0x0b -#define LSA_CREATETRUSTDOM 0x0c /* TODO: implement this one -- jerry */ -#define LSA_ENUMTRUSTDOM 0x0d -#define LSA_LOOKUPNAMES 0x0e -#define LSA_LOOKUPSIDS 0x0f -#define LSA_CREATESECRET 0x10 /* TODO: implement this one -- jerry */ -#define LSA_OPENACCOUNT 0x11 -#define LSA_ENUMPRIVSACCOUNT 0x12 -#define LSA_ADDPRIVS 0x13 -#define LSA_REMOVEPRIVS 0x14 -#define LSA_GETQUOTAS 0x15 -#define LSA_SETQUOTAS 0x16 -#define LSA_GETSYSTEMACCOUNT 0x17 -#define LSA_SETSYSTEMACCOUNT 0x18 -#define LSA_OPENTRUSTDOM 0x19 -#define LSA_QUERYTRUSTDOMINFO 0x1a -#define LSA_SETINFOTRUSTDOM 0x1b -#define LSA_OPENSECRET 0x1c /* TODO: implement this one -- jerry */ -#define LSA_SETSECRET 0x1d /* TODO: implement this one -- jerry */ -#define LSA_QUERYSECRET 0x1e -#define LSA_LOOKUPPRIVVALUE 0x1f -#define LSA_LOOKUPPRIVNAME 0x20 -#define LSA_PRIV_GET_DISPNAME 0x21 -#define LSA_DELETEOBJECT 0x22 /* TODO: implement this one -- jerry */ -#define LSA_ENUMACCTWITHRIGHT 0x23 /* TODO: implement this one -- jerry */ -#define LSA_ENUMACCTRIGHTS 0x24 -#define LSA_ADDACCTRIGHTS 0x25 -#define LSA_REMOVEACCTRIGHTS 0x26 -#define LSA_QUERYTRUSTDOMINFOBYSID 0x27 -#define LSA_SETTRUSTDOMINFO 0x28 -#define LSA_DELETETRUSTDOM 0x29 -#define LSA_STOREPRIVDATA 0x2a -#define LSA_RETRPRIVDATA 0x2b -#define LSA_OPENPOLICY2 0x2c -#define LSA_UNK_GET_CONNUSER 0x2d /* LsaGetConnectedCredentials ? */ -#define LSA_QUERYINFO2 0x2e -#define LSA_QUERYTRUSTDOMINFOBYNAME 0x30 -#define LSA_QUERYDOMINFOPOL 0x35 -#define LSA_OPENTRUSTDOMBYNAME 0x37 - -#define LSA_LOOKUPSIDS2 0x39 -#define LSA_LOOKUPNAMES2 0x3a -#define LSA_LOOKUPNAMES3 0x44 -#define LSA_LOOKUPSIDS3 0x4c -#define LSA_LOOKUPNAMES4 0x4d - -/* XXXX these are here to get a compile! */ -#define LSA_LOOKUPRIDS 0xFD - -#define LSA_AUDIT_NUM_CATEGORIES_NT4 7 -#define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9 -#define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4 - -#define POLICY_VIEW_LOCAL_INFORMATION 0x00000001 -#define POLICY_VIEW_AUDIT_INFORMATION 0x00000002 -#define POLICY_GET_PRIVATE_INFORMATION 0x00000004 -#define POLICY_TRUST_ADMIN 0x00000008 -#define POLICY_CREATE_ACCOUNT 0x00000010 -#define POLICY_CREATE_SECRET 0x00000020 -#define POLICY_CREATE_PRIVILEGE 0x00000040 -#define POLICY_SET_DEFAULT_QUOTA_LIMITS 0x00000080 -#define POLICY_SET_AUDIT_REQUIREMENTS 0x00000100 -#define POLICY_AUDIT_LOG_ADMIN 0x00000200 -#define POLICY_SERVER_ADMIN 0x00000400 -#define POLICY_LOOKUP_NAMES 0x00000800 - -#define POLICY_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED_ACCESS |\ - POLICY_VIEW_LOCAL_INFORMATION |\ - POLICY_VIEW_AUDIT_INFORMATION |\ - POLICY_GET_PRIVATE_INFORMATION |\ - POLICY_TRUST_ADMIN |\ - POLICY_CREATE_ACCOUNT |\ - POLICY_CREATE_SECRET |\ - POLICY_CREATE_PRIVILEGE |\ - POLICY_SET_DEFAULT_QUOTA_LIMITS |\ - POLICY_SET_AUDIT_REQUIREMENTS |\ - POLICY_AUDIT_LOG_ADMIN |\ - POLICY_SERVER_ADMIN |\ - POLICY_LOOKUP_NAMES ) - - -#define POLICY_READ ( STANDARD_RIGHTS_READ_ACCESS |\ - POLICY_VIEW_AUDIT_INFORMATION |\ - POLICY_GET_PRIVATE_INFORMATION) - -#define POLICY_WRITE ( STD_RIGHT_READ_CONTROL_ACCESS |\ - POLICY_TRUST_ADMIN |\ - POLICY_CREATE_ACCOUNT |\ - POLICY_CREATE_SECRET |\ - POLICY_CREATE_PRIVILEGE |\ - POLICY_SET_DEFAULT_QUOTA_LIMITS |\ - POLICY_SET_AUDIT_REQUIREMENTS |\ - POLICY_AUDIT_LOG_ADMIN |\ - POLICY_SERVER_ADMIN) - -#define POLICY_EXECUTE ( STANDARD_RIGHTS_EXECUTE_ACCESS |\ - POLICY_VIEW_LOCAL_INFORMATION |\ - POLICY_LOOKUP_NAMES ) - -/*******************************************************/ - -/*******************************************************/ - -#define MAX_REF_DOMAINS 32 - -/* DOM_TRUST_HDR */ -typedef struct dom_trust_hdr -{ - UNIHDR hdr_dom_name; /* referenced domain unicode string headers */ - uint32 ptr_dom_sid; - -} DOM_TRUST_HDR; - -/* DOM_TRUST_INFO */ -typedef struct dom_trust_info -{ - UNISTR2 uni_dom_name; /* domain name unicode string */ - DOM_SID2 ref_dom ; /* referenced domain SID */ - -} DOM_TRUST_INFO; - -/* DOM_R_REF */ -typedef struct dom_ref_info -{ - uint32 num_ref_doms_1; /* num referenced domains */ - uint32 ptr_ref_dom; /* pointer to referenced domains */ - uint32 max_entries; /* 32 - max number of entries */ - uint32 num_ref_doms_2; /* num referenced domains */ - - DOM_TRUST_HDR hdr_ref_dom[MAX_REF_DOMAINS]; /* referenced domains */ - DOM_TRUST_INFO ref_dom [MAX_REF_DOMAINS]; /* referenced domains */ - -} DOM_R_REF; - -/* the domain_idx points to a SID associated with the name */ - -/* LSA_TRANS_NAME - translated name */ -typedef struct lsa_trans_name_info -{ - uint16 sid_name_use; /* value is 5 for a well-known group; 2 for a domain group; 1 for a user... */ - UNIHDR hdr_name; - uint32 domain_idx; /* index into DOM_R_REF array of SIDs */ - -} LSA_TRANS_NAME; - -/* LSA_TRANS_NAME2 - translated name */ -typedef struct lsa_trans_name_info2 -{ - uint16 sid_name_use; /* value is 5 for a well-known group; 2 for a domain group; 1 for a user... */ - UNIHDR hdr_name; - uint32 domain_idx; /* index into DOM_R_REF array of SIDs */ - uint32 unknown; - -} LSA_TRANS_NAME2; - -/* This number is based on Win2k and later maximum response allowed */ -#define MAX_LOOKUP_SIDS 20480 /* 0x5000 */ - -/* LSA_TRANS_NAME_ENUM - LSA Translated Name Enumeration container */ -typedef struct lsa_trans_name_enum_info -{ - uint32 num_entries; - uint32 ptr_trans_names; - uint32 num_entries2; - - LSA_TRANS_NAME *name; /* translated names */ - UNISTR2 *uni_name; - -} LSA_TRANS_NAME_ENUM; - -/* LSA_TRANS_NAME_ENUM2 - LSA Translated Name Enumeration container 2 */ -typedef struct lsa_trans_name_enum_info2 -{ - uint32 num_entries; - uint32 ptr_trans_names; - uint32 num_entries2; - - LSA_TRANS_NAME2 *name; /* translated names */ - UNISTR2 *uni_name; - -} LSA_TRANS_NAME_ENUM2; - -/* LSA_SID_ENUM - LSA SID enumeration container */ -typedef struct lsa_sid_enum_info -{ - uint32 num_entries; - uint32 ptr_sid_enum; - uint32 num_entries2; - - uint32 *ptr_sid; /* domain SID pointers to be looked up. */ - DOM_SID2 *sid; /* domain SIDs to be looked up. */ - -} LSA_SID_ENUM; - -/* LSA_Q_LOOKUP_SIDS - LSA Lookup SIDs */ -typedef struct lsa_q_lookup_sids -{ - POLICY_HND pol; /* policy handle */ - LSA_SID_ENUM sids; - LSA_TRANS_NAME_ENUM names; - uint16 level; - uint32 mapped_count; - -} LSA_Q_LOOKUP_SIDS; - -/* LSA_R_LOOKUP_SIDS - response to LSA Lookup SIDs */ -typedef struct lsa_r_lookup_sids -{ - uint32 ptr_dom_ref; - DOM_R_REF *dom_ref; /* domain reference info */ - - LSA_TRANS_NAME_ENUM names; - uint32 mapped_count; - - NTSTATUS status; /* return code */ - -} LSA_R_LOOKUP_SIDS; - -/* LSA_Q_LOOKUP_SIDS2 - LSA Lookup SIDs 2*/ -typedef struct lsa_q_lookup_sids2 -{ - POLICY_HND pol; /* policy handle */ - LSA_SID_ENUM sids; - LSA_TRANS_NAME_ENUM2 names; - uint16 level; - uint32 mapped_count; - uint32 unknown1; - uint32 unknown2; - -} LSA_Q_LOOKUP_SIDS2; - -/* LSA_R_LOOKUP_SIDS2 - response to LSA Lookup SIDs 2*/ -typedef struct lsa_r_lookup_sids2 -{ - uint32 ptr_dom_ref; - DOM_R_REF *dom_ref; /* domain reference info */ - - LSA_TRANS_NAME_ENUM2 names; - uint32 mapped_count; - - NTSTATUS status; /* return code */ - -} LSA_R_LOOKUP_SIDS2; - -/* LSA_Q_LOOKUP_SIDS3 - LSA Lookup SIDs 3 */ -typedef struct lsa_q_lookup_sids3 -{ - LSA_SID_ENUM sids; - LSA_TRANS_NAME_ENUM2 names; - uint16 level; - uint32 mapped_count; - uint32 unknown1; - uint32 unknown2; - -} LSA_Q_LOOKUP_SIDS3; - -/* LSA_R_LOOKUP_SIDS3 - response to LSA Lookup SIDs 3 */ -typedef struct lsa_r_lookup_sids3 -{ - uint32 ptr_dom_ref; - DOM_R_REF *dom_ref; /* domain reference info */ - - LSA_TRANS_NAME_ENUM2 names; - uint32 mapped_count; - - NTSTATUS status; /* return code */ - -} LSA_R_LOOKUP_SIDS3; - -/* LSA_Q_LOOKUP_NAMES - LSA Lookup NAMEs */ -typedef struct lsa_q_lookup_names -{ - POLICY_HND pol; /* policy handle */ - uint32 num_entries; - uint32 num_entries2; - UNIHDR *hdr_name; /* name buffer pointers */ - UNISTR2 *uni_name; /* names to be looked up */ - - uint32 num_trans_entries; - uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */ - uint16 lookup_level; - uint32 mapped_count; - -} LSA_Q_LOOKUP_NAMES; - -/* LSA_R_LOOKUP_NAMES - response to LSA Lookup NAMEs by name */ -typedef struct lsa_r_lookup_names -{ - uint32 ptr_dom_ref; - DOM_R_REF *dom_ref; /* domain reference info */ - - uint32 num_entries; - uint32 ptr_entries; - uint32 num_entries2; - DOM_RID *dom_rid; /* domain RIDs being looked up */ - - uint32 mapped_count; - - NTSTATUS status; /* return code */ -} LSA_R_LOOKUP_NAMES; - -/* LSA_Q_LOOKUP_NAMES2 - LSA Lookup NAMEs 2*/ -typedef struct lsa_q_lookup_names2 -{ - POLICY_HND pol; /* policy handle */ - uint32 num_entries; - uint32 num_entries2; - UNIHDR *hdr_name; /* name buffer pointers */ - UNISTR2 *uni_name; /* names to be looked up */ - - uint32 num_trans_entries; - uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */ - uint16 lookup_level; - uint32 mapped_count; - uint32 unknown1; - uint32 unknown2; - -} LSA_Q_LOOKUP_NAMES2; - -/* LSA_R_LOOKUP_NAMES2 - response to LSA Lookup NAMEs by name 2 */ -typedef struct lsa_r_lookup_names2 -{ - uint32 ptr_dom_ref; - DOM_R_REF *dom_ref; /* domain reference info */ - - uint32 num_entries; - uint32 ptr_entries; - uint32 num_entries2; - DOM_RID2 *dom_rid; /* domain RIDs being looked up */ - - uint32 mapped_count; - - NTSTATUS status; /* return code */ -} LSA_R_LOOKUP_NAMES2; - -/* LSA_Q_LOOKUP_NAMES3 - LSA Lookup NAMEs 3 */ -typedef struct lsa_q_lookup_names3 -{ - POLICY_HND pol; /* policy handle */ - uint32 num_entries; - uint32 num_entries2; - UNIHDR *hdr_name; /* name buffer pointers */ - UNISTR2 *uni_name; /* names to be looked up */ - - uint32 num_trans_entries; - uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */ - uint16 lookup_level; - uint32 mapped_count; - uint32 unknown1; - uint32 unknown2; - -} LSA_Q_LOOKUP_NAMES3; - -/* Sid type used in lookupnames3 and lookupnames4. */ -typedef struct lsa_translatedsid3 { - uint8 sid_type; - DOM_SID2 *sid2; - uint32 sid_idx; - uint32 unknown; -} LSA_TRANSLATED_SID3; - -/* LSA_R_LOOKUP_NAMES3 - response to LSA Lookup NAMEs by name 3 */ -typedef struct lsa_r_lookup_names3 -{ - uint32 ptr_dom_ref; - DOM_R_REF *dom_ref; /* domain reference info */ - - uint32 num_entries; - uint32 ptr_entries; - uint32 num_entries2; - LSA_TRANSLATED_SID3 *trans_sids; - - uint32 mapped_count; - - NTSTATUS status; /* return code */ -} LSA_R_LOOKUP_NAMES3; - -/* LSA_Q_LOOKUP_NAMES4 - LSA Lookup NAMEs 4 */ -typedef struct lsa_q_lookup_names4 -{ - uint32 num_entries; - uint32 num_entries2; - UNIHDR *hdr_name; /* name buffer pointers */ - UNISTR2 *uni_name; /* names to be looked up */ - - uint32 num_trans_entries; - uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */ - uint16 lookup_level; - uint32 mapped_count; - uint32 unknown1; - uint32 unknown2; - -} LSA_Q_LOOKUP_NAMES4; - -/* LSA_R_LOOKUP_NAMES3 - response to LSA Lookup NAMEs by name 4 */ -typedef struct lsa_r_lookup_names4 -{ - uint32 ptr_dom_ref; - DOM_R_REF *dom_ref; /* domain reference info */ - - uint32 num_entries; - uint32 ptr_entries; - uint32 num_entries2; - LSA_TRANSLATED_SID3 *trans_sids; - - uint32 mapped_count; - - NTSTATUS status; /* return code */ -} LSA_R_LOOKUP_NAMES4; - -/* LSA_Q_ENUM_ACCT_RIGHTS - LSA enum account rights */ -typedef struct -{ - POLICY_HND pol; /* policy handle */ - DOM_SID2 sid; -} LSA_Q_ENUM_ACCT_RIGHTS; - -/* LSA_R_ENUM_ACCT_RIGHTS - LSA enum account rights */ -typedef struct -{ - uint32 count; - UNISTR4_ARRAY *rights; - NTSTATUS status; -} LSA_R_ENUM_ACCT_RIGHTS; - - -/* LSA_Q_ADD_ACCT_RIGHTS - LSA add account rights */ -typedef struct -{ - POLICY_HND pol; /* policy handle */ - DOM_SID2 sid; - uint32 count; - UNISTR4_ARRAY *rights; -} LSA_Q_ADD_ACCT_RIGHTS; - -/* LSA_R_ADD_ACCT_RIGHTS - LSA add account rights */ -typedef struct -{ - NTSTATUS status; -} LSA_R_ADD_ACCT_RIGHTS; - - -/* LSA_Q_REMOVE_ACCT_RIGHTS - LSA remove account rights */ -typedef struct -{ - POLICY_HND pol; /* policy handle */ - DOM_SID2 sid; - uint32 removeall; - uint32 count; - UNISTR4_ARRAY *rights; -} LSA_Q_REMOVE_ACCT_RIGHTS; - -/* LSA_R_REMOVE_ACCT_RIGHTS - LSA remove account rights */ -typedef struct -{ - NTSTATUS status; -} LSA_R_REMOVE_ACCT_RIGHTS; - - -/* LSA_Q_ENUM_ACCOUNTS */ -typedef struct lsa_q_enum_accounts -{ - POLICY_HND pol; /* policy handle */ - uint32 enum_context; - uint32 pref_max_length; -} LSA_Q_ENUM_ACCOUNTS; - -/* LSA_R_ENUM_ACCOUNTS */ -typedef struct lsa_r_enum_accounts -{ - uint32 enum_context; - LSA_SID_ENUM sids; - NTSTATUS status; -} LSA_R_ENUM_ACCOUNTS; - -typedef struct lsa_q_enumprivsaccount -{ - POLICY_HND pol; /* policy handle */ -} LSA_Q_ENUMPRIVSACCOUNT; - -typedef struct lsa_r_enumprivsaccount -{ - uint32 ptr; - uint32 count; - PRIVILEGE_SET set; - NTSTATUS status; -} LSA_R_ENUMPRIVSACCOUNT; - -typedef struct { - UNIHDR hdr; - UNISTR2 unistring; -} LSA_STRING; - -typedef struct { - POLICY_HND pol; /* policy handle */ - LSA_STRING privname; -} LSA_Q_LOOKUP_PRIV_VALUE; - -typedef struct { - LUID luid; - NTSTATUS status; -} LSA_R_LOOKUP_PRIV_VALUE; - -typedef struct lsa_q_addprivs -{ - POLICY_HND pol; /* policy handle */ - uint32 count; - PRIVILEGE_SET set; -} LSA_Q_ADDPRIVS; - -typedef struct lsa_r_addprivs -{ - NTSTATUS status; -} LSA_R_ADDPRIVS; - - -typedef struct lsa_q_removeprivs -{ - POLICY_HND pol; /* policy handle */ - uint32 allrights; - uint32 ptr; - uint32 count; - PRIVILEGE_SET set; -} LSA_Q_REMOVEPRIVS; - -typedef struct lsa_r_removeprivs -{ - NTSTATUS status; -} LSA_R_REMOVEPRIVS; +#define LSA_POLICY_ALL_ACCESS ( STANDARD_RIGHTS_REQUIRED_ACCESS |\ + LSA_POLICY_VIEW_LOCAL_INFORMATION |\ + LSA_POLICY_VIEW_AUDIT_INFORMATION |\ + LSA_POLICY_GET_PRIVATE_INFORMATION |\ + LSA_POLICY_TRUST_ADMIN |\ + LSA_POLICY_CREATE_ACCOUNT |\ + LSA_POLICY_CREATE_SECRET |\ + LSA_POLICY_CREATE_PRIVILEGE |\ + LSA_POLICY_SET_DEFAULT_QUOTA_LIMITS |\ + LSA_POLICY_SET_AUDIT_REQUIREMENTS |\ + LSA_POLICY_AUDIT_LOG_ADMIN |\ + LSA_POLICY_SERVER_ADMIN |\ + LSA_POLICY_LOOKUP_NAMES ) + + +#define LSA_POLICY_READ ( STANDARD_RIGHTS_READ_ACCESS |\ + LSA_POLICY_VIEW_AUDIT_INFORMATION |\ + LSA_POLICY_GET_PRIVATE_INFORMATION) + +#define LSA_POLICY_WRITE ( STD_RIGHT_READ_CONTROL_ACCESS |\ + LSA_POLICY_TRUST_ADMIN |\ + LSA_POLICY_CREATE_ACCOUNT |\ + LSA_POLICY_CREATE_SECRET |\ + LSA_POLICY_CREATE_PRIVILEGE |\ + LSA_POLICY_SET_DEFAULT_QUOTA_LIMITS |\ + LSA_POLICY_SET_AUDIT_REQUIREMENTS |\ + LSA_POLICY_AUDIT_LOG_ADMIN |\ + LSA_POLICY_SERVER_ADMIN) + +#define LSA_POLICY_EXECUTE ( STANDARD_RIGHTS_EXECUTE_ACCESS |\ + LSA_POLICY_VIEW_LOCAL_INFORMATION |\ + LSA_POLICY_LOOKUP_NAMES ) #endif /* _RPC_LSA_H */ diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h index f2802b8e72..cd88ffef59 100644 --- a/source3/include/rpc_netlogon.h +++ b/source3/include/rpc_netlogon.h @@ -23,59 +23,6 @@ #ifndef _RPC_NETLOGON_H /* _RPC_NETLOGON_H */ #define _RPC_NETLOGON_H - -/* NETLOGON pipe */ -#define NET_SAMLOGON 0x02 -#define NET_SAMLOGOFF 0x03 -#define NET_REQCHAL 0x04 -#define NET_AUTH 0x05 -#define NET_SRVPWSET 0x06 -#define NET_SAM_DELTAS 0x07 -#define NET_GETDCNAME 0x0b -#define NET_LOGON_CTRL 0x0c -#define NET_GETANYDCNAME 0x0d -#define NET_AUTH2 0x0f -#define NET_LOGON_CTRL2 0x0e -#define NET_SAM_SYNC 0x10 -#define NET_TRUST_DOM_LIST 0x13 -#define NET_DSR_GETDCNAME 0x14 -#define NET_AUTH3 0x1a -#define NET_DSR_GETDCNAMEEX 0x1b -#define NET_DSR_GETSITENAME 0x1c -#define NET_DSR_GETDCNAMEEX2 0x22 -#define NET_SAMLOGON_EX 0x27 - -/* Returned delta types */ -#define SAM_DELTA_DOMAIN_INFO 0x01 -#define SAM_DELTA_GROUP_INFO 0x02 -#define SAM_DELTA_RENAME_GROUP 0x04 -#define SAM_DELTA_ACCOUNT_INFO 0x05 -#define SAM_DELTA_RENAME_USER 0x07 -#define SAM_DELTA_GROUP_MEM 0x08 -#define SAM_DELTA_ALIAS_INFO 0x09 -#define SAM_DELTA_RENAME_ALIAS 0x0b -#define SAM_DELTA_ALIAS_MEM 0x0c -#define SAM_DELTA_POLICY_INFO 0x0d -#define SAM_DELTA_TRUST_DOMS 0x0e -#define SAM_DELTA_PRIVS_INFO 0x10 /* DT_DELTA_ACCOUNTS */ -#define SAM_DELTA_SECRET_INFO 0x12 -#define SAM_DELTA_DELETE_GROUP 0x14 -#define SAM_DELTA_DELETE_USER 0x15 -#define SAM_DELTA_MODIFIED_COUNT 0x16 - -/* SAM database types */ -#define SAM_DATABASE_DOMAIN 0x00 /* Domain users and groups */ -#define SAM_DATABASE_BUILTIN 0x01 /* BUILTIN users and groups */ -#define SAM_DATABASE_PRIVS 0x02 /* Privileges */ - -/* flags use when sending a NETLOGON_CONTROL request */ - -#define NETLOGON_CONTROL_SYNC 0x2 -#define NETLOGON_CONTROL_REDISCOVER 0x5 -#define NETLOGON_CONTROL_TC_QUERY 0x6 -#define NETLOGON_CONTROL_TRANSPORT_NOTIFY 0x7 -#define NETLOGON_CONTROL_SET_DBFLAG 0xfffe - /* Some flag values reverse engineered from NLTEST.EXE */ /* used in the NETLOGON_CONTROL[2] reply */ @@ -104,515 +51,9 @@ #define MSV1_0_RETURN_PROFILE_PATH 0x00000200 #endif -#if 0 -/* I think this is correct - it's what gets parsed on the wire. JRA. */ -/* NET_USER_INFO_2 */ -typedef struct net_user_info_2 { - uint32 ptr_user_info; - - NTTIME logon_time; /* logon time */ - NTTIME logoff_time; /* logoff time */ - NTTIME kickoff_time; /* kickoff time */ - NTTIME pass_last_set_time; /* password last set time */ - NTTIME pass_can_change_time; /* password can change time */ - NTTIME pass_must_change_time; /* password must change time */ - - UNIHDR hdr_user_name; /* username unicode string header */ - UNIHDR hdr_full_name; /* user's full name unicode string header */ - UNIHDR hdr_logon_script; /* logon script unicode string header */ - UNIHDR hdr_profile_path; /* profile path unicode string header */ - UNIHDR hdr_home_dir; /* home directory unicode string header */ - UNIHDR hdr_dir_drive; /* home directory drive unicode string header */ - - uint16 logon_count; /* logon count */ - uint16 bad_pw_count; /* bad password count */ - - uint32 user_id; /* User ID */ - uint32 group_id; /* Group ID */ - uint32 num_groups; /* num groups */ - uint32 buffer_groups; /* undocumented buffer pointer to groups. */ - uint32 user_flgs; /* user flags */ - - uint8 user_sess_key[16]; /* unused user session key */ - - UNIHDR hdr_logon_srv; /* logon server unicode string header */ - UNIHDR hdr_logon_dom; /* logon domain unicode string header */ - - uint32 buffer_dom_id; /* undocumented logon domain id pointer */ - uint8 padding[40]; /* unused padding bytes. expansion room */ - - UNISTR2 uni_user_name; /* username unicode string */ - UNISTR2 uni_full_name; /* user's full name unicode string */ - UNISTR2 uni_logon_script; /* logon script unicode string */ - UNISTR2 uni_profile_path; /* profile path unicode string */ - UNISTR2 uni_home_dir; /* home directory unicode string */ - UNISTR2 uni_dir_drive; /* home directory drive unicode string */ - - uint32 num_groups2; /* num groups */ - DOM_GID *gids; /* group info */ - - UNISTR2 uni_logon_srv; /* logon server unicode string */ - UNISTR2 uni_logon_dom; /* logon domain unicode string */ - - DOM_SID2 dom_sid; /* domain SID */ - - uint32 num_other_groups; /* other groups */ - DOM_GID *other_gids; /* group info */ - DOM_SID2 *other_sids; /* undocumented - domain SIDs */ - -} NET_USER_INFO_2; -#endif - -/* NET_USER_INFO_2 */ -typedef struct net_user_info_2 { - uint32 ptr_user_info; - - NTTIME logon_time; /* logon time */ - NTTIME logoff_time; /* logoff time */ - NTTIME kickoff_time; /* kickoff time */ - NTTIME pass_last_set_time; /* password last set time */ - NTTIME pass_can_change_time; /* password can change time */ - NTTIME pass_must_change_time; /* password must change time */ - - UNIHDR hdr_user_name; /* username unicode string header */ - UNIHDR hdr_full_name; /* user's full name unicode string header */ - UNIHDR hdr_logon_script; /* logon script unicode string header */ - UNIHDR hdr_profile_path; /* profile path unicode string header */ - UNIHDR hdr_home_dir; /* home directory unicode string header */ - UNIHDR hdr_dir_drive; /* home directory drive unicode string header */ - - uint16 logon_count; /* logon count */ - uint16 bad_pw_count; /* bad password count */ - - uint32 user_rid; /* User RID */ - uint32 group_rid; /* Group RID */ - - uint32 num_groups; /* num groups */ - uint32 buffer_groups; /* undocumented buffer pointer to groups. */ - uint32 user_flgs; /* user flags */ - - uint8 user_sess_key[16]; /* user session key */ - - UNIHDR hdr_logon_srv; /* logon server unicode string header */ - UNIHDR hdr_logon_dom; /* logon domain unicode string header */ - - uint32 buffer_dom_id; /* undocumented logon domain id pointer */ - uint8 lm_sess_key[8]; /* lm session key */ - uint32 acct_flags; /* account flags */ - uint32 unknown[7]; /* unknown */ - - UNISTR2 uni_user_name; /* username unicode string */ - UNISTR2 uni_full_name; /* user's full name unicode string */ - UNISTR2 uni_logon_script; /* logon script unicode string */ - UNISTR2 uni_profile_path; /* profile path unicode string */ - UNISTR2 uni_home_dir; /* home directory unicode string */ - UNISTR2 uni_dir_drive; /* home directory drive unicode string */ - - UNISTR2 uni_logon_srv; /* logon server unicode string */ - UNISTR2 uni_logon_dom; /* logon domain unicode string */ - - DOM_SID2 dom_sid; /* domain SID */ -} NET_USER_INFO_2; - -/* NET_USER_INFO_3 */ -typedef struct net_user_info_3 { - uint32 ptr_user_info; - - NTTIME logon_time; /* logon time */ - NTTIME logoff_time; /* logoff time */ - NTTIME kickoff_time; /* kickoff time */ - NTTIME pass_last_set_time; /* password last set time */ - NTTIME pass_can_change_time; /* password can change time */ - NTTIME pass_must_change_time; /* password must change time */ - - UNIHDR hdr_user_name; /* username unicode string header */ - UNIHDR hdr_full_name; /* user's full name unicode string header */ - UNIHDR hdr_logon_script; /* logon script unicode string header */ - UNIHDR hdr_profile_path; /* profile path unicode string header */ - UNIHDR hdr_home_dir; /* home directory unicode string header */ - UNIHDR hdr_dir_drive; /* home directory drive unicode string header */ - - uint16 logon_count; /* logon count */ - uint16 bad_pw_count; /* bad password count */ - - uint32 user_rid; /* User RID */ - uint32 group_rid; /* Group RID */ - - uint32 num_groups; /* num groups */ - uint32 buffer_groups; /* undocumented buffer pointer to groups. */ - uint32 user_flgs; /* user flags */ - - uint8 user_sess_key[16]; /* user session key */ - - UNIHDR hdr_logon_srv; /* logon server unicode string header */ - UNIHDR hdr_logon_dom; /* logon domain unicode string header */ - - uint32 buffer_dom_id; /* undocumented logon domain id pointer */ - uint8 lm_sess_key[8]; /* lm session key */ - uint32 acct_flags; /* account flags */ - uint32 unknown[7]; /* unknown */ - - uint32 num_other_sids; /* number of foreign/trusted domain sids */ - uint32 buffer_other_sids; - - /* The next three uint32 are not really part of user_info_3 but here - * for parsing convenience. They are only valid in Kerberos PAC - * parsing - Guenther */ - uint32 ptr_res_group_dom_sid; - uint32 res_group_count; - uint32 ptr_res_groups; - - UNISTR2 uni_user_name; /* username unicode string */ - UNISTR2 uni_full_name; /* user's full name unicode string */ - UNISTR2 uni_logon_script; /* logon script unicode string */ - UNISTR2 uni_profile_path; /* profile path unicode string */ - UNISTR2 uni_home_dir; /* home directory unicode string */ - UNISTR2 uni_dir_drive; /* home directory drive unicode string */ - - uint32 num_groups2; /* num groups */ - DOM_GID *gids; /* group info */ - - UNISTR2 uni_logon_srv; /* logon server unicode string */ - UNISTR2 uni_logon_dom; /* logon domain unicode string */ - - DOM_SID2 dom_sid; /* domain SID */ - - DOM_SID2 *other_sids; /* foreign/trusted domain SIDs */ - uint32 *other_sids_attrib; -} NET_USER_INFO_3; - - -/* NETLOGON_INFO_1 - pdc status info, i presume */ -typedef struct netlogon_1_info { - uint32 flags; /* 0x0 - undocumented */ - uint32 pdc_status; /* 0x0 - undocumented */ -} NETLOGON_INFO_1; - -/* NETLOGON_INFO_2 - pdc status info, plus trusted domain info */ -typedef struct netlogon_2_info { - uint32 flags; /* 0x0 - undocumented */ - uint32 pdc_status; /* 0x0 - undocumented */ - uint32 ptr_trusted_dc_name; /* pointer to trusted domain controller name */ - uint32 tc_status; - UNISTR2 uni_trusted_dc_name; /* unicode string - trusted dc name */ -} NETLOGON_INFO_2; - -/* NETLOGON_INFO_3 - logon status info, i presume */ -typedef struct netlogon_3_info { - uint32 flags; /* 0x0 - undocumented */ - uint32 logon_attempts; /* number of logon attempts */ - uint32 reserved_1; /* 0x0 - undocumented */ - uint32 reserved_2; /* 0x0 - undocumented */ - uint32 reserved_3; /* 0x0 - undocumented */ - uint32 reserved_4; /* 0x0 - undocumented */ - uint32 reserved_5; /* 0x0 - undocumented */ -} NETLOGON_INFO_3; - -/******************************************************** - Logon Control Query - - This is generated by a nltest /bdc_query:DOMAIN - - query_level 0x1, function_code 0x1 - - ********************************************************/ - -/* NET_Q_LOGON_CTRL - LSA Netr Logon Control */ - -typedef struct net_q_logon_ctrl_info { - uint32 ptr; - UNISTR2 uni_server_name; - uint32 function_code; - uint32 query_level; -} NET_Q_LOGON_CTRL; - -/* NET_R_LOGON_CTRL - LSA Netr Logon Control */ - -typedef struct net_r_logon_ctrl_info { - uint32 switch_value; - uint32 ptr; - - union { - NETLOGON_INFO_1 info1; - } logon; - - NTSTATUS status; -} NET_R_LOGON_CTRL; - - -typedef struct ctrl_data_info_5 { - uint32 function_code; - - uint32 ptr_domain; - UNISTR2 domain; -} CTRL_DATA_INFO_5; - -typedef struct ctrl_data_info_6 { - uint32 function_code; - - uint32 ptr_domain; - UNISTR2 domain; -} CTRL_DATA_INFO_6; - - -/******************************************************** - Logon Control2 Query - - query_level 0x1 - pdc status - query_level 0x3 - number of logon attempts. - - ********************************************************/ - -/* NET_Q_LOGON_CTRL2 - LSA Netr Logon Control 2 */ -typedef struct net_q_logon_ctrl2_info { - uint32 ptr; /* undocumented buffer pointer */ - UNISTR2 uni_server_name; /* server name, starting with two '\'s */ - - uint32 function_code; - uint32 query_level; - union { - CTRL_DATA_INFO_5 info5; - CTRL_DATA_INFO_6 info6; - } info; -} NET_Q_LOGON_CTRL2; - -/******************************************************* - Logon Control Response - - switch_value is same as query_level in request - *******************************************************/ - -/* NET_R_LOGON_CTRL2 - response to LSA Logon Control2 */ -typedef struct net_r_logon_ctrl2_info { - uint32 switch_value; /* 0x1, 0x3 */ - uint32 ptr; - - union - { - NETLOGON_INFO_1 info1; - NETLOGON_INFO_2 info2; - NETLOGON_INFO_3 info3; - - } logon; - - NTSTATUS status; /* return code */ -} NET_R_LOGON_CTRL2; - -/* NEG_FLAGS */ -typedef struct neg_flags_info { - uint32 neg_flags; /* negotiated flags */ -} NEG_FLAGS; - - -/* NET_Q_REQ_CHAL */ -typedef struct net_q_req_chal_info { - uint32 undoc_buffer; /* undocumented buffer pointer */ - UNISTR2 uni_logon_srv; /* logon server unicode string */ - UNISTR2 uni_logon_clnt; /* logon client unicode string */ - DOM_CHAL clnt_chal; /* client challenge */ -} NET_Q_REQ_CHAL; - - -/* NET_R_REQ_CHAL */ -typedef struct net_r_req_chal_info { - DOM_CHAL srv_chal; /* server challenge */ - NTSTATUS status; /* return code */ -} NET_R_REQ_CHAL; - -/* NET_Q_AUTH */ -typedef struct net_q_auth_info { - DOM_LOG_INFO clnt_id; /* client identification info */ - DOM_CHAL clnt_chal; /* client-calculated credentials */ -} NET_Q_AUTH; - -/* NET_R_AUTH */ -typedef struct net_r_auth_info { - DOM_CHAL srv_chal; /* server-calculated credentials */ - NTSTATUS status; /* return code */ -} NET_R_AUTH; - -/* NET_Q_AUTH_2 */ -typedef struct net_q_auth2_info { - DOM_LOG_INFO clnt_id; /* client identification info */ - DOM_CHAL clnt_chal; /* client-calculated credentials */ - - NEG_FLAGS clnt_flgs; /* usually 0x0000 01ff */ -} NET_Q_AUTH_2; - - -/* NET_R_AUTH_2 */ -typedef struct net_r_auth2_info { - DOM_CHAL srv_chal; /* server-calculated credentials */ - NEG_FLAGS srv_flgs; /* usually 0x0000 01ff */ - NTSTATUS status; /* return code */ -} NET_R_AUTH_2; - -/* NET_Q_AUTH_3 */ -typedef struct net_q_auth3_info { - DOM_LOG_INFO clnt_id; /* client identification info */ - DOM_CHAL clnt_chal; /* client-calculated credentials */ - NEG_FLAGS clnt_flgs; /* usually 0x6007 ffff */ -} NET_Q_AUTH_3; - -/* NET_R_AUTH_3 */ -typedef struct net_r_auth3_info { - DOM_CHAL srv_chal; /* server-calculated credentials */ - NEG_FLAGS srv_flgs; /* usually 0x6007 ffff */ - uint32 unknown; /* 0x0000045b */ - NTSTATUS status; /* return code */ -} NET_R_AUTH_3; - - -/* NET_Q_SRV_PWSET */ -typedef struct net_q_srv_pwset_info { - DOM_CLNT_INFO clnt_id; /* client identification/authentication info */ - uint8 pwd[16]; /* new password - undocumented. */ -} NET_Q_SRV_PWSET; - -/* NET_R_SRV_PWSET */ -typedef struct net_r_srv_pwset_info { - DOM_CRED srv_cred; /* server-calculated credentials */ - - NTSTATUS status; /* return code */ -} NET_R_SRV_PWSET; - -/* NET_ID_INFO_2 */ -typedef struct net_network_info_2 { - uint32 ptr_id_info2; /* pointer to id_info_2 */ - UNIHDR hdr_domain_name; /* domain name unicode header */ - uint32 param_ctrl; /* param control (0x2) */ - DOM_LOGON_ID logon_id; /* logon ID */ - UNIHDR hdr_user_name; /* user name unicode header */ - UNIHDR hdr_wksta_name; /* workstation name unicode header */ - uint8 lm_chal[8]; /* lan manager 8 byte challenge */ - STRHDR hdr_nt_chal_resp; /* nt challenge response */ - STRHDR hdr_lm_chal_resp; /* lm challenge response */ - - UNISTR2 uni_domain_name; /* domain name unicode string */ - UNISTR2 uni_user_name; /* user name unicode string */ - UNISTR2 uni_wksta_name; /* workgroup name unicode string */ - STRING2 nt_chal_resp; /* nt challenge response */ - STRING2 lm_chal_resp; /* lm challenge response */ -} NET_ID_INFO_2; - -/* NET_ID_INFO_1 */ -typedef struct id_info_1 { - uint32 ptr_id_info1; /* pointer to id_info_1 */ - UNIHDR hdr_domain_name; /* domain name unicode header */ - uint32 param_ctrl; /* param control */ - DOM_LOGON_ID logon_id; /* logon ID */ - UNIHDR hdr_user_name; /* user name unicode header */ - UNIHDR hdr_wksta_name; /* workstation name unicode header */ - OWF_INFO lm_owf; /* LM OWF Password */ - OWF_INFO nt_owf; /* NT OWF Password */ - UNISTR2 uni_domain_name; /* domain name unicode string */ - UNISTR2 uni_user_name; /* user name unicode string */ - UNISTR2 uni_wksta_name; /* workgroup name unicode string */ -} NET_ID_INFO_1; - #define INTERACTIVE_LOGON_TYPE 1 #define NET_LOGON_TYPE 2 -/* NET_ID_INFO_CTR */ -typedef struct net_id_info_ctr_info { - uint16 switch_value; - - union { - NET_ID_INFO_1 id1; /* auth-level 1 - interactive user login */ - NET_ID_INFO_2 id2; /* auth-level 2 - workstation referred login */ - } auth; -} NET_ID_INFO_CTR; - -/* SAM_INFO - sam logon/off id structure */ -typedef struct sam_info { - DOM_CLNT_INFO2 client; - uint32 ptr_rtn_cred; /* pointer to return credentials */ - DOM_CRED rtn_cred; /* return credentials */ - uint16 logon_level; - NET_ID_INFO_CTR *ctr; -} DOM_SAM_INFO; - -/* SAM_INFO - sam logon/off id structure - no creds */ -typedef struct sam_info_ex { - DOM_CLNT_SRV client; - uint16 logon_level; - NET_ID_INFO_CTR *ctr; -} DOM_SAM_INFO_EX; - -/* NET_Q_SAM_LOGON */ -typedef struct net_q_sam_logon_info { - DOM_SAM_INFO sam_id; - uint16 validation_level; -} NET_Q_SAM_LOGON; - -/* NET_Q_SAM_LOGON_EX */ -typedef struct net_q_sam_logon_info_ex { - DOM_SAM_INFO_EX sam_id; - uint16 validation_level; - uint32 flags; -} NET_Q_SAM_LOGON_EX; - -/* NET_R_SAM_LOGON */ -typedef struct net_r_sam_logon_info { - uint32 buffer_creds; /* undocumented buffer pointer */ - DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */ - - uint16 switch_value; /* 3 - indicates type of USER INFO */ - NET_USER_INFO_3 *user; - - uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */ - - NTSTATUS status; /* return code */ -} NET_R_SAM_LOGON; - -/* NET_R_SAM_LOGON_EX */ -typedef struct net_r_sam_logon_info_ex { - uint16 switch_value; /* 3 - indicates type of USER INFO */ - NET_USER_INFO_3 *user; - - uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */ - uint32 flags; - - NTSTATUS status; /* return code */ -} NET_R_SAM_LOGON_EX; - - -/* NET_Q_SAM_LOGOFF */ -typedef struct net_q_sam_logoff_info { - DOM_SAM_INFO sam_id; -} NET_Q_SAM_LOGOFF; - -/* NET_R_SAM_LOGOFF */ -typedef struct net_r_sam_logoff_info { - uint32 buffer_creds; /* undocumented buffer pointer */ - DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */ - NTSTATUS status; /* return code */ -} NET_R_SAM_LOGOFF; - -/* NET_Q_SAM_SYNC */ -typedef struct net_q_sam_sync_info { - UNISTR2 uni_srv_name; /* \\PDC */ - UNISTR2 uni_cli_name; /* BDC */ - DOM_CRED cli_creds; - DOM_CRED ret_creds; - - uint32 database_id; - uint32 restart_state; - uint32 sync_context; - - uint32 max_size; /* preferred maximum length */ -} NET_Q_SAM_SYNC; - -/* SAM_DELTA_HDR */ -typedef struct sam_delta_hdr_info { - uint16 type; /* type of structure attached */ - uint16 type2; - uint32 target_rid; - - uint32 type3; - uint32 ptr_delta; -} SAM_DELTA_HDR; - /* LOCKOUT_STRING */ typedef struct account_lockout_string { uint32 array_size; @@ -632,356 +73,6 @@ typedef struct hdr_account_lockout_string { uint32 buffer; } HDR_LOCKOUT_STRING; -/* SAM_DOMAIN_INFO (0x1) */ -typedef struct sam_domain_info_info { - UNIHDR hdr_dom_name; - UNIHDR hdr_oem_info; - - uint64 force_logoff; - uint16 min_pwd_len; - uint16 pwd_history_len; - uint64 max_pwd_age; - uint64 min_pwd_age; - uint64 dom_mod_count; - NTTIME creation_time; - uint32 security_information; - - BUFHDR4 hdr_sec_desc; /* security descriptor */ - - HDR_LOCKOUT_STRING hdr_account_lockout; - - UNIHDR hdr_unknown2; - UNIHDR hdr_unknown3; - UNIHDR hdr_unknown4; - - UNISTR2 uni_dom_name; - UNISTR2 buf_oem_info; - - RPC_DATA_BLOB buf_sec_desc; - - LOCKOUT_STRING account_lockout; - - UNISTR2 buf_unknown2; - UNISTR2 buf_unknown3; - UNISTR2 buf_unknown4; - - uint32 logon_chgpass; - uint32 unknown6; - uint32 unknown7; - uint32 unknown8; -} SAM_DOMAIN_INFO; - -/* SAM_GROUP_INFO (0x2) */ -typedef struct sam_group_info_info { - UNIHDR hdr_grp_name; - DOM_GID gid; - UNIHDR hdr_grp_desc; - BUFHDR2 hdr_sec_desc; /* security descriptor */ - uint8 reserved[48]; - - UNISTR2 uni_grp_name; - UNISTR2 uni_grp_desc; - RPC_DATA_BLOB buf_sec_desc; -} SAM_GROUP_INFO; - -/* SAM_PWD */ -typedef struct sam_passwd_info { - /* this structure probably contains password history */ - /* this is probably a count of lm/nt pairs */ - uint32 unk_0; /* 0x0000 0002 */ - - UNIHDR hdr_lm_pwd; - uint8 buf_lm_pwd[16]; - - UNIHDR hdr_nt_pwd; - uint8 buf_nt_pwd[16]; - - UNIHDR hdr_empty_lm; - UNIHDR hdr_empty_nt; -} SAM_PWD; - -/* SAM_ACCOUNT_INFO (0x5) */ -typedef struct sam_account_info_info { - UNIHDR hdr_acct_name; - UNIHDR hdr_full_name; - - uint32 user_rid; - uint32 group_rid; - - UNIHDR hdr_home_dir; - UNIHDR hdr_dir_drive; - UNIHDR hdr_logon_script; - UNIHDR hdr_acct_desc; - UNIHDR hdr_workstations; - - NTTIME logon_time; - NTTIME logoff_time; - - uint32 logon_divs; /* 0xA8 */ - uint32 ptr_logon_hrs; - - uint16 bad_pwd_count; - uint16 logon_count; - NTTIME pwd_last_set_time; - NTTIME acct_expiry_time; - - uint32 acb_info; - uint8 nt_pwd[16]; - uint8 lm_pwd[16]; - uint8 nt_pwd_present; - uint8 lm_pwd_present; - uint8 pwd_expired; - - UNIHDR hdr_comment; - UNIHDR hdr_parameters; - uint16 country; - uint16 codepage; - - BUFHDR2 hdr_sec_desc; /* security descriptor */ - - UNIHDR hdr_profile; - UNIHDR hdr_reserved[3]; /* space for more strings */ - uint32 dw_reserved[4]; /* space for more data - first two seem to - be an NTTIME */ - - UNISTR2 uni_acct_name; - UNISTR2 uni_full_name; - UNISTR2 uni_home_dir; - UNISTR2 uni_dir_drive; - UNISTR2 uni_logon_script; - UNISTR2 uni_acct_desc; - UNISTR2 uni_workstations; - - uint32 unknown1; /* 0x4EC */ - uint32 unknown2; /* 0 */ - - RPC_DATA_BLOB buf_logon_hrs; - UNISTR2 uni_comment; - UNISTR2 uni_parameters; - SAM_PWD pass; - RPC_DATA_BLOB buf_sec_desc; - UNISTR2 uni_profile; -} SAM_ACCOUNT_INFO; - -/* SAM_GROUP_MEM_INFO (0x8) */ -typedef struct sam_group_mem_info_info { - uint32 ptr_rids; - uint32 ptr_attribs; - uint32 num_members; - uint8 unknown[16]; - - uint32 num_members2; - uint32 *rids; - - uint32 num_members3; - uint32 *attribs; - -} SAM_GROUP_MEM_INFO; - -/* SAM_ALIAS_INFO (0x9) */ -typedef struct sam_alias_info_info { - UNIHDR hdr_als_name; - uint32 als_rid; - BUFHDR2 hdr_sec_desc; /* security descriptor */ - UNIHDR hdr_als_desc; - uint8 reserved[40]; - - UNISTR2 uni_als_name; - RPC_DATA_BLOB buf_sec_desc; - UNISTR2 uni_als_desc; -} SAM_ALIAS_INFO; - -/* SAM_ALIAS_MEM_INFO (0xC) */ -typedef struct sam_alias_mem_info_info { - uint32 num_members; - uint32 ptr_members; - uint8 unknown[16]; - - uint32 num_sids; - uint32 *ptr_sids; - DOM_SID2 *sids; -} SAM_ALIAS_MEM_INFO; - - -/* SAM_DELTA_POLICY (0x0D) */ -typedef struct { - uint32 max_log_size; /* 0x5000 */ - uint64 audit_retention_period; /* 0 */ - uint32 auditing_mode; /* 0 */ - uint32 num_events; - uint32 ptr_events; - UNIHDR hdr_dom_name; - uint32 sid_ptr; - - uint32 paged_pool_limit; /* 0x02000000 */ - uint32 non_paged_pool_limit; /* 0x00100000 */ - uint32 min_workset_size; /* 0x00010000 */ - uint32 max_workset_size; /* 0x0f000000 */ - uint32 page_file_limit; /* 0 */ - uint64 time_limit; /* 0 */ - NTTIME modify_time; /* 0x3c*/ - NTTIME create_time; /* a7080110 */ - BUFHDR2 hdr_sec_desc; - - uint32 num_event_audit_options; - uint32 event_audit_option; - - UNISTR2 domain_name; - DOM_SID2 domain_sid; - - RPC_DATA_BLOB buf_sec_desc; -} SAM_DELTA_POLICY; - -/* SAM_DELTA_TRUST_DOMS */ -typedef struct { - uint32 buf_size; - SEC_DESC *sec_desc; - DOM_SID2 sid; - UNIHDR hdr_domain; - - uint32 unknown0; - uint32 unknown1; - uint32 unknown2; - - uint32 buf_size2; - uint32 ptr; - - uint32 unknown3; - UNISTR2 domain; -} SAM_DELTA_TRUSTDOMS; - -/* SAM_DELTA_PRIVS (0x10) */ -typedef struct { - DOM_SID2 sid; - - uint32 priv_count; - uint32 priv_control; - - uint32 priv_attr_ptr; - uint32 priv_name_ptr; - - uint32 paged_pool_limit; /* 0x02000000 */ - uint32 non_paged_pool_limit; /* 0x00100000 */ - uint32 min_workset_size; /* 0x00010000 */ - uint32 max_workset_size; /* 0x0f000000 */ - uint32 page_file_limit; /* 0 */ - uint64 time_limit; /* 0 */ - uint32 system_flags; /* 1 */ - BUFHDR2 hdr_sec_desc; - - uint32 buf_size2; - - uint32 attribute_count; - uint32 *attributes; - - uint32 privlist_count; - UNIHDR *hdr_privslist; - UNISTR2 *uni_privslist; - - RPC_DATA_BLOB buf_sec_desc; -} SAM_DELTA_PRIVS; - -/* SAM_DELTA_SECRET */ -typedef struct { - uint32 buf_size; - SEC_DESC *sec_desc; - UNISTR2 secret; - - uint32 count1; - uint32 count2; - uint32 ptr; - NTTIME time1; - uint32 count3; - uint32 count4; - uint32 ptr2; - NTTIME time2; - uint32 unknow1; - - uint32 buf_size2; - uint32 ptr3; - uint32 unknow2; /* 0x0 12 times */ - - uint32 chal_len; - uint32 reserved1; /* 0 */ - uint32 chal_len2; - uint8 chal[16]; - - uint32 key_len; - uint32 reserved2; /* 0 */ - uint32 key_len2; - uint8 key[8]; - - uint32 buf_size3; - SEC_DESC *sec_desc2; -} SAM_DELTA_SECRET; - -/* SAM_DELTA_MOD_COUNT (0x16) */ -typedef struct { - uint32 seqnum; - uint32 dom_mod_count_ptr; - uint64 dom_mod_count; /* domain mod count at last sync */ -} SAM_DELTA_MOD_COUNT; - -typedef union sam_delta_ctr_info { - SAM_DOMAIN_INFO domain_info ; - SAM_GROUP_INFO group_info ; - SAM_ACCOUNT_INFO account_info; - SAM_GROUP_MEM_INFO grp_mem_info; - SAM_ALIAS_INFO alias_info ; - SAM_ALIAS_MEM_INFO als_mem_info; - SAM_DELTA_POLICY policy_info; - SAM_DELTA_PRIVS privs_info; - SAM_DELTA_MOD_COUNT mod_count; - SAM_DELTA_TRUSTDOMS trustdoms_info; - SAM_DELTA_SECRET secret_info; -} SAM_DELTA_CTR; - -/* NET_R_SAM_SYNC */ -typedef struct net_r_sam_sync_info { - DOM_CRED srv_creds; - - uint32 sync_context; - - uint32 ptr_deltas; - uint32 num_deltas; - uint32 ptr_deltas2; - uint32 num_deltas2; - - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; - - NTSTATUS status; -} NET_R_SAM_SYNC; - -/* NET_Q_SAM_DELTAS */ -typedef struct net_q_sam_deltas_info { - UNISTR2 uni_srv_name; - UNISTR2 uni_cli_name; - DOM_CRED cli_creds; - DOM_CRED ret_creds; - - uint32 database_id; - uint64 dom_mod_count; /* domain mod count at last sync */ - - uint32 max_size; /* preferred maximum length */ -} NET_Q_SAM_DELTAS; - -/* NET_R_SAM_DELTAS */ -typedef struct net_r_sam_deltas_info { - DOM_CRED srv_creds; - - uint64 dom_mod_count; /* new domain mod count */ - - uint32 ptr_deltas; - uint32 num_deltas; - uint32 num_deltas2; - - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; - - NTSTATUS status; -} NET_R_SAM_DELTAS; - #define DSGETDC_VALID_FLAGS ( \ DS_FORCE_REDISCOVERY | \ DS_DIRECTORY_SERVICE_REQUIRED | \ diff --git a/source3/include/rpc_ntsvcs.h b/source3/include/rpc_ntsvcs.h index 045d9b4e92..71274cc380 100644 --- a/source3/include/rpc_ntsvcs.h +++ b/source3/include/rpc_ntsvcs.h @@ -36,32 +36,6 @@ /**************************/ typedef struct { - /* nothing in the request */ - uint32 dummy; -} NTSVCS_Q_GET_VERSION; - -typedef struct { - uint32 version; - WERROR status; -} NTSVCS_R_GET_VERSION; - - -/**************************/ - -typedef struct { - UNISTR2 *devicename; - uint32 flags; -} NTSVCS_Q_GET_DEVICE_LIST_SIZE; - -typedef struct { - uint32 size; - WERROR status; -} NTSVCS_R_GET_DEVICE_LIST_SIZE; - - -/**************************/ - -typedef struct { UNISTR2 *devicename; uint32 buffer_size; uint32 flags; @@ -75,17 +49,6 @@ typedef struct { /**************************/ -typedef struct { - UNISTR2 devicepath; - uint32 flags; -} NTSVCS_Q_VALIDATE_DEVICE_INSTANCE; - -typedef struct { - WERROR status; -} NTSVCS_R_VALIDATE_DEVICE_INSTANCE; - -/**************************/ - #define DEV_REGPROP_DESC 1 typedef struct { @@ -105,42 +68,4 @@ typedef struct { WERROR status; } NTSVCS_R_GET_DEVICE_REG_PROPERTY; - -/**************************/ - -typedef struct { - uint32 index; - uint8 *buffer; - uint32 buffer_size; - uint32 unknown1; -} NTSVCS_Q_GET_HW_PROFILE_INFO; - -typedef struct { - uint32 buffer_size; /* the size (not included in the reply) - if just matched from the request */ - uint8 *buffer; - WERROR status; -} NTSVCS_R_GET_HW_PROFILE_INFO; - - -/**************************/ - -typedef struct { - uint32 unknown1; - UNISTR2 devicepath; - uint32 unknown2; - uint32 unknown3; - uint32 unknown4; - uint32 unknown5; - uint32 unknown6; - uint32 unknown7; -} NTSVCS_Q_HW_PROFILE_FLAGS; - -typedef struct { - uint32 unknown1; - uint32 unknown2; - uint32 unknown3; - WERROR status; -} NTSVCS_R_HW_PROFILE_FLAGS; - #endif /* _RPC_NTSVCS_H */ diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h deleted file mode 100644 index 62c6b167db..0000000000 --- a/source3/include/rpc_samr.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Paul Ashton 1997-2000 - Copyright (C) Jean François Micouleau 1998-2001 - Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#ifndef _RPC_SAMR_H /* _RPC_SAMR_H */ -#define _RPC_SAMR_H - -/******************************************************************* - the following information comes from a QuickView on samsrv.dll, - and gives an idea of exactly what is needed: - -x SamrAddMemberToAlias -x SamrAddMemberToGroup -SamrAddMultipleMembersToAlias -x SamrChangePasswordUser -x SamrCloseHandle -x SamrConnect -x SamrCreateAliasInDomain -x SamrCreateGroupInDomain -x SamrCreateUserInDomain -? SamrDeleteAlias -SamrDeleteGroup -x SamrDeleteUser -x SamrEnumerateAliasesInDomain -SamrEnumerateDomainsInSamServer -x SamrEnumerateGroupsInDomain -x SamrEnumerateUsersInDomain -SamrGetUserDomainPasswordInformation -SamrLookupDomainInSamServer -? SamrLookupIdsInDomain -x SamrLookupNamesInDomain -x SamrOpenAlias -x SamrOpenDomain -x SamrOpenGroup -x SamrOpenUser -x SamrQueryDisplayInformation -x SamrQueryInformationAlias -SamrQueryInformationDomain -? SamrQueryInformationUser -x SamrQuerySecurityObject -SamrRemoveMemberFromAlias -SamrRemoveMemberFromForiegnDomain -SamrRemoveMemberFromGroup -SamrRemoveMultipleMembersFromAlias -x SamrSetInformationAlias -SamrSetInformationDomain -x SamrSetInformationGroup -x SamrSetInformationUser -SamrSetMemberAttributesOfGroup -SamrSetSecurityObject -SamrShutdownSamServer -SamrTestPrivateFunctionsDomain -SamrTestPrivateFunctionsUser - -********************************************************************/ - -#define SAMR_CONNECT_ANON 0x00 -#define SAMR_CLOSE_HND 0x01 -#define SAMR_SET_SEC_OBJECT 0x02 -#define SAMR_QUERY_SEC_OBJECT 0x03 - -#define SAMR_UNKNOWN_4 0x04 /* profile info? */ -#define SAMR_LOOKUP_DOMAIN 0x05 -#define SAMR_ENUM_DOMAINS 0x06 -#define SAMR_OPEN_DOMAIN 0x07 -#define SAMR_QUERY_DOMAIN_INFO 0x08 -#define SAMR_SET_DOMAIN_INFO 0x09 - -#define SAMR_CREATE_DOM_GROUP 0x0a -#define SAMR_ENUM_DOM_GROUPS 0x0b -#define SAMR_ENUM_DOM_USERS 0x0d -#define SAMR_CREATE_DOM_ALIAS 0x0e -#define SAMR_ENUM_DOM_ALIASES 0x0f -#define SAMR_QUERY_USERALIASES 0x10 - -#define SAMR_LOOKUP_NAMES 0x11 -#define SAMR_LOOKUP_RIDS 0x12 - -#define SAMR_OPEN_GROUP 0x13 -#define SAMR_QUERY_GROUPINFO 0x14 -#define SAMR_SET_GROUPINFO 0x15 -#define SAMR_ADD_GROUPMEM 0x16 -#define SAMR_DELETE_DOM_GROUP 0x17 -#define SAMR_DEL_GROUPMEM 0x18 -#define SAMR_QUERY_GROUPMEM 0x19 -#define SAMR_UNKNOWN_1A 0x1a - -#define SAMR_OPEN_ALIAS 0x1b -#define SAMR_QUERY_ALIASINFO 0x1c -#define SAMR_SET_ALIASINFO 0x1d -#define SAMR_DELETE_DOM_ALIAS 0x1e -#define SAMR_ADD_ALIASMEM 0x1f -#define SAMR_DEL_ALIASMEM 0x20 -#define SAMR_QUERY_ALIASMEM 0x21 - -#define SAMR_OPEN_USER 0x22 -#define SAMR_DELETE_DOM_USER 0x23 -#define SAMR_QUERY_USERINFO 0x24 -#define SAMR_SET_USERINFO2 0x25 /* this is SAMR_SET_USERINFO! */ -#define SAMR_QUERY_USERGROUPS 0x27 - -#define SAMR_QUERY_DISPINFO 0x28 -#define SAMR_GET_DISPENUM_INDEX 0x29 -#define SAMR_UNKNOWN_2a 0x2a -#define SAMR_UNKNOWN_2b 0x2b -#define SAMR_GET_USRDOM_PWINFO 0x2c -#define SAMR_REMOVE_SID_FOREIGN_DOMAIN 0x2d -#define SAMR_QUERY_DOMAIN_INFO2 0x2e /* looks like an alias for SAMR_QUERY_DOMAIN_INFO */ -#define SAMR_UNKNOWN_2f 0x2f -#define SAMR_QUERY_DISPINFO3 0x30 /* Alias for SAMR_QUERY_DISPINFO - with info level 3 */ -#define SAMR_UNKNOWN_31 0x31 -#define SAMR_CREATE_USER 0x32 -#define SAMR_QUERY_DISPINFO4 0x33 /* Alias for SAMR_QUERY_DISPINFO - with info level 4 */ -#define SAMR_ADDMULTI_ALIASMEM 0x34 - -#define SAMR_UNKNOWN_35 0x35 -#define SAMR_UNKNOWN_36 0x36 -#define SAMR_CHGPASSWD_USER 0x37 -#define SAMR_GET_DOM_PWINFO 0x38 -#define SAMR_CONNECT 0x39 -#define SAMR_SET_USERINFO 0x3A /* this is SAMR_SET_USERINFO2! */ -#define SAMR_CONNECT4 0x3E -#define SAMR_CHGPASSWD_USER3 0x3F -#define SAMR_CONNECT5 0x40 - -#define PASS_MUST_CHANGE_AT_NEXT_LOGON 0x01 -#define PASS_DONT_CHANGE_AT_NEXT_LOGON 0x00 - -#define MAX_SAM_ENTRIES_W2K 0x400 -#define MAX_SAM_ENTRIES_W95 50 -/* The following should be the greater of the preceeding two. */ -#define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K - -/* these are from the old rpc_samr.h - they are needed while the merge - is still going on */ -#define MAX_SAM_SIDS 15 - -#endif /* _RPC_SAMR_H */ diff --git a/source3/include/rpc_srvsvc.h b/source3/include/rpc_srvsvc.h index 097c0d4348..d0b25e4fad 100644 --- a/source3/include/rpc_srvsvc.h +++ b/source3/include/rpc_srvsvc.h @@ -683,145 +683,6 @@ typedef struct { WERROR status; } SRV_R_NET_FILE_ENUM; -/* SRV_INFO_100 */ -typedef struct srv_info_100_info -{ - uint32 platform_id; /* 0x500 */ - uint32 ptr_name; /* pointer to server name */ - - UNISTR2 uni_name; /* server name "server" */ - -} SRV_INFO_100; - -/* SRV_INFO_101 */ -typedef struct srv_info_101_info -{ - uint32 platform_id; /* 0x500 */ - uint32 ptr_name; /* pointer to server name */ - uint32 ver_major; /* 0x4 */ - uint32 ver_minor; /* 0x2 */ - uint32 srv_type; /* browse etc type */ - uint32 ptr_comment; /* pointer to server comment */ - - UNISTR2 uni_name; /* server name "server" */ - UNISTR2 uni_comment; /* server comment "samba x.x.x blah" */ - -} SRV_INFO_101; - -/* SRV_INFO_102 */ -typedef struct srv_info_102_info -{ - uint32 platform_id; /* 0x500 */ - uint32 ptr_name; /* pointer to server name */ - uint32 ver_major; /* 0x4 */ - uint32 ver_minor; /* 0x2 */ - uint32 srv_type; /* browse etc type */ - uint32 ptr_comment; /* pointer to server comment */ - uint32 users; /* 0xffff ffff*/ - uint32 disc; /* 0xf */ - uint32 hidden; /* 0x0 */ - uint32 announce; /* 240 */ - uint32 ann_delta; /* 3000 */ - uint32 licenses; /* 0 */ - uint32 ptr_usr_path; /* pointer to user path */ - - UNISTR2 uni_name; /* server name "server" */ - UNISTR2 uni_comment; /* server comment "samba x.x.x blah" */ - UNISTR2 uni_usr_path; /* "c:\" (eh?) */ - -} SRV_INFO_102; - - -/* SRV_INFO_CTR */ -typedef struct srv_info_ctr_info -{ - uint32 switch_value; /* switch value */ - uint32 ptr_srv_ctr; /* pointer to server info */ - union - { - SRV_INFO_102 sv102; /* server info level 102 */ - SRV_INFO_101 sv101; /* server info level 101 */ - SRV_INFO_100 sv100; /* server info level 100 */ - - } srv; - -} SRV_INFO_CTR; - -/* SRV_Q_NET_SRV_GET_INFO */ -typedef struct q_net_srv_get_info -{ - uint32 ptr_srv_name; - UNISTR2 uni_srv_name; /* "\\server" */ - uint32 switch_value; - -} SRV_Q_NET_SRV_GET_INFO; - -/* SRV_R_NET_SRV_GET_INFO */ -typedef struct r_net_srv_get_info -{ - SRV_INFO_CTR *ctr; - - WERROR status; /* return status */ - -} SRV_R_NET_SRV_GET_INFO; - -/* SRV_Q_NET_SRV_SET_INFO */ -typedef struct q_net_srv_set_info -{ - uint32 ptr_srv_name; - UNISTR2 uni_srv_name; /* "\\server" */ - uint32 switch_value; - - SRV_INFO_CTR *ctr; - -} SRV_Q_NET_SRV_SET_INFO; - - -/* SRV_R_NET_SRV_SET_INFO */ -typedef struct r_net_srv_set_info -{ - uint32 switch_value; /* switch value */ - - WERROR status; /* return status */ - -} SRV_R_NET_SRV_SET_INFO; - -/* SRV_Q_NET_REMOTE_TOD */ -typedef struct q_net_remote_tod -{ - uint32 ptr_srv_name; - UNISTR2 uni_srv_name; /* "\\server" */ - -} SRV_Q_NET_REMOTE_TOD; - -/* TIME_OF_DAY_INFO */ -typedef struct time_of_day_info -{ - uint32 elapsedt; - uint32 msecs; - uint32 hours; - uint32 mins; - uint32 secs; - uint32 hunds; - uint32 zone; - uint32 tintervals; - uint32 day; - uint32 month; - uint32 year; - uint32 weekday; - -} TIME_OF_DAY_INFO; - -/* SRV_R_NET_REMOTE_TOD */ -typedef struct r_net_remote_tod -{ - uint32 ptr_srv_tod; /* pointer to TOD */ - TIME_OF_DAY_INFO *tod; - - WERROR status; /* return status */ - -} SRV_R_NET_REMOTE_TOD; - /* SRV_Q_NET_FILE_QUERY_SECDESC */ typedef struct q_net_file_query_secdesc { diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h index 1e42aef20c..5a87e350ba 100644 --- a/source3/include/rpc_svcctl.h +++ b/source3/include/rpc_svcctl.h @@ -197,81 +197,6 @@ typedef struct _ServiceInfo { /**************************/ typedef struct { - UNISTR2 *servername; - UNISTR2 *database; - uint32 access; -} SVCCTL_Q_OPEN_SCMANAGER; - -typedef struct { - POLICY_HND handle; - WERROR status; -} SVCCTL_R_OPEN_SCMANAGER; - -/**************************/ - -typedef struct { - POLICY_HND handle; - UNISTR2 servicename; - uint32 display_name_len; -} SVCCTL_Q_GET_DISPLAY_NAME; - -typedef struct { - UNISTR2 displayname; - uint32 display_name_len; - WERROR status; -} SVCCTL_R_GET_DISPLAY_NAME; - -/**************************/ - -typedef struct { - POLICY_HND handle; - UNISTR2 servicename; - uint32 access; -} SVCCTL_Q_OPEN_SERVICE; - -typedef struct { - POLICY_HND handle; - WERROR status; -} SVCCTL_R_OPEN_SERVICE; - -/**************************/ - -typedef struct { - POLICY_HND handle; - uint32 parmcount; - UNISTR4_ARRAY *parameters; -} SVCCTL_Q_START_SERVICE; - -typedef struct { - WERROR status; -} SVCCTL_R_START_SERVICE; - -/**************************/ - -typedef struct { - POLICY_HND handle; - uint32 control; -} SVCCTL_Q_CONTROL_SERVICE; - -typedef struct { - SERVICE_STATUS svc_status; - WERROR status; -} SVCCTL_R_CONTROL_SERVICE; - -/**************************/ - -typedef struct { - POLICY_HND handle; -} SVCCTL_Q_QUERY_STATUS; - -typedef struct { - SERVICE_STATUS svc_status; - WERROR status; -} SVCCTL_R_QUERY_STATUS; - -/**************************/ - -typedef struct { POLICY_HND handle; uint32 type; uint32 state; @@ -346,57 +271,5 @@ typedef struct { WERROR status; } SVCCTL_R_QUERY_SERVICE_STATUSEX; - -/**************************/ - -typedef struct { - POLICY_HND handle; -} SVCCTL_Q_LOCK_SERVICE_DB; - -typedef struct { - POLICY_HND h_lock; - WERROR status; -} SVCCTL_R_LOCK_SERVICE_DB; - - -/**************************/ - -typedef struct { - POLICY_HND h_lock; -} SVCCTL_Q_UNLOCK_SERVICE_DB; - -typedef struct { - WERROR status; -} SVCCTL_R_UNLOCK_SERVICE_DB; - - -/**************************/ - -typedef struct { - POLICY_HND handle; - uint32 security_flags; - uint32 buffer_size; -} SVCCTL_Q_QUERY_SERVICE_SEC; - -typedef struct { - RPC_BUFFER buffer; - uint32 needed; - WERROR status; -} SVCCTL_R_QUERY_SERVICE_SEC; - -/**************************/ - -typedef struct { - POLICY_HND handle; - uint32 security_flags; - RPC_BUFFER buffer; - uint32 buffer_size; -} SVCCTL_Q_SET_SERVICE_SEC; - -typedef struct { - WERROR status; -} SVCCTL_R_SET_SERVICE_SEC; - - #endif /* _RPC_SVCCTL_H */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 3e0c997997..c582a97e5c 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -308,6 +308,8 @@ extern const DATA_BLOB data_blob_null; #include "librpc/gen_ndr/samr.h" #include "librpc/gen_ndr/dssetup.h" #include "librpc/gen_ndr/libnet_join.h" +#include "librpc/gen_ndr/krb5pac.h" +#include "librpc/gen_ndr/ntsvcs.h" struct lsa_dom_info { bool valid; diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index 463a2bdb0b..c98c4244de 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -305,10 +305,9 @@ NULL returns on zero request. JRA. #define talloc_destroy(ctx) talloc_free(ctx) #define TALLOC_FREE(ctx) do { if ((ctx) != NULL) {talloc_free(ctx); ctx=NULL;} } while(0) -/* only define PARANOID_MALLOC_CHECKER with --enable-developer and not compiling - the smbmount utils */ +/* only define PARANOID_MALLOC_CHECKER with --enable-developer */ -#if defined(DEVELOPER) && !defined(SMBMOUNT_MALLOC) +#if defined(DEVELOPER) # define PARANOID_MALLOC_CHECKER 1 #endif diff --git a/source3/intl/lang_tdb.c b/source3/intl/lang_tdb.c index bb780c5fed..6ad9ef8496 100644 --- a/source3/intl/lang_tdb.c +++ b/source3/intl/lang_tdb.c @@ -127,7 +127,11 @@ bool lang_tdb_init(const char *lang) if (!lang) return True; - asprintf(&msg_path, "%s.msg", data_path((const char *)lang)); + if (asprintf(&msg_path, "%s.msg", + data_path((const char *)lang)) == -1) { + DEBUG(0, ("asprintf failed\n")); + goto done; + } if (stat(msg_path, &st) != 0) { /* the msg file isn't available */ DEBUG(10, ("lang_tdb_init: %s: %s\n", msg_path, @@ -135,7 +139,10 @@ bool lang_tdb_init(const char *lang) goto done; } - asprintf(&path, "%s%s.tdb", lock_path("lang_"), lang); + if (asprintf(&path, "%s%s.tdb", lock_path("lang_"), lang) == -1) { + DEBUG(0, ("asprintf failed\n")); + goto done; + } DEBUG(10, ("lang_tdb_init: loading %s\n", path)); diff --git a/source3/lib/debug.c b/source3/lib/debug.c index 9ff267b607..c4a0d1b47b 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -827,6 +827,7 @@ void check_log_size( void ) }; int priority; char *msgbuf = NULL; + int ret; if( syslog_level >= ( sizeof(priority_map) / sizeof(priority_map[0]) ) || syslog_level < 0) priority = LOG_DEBUG; @@ -834,10 +835,10 @@ void check_log_size( void ) priority = priority_map[syslog_level]; va_start(ap, format_str); - vasprintf(&msgbuf, format_str, ap); + ret = vasprintf(&msgbuf, format_str, ap); va_end(ap); - if (msgbuf) { + if (ret == -1) { syslog(priority, "%s", msgbuf); } SAFE_FREE(msgbuf); @@ -1059,12 +1060,13 @@ bool dbghdr(int level, int cls, const char *file, const char *func, int line) va_list ap; char *msgbuf = NULL; bool ret = true; + int res; va_start(ap, format_str); - vasprintf(&msgbuf, format_str, ap); + res = vasprintf(&msgbuf, format_str, ap); va_end(ap); - if (msgbuf) { + if (res != -1) { format_debug_text(msgbuf); } else { ret = false; diff --git a/source3/lib/display_dsdcinfo.c b/source3/lib/display_dsdcinfo.c deleted file mode 100644 index dcb05297a1..0000000000 --- a/source3/lib/display_dsdcinfo.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Guenther Deschner 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" - -/**************************************************************** -****************************************************************/ - -void display_ds_domain_controller_info(TALLOC_CTX *mem_ctx, - const struct DS_DOMAIN_CONTROLLER_INFO *info) -{ - d_printf("domain_controller_name: %s\n", - info->domain_controller_name); - d_printf("domain_controller_address: %s\n", - info->domain_controller_address); - d_printf("domain_controller_address_type: %d\n", - info->domain_controller_address_type); - d_printf("domain_guid: %s\n", - GUID_string(mem_ctx, info->domain_guid)); - d_printf("domain_name: %s\n", - info->domain_name); - d_printf("dns_forest_name: %s\n", - info->dns_forest_name); - - d_printf("flags: 0x%08x\n" - "\tIs a PDC: %s\n" - "\tIs a GC of the forest: %s\n" - "\tIs an LDAP server: %s\n" - "\tSupports DS: %s\n" - "\tIs running a KDC: %s\n" - "\tIs running time services: %s\n" - "\tIs the closest DC: %s\n" - "\tIs writable: %s\n" - "\tHas a hardware clock: %s\n" - "\tIs a non-domain NC serviced by LDAP server: %s\n" - "\tDomainControllerName is a DNS name: %s\n" - "\tDomainName is a DNS name: %s\n" - "\tDnsForestName is a DNS name: %s\n", - info->flags, - (info->flags & ADS_PDC) ? "yes" : "no", - (info->flags & ADS_GC) ? "yes" : "no", - (info->flags & ADS_LDAP) ? "yes" : "no", - (info->flags & ADS_DS) ? "yes" : "no", - (info->flags & ADS_KDC) ? "yes" : "no", - (info->flags & ADS_TIMESERV) ? "yes" : "no", - (info->flags & ADS_CLOSEST) ? "yes" : "no", - (info->flags & ADS_WRITABLE) ? "yes" : "no", - (info->flags & ADS_GOOD_TIMESERV) ? "yes" : "no", - (info->flags & ADS_NDNC) ? "yes" : "no", - (info->flags & ADS_DNS_CONTROLLER) ? "yes":"no", - (info->flags & ADS_DNS_DOMAIN) ? "yes":"no", - (info->flags & ADS_DNS_FOREST) ? "yes":"no"); - - d_printf("dc_site_name: %s\n", info->dc_site_name); - d_printf("client_site_name: %s\n", info->client_site_name); -} diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c index 663385cfe3..6131269adb 100644 --- a/source3/lib/gencache.c +++ b/source3/lib/gencache.c @@ -120,9 +120,9 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout) if (!gencache_init()) return False; - asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value); - if (!valstr) + if (asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value) == -1) { return False; + } databuf = string_term_tdb_data(valstr); DEBUG(10, ("Adding cache entry with key = %s; value = %s and timeout =" @@ -340,8 +340,7 @@ bool gencache_set_data_blob(const char *keystr, DATA_BLOB *blob, time_t timeout) return False; } - asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE); - if (!valstr) { + if (asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE) == -1) { return False; } @@ -452,8 +451,9 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time break; } - asprintf(&fmt, READ_CACHE_DATA_FMT_TEMPLATE, (unsigned int)databuf.dsize - TIMEOUT_LEN); - if (!fmt) { + if (asprintf(&fmt, READ_CACHE_DATA_FMT_TEMPLATE, + (unsigned int)databuf.dsize - TIMEOUT_LEN) + == -1) { SAFE_FREE(valstr); SAFE_FREE(entry); SAFE_FREE(keystr); diff --git a/source3/lib/interfaces.c b/source3/lib/interfaces.c index 3797fc679d..dd857ae672 100644 --- a/source3/lib/interfaces.c +++ b/source3/lib/interfaces.c @@ -191,7 +191,6 @@ void make_net(struct sockaddr_storage *pss_out, Also gets IPv6 interfaces. ****************************************************************************/ -#if HAVE_IFACE_GETIFADDRS /**************************************************************************** Get the netmask address for a local interface. ****************************************************************************/ @@ -237,19 +236,9 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) memcpy(&ifaces[total].netmask, ifptr->ifa_netmask, copy_size); if (ifaces[total].flags & (IFF_BROADCAST|IFF_LOOPBACK)) { - if (ifptr->ifa_broadaddr) { - memcpy(&ifaces[total].bcast, - ifptr->ifa_broadaddr, - copy_size); - } else { - /* For some reason ifptr->ifa_broadaddr - * is null. Make one from ifa_addr and - * ifa_netmask. - */ - make_bcast(&ifaces[total].bcast, - &ifaces[total].ip, - &ifaces[total].netmask); - } + make_bcast(&ifaces[total].bcast, + &ifaces[total].ip, + &ifaces[total].netmask); } else if ((ifaces[total].flags & IFF_POINTOPOINT) && ifptr->ifa_dstaddr ) { memcpy(&ifaces[total].bcast, @@ -269,339 +258,6 @@ static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) return total; } -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_GETIFADDRS */ -#if HAVE_IFACE_IFCONF - -/* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 - V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. - - It probably also works on any BSD style system. */ - -/**************************************************************************** - Get the netmask address for a local interface. -****************************************************************************/ - -static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) -{ - struct ifconf ifc; - char buff[8192]; - int fd, i, n; - struct ifreq *ifr=NULL; - int total = 0; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - return -1; - } - - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - - if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { - close(fd); - return -1; - } - - ifr = ifc.ifc_req; - - n = ifc.ifc_len / sizeof(struct ifreq); - - /* Loop through interfaces, looking for given IP address */ - for (i=n-1;i>=0 && total < max_interfaces;i--) { - - memset(&ifaces[total], '\0', sizeof(ifaces[total])); - - /* Check the interface is up. */ - if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) != 0) { - continue; - } - - ifaces[total].flags = ifr[i].ifr_flags; - - if (!(ifaces[total].flags & IFF_UP)) { - continue; - } - - if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) { - continue; - } - - strlcpy(ifaces[total].name, ifr[i].ifr_name, - sizeof(ifaces[total].name)); - - memcpy(&ifaces[total].ip, &ifr[i].ifr_addr, - sizeof(struct sockaddr_in)); - - if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != 0) { - continue; - } - - memcpy(&ifaces[total].netmask, &ifr[i].ifr_netmask, - sizeof(struct sockaddr_in)); - - if (ifaces[total].flags & IFF_BROADCAST) { - if (ioctl(fd, SIOCGIFBRDADDR, &ifr[i]) != 0) { - continue; - } - memcpy(&ifaces[total].bcast, &ifr[i].ifr_broadaddr, - sizeof(struct sockaddr_in)); - } else if (ifaces[total].flags & IFF_POINTOPOINT) { - if (ioctl(fd, SIOCGIFDSTADDR, &ifr[i]) != 0) { - continue; - } - memcpy(&ifaces[total].bcast, &ifr[i].ifr_dstaddr, - sizeof(struct sockaddr_in)); - } else { - continue; - } - - total++; - } - - close(fd); - - return total; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_IFCONF */ -#ifdef HAVE_IFACE_IFREQ - -#ifndef I_STR -#include <sys/stropts.h> -#endif - -/**************************************************************************** - This should cover most of the streams based systems. - Thanks to Andrej.Borsenkow@mow.siemens.ru for several ideas in this code. -****************************************************************************/ - -static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) -{ - struct ifreq ifreq; - struct strioctl strioctl; - char buff[8192]; - int fd, i, n; - struct ifreq *ifr=NULL; - int total = 0; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - return -1; - } - - strioctl.ic_cmd = SIOCGIFCONF; - strioctl.ic_dp = buff; - strioctl.ic_len = sizeof(buff); - if (ioctl(fd, I_STR, &strioctl) < 0) { - close(fd); - return -1; - } - - /* we can ignore the possible sizeof(int) here as the resulting - number of interface structures won't change */ - n = strioctl.ic_len / sizeof(struct ifreq); - - /* we will assume that the kernel returns the length as an int - at the start of the buffer if the offered size is a - multiple of the structure size plus an int */ - if (n*sizeof(struct ifreq) + sizeof(int) == strioctl.ic_len) { - ifr = (struct ifreq *)(buff + sizeof(int)); - } else { - ifr = (struct ifreq *)buff; - } - - /* Loop through interfaces */ - - for (i = 0; i<n && total < max_interfaces; i++) { - - memset(&ifaces[total], '\0', sizeof(ifaces[total])); - - ifreq = ifr[i]; - - strioctl.ic_cmd = SIOCGIFFLAGS; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - continue; - } - - ifaces[total].flags = ifreq.ifr_flags; - - if (!(ifaces[total].flags & IFF_UP)) { - continue; - } - - strioctl.ic_cmd = SIOCGIFADDR; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - continue; - } - - strlcpy(ifaces[total].name, - ifreq.ifr_name, - sizeof(ifaces[total].name)); - - memcpy(&ifaces[total].ip, &ifreq.ifr_addr, - sizeof(struct sockaddr_in)); - - strioctl.ic_cmd = SIOCGIFNETMASK; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - continue; - } - - memcpy(&ifaces[total].netmask, &ifreq.ifr_addr, - sizeof(struct sockaddr_in)); - - if (ifaces[total].flags & IFF_BROADCAST) { - strioctl.ic_cmd = SIOCGIFBRDADDR; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - continue; - } - memcpy(&ifaces[total].bcast, &ifreq.ifr_broadaddr, - sizeof(struct sockaddr_in)); - } else if (ifaces[total].flags & IFF_POINTOPOINT) { - strioctl.ic_cmd = SIOCGIFDSTADDR; - strioctl.ic_dp = (char *)&ifreq; - strioctl.ic_len = sizeof(struct ifreq); - if (ioctl(fd, I_STR, &strioctl) != 0) { - continue; - } - memcpy(&ifaces[total].bcast, &ifreq.ifr_dstaddr, - sizeof(struct sockaddr_in)); - } else { - continue; - } - - total++; - } - - close(fd); - - return total; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_IFREQ */ -#ifdef HAVE_IFACE_AIX - -/**************************************************************************** - This one is for AIX (tested on 4.2). -****************************************************************************/ - -static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) -{ - char buff[8192]; - int fd, i; - struct ifconf ifc; - struct ifreq *ifr=NULL; - int total = 0; - - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - return -1; - } - - - ifc.ifc_len = sizeof(buff); - ifc.ifc_buf = buff; - - if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { - close(fd); - return -1; - } - - ifr = ifc.ifc_req; - - /* Loop through interfaces */ - i = ifc.ifc_len; - - while (i > 0 && total < max_interfaces) { - uint_t inc; - - memset(&ifaces[total], '\0', sizeof(ifaces[total])); - - inc = ifr->ifr_addr.sa_len; - - if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) { - goto next; - } - - ifaces[total].flags = ifr->ifr_flags; - - if (!(ifaces[total].flags & IFF_UP)) { - goto next; - } - - if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { - goto next; - } - - memcpy(&ifaces[total].ip, &ifr->ifr_addr, - sizeof(struct sockaddr_in)); - - strlcpy(ifaces[total].name, ifr->ifr_name, - sizeof(ifaces[total].name)); - - if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { - goto next; - } - - memcpy(&ifaces[total].netmask, &ifr->ifr_addr, - sizeof(struct sockaddr_in)); - - if (ifaces[total].flags & IFF_BROADCAST) { - if (ioctl(fd, SIOCGIFBRDADDR, ifr) != 0) { - goto next; - } - memcpy(&ifaces[total].bcast, &ifr->ifr_broadaddr, - sizeof(struct sockaddr_in)); - } else if (ifaces[total].flags & IFF_POINTOPOINT) { - if (ioctl(fd, SIOCGIFDSTADDR, ifr) != 0) { - goto next; - } - memcpy(&ifaces[total].bcast, &ifr->ifr_dstaddr, - sizeof(struct sockaddr_in)); - } else { - goto next; - } - - - total++; - - next: - /* - * Patch from Archie Cobbs (archie@whistle.com). The - * addresses in the SIOCGIFCONF interface list have a - * minimum size. Usually this doesn't matter, but if - * your machine has tunnel interfaces, etc. that have - * a zero length "link address", this does matter. */ - - if (inc < sizeof(ifr->ifr_addr)) - inc = sizeof(ifr->ifr_addr); - inc += IFNAMSIZ; - - ifr = (struct ifreq*) (((char*) ifr) + inc); - i -= inc; - } - - close(fd); - return total; -} - -#define _FOUND_IFACE_ANY -#endif /* HAVE_IFACE_AIX */ -#ifndef _FOUND_IFACE_ANY -static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces) -{ - return -1; -} -#endif - - static int iface_comp(struct iface_struct *i1, struct iface_struct *i2) { int r; @@ -693,55 +349,3 @@ int get_interfaces(struct iface_struct *ifaces, int max_interfaces) return total; } - -#ifdef AUTOCONF_TEST -/* this is the autoconf driver to test get_interfaces() */ - -static socklen_t calc_sa_size(struct sockaddr *psa) -{ - socklen_t sl = sizeof(struct sockaddr_in); -#if defined(HAVE_IPV6) - if (psa->sa_family == AF_INET6) { - sl = sizeof(struct sockaddr_in6); - } -#endif - return sl; -} - - int main() -{ - struct iface_struct ifaces[MAX_INTERFACES]; - int total = get_interfaces(ifaces, MAX_INTERFACES); - int i; - - printf("got %d interfaces:\n", total); - if (total <= 0) { - exit(1); - } - - for (i=0;i<total;i++) { - char addr[INET6_ADDRSTRLEN]; - int ret; - printf("%-10s ", ifaces[i].name); - addr[0] = '\0'; - ret = getnameinfo((struct sockaddr *)&ifaces[i].ip, - calc_sa_size(&ifaces[i].ip), - addr, sizeof(addr), - NULL, 0, NI_NUMERICHOST); - printf("IP=%s ", addr); - addr[0] = '\0'; - ret = getnameinfo((struct sockaddr *)&ifaces[i].netmask, - calc_sa_size(&ifaces[i].netmask), - addr, sizeof(addr), - NULL, 0, NI_NUMERICHOST); - printf("NETMASK=%s ", addr); - addr[0] = '\0'; - ret = getnameinfo((struct sockaddr *)&ifaces[i].bcast, - calc_sa_size(&ifaces[i].bcast), - addr, sizeof(addr), - NULL, 0, NI_NUMERICHOST); - printf("BCAST=%s\n", addr); - } - return 0; -} -#endif diff --git a/source3/lib/netapi/examples/Makefile.in b/source3/lib/netapi/examples/Makefile.in index 86e1b1bc2f..000eef118b 100644 --- a/source3/lib/netapi/examples/Makefile.in +++ b/source3/lib/netapi/examples/Makefile.in @@ -3,10 +3,11 @@ GTK_LIBS=`pkg-config gtk+-2.0 --libs` KRB5LIBS=@KRB5_LIBS@ LDAP_LIBS=@LDAP_LIBS@ -LIBS=@LIBS@ -lnetapi +LIBS=@LIBS@ -lnetapi -ltdb -ltalloc DEVELOPER_CFLAGS=@DEVELOPER_CFLAGS@ FLAGS=-I../ -L../../../bin @CFLAGS@ $(GTK_FLAGS) CC=@CC@ +PICFLAG=@PICFLAG@ LDFLAGS=@PIE_LDFLAGS@ @LDFLAGS@ DYNEXP=@DYNEXP@ @@ -14,7 +15,12 @@ DYNEXP=@DYNEXP@ COMPILE_CC = $(CC) -I. $(FLAGS) $(PICFLAG) -c $< -o $@ COMPILE = $(COMPILE_CC) -BINARY_PREREQS = proto_exists bin/.dummy +PROGS = bin/getdc@EXEEXT@ \ + bin/netdomjoin@EXEEXT@ \ + bin/netdomjoin-gui@EXEEXT@ \ + bin/getjoinableous@EXEEXT@ + +all: $(PROGS) MAKEDIR = || exec false; \ if test -d "$$dir"; then :; else \ @@ -24,6 +30,13 @@ MAKEDIR = || exec false; \ mkdir "$$dir" || \ exec false; fi || exec false +BINARY_PREREQS = bin/.dummy + +bin/.dummy: + @if (: >> $@ || : > $@) >/dev/null 2>&1; then :; else \ + dir=bin $(MAKEDIR); fi + @: >> $@ || : > $@ # what a fancy emoticon! + .c.o: @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi @@ -38,30 +51,23 @@ NETDOMJOIN_OBJ = netdomjoin/netdomjoin.o NETDOMJOIN_GUI_OBJ = netdomjoin-gui/netdomjoin-gui.o GETJOINABLEOUS_OBJ = getjoinableous/getjoinableous.o -PROGS = bin/getdc@EXEEXT@ \ - bin/netdomjoin@EXEEXT@ \ - bin/netdomjoin-gui@EXEEXT@ \ - bin/getjoinableous@EXEEXT@ - -all: $(PROGS) - -bin/getdc@EXEEXT@: $(GETDC_OBJ) +bin/getdc@EXEEXT@: $(BINARY_PREREQS) $(GETDC_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(GETDC_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) -bin/getjoinableous@EXEEXT@: $(GETJOINABLEOUS_OBJ) +bin/getjoinableous@EXEEXT@: $(BINARY_PREREQS) $(GETJOINABLEOUS_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(GETJOINABLEOUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) -bin/netdomjoin@EXEEXT@: $(NETDOMJOIN_OBJ) +bin/netdomjoin@EXEEXT@: $(BINARY_PREREQS) $(NETDOMJOIN_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(NETDOMJOIN_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) -bin/netdomjoin-gui@EXEEXT@: $(NETDOMJOIN_GUI_OBJ) +bin/netdomjoin-gui@EXEEXT@: $(BINARY_PREREQS) $(NETDOMJOIN_GUI_OBJ) @echo Linking $@ @$(CC) $(FLAGS) $(GTK_FLAGS) -o $@ $(NETDOMJOIN_GUI_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(GTK_LIBS) clean: -rm -f $(PROGS) -rm -f core */*~ *~ \ - */*.o */*/*.o */*/*/*.o \ + */*.o */*/*.o */*/*/*.o diff --git a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c index 73b14d4d87..a3719c7442 100644 --- a/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c +++ b/source3/lib/netapi/examples/netdomjoin-gui/netdomjoin-gui.c @@ -154,7 +154,7 @@ static void callback_apply_description_change(GtkWidget *widget, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Failed to change computer description: %s.", - libnetapi_errstr(status)); + libnetapi_get_error_string(state->ctx, status)); g_signal_connect_swapped(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog); diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 55f334b5e1..405f96a87e 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -48,7 +48,7 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, if (join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { NTSTATUS status; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | DS_WRITABLE_REQUIRED | DS_RETURN_DNS_NAME; @@ -60,7 +60,7 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx, return ntstatus_to_werror(status); } r->in.dc_name = talloc_strdup(mem_ctx, - info->domain_controller_name); + info->dc_unc); W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); } @@ -252,7 +252,7 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, } else { NTSTATUS status; const char *domain = NULL; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | DS_WRITABLE_REQUIRED | DS_RETURN_DNS_NAME; @@ -269,7 +269,7 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx, return ntstatus_to_werror(status); } r->in.dc_name = talloc_strdup(mem_ctx, - info->domain_controller_name); + info->dc_unc); W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); } @@ -562,7 +562,7 @@ static WERROR NetGetJoinableOUsLocal(struct libnetapi_ctx *ctx, NTSTATUS status; ADS_STATUS ads_status; ADS_STRUCT *ads = NULL; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | DS_RETURN_DNS_NAME; @@ -574,7 +574,7 @@ static WERROR NetGetJoinableOUsLocal(struct libnetapi_ctx *ctx, return ntstatus_to_werror(status); } - ads = ads_init(domain, domain, info->domain_controller_name); + ads = ads_init(domain, domain, info->dc_unc); if (!ads) { return WERR_GENERAL_FAILURE; } diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 47b3ba93cf..fb091f6e0b 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -50,7 +50,9 @@ NET_API_STATUS libnetapi_init(struct libnetapi_ctx **context) return W_ERROR_V(WERR_NOMEM); } - DEBUGLEVEL = 0; + if (!DEBUGLEVEL) { + DEBUGLEVEL = 0; + } setup_logging("libnetapi", true); dbf = x_stderr; diff --git a/source3/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index 7fa166e411..d30e7d97f7 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -185,6 +185,9 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx, } if (!lp_config_backend_is_registry()) { + libnetapi_set_error_string(ctx, + "Configuration manipulation requested but not " + "supported by backend"); return WERR_NOT_SUPPORTED; } @@ -268,7 +271,7 @@ static WERROR NetServerSetInfoRemote(struct libnetapi_ctx *ctx, status = rpccli_srvsvc_NetSrvSetInfo(pipe_cli, ctx, server_name, level, - info, + &info, parm_error, &werr); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/lib/privileges_basic.c b/source3/lib/privileges_basic.c index 753f7265a1..865c1f655c 100644 --- a/source3/lib/privileges_basic.c +++ b/source3/lib/privileges_basic.c @@ -473,7 +473,7 @@ bool se_priv_to_privilege_set( PRIVILEGE_SET *set, SE_PRIV *mask ) /******************************************************************* *******************************************************************/ -static bool luid_to_se_priv( LUID *luid, SE_PRIV *mask ) +static bool luid_to_se_priv( struct lsa_LUID *luid, SE_PRIV *mask ) { int i; uint32 num_privs = count_all_privileges(); @@ -491,7 +491,7 @@ static bool luid_to_se_priv( LUID *luid, SE_PRIV *mask ) /******************************************************************* *******************************************************************/ -bool privilege_set_to_se_priv( SE_PRIV *mask, PRIVILEGE_SET *privset ) +bool privilege_set_to_se_priv( SE_PRIV *mask, struct lsa_PrivilegeSet *privset ) { int i; diff --git a/source3/lib/repdir.c b/source3/lib/repdir.c deleted file mode 100644 index 08f7d16a81..0000000000 --- a/source3/lib/repdir.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Andrew Tridgell 2005 - Updated for Samba3 64-bit cleanliness (C) Jeremy Allison 2006 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -/* - a replacement for opendir/readdir/telldir/seekdir/closedir for BSD systems - - This is needed because the existing directory handling in FreeBSD - and OpenBSD (and possibly NetBSD) doesn't correctly handle unlink() - on files in a directory where telldir() has been used. On a block - boundary it will occasionally miss a file when seekdir() is used to - return to a position previously recorded with telldir(). - - This also fixes a severe performance and memory usage problem with - telldir() on BSD systems. Each call to telldir() in BSD adds an - entry to a linked list, and those entries are cleaned up on - closedir(). This means with a large directory closedir() can take an - arbitrary amount of time, causing network timeouts as millions of - telldir() entries are freed - - Note! This replacement code is not portable. It relies on getdents() - always leaving the file descriptor at a seek offset that is a - multiple of DIR_BUF_SIZE. If the code detects that this doesn't - happen then it will abort(). It also does not handle directories - with offsets larger than can be stored in a long, - - This code is available under other free software licenses as - well. Contact the author. -*/ - -#include <include/includes.h> - - void replace_readdir_dummy(void); - void replace_readdir_dummy(void) {} - -#if defined(REPLACE_READDIR) - -#if defined(PARANOID_MALLOC_CHECKER) -#ifdef malloc -#undef malloc -#endif -#endif - -#define DIR_BUF_BITS 9 -#define DIR_BUF_SIZE (1<<DIR_BUF_BITS) - -struct dir_buf { - int fd; - int nbytes, ofs; - SMB_OFF_T seekpos; - char buf[DIR_BUF_SIZE]; -}; - -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64) - SMB_STRUCT_DIR *opendir64(const char *dname) -#else - SMB_STRUCT_DIR *opendir(const char *dname) -#endif -{ - struct dir_buf *d; - d = malloc(sizeof(*d)); - if (d == NULL) { - errno = ENOMEM; - return NULL; - } -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64) - d->fd = open64(dname, O_RDONLY); -#else - d->fd = open(dname, O_RDONLY); -#endif - - if (d->fd == -1) { - free(d); - return NULL; - } - d->ofs = 0; - d->seekpos = 0; - d->nbytes = 0; - return (SMB_STRUCT_DIR *)d; -} - -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64) - SMB_STRUCT_DIRENT *readdir64(SMB_STRUCT_DIR *dir) -#else - SMB_STRUCT_DIRENT *readdir(SMB_STRUCT_DIR *dir) -#endif -{ - struct dir_buf *d = (struct dir_buf *)dir; - SMB_STRUCT_DIRENT *de; - - if (d->ofs >= d->nbytes) { -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_LSEEK64) - d->seekpos = lseek64(d->fd, 0, SEEK_CUR); -#else - d->seekpos = lseek(d->fd, 0, SEEK_CUR); -#endif - -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_GETDENTS64) - d->nbytes = getdents64(d->fd, d->buf, DIR_BUF_SIZE); -#else - d->nbytes = getdents(d->fd, d->buf, DIR_BUF_SIZE); -#endif - d->ofs = 0; - } - if (d->ofs >= d->nbytes) { - return NULL; - } - de = (SMB_STRUCT_DIRENT *)&d->buf[d->ofs]; - d->ofs += de->d_reclen; - return de; -} - -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64) - long telldir64(SMB_STRUCT_DIR *dir) -#else - long telldir(SMB_STRUCT_DIR *dir) -#endif -{ - struct dir_buf *d = (struct dir_buf *)dir; - if (d->ofs >= d->nbytes) { -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_LSEEK64) - d->seekpos = lseek64(d->fd, 0, SEEK_CUR); -#else - d->seekpos = lseek(d->fd, 0, SEEK_CUR); -#endif - d->ofs = 0; - d->nbytes = 0; - } - /* this relies on seekpos always being a multiple of - DIR_BUF_SIZE. Is that always true on BSD systems? */ - if (d->seekpos & (DIR_BUF_SIZE-1)) { - abort(); - } - return d->seekpos + d->ofs; -} - -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64) - void seekdir64(SMB_STRUCT_DIR *dir, long ofs) -#else - void seekdir(SMB_STRUCT_DIR *dir, long ofs) -#endif -{ - struct dir_buf *d = (struct dir_buf *)dir; -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_LSEEK64) - d->seekpos = lseek64(d->fd, ofs & ~(DIR_BUF_SIZE-1), SEEK_SET); -#else - d->seekpos = lseek(d->fd, ofs & ~(DIR_BUF_SIZE-1), SEEK_SET); -#endif - -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_GETDENTS64) - d->nbytes = getdents64(d->fd, d->buf, DIR_BUF_SIZE); -#else - d->nbytes = getdents(d->fd, d->buf, DIR_BUF_SIZE); -#endif - - d->ofs = 0; - while (d->ofs < (ofs & (DIR_BUF_SIZE-1))) { -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64) - if (readdir64(dir) == NULL) break; -#else - if (readdir(dir) == NULL) break; -#endif - } -} - -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64) - void rewinddir64(SMB_STRUCT_DIR *dir) -#else - void rewinddir(SMB_STRUCT_DIR *dir) -#endif -{ -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64) - seekdir64(dir, 0); -#else - seekdir(dir, 0); -#endif -} - -#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64) - int closedir64(SMB_STRUCT_DIR *dir) -#else - int closedir(SMB_STRUCT_DIR *dir) -#endif -{ - struct dir_buf *d = (struct dir_buf *)dir; - int r = close(d->fd); - if (r != 0) { - return r; - } - free(d); - return 0; -} - -#ifndef dirfd -/* darn, this is a macro on some systems. */ - int dirfd(SMB_STRUCT_DIR *dir) -{ - struct dir_buf *d = (struct dir_buf *)dir; - return d->fd; -} -#endif -#endif /* REPLACE_READDIR */ diff --git a/source3/lib/replace/Makefile.in b/source3/lib/replace/Makefile.in index 30f39ac6cb..c989835a8d 100644 --- a/source3/lib/replace/Makefile.in +++ b/source3/lib/replace/Makefile.in @@ -10,6 +10,7 @@ VPATH = @libreplacedir@ srcdir = @srcdir@ builddir = @builddir@ INSTALL = @INSTALL@ +LIBS = @LIBS@ .PHONY: test all showflags install installcheck clean distclean realdistclean @@ -25,6 +26,7 @@ showflags: @echo ' CC = $(CC)' @echo ' CFLAGS = $(CFLAGS)' @echo ' LDFLAGS= $(LDFLAGS)' + @echo ' LIBS = $(LIBS)' install: all mkdir -p $(libdir) @@ -38,10 +40,10 @@ test: all installcheck: install test -TEST_OBJS = test/testsuite.o test/os2_delete.o test/strptime.o +TEST_OBJS = test/testsuite.o test/os2_delete.o test/strptime.o test/getifaddrs.o testsuite: libreplace.a $(TEST_OBJS) - $(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS) + $(CC) -o testsuite $(TEST_OBJS) -L. -lreplace $(LDFLAGS) $(LIBS) .c.o: @echo Compiling $*.c diff --git a/source3/lib/replace/README b/source3/lib/replace/README index c61f78a951..268a1b15cf 100644 --- a/source3/lib/replace/README +++ b/source3/lib/replace/README @@ -60,6 +60,8 @@ getaddrinfo freeaddrinfo getnameinfo gai_strerror +getifaddrs +freeifaddrs Types: bool diff --git a/source3/lib/replace/configure.ac b/source3/lib/replace/configure.ac index beeb77e152..f5e054f476 100644 --- a/source3/lib/replace/configure.ac +++ b/source3/lib/replace/configure.ac @@ -3,6 +3,8 @@ AC_INIT(replace.c) AC_CONFIG_SRCDIR([replace.c]) AC_CONFIG_HEADER(config.h) +CFLAGS="$CFLAGS -I$srcdir" + AC_LIBREPLACE_ALL_CHECKS if test "$ac_cv_prog_gcc" = yes; then diff --git a/source3/lib/replace/dlfcn.c b/source3/lib/replace/dlfcn.c index 42848848e8..3b109d7e40 100644 --- a/source3/lib/replace/dlfcn.c +++ b/source3/lib/replace/dlfcn.c @@ -35,6 +35,8 @@ void *rep_dlopen(const char *name, int flags) #endif { #ifdef HAVE_SHL_LOAD + if (name == NULL) + return PROG_HANDLE; return (void *)shl_load(name, flags, 0); #else return NULL; diff --git a/source3/lib/replace/getifaddrs.c b/source3/lib/replace/getifaddrs.c new file mode 100644 index 0000000000..f6f0ec080c --- /dev/null +++ b/source3/lib/replace/getifaddrs.c @@ -0,0 +1,361 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Jeremy Allison 2007 + Copyright (C) Jelmer Vernooij <jelmer@samba.org> 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/>. +*/ + +#define SOCKET_WRAPPER_NOT_REPLACE + +#include "replace.h" +#include "system/network.h" + +#include <unistd.h> +#include <stdio.h> +#include <sys/types.h> + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif + +#ifndef SIOCGIFCONF +#ifdef HAVE_SYS_SOCKIO_H +#include <sys/sockio.h> +#endif +#endif + +#ifdef HAVE_IFACE_GETIFADDRS +#define _FOUND_IFACE_ANY +#else + +void rep_freeifaddrs(struct ifaddrs *ifp) +{ + if (ifp != NULL) { + free(ifp->ifa_name); + free(ifp->ifa_addr); + free(ifp->ifa_netmask); + free(ifp->ifa_dstaddr); + freeifaddrs(ifp->ifa_next); + free(ifp); + } +} + +static struct sockaddr *sockaddr_dup(struct sockaddr *sa) +{ + struct sockaddr *ret; + socklen_t socklen; +#ifdef HAVE_SOCKADDR_SA_LEN + socklen = sa->sa_len; +#else + socklen = sizeof(struct sockaddr_storage); +#endif + ret = calloc(1, socklen); + if (ret == NULL) + return NULL; + memcpy(ret, sa, socklen); + return ret; +} +#endif + +#if HAVE_IFACE_IFCONF + +/* this works for Linux 2.2, Solaris 2.5, SunOS4, HPUX 10.20, OSF1 + V4.0, Ultrix 4.4, SCO Unix 3.2, IRIX 6.4 and FreeBSD 3.2. + + It probably also works on any BSD style system. */ + +int rep_getifaddrs(struct ifaddrs **ifap) +{ + struct ifconf ifc; + char buff[8192]; + int fd, i, n; + struct ifreq *ifr=NULL; + struct in_addr ipaddr; + struct in_addr nmask; + char *iname; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; + + *ifap = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + + ifc.ifc_len = sizeof(buff); + ifc.ifc_buf = buff; + + if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { + close(fd); + return -1; + } + + ifr = ifc.ifc_req; + + n = ifc.ifc_len / sizeof(struct ifreq); + + /* Loop through interfaces, looking for given IP address */ + for (i=n-1; i>=0; i--) { + if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) == -1) { + freeifaddrs(*ifap); + return -1; + } + + curif = calloc(1, sizeof(struct ifaddrs)); + curif->ifa_name = strdup(ifr[i].ifr_name); + curif->ifa_flags = ifr[i].ifr_flags; + curif->ifa_dstaddr = NULL; + curif->ifa_data = NULL; + curif->ifa_next = NULL; + + curif->ifa_addr = NULL; + if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != -1) { + curif->ifa_addr = sockaddr_dup(&ifr[i].ifr_addr); + } + + curif->ifa_netmask = NULL; + if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != -1) { + curif->ifa_netmask = sockaddr_dup(&ifr[i].ifr_addr); + } + + if (lastif == NULL) { + *ifap = curif; + } else { + lastif->ifa_next = curif; + } + lastif = curif; + } + + close(fd); + + return 0; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_IFCONF */ +#ifdef HAVE_IFACE_IFREQ + +#ifndef I_STR +#include <sys/stropts.h> +#endif + +/**************************************************************************** +this should cover most of the streams based systems +Thanks to Andrej.Borsenkow@mow.siemens.ru for several ideas in this code +****************************************************************************/ +int rep_getifaddrs(struct ifaddrs **ifap) +{ + struct ifreq ifreq; + struct strioctl strioctl; + char buff[8192]; + int fd, i, n; + struct ifreq *ifr=NULL; + struct in_addr ipaddr; + struct in_addr nmask; + char *iname; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; + + *ifap = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + + strioctl.ic_cmd = SIOCGIFCONF; + strioctl.ic_dp = buff; + strioctl.ic_len = sizeof(buff); + if (ioctl(fd, I_STR, &strioctl) < 0) { + close(fd); + return -1; + } + + /* we can ignore the possible sizeof(int) here as the resulting + number of interface structures won't change */ + n = strioctl.ic_len / sizeof(struct ifreq); + + /* we will assume that the kernel returns the length as an int + at the start of the buffer if the offered size is a + multiple of the structure size plus an int */ + if (n*sizeof(struct ifreq) + sizeof(int) == strioctl.ic_len) { + ifr = (struct ifreq *)(buff + sizeof(int)); + } else { + ifr = (struct ifreq *)buff; + } + + /* Loop through interfaces */ + + for (i = 0; i<n; i++) { + ifreq = ifr[i]; + + curif = calloc(1, sizeof(struct ifaddrs)); + if (lastif == NULL) { + *ifap = curif; + } else { + lastif->ifa_next = curif; + } + + strioctl.ic_cmd = SIOCGIFFLAGS; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(fd, I_STR, &strioctl) != 0) { + freeifaddrs(*ifap); + return -1; + } + + curif->ifa_flags = ifreq.ifr_flags; + + strioctl.ic_cmd = SIOCGIFADDR; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(fd, I_STR, &strioctl) != 0) { + freeifaddrs(*ifap); + return -1; + } + + curif->ifa_name = strdup(ifreq.ifr_name); + curif->ifa_addr = sockaddr_dup(&ifreq.ifr_addr); + curif->ifa_dstaddr = NULL; + curif->ifa_data = NULL; + curif->ifa_next = NULL; + curif->ifa_netmask = NULL; + + strioctl.ic_cmd = SIOCGIFNETMASK; + strioctl.ic_dp = (char *)&ifreq; + strioctl.ic_len = sizeof(struct ifreq); + if (ioctl(fd, I_STR, &strioctl) != 0) { + freeifaddrs(*ifap); + return -1; + } + + curif->ifa_netmask = sockaddr_dup(&ifreq.ifr_addr); + + lastif = curif; + } + + close(fd); + + return 0; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_IFREQ */ +#ifdef HAVE_IFACE_AIX + +/**************************************************************************** +this one is for AIX (tested on 4.2) +****************************************************************************/ +int rep_getifaddrs(struct ifaddrs **ifap) +{ + char buff[8192]; + int fd, i; + struct ifconf ifc; + struct ifreq *ifr=NULL; + struct in_addr ipaddr; + struct in_addr nmask; + char *iname; + struct ifaddrs *curif; + struct ifaddrs *lastif = NULL; + + *ifap = NULL; + + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + return -1; + } + + ifc.ifc_len = sizeof(buff); + ifc.ifc_buf = buff; + + if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) { + close(fd); + return -1; + } + + ifr = ifc.ifc_req; + + /* Loop through interfaces */ + i = ifc.ifc_len; + + while (i > 0) { + uint_t inc; + + inc = ifr->ifr_addr.sa_len; + + if (ioctl(fd, SIOCGIFADDR, ifr) != 0) { + freeaddrinfo(*ifap); + return -1; + } + + curif = calloc(1, sizeof(struct ifaddrs)); + if (lastif == NULL) { + *ifap = curif; + } else { + lastif->ifa_next = curif; + } + + curif->ifa_name = strdup(ifr->ifr_name); + curif->ifa_addr = sockaddr_dup(&ifr->ifr_addr); + curif->ifa_dstaddr = NULL; + curif->ifa_data = NULL; + curif->ifa_netmask = NULL; + curif->ifa_next = NULL; + + if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) { + freeaddrinfo(*ifap); + return -1; + } + + curif->ifa_flags = ifr->ifr_flags; + + if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) { + freeaddrinfo(*ifap); + return -1; + } + + curif->ifa_netmask = sockaddr_dup(&ifr->ifr_addr); + + lastif = curif; + + next: + /* + * Patch from Archie Cobbs (archie@whistle.com). The + * addresses in the SIOCGIFCONF interface list have a + * minimum size. Usually this doesn't matter, but if + * your machine has tunnel interfaces, etc. that have + * a zero length "link address", this does matter. */ + + if (inc < sizeof(ifr->ifr_addr)) + inc = sizeof(ifr->ifr_addr); + inc += IFNAMSIZ; + + ifr = (struct ifreq*) (((char*) ifr) + inc); + i -= inc; + } + + close(fd); + return 0; +} + +#define _FOUND_IFACE_ANY +#endif /* HAVE_IFACE_AIX */ +#ifndef _FOUND_IFACE_ANY +int rep_getifaddrs(struct ifaddrs **ifap) +{ + errno = ENOSYS; + return -1; +} +#endif diff --git a/source3/lib/replace/getifaddrs.m4 b/source3/lib/replace/getifaddrs.m4 new file mode 100644 index 0000000000..6cca155de3 --- /dev/null +++ b/source3/lib/replace/getifaddrs.m4 @@ -0,0 +1,127 @@ +AC_CHECK_HEADERS([ifaddrs.h]) + +dnl Used when getifaddrs is not available +AC_CHECK_MEMBERS([struct sockaddr.sa_len], + [AC_DEFINE(HAVE_SOCKADDR_SA_LEN, 1, [Whether struct sockaddr has a sa_len member])], + [], + [#include <sys/socket.h>]) + +dnl test for getifaddrs and freeifaddrs +AC_CACHE_CHECK([for getifaddrs and freeifaddrs],libreplace_cv_HAVE_GETIFADDRS,[ +AC_TRY_COMPILE([ +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ifaddrs.h> +#include <netdb.h>], +[ +struct ifaddrs *ifp = NULL; +int ret = getifaddrs (&ifp); +freeifaddrs(ifp); +], +libreplace_cv_HAVE_GETIFADDRS=yes,libreplace_cv_HAVE_GETIFADDRS=no)]) +if test x"$libreplace_cv_HAVE_GETIFADDRS" = x"yes"; then + AC_DEFINE(HAVE_GETIFADDRS,1,[Whether the system has getifaddrs]) + AC_DEFINE(HAVE_FREEIFADDRS,1,[Whether the system has freeifaddrs]) + AC_DEFINE(HAVE_STRUCT_IFADDRS,1,[Whether struct ifaddrs is available]) +fi + +################## +# look for a method of finding the list of network interfaces +# +# This tests need LIBS="$NSL_LIBS $SOCKET_LIBS" +# +old_LIBS=$LIBS +LIBS="$NSL_LIBS $SOCKET_LIBS" +iface=no; +################## +# look for a method of finding the list of network interfaces +iface=no; +AC_CACHE_CHECK([for iface getifaddrs],libreplace_cv_HAVE_IFACE_GETIFADDRS,[ +AC_TRY_RUN([ +#define HAVE_IFACE_GETIFADDRS 1 +#define NO_CONFIG_H 1 +#define AUTOCONF_TEST 1 +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" +#include "$libreplacedir/inet_ntop.c" +#include "$libreplacedir/snprintf.c" +#include "$libreplacedir/getifaddrs.c" +#define getifaddrs_test main +#include "$libreplacedir/test/getifaddrs.c"], + libreplace_cv_HAVE_IFACE_GETIFADDRS=yes,libreplace_cv_HAVE_IFACE_GETIFADDRS=no,libreplace_cv_HAVE_IFACE_GETIFADDRS=cross)]) +if test x"$libreplace_cv_HAVE_IFACE_GETIFADDRS" = x"yes"; then + iface=yes;AC_DEFINE(HAVE_IFACE_GETIFADDRS,1,[Whether iface getifaddrs is available]) +else + LIBREPLACEOBJ="${LIBREPLACEOBJ} getifaddrs.o" +fi + + +if test $iface = no; then +AC_CACHE_CHECK([for iface AIX],libreplace_cv_HAVE_IFACE_AIX,[ +AC_TRY_RUN([ +#define HAVE_IFACE_AIX 1 +#define NO_CONFIG_H 1 +#define AUTOCONF_TEST 1 +#undef _XOPEN_SOURCE_EXTENDED +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" +#include "$libreplacedir/inet_ntop.c" +#include "$libreplacedir/snprintf.c" +#include "$libreplacedir/getifaddrs.c" +#define getifaddrs_test main +#include "$libreplacedir/test/getifaddrs.c"], + libreplace_cv_HAVE_IFACE_AIX=yes,libreplace_cv_HAVE_IFACE_AIX=no,libreplace_cv_HAVE_IFACE_AIX=cross)]) +if test x"$libreplace_cv_HAVE_IFACE_AIX" = x"yes"; then + iface=yes;AC_DEFINE(HAVE_IFACE_AIX,1,[Whether iface AIX is available]) + old_LIBS="$old_LIBS $LIBS" +fi +fi + + +if test $iface = no; then +AC_CACHE_CHECK([for iface ifconf],libreplace_cv_HAVE_IFACE_IFCONF,[ +AC_TRY_RUN([ +#define HAVE_IFACE_IFCONF 1 +#define NO_CONFIG_H 1 +#define AUTOCONF_TEST 1 +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" +#include "$libreplacedir/inet_ntop.c" +#include "$libreplacedir/snprintf.c" +#include "$libreplacedir/getifaddrs.c" +#define getifaddrs_test main +#include "$libreplacedir/test/getifaddrs.c"], + libreplace_cv_HAVE_IFACE_IFCONF=yes,libreplace_cv_HAVE_IFACE_IFCONF=no,libreplace_cv_HAVE_IFACE_IFCONF=cross)]) +if test x"$libreplace_cv_HAVE_IFACE_IFCONF" = x"yes"; then + iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF,1,[Whether iface ifconf is available]) + old_LIBS="$old_LIBS $LIBS" +fi +fi + +if test $iface = no; then +AC_CACHE_CHECK([for iface ifreq],libreplace_cv_HAVE_IFACE_IFREQ,[ +AC_TRY_RUN([ +#define HAVE_IFACE_IFREQ 1 +#define NO_CONFIG_H 1 +#define AUTOCONF_TEST 1 +#define SOCKET_WRAPPER_NOT_REPLACE +#include "$libreplacedir/replace.c" +#include "$libreplacedir/inet_ntop.c" +#include "$libreplacedir/snprintf.c" +#include "$libreplacedir/getifaddrs.c" +#define getifaddrs_test main +#include "$libreplacedir/test/getifaddrs.c"], + libreplace_cv_HAVE_IFACE_IFREQ=yes,libreplace_cv_HAVE_IFACE_IFREQ=no,libreplace_cv_HAVE_IFACE_IFREQ=cross)]) +if test x"$libreplace_cv_HAVE_IFACE_IFREQ" = x"yes"; then + iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ,1,[Whether iface ifreq is available]) + old_LIBS="$old_LIBS $LIBS" +fi +fi + +LIBS=$old_LIBS diff --git a/source3/lib/replace/getpass.c b/source3/lib/replace/getpass.c index d91d029f6a..57e28eb981 100644 --- a/source3/lib/replace/getpass.c +++ b/source3/lib/replace/getpass.c @@ -185,7 +185,10 @@ char *rep_getpass(const char *prompt) buf[0] = 0; if (!gotintr) { in_fd = fileno(in); - fgets(buf, bufsize, in); + if (fgets(buf, bufsize, in) == NULL) { + buf[0] = 0; + return buf; + } } nread = strlen(buf); if (nread) { diff --git a/source3/lib/replace/getpass.m4 b/source3/lib/replace/getpass.m4 index c4da9aae59..b93817f9d3 100644 --- a/source3/lib/replace/getpass.m4 +++ b/source3/lib/replace/getpass.m4 @@ -1,22 +1,22 @@ -AC_CHECK_FUNC(getpass, samba_cv_HAVE_GETPASS=yes) -AC_CHECK_FUNC(getpassphrase, samba_cv_HAVE_GETPASSPHRASE=yes) -if test x"$samba_cv_HAVE_GETPASS" = x"yes" -a x"$samba_cv_HAVE_GETPASSPHRASE" = x"yes"; then +AC_CHECK_FUNC(getpass, libreplace_cv_HAVE_GETPASS=yes) +AC_CHECK_FUNC(getpassphrase, libreplace_cv_HAVE_GETPASSPHRASE=yes) +if test x"$libreplace_cv_HAVE_GETPASS" = x"yes" -a x"$libreplace_cv_HAVE_GETPASSPHRASE" = x"yes"; then AC_DEFINE(REPLACE_GETPASS_BY_GETPASSPHRASE, 1, [getpass returns <9 chars where getpassphrase returns <265 chars]) AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o" else -AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[ +AC_CACHE_CHECK([whether getpass should be replaced],libreplace_cv_REPLACE_GETPASS,[ SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I$libreplacedir/" AC_TRY_COMPILE([ #include "confdefs.h" #define NO_CONFIG_H #include "$libreplacedir/getpass.c" -],[],samba_cv_REPLACE_GETPASS=yes,samba_cv_REPLACE_GETPASS=no) +],[],libreplace_cv_REPLACE_GETPASS=yes,libreplace_cv_REPLACE_GETPASS=no) CPPFLAGS="$SAVE_CPPFLAGS" ]) -if test x"$samba_cv_REPLACE_GETPASS" = x"yes"; then +if test x"$libreplace_cv_REPLACE_GETPASS" = x"yes"; then AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced]) LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o" fi diff --git a/source3/lib/replace/libreplace.m4 b/source3/lib/replace/libreplace.m4 index f866b3648f..e0cc57f4c8 100644 --- a/source3/lib/replace/libreplace.m4 +++ b/source3/lib/replace/libreplace.m4 @@ -85,10 +85,10 @@ AC_INCLUDES_DEFAULT #endif] ) -AC_CACHE_CHECK([for working mmap],samba_cv_HAVE_MMAP,[ +AC_CACHE_CHECK([for working mmap],libreplace_cv_HAVE_MMAP,[ AC_TRY_RUN([#include "$libreplacedir/test/shared_mmap.c"], - samba_cv_HAVE_MMAP=yes,samba_cv_HAVE_MMAP=no,samba_cv_HAVE_MMAP=cross)]) -if test x"$samba_cv_HAVE_MMAP" = x"yes"; then + libreplace_cv_HAVE_MMAP=yes,libreplace_cv_HAVE_MMAP=no,libreplace_cv_HAVE_MMAP=cross)]) +if test x"$libreplace_cv_HAVE_MMAP" = x"yes"; then AC_DEFINE(HAVE_MMAP,1,[Whether mmap works]) fi @@ -120,7 +120,7 @@ if test x"$libreplace_cv_USABLE_NET_IF_H" = x"yes";then AC_DEFINE(HAVE_NET_IF_H, 1, usability of net/if.h) fi -AC_CACHE_CHECK([for broken inet_ntoa],samba_cv_REPLACE_INET_NTOA,[ +AC_CACHE_CHECK([for broken inet_ntoa],libreplace_cv_REPLACE_INET_NTOA,[ AC_TRY_RUN([ #include <stdio.h> #include <unistd.h> @@ -133,8 +133,8 @@ main() { struct in_addr ip; ip.s_addr = 0x12345678; if (strcmp(inet_ntoa(ip),"18.52.86.120") && strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); } exit(1);}], - samba_cv_REPLACE_INET_NTOA=yes,samba_cv_REPLACE_INET_NTOA=no,samba_cv_REPLACE_INET_NTOA=cross)]) -if test x"$samba_cv_REPLACE_INET_NTOA" = x"yes"; then + libreplace_cv_REPLACE_INET_NTOA=yes,libreplace_cv_REPLACE_INET_NTOA=no,libreplace_cv_REPLACE_INET_NTOA=cross)]) +if test x"$libreplace_cv_REPLACE_INET_NTOA" = x"yes"; then AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced]) fi @@ -182,7 +182,7 @@ AC_HAVE_DECL(setresuid, [#include <unistd.h>]) AC_HAVE_DECL(setresgid, [#include <unistd.h>]) AC_HAVE_DECL(errno, [#include <errno.h>]) -AC_CACHE_CHECK([for secure mkstemp],samba_cv_HAVE_SECURE_MKSTEMP,[ +AC_CACHE_CHECK([for secure mkstemp],libreplace_cv_HAVE_SECURE_MKSTEMP,[ AC_TRY_RUN([#include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> @@ -197,10 +197,10 @@ main() { if ((st.st_mode & 0777) != 0600) exit(1); exit(0); }], -samba_cv_HAVE_SECURE_MKSTEMP=yes, -samba_cv_HAVE_SECURE_MKSTEMP=no, -samba_cv_HAVE_SECURE_MKSTEMP=cross)]) -if test x"$samba_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then +libreplace_cv_HAVE_SECURE_MKSTEMP=yes, +libreplace_cv_HAVE_SECURE_MKSTEMP=no, +libreplace_cv_HAVE_SECURE_MKSTEMP=cross)]) +if test x"$libreplace_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then AC_DEFINE(HAVE_SECURE_MKSTEMP,1,[Whether mkstemp is secure]) fi @@ -209,7 +209,7 @@ AC_CHECK_HEADERS(stdio.h strings.h) AC_CHECK_DECLS([snprintf, vsnprintf, asprintf, vasprintf]) AC_CHECK_FUNCS(snprintf vsnprintf asprintf vasprintf) -AC_CACHE_CHECK([for C99 vsnprintf],samba_cv_HAVE_C99_VSNPRINTF,[ +AC_CACHE_CHECK([for C99 vsnprintf],libreplace_cv_HAVE_C99_VSNPRINTF,[ AC_TRY_RUN([ #include <sys/types.h> #include <stdio.h> @@ -243,43 +243,43 @@ void foo(const char *format, ...) { } main() { foo("hello"); } ], -samba_cv_HAVE_C99_VSNPRINTF=yes,samba_cv_HAVE_C99_VSNPRINTF=no,samba_cv_HAVE_C99_VSNPRINTF=cross)]) -if test x"$samba_cv_HAVE_C99_VSNPRINTF" = x"yes"; then +libreplace_cv_HAVE_C99_VSNPRINTF=yes,libreplace_cv_HAVE_C99_VSNPRINTF=no,libreplace_cv_HAVE_C99_VSNPRINTF=cross)]) +if test x"$libreplace_cv_HAVE_C99_VSNPRINTF" = x"yes"; then AC_DEFINE(HAVE_C99_VSNPRINTF,1,[Whether there is a C99 compliant vsnprintf]) fi dnl VA_COPY -AC_CACHE_CHECK([for va_copy],samba_cv_HAVE_VA_COPY,[ +AC_CACHE_CHECK([for va_copy],libreplace_cv_HAVE_VA_COPY,[ AC_TRY_LINK([#include <stdarg.h> va_list ap1,ap2;], [va_copy(ap1,ap2);], -samba_cv_HAVE_VA_COPY=yes,samba_cv_HAVE_VA_COPY=no)]) -if test x"$samba_cv_HAVE_VA_COPY" = x"yes"; then +libreplace_cv_HAVE_VA_COPY=yes,libreplace_cv_HAVE_VA_COPY=no)]) +if test x"$libreplace_cv_HAVE_VA_COPY" = x"yes"; then AC_DEFINE(HAVE_VA_COPY,1,[Whether va_copy() is available]) fi -if test x"$samba_cv_HAVE_VA_COPY" != x"yes"; then -AC_CACHE_CHECK([for __va_copy],samba_cv_HAVE___VA_COPY,[ +if test x"$libreplace_cv_HAVE_VA_COPY" != x"yes"; then +AC_CACHE_CHECK([for __va_copy],libreplace_cv_HAVE___VA_COPY,[ AC_TRY_LINK([#include <stdarg.h> va_list ap1,ap2;], [__va_copy(ap1,ap2);], -samba_cv_HAVE___VA_COPY=yes,samba_cv_HAVE___VA_COPY=no)]) -if test x"$samba_cv_HAVE___VA_COPY" = x"yes"; then +libreplace_cv_HAVE___VA_COPY=yes,libreplace_cv_HAVE___VA_COPY=no)]) +if test x"$libreplace_cv_HAVE___VA_COPY" = x"yes"; then AC_DEFINE(HAVE___VA_COPY,1,[Whether __va_copy() is available]) fi fi dnl __FUNCTION__ macro -AC_CACHE_CHECK([for __FUNCTION__ macro],samba_cv_HAVE_FUNCTION_MACRO,[ +AC_CACHE_CHECK([for __FUNCTION__ macro],libreplace_cv_HAVE_FUNCTION_MACRO,[ AC_TRY_COMPILE([#include <stdio.h>], [printf("%s\n", __FUNCTION__);], -samba_cv_HAVE_FUNCTION_MACRO=yes,samba_cv_HAVE_FUNCTION_MACRO=no)]) -if test x"$samba_cv_HAVE_FUNCTION_MACRO" = x"yes"; then +libreplace_cv_HAVE_FUNCTION_MACRO=yes,libreplace_cv_HAVE_FUNCTION_MACRO=no)]) +if test x"$libreplace_cv_HAVE_FUNCTION_MACRO" = x"yes"; then AC_DEFINE(HAVE_FUNCTION_MACRO,1,[Whether there is a __FUNCTION__ macro]) else dnl __func__ macro - AC_CACHE_CHECK([for __func__ macro],samba_cv_HAVE_func_MACRO,[ + AC_CACHE_CHECK([for __func__ macro],libreplace_cv_HAVE_func_MACRO,[ AC_TRY_COMPILE([#include <stdio.h>], [printf("%s\n", __func__);], - samba_cv_HAVE_func_MACRO=yes,samba_cv_HAVE_func_MACRO=no)]) - if test x"$samba_cv_HAVE_func_MACRO" = x"yes"; then + libreplace_cv_HAVE_func_MACRO=yes,libreplace_cv_HAVE_func_MACRO=no)]) + if test x"$libreplace_cv_HAVE_func_MACRO" = x"yes"; then AC_DEFINE(HAVE_func_MACRO,1,[Whether there is a __func__ macro]) fi fi @@ -302,7 +302,7 @@ eprintf("bla", "bar"); ], AC_DEFINE(HAVE__VA_ARGS__MACRO, 1, [Whether the __VA_ARGS__ macro is available])) -AC_CACHE_CHECK([for sig_atomic_t type],samba_cv_sig_atomic_t, [ +AC_CACHE_CHECK([for sig_atomic_t type],libreplace_cv_sig_atomic_t, [ AC_TRY_COMPILE([ #include <sys/types.h> #if STDC_HEADERS @@ -310,30 +310,30 @@ AC_CACHE_CHECK([for sig_atomic_t type],samba_cv_sig_atomic_t, [ #include <stddef.h> #endif #include <signal.h>],[sig_atomic_t i = 0], - samba_cv_sig_atomic_t=yes,samba_cv_sig_atomic_t=no)]) -if test x"$samba_cv_sig_atomic_t" = x"yes"; then + libreplace_cv_sig_atomic_t=yes,libreplace_cv_sig_atomic_t=no)]) +if test x"$libreplace_cv_sig_atomic_t" = x"yes"; then AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE,1,[Whether we have the atomic_t variable type]) fi -AC_CACHE_CHECK([for O_DIRECT flag to open(2)],samba_cv_HAVE_OPEN_O_DIRECT,[ +AC_CACHE_CHECK([for O_DIRECT flag to open(2)],libreplace_cv_HAVE_OPEN_O_DIRECT,[ AC_TRY_COMPILE([ #include <unistd.h> #ifdef HAVE_FCNTL_H #include <fcntl.h> #endif], [int fd = open("/dev/null", O_DIRECT);], -samba_cv_HAVE_OPEN_O_DIRECT=yes,samba_cv_HAVE_OPEN_O_DIRECT=no)]) -if test x"$samba_cv_HAVE_OPEN_O_DIRECT" = x"yes"; then +libreplace_cv_HAVE_OPEN_O_DIRECT=yes,libreplace_cv_HAVE_OPEN_O_DIRECT=no)]) +if test x"$libreplace_cv_HAVE_OPEN_O_DIRECT" = x"yes"; then AC_DEFINE(HAVE_OPEN_O_DIRECT,1,[Whether the open(2) accepts O_DIRECT]) fi dnl Check if the C compiler understands volatile (it should, being ANSI). -AC_CACHE_CHECK([that the C compiler understands volatile],samba_cv_volatile, [ +AC_CACHE_CHECK([that the C compiler understands volatile],libreplace_cv_volatile, [ AC_TRY_COMPILE([#include <sys/types.h>],[volatile int i = 0], - samba_cv_volatile=yes,samba_cv_volatile=no)]) -if test x"$samba_cv_volatile" = x"yes"; then + libreplace_cv_volatile=yes,libreplace_cv_volatile=no)]) +if test x"$libreplace_cv_volatile" = x"yes"; then AC_DEFINE(HAVE_VOLATILE, 1, [Whether the C compiler understands volatile]) fi @@ -344,10 +344,12 @@ m4_include(getpass.m4) m4_include(strptime.m4) m4_include(win32.m4) m4_include(timegm.m4) +m4_include(socket.m4) m4_include(inet_ntop.m4) m4_include(inet_pton.m4) m4_include(getaddrinfo.m4) m4_include(repdir.m4) +m4_include(getifaddrs.m4) AC_CHECK_FUNCS([syslog printf memset memcpy],,[AC_MSG_ERROR([Required function not found])]) diff --git a/source3/lib/replace/libreplace_ld.m4 b/source3/lib/replace/libreplace_ld.m4 index 08defb091f..f0d10c1e3e 100644 --- a/source3/lib/replace/libreplace_ld.m4 +++ b/source3/lib/replace/libreplace_ld.m4 @@ -246,10 +246,6 @@ AC_DEFUN([AC_LD_SONAMEFLAG], # Not supported SONAMEFLAG="#" ;; - *aix*) - # Not supported - SONAMEFLAG="#" - ;; esac ]) diff --git a/source3/lib/replace/replace.h b/source3/lib/replace/replace.h index 1d1cbc2cd2..0d16f4ffd0 100644 --- a/source3/lib/replace/replace.h +++ b/source3/lib/replace/replace.h @@ -340,6 +340,26 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) /* prototype is in "system/network.h" */ #endif +#ifndef HAVE_CONNECT +#define connect rep_connect +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_GETHOSTBYNAME +#define gethostbyname rep_gethostbyname +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_GETIFADDRS +#define getifaddrs rep_getifaddrs +/* prototype is in "system/network.h" */ +#endif + +#ifndef HAVE_FREEIFADDRS +#define freeifaddrs rep_freeifaddrs +/* prototype is in "system/network.h" */ +#endif + #ifdef HAVE_LIMITS_H #include <limits.h> #endif diff --git a/source3/lib/replace/socket.c b/source3/lib/replace/socket.c new file mode 100644 index 0000000000..35e975fce7 --- /dev/null +++ b/source3/lib/replace/socket.c @@ -0,0 +1,35 @@ +/* + * Unix SMB/CIFS implementation. + * + * Dummy replacements for socket functions. + * + * Copyright (C) Michael Adam <obnox@samba.org> 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "replace.h" +#include "system/network.h" + +int rep_connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) +{ + errno = ENOSYS; + return -1; +} + +struct hostent *rep_gethostbyname(const char *name) +{ + errno = ENOSYS; + return NULL; +} diff --git a/source3/lib/replace/socket.m4 b/source3/lib/replace/socket.m4 new file mode 100644 index 0000000000..c0c8f93e81 --- /dev/null +++ b/source3/lib/replace/socket.m4 @@ -0,0 +1,40 @@ +dnl The following test is roughl taken from the cvs sources. +dnl +dnl If we can't find connect, try looking in -lsocket, -lnsl, and -linet. +dnl The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has +dnl libsocket.so which has a bad implementation of gethostbyname (it +dnl only looks in /etc/hosts), so we only look for -lsocket if we need +dnl it. +AC_CHECK_FUNCS(connect) +if test x"$ac_cv_func_connect" = x"no"; then + AC_CHECK_LIB_EXT(nsl_s, SOCKET_LIBS, connect) + AC_CHECK_LIB_EXT(nsl, SOCKET_LIBS, connect) + AC_CHECK_LIB_EXT(socket, SOCKET_LIBS, connect) + AC_CHECK_LIB_EXT(inet, SOCKET_LIBS, connect) + dnl We can't just call AC_CHECK_FUNCS(connect) here, + dnl because the value has been cached. + if test x"$ac_cv_lib_ext_nsl_s_connect" = x"yes" || + test x"$ac_cv_lib_ext_nsl_connect" = x"yes" || + test x"$ac_cv_lib_ext_socket_connect" = x"yes" || + test x"$ac_cv_lib_ext_inet_connect" = x"yes" + then + AC_DEFINE(HAVE_CONNECT,1,[Whether the system has connect()]) + fi +fi + +AC_CHECK_FUNCS(gethostbyname) +if test x"$ac_cv_func_gethostbyname" = x"no"; then + AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, gethostbyname) + AC_CHECK_LIB_EXT(nsl, NSL_LIBS, gethostbyname) + AC_CHECK_LIB_EXT(socket, NSL_LIBS, gethostbyname) + dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here, + dnl because the value has been cached. + if test x"$ac_cv_lib_ext_nsl_s_gethostbyname" = x"yes" || + test x"$ac_cv_lib_ext_nsl_gethostbyname" = x"yes" || + test x"$ac_cv_lib_ext_socket_gethostbyname" = x"yes" + then + AC_DEFINE(HAVE_GETHOSTBYNAME,1, + [Whether the system has gethostbyname()]) + fi +fi + diff --git a/source3/lib/replace/system/config.m4 b/source3/lib/replace/system/config.m4 index 1c05733126..66c2bd652a 100644 --- a/source3/lib/replace/system/config.m4 +++ b/source3/lib/replace/system/config.m4 @@ -18,7 +18,7 @@ AC_CHECK_HEADERS(sys/capability.h) case "$host_os" in *linux*) -AC_CACHE_CHECK([for broken RedHat 7.2 system header files],samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS,[ +AC_CACHE_CHECK([for broken RedHat 7.2 system header files],libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS,[ AC_TRY_COMPILE([ #ifdef HAVE_SYS_VFS_H #include <sys/vfs.h> @@ -29,14 +29,14 @@ AC_TRY_COMPILE([ ],[ int i; ], - samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=no, - samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=yes + libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=no, + libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS=yes )]) -if test x"$samba_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS" = x"yes"; then +if test x"$libreplace_cv_BROKEN_REDHAT_7_SYSTEM_HEADERS" = x"yes"; then AC_DEFINE(BROKEN_REDHAT_7_SYSTEM_HEADERS,1,[Broken RedHat 7.2 system header files]) fi -AC_CACHE_CHECK([for broken RHEL5 sys/capability.h],samba_cv_BROKEN_RHEL5_SYS_CAP_HEADER,[ +AC_CACHE_CHECK([for broken RHEL5 sys/capability.h],libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER,[ AC_TRY_COMPILE([ #ifdef HAVE_SYS_CAPABILITY_H #include <sys/capability.h> @@ -45,10 +45,10 @@ AC_TRY_COMPILE([ ],[ __s8 i; ], - samba_cv_BROKEN_RHEL5_SYS_CAP_HEADER=no, - samba_cv_BROKEN_RHEL5_SYS_CAP_HEADER=yes + libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER=no, + libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER=yes )]) -if test x"$samba_cv_BROKEN_RHEL5_SYS_CAP_HEADER" = x"yes"; then +if test x"$libreplace_cv_BROKEN_RHEL5_SYS_CAP_HEADER" = x"yes"; then AC_DEFINE(BROKEN_RHEL5_SYS_CAP_HEADER,1,[Broken RHEL5 sys/capability.h]) fi ;; diff --git a/source3/lib/replace/system/network.h b/source3/lib/replace/system/network.h index aff8a841da..796df2d1da 100644 --- a/source3/lib/replace/system/network.h +++ b/source3/lib/replace/system/network.h @@ -6,6 +6,7 @@ networking system include wrappers Copyright (C) Andrew Tridgell 2004 + Copyright (C) Jelmer Vernooij 2007 ** NOTE! The following LGPL license applies to the replace ** library. This does NOT imply that all of Samba is released @@ -82,6 +83,11 @@ #include <stropts.h> #endif +#ifndef HAVE_SOCKLEN_T +#define HAVE_SOCKLEN_T +typedef int socklen_t; +#endif + #ifdef REPLACE_INET_NTOA /* define is in "replace.h" */ char *rep_inet_ntoa(struct in_addr ip); @@ -97,6 +103,41 @@ int rep_inet_pton(int af, const char *src, void *dst); const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); #endif +#ifndef HAVE_CONNECT +/* define is in "replace.h" */ +int rep_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); +#endif + +#ifndef HAVE_GETHOSTBYNAME +/* define is in "replace.h" */ +struct hostent *rep_gethostbyname(const char *name); +#endif + +#ifdef HAVE_IFADDRS_H +#include <ifaddrs.h> +#endif + +#ifndef HAVE_STRUCT_IFADDRS +struct ifaddrs { + struct ifaddrs *ifa_next; /* Pointer to next struct */ + char *ifa_name; /* Interface name */ + unsigned int ifa_flags; /* Interface flags */ + struct sockaddr *ifa_addr; /* Interface address */ + struct sockaddr *ifa_netmask; /* Interface netmask */ +#undef ifa_dstaddr + struct sockaddr *ifa_dstaddr; /* P2P interface destination */ + void *ifa_data; /* Address specific data */ +}; +#endif + +#ifndef HAVE_GETIFADDRS +int rep_getifaddrs(struct ifaddrs **); +#endif + +#ifndef HAVE_FREEIFADDRS +void rep_freeifaddrs(struct ifaddrs *); +#endif + /* * Some systems have getaddrinfo but not the * defines needed to use it. @@ -219,11 +260,6 @@ const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); #define HOST_NAME_MAX 256 #endif -#ifndef HAVE_SOCKLEN_T -#define HAVE_SOCKLEN_T -typedef int socklen_t; -#endif - #ifndef HAVE_SA_FAMILY_T #define HAVE_SA_FAMILY_T typedef unsigned short int sa_family_t; @@ -269,7 +305,7 @@ struct addrinfo { /* Needed for some systems that don't define it (Solaris). */ #ifndef ifr_netmask -#define ifr_netmask ifr_addrs +#define ifr_netmask ifr_addr #endif #ifdef SOCKET_WRAPPER diff --git a/source3/lib/replace/test/getifaddrs.c b/source3/lib/replace/test/getifaddrs.c new file mode 100644 index 0000000000..8b00ac2f40 --- /dev/null +++ b/source3/lib/replace/test/getifaddrs.c @@ -0,0 +1,100 @@ +/* + * Unix SMB/CIFS implementation. + * + * libreplace getifaddrs test + * + * Copyright (C) Michael Adam <obnox@samba.org> 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 AUTOCONF_TEST +#include "replace.h" +#include "system/network.h" +#endif + +#ifdef HAVE_INET_NTOP +#define rep_inet_ntop inet_ntop +#endif + +static const char *format_sockaddr(struct sockaddr *addr, + char *addrstring, + socklen_t addrlen) +{ + const char *result = NULL; + + if (addr->sa_family == AF_INET) { + result = rep_inet_ntop(AF_INET, + &((struct sockaddr_in *)addr)->sin_addr, + addrstring, + addrlen); +#ifdef HAVE_STRUCT_SOCKADDR_IN6 + } else if (addr->sa_family == AF_INET6) { + result = rep_inet_ntop(AF_INET6, + &((struct sockaddr_in6 *)addr)->sin6_addr, + addrstring, + addrlen); +#endif + } + return result; +} + +int getifaddrs_test(void) +{ + struct ifaddrs *ifs = NULL; + struct ifaddrs *ifs_head = NULL; + int ret; + + ret = getifaddrs(&ifs); + ifs_head = ifs; + if (ret != 0) { + fprintf(stderr, "getifaddrs() failed: %s\n", strerror(errno)); + return 1; + } + + while (ifs) { + printf("%-10s ", ifs->ifa_name); + if (ifs->ifa_addr != NULL) { + char addrstring[INET6_ADDRSTRLEN]; + const char *result; + + result = format_sockaddr(ifs->ifa_addr, + addrstring, + sizeof(addrstring)); + if (result != NULL) { + printf("IP=%s ", addrstring); + } + + if (ifs->ifa_netmask != NULL) { + result = format_sockaddr(ifs->ifa_netmask, + addrstring, + sizeof(addrstring)); + if (result != NULL) { + printf("NETMASK=%s", addrstring); + } + } else { + printf("AF=%d ", ifs->ifa_addr->sa_family); + } + } else { + printf("<no address>"); + } + + printf("\n"); + ifs = ifs->ifa_next; + } + + freeifaddrs(ifs_head); + + return 0; +} diff --git a/source3/lib/replace/test/testsuite.c b/source3/lib/replace/test/testsuite.c index 5b95ae395c..b538360365 100644 --- a/source3/lib/replace/test/testsuite.c +++ b/source3/lib/replace/test/testsuite.c @@ -856,6 +856,22 @@ static int test_strptime(void) return libreplace_test_strptime(); } +extern int getifaddrs_test(void); + +static int test_getifaddrs(void) +{ + + printf("test: getifaddrs\n"); + + if (getifaddrs_test() != 0) { + printf("failure: getifaddrs\n"); + return false; + } + + printf("success: getifaddrs\n"); + return true; +} + struct torture_context; bool torture_local_replace(struct torture_context *ctx) { @@ -903,6 +919,7 @@ bool torture_local_replace(struct torture_context *ctx) ret &= test_MAX(); ret &= test_socketpair(); ret &= test_strptime(); + ret &= test_getifaddrs(); return ret; } diff --git a/source3/lib/select.c b/source3/lib/select.c index d5e4ba68f2..c3da6a9bba 100644 --- a/source3/lib/select.c +++ b/source3/lib/select.c @@ -58,7 +58,8 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s fd_set *readfds2, readfds_buf; if (initialised != sys_getpid()) { - pipe(select_pipe); + if (pipe(select_pipe) == -1) + smb_panic("Could not create select pipe"); /* * These next two lines seem to fix a bug with the Linux diff --git a/source3/lib/sock_exec.c b/source3/lib/sock_exec.c index 203d7e93b3..278a174663 100644 --- a/source3/lib/sock_exec.c +++ b/source3/lib/sock_exec.c @@ -105,8 +105,12 @@ int sock_exec(const char *prog) close(fd[0]); close(0); close(1); - dup(fd[1]); - dup(fd[1]); + if (dup(fd[1]) == -1) { + exit(1); + } + if (dup(fd[1]) == -1) { + exit(1); + } exit(system(prog)); } close(fd[1]); diff --git a/source3/lib/util_nttoken.c b/source3/lib/util_nttoken.c index 13c66a5f45..f81191af58 100644 --- a/source3/lib/util_nttoken.c +++ b/source3/lib/util_nttoken.c @@ -7,6 +7,7 @@ * Copyright (C) Rafal Szczesniak 2002 * Copyright (C) Volker Lendecke 2006 * Copyright (C) Michael Adam 2007 + * Copyright (C) Guenther Deschner 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 @@ -67,3 +68,52 @@ NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, const NT_USER_TOKEN *ptoken) return token; } +/**************************************************************************** + merge NT tokens +****************************************************************************/ + +NTSTATUS merge_nt_token(TALLOC_CTX *mem_ctx, + const struct nt_user_token *token_1, + const struct nt_user_token *token_2, + struct nt_user_token **token_out) +{ + struct nt_user_token *token = NULL; + NTSTATUS status; + int i; + + if (!token_1 || !token_2 || !token_out) { + return NT_STATUS_INVALID_PARAMETER; + } + + token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token); + NT_STATUS_HAVE_NO_MEMORY(token); + + for (i=0; i < token_1->num_sids; i++) { + status = add_sid_to_array_unique(mem_ctx, + &token_1->user_sids[i], + &token->user_sids, + &token->num_sids); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(token); + return status; + } + } + + for (i=0; i < token_2->num_sids; i++) { + status = add_sid_to_array_unique(mem_ctx, + &token_2->user_sids[i], + &token->user_sids, + &token->num_sids); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(token); + return status; + } + } + + se_priv_add(&token->privileges, &token_1->privileges); + se_priv_add(&token->privileges, &token_2->privileges); + + *token_out = token; + + return NT_STATUS_OK; +} diff --git a/source3/lib/util_reg.c b/source3/lib/util_reg.c index 2d7d70c63f..2475dca040 100644 --- a/source3/lib/util_reg.c +++ b/source3/lib/util_reg.c @@ -95,7 +95,7 @@ WERROR reg_pull_multi_sz(TALLOC_CTX *mem_ctx, const void *buf, size_t len, thislen = strnlen_w(p, len) + 1; dstlen = convert_string_allocate(*values, CH_UTF16LE, CH_UNIX, p, thislen*2, (void *)&val, - True); + true); if (dstlen == (size_t)-1) { TALLOC_FREE(*values); return WERR_NOMEM; @@ -137,8 +137,8 @@ bool registry_smbconf_valname_forbidden(const char *valname) for (forbidden = forbidden_valnames; *forbidden != NULL; forbidden++) { if (strwicmp(valname, *forbidden) == 0) { - return True; + return true; } } - return False; + return false; } diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 37865238a5..fd2e93a697 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -665,7 +665,7 @@ bool is_null_sid(const DOM_SID *sid) } NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, - const NET_USER_INFO_3 *info3, + const struct netr_SamInfo3 *info3, DOM_SID **user_sids, size_t *num_user_sids, bool include_user_group_rid) @@ -678,45 +678,45 @@ NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, if (include_user_group_rid) { - if (!sid_compose(&sid, &(info3->dom_sid.sid), info3->user_rid)) + if (!sid_compose(&sid, info3->base.domain_sid, info3->base.rid)) { DEBUG(3, ("could not compose user SID from rid 0x%x\n", - info3->user_rid)); + info3->base.rid)); return NT_STATUS_INVALID_PARAMETER; } status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("could not append user SID from rid 0x%x\n", - info3->user_rid)); + info3->base.rid)); return status; } - if (!sid_compose(&sid, &(info3->dom_sid.sid), info3->group_rid)) + if (!sid_compose(&sid, info3->base.domain_sid, info3->base.primary_gid)) { DEBUG(3, ("could not compose group SID from rid 0x%x\n", - info3->group_rid)); + info3->base.primary_gid)); return NT_STATUS_INVALID_PARAMETER; } status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("could not append group SID from rid 0x%x\n", - info3->group_rid)); + info3->base.rid)); return status; } } - for (i = 0; i < info3->num_groups2; i++) { - if (!sid_compose(&sid, &(info3->dom_sid.sid), - info3->gids[i].g_rid)) + for (i = 0; i < info3->base.groups.count; i++) { + if (!sid_compose(&sid, info3->base.domain_sid, + info3->base.groups.rids[i].rid)) { DEBUG(3, ("could not compose SID from additional group " - "rid 0x%x\n", info3->gids[i].g_rid)); + "rid 0x%x\n", info3->base.groups.rids[i].rid)); return NT_STATUS_INVALID_PARAMETER; } status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("could not append SID from additional group " - "rid 0x%x\n", info3->gids[i].g_rid)); + "rid 0x%x\n", info3->base.groups.rids[i].rid)); return status; } } @@ -727,12 +727,12 @@ NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp */ - for (i = 0; i < info3->num_other_sids; i++) { - status = add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, + for (i = 0; i < info3->sidcount; i++) { + status = add_sid_to_array(mem_ctx, info3->sids[i].sid, &sid_array, &num_sids); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("could not add SID to array: %s\n", - sid_string_dbg(&info3->other_sids[i].sid))); + sid_string_dbg(info3->sids[i].sid))); return status; } } diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 71d48d6053..2a65943872 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -370,7 +370,7 @@ void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss, Convert an IPv6 struct in_addr to a struct sockaddr_storage. ********************************************************************/ -void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss, + void in6_addr_to_sockaddr_storage(struct sockaddr_storage *ss, struct in6_addr ip) { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)ss; @@ -1904,8 +1904,7 @@ int create_pipe_sock(const char *socket_dir, goto out_close; } - asprintf(&path, "%s/%s", socket_dir, socket_name); - if (!path) { + if (asprintf(&path, "%s/%s", socket_dir, socket_name) == -1) { goto out_close; } @@ -1933,7 +1932,8 @@ int create_pipe_sock(const char *socket_dir, out_close: SAFE_FREE(path); - close(sock); + if (sock != -1) + close(sock); out_umask: umask(old_umask); diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index f631dfffee..cb8a100fa7 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -2086,6 +2086,7 @@ static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service) { char *new_ipstr = NULL; char addr_buf[INET6_ADDRSTRLEN]; + int ret; /* arguments checking */ if (!ipstr_list || !service) { @@ -2100,33 +2101,30 @@ static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service) if (*ipstr_list) { if (service->ss.ss_family == AF_INET) { /* IPv4 */ - asprintf(&new_ipstr, "%s%s%s:%d", - *ipstr_list, - IPSTR_LIST_SEP, - addr_buf, - service->port); + ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, + IPSTR_LIST_SEP, addr_buf, + service->port); } else { /* IPv6 */ - asprintf(&new_ipstr, "%s%s[%s]:%d", - *ipstr_list, - IPSTR_LIST_SEP, - addr_buf, - service->port); + ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list, + IPSTR_LIST_SEP, addr_buf, + service->port); } SAFE_FREE(*ipstr_list); } else { if (service->ss.ss_family == AF_INET) { /* IPv4 */ - asprintf(&new_ipstr, "%s:%d", - addr_buf, - service->port); + ret = asprintf(&new_ipstr, "%s:%d", addr_buf, + service->port); } else { /* IPv6 */ - asprintf(&new_ipstr, "[%s]:%d", - addr_buf, - service->port); + ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf, + service->port); } } + if (ret == -1) { + return NULL; + } *ipstr_list = new_ipstr; return *ipstr_list; } diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c index dd5ebcd7ab..724832ea5b 100644 --- a/source3/lib/util_tdb.c +++ b/source3/lib/util_tdb.c @@ -669,12 +669,13 @@ static void tdb_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, const char *fo { va_list ap; char *ptr = NULL; + int ret; va_start(ap, format); - vasprintf(&ptr, format, ap); + ret = vasprintf(&ptr, format, ap); va_end(ap); - if (!ptr || !*ptr) + if ((ret == -1) || !*ptr) return; DEBUG((int)level, ("tdb(%s): %s", tdb_name(tdb) ? tdb_name(tdb) : "unnamed", ptr)); @@ -867,11 +868,8 @@ static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, va_list ap; char *ptr = NULL; int debuglevel = 0; + int ret; - va_start(ap, format); - vasprintf(&ptr, format, ap); - va_end(ap); - switch (level) { case TDB_DEBUG_FATAL: debug_level = 0; @@ -889,7 +887,11 @@ static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, debuglevel = 0; } - if (ptr != NULL) { + va_start(ap, format); + ret = vasprintf(&ptr, format, ap); + va_end(ap); + + if (ret != -1) { const char *name = tdb_name(tdb); DEBUG(debuglevel, ("tdb(%s): %s", name ? name : "unnamed", ptr)); free(ptr); diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c index 644f8515bc..0bde3e6984 100644 --- a/source3/libads/authdata.c +++ b/source3/libads/authdata.c @@ -1,23 +1,23 @@ -/* +/* Unix SMB/CIFS implementation. kerberos authorization data (PAC) utility library - Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005 Copyright (C) Andrew Tridgell 2001 Copyright (C) Luke Howard 2002-2003 Copyright (C) Stefan Metzmacher 2004-2005 - Copyright (C) Guenther Deschner 2005,2007 - + Copyright (C) Guenther Deschner 2005,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 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/>. */ @@ -26,628 +26,14 @@ #ifdef HAVE_KRB5 -static bool pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name, - prs_struct *ps, int depth) -{ - if (NULL == logon_name) - return False; - - prs_debug(ps, depth, desc, "pac_io_logon_name"); - depth++; - - if (!smb_io_time("logon_time", &logon_name->logon_time, ps, depth)) - return False; - - if (!prs_uint16("len", ps, depth, &logon_name->len)) - return False; - - /* The following string is always in little endian 16 bit values, - copy as 8 bits to avoid endian reversal on big-endian machines. - len is the length in bytes. */ - - if (UNMARSHALLING(ps) && logon_name->len) { - logon_name->username = PRS_ALLOC_MEM(ps, uint8, logon_name->len); - if (!logon_name->username) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - if (!prs_uint8s(True, "name", ps, depth, logon_name->username, logon_name->len)) - return False; - - return True; -} - -#if 0 /* Unused (handled now in net_io_user_info3()) - Guenther */ -static bool pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, - prs_struct *ps, int depth) -{ - if (NULL == sid_and_attr) - return False; - - prs_debug(ps, depth, desc, "pac_io_krb_sids"); - depth++; - - if (UNMARSHALLING(ps)) { - sid_and_attr->sid = PRS_ALLOC_MEM(ps, DOM_SID2, 1); - if (!sid_and_attr->sid) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - if(!smb_io_dom_sid2("sid", sid_and_attr->sid, ps, depth)) - return False; - - return True; -} - - -static bool pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr, - prs_struct *ps, int depth) -{ - if (NULL == sid_and_attr) - return False; - - prs_debug(ps, depth, desc, "pac_io_krb_attrs"); - depth++; - - if (!prs_uint32("sid_ptr", ps, depth, &sid_and_attr->sid_ptr)) - return False; - if (!prs_uint32("attrs", ps, depth, &sid_and_attr->attrs)) - return False; - - return True; -} - -static bool pac_io_krb_sid_and_attr_array(const char *desc, - KRB_SID_AND_ATTR_ARRAY *array, - uint32 num, - prs_struct *ps, int depth) -{ - int i; - - if (NULL == array) - return False; - - prs_debug(ps, depth, desc, "pac_io_krb_sid_and_attr_array"); - depth++; - - - if (!prs_uint32("count", ps, depth, &array->count)) - return False; - - if (UNMARSHALLING(ps)) { - if (num) { - array->krb_sid_and_attrs = PRS_ALLOC_MEM(ps, KRB_SID_AND_ATTRS, num); - if (!array->krb_sid_and_attrs) { - DEBUG(3, ("No memory available\n")); - return False; - } - } else { - array->krb_sid_and_attrs = NULL; - } - } - - for (i=0; i<num; i++) { - if (!pac_io_krb_attrs(desc, - &array->krb_sid_and_attrs[i], - ps, depth)) - return False; - - } - for (i=0; i<num; i++) { - if (!pac_io_krb_sids(desc, - &array->krb_sid_and_attrs[i], - ps, depth)) - return False; - - } - - return True; - -} -#endif - -static bool pac_io_group_membership(const char *desc, - GROUP_MEMBERSHIP *membership, - prs_struct *ps, int depth) -{ - if (NULL == membership) - return False; - - prs_debug(ps, depth, desc, "pac_io_group_membership"); - depth++; - - if (!prs_uint32("rid", ps, depth, &membership->rid)) - return False; - if (!prs_uint32("attrs", ps, depth, &membership->attrs)) - return False; - - return True; -} - - -static bool pac_io_group_membership_array(const char *desc, - GROUP_MEMBERSHIP_ARRAY *array, - uint32 num, - prs_struct *ps, int depth) -{ - int i; - - if (NULL == array) - return False; - - prs_debug(ps, depth, desc, "pac_io_group_membership_array"); - depth++; - - - if (!prs_uint32("count", ps, depth, &array->count)) - return False; - - if (UNMARSHALLING(ps)) { - if (num) { - array->group_membership = PRS_ALLOC_MEM(ps, GROUP_MEMBERSHIP, num); - if (!array->group_membership) { - DEBUG(3, ("No memory available\n")); - return False; - } - } else { - array->group_membership = NULL; - } - } - - for (i=0; i<num; i++) { - if (!pac_io_group_membership(desc, - &array->group_membership[i], - ps, depth)) - return False; - - } - - return True; - -} - -#if 0 /* Unused, replaced using an expanded net_io_user_info3() now - Guenther */ -static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, - prs_struct *ps, int depth) -{ - uint32 garbage = 0, i; - - if (NULL == info) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */ - return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */ - return False; - if (!prs_uint32("bufferlen", ps, depth, &garbage)) - return False; - if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */ - return False; - - if (!prs_uint32("pointer", ps, depth, &garbage)) - return False; - - if (!prs_align(ps)) - return False; - if (!smb_io_time("logon_time", &info->logon_time, ps, depth)) - return False; - if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth)) - return False; - if (!smb_io_time("kickoff_time", &info->kickoff_time, ps, depth)) - return False; - if (!smb_io_time("pass_last_set_time", &info->pass_last_set_time, - ps, depth)) - return False; - if (!smb_io_time("pass_can_change_time", &info->pass_can_change_time, - ps, depth)) - return False; - if (!smb_io_time("pass_must_change_time", &info->pass_must_change_time, - ps, depth)) - return False; - - if (!smb_io_unihdr("hdr_user_name", &info->hdr_user_name, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, - ps, depth)) - return False; - if (!smb_io_unihdr("hdr_profile_path", &info->hdr_profile_path, - ps, depth)) - return False; - if (!smb_io_unihdr("hdr_home_dir", &info->hdr_home_dir, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth)) - return False; - - if (!prs_uint16("logon_count", ps, depth, &info->logon_count)) - return False; - if (!prs_uint16("bad_password_count", ps, depth, &info->bad_password_count)) - return False; - if (!prs_uint32("user_rid", ps, depth, &info->user_rid)) - return False; - if (!prs_uint32("group_rid", ps, depth, &info->group_rid)) - return False; - if (!prs_uint32("group_count", ps, depth, &info->group_count)) - return False; - /* I haven't seen this contain anything yet, but when it does - we will have to make sure we decode the contents in the middle - all the unistr2s ... */ - if (!prs_uint32("group_mem_ptr", ps, depth, - &info->group_membership_ptr)) - return False; - if (!prs_uint32("user_flags", ps, depth, &info->user_flags)) - return False; - - if (!prs_uint8s(False, "session_key", ps, depth, info->session_key, 16)) - return False; - - if (!smb_io_unihdr("hdr_dom_controller", - &info->hdr_dom_controller, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth)) - return False; - - /* this should be followed, but just get ptr for now */ - if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid)) - return False; - - if (!prs_uint8s(False, "lm_session_key", ps, depth, info->lm_session_key, 8)) - return False; - - if (!prs_uint32("acct_flags", ps, depth, &info->acct_flags)) - return False; - - for (i = 0; i < 7; i++) - { - if (!prs_uint32("unkown", ps, depth, &info->unknown[i])) /* unknown */ - return False; - } - - if (!prs_uint32("sid_count", ps, depth, &info->sid_count)) - return False; - if (!prs_uint32("ptr_extra_sids", ps, depth, &info->ptr_extra_sids)) - return False; - if (!prs_uint32("ptr_res_group_dom_sid", ps, depth, - &info->ptr_res_group_dom_sid)) - return False; - if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count)) - return False; - if (!prs_uint32("ptr_res_groups", ps, depth, &info->ptr_res_groups)) - return False; - - if(!smb_io_unistr2("uni_user_name", &info->uni_user_name, - info->hdr_user_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_full_name", &info->uni_full_name, - info->hdr_full_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_logon_script", &info->uni_logon_script, - info->hdr_logon_script.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_profile_path", &info->uni_profile_path, - info->hdr_profile_path.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_home_dir", &info->uni_home_dir, - info->hdr_home_dir.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive, - info->hdr_dir_drive.buffer, ps, depth)) - return False; - - if (info->group_membership_ptr) { - if (!pac_io_group_membership_array("group membership", - &info->groups, - info->group_count, - ps, depth)) - return False; - } - - - if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller, - info->hdr_dom_controller.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_dom_name", &info->uni_dom_name, - info->hdr_dom_name.buffer, ps, depth)) - return False; - - if(info->ptr_dom_sid) - if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth)) - return False; - - - if (info->sid_count && info->ptr_extra_sids) - if (!pac_io_krb_sid_and_attr_array("extra_sids", - &info->extra_sids, - info->sid_count, - ps, depth)) - return False; - - if (info->ptr_res_group_dom_sid) - if (!smb_io_dom_sid2("res_group_dom_sid", - &info->res_group_dom_sid, ps, depth)) - return False; - - if (info->ptr_res_groups) { - - if (!(info->user_flgs & LOGON_RESOURCE_GROUPS)) { - DEBUG(0,("user_flgs attribute does not have LOGON_RESOURCE_GROUPS\n")); - /* return False; */ - } - - if (!pac_io_group_membership_array("res group membership", - &info->res_groups, - info->res_group_count, - ps, depth)) - return False; - } - - return True; -} -#endif - -static bool pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info, - prs_struct *ps, int depth) -{ - uint32 garbage = 0; - bool kerb_validation_info = True; - - if (NULL == info) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_logon_info"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */ - return False; - if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */ - return False; - if (!prs_uint32("bufferlen", ps, depth, &garbage)) - return False; - if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */ - return False; - - if(!net_io_user_info3("", &info->info3, ps, depth, 3, kerb_validation_info)) - return False; - - if (info->info3.ptr_res_group_dom_sid) { - if (!smb_io_dom_sid2("res_group_dom_sid", - &info->res_group_dom_sid, ps, depth)) - return False; - } - - if (info->info3.ptr_res_groups) { - - if (!(info->info3.user_flgs & NETLOGON_RESOURCE_GROUPS)) { - DEBUG(0,("user_flgs attribute does not have NETLOGON_RESOURCE_GROUPS\n")); - /* return False; */ - } - - if (!pac_io_group_membership_array("res group membership", - &info->res_groups, - info->info3.res_group_count, - ps, depth)) - return False; - } - - return True; -} - - - -static bool pac_io_pac_signature_data(const char *desc, - PAC_SIGNATURE_DATA *data, uint32 length, - prs_struct *ps, int depth) -{ - uint32 siglen = 0; - - prs_debug(ps, depth, desc, "pac_io_pac_signature_data"); - depth++; - - if (data == NULL) - return False; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("type", ps, depth, &data->type)) - return False; - - if ( length > sizeof(uint32) ) - siglen = length - sizeof(uint32); - - if (UNMARSHALLING(ps) && length) { - if (siglen) { - data->signature.buffer = PRS_ALLOC_MEM(ps, uint8, siglen); - if (!data->signature.buffer) { - DEBUG(3, ("No memory available\n")); - return False; - } - } else { - data->signature.buffer = NULL; - } - } - - data->signature.buf_len = siglen; - - if (!prs_uint8s(False, "signature", ps, depth, data->signature.buffer, data->signature.buf_len)) - return False; - - - return True; -} - -static bool pac_io_pac_info_hdr_ctr(const char *desc, PAC_BUFFER *hdr, - prs_struct *ps, int depth) -{ - if (NULL == hdr) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_info_hdr_ctr"); - depth++; - - if (!prs_align(ps)) - return False; - - if (hdr->offset != prs_offset(ps)) { - DEBUG(5,("offset in header(x%x) and data(x%x) do not match, correcting\n", - hdr->offset, prs_offset(ps))); - prs_set_offset(ps, hdr->offset); - } - - if (UNMARSHALLING(ps) && hdr->size > 0) { - hdr->ctr = PRS_ALLOC_MEM(ps, PAC_INFO_CTR, 1); - if (!hdr->ctr) { - DEBUG(3, ("No memory available\n")); - return False; - } - } - - switch(hdr->type) { - case PAC_TYPE_LOGON_INFO: - DEBUG(5, ("PAC_TYPE_LOGON_INFO\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.logon_info = PRS_ALLOC_MEM(ps, PAC_LOGON_INFO, 1); - if (!hdr->ctr->pac.logon_info) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_pac_logon_info(desc, hdr->ctr->pac.logon_info, - ps, depth)) - return False; - break; - - case PAC_TYPE_SERVER_CHECKSUM: - DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.srv_cksum = PRS_ALLOC_MEM(ps, PAC_SIGNATURE_DATA, 1); - if (!hdr->ctr->pac.srv_cksum) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_pac_signature_data(desc, hdr->ctr->pac.srv_cksum, - hdr->size, ps, depth)) - return False; - break; - - case PAC_TYPE_PRIVSVR_CHECKSUM: - DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.privsrv_cksum = PRS_ALLOC_MEM(ps, PAC_SIGNATURE_DATA, 1); - if (!hdr->ctr->pac.privsrv_cksum) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_pac_signature_data(desc, - hdr->ctr->pac.privsrv_cksum, - hdr->size, ps, depth)) - return False; - break; - - case PAC_TYPE_LOGON_NAME: - DEBUG(5, ("PAC_TYPE_LOGON_NAME\n")); - if (UNMARSHALLING(ps)) - hdr->ctr->pac.logon_name = PRS_ALLOC_MEM(ps, PAC_LOGON_NAME, 1); - if (!hdr->ctr->pac.logon_name) { - DEBUG(3, ("No memory available\n")); - return False; - } - if (!pac_io_logon_name(desc, hdr->ctr->pac.logon_name, - ps, depth)) - return False; - break; - - default: - /* dont' know, so we need to skip it */ - DEBUG(3, ("unknown PAC type %d\n", hdr->type)); - prs_set_offset(ps, prs_offset(ps) + hdr->size); - } - -#if 0 - /* obscure pad */ - if (!prs_uint32("pad", ps, depth, &hdr->pad)) - return False; -#endif - return True; -} - -static bool pac_io_pac_info_hdr(const char *desc, PAC_BUFFER *hdr, - prs_struct *ps, int depth) -{ - if (NULL == hdr) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_info_hdr"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("type", ps, depth, &hdr->type)) - return False; - if (!prs_uint32("size", ps, depth, &hdr->size)) - return False; - if (!prs_uint32("offset", ps, depth, &hdr->offset)) - return False; - if (!prs_uint32("offsethi", ps, depth, &hdr->offsethi)) - return False; - - return True; -} - -static bool pac_io_pac_data(const char *desc, PAC_DATA *data, - prs_struct *ps, int depth) -{ - int i; - - if (NULL == data) - return False; - - prs_debug(ps, depth, desc, "pac_io_pac_data"); - depth++; - - if (!prs_align(ps)) - return False; - if (!prs_uint32("num_buffers", ps, depth, &data->num_buffers)) - return False; - if (!prs_uint32("version", ps, depth, &data->version)) - return False; - - if (UNMARSHALLING(ps) && data->num_buffers > 0) { - if ((data->pac_buffer = PRS_ALLOC_MEM(ps, PAC_BUFFER, data->num_buffers)) == NULL) { - return False; - } - } - - for (i=0; i<data->num_buffers; i++) { - if (!pac_io_pac_info_hdr(desc, &data->pac_buffer[i], ps, - depth)) - return False; - } - - for (i=0; i<data->num_buffers; i++) { - if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_buffer[i], - ps, depth)) - return False; - } - - return True; -} +/**************************************************************** +****************************************************************/ -static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx, - DATA_BLOB pac_data, - PAC_SIGNATURE_DATA *sig, - krb5_context context, - krb5_keyblock *keyblock) +static krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, + DATA_BLOB pac_data, + struct PAC_SIGNATURE_DATA *sig, + krb5_context context, + krb5_keyblock *keyblock) { krb5_error_code ret; krb5_checksum cksum; @@ -663,299 +49,289 @@ static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx, #error UNKNOWN_KRB5_KEYUSAGE #endif - ret = smb_krb5_verify_checksum(context, - keyblock, - usage, + ret = smb_krb5_verify_checksum(context, + keyblock, + usage, &cksum, - pac_data.data, + pac_data.data, pac_data.length); if (ret) { - DEBUG(2,("check_pac_checksum: PAC Verification failed: %s (%d)\n", + DEBUG(2,("check_pac_checksum: PAC Verification failed: %s (%d)\n", error_message(ret), ret)); - return NT_STATUS_ACCESS_DENIED; + return ret; } - return NT_STATUS_OK; -} - -static NTSTATUS parse_pac_data(TALLOC_CTX *mem_ctx, DATA_BLOB *pac_data_blob, PAC_DATA *pac_data) -{ - prs_struct ps; - PAC_DATA *my_pac; - - if (!prs_init(&ps, pac_data_blob->length, mem_ctx, UNMARSHALL)) - return NT_STATUS_NO_MEMORY; - - if (!prs_copy_data_in(&ps, (char *)pac_data_blob->data, pac_data_blob->length)) - return NT_STATUS_INVALID_PARAMETER; - - prs_set_offset(&ps, 0); - - my_pac = TALLOC_ZERO_P(mem_ctx, PAC_DATA); - if (!pac_io_pac_data("pac data", my_pac, &ps, 0)) - return NT_STATUS_INVALID_PARAMETER; - - prs_mem_free(&ps); - - *pac_data = *my_pac; - - return NT_STATUS_OK; -} - -/* just for debugging, will be removed later - Guenther */ -char *pac_group_attr_string(uint32 attr) -{ - fstring name = ""; - - if (!attr) - return NULL; - - if (attr & SE_GROUP_MANDATORY) fstrcat(name, "SE_GROUP_MANDATORY "); - if (attr & SE_GROUP_ENABLED_BY_DEFAULT) fstrcat(name, "SE_GROUP_ENABLED_BY_DEFAULT "); - if (attr & SE_GROUP_ENABLED) fstrcat(name, "SE_GROUP_ENABLED "); - if (attr & SE_GROUP_OWNER) fstrcat(name, "SE_GROUP_OWNER "); - if (attr & SE_GROUP_USE_FOR_DENY_ONLY) fstrcat(name, "SE_GROUP_USE_FOR_DENY_ONLY "); - if (attr & SE_GROUP_LOGON_ID) fstrcat(name, "SE_GROUP_LOGON_ID "); - if (attr & SE_GROUP_RESOURCE) fstrcat(name, "SE_GROUP_RESOURCE "); - - return SMB_STRDUP(name); + return ret; } -/* just for debugging, will be removed later - Guenther */ -void dump_pac_logon_info(int lvl, PAC_LOGON_INFO *logon_info) -{ - DOM_SID dom_sid, res_group_dom_sid; - int i; - char *attr_string; - uint32 user_flgs = logon_info->info3.user_flgs; - - if (logon_info->info3.ptr_res_group_dom_sid) { - sid_copy(&res_group_dom_sid, &logon_info->res_group_dom_sid.sid); - } - sid_copy(&dom_sid, &logon_info->info3.dom_sid.sid); - - DEBUG(lvl,("The PAC:\n")); - - DEBUGADD(lvl,("\tUser Flags: 0x%x (%d)\n", user_flgs, user_flgs)); - if (user_flgs & NETLOGON_EXTRA_SIDS) - DEBUGADD(lvl,("\tUser Flags: NETLOGON_EXTRA_SIDS 0x%x (%d)\n", NETLOGON_EXTRA_SIDS, NETLOGON_EXTRA_SIDS)); - if (user_flgs & NETLOGON_RESOURCE_GROUPS) - DEBUGADD(lvl,("\tUser Flags: NETLOGON_RESOURCE_GROUPS 0x%x (%d)\n", NETLOGON_RESOURCE_GROUPS, NETLOGON_RESOURCE_GROUPS)); - DEBUGADD(lvl,("\tUser SID: %s-%d\n", sid_string_dbg(&dom_sid), - logon_info->info3.user_rid)); - DEBUGADD(lvl,("\tGroup SID: %s-%d\n", sid_string_dbg(&dom_sid), - logon_info->info3.group_rid)); - - DEBUGADD(lvl,("\tGroup Membership (Global and Universal Groups of own domain):\n")); - for (i = 0; i < logon_info->info3.num_groups; i++) { - attr_string = pac_group_attr_string(logon_info->info3.gids[i].attr); - DEBUGADD(lvl,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", - i, sid_string_dbg(&dom_sid), - logon_info->info3.gids[i].g_rid, - logon_info->info3.gids[i].attr, - attr_string)); - SAFE_FREE(attr_string); - } - - DEBUGADD(lvl,("\tGroup Membership (Domain Local Groups and Groups from Trusted Domains):\n")); - for (i = 0; i < logon_info->info3.num_other_sids; i++) { - attr_string = pac_group_attr_string(logon_info->info3.other_sids_attrib[i]); - DEBUGADD(lvl,("\t\t%d: sid: %s\n\t\t attr: 0x%x == %s\n", - i, sid_string_dbg( - &logon_info->info3.other_sids[i].sid), - logon_info->info3.other_sids_attrib[i], - attr_string)); - SAFE_FREE(attr_string); - } - - DEBUGADD(lvl,("\tGroup Membership (Resource Groups (SID History ?)):\n")); - for (i = 0; i < logon_info->info3.res_group_count; i++) { - attr_string = pac_group_attr_string(logon_info->res_groups.group_membership[i].attrs); - DEBUGADD(lvl,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n", - i, sid_string_dbg(&res_group_dom_sid), - logon_info->res_groups.group_membership[i].rid, - logon_info->res_groups.group_membership[i].attrs, - attr_string)); - SAFE_FREE(attr_string); - } -} +/**************************************************************** +****************************************************************/ NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx, DATA_BLOB *pac_data_blob, - krb5_context context, + krb5_context context, krb5_keyblock *service_keyblock, krb5_const_principal client_principal, time_t tgs_authtime, - PAC_DATA **pac_data) - + struct PAC_DATA **pac_data_out) { - DATA_BLOB modified_pac_blob; - PAC_DATA *my_pac; - NTSTATUS nt_status; + NTSTATUS status; + enum ndr_err_code ndr_err; krb5_error_code ret; - PAC_SIGNATURE_DATA *srv_sig = NULL; - PAC_SIGNATURE_DATA *kdc_sig = NULL; - PAC_LOGON_NAME *logon_name = NULL; - PAC_LOGON_INFO *logon_info = NULL; - krb5_principal client_principal_pac = NULL; - NTTIME tgs_authtime_nttime; - int i, srv_sig_pos = 0, kdc_sig_pos = 0; - fstring username; + DATA_BLOB modified_pac_blob; - *pac_data = NULL; + NTTIME tgs_authtime_nttime; + krb5_principal client_principal_pac = NULL; + int i; - my_pac = talloc(mem_ctx, PAC_DATA); - if (!my_pac) { + struct PAC_SIGNATURE_DATA *srv_sig_ptr = NULL; + struct PAC_SIGNATURE_DATA *kdc_sig_ptr = NULL; + struct PAC_SIGNATURE_DATA *srv_sig_wipe = NULL; + struct PAC_SIGNATURE_DATA *kdc_sig_wipe = NULL; + struct PAC_LOGON_NAME *logon_name = NULL; + struct PAC_LOGON_INFO *logon_info = NULL; + struct PAC_DATA *pac_data = NULL; + struct PAC_DATA_RAW *pac_data_raw = NULL; + + DATA_BLOB *srv_sig_blob = NULL; + DATA_BLOB *kdc_sig_blob = NULL; + + *pac_data_out = NULL; + + pac_data = TALLOC_ZERO_P(mem_ctx, struct PAC_DATA); + pac_data_raw = TALLOC_ZERO_P(mem_ctx, struct PAC_DATA_RAW); + kdc_sig_wipe = TALLOC_ZERO_P(mem_ctx, struct PAC_SIGNATURE_DATA); + srv_sig_wipe = TALLOC_ZERO_P(mem_ctx, struct PAC_SIGNATURE_DATA); + if (!pac_data_raw || !pac_data || !kdc_sig_wipe || !srv_sig_wipe) { return NT_STATUS_NO_MEMORY; } - nt_status = parse_pac_data(mem_ctx, pac_data_blob, my_pac); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("decode_pac_data: failed to parse PAC\n")); - return nt_status; + ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data, + pac_data, + (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't parse the PAC: %s\n", + nt_errstr(status))); + return status; } - modified_pac_blob = data_blob_talloc(mem_ctx, pac_data_blob->data, pac_data_blob->length); + if (pac_data->num_buffers < 4) { + /* we need logon_ingo, service_key and kdc_key */ + DEBUG(0,("less than 4 PAC buffers\n")); + return NT_STATUS_INVALID_PARAMETER; + } - if (my_pac->num_buffers < 4) { - nt_status = NT_STATUS_INVALID_PARAMETER; - goto out; + ndr_err = ndr_pull_struct_blob(pac_data_blob, pac_data_raw, + pac_data_raw, + (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't parse the PAC: %s\n", + nt_errstr(status))); + return status; + } + + if (pac_data_raw->num_buffers < 4) { + /* we need logon_ingo, service_key and kdc_key */ + DEBUG(0,("less than 4 PAC buffers\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (pac_data->num_buffers != pac_data_raw->num_buffers) { + /* we need logon_ingo, service_key and kdc_key */ + DEBUG(0,("misparse! PAC_DATA has %d buffers while PAC_DATA_RAW has %d\n", + pac_data->num_buffers, pac_data_raw->num_buffers)); + return NT_STATUS_INVALID_PARAMETER; } - /* store signatures */ - for (i=0; i < my_pac->num_buffers; i++) { - - switch (my_pac->pac_buffer[i].type) { - - case PAC_TYPE_SERVER_CHECKSUM: - if (!my_pac->pac_buffer[i].ctr->pac.srv_cksum) { + for (i=0; i < pac_data->num_buffers; i++) { + if (pac_data->buffers[i].type != pac_data_raw->buffers[i].type) { + DEBUG(0,("misparse! PAC_DATA buffer %d has type %d while PAC_DATA_RAW has %d\n", + i, pac_data->buffers[i].type, pac_data->buffers[i].type)); + return NT_STATUS_INVALID_PARAMETER; + } + switch (pac_data->buffers[i].type) { + case PAC_TYPE_LOGON_INFO: + if (!pac_data->buffers[i].info) { break; } - - srv_sig = my_pac->pac_buffer[i].ctr->pac.srv_cksum; - - /* get position of signature buffer */ - srv_sig_pos = my_pac->pac_buffer[i].offset; - srv_sig_pos += sizeof(uint32); - + logon_info = pac_data->buffers[i].info->logon_info.info; break; - - case PAC_TYPE_PRIVSVR_CHECKSUM: - if (!my_pac->pac_buffer[i].ctr->pac.privsrv_cksum) { + case PAC_TYPE_SRV_CHECKSUM: + if (!pac_data->buffers[i].info) { break; } - - kdc_sig = my_pac->pac_buffer[i].ctr->pac.privsrv_cksum; - - /* get position of signature buffer */ - kdc_sig_pos = my_pac->pac_buffer[i].offset; - kdc_sig_pos += sizeof(uint32); - + srv_sig_ptr = &pac_data->buffers[i].info->srv_cksum; + srv_sig_blob = &pac_data_raw->buffers[i].info->remaining; break; - - case PAC_TYPE_LOGON_NAME: - if (!my_pac->pac_buffer[i].ctr->pac.logon_name) { + case PAC_TYPE_KDC_CHECKSUM: + if (!pac_data->buffers[i].info) { break; } - - logon_name = my_pac->pac_buffer[i].ctr->pac.logon_name; + kdc_sig_ptr = &pac_data->buffers[i].info->kdc_cksum; + kdc_sig_blob = &pac_data_raw->buffers[i].info->remaining; + break; + case PAC_TYPE_LOGON_NAME: + logon_name = &pac_data->buffers[i].info->logon_name; + break; + default: break; + } + } - case PAC_TYPE_LOGON_INFO: - if (!my_pac->pac_buffer[i].ctr->pac.logon_info) { - break; - } + if (!logon_info) { + DEBUG(0,("PAC no logon_info\n")); + return NT_STATUS_INVALID_PARAMETER; + } - logon_info = my_pac->pac_buffer[i].ctr->pac.logon_info; - break; - } + if (!logon_name) { + DEBUG(0,("PAC no logon_name\n")); + return NT_STATUS_INVALID_PARAMETER; + } + if (!srv_sig_ptr || !srv_sig_blob) { + DEBUG(0,("PAC no srv_key\n")); + return NT_STATUS_INVALID_PARAMETER; } - if (!srv_sig || !kdc_sig || !logon_name || !logon_info) { - nt_status = NT_STATUS_INVALID_PARAMETER; - goto out; + if (!kdc_sig_ptr || !kdc_sig_blob) { + DEBUG(0,("PAC no kdc_key\n")); + return NT_STATUS_INVALID_PARAMETER; } - /* zero PAC_SIGNATURE_DATA signature buffer */ - memset(&modified_pac_blob.data[srv_sig_pos], '\0', srv_sig->signature.buf_len); - memset(&modified_pac_blob.data[kdc_sig_pos], '\0', kdc_sig->signature.buf_len); + /* Find and zero out the signatures, as required by the signing algorithm */ - /* check server signature */ - nt_status = check_pac_checksum(mem_ctx, modified_pac_blob, srv_sig, context, service_keyblock); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("decode_pac_data: failed to verify PAC server signature\n")); - goto out; + /* We find the data blobs above, now we parse them to get at the exact portion we should zero */ + ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe, + kdc_sig_wipe, + (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't parse the KDC signature: %s\n", + nt_errstr(status))); + return status; } - /* Convert to NT time, so as not to loose accuracy in comparison */ - unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime); + ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe, + srv_sig_wipe, + (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't parse the SRV signature: %s\n", + nt_errstr(status))); + return status; + } - if (!nt_time_equals(&tgs_authtime_nttime, &logon_name->logon_time)) { - - DEBUG(2,("decode_pac_data: Logon time mismatch between ticket and PAC!\n")); - DEBUGADD(2, ("decode_pac_data: PAC: %s\n", - http_timestring(nt_time_to_unix(logon_name->logon_time)))); - DEBUGADD(2, ("decode_pac_data: Ticket: %s\n", - http_timestring(nt_time_to_unix(tgs_authtime_nttime)))); - - nt_status = NT_STATUS_ACCESS_DENIED; - goto out; + /* Now zero the decoded structure */ + memset(kdc_sig_wipe->signature.data, '\0', kdc_sig_wipe->signature.length); + memset(srv_sig_wipe->signature.data, '\0', srv_sig_wipe->signature.length); + + /* and reencode, back into the same place it came from */ + ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw, + kdc_sig_wipe, + (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't repack the KDC signature: %s\n", + nt_errstr(status))); + return status; + } + ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw, + srv_sig_wipe, + (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't repack the SRV signature: %s\n", + nt_errstr(status))); + return status; } - if (!logon_name->len) { - DEBUG(2,("decode_pac_data: No Logon Name available\n")); - nt_status = NT_STATUS_INVALID_PARAMETER; - goto out; + /* push out the whole structure, but now with zero'ed signatures */ + ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw, + pac_data_raw, + (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("can't repack the RAW PAC: %s\n", + nt_errstr(status))); + return status; } - rpcstr_pull(username, logon_name->username, sizeof(username), logon_name->len, 0); - ret = smb_krb5_parse_name_norealm(context, username, &client_principal_pac); + /* verify by service_key */ + ret = check_pac_checksum(mem_ctx, + modified_pac_blob, srv_sig_ptr, + context, + service_keyblock); if (ret) { - DEBUG(2,("decode_pac_data: Could not parse name from incoming PAC: [%s]: %s\n", - username, error_message(ret))); - nt_status = NT_STATUS_INVALID_PARAMETER; - goto out; + DEBUG(1, ("PAC Decode: Failed to verify the service signature: %s\n", + error_message(ret))); + return NT_STATUS_ACCESS_DENIED; } - if (!smb_krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) { - DEBUG(2,("decode_pac_data: Name in PAC [%s] does not match principal name in ticket\n", - username)); - nt_status = NT_STATUS_ACCESS_DENIED; - goto out; + /* Convert to NT time, so as not to loose accuracy in comparison */ + unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime); + + if (tgs_authtime_nttime != logon_name->logon_time) { + DEBUG(2, ("PAC Decode: Logon time mismatch between ticket and PAC!\n")); + DEBUG(2, ("PAC Decode: PAC: %s\n", nt_time_string(mem_ctx, logon_name->logon_time))); + DEBUG(2, ("PAC Decode: Ticket: %s\n", nt_time_string(mem_ctx, tgs_authtime_nttime))); + return NT_STATUS_ACCESS_DENIED; } - DEBUG(10,("Successfully validated Kerberos PAC\n")); + ret = smb_krb5_parse_name_norealm(context, logon_name->account_name, + &client_principal_pac); + if (ret) { + DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n", + logon_name->account_name, + error_message(ret))); + return NT_STATUS_INVALID_PARAMETER; + } - dump_pac_logon_info(10, logon_info); + if (!smb_krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) { + DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n", + logon_name->account_name)); + krb5_free_principal(context, client_principal_pac); + return NT_STATUS_ACCESS_DENIED; + } - *pac_data = my_pac; + DEBUG(3,("Found account name from PAC: %s [%s]\n", + logon_info->info3.base.account_name.string, + logon_info->info3.base.full_name.string)); - nt_status = NT_STATUS_OK; + DEBUG(10,("Successfully validated Kerberos PAC\n")); -out: - if (client_principal_pac) { - krb5_free_principal(context, client_principal_pac); + if (DEBUGLEVEL >= 10) { + const char *s; + s = NDR_PRINT_STRUCT_STRING(mem_ctx, PAC_DATA, pac_data); + if (s) { + DEBUGADD(10,("%s\n", s)); + } } - return nt_status; + *pac_data_out = pac_data; + + return NT_STATUS_OK; } - PAC_LOGON_INFO *get_logon_info_from_pac(PAC_DATA *pac_data) +/**************************************************************** +****************************************************************/ + +struct PAC_LOGON_INFO *get_logon_info_from_pac(struct PAC_DATA *pac_data) { - PAC_LOGON_INFO *logon_info = NULL; int i; - + for (i=0; i < pac_data->num_buffers; i++) { - if (pac_data->pac_buffer[i].type != PAC_TYPE_LOGON_INFO) + if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) { continue; + } - logon_info = pac_data->pac_buffer[i].ctr->pac.logon_info; - break; + return pac_data->buffers[i].info->logon_info.info; } - return logon_info; + + return NULL; } /**************************************************************** @@ -971,12 +347,12 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, bool request_pac, bool add_netbios_addr, time_t renewable_time, - PAC_DATA **pac_ret) + struct PAC_DATA **pac_ret) { krb5_error_code ret; NTSTATUS status = NT_STATUS_INVALID_PARAMETER; DATA_BLOB tkt, ap_rep, sesskey1, sesskey2; - PAC_DATA *pac_data = NULL; + struct PAC_DATA *pac_data = NULL; char *client_princ_out = NULL; const char *auth_princ = NULL; const char *local_service = NULL; @@ -1110,11 +486,11 @@ static NTSTATUS kerberos_return_pac_logon_info(TALLOC_CTX *mem_ctx, bool request_pac, bool add_netbios_addr, time_t renewable_time, - PAC_LOGON_INFO **logon_info) + struct PAC_LOGON_INFO **logon_info) { NTSTATUS status; - PAC_DATA *pac_data = NULL; - PAC_LOGON_INFO *info = NULL; + struct PAC_DATA *pac_data = NULL; + struct PAC_LOGON_INFO *info = NULL; status = kerberos_return_pac(mem_ctx, name, @@ -1160,10 +536,10 @@ NTSTATUS kerberos_return_info3_from_pac(TALLOC_CTX *mem_ctx, bool request_pac, bool add_netbios_addr, time_t renewable_time, - NET_USER_INFO_3 **info3) + struct netr_SamInfo3 **info3) { NTSTATUS status; - PAC_LOGON_INFO *logon_info = NULL; + struct PAC_LOGON_INFO *logon_info = NULL; status = kerberos_return_pac_logon_info(mem_ctx, name, diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index d47e8a3ff1..b37b9a500f 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -407,8 +407,8 @@ static char *kerberos_secrets_fetch_salting_principal(const char *service, int e char *key = NULL; char *ret = NULL; - asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, service, enctype); - if (!key) { + if (asprintf(&key, "%s/%s/enctype=%d", + SECRETS_SALTING_PRINCIPAL, service, enctype) == -1) { return NULL; } ret = (char *)secrets_fetch(key, NULL); @@ -438,7 +438,10 @@ static char* des_salt_key( void ) { char *key; - asprintf(&key, "%s/DES/%s", SECRETS_SALTING_PRINCIPAL, lp_realm()); + if (asprintf(&key, "%s/DES/%s", SECRETS_SALTING_PRINCIPAL, + lp_realm()) == -1) { + return NULL; + } return key; } @@ -609,9 +612,13 @@ bool kerberos_secrets_store_salting_principal(const char *service, return False; } if (strchr_m(service, '@')) { - asprintf(&princ_s, "%s", service); + if (asprintf(&princ_s, "%s", service) == -1) { + goto out; + } } else { - asprintf(&princ_s, "%s@%s", service, lp_realm()); + if (asprintf(&princ_s, "%s@%s", service, lp_realm()) == -1) { + goto out; + } } if (smb_krb5_parse_name(context, princ_s, &princ) != 0) { @@ -622,8 +629,9 @@ bool kerberos_secrets_store_salting_principal(const char *service, goto out; } - asprintf(&key, "%s/%s/enctype=%d", SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype); - if (!key) { + if (asprintf(&key, "%s/%s/enctype=%d", + SECRETS_SALTING_PRINCIPAL, unparsed_name, enctype) + == -1) { goto out; } diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c index 5ce7aa6b45..f112dd34e3 100644 --- a/source3/libads/kerberos_verify.c +++ b/source3/libads/kerberos_verify.c @@ -309,7 +309,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, time_t time_offset, const DATA_BLOB *ticket, char **principal, - PAC_DATA **pac_data, + struct PAC_DATA **pac_data, DATA_BLOB *ap_rep, DATA_BLOB *session_key, bool use_replay_cache) diff --git a/source3/libgpo/gpext/gpext.c b/source3/libgpo/gpext/gpext.c new file mode 100644 index 0000000000..184a2fa185 --- /dev/null +++ b/source3/libgpo/gpext/gpext.c @@ -0,0 +1,746 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Support + * Copyright (C) Guenther Deschner 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 + * 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" + +static struct gp_extension *extensions = NULL; + +/**************************************************************** +****************************************************************/ + +struct gp_extension *get_gp_extension_list(void) +{ + return extensions; +} + +/**************************************************************** +****************************************************************/ + +/* see http://support.microsoft.com/kb/216358/en-us/ for more info */ + +struct gp_extension_reg_table gpext_reg_vals[] = { + { "DllName", REG_EXPAND_SZ }, + { "ProcessGroupPolicy", REG_SZ }, + { "NoMachinePolicy", REG_DWORD }, + { "NoUserPolicy", REG_DWORD }, + { "NoSlowLink", REG_DWORD }, + { "NoBackgroundPolicy", REG_DWORD }, + { "NoGPOListChanges", REG_DWORD }, + { "PerUserLocalSettings", REG_DWORD }, + { "RequiresSuccessfulRegistry", REG_DWORD }, + { "EnableAsynchronousProcessing", REG_DWORD }, + { "ExtensionDebugLevel", REG_DWORD }, + /* new */ + { "GenerateGroupPolicy", REG_SZ }, /* not supported on w2k */ + { "NotifyLinkTransition", REG_DWORD }, + { "ProcessGroupPolicyEx", REG_SZ }, /* not supported on w2k */ + { "ExtensionEventSource", REG_MULTI_SZ }, /* not supported on w2k */ + { "GenerateGroupPolicy", REG_SZ }, + { "MaxNoGPOListChangesInterval", REG_DWORD }, + { NULL, REG_NONE } +}; + +/**************************************************************** +****************************************************************/ + +static struct gp_extension *get_extension_by_name(struct gp_extension *be, + const char *name) +{ + struct gp_extension *b; + + for (b = be; b; b = b->next) { + if (strequal(b->name, name)) { + return b; + } + } + + return NULL; +} + +/**************************************************************** +****************************************************************/ + +static struct gp_extension_methods *get_methods_by_name(struct gp_extension *be, + const char *name) +{ + struct gp_extension *b; + + for (b = be; b; b = b->next) { + if (strequal(b->name, name)) { + return b->methods; + } + } + + return NULL; +} + +/**************************************************************** +****************************************************************/ + +NTSTATUS unregister_gp_extension(const char *name) +{ + struct gp_extension *ext; + + ext = get_extension_by_name(extensions, name); + if (!ext) { + return NT_STATUS_OK; + } + + DLIST_REMOVE(extensions, ext); + TALLOC_FREE(ext); + + DEBUG(2,("Successfully removed GP extension '%s'\n", name)); + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +NTSTATUS register_gp_extension(TALLOC_CTX *gpext_ctx, + int version, + const char *name, + const char *guid, + struct gp_extension_methods *methods) +{ + struct gp_extension_methods *test; + struct gp_extension *entry; + NTSTATUS status; + + if (!gpext_ctx) { + return NT_STATUS_INTERNAL_DB_ERROR; + } + + if ((version != SMB_GPEXT_INTERFACE_VERSION)) { + DEBUG(0,("Failed to register gp extension.\n" + "The module was compiled against " + "SMB_GPEXT_INTERFACE_VERSION %d,\n" + "current SMB_GPEXT_INTERFACE_VERSION is %d.\n" + "Please recompile against the current " + "version of samba!\n", + version, SMB_GPEXT_INTERFACE_VERSION)); + return NT_STATUS_OBJECT_TYPE_MISMATCH; + } + + if (!guid || !name || !name[0] || !methods) { + DEBUG(0,("Called with NULL pointer or empty name!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + test = get_methods_by_name(extensions, name); + if (test) { + DEBUG(0,("GP extension module %s already registered!\n", + name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + entry = TALLOC_ZERO_P(gpext_ctx, struct gp_extension); + NT_STATUS_HAVE_NO_MEMORY(entry); + + entry->name = talloc_strdup(gpext_ctx, name); + NT_STATUS_HAVE_NO_MEMORY(entry->name); + + entry->guid = TALLOC_ZERO_P(gpext_ctx, struct GUID); + NT_STATUS_HAVE_NO_MEMORY(entry->guid); + status = GUID_from_string(guid, entry->guid); + NT_STATUS_NOT_OK_RETURN(status); + + entry->methods = methods; + DLIST_ADD(extensions, entry); + + DEBUG(2,("Successfully added GP extension '%s' %s\n", + name, GUID_string2(gpext_ctx, entry->guid))); + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS gp_extension_init_module(TALLOC_CTX *mem_ctx, + const char *name, + struct gp_extension **gpext) +{ + NTSTATUS status; + struct gp_extension *ext = NULL; + + ext = TALLOC_ZERO_P(mem_ctx, struct gp_extension); + NT_STATUS_HAVE_NO_MEMORY(gpext); + + ext->methods = get_methods_by_name(extensions, name); + if (!ext->methods) { + + status = smb_probe_module(SAMBA_SUBSYSTEM_GPEXT, + name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ext->methods = get_methods_by_name(extensions, name); + if (!ext->methods) { + return NT_STATUS_DLL_INIT_FAILED; + } + } + + *gpext = ext; + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static bool add_gp_extension_reg_entry_to_array(TALLOC_CTX *mem_ctx, + struct gp_extension_reg_entry *entry, + struct gp_extension_reg_entry **entries, + size_t *num) +{ + *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries, + struct gp_extension_reg_entry, + (*num)+1); + if (*entries == NULL) { + *num = 0; + return false; + } + + (*entries)[*num].value = entry->value; + (*entries)[*num].data = entry->data; + + *num += 1; + return true; +} + +/**************************************************************** +****************************************************************/ + +static bool add_gp_extension_reg_info_entry_to_array(TALLOC_CTX *mem_ctx, + struct gp_extension_reg_info_entry *entry, + struct gp_extension_reg_info_entry **entries, + size_t *num) +{ + *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries, + struct gp_extension_reg_info_entry, + (*num)+1); + if (*entries == NULL) { + *num = 0; + return false; + } + + (*entries)[*num].guid = entry->guid; + (*entries)[*num].num_entries = entry->num_entries; + (*entries)[*num].entries = entry->entries; + + *num += 1; + return true; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS gp_ext_info_add_reg(TALLOC_CTX *mem_ctx, + struct gp_extension_reg_info_entry *entry, + const char *value, + enum winreg_Type type, + const char *data_s) +{ + struct gp_extension_reg_entry *reg_entry = NULL; + struct registry_value *data = NULL; + + reg_entry = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_entry); + NT_STATUS_HAVE_NO_MEMORY(reg_entry); + + data = TALLOC_ZERO_P(mem_ctx, struct registry_value); + NT_STATUS_HAVE_NO_MEMORY(data); + + data->type = type; + + switch (type) { + case REG_SZ: + case REG_EXPAND_SZ: + data->v.sz.str = talloc_strdup(mem_ctx, data_s); + NT_STATUS_HAVE_NO_MEMORY(data->v.sz.str); + data->v.sz.len = strlen(data_s); + break; + case REG_DWORD: + data->v.dword = atoi(data_s); + break; + default: + return NT_STATUS_NOT_SUPPORTED; + } + + reg_entry->value = value; + reg_entry->data = data; + + if (!add_gp_extension_reg_entry_to_array(mem_ctx, reg_entry, + &entry->entries, + &entry->num_entries)) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS gp_ext_info_add_reg_table(TALLOC_CTX *mem_ctx, + const char *module, + struct gp_extension_reg_info_entry *entry, + struct gp_extension_reg_table *table) +{ + NTSTATUS status; + const char *module_name = NULL; + int i; + + module_name = talloc_asprintf(mem_ctx, "%s.%s", module, shlib_ext()); + NT_STATUS_HAVE_NO_MEMORY(module_name); + + status = gp_ext_info_add_reg(mem_ctx, entry, + "DllName", REG_EXPAND_SZ, module_name); + NT_STATUS_NOT_OK_RETURN(status); + + for (i=0; table[i].val; i++) { + status = gp_ext_info_add_reg(mem_ctx, entry, + table[i].val, + table[i].type, + table[i].data); + NT_STATUS_NOT_OK_RETURN(status); + } + + return status; +} + +/**************************************************************** +****************************************************************/ + +NTSTATUS gp_ext_info_add_entry(TALLOC_CTX *mem_ctx, + const char *module, + const char *ext_guid, + struct gp_extension_reg_table *table, + struct gp_extension_reg_info *info) +{ + NTSTATUS status; + struct gp_extension_reg_info_entry *entry = NULL; + + entry = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_info_entry); + NT_STATUS_HAVE_NO_MEMORY(entry); + + status = GUID_from_string(ext_guid, &entry->guid); + NT_STATUS_NOT_OK_RETURN(status); + + status = gp_ext_info_add_reg_table(mem_ctx, module, entry, table); + NT_STATUS_NOT_OK_RETURN(status); + + if (!add_gp_extension_reg_info_entry_to_array(mem_ctx, entry, + &info->entries, + &info->num_entries)) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static bool gp_extension_reg_info_verify_entry(struct gp_extension_reg_entry *entry) +{ + int i; + + for (i=0; gpext_reg_vals[i].val; i++) { + + if ((strequal(entry->value, gpext_reg_vals[i].val)) && + (entry->data->type == gpext_reg_vals[i].type)) { + return true; + } + } + + return false; +} + +/**************************************************************** +****************************************************************/ + +static bool gp_extension_reg_info_verify(struct gp_extension_reg_info_entry *entry) +{ + int i; + + for (i=0; i < entry->num_entries; i++) { + if (!gp_extension_reg_info_verify_entry(&entry->entries[i])) { + return false; + } + } + + return true; +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_extension_store_reg_vals(TALLOC_CTX *mem_ctx, + struct registry_key *key, + struct gp_extension_reg_info_entry *entry) +{ + WERROR werr = WERR_OK; + size_t i; + + for (i=0; i < entry->num_entries; i++) { + + werr = reg_setvalue(key, + entry->entries[i].value, + entry->entries[i].data); + W_ERROR_NOT_OK_RETURN(werr); + } + + return werr; +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_extension_store_reg_entry(TALLOC_CTX *mem_ctx, + struct gp_registry_context *reg_ctx, + struct gp_extension_reg_info_entry *entry) +{ + WERROR werr; + struct registry_key *key = NULL; + const char *subkeyname = NULL; + + if (!gp_extension_reg_info_verify(entry)) { + return WERR_INVALID_PARAM; + } + + subkeyname = GUID_string2(mem_ctx, &entry->guid); + W_ERROR_HAVE_NO_MEMORY(subkeyname); + + strupper_m(CONST_DISCARD(char *,subkeyname)); + + werr = gp_store_reg_subkey(mem_ctx, + subkeyname, + reg_ctx->curr_key, + &key); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_extension_store_reg_vals(mem_ctx, + key, + entry); + W_ERROR_NOT_OK_RETURN(werr); + + return werr; +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_extension_store_reg(TALLOC_CTX *mem_ctx, + struct gp_registry_context *reg_ctx, + struct gp_extension_reg_info *info) +{ + WERROR werr = WERR_OK; + int i; + + if (!info) { + return WERR_OK; + } + + for (i=0; i < info->num_entries; i++) { + werr = gp_extension_store_reg_entry(mem_ctx, + reg_ctx, + &info->entries[i]); + W_ERROR_NOT_OK_RETURN(werr); + } + + return werr; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS gp_glob_ext_list(TALLOC_CTX *mem_ctx, + const char ***ext_list, + size_t *ext_list_len) +{ + SMB_STRUCT_DIR *dir = NULL; + SMB_STRUCT_DIRENT *dirent = NULL; + + dir = sys_opendir(lib_path(SAMBA_SUBSYSTEM_GPEXT)); + if (!dir) { + return map_nt_error_from_unix(errno); + } + + while ((dirent = sys_readdir(dir))) { + + fstring name; /* forgive me... */ + char *p; + + if ((strequal(dirent->d_name, ".")) || + (strequal(dirent->d_name, ".."))) { + continue; + } + + p = strrchr(dirent->d_name, '.'); + if (!p) { + sys_closedir(dir); + return NT_STATUS_NO_MEMORY; + } + + if (!strcsequal(p+1, shlib_ext())) { + DEBUG(10,("gp_glob_ext_list: not a *.so file: %s\n", + dirent->d_name)); + continue; + } + + fstrcpy(name, dirent->d_name); + name[PTR_DIFF(p, dirent->d_name)] = 0; + + if (!add_string_to_array(mem_ctx, name, ext_list, + (int *)ext_list_len)) { + sys_closedir(dir); + return NT_STATUS_NO_MEMORY; + } + } + + sys_closedir(dir); + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +NTSTATUS shutdown_gp_extensions(void) +{ + struct gp_extension *ext = NULL; + + for (ext = extensions; ext; ext = ext->next) { + if (ext->methods && ext->methods->shutdown) { + ext->methods->shutdown(); + } + } + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +NTSTATUS init_gp_extensions(TALLOC_CTX *mem_ctx) +{ + NTSTATUS status; + WERROR werr; + int i = 0; + const char **ext_array = NULL; + size_t ext_array_len = 0; + struct gp_extension *gpext = NULL; + struct gp_registry_context *reg_ctx = NULL; + + if (get_gp_extension_list()) { + return NT_STATUS_OK; + } + + status = gp_glob_ext_list(mem_ctx, &ext_array, &ext_array_len); + NT_STATUS_NOT_OK_RETURN(status); + + for (i=0; i<ext_array_len; i++) { + + struct gp_extension_reg_info *info = NULL; + + status = gp_extension_init_module(mem_ctx, ext_array[i], + &gpext); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + if (gpext->methods->get_reg_config) { + + status = gpext->methods->initialize(mem_ctx); + if (!NT_STATUS_IS_OK(status)) { + gpext->methods->shutdown(); + goto out; + } + + status = gpext->methods->get_reg_config(mem_ctx, + &info); + if (!NT_STATUS_IS_OK(status)) { + gpext->methods->shutdown(); + goto out; + } + + if (!reg_ctx) { + struct nt_user_token *token; + + token = registry_create_system_token(mem_ctx); + NT_STATUS_HAVE_NO_MEMORY(token); + + werr = gp_init_reg_ctx(mem_ctx, + KEY_WINLOGON_GPEXT_PATH, + REG_KEY_WRITE, + token, + ®_ctx); + if (!W_ERROR_IS_OK(werr)) { + status = werror_to_ntstatus(werr); + gpext->methods->shutdown(); + goto out; + } + } + + werr = gp_extension_store_reg(mem_ctx, reg_ctx, info); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(1,("gp_extension_store_reg failed: %s\n", + dos_errstr(werr))); + TALLOC_FREE(info); + gpext->methods->shutdown(); + status = werror_to_ntstatus(werr); + goto out; + } + TALLOC_FREE(info); + } + + } + + out: + TALLOC_FREE(reg_ctx); + + return status; +} + +/**************************************************************** +****************************************************************/ + +NTSTATUS free_gp_extensions(void) +{ + struct gp_extension *ext, *ext_next = NULL; + + for (ext = extensions; ext; ext = ext_next) { + ext_next = ext->next; + DLIST_REMOVE(extensions, ext); + TALLOC_FREE(ext); + } + + extensions = NULL; + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +void debug_gpext_header(int lvl, + const char *name, + uint32_t flags, + struct GROUP_POLICY_OBJECT *gpo, + const char *extension_guid, + const char *snapin_guid) +{ + char *flags_str = NULL; + + DEBUG(lvl,("%s\n", name)); + DEBUGADD(lvl,("\tgpo: %s (%s)\n", gpo->name, + gpo->display_name)); + DEBUGADD(lvl,("\tcse extension: %s (%s)\n", extension_guid, + cse_gpo_guid_string_to_name(extension_guid))); + DEBUGADD(lvl,("\tgplink: %s\n", gpo->link)); + DEBUGADD(lvl,("\tsnapin: %s (%s)\n", snapin_guid, + cse_snapin_gpo_guid_string_to_name(snapin_guid))); + + flags_str = gpo_flag_str(flags); + DEBUGADD(lvl,("\tflags: 0x%08x %s\n", flags, flags_str)); + SAFE_FREE(flags_str); +} + +NTSTATUS process_gpo_list_with_extension(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + uint32_t flags, + const struct nt_user_token *token, + struct GROUP_POLICY_OBJECT *gpo_list, + const char *extension_guid, + const char *snapin_guid) +{ + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +NTSTATUS gpext_process_extension(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + uint32_t flags, + const struct nt_user_token *token, + struct registry_key *root_key, + struct GROUP_POLICY_OBJECT *gpo, + const char *extension_guid, + const char *snapin_guid) +{ + NTSTATUS status; + struct gp_extension *ext = NULL; + struct GUID guid; + bool cse_found = false; + + status = init_gp_extensions(mem_ctx); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1,("init_gp_extensions failed: %s\n", + nt_errstr(status))); + return status; + } + + status = GUID_from_string(extension_guid, &guid); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + for (ext = extensions; ext; ext = ext->next) { + + if (GUID_equal(ext->guid, &guid)) { + cse_found = true; + break; + } + } + + if (!cse_found) { + goto no_ext; + } + + status = ext->methods->initialize(mem_ctx); + NT_STATUS_NOT_OK_RETURN(status); + + status = ext->methods->process_group_policy(ads, + mem_ctx, + flags, + root_key, + token, + gpo, + extension_guid, + snapin_guid); + if (!NT_STATUS_IS_OK(status)) { + ext->methods->shutdown(); + } + + return status; + + no_ext: + if (flags & GPO_INFO_FLAG_VERBOSE) { + DEBUG(0,("process_extension: no extension available for:\n")); + DEBUGADD(0,("%s (%s) (snapin: %s)\n", + extension_guid, + cse_gpo_guid_string_to_name(extension_guid), + snapin_guid)); + } + + return NT_STATUS_OK; +} diff --git a/source3/libgpo/gpext/gpext.h b/source3/libgpo/gpext/gpext.h new file mode 100644 index 0000000000..0f0445701d --- /dev/null +++ b/source3/libgpo/gpext/gpext.h @@ -0,0 +1,79 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Support + * Copyright (C) Guenther Deschner 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 + * 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/>. + */ + +#define KEY_WINLOGON_GPEXT_PATH "HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions" + +#define SAMBA_SUBSYSTEM_GPEXT "gpext" + +#define SMB_GPEXT_INTERFACE_VERSION 1 + +struct gp_extension { + struct GUID *guid; + const char *name; + struct gp_extension_methods *methods; + struct gp_extension *prev, *next; +}; + +struct gp_extension_reg_table { + const char *val; + enum winreg_Type type; + const char *data; +}; + +struct gp_extension_reg_entry { + const char *value; + struct registry_value *data; +}; + +struct gp_extension_reg_info_entry { + struct GUID guid; + size_t num_entries; + struct gp_extension_reg_entry *entries; +}; + +struct gp_extension_reg_info { + size_t num_entries; + struct gp_extension_reg_info_entry *entries; +}; + +struct gp_extension_methods { + + NTSTATUS (*initialize)(TALLOC_CTX *mem_ctx); + + NTSTATUS (*process_group_policy)(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + uint32_t flags, + struct registry_key *root_key, + const struct nt_user_token *token, + struct GROUP_POLICY_OBJECT *gpo, + const char *extension_guid, + const char *snapin_guid); + + NTSTATUS (*process_group_policy2)(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + uint32_t flags, + const struct nt_user_token *token, + struct GROUP_POLICY_OBJECT *gpo_list, + const char *extension_guid); + + NTSTATUS (*get_reg_config)(TALLOC_CTX *mem_ctx, + struct gp_extension_reg_info **info); + + NTSTATUS (*shutdown)(void); +}; diff --git a/source3/libgpo/gpext/registry.c b/source3/libgpo/gpext/registry.c new file mode 100644 index 0000000000..6cad8c796c --- /dev/null +++ b/source3/libgpo/gpext/registry.c @@ -0,0 +1,634 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Support + * Copyright (C) Guenther Deschner 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 + * 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" + +#define GP_EXT_NAME "registry" + +/* more info can be found at: + * http://msdn2.microsoft.com/en-us/library/aa374407.aspx */ + +#define GP_REGPOL_FILE "Registry.pol" + +#define GP_REGPOL_FILE_SIGNATURE 0x67655250 /* 'PReg' */ +#define GP_REGPOL_FILE_VERSION 1 + +static TALLOC_CTX *ctx = NULL; + +struct gp_registry_file_header { + uint32_t signature; + uint32_t version; +}; + +struct gp_registry_file_entry { + UNISTR key; + UNISTR value; + enum winreg_Type type; + size_t size; + uint8_t *data; +}; + +struct gp_registry_file { + struct gp_registry_file_header header; + size_t num_entries; + struct gp_registry_entry *entries; +}; + +/**************************************************************** +****************************************************************/ + +static bool reg_parse_header(const char *desc, + struct gp_registry_file_header *header, + prs_struct *ps, + int depth) +{ + if (!header) + return false; + + prs_debug(ps, depth, desc, "reg_parse_header"); + depth++; + + if (!prs_uint32("signature", ps, depth, &header->signature)) + return false; + + if (!prs_uint32("version", ps, depth, &header->version)) + return false; + + return true; +} + +/**************************************************************** +****************************************************************/ + +static bool reg_parse_and_verify_ucs2_char(const char *desc, + char character, + prs_struct *ps, + int depth) +{ + uint16_t tmp; + + if (!prs_uint16(desc, ps, depth, &tmp)) + return false; + + if (tmp != UCS2_CHAR(character)) + return false; + + return true; +} + +/**************************************************************** +****************************************************************/ + +static bool reg_parse_init(prs_struct *ps, int depth) +{ + return reg_parse_and_verify_ucs2_char("initiator '['", '[', + ps, depth); +} + +/**************************************************************** +****************************************************************/ + +static bool reg_parse_sep(prs_struct *ps, int depth) +{ + return reg_parse_and_verify_ucs2_char("separator ';'", ';', + ps, depth); +} + +/**************************************************************** +****************************************************************/ + +static bool reg_parse_term(prs_struct *ps, int depth) +{ + return reg_parse_and_verify_ucs2_char("terminator ']'", ']', + ps, depth); +} + + +/**************************************************************** +* [key;value;type;size;data] +****************************************************************/ + +static bool reg_parse_entry(TALLOC_CTX *mem_ctx, + const char *desc, + struct gp_registry_file_entry *entry, + prs_struct *ps, + int depth) +{ + uint32_t size = 0; + + if (!entry) + return false; + + prs_debug(ps, depth, desc, "reg_parse_entry"); + depth++; + + ZERO_STRUCTP(entry); + + if (!reg_parse_init(ps, depth)) + return false; + + if (!prs_unistr("key", ps, depth, &entry->key)) + return false; + + if (!reg_parse_sep(ps, depth)) + return false; + + if (!prs_unistr("value", ps, depth, &entry->value)) + return false; + + if (!reg_parse_sep(ps, depth)) + return false; + + if (!prs_uint32("type", ps, depth, &entry->type)) + return false; + + if (!reg_parse_sep(ps, depth)) + return false; + + if (!prs_uint32("size", ps, depth, &size)) + return false; + + entry->size = size; + + if (!reg_parse_sep(ps, depth)) + return false; + + if (entry->size) { + entry->data = TALLOC_ZERO_ARRAY(mem_ctx, uint8, entry->size); + if (!entry->data) + return false; + } + + if (!prs_uint8s(false, "data", ps, depth, entry->data, entry->size)) + return false; + + if (!reg_parse_term(ps, depth)) + return false; + + return true; +} + +/**************************************************************** +****************************************************************/ + +static bool reg_parse_value(TALLOC_CTX *mem_ctx, + char **value, + enum gp_reg_action *action) +{ + if (!*value) { + *action = GP_REG_ACTION_ADD_KEY; + return true; + } + + if (strncmp(*value, "**", 2) != 0) { + *action = GP_REG_ACTION_ADD_VALUE; + return true; + } + + if (strnequal(*value, "**DelVals.", 10)) { + *action = GP_REG_ACTION_DEL_ALL_VALUES; + return true; + } + + if (strnequal(*value, "**Del.", 6)) { + *value = talloc_strdup(mem_ctx, *value + 6); + *action = GP_REG_ACTION_DEL_VALUE; + return true; + } + + if (strnequal(*value, "**SecureKey", 11)) { + if (strnequal(*value, "**SecureKey=1", 13)) { + *action = GP_REG_ACTION_SEC_KEY_SET; + return true; + } + + /*************** not tested from here on ***************/ + if (strnequal(*value, "**SecureKey=0", 13)) { + smb_panic("not supported: **SecureKey=0"); + *action = GP_REG_ACTION_SEC_KEY_RESET; + return true; + } + DEBUG(0,("unknown: SecureKey: %s\n", *value)); + smb_panic("not supported SecureKey method"); + return false; + } + + if (strnequal(*value, "**DeleteValues", strlen("**DeleteValues"))) { + smb_panic("not supported: **DeleteValues"); + *action = GP_REG_ACTION_DEL_VALUES; + return false; + } + + if (strnequal(*value, "**DeleteKeys", strlen("**DeleteKeys"))) { + smb_panic("not supported: **DeleteKeys"); + *action = GP_REG_ACTION_DEL_KEYS; + return false; + } + + DEBUG(0,("unknown value: %s\n", *value)); + smb_panic(*value); + return false; +} + +/**************************************************************** +****************************************************************/ + +static bool gp_reg_entry_from_file_entry(TALLOC_CTX *mem_ctx, + struct gp_registry_file_entry *file_entry, + struct gp_registry_entry **reg_entry) +{ + struct registry_value *data = NULL; + struct gp_registry_entry *entry = NULL; + char *key = NULL; + char *value = NULL; + enum gp_reg_action action = GP_REG_ACTION_NONE; + + ZERO_STRUCTP(*reg_entry); + + data = TALLOC_ZERO_P(mem_ctx, struct registry_value); + if (!data) + return false; + + if (strlen_w((const smb_ucs2_t *)file_entry->key.buffer) <= 0) + return false; + + if (!pull_ucs2_talloc(mem_ctx, &key, file_entry->key.buffer)) + return false; + + if (strlen_w((const smb_ucs2_t *)file_entry->value.buffer) > 0) { + if (!pull_ucs2_talloc(mem_ctx, &value, + file_entry->value.buffer)) + return false; + } + + if (!reg_parse_value(mem_ctx, &value, &action)) + return false; + + data->type = file_entry->type; + + switch (data->type) { + case REG_DWORD: + data->v.dword = atoi((char *)file_entry->data); + break; + case REG_BINARY: + data->v.binary = data_blob_talloc(mem_ctx, + file_entry->data, + file_entry->size); + break; + case REG_NONE: + break; + case REG_SZ: + data->v.sz.len = pull_ucs2_talloc(mem_ctx, + &data->v.sz.str, + (const smb_ucs2_t *)file_entry->data); + break; + case REG_DWORD_BIG_ENDIAN: + case REG_EXPAND_SZ: + case REG_LINK: + case REG_MULTI_SZ: + case REG_QWORD: +/* case REG_DWORD_LITTLE_ENDIAN: */ +/* case REG_QWORD_LITTLE_ENDIAN: */ + printf("not yet implemented: %d\n", data->type); + return false; + default: + printf("invalid reg type defined: %d\n", data->type); + return false; + + } + + entry = TALLOC_ZERO_P(mem_ctx, struct gp_registry_entry); + if (!entry) + return false; + + entry->key = key; + entry->value = value; + entry->data = data; + entry->action = action; + + *reg_entry = entry; + + return true; +} + +/**************************************************************** +* [key;value;type;size;data][key;value;type;size;data]... +****************************************************************/ + +static bool reg_parse_entries(TALLOC_CTX *mem_ctx, + const char *desc, + struct gp_registry_entry **entries, + size_t *num_entries, + prs_struct *ps, + int depth) +{ + + if (!entries || !num_entries) + return false; + + prs_debug(ps, depth, desc, "reg_parse_entries"); + depth++; + + *entries = NULL; + *num_entries = 0; + + while (ps->buffer_size > ps->data_offset) { + + struct gp_registry_file_entry f_entry; + struct gp_registry_entry *r_entry = NULL; + + if (!reg_parse_entry(mem_ctx, desc, &f_entry, + ps, depth)) + return false; + + if (!gp_reg_entry_from_file_entry(mem_ctx, + &f_entry, + &r_entry)) + return false; + + if (!add_gp_registry_entry_to_array(mem_ctx, + r_entry, + entries, + num_entries)) + return false; + } + + return true; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS reg_parse_registry(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *filename, + struct gp_registry_entry **entries, + size_t *num_entries) +{ + uint16_t *buf = NULL; + size_t n = 0; + NTSTATUS status; + prs_struct ps; + struct gp_registry_file *reg_file; + const char *real_filename = NULL; + + reg_file = TALLOC_ZERO_P(mem_ctx, struct gp_registry_file); + NT_STATUS_HAVE_NO_MEMORY(reg_file); + + status = gp_find_file(mem_ctx, + flags, + filename, + GP_REGPOL_FILE, + &real_filename); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(reg_file); + return status; + } + + buf = (uint16 *)file_load(real_filename, &n, 0); + if (!buf) { + TALLOC_FREE(reg_file); + return NT_STATUS_CANNOT_LOAD_REGISTRY_FILE; + } + + if (!prs_init(&ps, n, mem_ctx, UNMARSHALL)) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + + if (!prs_copy_data_in(&ps, (char *)buf, n)) { + status = NT_STATUS_NO_MEMORY; + goto out; + } + + prs_set_offset(&ps, 0); + + if (!reg_parse_header("header", ®_file->header, &ps, 0)) { + status = NT_STATUS_REGISTRY_IO_FAILED; + goto out; + } + + if (reg_file->header.signature != GP_REGPOL_FILE_SIGNATURE) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + if (reg_file->header.version != GP_REGPOL_FILE_VERSION) { + status = NT_STATUS_INVALID_PARAMETER; + goto out; + } + + if (!reg_parse_entries(mem_ctx, "entries", ®_file->entries, + ®_file->num_entries, &ps, 0)) { + status = NT_STATUS_REGISTRY_IO_FAILED; + goto out; + } + + *entries = reg_file->entries; + *num_entries = reg_file->num_entries; + + status = NT_STATUS_OK; + + out: + SAFE_FREE(buf); + prs_mem_free(&ps); + + return status; +} + +/**************************************************************** +****************************************************************/ + +static WERROR reg_apply_registry(TALLOC_CTX *mem_ctx, + const struct nt_user_token *token, + struct registry_key *root_key, + uint32_t flags, + struct gp_registry_entry *entries, + size_t num_entries) +{ + struct gp_registry_context *reg_ctx = NULL; + WERROR werr; + size_t i; + + if (num_entries == 0) { + return WERR_OK; + } + +#if 0 + if (flags & GPO_LIST_FLAG_MACHINE) { + werr = gp_init_reg_ctx(mem_ctx, KEY_HKLM, REG_KEY_WRITE, + get_system_token(), + ®_ctx); + } else { + werr = gp_init_reg_ctx(mem_ctx, KEY_HKCU, REG_KEY_WRITE, + token, + ®_ctx); + } + W_ERROR_NOT_OK_RETURN(werr); +#endif + for (i=0; i<num_entries; i++) { + + /* FIXME: maybe we should check here if we attempt to go beyond + * the 4 allowed reg keys */ + + werr = reg_apply_registry_entry(mem_ctx, root_key, + reg_ctx, + &(entries)[i], + token, flags); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("failed to apply registry: %s\n", + dos_errstr(werr))); + goto done; + } + } + +done: + gp_free_reg_ctx(reg_ctx); + return werr; +} + + +/**************************************************************** +****************************************************************/ + +static NTSTATUS registry_process_group_policy(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + uint32_t flags, + struct registry_key *root_key, + const struct nt_user_token *token, + struct GROUP_POLICY_OBJECT *gpo, + const char *extension_guid, + const char *snapin_guid) +{ + NTSTATUS status; + WERROR werr; + struct gp_registry_entry *entries = NULL; + size_t num_entries = 0; + char *unix_path = NULL; + + debug_gpext_header(0, "registry_process_group_policy", flags, gpo, + extension_guid, snapin_guid); + + status = gpo_get_unix_path(mem_ctx, gpo, &unix_path); + NT_STATUS_NOT_OK_RETURN(status); + + status = reg_parse_registry(mem_ctx, + flags, + unix_path, + &entries, + &num_entries); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("failed to parse registry: %s\n", + nt_errstr(status))); + return status; + } + + dump_reg_entries(flags, "READ", entries, num_entries); + + werr = reg_apply_registry(mem_ctx, token, root_key, flags, + entries, num_entries); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("failed to apply registry: %s\n", + dos_errstr(werr))); + return werror_to_ntstatus(werr); + } + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS registry_get_reg_config(TALLOC_CTX *mem_ctx, + struct gp_extension_reg_info **reg_info) +{ + NTSTATUS status; + struct gp_extension_reg_info *info = NULL; + struct gp_extension_reg_table table[] = { + { "ProcessGroupPolicy", REG_SZ, "registry_process_group_policy" }, + { NULL, REG_NONE, NULL } + }; + + info = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_info); + NT_STATUS_HAVE_NO_MEMORY(info); + + status = gp_ext_info_add_entry(mem_ctx, GP_EXT_NAME, + GP_EXT_GUID_REGISTRY, + table, info); + NT_STATUS_NOT_OK_RETURN(status); + + *reg_info = info; + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS registry_initialize(TALLOC_CTX *mem_ctx) +{ + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS registry_shutdown(void) +{ + NTSTATUS status; + + status = unregister_gp_extension(GP_EXT_NAME); + if (NT_STATUS_IS_OK(status)) { + return status; + } + + TALLOC_FREE(ctx); + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static struct gp_extension_methods registry_methods = { + .initialize = registry_initialize, + .process_group_policy = registry_process_group_policy, + .get_reg_config = registry_get_reg_config, + .shutdown = registry_shutdown +}; + +/**************************************************************** +****************************************************************/ + +NTSTATUS gpext_registry_init(void) +{ + NTSTATUS status; + + ctx = talloc_init("gpext_registry_init"); + NT_STATUS_HAVE_NO_MEMORY(ctx); + + status = register_gp_extension(ctx, SMB_GPEXT_INTERFACE_VERSION, + GP_EXT_NAME, GP_EXT_GUID_REGISTRY, + ®istry_methods); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(ctx); + } + + return status; +} diff --git a/source3/libgpo/gpo_fetch.c b/source3/libgpo/gpo_fetch.c index 916db2b3d3..2ec066425b 100644 --- a/source3/libgpo/gpo_fetch.c +++ b/source3/libgpo/gpo_fetch.c @@ -44,15 +44,18 @@ NTSTATUS gpo_explode_filesyspath(TALLOC_CTX *mem_ctx, if (!next_token_talloc(mem_ctx, &file_sys_path, server, "\\")) { return NT_STATUS_INVALID_PARAMETER; } + NT_STATUS_HAVE_NO_MEMORY(*server); if (!next_token_talloc(mem_ctx, &file_sys_path, service, "\\")) { return NT_STATUS_INVALID_PARAMETER; } + NT_STATUS_HAVE_NO_MEMORY(*service); if ((*nt_path = talloc_asprintf(mem_ctx, "\\%s", file_sys_path)) == NULL) { return NT_STATUS_NO_MEMORY; } + NT_STATUS_HAVE_NO_MEMORY(*nt_path); if ((path = talloc_asprintf(mem_ctx, "%s/%s", @@ -65,9 +68,8 @@ NTSTATUS gpo_explode_filesyspath(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - if ((*unix_path = talloc_strdup(mem_ctx, path)) == NULL) { - return NT_STATUS_NO_MEMORY; - } + *unix_path = talloc_strdup(mem_ctx, path); + NT_STATUS_HAVE_NO_MEMORY(*unix_path); TALLOC_FREE(path); return NT_STATUS_OK; @@ -124,36 +126,23 @@ NTSTATUS gpo_fetch_files(TALLOC_CTX *mem_ctx, result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path, &server, &service, &nt_path, &unix_path); - if (!NT_STATUS_IS_OK(result)) { - goto out; - } + NT_STATUS_NOT_OK_RETURN(result); result = gpo_prepare_local_store(mem_ctx, unix_path); - if (!NT_STATUS_IS_OK(result)) { - goto out; - } + NT_STATUS_NOT_OK_RETURN(result); unix_ini_path = talloc_asprintf(mem_ctx, "%s/%s", unix_path, GPT_INI); nt_ini_path = talloc_asprintf(mem_ctx, "%s\\%s", nt_path, GPT_INI); - if (!unix_path || !nt_ini_path) { - result = NT_STATUS_NO_MEMORY; - goto out; - } + NT_STATUS_HAVE_NO_MEMORY(unix_ini_path); + NT_STATUS_HAVE_NO_MEMORY(nt_ini_path); result = gpo_copy_file(mem_ctx, cli, nt_ini_path, unix_ini_path); - if (!NT_STATUS_IS_OK(result)) { - goto out; - } + NT_STATUS_NOT_OK_RETURN(result); result = gpo_sync_directories(mem_ctx, cli, nt_path, unix_path); - if (!NT_STATUS_IS_OK(result)) { - goto out; - } + NT_STATUS_NOT_OK_RETURN(result); - result = NT_STATUS_OK; - - out: - return result; + return NT_STATUS_OK; } /**************************************************************** diff --git a/source3/libgpo/gpo_filesync.c b/source3/libgpo/gpo_filesync.c index 03d5286fae..6d64d7b968 100644 --- a/source3/libgpo/gpo_filesync.c +++ b/source3/libgpo/gpo_filesync.c @@ -117,10 +117,10 @@ static bool gpo_sync_files(struct sync_context *ctx) ctx) == -1) { DEBUG(1,("listing [%s] failed with error: %s\n", ctx->mask, cli_errstr(ctx->cli))); - return False; + return false; } - return True; + return true; } /**************************************************************** diff --git a/source3/libgpo/gpo_ini.c b/source3/libgpo/gpo_ini.c index 306d6f9bec..d8f14b609f 100644 --- a/source3/libgpo/gpo_ini.c +++ b/source3/libgpo/gpo_ini.c @@ -174,7 +174,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx, failed: - DEBUG(1,("gp_inifile_init_context failed: %s\n", + DEBUG(1,("gp_inifile_init_context failed: %s\n", nt_errstr(status))); TALLOC_FREE(ctx); @@ -237,7 +237,7 @@ NTSTATUS parse_gpt_ini(TALLOC_CTX *mem_ctx, result = NT_STATUS_OK; out: - if (dict) { + if (dict) { iniparser_freedict(dict); } diff --git a/source3/libgpo/gpo_ldap.c b/source3/libgpo/gpo_ldap.c index a34e6861a5..477832abc5 100644 --- a/source3/libgpo/gpo_ldap.c +++ b/source3/libgpo/gpo_ldap.c @@ -27,7 +27,7 @@ bool ads_parse_gp_ext(TALLOC_CTX *mem_ctx, const char *extension_raw, struct GP_EXT **gp_ext) { - bool ret = False; + bool ret = false; struct GP_EXT *ext = NULL; char **ext_list = NULL; char **ext_strings = NULL; @@ -134,7 +134,7 @@ bool ads_parse_gp_ext(TALLOC_CTX *mem_ctx, *gp_ext = ext; - ret = True; + ret = true; parse_error: TALLOC_FREE(ext_list); @@ -659,7 +659,7 @@ ADS_STATUS ads_get_sid_token(ADS_STRUCT *ads, } } - new_token = create_local_nt_token(mem_ctx, &object_sid, False, + new_token = create_local_nt_token(mem_ctx, &object_sid, false, num_token_sids, token_sids); ADS_ERROR_HAVE_NO_MEMORY(new_token); @@ -713,7 +713,7 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, ADS_STATUS status; struct GP_LINK gp_link; const char *parent_dn, *site_dn, *tmp_dn; - bool add_only_forced_gpos = False; + bool add_only_forced_gpos = false; ZERO_STRUCTP(gpo_list); @@ -793,7 +793,7 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, /* block inheritance from now on */ if (gp_link.gp_opts & GPOPTIONS_BLOCK_INHERITANCE) { - add_only_forced_gpos = True; + add_only_forced_gpos = true; } status = add_gplink_to_gpo_list(ads, @@ -839,7 +839,7 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, /* block inheritance from now on */ if (gp_link.gp_opts & GPOPTIONS_BLOCK_INHERITANCE) { - add_only_forced_gpos = True; + add_only_forced_gpos = true; } status = add_gplink_to_gpo_list(ads, diff --git a/source3/libgpo/gpo_reg.c b/source3/libgpo/gpo_reg.c new file mode 100644 index 0000000000..2a27a7ed93 --- /dev/null +++ b/source3/libgpo/gpo_reg.c @@ -0,0 +1,1058 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Object Support + * Copyright (C) Guenther Deschner 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 + * 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" + + +extern REGISTRY_OPS regdb_ops; + +static int gp_reg_fetch_keys(const char *key, REGSUBKEY_CTR *subkey_ctr) +{ + return regdb_ops.fetch_subkeys(key, subkey_ctr); +} + +static bool gp_reg_store_keys(const char *key, REGSUBKEY_CTR *subkeys) +{ + return regdb_ops.store_subkeys(key, subkeys); +} + +static int gp_reg_fetch_values(const char *key, REGVAL_CTR *val) +{ + return regdb_ops.fetch_values(key, val); +} + +static bool gp_reg_store_values(const char *key, REGVAL_CTR *val) +{ + return regdb_ops.store_values(key, val); +} + +static WERROR gp_reg_get_secdesc(TALLOC_CTX *mem_ctx, const char *key, + struct security_descriptor **psecdesc) +{ + return regdb_ops.get_secdesc(mem_ctx, key, psecdesc); +} + +static WERROR gp_reg_set_secdesc(const char *key, + struct security_descriptor *secdesc) +{ + return regdb_ops.set_secdesc(key, secdesc); +} + +/**************************************************************** +****************************************************************/ + +static REGISTRY_OPS gp_reg_ops = { + .fetch_subkeys = gp_reg_fetch_keys, + .fetch_values = gp_reg_fetch_values, + .store_subkeys = gp_reg_store_keys, + .store_values = gp_reg_store_values, +/* .reg_access_check = gp_reg_reg_access_check, */ + .get_secdesc = gp_reg_get_secdesc, + .set_secdesc = gp_reg_set_secdesc +}; + +/**************************************************************** +****************************************************************/ + +struct nt_user_token *registry_create_system_token(TALLOC_CTX *mem_ctx) +{ + struct nt_user_token *token = NULL; + + token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token); + if (!token) { + DEBUG(1,("talloc failed\n")); + return NULL; + } + + token->privileges = se_priv_all; + + if (!NT_STATUS_IS_OK(add_sid_to_array(token, &global_sid_System, + &token->user_sids, &token->num_sids))) { + DEBUG(1,("Error adding nt-authority system sid to token\n")); + return NULL; + } + + return token; +} + +/**************************************************************** +****************************************************************/ + +WERROR gp_init_reg_ctx(TALLOC_CTX *mem_ctx, + const char *initial_path, + uint32_t desired_access, + const struct nt_user_token *token, + struct gp_registry_context **reg_ctx) +{ + struct gp_registry_context *tmp_ctx; + static REGISTRY_HOOK gp_reg_hook; + WERROR werr; + + if (!reg_ctx) { + return WERR_INVALID_PARAM; + } + + if (!regdb_init()) { + return WERR_CAN_NOT_COMPLETE; + } + + gp_reg_hook.keyname = initial_path; /* KEY_SAMBA_GROUP_POLICY */ + gp_reg_hook.ops = &gp_reg_ops; + + /* not sure about the cache hook */ + reghook_cache_init(); + + if (!reghook_cache_add(&gp_reg_hook)) { + return WERR_CAN_NOT_COMPLETE; + } + + tmp_ctx = TALLOC_ZERO_P(mem_ctx, struct gp_registry_context); + W_ERROR_HAVE_NO_MEMORY(tmp_ctx); + + if (token) { + tmp_ctx->token = token; + } else { + tmp_ctx->token = registry_create_system_token(mem_ctx); + } + if (!tmp_ctx->token) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + if (initial_path) { + tmp_ctx->path = talloc_strdup(mem_ctx, initial_path); + if (!tmp_ctx->path) { + TALLOC_FREE(tmp_ctx); + return WERR_NOMEM; + } + + werr = reg_open_path(mem_ctx, tmp_ctx->path, desired_access, + tmp_ctx->token, &tmp_ctx->curr_key); + if (!W_ERROR_IS_OK(werr)) { + TALLOC_FREE(tmp_ctx); + return werr; + } + } + + *reg_ctx = tmp_ctx; + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + +void gp_free_reg_ctx(struct gp_registry_context *reg_ctx) +{ + TALLOC_FREE(reg_ctx); +} + +/**************************************************************** +****************************************************************/ + +WERROR gp_store_reg_subkey(TALLOC_CTX *mem_ctx, + const char *subkeyname, + struct registry_key *curr_key, + struct registry_key **new_key) +{ + enum winreg_CreateAction action = REG_ACTION_NONE; + WERROR werr; + + werr = reg_createkey(mem_ctx, curr_key, subkeyname, + REG_KEY_WRITE, new_key, &action); + if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) { + return WERR_OK; + } + + return werr; +} + +/**************************************************************** +****************************************************************/ + +WERROR gp_read_reg_subkey(TALLOC_CTX *mem_ctx, + struct gp_registry_context *reg_ctx, + const char *subkeyname, + struct registry_key **key) +{ + const char *tmp = NULL; + + if (!reg_ctx || !subkeyname || !key) { + return WERR_INVALID_PARAM; + } + + tmp = talloc_asprintf(mem_ctx, "%s\\%s", reg_ctx->path, subkeyname); + W_ERROR_HAVE_NO_MEMORY(tmp); + + return reg_open_path(mem_ctx, tmp, REG_KEY_READ, + reg_ctx->token, key); +} + +/**************************************************************** +****************************************************************/ + +WERROR gp_store_reg_val_sz(TALLOC_CTX *mem_ctx, + struct registry_key *key, + const char *val_name, + const char *val) +{ + struct registry_value reg_val; + ZERO_STRUCT(reg_val); + + /* FIXME: hack */ + val = val ? val : " "; + + reg_val.type = REG_SZ; + reg_val.v.sz.len = strlen(val); + reg_val.v.sz.str = talloc_strdup(mem_ctx, val); + W_ERROR_HAVE_NO_MEMORY(reg_val.v.sz.str); + + return reg_setvalue(key, val_name, ®_val); +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_store_reg_val_dword(TALLOC_CTX *mem_ctx, + struct registry_key *key, + const char *val_name, + uint32_t val) +{ + struct registry_value reg_val; + ZERO_STRUCT(reg_val); + + reg_val.type = REG_DWORD; + reg_val.v.dword = val; + + return reg_setvalue(key, val_name, ®_val); +} + +/**************************************************************** +****************************************************************/ + +WERROR gp_read_reg_val_sz(TALLOC_CTX *mem_ctx, + struct registry_key *key, + const char *val_name, + const char **val) +{ + WERROR werr; + struct registry_value *reg_val = NULL; + + werr = reg_queryvalue(mem_ctx, key, val_name, ®_val); + W_ERROR_NOT_OK_RETURN(werr); + + if (reg_val->type != REG_SZ) { + return WERR_INVALID_DATATYPE; + } + + *val = talloc_strdup(mem_ctx, reg_val->v.sz.str); + W_ERROR_HAVE_NO_MEMORY(*val); + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_read_reg_val_dword(TALLOC_CTX *mem_ctx, + struct registry_key *key, + const char *val_name, + uint32_t *val) +{ + WERROR werr; + struct registry_value *reg_val = NULL; + + werr = reg_queryvalue(mem_ctx, key, val_name, ®_val); + W_ERROR_NOT_OK_RETURN(werr); + + if (reg_val->type != REG_DWORD) { + return WERR_INVALID_DATATYPE; + } + + *val = reg_val->v.dword; + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_store_reg_gpovals(TALLOC_CTX *mem_ctx, + struct registry_key *key, + struct GROUP_POLICY_OBJECT *gpo) +{ + WERROR werr; + + if (!key || !gpo) { + return WERR_INVALID_PARAM; + } + + werr = gp_store_reg_val_dword(mem_ctx, key, "Version", + gpo->version); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_store_reg_val_dword(mem_ctx, key, "WQLFilterPass", + true); /* fake */ + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_store_reg_val_dword(mem_ctx, key, "AccessDenied", + false); /* fake */ + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_store_reg_val_dword(mem_ctx, key, "GPO-Disabled", + (gpo->options & GPO_FLAG_DISABLE)); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_store_reg_val_dword(mem_ctx, key, "Options", + gpo->options); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_store_reg_val_sz(mem_ctx, key, "GPOID", + gpo->name); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_store_reg_val_sz(mem_ctx, key, "SOM", + gpo->link); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_store_reg_val_sz(mem_ctx, key, "DisplayName", + gpo->display_name); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_store_reg_val_sz(mem_ctx, key, "WQL-Id", + NULL); + W_ERROR_NOT_OK_RETURN(werr); + + return werr; +} + +/**************************************************************** +****************************************************************/ + +static const char *gp_reg_groupmembership_path(TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + uint32_t flags) +{ + if (flags & GPO_LIST_FLAG_MACHINE) { + return "GroupMembership"; + } + + return talloc_asprintf(mem_ctx, "%s\\%s", sid_string_tos(sid), + "GroupMembership"); +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_reg_del_groupmembership(TALLOC_CTX *mem_ctx, + struct registry_key *key, + const struct nt_user_token *token, + uint32_t flags) +{ + const char *path = NULL; + + path = gp_reg_groupmembership_path(mem_ctx, &token->user_sids[0], + flags); + W_ERROR_HAVE_NO_MEMORY(path); + + return reg_deletekey_recursive(mem_ctx, key, path); + +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_reg_store_groupmembership(TALLOC_CTX *mem_ctx, + struct gp_registry_context *reg_ctx, + const struct nt_user_token *token, + uint32_t flags) +{ + struct registry_key *key = NULL; + WERROR werr; + int i = 0; + const char *valname = NULL; + const char *path = NULL; + const char *val = NULL; + int count = 0; + + path = gp_reg_groupmembership_path(mem_ctx, &token->user_sids[0], + flags); + W_ERROR_HAVE_NO_MEMORY(path); + + gp_reg_del_groupmembership(mem_ctx, reg_ctx->curr_key, token, flags); + + werr = gp_store_reg_subkey(mem_ctx, path, + reg_ctx->curr_key, &key); + W_ERROR_NOT_OK_RETURN(werr); + + for (i=0; i<token->num_sids; i++) { + + valname = talloc_asprintf(mem_ctx, "Group%d", count++); + W_ERROR_HAVE_NO_MEMORY(valname); + + val = sid_string_talloc(mem_ctx, &token->user_sids[i]); + W_ERROR_HAVE_NO_MEMORY(val); + werr = gp_store_reg_val_sz(mem_ctx, key, valname, val); + W_ERROR_NOT_OK_RETURN(werr); + } + + werr = gp_store_reg_val_dword(mem_ctx, key, "Count", count); + W_ERROR_NOT_OK_RETURN(werr); + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ +#if 0 +/* not used yet */ +static WERROR gp_reg_read_groupmembership(TALLOC_CTX *mem_ctx, + struct gp_registry_context *reg_ctx, + const DOM_SID *object_sid, + struct nt_user_token **token, + uint32_t flags) +{ + struct registry_key *key = NULL; + WERROR werr; + int i = 0; + const char *valname = NULL; + const char *val = NULL; + const char *path = NULL; + uint32_t count = 0; + int num_token_sids = 0; + struct nt_user_token *tmp_token = NULL; + + tmp_token = TALLOC_ZERO_P(mem_ctx, struct nt_user_token); + W_ERROR_HAVE_NO_MEMORY(tmp_token); + + path = gp_reg_groupmembership_path(mem_ctx, object_sid, flags); + W_ERROR_HAVE_NO_MEMORY(path); + + werr = gp_read_reg_subkey(mem_ctx, reg_ctx, path, &key); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_read_reg_val_dword(mem_ctx, key, "Count", &count); + W_ERROR_NOT_OK_RETURN(werr); + + for (i=0; i<count; i++) { + + valname = talloc_asprintf(mem_ctx, "Group%d", i); + W_ERROR_HAVE_NO_MEMORY(valname); + + werr = gp_read_reg_val_sz(mem_ctx, key, valname, &val); + W_ERROR_NOT_OK_RETURN(werr); + + if (!string_to_sid(&tmp_token->user_sids[num_token_sids++], + val)) { + return WERR_INSUFFICIENT_BUFFER; + } + } + + tmp_token->num_sids = num_token_sids; + + *token = tmp_token; + + return WERR_OK; +} +#endif +/**************************************************************** +****************************************************************/ + +static const char *gp_req_state_path(TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + uint32_t flags) +{ + if (flags & GPO_LIST_FLAG_MACHINE) { + return GPO_REG_STATE_MACHINE; + } + + return talloc_asprintf(mem_ctx, "%s\\%s", "State", sid_string_tos(sid)); +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_del_reg_state(TALLOC_CTX *mem_ctx, + struct registry_key *key, + const char *path) +{ + return reg_deletesubkeys_recursive(mem_ctx, key, path); +} + +/**************************************************************** +****************************************************************/ + +WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *dn, + const struct nt_user_token *token, + struct GROUP_POLICY_OBJECT *gpo_list) +{ + struct gp_registry_context *reg_ctx = NULL; + WERROR werr = WERR_GENERAL_FAILURE; + const char *subkeyname = NULL; + struct GROUP_POLICY_OBJECT *gpo; + int count = 0; + struct registry_key *key; + + werr = gp_init_reg_ctx(mem_ctx, KEY_GROUP_POLICY, REG_KEY_WRITE, + token, ®_ctx); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_secure_key(mem_ctx, flags, KEY_GROUP_POLICY, + &token->user_sids[0]); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("failed to secure key: %s\n", dos_errstr(werr))); + goto done; + } + + werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("failed to store group membership: %s\n", dos_errstr(werr))); + goto done; + } + + subkeyname = gp_req_state_path(mem_ctx, &token->user_sids[0], flags); + if (!subkeyname) { + werr = WERR_NOMEM; + goto done; + } + + werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("failed to delete old state: %s\n", dos_errstr(werr))); + /* goto done; */ + } + + werr = gp_store_reg_subkey(mem_ctx, subkeyname, + reg_ctx->curr_key, ®_ctx->curr_key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = gp_store_reg_val_sz(mem_ctx, reg_ctx->curr_key, + "Distinguished-Name", dn); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + /* store link list */ + + werr = gp_store_reg_subkey(mem_ctx, "GPLink-List", + reg_ctx->curr_key, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + /* store gpo list */ + + werr = gp_store_reg_subkey(mem_ctx, "GPO-List", + reg_ctx->curr_key, ®_ctx->curr_key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + for (gpo = gpo_list; gpo; gpo = gpo->next) { + + subkeyname = talloc_asprintf(mem_ctx, "%d", count++); + if (!subkeyname) { + werr = WERR_NOMEM; + goto done; + } + + werr = gp_store_reg_subkey(mem_ctx, subkeyname, + reg_ctx->curr_key, &key); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = gp_store_reg_gpovals(mem_ctx, key, gpo); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("gp_reg_state_store: " + "gpo_store_reg_gpovals failed for %s: %s\n", + gpo->display_name, dos_errstr(werr))); + goto done; + } + } + done: + gp_free_reg_ctx(reg_ctx); + return werr; +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_read_reg_gpovals(TALLOC_CTX *mem_ctx, + struct registry_key *key, + struct GROUP_POLICY_OBJECT *gpo) +{ + WERROR werr; + + if (!key || !gpo) { + return WERR_INVALID_PARAM; + } + + werr = gp_read_reg_val_dword(mem_ctx, key, "Version", + &gpo->version); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_read_reg_val_dword(mem_ctx, key, "Options", + &gpo->options); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_read_reg_val_sz(mem_ctx, key, "GPOID", + &gpo->name); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_read_reg_val_sz(mem_ctx, key, "SOM", + &gpo->link); + W_ERROR_NOT_OK_RETURN(werr); + + werr = gp_read_reg_val_sz(mem_ctx, key, "DisplayName", + &gpo->display_name); + W_ERROR_NOT_OK_RETURN(werr); + + return werr; +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_read_reg_gpo(TALLOC_CTX *mem_ctx, + struct registry_key *key, + struct GROUP_POLICY_OBJECT **gpo_ret) +{ + struct GROUP_POLICY_OBJECT *gpo = NULL; + WERROR werr; + + if (!gpo_ret || !key) { + return WERR_INVALID_PARAM; + } + + gpo = TALLOC_ZERO_P(mem_ctx, struct GROUP_POLICY_OBJECT); + W_ERROR_HAVE_NO_MEMORY(gpo); + + werr = gp_read_reg_gpovals(mem_ctx, key, gpo); + W_ERROR_NOT_OK_RETURN(werr); + + *gpo_ret = gpo; + + return werr; +} + +/**************************************************************** +****************************************************************/ + +WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx, + uint32_t flags, + const DOM_SID *sid, + struct GROUP_POLICY_OBJECT **gpo_list) +{ + struct gp_registry_context *reg_ctx = NULL; + WERROR werr = WERR_GENERAL_FAILURE; + const char *subkeyname = NULL; + struct GROUP_POLICY_OBJECT *gpo = NULL; + int count = 0; + struct registry_key *key = NULL; + const char *path = NULL; + const char *gp_state_path = NULL; + + if (!gpo_list) { + return WERR_INVALID_PARAM; + } + + ZERO_STRUCTP(gpo_list); + + gp_state_path = gp_req_state_path(mem_ctx, sid, flags); + if (!gp_state_path) { + werr = WERR_NOMEM; + goto done; + } + + path = talloc_asprintf(mem_ctx, "%s\\%s\\%s", + KEY_GROUP_POLICY, + gp_state_path, + "GPO-List"); + if (!path) { + werr = WERR_NOMEM; + goto done; + } + + werr = gp_init_reg_ctx(mem_ctx, path, REG_KEY_READ, NULL, ®_ctx); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + while (1) { + + subkeyname = talloc_asprintf(mem_ctx, "%d", count++); + if (!subkeyname) { + werr = WERR_NOMEM; + goto done; + } + + werr = gp_read_reg_subkey(mem_ctx, reg_ctx, subkeyname, &key); + if (W_ERROR_EQUAL(werr, WERR_BADFILE)) { + werr = WERR_OK; + break; + } + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("gp_reg_state_read: " + "gp_read_reg_subkey gave: %s\n", + dos_errstr(werr))); + goto done; + } + + werr = gp_read_reg_gpo(mem_ctx, key, &gpo); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + DLIST_ADD(*gpo_list, gpo); + } + + done: + gp_free_reg_ctx(reg_ctx); + return werr; +} + +/**************************************************************** +****************************************************************/ + +static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx, + const DOM_SID *sid, + struct security_descriptor **sd, + size_t *sd_size) +{ + SEC_ACE ace[6]; + SEC_ACCESS mask; + + SEC_ACL *acl = NULL; + + uint8_t inherit_flags; + + init_sec_access(&mask, REG_KEY_ALL); + init_sec_ace(&ace[0], + &global_sid_System, + SEC_ACE_TYPE_ACCESS_ALLOWED, + mask, 0); + + init_sec_access(&mask, REG_KEY_ALL); + init_sec_ace(&ace[1], + &global_sid_Builtin_Administrators, + SEC_ACE_TYPE_ACCESS_ALLOWED, + mask, 0); + + init_sec_access(&mask, REG_KEY_READ); + init_sec_ace(&ace[2], + sid ? sid : &global_sid_Authenticated_Users, + SEC_ACE_TYPE_ACCESS_ALLOWED, + mask, 0); + + inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT | + SEC_ACE_FLAG_CONTAINER_INHERIT | + SEC_ACE_FLAG_INHERIT_ONLY; + + init_sec_access(&mask, REG_KEY_ALL); + init_sec_ace(&ace[3], + &global_sid_System, + SEC_ACE_TYPE_ACCESS_ALLOWED, + mask, inherit_flags); + + init_sec_access(&mask, REG_KEY_ALL); + init_sec_ace(&ace[4], + &global_sid_Builtin_Administrators, + SEC_ACE_TYPE_ACCESS_ALLOWED, + mask, inherit_flags); + + init_sec_access(&mask, REG_KEY_READ); + init_sec_ace(&ace[5], + sid ? sid : &global_sid_Authenticated_Users, + SEC_ACE_TYPE_ACCESS_ALLOWED, + mask, inherit_flags); + + acl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace); + W_ERROR_HAVE_NO_MEMORY(acl); + + *sd = make_sec_desc(mem_ctx, SEC_DESC_REVISION, + SEC_DESC_SELF_RELATIVE | + SEC_DESC_DACL_AUTO_INHERITED | /* really ? */ + SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */ + NULL, NULL, NULL, + acl, sd_size); + W_ERROR_HAVE_NO_MEMORY(*sd); + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + +WERROR gp_secure_key(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *key, + const DOM_SID *sid) +{ + struct security_descriptor *sd = NULL; + size_t sd_size = 0; + const DOM_SID *sd_sid = NULL; + WERROR werr; + + if (!(flags & GPO_LIST_FLAG_MACHINE)) { + sd_sid = sid; + } + + werr = gp_reg_generate_sd(mem_ctx, sd_sid, &sd, &sd_size); + W_ERROR_NOT_OK_RETURN(werr); + + return gp_reg_set_secdesc(key, sd); +} + +/**************************************************************** +****************************************************************/ + +void dump_reg_val(int lvl, const char *direction, + const char *key, const char *subkey, + struct registry_value *val) +{ + int i = 0; + const char *type_str = NULL; + + if (!val) { + DEBUG(lvl,("no val!\n")); + return; + } + + type_str = reg_type_lookup(val->type); + + DEBUG(lvl,("\tdump_reg_val: %s '%s' '%s' %s: ", + direction, key, subkey, type_str)); + + switch (val->type) { + case REG_DWORD: + DEBUG(lvl,("%d\n", (int)val->v.dword)); + break; + case REG_QWORD: + DEBUG(lvl,("%d\n", (int)val->v.qword)); + break; + case REG_SZ: + DEBUG(lvl,("%s (length: %d)\n", + val->v.sz.str, + (int)val->v.sz.len)); + break; + case REG_MULTI_SZ: + DEBUG(lvl,("(num_strings: %d)\n", + val->v.multi_sz.num_strings)); + for (i=0; i < val->v.multi_sz.num_strings; i++) { + DEBUGADD(lvl,("\t%s\n", + val->v.multi_sz.strings[i])); + } + break; + case REG_NONE: + DEBUG(lvl,("\n")); + break; + case REG_BINARY: + dump_data(lvl, val->v.binary.data, + val->v.binary.length); + break; + default: + DEBUG(lvl,("unsupported type: %d\n", val->type)); + break; + } +} + +/**************************************************************** +****************************************************************/ + +void dump_reg_entry(uint32_t flags, + const char *dir, + struct gp_registry_entry *entry) +{ + if (!(flags & GPO_INFO_FLAG_VERBOSE)) + return; + + dump_reg_val(1, dir, + entry->key, + entry->value, + entry->data); +} + +/**************************************************************** +****************************************************************/ + +void dump_reg_entries(uint32_t flags, + const char *dir, + struct gp_registry_entry *entries, + size_t num_entries) +{ + size_t i; + + if (!(flags & GPO_INFO_FLAG_VERBOSE)) + return; + + for (i=0; i < num_entries; i++) { + dump_reg_entry(flags, dir, &entries[i]); + } +} + +/**************************************************************** +****************************************************************/ + +bool add_gp_registry_entry_to_array(TALLOC_CTX *mem_ctx, + struct gp_registry_entry *entry, + struct gp_registry_entry **entries, + size_t *num) +{ + *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries, + struct gp_registry_entry, + (*num)+1); + + if (*entries == NULL) { + *num = 0; + return false; + } + + (*entries)[*num].action = entry->action; + (*entries)[*num].key = entry->key; + (*entries)[*num].value = entry->value; + (*entries)[*num].data = entry->data; + + *num += 1; + return true; +} + +/**************************************************************** +****************************************************************/ + +static const char *gp_reg_action_str(enum gp_reg_action action) +{ + switch (action) { + case GP_REG_ACTION_NONE: + return "GP_REG_ACTION_NONE"; + case GP_REG_ACTION_ADD_VALUE: + return "GP_REG_ACTION_ADD_VALUE"; + case GP_REG_ACTION_ADD_KEY: + return "GP_REG_ACTION_ADD_KEY"; + case GP_REG_ACTION_DEL_VALUES: + return "GP_REG_ACTION_DEL_VALUES"; + case GP_REG_ACTION_DEL_VALUE: + return "GP_REG_ACTION_DEL_VALUE"; + case GP_REG_ACTION_DEL_ALL_VALUES: + return "GP_REG_ACTION_DEL_ALL_VALUES"; + case GP_REG_ACTION_DEL_KEYS: + return "GP_REG_ACTION_DEL_KEYS"; + case GP_REG_ACTION_SEC_KEY_SET: + return "GP_REG_ACTION_SEC_KEY_SET"; + case GP_REG_ACTION_SEC_KEY_RESET: + return "GP_REG_ACTION_SEC_KEY_RESET"; + default: + return "unknown"; + } +}; + +/**************************************************************** +****************************************************************/ + +WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx, + struct registry_key *root_key, + struct gp_registry_context *reg_ctx, + struct gp_registry_entry *entry, + const struct nt_user_token *token, + uint32_t flags) +{ + WERROR werr; + struct registry_key *key = NULL; + + if (flags & GPO_INFO_FLAG_VERBOSE) { + printf("about to store key: [%s]\n", entry->key); + printf(" value: [%s]\n", entry->value); + printf(" data: [%s]\n", reg_type_lookup(entry->data->type)); + printf(" action: [%s]\n", gp_reg_action_str(entry->action)); + } + + werr = gp_store_reg_subkey(mem_ctx, entry->key, + root_key, &key); + /* reg_ctx->curr_key, &key); */ + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("gp_store_reg_subkey failed: %s\n", dos_errstr(werr))); + return werr; + } + + switch (entry->action) { + case GP_REG_ACTION_NONE: + case GP_REG_ACTION_ADD_KEY: + return WERR_OK; + + case GP_REG_ACTION_SEC_KEY_SET: + werr = gp_secure_key(mem_ctx, flags, + entry->key, + &token->user_sids[0]); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("reg_apply_registry_entry: " + "gp_secure_key failed: %s\n", + dos_errstr(werr))); + return werr; + } + break; + case GP_REG_ACTION_ADD_VALUE: + werr = reg_setvalue(key, entry->value, entry->data); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("reg_apply_registry_entry: " + "reg_setvalue failed: %s\n", + dos_errstr(werr))); + dump_reg_entry(flags, "STORE", entry); + return werr; + } + break; + case GP_REG_ACTION_DEL_VALUE: + werr = reg_deletevalue(key, entry->value); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("reg_apply_registry_entry: " + "reg_deletevalue failed: %s\n", + dos_errstr(werr))); + dump_reg_entry(flags, "STORE", entry); + return werr; + } + break; + case GP_REG_ACTION_DEL_ALL_VALUES: + werr = reg_deleteallvalues(key); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,("reg_apply_registry_entry: " + "reg_deleteallvalues failed: %s\n", + dos_errstr(werr))); + dump_reg_entry(flags, "STORE", entry); + return werr; + } + break; + case GP_REG_ACTION_DEL_VALUES: + case GP_REG_ACTION_DEL_KEYS: + case GP_REG_ACTION_SEC_KEY_RESET: + DEBUG(0,("reg_apply_registry_entry: " + "not yet supported: %s (%d)\n", + gp_reg_action_str(entry->action), + entry->action)); + return WERR_NOT_SUPPORTED; + default: + DEBUG(0,("invalid action: %d\n", entry->action)); + return WERR_INVALID_PARAM; + } + + return werr; +} + diff --git a/source3/libgpo/gpo_sec.c b/source3/libgpo/gpo_sec.c index 7f8324b994..42ab72a99b 100644 --- a/source3/libgpo/gpo_sec.c +++ b/source3/libgpo/gpo_sec.c @@ -28,13 +28,13 @@ static bool gpo_sd_check_agp_object_guid(const struct security_ace_object *objec NTSTATUS status; if (!object) { - return False; + return false; } status = GUID_from_string(ADS_EXTENDED_RIGHT_APPLY_GROUP_POLICY, &ext_right_apg_guid); if (!NT_STATUS_IS_OK(status)) { - return False; + return false; } switch (object->flags) { @@ -52,7 +52,7 @@ static bool gpo_sd_check_agp_object_guid(const struct security_ace_object *objec break; } - return False; + return false; } /**************************************************************** @@ -61,7 +61,7 @@ static bool gpo_sd_check_agp_object_guid(const struct security_ace_object *objec static bool gpo_sd_check_agp_object(const SEC_ACE *ace) { if (!sec_ace_object(ace->type)) { - return False; + return false; } return gpo_sd_check_agp_object_guid(&ace->object.object); diff --git a/source3/libgpo/gpo_util.c b/source3/libgpo/gpo_util.c index cd532da48b..f41bbc1817 100644 --- a/source3/libgpo/gpo_util.c +++ b/source3/libgpo/gpo_util.c @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. * Group Policy Object Support - * Copyright (C) Guenther Deschner 2005-2007 + * Copyright (C) Guenther Deschner 2005-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 @@ -668,6 +668,51 @@ NTSTATUS check_refresh_gpo_list(ADS_STRUCT *ads, /**************************************************************** ****************************************************************/ +NTSTATUS gpo_get_unix_path(TALLOC_CTX *mem_ctx, + struct GROUP_POLICY_OBJECT *gpo, + char **unix_path) +{ + char *server, *share, *nt_path; + return gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path, + &server, &share, &nt_path, unix_path); +} + +/**************************************************************** +****************************************************************/ + +char *gpo_flag_str(uint32_t flags) +{ + fstring str = ""; + + if (flags == 0) { + return NULL; + } + + if (flags & GPO_INFO_FLAG_SLOWLINK) + fstrcat(str, "GPO_INFO_FLAG_SLOWLINK "); + if (flags & GPO_INFO_FLAG_VERBOSE) + fstrcat(str, "GPO_INFO_FLAG_VERBOSE "); + if (flags & GPO_INFO_FLAG_SAFEMODE_BOOT) + fstrcat(str, "GPO_INFO_FLAG_SAFEMODE_BOOT "); + if (flags & GPO_INFO_FLAG_NOCHANGES) + fstrcat(str, "GPO_INFO_FLAG_NOCHANGES "); + if (flags & GPO_INFO_FLAG_MACHINE) + fstrcat(str, "GPO_INFO_FLAG_MACHINE "); + if (flags & GPO_INFO_FLAG_LOGRSOP_TRANSITION) + fstrcat(str, "GPO_INFO_FLAG_LOGRSOP_TRANSITION "); + if (flags & GPO_INFO_FLAG_LINKTRANSITION) + fstrcat(str, "GPO_INFO_FLAG_LINKTRANSITION "); + if (flags & GPO_INFO_FLAG_FORCED_REFRESH) + fstrcat(str, "GPO_INFO_FLAG_FORCED_REFRESH "); + if (flags & GPO_INFO_FLAG_BACKGROUND) + fstrcat(str, "GPO_INFO_FLAG_BACKGROUND "); + + return SMB_STRDUP(str); +} + +/**************************************************************** +****************************************************************/ + NTSTATUS gp_find_file(TALLOC_CTX *mem_ctx, uint32_t flags, const char *filename, @@ -693,8 +738,11 @@ NTSTATUS gp_find_file(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } - tmp = talloc_asprintf_strupper_m(mem_ctx, "%s/%s/%s", filename, path, - suffix); + path = talloc_strdup_upper(mem_ctx, path); + NT_STATUS_HAVE_NO_MEMORY(path); + + tmp = talloc_asprintf(mem_ctx, "%s/%s/%s", filename, + path, suffix); NT_STATUS_HAVE_NO_MEMORY(tmp); if (sys_stat(tmp, &sbuf) == 0) { @@ -705,3 +753,31 @@ NTSTATUS gp_find_file(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_SUCH_FILE; } +/**************************************************************** +****************************************************************/ + +ADS_STATUS gp_get_machine_token(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *dn, + struct nt_user_token **token) +{ + struct nt_user_token *ad_token = NULL; + ADS_STATUS status; + NTSTATUS ntstatus; + +#ifndef HAVE_ADS + return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED); +#endif + status = ads_get_sid_token(ads, mem_ctx, dn, &ad_token); + if (!ADS_ERR_OK(status)) { + return status; + } + + ntstatus = merge_nt_token(mem_ctx, ad_token, get_system_token(), + token); + if (!NT_STATUS_IS_OK(ntstatus)) { + return ADS_ERROR_NT(ntstatus); + } + + return ADS_SUCCESS; +} diff --git a/source3/libnet/libnet_conf.c b/source3/libnet/libnet_conf.c index 4d998acad8..688097bc5e 100644 --- a/source3/libnet/libnet_conf.c +++ b/source3/libnet/libnet_conf.c @@ -62,7 +62,7 @@ static WERROR libnet_conf_reg_initialize(struct libnet_conf_ctx *ctx) { WERROR werr = WERR_OK; - if (!registry_init_regdb()) { + if (!registry_init_smbconf()) { werr = WERR_REG_IO_FAILURE; goto done; } @@ -482,6 +482,19 @@ void libnet_conf_close(struct libnet_conf_ctx *ctx) } /** + * Get the change sequence number of the given service/parameter. + * + * NOTE: Currently, for registry configuration, this is independent + * of the service and parameter, it returns the registry-sequence + * number. + */ +uint64_t libnet_conf_get_seqnum(struct libnet_conf_ctx *ctx, + const char *service, const char *param) +{ + return (uint64_t)regdb_get_seqnum(); +} + +/** * Drop the whole configuration (restarting empty). */ WERROR libnet_conf_drop(struct libnet_conf_ctx *ctx) diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 0543ca8474..9bed346b5e 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -29,7 +29,7 @@ char *str = NULL; \ str = NDR_PRINT_FUNCTION_STRING(ctx, libnet_JoinCtx, f, r); \ DEBUG(1,("libnet_Join:\n%s", str)); \ - talloc_free(str); \ + TALLOC_FREE(str); \ } while (0) #define LIBNET_JOIN_IN_DUMP_CTX(ctx, r) \ @@ -42,7 +42,7 @@ char *str = NULL; \ str = NDR_PRINT_FUNCTION_STRING(ctx, libnet_UnjoinCtx, f, r); \ DEBUG(1,("libnet_Unjoin:\n%s", str)); \ - talloc_free(str); \ + TALLOC_FREE(str); \ } while (0) #define LIBNET_UNJOIN_IN_DUMP_CTX(ctx, r) \ @@ -50,6 +50,12 @@ #define LIBNET_UNJOIN_OUT_DUMP_CTX(ctx, r) \ LIBNET_UNJOIN_DUMP_CTX(ctx, r, NDR_OUT) +#define W_ERROR_NOT_OK_GOTO_DONE(x) do { \ + if (!W_ERROR_IS_OK(x)) {\ + goto done;\ + }\ +} while (0) + /**************************************************************** ****************************************************************/ @@ -146,9 +152,24 @@ static ADS_STATUS libnet_join_connect_ads(TALLOC_CTX *mem_ctx, libnet_join_set_error_string(mem_ctx, r, "failed to connect to AD: %s", ads_errstr(status)); + return status; } - return status; + if (!r->out.netbios_domain_name) { + r->out.netbios_domain_name = talloc_strdup(mem_ctx, + r->in.ads->server.workgroup); + ADS_ERROR_HAVE_NO_MEMORY(r->out.netbios_domain_name); + } + + if (!r->out.dns_domain_name) { + r->out.dns_domain_name = talloc_strdup(mem_ctx, + r->in.ads->config.realm); + ADS_ERROR_HAVE_NO_MEMORY(r->out.dns_domain_name); + } + + r->out.domain_is_ad = true; + + return ADS_SUCCESS; } /**************************************************************** @@ -175,6 +196,7 @@ static ADS_STATUS libnet_unjoin_connect_ads(TALLOC_CTX *mem_ctx, } /**************************************************************** + join a domain using ADS (LDAP mods) ****************************************************************/ static ADS_STATUS libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx, @@ -183,6 +205,7 @@ static ADS_STATUS libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx, ADS_STATUS status; LDAPMessage *res = NULL; const char *attrs[] = { "dn", NULL }; + bool moved = false; status = ads_search_dn(r->in.ads, &res, r->in.account_ou, attrs); if (!ADS_ERR_OK(status)) { @@ -194,16 +217,41 @@ static ADS_STATUS libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx, return ADS_ERROR_LDAP(LDAP_NO_SUCH_OBJECT); } + ads_msgfree(r->in.ads, res); + + /* Attempt to create the machine account and bail if this fails. + Assume that the admin wants exactly what they requested */ + status = ads_create_machine_acct(r->in.ads, r->in.machine_name, r->in.account_ou); - ads_msgfree(r->in.ads, res); - if ((status.error_type == ENUM_ADS_ERROR_LDAP) && - (status.err.rc == LDAP_ALREADY_EXISTS)) { + if (ADS_ERR_OK(status)) { + DEBUG(1,("machine account creation created\n")); + return status; + } else if ((status.error_type == ENUM_ADS_ERROR_LDAP) && + (status.err.rc == LDAP_ALREADY_EXISTS)) { status = ADS_SUCCESS; } + if (!ADS_ERR_OK(status)) { + DEBUG(1,("machine account creation failed\n")); + return status; + } + + status = ads_move_machine_acct(r->in.ads, + r->in.machine_name, + r->in.account_ou, + &moved); + if (!ADS_ERR_OK(status)) { + DEBUG(1,("failure to locate/move pre-existing " + "machine account\n")); + return status; + } + + DEBUG(1,("The machine account %s the specified OU.\n", + moved ? "was moved into" : "already exists in")); + return status; } @@ -279,6 +327,7 @@ static ADS_STATUS libnet_join_find_machine_acct(TALLOC_CTX *mem_ctx, } /**************************************************************** + Set a machines dNSHostName and servicePrincipalName attributes ****************************************************************/ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, @@ -290,18 +339,15 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, const char *spn_array[3] = {NULL, NULL, NULL}; char *spn = NULL; - if (!r->in.ads) { - status = libnet_join_connect_ads(mem_ctx, r); - if (!ADS_ERR_OK(status)) { - return status; - } - } + /* Find our DN */ status = libnet_join_find_machine_acct(mem_ctx, r); if (!ADS_ERR_OK(status)) { return status; } + /* Windows only creates HOST/shortname & HOST/fqdn. */ + spn = talloc_asprintf(mem_ctx, "HOST/%s", r->in.machine_name); if (!spn) { return ADS_ERROR_LDAP(LDAP_NO_MEMORY); @@ -325,6 +371,8 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, return ADS_ERROR_LDAP(LDAP_NO_MEMORY); } + /* fields of primary importance */ + status = ads_mod_str(mem_ctx, &mods, "dNSHostName", my_fqdn); if (!ADS_ERR_OK(status)) { return ADS_ERROR_LDAP(LDAP_NO_MEMORY); @@ -352,12 +400,7 @@ static ADS_STATUS libnet_join_set_machine_upn(TALLOC_CTX *mem_ctx, return ADS_SUCCESS; } - if (!r->in.ads) { - status = libnet_join_connect_ads(mem_ctx, r); - if (!ADS_ERR_OK(status)) { - return status; - } - } + /* Find our DN */ status = libnet_join_find_machine_acct(mem_ctx, r); if (!ADS_ERR_OK(status)) { @@ -374,11 +417,15 @@ static ADS_STATUS libnet_join_set_machine_upn(TALLOC_CTX *mem_ctx, } } + /* now do the mods */ + mods = ads_init_mods(mem_ctx); if (!mods) { return ADS_ERROR_LDAP(LDAP_NO_MEMORY); } + /* fields of primary importance */ + status = ads_mod_str(mem_ctx, &mods, "userPrincipalName", r->in.upn); if (!ADS_ERR_OK(status)) { return ADS_ERROR_LDAP(LDAP_NO_MEMORY); @@ -402,18 +449,15 @@ static ADS_STATUS libnet_join_set_os_attributes(TALLOC_CTX *mem_ctx, return ADS_SUCCESS; } - if (!r->in.ads) { - status = libnet_join_connect_ads(mem_ctx, r); - if (!ADS_ERR_OK(status)) { - return status; - } - } + /* Find our DN */ status = libnet_join_find_machine_acct(mem_ctx, r); if (!ADS_ERR_OK(status)) { return status; } + /* now do the mods */ + mods = ads_init_mods(mem_ctx); if (!mods) { return ADS_ERROR(LDAP_NO_MEMORY); @@ -424,6 +468,8 @@ static ADS_STATUS libnet_join_set_os_attributes(TALLOC_CTX *mem_ctx, return ADS_ERROR(LDAP_NO_MEMORY); } + /* fields of primary importance */ + status = ads_mod_str(mem_ctx, &mods, "operatingSystem", r->in.os_name); if (!ADS_ERR_OK(status)) { @@ -481,6 +527,8 @@ static bool libnet_join_derive_salting_principal(TALLOC_CTX *mem_ctx, return false; } + /* go ahead and setup the default salt */ + std_salt = kerberos_standard_des_salt(); if (!std_salt) { libnet_join_set_error_string(mem_ctx, r, @@ -495,6 +543,8 @@ static bool libnet_join_derive_salting_principal(TALLOC_CTX *mem_ctx, SAFE_FREE(std_salt); + /* if it's a Windows functional domain, we have to look for the UPN */ + if (domain_func == DS_DOMAIN_FUNCTION_2000) { char *upn; @@ -519,6 +569,13 @@ static ADS_STATUS libnet_join_post_processing_ads(TALLOC_CTX *mem_ctx, { ADS_STATUS status; + if (!r->in.ads) { + status = libnet_join_connect_ads(mem_ctx, r); + if (!ADS_ERR_OK(status)) { + return status; + } + } + status = libnet_join_set_machine_spn(mem_ctx, r); if (!ADS_ERR_OK(status)) { libnet_join_set_error_string(mem_ctx, r, @@ -558,6 +615,7 @@ static ADS_STATUS libnet_join_post_processing_ads(TALLOC_CTX *mem_ctx, #endif /* WITH_ADS */ /**************************************************************** + Store the machine password and domain SID ****************************************************************/ static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx, @@ -566,13 +624,15 @@ static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx, if (!secrets_store_domain_sid(r->out.netbios_domain_name, r->out.domain_sid)) { + DEBUG(1,("Failed to save domain sid\n")); return false; } if (!secrets_store_machine_password(r->in.machine_password, r->out.netbios_domain_name, - SEC_CHAN_WKSTA)) + r->in.secure_channel_type)) { + DEBUG(1,("Failed to save machine password\n")); return false; } @@ -580,6 +640,7 @@ static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx, } /**************************************************************** + Do the domain join ****************************************************************/ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, @@ -591,8 +652,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, NTSTATUS status = NT_STATUS_UNSUCCESSFUL; char *acct_name; struct lsa_String lsa_acct_name; - uint32 user_rid; - uint32 acb_info = ACB_WSTRUST; + uint32_t user_rid; + uint32_t acct_flags = ACB_WSTRUST; uchar pwbuf[532]; struct MD5Context md5ctx; uchar md5buffer[16]; @@ -624,10 +685,12 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &status); if (!pipe_hnd) { + DEBUG(0,("Error connecting to LSA pipe. Error was %s\n", + nt_errstr(status))); goto done; } - status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, + status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, true, SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol); if (!NT_STATUS_IS_OK(status)) { goto done; @@ -660,8 +723,12 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol); cli_rpc_pipe_close(pipe_hnd); + /* Open the domain */ + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &status); if (!pipe_hnd) { + DEBUG(0,("Error connecting to SAM pipe. Error was %s\n", + nt_errstr(status))); goto done; } @@ -682,13 +749,15 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, goto done; } + /* Create domain user */ + acct_name = talloc_asprintf(mem_ctx, "%s$", r->in.machine_name); strlower_m(acct_name); init_lsa_String(&lsa_acct_name, acct_name); if (r->in.join_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE) { - uint32_t acct_flags = + uint32_t access_desired = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE | SEC_STD_WRITE_DAC | SEC_STD_DELETE | SAMR_USER_ACCESS_SET_PASSWORD | @@ -696,14 +765,38 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, SAMR_USER_ACCESS_SET_ATTRIBUTES; uint32_t access_granted = 0; + /* Don't try to set any acct_flags flags other than ACB_WSTRUST */ + + DEBUG(10,("Creating account with desired access mask: %d\n", + access_desired)); + status = rpccli_samr_CreateUser2(pipe_hnd, mem_ctx, &domain_pol, &lsa_acct_name, ACB_WSTRUST, - acct_flags, + access_desired, &user_pol, &access_granted, &user_rid); + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { + + DEBUG(10,("Creation of workstation account failed: %s\n", + nt_errstr(status))); + + /* If NT_STATUS_ACCESS_DENIED then we have a valid + username/password combo but the user does not have + administrator access. */ + + if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + libnet_join_set_error_string(mem_ctx, r, + "User specified does not have " + "administrator privileges"); + } + + return status; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { if (!(r->in.join_flags & WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED)) { @@ -711,6 +804,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, } } + /* We *must* do this.... don't ask... */ + if (NT_STATUS_IS_OK(status)) { rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol); } @@ -727,12 +822,16 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, } if (name_types.ids[0] != SID_NAME_USER) { + DEBUG(0,("%s is not a user account (type=%d)\n", + acct_name, name_types.ids[0])); status = NT_STATUS_INVALID_WORKSTATION; goto done; } user_rid = user_rids.ids[0]; + /* Open handle on user */ + status = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, &domain_pol, SEC_RIGHTS_MAXIMUM_ALLOWED, @@ -742,10 +841,12 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, goto done; } + /* Create a random machine account password and generate the hash */ + E_md4hash(r->in.machine_password, md4_trust_password); encode_pw_buffer(pwbuf, r->in.machine_password, STR_UNICODE); - generate_random_buffer((uint8*)md5buffer, sizeof(md5buffer)); + generate_random_buffer((uint8_t*)md5buffer, sizeof(md5buffer)); digested_session_key = data_blob_talloc(mem_ctx, 0, 16); MD5Init(&md5ctx); @@ -757,27 +858,54 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, SamOEMhashBlob(pwbuf, sizeof(pwbuf), &digested_session_key); memcpy(&pwbuf[516], md5buffer, sizeof(md5buffer)); - acb_info |= ACB_PWNOEXP; + /* Fill in the additional account flags now */ + + acct_flags |= ACB_PWNOEXP; if (r->out.domain_is_ad) { #if !defined(ENCTYPE_ARCFOUR_HMAC) - acb_info |= ACB_USE_DES_KEY_ONLY; + acct_flags |= ACB_USE_DES_KEY_ONLY; #endif ;; } + /* Set password and account flags on machine account */ + ZERO_STRUCT(user_info.info25); user_info.info25.info.fields_present = ACCT_NT_PWD_SET | ACCT_LM_PWD_SET | SAMR_FIELD_ACCT_FLAGS; - user_info.info25.info.acct_flags = acb_info; + + user_info.info25.info.acct_flags = acct_flags; memcpy(&user_info.info25.password.data, pwbuf, sizeof(pwbuf)); status = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, &user_pol, 25, &user_info); + + if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) { + + uchar pwbuf2[516]; + + encode_pw_buffer(pwbuf2, r->in.machine_password, STR_UNICODE); + + /* retry with level 24 */ + init_samr_user_info24(&user_info.info24, pwbuf2, 24); + + SamOEMhashBlob(user_info.info24.password.data, 516, + &cli->user_session_key); + + status = rpccli_samr_SetUserInfo2(pipe_hnd, mem_ctx, + &user_pol, + 24, + &user_info); + } + if (!NT_STATUS_IS_OK(status)) { + libnet_join_set_error_string(mem_ctx, r, + "Failed to set password for machine account (%s)\n", + nt_errstr(status)); goto done; } @@ -796,6 +924,131 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +NTSTATUS libnet_join_ok(const char *netbios_domain_name, + const char *machine_name, + const char *dc_name) +{ + uint32_t neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS | + NETLOGON_NEG_SCHANNEL; + struct cli_state *cli = NULL; + struct rpc_pipe_client *pipe_hnd = NULL; + struct rpc_pipe_client *netlogon_pipe = NULL; + NTSTATUS status; + char *machine_password = NULL; + char *machine_account = NULL; + + if (!dc_name) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!secrets_init()) { + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + machine_password = secrets_fetch_machine_password(netbios_domain_name, + NULL, NULL); + if (!machine_password) { + return NT_STATUS_NO_TRUST_LSA_SECRET; + } + + asprintf(&machine_account, "%s$", machine_name); + if (!machine_account) { + SAFE_FREE(machine_password); + return NT_STATUS_NO_MEMORY; + } + + status = cli_full_connection(&cli, NULL, + dc_name, + NULL, 0, + "IPC$", "IPC", + machine_account, + NULL, + machine_password, + 0, + Undefined, NULL); + free(machine_account); + free(machine_password); + + if (!NT_STATUS_IS_OK(status)) { + status = cli_full_connection(&cli, NULL, + dc_name, + NULL, 0, + "IPC$", "IPC", + "", + NULL, + "", + 0, + Undefined, NULL); + } + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + netlogon_pipe = get_schannel_session_key(cli, + netbios_domain_name, + &neg_flags, &status); + if (!netlogon_pipe) { + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_NETWORK_RESPONSE)) { + cli_shutdown(cli); + return NT_STATUS_OK; + } + + DEBUG(0,("libnet_join_ok: failed to get schannel session " + "key from server %s for domain %s. Error was %s\n", + cli->desthost, netbios_domain_name, nt_errstr(status))); + cli_shutdown(cli); + return status; + } + + if (!lp_client_schannel()) { + cli_shutdown(cli); + return NT_STATUS_OK; + } + + pipe_hnd = cli_rpc_pipe_open_schannel_with_key(cli, PI_NETLOGON, + PIPE_AUTH_LEVEL_PRIVACY, + netbios_domain_name, + netlogon_pipe->dc, + &status); + + cli_shutdown(cli); + + if (!pipe_hnd) { + DEBUG(0,("libnet_join_ok: failed to open schannel session " + "on netlogon pipe to server %s for domain %s. " + "Error was %s\n", + cli->desthost, netbios_domain_name, nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static WERROR libnet_join_post_verify(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) +{ + NTSTATUS status; + + status = libnet_join_ok(r->out.netbios_domain_name, + r->in.machine_name, + r->in.dc_name); + if (!NT_STATUS_IS_OK(status)) { + libnet_join_set_error_string(mem_ctx, r, + "failed to verify domain membership after joining: %s", + get_friendly_nt_error_msg(status)); + return WERR_SETUP_NOT_JOINED; + } + + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + static bool libnet_join_unjoindomain_remove_secrets(TALLOC_CTX *mem_ctx, struct libnet_UnjoinCtx *r) { @@ -821,7 +1074,7 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx, POLICY_HND sam_pol, domain_pol, user_pol; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; char *acct_name; - uint32 user_rid; + uint32_t user_rid; struct lsa_String lsa_acct_name; struct samr_Ids user_rids; struct samr_Ids name_types; @@ -840,8 +1093,12 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx, goto done; } + /* Open the domain */ + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &status); if (!pipe_hnd) { + DEBUG(0,("Error connecting to SAM pipe. Error was %s\n", + nt_errstr(status))); goto done; } @@ -862,6 +1119,8 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx, goto done; } + /* Create domain user */ + acct_name = talloc_asprintf(mem_ctx, "%s$", r->in.machine_name); strlower_m(acct_name); @@ -879,12 +1138,16 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx, } if (name_types.ids[0] != SID_NAME_USER) { + DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, + name_types.ids[0])); status = NT_STATUS_INVALID_WORKSTATION; goto done; } user_rid = user_rids.ids[0]; + /* Open handle on user */ + status = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, &domain_pol, SEC_RIGHTS_MAXIMUM_ALLOWED, @@ -894,6 +1157,8 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx, goto done; } + /* Get user info */ + status = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, &user_pol, 16, @@ -903,6 +1168,8 @@ static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx, goto done; } + /* now disable and setuser info */ + info->info16.acct_flags |= ACB_DISABLED; status = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, @@ -942,9 +1209,7 @@ static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r) if (!(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE)) { werr = libnet_conf_set_global_parameter(ctx, "security", "user"); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } + W_ERROR_NOT_OK_GOTO_DONE(werr); werr = libnet_conf_set_global_parameter(ctx, "workgroup", r->in.domain_name); @@ -952,27 +1217,22 @@ static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r) } werr = libnet_conf_set_global_parameter(ctx, "security", "domain"); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } + W_ERROR_NOT_OK_GOTO_DONE(werr); werr = libnet_conf_set_global_parameter(ctx, "workgroup", r->out.netbios_domain_name); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } + W_ERROR_NOT_OK_GOTO_DONE(werr); if (r->out.domain_is_ad) { werr = libnet_conf_set_global_parameter(ctx, "security", "ads"); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } + W_ERROR_NOT_OK_GOTO_DONE(werr); werr = libnet_conf_set_global_parameter(ctx, "realm", r->out.dns_domain_name); + W_ERROR_NOT_OK_GOTO_DONE(werr); } -done: + done: libnet_conf_close(ctx); return werr; } @@ -993,14 +1253,11 @@ static WERROR do_unjoin_modify_vals_config(struct libnet_UnjoinCtx *r) if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { werr = libnet_conf_set_global_parameter(ctx, "security", "user"); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } + W_ERROR_NOT_OK_GOTO_DONE(werr); + libnet_conf_delete_global_parameter(ctx, "realm"); } - libnet_conf_delete_global_parameter(ctx, "realm"); - -done: + done: libnet_conf_close(ctx); return werr; } @@ -1034,7 +1291,7 @@ static WERROR do_JoinConfig(struct libnet_JoinCtx *r) /**************************************************************** ****************************************************************/ -static WERROR do_UnjoinConfig(struct libnet_UnjoinCtx *r) +static WERROR libnet_unjoin_config(struct libnet_UnjoinCtx *r) { WERROR werr; @@ -1063,12 +1320,16 @@ 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) { + libnet_join_set_error_string(mem_ctx, r, + "No domain name defined"); return WERR_INVALID_PARAM; } if (r->in.modify_config && !lp_config_backend_is_registry()) { + libnet_join_set_error_string(mem_ctx, r, + "Configuration manipulation requested but not " + "supported by backend"); return WERR_NOT_SUPPORTED; } @@ -1151,6 +1412,8 @@ WERROR libnet_init_JoinCtx(TALLOC_CTX *mem_ctx, ctx->in.machine_name = talloc_strdup(mem_ctx, global_myname()); W_ERROR_HAVE_NO_MEMORY(ctx->in.machine_name); + ctx->in.secure_channel_type = SEC_CHAN_WKSTA; + *r = ctx; return WERR_OK; @@ -1191,7 +1454,7 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, #endif /* WITH_ADS */ if (!r->in.dc_name) { - struct DS_DOMAIN_CONTROLLER_INFO *info; + struct netr_DsRGetDCNameInfo *info; status = dsgetdcname(mem_ctx, r->in.domain_name, NULL, @@ -1209,7 +1472,7 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, } r->in.dc_name = talloc_strdup(mem_ctx, - info->domain_controller_name); + info->dc_unc); W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); } @@ -1283,6 +1546,11 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(werr)) { goto done; } + + werr = libnet_join_post_verify(mem_ctx, r); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } } werr = libnet_join_post_processing(mem_ctx, r); @@ -1318,7 +1586,7 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, } if (!r->in.dc_name) { - struct DS_DOMAIN_CONTROLLER_INFO *info; + struct netr_DsRGetDCNameInfo *info; status = dsgetdcname(mem_ctx, r->in.domain_name, NULL, @@ -1336,7 +1604,7 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, } r->in.dc_name = talloc_strdup(mem_ctx, - info->domain_controller_name); + info->dc_unc); W_ERROR_HAVE_NO_MEMORY(r->in.dc_name); } @@ -1351,6 +1619,8 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, return ntstatus_to_werror(status); } + r->out.disabled_machine_account = true; + #ifdef WITH_ADS if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE) { ADS_STATUS ads_status; @@ -1360,6 +1630,12 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, libnet_unjoin_set_error_string(mem_ctx, r, "failed to remove machine account from AD: %s", ads_errstr(ads_status)); + } else { + r->out.deleted_machine_account = true; + /* dirty hack */ + r->out.dns_domain_name = talloc_strdup(mem_ctx, + r->in.ads->server.realm); + W_ERROR_HAVE_NO_MEMORY(r->out.dns_domain_name); } } #endif /* WITH_ADS */ @@ -1375,10 +1651,23 @@ 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.domain_name) { + libnet_unjoin_set_error_string(mem_ctx, r, + "No domain name defined"); + return WERR_INVALID_PARAM; + } + if (r->in.modify_config && !lp_config_backend_is_registry()) { + libnet_unjoin_set_error_string(mem_ctx, r, + "Configuration manipulation requested but not " + "supported by backend"); return WERR_NOT_SUPPORTED; } + if (IS_DC) { + return WERR_SETUP_DOMAIN_CONTROLLER; + } + if (!secrets_init()) { libnet_unjoin_set_error_string(mem_ctx, r, "Unable to open secrets database"); @@ -1388,6 +1677,17 @@ static WERROR libnet_unjoin_pre_processing(TALLOC_CTX *mem_ctx, return WERR_OK; } +/**************************************************************** +****************************************************************/ + +static WERROR libnet_unjoin_post_processing(TALLOC_CTX *mem_ctx, + struct libnet_UnjoinCtx *r) +{ + saf_delete(r->out.netbios_domain_name); + saf_delete(r->out.dns_domain_name); + + return libnet_unjoin_config(r); +} /**************************************************************** ****************************************************************/ @@ -1409,11 +1709,12 @@ WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx, if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) { werr = libnet_DomainUnjoin(mem_ctx, r); if (!W_ERROR_IS_OK(werr)) { + libnet_unjoin_config(r); goto done; } } - werr = do_UnjoinConfig(r); + werr = libnet_unjoin_post_processing(mem_ctx, r); if (!W_ERROR_IS_OK(werr)) { goto done; } diff --git a/source3/library-versions.in b/source3/library-versions.in index 2d69d3e02c..e8ef0645a7 100644 --- a/source3/library-versions.in +++ b/source3/library-versions.in @@ -3,6 +3,7 @@ ## Makefile_target:major:minor ## bin/libtalloc.@SHLIBEXT@:1:0 +bin/libtdb.@SHLIBEXT@:0:1 bin/libsmbclient.@SHLIBEXT@:0:1 bin/libsmbsharemodes.@SHLIBEXT@:0:2 bin/libaddns.@SHLIBEXT@:0:1 diff --git a/source3/librpc/gen_ndr/cli_lsa.c b/source3/librpc/gen_ndr/cli_lsa.c index 27ed572a19..b1609ea97b 100644 --- a/source3/librpc/gen_ndr/cli_lsa.c +++ b/source3/librpc/gen_ndr/cli_lsa.c @@ -471,8 +471,8 @@ NTSTATUS rpccli_lsa_EnumAccounts(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, uint32_t *resume_handle, - uint32_t num_entries, - struct lsa_SidArray *sids) + struct lsa_SidArray *sids, + uint32_t num_entries) { struct lsa_EnumAccounts r; NTSTATUS status; @@ -609,7 +609,7 @@ NTSTATUS rpccli_lsa_LookupNames(struct rpc_pipe_client *cli, struct policy_handle *handle, uint32_t num_names, struct lsa_String *names, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransSidArray *sids, enum lsa_LookupNamesLevel level, uint32_t *count) @@ -649,9 +649,7 @@ NTSTATUS rpccli_lsa_LookupNames(struct rpc_pipe_client *cli, } /* Return variables */ - if (domains && r.out.domains) { - *domains = *r.out.domains; - } + *domains = *r.out.domains; *sids = *r.out.sids; *count = *r.out.count; @@ -663,7 +661,7 @@ NTSTATUS rpccli_lsa_LookupSids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_SidArray *sids, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransNameArray *names, uint16_t level, uint32_t *count) @@ -702,9 +700,7 @@ NTSTATUS rpccli_lsa_LookupSids(struct rpc_pipe_client *cli, } /* Return variables */ - if (domains && r.out.domains) { - *domains = *r.out.domains; - } + *domains = *r.out.domains; *names = *r.out.names; *count = *r.out.count; @@ -805,7 +801,7 @@ NTSTATUS rpccli_lsa_OpenAccount(struct rpc_pipe_client *cli, NTSTATUS rpccli_lsa_EnumPrivsAccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, - struct lsa_PrivilegeSet *privs) + struct lsa_PrivilegeSet **privs) { struct lsa_EnumPrivsAccount r; NTSTATUS status; @@ -837,9 +833,7 @@ NTSTATUS rpccli_lsa_EnumPrivsAccount(struct rpc_pipe_client *cli, } /* Return variables */ - if (privs && r.out.privs) { - *privs = *r.out.privs; - } + *privs = *r.out.privs; /* Return result */ return r.out.result; @@ -1669,7 +1663,7 @@ NTSTATUS rpccli_lsa_RemoveAccountRights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct dom_sid2 *sid, - uint32_t unknown, + uint8_t remove_all, struct lsa_RightSet *rights) { struct lsa_RemoveAccountRights r; @@ -1678,7 +1672,7 @@ NTSTATUS rpccli_lsa_RemoveAccountRights(struct rpc_pipe_client *cli, /* In parameters */ r.in.handle = handle; r.in.sid = sid; - r.in.unknown = unknown; + r.in.remove_all = remove_all; r.in.rights = rights; if (DEBUGLEVEL >= 10) { @@ -2474,7 +2468,7 @@ NTSTATUS rpccli_lsa_LookupSids2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_SidArray *sids, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransNameArray2 *names, uint16_t level, uint32_t *count, @@ -2517,9 +2511,7 @@ NTSTATUS rpccli_lsa_LookupSids2(struct rpc_pipe_client *cli, } /* Return variables */ - if (domains && r.out.domains) { - *domains = *r.out.domains; - } + *domains = *r.out.domains; *names = *r.out.names; *count = *r.out.count; @@ -2532,7 +2524,7 @@ NTSTATUS rpccli_lsa_LookupNames2(struct rpc_pipe_client *cli, struct policy_handle *handle, uint32_t num_names, struct lsa_String *names, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransSidArray2 *sids, enum lsa_LookupNamesLevel level, uint32_t *count, @@ -2576,9 +2568,7 @@ NTSTATUS rpccli_lsa_LookupNames2(struct rpc_pipe_client *cli, } /* Return variables */ - if (domains && r.out.domains) { - *domains = *r.out.domains; - } + *domains = *r.out.domains; *sids = *r.out.sids; *count = *r.out.count; @@ -2924,7 +2914,7 @@ NTSTATUS rpccli_lsa_LookupNames3(struct rpc_pipe_client *cli, struct policy_handle *handle, uint32_t num_names, struct lsa_String *names, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransSidArray3 *sids, enum lsa_LookupNamesLevel level, uint32_t *count, @@ -2968,9 +2958,7 @@ NTSTATUS rpccli_lsa_LookupNames3(struct rpc_pipe_client *cli, } /* Return variables */ - if (domains && r.out.domains) { - *domains = *r.out.domains; - } + *domains = *r.out.domains; *sids = *r.out.sids; *count = *r.out.count; @@ -3248,7 +3236,7 @@ NTSTATUS rpccli_lsa_CREDRRENAME(struct rpc_pipe_client *cli, NTSTATUS rpccli_lsa_LookupSids3(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct lsa_SidArray *sids, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransNameArray2 *names, uint16_t level, uint32_t *count, @@ -3290,9 +3278,7 @@ NTSTATUS rpccli_lsa_LookupSids3(struct rpc_pipe_client *cli, } /* Return variables */ - if (domains && r.out.domains) { - *domains = *r.out.domains; - } + *domains = *r.out.domains; *names = *r.out.names; *count = *r.out.count; @@ -3304,7 +3290,7 @@ NTSTATUS rpccli_lsa_LookupNames4(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32_t num_names, struct lsa_String *names, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransSidArray3 *sids, enum lsa_LookupNamesLevel level, uint32_t *count, @@ -3347,9 +3333,7 @@ NTSTATUS rpccli_lsa_LookupNames4(struct rpc_pipe_client *cli, } /* Return variables */ - if (domains && r.out.domains) { - *domains = *r.out.domains; - } + *domains = *r.out.domains; *sids = *r.out.sids; *count = *r.out.count; diff --git a/source3/librpc/gen_ndr/cli_lsa.h b/source3/librpc/gen_ndr/cli_lsa.h index ddcd161413..7d69926484 100644 --- a/source3/librpc/gen_ndr/cli_lsa.h +++ b/source3/librpc/gen_ndr/cli_lsa.h @@ -53,8 +53,8 @@ NTSTATUS rpccli_lsa_EnumAccounts(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, uint32_t *resume_handle, - uint32_t num_entries, - struct lsa_SidArray *sids); + struct lsa_SidArray *sids, + uint32_t num_entries); NTSTATUS rpccli_lsa_CreateTrustedDomain(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, @@ -72,7 +72,7 @@ NTSTATUS rpccli_lsa_LookupNames(struct rpc_pipe_client *cli, struct policy_handle *handle, uint32_t num_names, struct lsa_String *names, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransSidArray *sids, enum lsa_LookupNamesLevel level, uint32_t *count); @@ -80,7 +80,7 @@ NTSTATUS rpccli_lsa_LookupSids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_SidArray *sids, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransNameArray *names, uint16_t level, uint32_t *count); @@ -99,7 +99,7 @@ NTSTATUS rpccli_lsa_OpenAccount(struct rpc_pipe_client *cli, NTSTATUS rpccli_lsa_EnumPrivsAccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, - struct lsa_PrivilegeSet *privs); + struct lsa_PrivilegeSet **privs); NTSTATUS rpccli_lsa_AddPrivilegesToAccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, @@ -192,7 +192,7 @@ NTSTATUS rpccli_lsa_RemoveAccountRights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct dom_sid2 *sid, - uint32_t unknown, + uint8_t remove_all, struct lsa_RightSet *rights); NTSTATUS rpccli_lsa_QueryTrustedDomainInfoBySid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, @@ -276,7 +276,7 @@ NTSTATUS rpccli_lsa_LookupSids2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_SidArray *sids, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransNameArray2 *names, uint16_t level, uint32_t *count, @@ -287,7 +287,7 @@ NTSTATUS rpccli_lsa_LookupNames2(struct rpc_pipe_client *cli, struct policy_handle *handle, uint32_t num_names, struct lsa_String *names, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransSidArray2 *sids, enum lsa_LookupNamesLevel level, uint32_t *count, @@ -316,7 +316,7 @@ NTSTATUS rpccli_lsa_LookupNames3(struct rpc_pipe_client *cli, struct policy_handle *handle, uint32_t num_names, struct lsa_String *names, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransSidArray3 *sids, enum lsa_LookupNamesLevel level, uint32_t *count, @@ -343,7 +343,7 @@ NTSTATUS rpccli_lsa_CREDRRENAME(struct rpc_pipe_client *cli, NTSTATUS rpccli_lsa_LookupSids3(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct lsa_SidArray *sids, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransNameArray2 *names, uint16_t level, uint32_t *count, @@ -353,7 +353,7 @@ NTSTATUS rpccli_lsa_LookupNames4(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32_t num_names, struct lsa_String *names, - struct lsa_RefDomainList *domains, + struct lsa_RefDomainList **domains, struct lsa_TransSidArray3 *sids, enum lsa_LookupNamesLevel level, uint32_t *count, diff --git a/source3/librpc/gen_ndr/cli_netlogon.c b/source3/librpc/gen_ndr/cli_netlogon.c index de04c21dc5..2937cc09b9 100644 --- a/source3/librpc/gen_ndr/cli_netlogon.c +++ b/source3/librpc/gen_ndr/cli_netlogon.c @@ -113,7 +113,7 @@ NTSTATUS rpccli_netr_LogonSamLogon(struct rpc_pipe_client *cli, struct netr_Authenticator *credential, struct netr_Authenticator *return_authenticator, uint16_t logon_level, - union netr_LogonLevel logon, + union netr_LogonLevel *logon, uint16_t validation_level, union netr_Validation *validation, uint8_t *authoritative) @@ -220,7 +220,8 @@ NTSTATUS rpccli_netr_ServerReqChallenge(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *server_name, const char *computer_name, - struct netr_Credential *credentials) + struct netr_Credential *credentials, + struct netr_Credential *return_credentials) { struct netr_ServerReqChallenge r; NTSTATUS status; @@ -254,7 +255,7 @@ NTSTATUS rpccli_netr_ServerReqChallenge(struct rpc_pipe_client *cli, } /* Return variables */ - *credentials = *r.out.credentials; + *return_credentials = *r.out.return_credentials; /* Return result */ return r.out.result; @@ -266,7 +267,8 @@ NTSTATUS rpccli_netr_ServerAuthenticate(struct rpc_pipe_client *cli, const char *account_name, enum netr_SchannelType secure_channel_type, const char *computer_name, - struct netr_Credential *credentials) + struct netr_Credential *credentials, + struct netr_Credential *return_credentials) { struct netr_ServerAuthenticate r; NTSTATUS status; @@ -302,7 +304,7 @@ NTSTATUS rpccli_netr_ServerAuthenticate(struct rpc_pipe_client *cli, } /* Return variables */ - *credentials = *r.out.credentials; + *return_credentials = *r.out.return_credentials; /* Return result */ return r.out.result; @@ -314,9 +316,9 @@ NTSTATUS rpccli_netr_ServerPasswordSet(struct rpc_pipe_client *cli, const char *account_name, enum netr_SchannelType secure_channel_type, const char *computer_name, - struct netr_Authenticator credential, - struct samr_Password new_password, - struct netr_Authenticator *return_authenticator) + struct netr_Authenticator *credential, + struct netr_Authenticator *return_authenticator, + struct samr_Password *new_password) { struct netr_ServerPasswordSet r; NTSTATUS status; @@ -363,12 +365,12 @@ NTSTATUS rpccli_netr_DatabaseDeltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *logon_server, const char *computername, - struct netr_Authenticator credential, + struct netr_Authenticator *credential, struct netr_Authenticator *return_authenticator, enum netr_SamDatabaseID database_id, uint64_t *sequence_num, - uint32_t preferredmaximumlength, - struct netr_DELTA_ENUM_ARRAY *delta_enum_array) + struct netr_DELTA_ENUM_ARRAY **delta_enum_array, + uint32_t preferredmaximumlength) { struct netr_DatabaseDeltas r; NTSTATUS status; @@ -745,7 +747,7 @@ NTSTATUS rpccli_netr_LogonControl2(struct rpc_pipe_client *cli, const char *logon_server, uint32_t function_code, uint32_t level, - union netr_CONTROL_DATA_INFORMATION data, + union netr_CONTROL_DATA_INFORMATION *data, union netr_CONTROL_QUERY_INFORMATION *query, WERROR *werror) { @@ -799,6 +801,7 @@ NTSTATUS rpccli_netr_ServerAuthenticate2(struct rpc_pipe_client *cli, enum netr_SchannelType secure_channel_type, const char *computer_name, struct netr_Credential *credentials, + struct netr_Credential *return_credentials, uint32_t *negotiate_flags) { struct netr_ServerAuthenticate2 r; @@ -836,7 +839,7 @@ NTSTATUS rpccli_netr_ServerAuthenticate2(struct rpc_pipe_client *cli, } /* Return variables */ - *credentials = *r.out.credentials; + *return_credentials = *r.out.return_credentials; *negotiate_flags = *r.out.negotiate_flags; /* Return result */ @@ -847,13 +850,13 @@ NTSTATUS rpccli_netr_DatabaseSync2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *logon_server, const char *computername, - struct netr_Authenticator credential, + struct netr_Authenticator *credential, struct netr_Authenticator *return_authenticator, enum netr_SamDatabaseID database_id, uint16_t restart_state, uint32_t *sync_context, - uint32_t preferredmaximumlength, - struct netr_DELTA_ENUM_ARRAY *delta_enum_array) + struct netr_DELTA_ENUM_ARRAY **delta_enum_array, + uint32_t preferredmaximumlength) { struct netr_DatabaseSync2 r; NTSTATUS status; @@ -1971,7 +1974,7 @@ NTSTATUS rpccli_netr_LogonSamLogonEx(struct rpc_pipe_client *cli, const char *server_name, const char *computer_name, uint16_t logon_level, - union netr_LogonLevel logon, + union netr_LogonLevel *logon, uint16_t validation_level, union netr_Validation *validation, uint8_t *authoritative, diff --git a/source3/librpc/gen_ndr/cli_netlogon.h b/source3/librpc/gen_ndr/cli_netlogon.h index 4aa0f9fa73..1fdc1f6c46 100644 --- a/source3/librpc/gen_ndr/cli_netlogon.h +++ b/source3/librpc/gen_ndr/cli_netlogon.h @@ -22,7 +22,7 @@ NTSTATUS rpccli_netr_LogonSamLogon(struct rpc_pipe_client *cli, struct netr_Authenticator *credential, struct netr_Authenticator *return_authenticator, uint16_t logon_level, - union netr_LogonLevel logon, + union netr_LogonLevel *logon, uint16_t validation_level, union netr_Validation *validation, uint8_t *authoritative); @@ -38,33 +38,35 @@ NTSTATUS rpccli_netr_ServerReqChallenge(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *server_name, const char *computer_name, - struct netr_Credential *credentials); + struct netr_Credential *credentials, + struct netr_Credential *return_credentials); NTSTATUS rpccli_netr_ServerAuthenticate(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *server_name, const char *account_name, enum netr_SchannelType secure_channel_type, const char *computer_name, - struct netr_Credential *credentials); + struct netr_Credential *credentials, + struct netr_Credential *return_credentials); NTSTATUS rpccli_netr_ServerPasswordSet(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *server_name, const char *account_name, enum netr_SchannelType secure_channel_type, const char *computer_name, - struct netr_Authenticator credential, - struct samr_Password new_password, - struct netr_Authenticator *return_authenticator); + struct netr_Authenticator *credential, + struct netr_Authenticator *return_authenticator, + struct samr_Password *new_password); NTSTATUS rpccli_netr_DatabaseDeltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *logon_server, const char *computername, - struct netr_Authenticator credential, + struct netr_Authenticator *credential, struct netr_Authenticator *return_authenticator, enum netr_SamDatabaseID database_id, uint64_t *sequence_num, - uint32_t preferredmaximumlength, - struct netr_DELTA_ENUM_ARRAY *delta_enum_array); + struct netr_DELTA_ENUM_ARRAY **delta_enum_array, + uint32_t preferredmaximumlength); NTSTATUS rpccli_netr_DatabaseSync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *logon_server, @@ -127,7 +129,7 @@ NTSTATUS rpccli_netr_LogonControl2(struct rpc_pipe_client *cli, const char *logon_server, uint32_t function_code, uint32_t level, - union netr_CONTROL_DATA_INFORMATION data, + union netr_CONTROL_DATA_INFORMATION *data, union netr_CONTROL_QUERY_INFORMATION *query, WERROR *werror); NTSTATUS rpccli_netr_ServerAuthenticate2(struct rpc_pipe_client *cli, @@ -137,18 +139,19 @@ NTSTATUS rpccli_netr_ServerAuthenticate2(struct rpc_pipe_client *cli, enum netr_SchannelType secure_channel_type, const char *computer_name, struct netr_Credential *credentials, + struct netr_Credential *return_credentials, uint32_t *negotiate_flags); NTSTATUS rpccli_netr_DatabaseSync2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *logon_server, const char *computername, - struct netr_Authenticator credential, + struct netr_Authenticator *credential, struct netr_Authenticator *return_authenticator, enum netr_SamDatabaseID database_id, uint16_t restart_state, uint32_t *sync_context, - uint32_t preferredmaximumlength, - struct netr_DELTA_ENUM_ARRAY *delta_enum_array); + struct netr_DELTA_ENUM_ARRAY **delta_enum_array, + uint32_t preferredmaximumlength); NTSTATUS rpccli_netr_DatabaseRedo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *logon_server, @@ -295,7 +298,7 @@ NTSTATUS rpccli_netr_LogonSamLogonEx(struct rpc_pipe_client *cli, const char *server_name, const char *computer_name, uint16_t logon_level, - union netr_LogonLevel logon, + union netr_LogonLevel *logon, uint16_t validation_level, union netr_Validation *validation, uint8_t *authoritative, diff --git a/source3/librpc/gen_ndr/cli_ntsvcs.c b/source3/librpc/gen_ndr/cli_ntsvcs.c new file mode 100644 index 0000000000..5597fccdb5 --- /dev/null +++ b/source3/librpc/gen_ndr/cli_ntsvcs.c @@ -0,0 +1,2783 @@ +/* + * Unix SMB/CIFS implementation. + * client auto-generated by pidl. DO NOT MODIFY! + */ + +#include "includes.h" +#include "librpc/gen_ndr/cli_ntsvcs.h" + +NTSTATUS rpccli_PNP_Disconnect(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_Disconnect r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_Disconnect, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_DISCONNECT, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_Disconnect, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_Connect(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_Connect r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_Connect, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_CONNECT, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_Connect, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetVersion(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + uint16_t *version, + WERROR *werror) +{ + struct PNP_GetVersion r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetVersion, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETVERSION, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetVersion, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + *version = *r.out.version; + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetGlobalState(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetGlobalState r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetGlobalState, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETGLOBALSTATE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetGlobalState, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_InitDetection(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_InitDetection r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_InitDetection, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_INITDETECTION, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_InitDetection, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_ReportLogOn(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_ReportLogOn r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_ReportLogOn, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_REPORTLOGON, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_ReportLogOn, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_ValidateDeviceInstance(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *devicepath, + uint32_t flags, + WERROR *werror) +{ + struct PNP_ValidateDeviceInstance r; + NTSTATUS status; + + /* In parameters */ + r.in.devicepath = devicepath; + r.in.flags = flags; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_ValidateDeviceInstance, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_VALIDATEDEVICEINSTANCE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_ValidateDeviceInstance, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetRootDeviceInstance(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetRootDeviceInstance r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetRootDeviceInstance, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETROOTDEVICEINSTANCE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetRootDeviceInstance, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetRelatedDeviceInstance(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetRelatedDeviceInstance r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetRelatedDeviceInstance, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETRELATEDDEVICEINSTANCE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetRelatedDeviceInstance, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_EnumerateSubKeys(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_EnumerateSubKeys r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_EnumerateSubKeys, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_ENUMERATESUBKEYS, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_EnumerateSubKeys, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetDeviceList(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetDeviceList r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDeviceList, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETDEVICELIST, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDeviceList, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetDeviceListSize(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *devicename, + uint32_t *size, + uint32_t flags, + WERROR *werror) +{ + struct PNP_GetDeviceListSize r; + NTSTATUS status; + + /* In parameters */ + r.in.devicename = devicename; + r.in.flags = flags; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDeviceListSize, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETDEVICELISTSIZE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDeviceListSize, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + *size = *r.out.size; + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetDepth(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetDepth r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDepth, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETDEPTH, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDepth, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetDeviceRegProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetDeviceRegProp r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDeviceRegProp, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETDEVICEREGPROP, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDeviceRegProp, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_SetDeviceRegProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_SetDeviceRegProp r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_SetDeviceRegProp, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_SETDEVICEREGPROP, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_SetDeviceRegProp, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetClassInstance(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetClassInstance r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetClassInstance, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETCLASSINSTANCE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetClassInstance, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_CreateKey(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_CreateKey r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_CreateKey, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_CREATEKEY, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_CreateKey, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_DeleteRegistryKey(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_DeleteRegistryKey r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DeleteRegistryKey, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_DELETEREGISTRYKEY, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DeleteRegistryKey, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetClassCount(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetClassCount r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetClassCount, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETCLASSCOUNT, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetClassCount, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetClassName(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetClassName r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetClassName, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETCLASSNAME, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetClassName, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_DeleteClassKey(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_DeleteClassKey r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DeleteClassKey, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_DELETECLASSKEY, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DeleteClassKey, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetInterfaceDeviceAlias(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetInterfaceDeviceAlias r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetInterfaceDeviceAlias, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETINTERFACEDEVICEALIAS, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetInterfaceDeviceAlias, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetInterfaceDeviceList(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetInterfaceDeviceList r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetInterfaceDeviceList, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETINTERFACEDEVICELIST, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetInterfaceDeviceList, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetInterfaceDeviceListSize(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetInterfaceDeviceListSize r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetInterfaceDeviceListSize, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETINTERFACEDEVICELISTSIZE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetInterfaceDeviceListSize, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_RegisterDeviceClassAssociation(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_RegisterDeviceClassAssociation r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RegisterDeviceClassAssociation, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_REGISTERDEVICECLASSASSOCIATION, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RegisterDeviceClassAssociation, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_UnregisterDeviceClassAssociation(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_UnregisterDeviceClassAssociation r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_UnregisterDeviceClassAssociation, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_UNREGISTERDEVICECLASSASSOCIATION, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_UnregisterDeviceClassAssociation, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetClassRegProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetClassRegProp r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetClassRegProp, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETCLASSREGPROP, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetClassRegProp, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_SetClassRegProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_SetClassRegProp r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_SetClassRegProp, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_SETCLASSREGPROP, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_SetClassRegProp, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_CreateDevInst(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_CreateDevInst r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_CreateDevInst, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_CREATEDEVINST, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_CreateDevInst, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_DeviceInstanceAction(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_DeviceInstanceAction r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DeviceInstanceAction, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_DEVICEINSTANCEACTION, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DeviceInstanceAction, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetDeviceStatus(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetDeviceStatus r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDeviceStatus, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETDEVICESTATUS, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDeviceStatus, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_SetDeviceProblem(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_SetDeviceProblem r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_SetDeviceProblem, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_SETDEVICEPROBLEM, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_SetDeviceProblem, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_DisableDevInst(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_DisableDevInst r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DisableDevInst, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_DISABLEDEVINST, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DisableDevInst, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_UninstallDevInst(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_UninstallDevInst r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_UninstallDevInst, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_UNINSTALLDEVINST, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_UninstallDevInst, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_AddID(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_AddID r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_AddID, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_ADDID, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_AddID, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_RegisterDriver(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_RegisterDriver r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RegisterDriver, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_REGISTERDRIVER, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RegisterDriver, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_QueryRemove(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_QueryRemove r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_QueryRemove, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_QUERYREMOVE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_QueryRemove, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_RequestDeviceEject(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_RequestDeviceEject r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RequestDeviceEject, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_REQUESTDEVICEEJECT, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RequestDeviceEject, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_IsDockStationPresent(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_IsDockStationPresent r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_IsDockStationPresent, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_ISDOCKSTATIONPRESENT, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_IsDockStationPresent, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_RequestEjectPC(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_RequestEjectPC r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RequestEjectPC, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_REQUESTEJECTPC, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RequestEjectPC, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_HwProfFlags(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + uint32_t unknown1, + const char *devicepath, + uint32_t unknown2, + uint32_t *unknown3, + uint16_t *unknown4, + const char *unknown5, + const char **unknown5a, + uint32_t unknown6, + uint32_t unknown7, + WERROR *werror) +{ + struct PNP_HwProfFlags r; + NTSTATUS status; + + /* In parameters */ + r.in.unknown1 = unknown1; + r.in.devicepath = devicepath; + r.in.unknown2 = unknown2; + r.in.unknown3 = unknown3; + r.in.unknown4 = unknown4; + r.in.unknown5 = unknown5; + r.in.unknown6 = unknown6; + r.in.unknown7 = unknown7; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_HwProfFlags, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_HWPROFFLAGS, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_HwProfFlags, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + *unknown3 = *r.out.unknown3; + if (unknown4 && r.out.unknown4) { + *unknown4 = *r.out.unknown4; + } + if (unknown5a && r.out.unknown5a) { + *unknown5a = *r.out.unknown5a; + } + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetHwProfInfo(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + uint32_t idx, + struct PNP_HwProfInfo *info, + uint32_t unknown1, + uint32_t unknown2, + WERROR *werror) +{ + struct PNP_GetHwProfInfo r; + NTSTATUS status; + + /* In parameters */ + r.in.idx = idx; + r.in.info = info; + r.in.unknown1 = unknown1; + r.in.unknown2 = unknown2; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetHwProfInfo, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETHWPROFINFO, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetHwProfInfo, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + *info = *r.out.info; + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_AddEmptyLogConf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_AddEmptyLogConf r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_AddEmptyLogConf, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_ADDEMPTYLOGCONF, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_AddEmptyLogConf, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_FreeLogConf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_FreeLogConf r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_FreeLogConf, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_FREELOGCONF, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_FreeLogConf, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetFirstLogConf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetFirstLogConf r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetFirstLogConf, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETFIRSTLOGCONF, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetFirstLogConf, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetNextLogConf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetNextLogConf r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetNextLogConf, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETNEXTLOGCONF, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetNextLogConf, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetLogConfPriority(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetLogConfPriority r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetLogConfPriority, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETLOGCONFPRIORITY, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetLogConfPriority, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_AddResDes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_AddResDes r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_AddResDes, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_ADDRESDES, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_AddResDes, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_FreeResDes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_FreeResDes r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_FreeResDes, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_FREERESDES, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_FreeResDes, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetNextResDes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetNextResDes r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetNextResDes, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETNEXTRESDES, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetNextResDes, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetResDesData(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetResDesData r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetResDesData, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETRESDESDATA, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetResDesData, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetResDesDataSize(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetResDesDataSize r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetResDesDataSize, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETRESDESDATASIZE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetResDesDataSize, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_ModifyResDes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_ModifyResDes r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_ModifyResDes, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_MODIFYRESDES, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_ModifyResDes, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_DetectResourceLimit(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_DetectResourceLimit r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DetectResourceLimit, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_DETECTRESOURCELIMIT, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DetectResourceLimit, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_QueryResConfList(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_QueryResConfList r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_QueryResConfList, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_QUERYRESCONFLIST, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_QueryResConfList, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_SetHwProf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_SetHwProf r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_SetHwProf, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_SETHWPROF, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_SetHwProf, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_QueryArbitratorFreeData(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_QueryArbitratorFreeData r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_QueryArbitratorFreeData, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_QUERYARBITRATORFREEDATA, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_QueryArbitratorFreeData, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_QueryArbitratorFreeSize(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_QueryArbitratorFreeSize r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_QueryArbitratorFreeSize, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_QUERYARBITRATORFREESIZE, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_QueryArbitratorFreeSize, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_RunDetection(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_RunDetection r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RunDetection, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_RUNDETECTION, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RunDetection, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_RegisterNotification(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_RegisterNotification r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RegisterNotification, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_REGISTERNOTIFICATION, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RegisterNotification, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_UnregisterNotification(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_UnregisterNotification r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_UnregisterNotification, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_UNREGISTERNOTIFICATION, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_UnregisterNotification, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetCustomDevProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetCustomDevProp r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetCustomDevProp, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETCUSTOMDEVPROP, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetCustomDevProp, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetVersionInternal(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetVersionInternal r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetVersionInternal, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETVERSIONINTERNAL, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetVersionInternal, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetBlockedDriverInfo(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetBlockedDriverInfo r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetBlockedDriverInfo, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETBLOCKEDDRIVERINFO, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetBlockedDriverInfo, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + +NTSTATUS rpccli_PNP_GetServerSideDeviceInstallFlags(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror) +{ + struct PNP_GetServerSideDeviceInstallFlags r; + NTSTATUS status; + + /* In parameters */ + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetServerSideDeviceInstallFlags, &r); + } + + status = cli_do_rpc_ndr(cli, + mem_ctx, + PI_NTSVCS, + &ndr_table_ntsvcs, + NDR_PNP_GETSERVERSIDEDEVICEINSTALLFLAGS, + &r); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetServerSideDeviceInstallFlags, &r); + } + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + /* Return variables */ + + /* Return result */ + if (werror) { + *werror = r.out.result; + } + + return werror_to_ntstatus(r.out.result); +} + diff --git a/source3/librpc/gen_ndr/cli_ntsvcs.h b/source3/librpc/gen_ndr/cli_ntsvcs.h new file mode 100644 index 0000000000..33df63ee5d --- /dev/null +++ b/source3/librpc/gen_ndr/cli_ntsvcs.h @@ -0,0 +1,218 @@ +#include "librpc/gen_ndr/ndr_ntsvcs.h" +#ifndef __CLI_NTSVCS__ +#define __CLI_NTSVCS__ +NTSTATUS rpccli_PNP_Disconnect(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_Connect(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetVersion(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + uint16_t *version, + WERROR *werror); +NTSTATUS rpccli_PNP_GetGlobalState(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_InitDetection(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_ReportLogOn(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_ValidateDeviceInstance(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *devicepath, + uint32_t flags, + WERROR *werror); +NTSTATUS rpccli_PNP_GetRootDeviceInstance(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetRelatedDeviceInstance(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_EnumerateSubKeys(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetDeviceList(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetDeviceListSize(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *devicename, + uint32_t *size, + uint32_t flags, + WERROR *werror); +NTSTATUS rpccli_PNP_GetDepth(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetDeviceRegProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_SetDeviceRegProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetClassInstance(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_CreateKey(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_DeleteRegistryKey(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetClassCount(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetClassName(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_DeleteClassKey(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetInterfaceDeviceAlias(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetInterfaceDeviceList(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetInterfaceDeviceListSize(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_RegisterDeviceClassAssociation(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_UnregisterDeviceClassAssociation(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetClassRegProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_SetClassRegProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_CreateDevInst(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_DeviceInstanceAction(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetDeviceStatus(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_SetDeviceProblem(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_DisableDevInst(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_UninstallDevInst(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_AddID(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_RegisterDriver(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_QueryRemove(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_RequestDeviceEject(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_IsDockStationPresent(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_RequestEjectPC(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_HwProfFlags(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + uint32_t unknown1, + const char *devicepath, + uint32_t unknown2, + uint32_t *unknown3, + uint16_t *unknown4, + const char *unknown5, + const char **unknown5a, + uint32_t unknown6, + uint32_t unknown7, + WERROR *werror); +NTSTATUS rpccli_PNP_GetHwProfInfo(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + uint32_t idx, + struct PNP_HwProfInfo *info, + uint32_t unknown1, + uint32_t unknown2, + WERROR *werror); +NTSTATUS rpccli_PNP_AddEmptyLogConf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_FreeLogConf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetFirstLogConf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetNextLogConf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetLogConfPriority(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_AddResDes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_FreeResDes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetNextResDes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetResDesData(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetResDesDataSize(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_ModifyResDes(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_DetectResourceLimit(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_QueryResConfList(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_SetHwProf(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_QueryArbitratorFreeData(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_QueryArbitratorFreeSize(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_RunDetection(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_RegisterNotification(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_UnregisterNotification(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetCustomDevProp(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetVersionInternal(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetBlockedDriverInfo(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +NTSTATUS rpccli_PNP_GetServerSideDeviceInstallFlags(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + WERROR *werror); +#endif /* __CLI_NTSVCS__ */ diff --git a/source3/librpc/gen_ndr/cli_srvsvc.c b/source3/librpc/gen_ndr/cli_srvsvc.c index 2b1d050a14..3624fb0dd4 100644 --- a/source3/librpc/gen_ndr/cli_srvsvc.c +++ b/source3/librpc/gen_ndr/cli_srvsvc.c @@ -923,7 +923,7 @@ NTSTATUS rpccli_srvsvc_NetShareSetInfo(struct rpc_pipe_client *cli, const char *server_unc, const char *share_name, uint32_t level, - union srvsvc_NetShareInfo info, + union srvsvc_NetShareInfo *info, uint32_t *parm_error, WERROR *werror) { @@ -1169,7 +1169,7 @@ NTSTATUS rpccli_srvsvc_NetSrvSetInfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *server_unc, uint32_t level, - union srvsvc_NetSrvInfo info, + union srvsvc_NetSrvInfo *info, uint32_t *parm_error, WERROR *werror) { @@ -1486,7 +1486,7 @@ NTSTATUS rpccli_srvsvc_NetTransportDel(struct rpc_pipe_client *cli, NTSTATUS rpccli_srvsvc_NetRemoteTOD(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *server_unc, - struct srvsvc_NetRemoteTODInfo *info, + struct srvsvc_NetRemoteTODInfo **info, WERROR *werror) { struct srvsvc_NetRemoteTOD r; @@ -1519,9 +1519,7 @@ NTSTATUS rpccli_srvsvc_NetRemoteTOD(struct rpc_pipe_client *cli, } /* Return variables */ - if (info && r.out.info) { - *info = *r.out.info; - } + *info = *r.out.info; /* Return result */ if (werror) { diff --git a/source3/librpc/gen_ndr/cli_srvsvc.h b/source3/librpc/gen_ndr/cli_srvsvc.h index eb19db37bd..4f52600a99 100644 --- a/source3/librpc/gen_ndr/cli_srvsvc.h +++ b/source3/librpc/gen_ndr/cli_srvsvc.h @@ -138,7 +138,7 @@ NTSTATUS rpccli_srvsvc_NetShareSetInfo(struct rpc_pipe_client *cli, const char *server_unc, const char *share_name, uint32_t level, - union srvsvc_NetShareInfo info, + union srvsvc_NetShareInfo *info, uint32_t *parm_error, WERROR *werror); NTSTATUS rpccli_srvsvc_NetShareDel(struct rpc_pipe_client *cli, @@ -169,7 +169,7 @@ NTSTATUS rpccli_srvsvc_NetSrvSetInfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *server_unc, uint32_t level, - union srvsvc_NetSrvInfo info, + union srvsvc_NetSrvInfo *info, uint32_t *parm_error, WERROR *werror); NTSTATUS rpccli_srvsvc_NetDiskEnum(struct rpc_pipe_client *cli, @@ -213,7 +213,7 @@ NTSTATUS rpccli_srvsvc_NetTransportDel(struct rpc_pipe_client *cli, NTSTATUS rpccli_srvsvc_NetRemoteTOD(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *server_unc, - struct srvsvc_NetRemoteTODInfo *info, + struct srvsvc_NetRemoteTODInfo **info, WERROR *werror); NTSTATUS rpccli_srvsvc_NetSetServiceBits(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/librpc/gen_ndr/cli_svcctl.c b/source3/librpc/gen_ndr/cli_svcctl.c index 2a5d6badc6..b8f18afe1c 100644 --- a/source3/librpc/gen_ndr/cli_svcctl.c +++ b/source3/librpc/gen_ndr/cli_svcctl.c @@ -191,12 +191,20 @@ NTSTATUS rpccli_svcctl_LockServiceDatabase(struct rpc_pipe_client *cli, NTSTATUS rpccli_svcctl_QueryServiceObjectSecurity(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t security_flags, + uint8_t *buffer, + uint32_t buffer_size, + uint32_t *needed, WERROR *werror) { struct svcctl_QueryServiceObjectSecurity r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.security_flags = security_flags; + r.in.buffer_size = buffer_size; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(svcctl_QueryServiceObjectSecurity, &r); @@ -222,6 +230,8 @@ NTSTATUS rpccli_svcctl_QueryServiceObjectSecurity(struct rpc_pipe_client *cli, } /* Return variables */ + memcpy(buffer, r.out.buffer, r.in.buffer_size); + *needed = *r.out.needed; /* Return result */ if (werror) { @@ -233,12 +243,20 @@ NTSTATUS rpccli_svcctl_QueryServiceObjectSecurity(struct rpc_pipe_client *cli, NTSTATUS rpccli_svcctl_SetServiceObjectSecurity(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t security_flags, + uint8_t *buffer, + uint32_t buffer_size, WERROR *werror) { struct svcctl_SetServiceObjectSecurity r; NTSTATUS status; /* In parameters */ + r.in.handle = handle; + r.in.security_flags = security_flags; + r.in.buffer = buffer; + r.in.buffer_size = buffer_size; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(svcctl_SetServiceObjectSecurity, &r); diff --git a/source3/librpc/gen_ndr/cli_svcctl.h b/source3/librpc/gen_ndr/cli_svcctl.h index e9eeb2d9e2..7c62519187 100644 --- a/source3/librpc/gen_ndr/cli_svcctl.h +++ b/source3/librpc/gen_ndr/cli_svcctl.h @@ -22,9 +22,18 @@ NTSTATUS rpccli_svcctl_LockServiceDatabase(struct rpc_pipe_client *cli, WERROR *werror); NTSTATUS rpccli_svcctl_QueryServiceObjectSecurity(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t security_flags, + uint8_t *buffer, + uint32_t buffer_size, + uint32_t *needed, WERROR *werror); NTSTATUS rpccli_svcctl_SetServiceObjectSecurity(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, + struct policy_handle *handle, + uint32_t security_flags, + uint8_t *buffer, + uint32_t buffer_size, WERROR *werror); NTSTATUS rpccli_svcctl_QueryServiceStatus(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/librpc/gen_ndr/cli_unixinfo.c b/source3/librpc/gen_ndr/cli_unixinfo.c deleted file mode 100644 index c8a6c926ef..0000000000 --- a/source3/librpc/gen_ndr/cli_unixinfo.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * client auto-generated by pidl. DO NOT MODIFY! - */ - -#include "includes.h" -#include "librpc/gen_ndr/cli_unixinfo.h" - -NTSTATUS rpccli_unixinfo_SidToUid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - struct dom_sid sid, - uint64_t *uid) -{ - struct unixinfo_SidToUid r; - NTSTATUS status; - - /* In parameters */ - r.in.sid = sid; - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_SidToUid, &r); - } - - status = cli_do_rpc_ndr(cli, - mem_ctx, - PI_UNIXINFO, - &ndr_table_unixinfo, - NDR_UNIXINFO_SIDTOUID, - &r); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_SidToUid, &r); - } - - if (NT_STATUS_IS_ERR(status)) { - return status; - } - - /* Return variables */ - *uid = *r.out.uid; - - /* Return result */ - return r.out.result; -} - -NTSTATUS rpccli_unixinfo_UidToSid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint64_t uid, - struct dom_sid *sid) -{ - struct unixinfo_UidToSid r; - NTSTATUS status; - - /* In parameters */ - r.in.uid = uid; - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_UidToSid, &r); - } - - status = cli_do_rpc_ndr(cli, - mem_ctx, - PI_UNIXINFO, - &ndr_table_unixinfo, - NDR_UNIXINFO_UIDTOSID, - &r); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_UidToSid, &r); - } - - if (NT_STATUS_IS_ERR(status)) { - return status; - } - - /* Return variables */ - *sid = *r.out.sid; - - /* Return result */ - return r.out.result; -} - -NTSTATUS rpccli_unixinfo_SidToGid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - struct dom_sid sid, - uint64_t *gid) -{ - struct unixinfo_SidToGid r; - NTSTATUS status; - - /* In parameters */ - r.in.sid = sid; - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_SidToGid, &r); - } - - status = cli_do_rpc_ndr(cli, - mem_ctx, - PI_UNIXINFO, - &ndr_table_unixinfo, - NDR_UNIXINFO_SIDTOGID, - &r); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_SidToGid, &r); - } - - if (NT_STATUS_IS_ERR(status)) { - return status; - } - - /* Return variables */ - *gid = *r.out.gid; - - /* Return result */ - return r.out.result; -} - -NTSTATUS rpccli_unixinfo_GidToSid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint64_t gid, - struct dom_sid *sid) -{ - struct unixinfo_GidToSid r; - NTSTATUS status; - - /* In parameters */ - r.in.gid = gid; - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_GidToSid, &r); - } - - status = cli_do_rpc_ndr(cli, - mem_ctx, - PI_UNIXINFO, - &ndr_table_unixinfo, - NDR_UNIXINFO_GIDTOSID, - &r); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_GidToSid, &r); - } - - if (NT_STATUS_IS_ERR(status)) { - return status; - } - - /* Return variables */ - *sid = *r.out.sid; - - /* Return result */ - return r.out.result; -} - -NTSTATUS rpccli_unixinfo_GetPWUid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint32_t *count, - uint64_t *uids, - struct unixinfo_GetPWUidInfo *infos) -{ - struct unixinfo_GetPWUid r; - NTSTATUS status; - - /* In parameters */ - r.in.count = count; - r.in.uids = uids; - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_GetPWUid, &r); - } - - status = cli_do_rpc_ndr(cli, - mem_ctx, - PI_UNIXINFO, - &ndr_table_unixinfo, - NDR_UNIXINFO_GETPWUID, - &r); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_GetPWUid, &r); - } - - if (NT_STATUS_IS_ERR(status)) { - return status; - } - - /* Return variables */ - *count = *r.out.count; - memcpy(infos, r.out.infos, *r.in.count); - - /* Return result */ - return r.out.result; -} - diff --git a/source3/librpc/gen_ndr/cli_unixinfo.h b/source3/librpc/gen_ndr/cli_unixinfo.h deleted file mode 100644 index fa084cc75d..0000000000 --- a/source3/librpc/gen_ndr/cli_unixinfo.h +++ /dev/null @@ -1,25 +0,0 @@ -#include "librpc/gen_ndr/ndr_unixinfo.h" -#ifndef __CLI_UNIXINFO__ -#define __CLI_UNIXINFO__ -NTSTATUS rpccli_unixinfo_SidToUid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - struct dom_sid sid, - uint64_t *uid); -NTSTATUS rpccli_unixinfo_UidToSid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint64_t uid, - struct dom_sid *sid); -NTSTATUS rpccli_unixinfo_SidToGid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - struct dom_sid sid, - uint64_t *gid); -NTSTATUS rpccli_unixinfo_GidToSid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint64_t gid, - struct dom_sid *sid); -NTSTATUS rpccli_unixinfo_GetPWUid(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint32_t *count, - uint64_t *uids, - struct unixinfo_GetPWUidInfo *infos); -#endif /* __CLI_UNIXINFO__ */ diff --git a/source3/librpc/gen_ndr/krb5pac.h b/source3/librpc/gen_ndr/krb5pac.h new file mode 100644 index 0000000000..8a148253ae --- /dev/null +++ b/source3/librpc/gen_ndr/krb5pac.h @@ -0,0 +1,137 @@ +/* header auto-generated by pidl */ + +#include <stdint.h> + +#include "librpc/gen_ndr/security.h" +#include "librpc/gen_ndr/netlogon.h" +#include "librpc/gen_ndr/samr.h" +#ifndef _HEADER_krb5pac +#define _HEADER_krb5pac + +struct PAC_LOGON_NAME { + NTTIME logon_time; + uint16_t size;/* [value(2*strlen_m(account_name))] */ + const char *account_name;/* [charset(UTF16)] */ +}; + +struct PAC_SIGNATURE_DATA { + uint32_t type; + DATA_BLOB signature;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}/* [public,flag(LIBNDR_PRINT_ARRAY_HEX)] */; + +struct PAC_LOGON_INFO { + struct netr_SamInfo3 info3; + struct dom_sid2 *res_group_dom_sid;/* [unique] */ + struct samr_RidWithAttributeArray res_groups; +}/* [gensize] */; + +struct PAC_UNKNOWN_12 { + uint16_t upn_size;/* [value(2*strlen_m(upn_name))] */ + uint16_t unknown1; + uint16_t domain_size;/* [value(2*strlen_m(domain_name))] */ + uint16_t unknown2; + uint16_t unknown3; + uint16_t unknown4; + uint32_t unknown5; + const char *upn_name;/* [charset(UTF16)] */ + const char *domain_name;/* [charset(UTF16)] */ + uint32_t unknown6; +}; + +struct PAC_LOGON_INFO_CTR { + uint32_t unknown1;/* [value(0x00081001)] */ + uint32_t unknown2;/* [value(0xCCCCCCCC)] */ + uint32_t _ndr_size;/* [value(NDR_ROUND(ndr_size_PAC_LOGON_INFO(info,ndr->flags)+4,8))] */ + uint32_t unknown3;/* [value(0x00000000)] */ + struct PAC_LOGON_INFO *info;/* [unique] */ +}/* [public] */; + +enum PAC_TYPE +#ifndef USE_UINT_ENUMS + { + PAC_TYPE_LOGON_INFO=1, + PAC_TYPE_SRV_CHECKSUM=6, + PAC_TYPE_KDC_CHECKSUM=7, + PAC_TYPE_LOGON_NAME=10, + PAC_TYPE_CONSTRAINED_DELEGATION=11, + PAC_TYPE_UNKNOWN_12=12 +} +#else + { __donnot_use_enum_PAC_TYPE=0x7FFFFFFF} +#define PAC_TYPE_LOGON_INFO ( 1 ) +#define PAC_TYPE_SRV_CHECKSUM ( 6 ) +#define PAC_TYPE_KDC_CHECKSUM ( 7 ) +#define PAC_TYPE_LOGON_NAME ( 10 ) +#define PAC_TYPE_CONSTRAINED_DELEGATION ( 11 ) +#define PAC_TYPE_UNKNOWN_12 ( 12 ) +#endif +; + +union PAC_INFO { + struct PAC_LOGON_INFO_CTR logon_info;/* [case(PAC_TYPE_LOGON_INFO)] */ + struct PAC_SIGNATURE_DATA srv_cksum;/* [case(PAC_TYPE_SRV_CHECKSUM)] */ + struct PAC_SIGNATURE_DATA kdc_cksum;/* [case(PAC_TYPE_KDC_CHECKSUM)] */ + struct PAC_LOGON_NAME logon_name;/* [case(PAC_TYPE_LOGON_NAME)] */ + struct PAC_UNKNOWN_12 unknown;/* [case(PAC_TYPE_UNKNOWN_12)] */ +}/* [gensize,nodiscriminant,public] */; + +struct PAC_BUFFER { + enum PAC_TYPE type; + uint32_t _ndr_size;/* [value(_ndr_size_PAC_INFO(info,type,0))] */ + union PAC_INFO *info;/* [relative,subcontext_size(_subcontext_size_PAC_INFO(r,ndr->flags)),subcontext(0),switch_is(type),flag(LIBNDR_FLAG_ALIGN8)] */ + uint32_t _pad;/* [value(0)] */ +}/* [noprint,nopull,public,nopush] */; + +struct PAC_DATA { + uint32_t num_buffers; + uint32_t version; + struct PAC_BUFFER *buffers; +}/* [public] */; + +struct DATA_BLOB_REM { + DATA_BLOB remaining;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +struct PAC_BUFFER_RAW { + enum PAC_TYPE type; + uint32_t ndr_size; + struct DATA_BLOB_REM *info;/* [relative,subcontext_size(NDR_ROUND(ndr_size,8)),subcontext(0),flag(LIBNDR_FLAG_ALIGN8)] */ + uint32_t _pad;/* [value(0)] */ +}/* [public] */; + +struct PAC_DATA_RAW { + uint32_t num_buffers; + uint32_t version; + struct PAC_BUFFER_RAW *buffers; +}/* [public] */; + +struct netsamlogoncache_entry { + time_t timestamp; + struct netr_SamInfo3 info3; +}/* [public] */; + + +struct decode_pac { + struct { + struct PAC_DATA pac; + } in; + +}; + + +struct decode_pac_raw { + struct { + struct PAC_DATA_RAW pac; + } in; + +}; + + +struct decode_login_info { + struct { + struct PAC_LOGON_INFO logon_info; + } in; + +}; + +#endif /* _HEADER_krb5pac */ diff --git a/source3/librpc/gen_ndr/libnet_join.h b/source3/librpc/gen_ndr/libnet_join.h index 40759cb489..0415f030b4 100644 --- a/source3/librpc/gen_ndr/libnet_join.h +++ b/source3/librpc/gen_ndr/libnet_join.h @@ -7,7 +7,7 @@ #ifndef _HEADER_libnetjoin #define _HEADER_libnetjoin -; +enum netr_SchannelType; struct libnet_JoinCtx { @@ -27,6 +27,7 @@ struct libnet_JoinCtx { uint8_t modify_config; struct ads_struct *ads;/* [ref] */ uint8_t debug; + enum netr_SchannelType secure_channel_type; } in; struct { @@ -65,6 +66,8 @@ struct libnet_UnjoinCtx { const char * dns_domain_name; uint8_t modified_config; const char * error_string; + uint8_t disabled_machine_account; + uint8_t deleted_machine_account; WERROR result; } out; diff --git a/source3/librpc/gen_ndr/lsa.h b/source3/librpc/gen_ndr/lsa.h index 14d46a6542..4fea08e99d 100644 --- a/source3/librpc/gen_ndr/lsa.h +++ b/source3/librpc/gen_ndr/lsa.h @@ -8,6 +8,8 @@ #define LSA_ENUM_TRUST_DOMAIN_MULTIPLIER ( 60 ) #define LSA_REF_DOMAIN_LIST_MULTIPLIER ( 32 ) +#define MAX_REF_DOMAINS ( LSA_REF_DOMAIN_LIST_MULTIPLIER ) +#define MAX_LOOKUP_SIDS ( 0x5000 ) #define LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER ( 82 ) struct lsa_String { uint16_t length;/* [value(2*strlen_m(string))] */ @@ -17,7 +19,7 @@ struct lsa_String { struct lsa_StringLarge { uint16_t length;/* [value(2*strlen_m(string))] */ - uint16_t size;/* [value(2*(strlen_m(string)+1))] */ + uint16_t size;/* [value(2*strlen_m_term(string))] */ const char *string;/* [unique,charset(UTF16),length_is(length/2),size_is(size/2)] */ }/* [public] */; @@ -29,7 +31,13 @@ struct lsa_Strings { struct lsa_AsciiString { uint16_t length;/* [value(strlen_m(string))] */ uint16_t size;/* [value(strlen_m(string))] */ - const char * string;/* [unique,flag(LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4)] */ + const char *string;/* [unique,charset(DOS),length_is(length),size_is(size)] */ +}/* [public] */; + +struct lsa_AsciiStringLarge { + uint16_t length;/* [value(strlen_m(string))] */ + uint16_t size;/* [value(strlen_m_term(string))] */ + const char *string;/* [unique,charset(DOS),length_is(length),size_is(size)] */ }/* [public] */; struct lsa_LUID { @@ -63,6 +71,20 @@ struct lsa_ObjectAttribute { struct lsa_QosInfo *sec_qos;/* [unique] */ }; +/* bitmap lsa_PolicyAccessMask */ +#define LSA_POLICY_VIEW_LOCAL_INFORMATION ( 0x00000001 ) +#define LSA_POLICY_VIEW_AUDIT_INFORMATION ( 0x00000002 ) +#define LSA_POLICY_GET_PRIVATE_INFORMATION ( 0x00000004 ) +#define LSA_POLICY_TRUST_ADMIN ( 0x00000008 ) +#define LSA_POLICY_CREATE_ACCOUNT ( 0x00000010 ) +#define LSA_POLICY_CREATE_SECRET ( 0x00000020 ) +#define LSA_POLICY_CREATE_PRIVILEGE ( 0x00000040 ) +#define LSA_POLICY_SET_DEFAULT_QUOTA_LIMITS ( 0x00000080 ) +#define LSA_POLICY_SET_AUDIT_REQUIREMENTS ( 0x00000100 ) +#define LSA_POLICY_AUDIT_LOG_ADMIN ( 0x00000200 ) +#define LSA_POLICY_SERVER_ADMIN ( 0x00000400 ) +#define LSA_POLICY_LOOKUP_NAMES ( 0x00000800 ) + struct lsa_AuditLogInfo { uint32_t percent_full; uint32_t log_size; @@ -448,7 +470,7 @@ struct lsa_RightAttribute { }; struct lsa_RightSet { - uint32_t count; + uint32_t count;/* [range(0,256)] */ struct lsa_StringLarge *names;/* [unique,size_is(count)] */ }; @@ -774,7 +796,7 @@ struct lsa_LookupNames { } in; struct { - struct lsa_RefDomainList *domains;/* [unique] */ + struct lsa_RefDomainList **domains;/* [ref] */ struct lsa_TransSidArray *sids;/* [ref] */ uint32_t *count;/* [ref] */ NTSTATUS result; @@ -793,7 +815,7 @@ struct lsa_LookupSids { } in; struct { - struct lsa_RefDomainList *domains;/* [unique] */ + struct lsa_RefDomainList **domains;/* [ref] */ struct lsa_TransNameArray *names;/* [ref] */ uint32_t *count;/* [ref] */ NTSTATUS result; @@ -838,7 +860,7 @@ struct lsa_EnumPrivsAccount { } in; struct { - struct lsa_PrivilegeSet *privs;/* [unique] */ + struct lsa_PrivilegeSet **privs;/* [ref] */ NTSTATUS result; } out; @@ -1104,7 +1126,7 @@ struct lsa_RemoveAccountRights { struct { struct policy_handle *handle;/* [ref] */ struct dom_sid2 *sid;/* [ref] */ - uint32_t unknown; + uint8_t remove_all; struct lsa_RightSet *rights;/* [ref] */ } in; @@ -1356,7 +1378,7 @@ struct lsa_LookupSids2 { } in; struct { - struct lsa_RefDomainList *domains;/* [unique] */ + struct lsa_RefDomainList **domains;/* [ref] */ struct lsa_TransNameArray2 *names;/* [ref] */ uint32_t *count;/* [ref] */ NTSTATUS result; @@ -1378,7 +1400,7 @@ struct lsa_LookupNames2 { } in; struct { - struct lsa_RefDomainList *domains;/* [unique] */ + struct lsa_RefDomainList **domains;/* [ref] */ struct lsa_TransSidArray2 *sids;/* [ref] */ uint32_t *count;/* [ref] */ NTSTATUS result; @@ -1472,7 +1494,7 @@ struct lsa_LookupNames3 { } in; struct { - struct lsa_RefDomainList *domains;/* [unique] */ + struct lsa_RefDomainList **domains;/* [ref] */ struct lsa_TransSidArray3 *sids;/* [ref] */ uint32_t *count;/* [ref] */ NTSTATUS result; @@ -1555,7 +1577,7 @@ struct lsa_LookupSids3 { } in; struct { - struct lsa_RefDomainList *domains;/* [unique] */ + struct lsa_RefDomainList **domains;/* [ref] */ struct lsa_TransNameArray2 *names;/* [ref] */ uint32_t *count;/* [ref] */ NTSTATUS result; @@ -1576,7 +1598,7 @@ struct lsa_LookupNames4 { } in; struct { - struct lsa_RefDomainList *domains;/* [unique] */ + struct lsa_RefDomainList **domains;/* [ref] */ struct lsa_TransSidArray3 *sids;/* [ref] */ uint32_t *count;/* [ref] */ NTSTATUS result; diff --git a/source3/librpc/gen_ndr/ndr_dfs.c b/source3/librpc/gen_ndr/ndr_dfs.c index f5ce913bd2..2e9873e929 100644 --- a/source3/librpc/gen_ndr/ndr_dfs.c +++ b/source3/librpc/gen_ndr/ndr_dfs.c @@ -506,8 +506,7 @@ _PUBLIC_ void ndr_print_dfs_Info3(struct ndr_print *ndr, const char *name, const ndr->depth++; for (cntr_stores_1=0;cntr_stores_1<r->num_stores;cntr_stores_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_stores_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_stores_1) != -1) { ndr_print_dfs_StorageInfo(ndr, "stores", &r->stores[cntr_stores_1]); free(idx_1); } @@ -670,8 +669,7 @@ _PUBLIC_ void ndr_print_dfs_Info4(struct ndr_print *ndr, const char *name, const ndr->depth++; for (cntr_stores_1=0;cntr_stores_1<r->num_stores;cntr_stores_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_stores_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_stores_1) != -1) { ndr_print_dfs_StorageInfo(ndr, "stores", &r->stores[cntr_stores_1]); free(idx_1); } @@ -1079,8 +1077,7 @@ _PUBLIC_ void ndr_print_dfs_Info6(struct ndr_print *ndr, const char *name, const ndr->depth++; for (cntr_stores_1=0;cntr_stores_1<r->num_stores;cntr_stores_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_stores_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_stores_1) != -1) { ndr_print_dfs_StorageInfo2(ndr, "stores", &r->stores[cntr_stores_1]); free(idx_1); } @@ -2271,8 +2268,7 @@ _PUBLIC_ void ndr_print_dfs_EnumArray1(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_s_1=0;cntr_s_1<r->count;cntr_s_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_s_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_s_1) != -1) { ndr_print_dfs_Info1(ndr, "s", &r->s[cntr_s_1]); free(idx_1); } @@ -2358,8 +2354,7 @@ _PUBLIC_ void ndr_print_dfs_EnumArray2(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_s_1=0;cntr_s_1<r->count;cntr_s_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_s_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_s_1) != -1) { ndr_print_dfs_Info2(ndr, "s", &r->s[cntr_s_1]); free(idx_1); } @@ -2445,8 +2440,7 @@ _PUBLIC_ void ndr_print_dfs_EnumArray3(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_s_1=0;cntr_s_1<r->count;cntr_s_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_s_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_s_1) != -1) { ndr_print_dfs_Info3(ndr, "s", &r->s[cntr_s_1]); free(idx_1); } @@ -2532,8 +2526,7 @@ _PUBLIC_ void ndr_print_dfs_EnumArray4(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_s_1=0;cntr_s_1<r->count;cntr_s_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_s_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_s_1) != -1) { ndr_print_dfs_Info4(ndr, "s", &r->s[cntr_s_1]); free(idx_1); } @@ -2619,8 +2612,7 @@ _PUBLIC_ void ndr_print_dfs_EnumArray5(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_s_1=0;cntr_s_1<r->count;cntr_s_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_s_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_s_1) != -1) { ndr_print_dfs_Info5(ndr, "s", &r->s[cntr_s_1]); free(idx_1); } @@ -2706,8 +2698,7 @@ _PUBLIC_ void ndr_print_dfs_EnumArray6(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_s_1=0;cntr_s_1<r->count;cntr_s_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_s_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_s_1) != -1) { ndr_print_dfs_Info6(ndr, "s", &r->s[cntr_s_1]); free(idx_1); } @@ -2793,8 +2784,7 @@ _PUBLIC_ void ndr_print_dfs_EnumArray200(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_s_1=0;cntr_s_1<r->count;cntr_s_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_s_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_s_1) != -1) { ndr_print_dfs_Info200(ndr, "s", &r->s[cntr_s_1]); free(idx_1); } @@ -2880,8 +2870,7 @@ _PUBLIC_ void ndr_print_dfs_EnumArray300(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_s_1=0;cntr_s_1<r->count;cntr_s_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_s_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_s_1) != -1) { ndr_print_dfs_Info300(ndr, "s", &r->s[cntr_s_1]); free(idx_1); } diff --git a/source3/librpc/gen_ndr/ndr_echo.c b/source3/librpc/gen_ndr/ndr_echo.c index 67ff0f2df4..340167cf73 100644 --- a/source3/librpc/gen_ndr/ndr_echo.c +++ b/source3/librpc/gen_ndr/ndr_echo.c @@ -627,8 +627,7 @@ _PUBLIC_ void ndr_print_echo_Surrounding(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_surrounding_0=0;cntr_surrounding_0<r->x;cntr_surrounding_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_surrounding_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_surrounding_0) != -1) { ndr_print_uint16(ndr, "surrounding", r->surrounding[cntr_surrounding_0]); free(idx_0); } diff --git a/source3/librpc/gen_ndr/ndr_epmapper.c b/source3/librpc/gen_ndr/ndr_epmapper.c index 4f9422ea57..2e709e11e0 100644 --- a/source3/librpc/gen_ndr/ndr_epmapper.c +++ b/source3/librpc/gen_ndr/ndr_epmapper.c @@ -1566,8 +1566,7 @@ _PUBLIC_ void ndr_print_epm_tower(struct ndr_print *ndr, const char *name, const ndr->depth++; for (cntr_floors_0=0;cntr_floors_0<r->num_floors;cntr_floors_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_floors_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_floors_0) != -1) { ndr_print_epm_floor(ndr, "floors", &r->floors[cntr_floors_0]); free(idx_0); } @@ -1849,8 +1848,7 @@ _PUBLIC_ void ndr_print_epm_Insert(struct ndr_print *ndr, const char *name, int ndr->depth++; for (cntr_entries_0=0;cntr_entries_0<r->in.num_ents;cntr_entries_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_entries_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_entries_0) != -1) { ndr_print_epm_entry_t(ndr, "entries", &r->in.entries[cntr_entries_0]); free(idx_0); } @@ -1930,8 +1928,7 @@ _PUBLIC_ void ndr_print_epm_Delete(struct ndr_print *ndr, const char *name, int ndr->depth++; for (cntr_entries_0=0;cntr_entries_0<r->in.num_ents;cntr_entries_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_entries_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_entries_0) != -1) { ndr_print_epm_entry_t(ndr, "entries", &r->in.entries[cntr_entries_0]); free(idx_0); } @@ -2131,8 +2128,7 @@ _PUBLIC_ void ndr_print_epm_Lookup(struct ndr_print *ndr, const char *name, int ndr->depth++; for (cntr_entries_0=0;cntr_entries_0<*r->out.num_ents;cntr_entries_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_entries_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_entries_0) != -1) { ndr_print_epm_entry_t(ndr, "entries", &r->out.entries[cntr_entries_0]); free(idx_0); } @@ -2321,8 +2317,7 @@ _PUBLIC_ void ndr_print_epm_Map(struct ndr_print *ndr, const char *name, int fla ndr->depth++; for (cntr_towers_0=0;cntr_towers_0<*r->out.num_towers;cntr_towers_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_towers_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_towers_0) != -1) { ndr_print_epm_twr_p_t(ndr, "towers", &r->out.towers[cntr_towers_0]); free(idx_0); } diff --git a/source3/librpc/gen_ndr/ndr_eventlog.c b/source3/librpc/gen_ndr/ndr_eventlog.c index c6a77c54e5..c5461d99ab 100644 --- a/source3/librpc/gen_ndr/ndr_eventlog.c +++ b/source3/librpc/gen_ndr/ndr_eventlog.c @@ -176,8 +176,7 @@ _PUBLIC_ void ndr_print_eventlog_Record(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_strings_0=0;cntr_strings_0<r->num_of_strings;cntr_strings_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_strings_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_strings_0) != -1) { ndr_print_string(ndr, "strings", r->strings[cntr_strings_0]); free(idx_0); } @@ -878,7 +877,7 @@ static enum ndr_err_code ndr_pull_eventlog_ReadEventLogW(struct ndr_pull *ndr, i return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_PULL_ALLOC_N(ndr, r->out.data, r->in.number_of_bytes); - memset(r->out.data, 0, r->in.number_of_bytes * sizeof(*r->out.data)); + memset(r->out.data, 0, (r->in.number_of_bytes) * sizeof(*r->out.data)); NDR_PULL_ALLOC(ndr, r->out.sent_size); ZERO_STRUCTP(r->out.sent_size); NDR_PULL_ALLOC(ndr, r->out.real_size); diff --git a/source3/librpc/gen_ndr/ndr_krb5pac.c b/source3/librpc/gen_ndr/ndr_krb5pac.c new file mode 100644 index 0000000000..be9e2e1e4e --- /dev/null +++ b/source3/librpc/gen_ndr/ndr_krb5pac.c @@ -0,0 +1,949 @@ +/* parser auto-generated by pidl */ + +#include "includes.h" +#include "librpc/gen_ndr/ndr_krb5pac.h" + +#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/ndr_netlogon.h" +#include "librpc/gen_ndr/ndr_samr.h" +static enum ndr_err_code ndr_push_PAC_LOGON_NAME(struct ndr_push *ndr, int ndr_flags, const struct PAC_LOGON_NAME *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_NTTIME(ndr, NDR_SCALARS, r->logon_time)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 2 * strlen_m(r->account_name))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->account_name, 2 * strlen_m(r->account_name), sizeof(uint8_t), CH_UTF16)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PAC_LOGON_NAME(struct ndr_pull *ndr, int ndr_flags, struct PAC_LOGON_NAME *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_NTTIME(ndr, NDR_SCALARS, &r->logon_time)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->account_name, r->size, sizeof(uint8_t), CH_UTF16)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_LOGON_NAME(struct ndr_print *ndr, const char *name, const struct PAC_LOGON_NAME *r) +{ + ndr_print_struct(ndr, name, "PAC_LOGON_NAME"); + ndr->depth++; + ndr_print_NTTIME(ndr, "logon_time", r->logon_time); + ndr_print_uint16(ndr, "size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2 * strlen_m(r->account_name):r->size); + ndr_print_string(ndr, "account_name", r->account_name); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_PAC_SIGNATURE_DATA(struct ndr_push *ndr, int ndr_flags, const struct PAC_SIGNATURE_DATA *r) +{ + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->type)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->signature)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_PAC_SIGNATURE_DATA(struct ndr_pull *ndr, int ndr_flags, struct PAC_SIGNATURE_DATA *r) +{ + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->type)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->signature)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + ndr->flags = _flags_save_STRUCT; + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_SIGNATURE_DATA(struct ndr_print *ndr, const char *name, const struct PAC_SIGNATURE_DATA *r) +{ + ndr_print_struct(ndr, name, "PAC_SIGNATURE_DATA"); + { + uint32_t _flags_save_STRUCT = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX); + ndr->depth++; + ndr_print_uint32(ndr, "type", r->type); + ndr_print_DATA_BLOB(ndr, "signature", r->signature); + ndr->depth--; + ndr->flags = _flags_save_STRUCT; + } +} + +static enum ndr_err_code ndr_push_PAC_LOGON_INFO(struct ndr_push *ndr, int ndr_flags, const struct PAC_LOGON_INFO *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_netr_SamInfo3(ndr, NDR_SCALARS, &r->info3)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->res_group_dom_sid)); + NDR_CHECK(ndr_push_samr_RidWithAttributeArray(ndr, NDR_SCALARS, &r->res_groups)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_netr_SamInfo3(ndr, NDR_BUFFERS, &r->info3)); + if (r->res_group_dom_sid) { + NDR_CHECK(ndr_push_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->res_group_dom_sid)); + } + NDR_CHECK(ndr_push_samr_RidWithAttributeArray(ndr, NDR_BUFFERS, &r->res_groups)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PAC_LOGON_INFO(struct ndr_pull *ndr, int ndr_flags, struct PAC_LOGON_INFO *r) +{ + uint32_t _ptr_res_group_dom_sid; + TALLOC_CTX *_mem_save_res_group_dom_sid_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_netr_SamInfo3(ndr, NDR_SCALARS, &r->info3)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_res_group_dom_sid)); + if (_ptr_res_group_dom_sid) { + NDR_PULL_ALLOC(ndr, r->res_group_dom_sid); + } else { + r->res_group_dom_sid = NULL; + } + NDR_CHECK(ndr_pull_samr_RidWithAttributeArray(ndr, NDR_SCALARS, &r->res_groups)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_netr_SamInfo3(ndr, NDR_BUFFERS, &r->info3)); + if (r->res_group_dom_sid) { + _mem_save_res_group_dom_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->res_group_dom_sid, 0); + NDR_CHECK(ndr_pull_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->res_group_dom_sid)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_res_group_dom_sid_0, 0); + } + NDR_CHECK(ndr_pull_samr_RidWithAttributeArray(ndr, NDR_BUFFERS, &r->res_groups)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_LOGON_INFO(struct ndr_print *ndr, const char *name, const struct PAC_LOGON_INFO *r) +{ + ndr_print_struct(ndr, name, "PAC_LOGON_INFO"); + ndr->depth++; + ndr_print_netr_SamInfo3(ndr, "info3", &r->info3); + ndr_print_ptr(ndr, "res_group_dom_sid", r->res_group_dom_sid); + ndr->depth++; + if (r->res_group_dom_sid) { + ndr_print_dom_sid2(ndr, "res_group_dom_sid", r->res_group_dom_sid); + } + ndr->depth--; + ndr_print_samr_RidWithAttributeArray(ndr, "res_groups", &r->res_groups); + ndr->depth--; +} + +static size_t ndr_size_PAC_LOGON_INFO(const struct PAC_LOGON_INFO *r, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_PAC_LOGON_INFO); +} + +static enum ndr_err_code ndr_push_PAC_UNKNOWN_12(struct ndr_push *ndr, int ndr_flags, const struct PAC_UNKNOWN_12 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 2 * strlen_m(r->upn_name))); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->unknown1)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 2 * strlen_m(r->domain_name))); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->unknown2)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->unknown3)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->unknown4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown5)); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->upn_name, 2 * strlen_m(r->upn_name) + 2, sizeof(uint8_t), CH_UTF16)); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->domain_name, 2 * strlen_m(r->domain_name) + 2, sizeof(uint8_t), CH_UTF16)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown6)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PAC_UNKNOWN_12(struct ndr_pull *ndr, int ndr_flags, struct PAC_UNKNOWN_12 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->upn_size)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->unknown1)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->domain_size)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->unknown2)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->unknown3)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->unknown4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown5)); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->upn_name, r->upn_size + 2, sizeof(uint8_t), CH_UTF16)); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->domain_name, r->domain_size + 2, sizeof(uint8_t), CH_UTF16)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown6)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_UNKNOWN_12(struct ndr_print *ndr, const char *name, const struct PAC_UNKNOWN_12 *r) +{ + ndr_print_struct(ndr, name, "PAC_UNKNOWN_12"); + ndr->depth++; + ndr_print_uint16(ndr, "upn_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2 * strlen_m(r->upn_name):r->upn_size); + ndr_print_uint16(ndr, "unknown1", r->unknown1); + ndr_print_uint16(ndr, "domain_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2 * strlen_m(r->domain_name):r->domain_size); + ndr_print_uint16(ndr, "unknown2", r->unknown2); + ndr_print_uint16(ndr, "unknown3", r->unknown3); + ndr_print_uint16(ndr, "unknown4", r->unknown4); + ndr_print_uint32(ndr, "unknown5", r->unknown5); + ndr_print_string(ndr, "upn_name", r->upn_name); + ndr_print_string(ndr, "domain_name", r->domain_name); + ndr_print_uint32(ndr, "unknown6", r->unknown6); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_PAC_LOGON_INFO_CTR(struct ndr_push *ndr, int ndr_flags, const struct PAC_LOGON_INFO_CTR *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0x00081001)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xCCCCCCCC)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, NDR_ROUND(ndr_size_PAC_LOGON_INFO(r->info, ndr->flags) + 4, 8))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0x00000000)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->info)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->info) { + NDR_CHECK(ndr_push_PAC_LOGON_INFO(ndr, NDR_SCALARS|NDR_BUFFERS, r->info)); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_PAC_LOGON_INFO_CTR(struct ndr_pull *ndr, int ndr_flags, struct PAC_LOGON_INFO_CTR *r) +{ + uint32_t _ptr_info; + TALLOC_CTX *_mem_save_info_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown1)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown2)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown3)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); + if (_ptr_info) { + NDR_PULL_ALLOC(ndr, r->info); + } else { + r->info = NULL; + } + } + if (ndr_flags & NDR_BUFFERS) { + if (r->info) { + _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info, 0); + NDR_CHECK(ndr_pull_PAC_LOGON_INFO(ndr, NDR_SCALARS|NDR_BUFFERS, r->info)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_LOGON_INFO_CTR(struct ndr_print *ndr, const char *name, const struct PAC_LOGON_INFO_CTR *r) +{ + ndr_print_struct(ndr, name, "PAC_LOGON_INFO_CTR"); + ndr->depth++; + ndr_print_uint32(ndr, "unknown1", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?0x00081001:r->unknown1); + ndr_print_uint32(ndr, "unknown2", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?0xCCCCCCCC:r->unknown2); + ndr_print_uint32(ndr, "_ndr_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?NDR_ROUND(ndr_size_PAC_LOGON_INFO(r->info, ndr->flags) + 4, 8):r->_ndr_size); + ndr_print_uint32(ndr, "unknown3", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?0x00000000:r->unknown3); + ndr_print_ptr(ndr, "info", r->info); + ndr->depth++; + if (r->info) { + ndr_print_PAC_LOGON_INFO(ndr, "info", r->info); + } + ndr->depth--; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_PAC_TYPE(struct ndr_push *ndr, int ndr_flags, enum PAC_TYPE r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_PAC_TYPE(struct ndr_pull *ndr, int ndr_flags, enum PAC_TYPE *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_TYPE(struct ndr_print *ndr, const char *name, enum PAC_TYPE r) +{ + const char *val = NULL; + + switch (r) { + case PAC_TYPE_LOGON_INFO: val = "PAC_TYPE_LOGON_INFO"; break; + case PAC_TYPE_SRV_CHECKSUM: val = "PAC_TYPE_SRV_CHECKSUM"; break; + case PAC_TYPE_KDC_CHECKSUM: val = "PAC_TYPE_KDC_CHECKSUM"; break; + case PAC_TYPE_LOGON_NAME: val = "PAC_TYPE_LOGON_NAME"; break; + case PAC_TYPE_CONSTRAINED_DELEGATION: val = "PAC_TYPE_CONSTRAINED_DELEGATION"; break; + case PAC_TYPE_UNKNOWN_12: val = "PAC_TYPE_UNKNOWN_12"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +_PUBLIC_ enum ndr_err_code ndr_push_PAC_INFO(struct ndr_push *ndr, int ndr_flags, const union PAC_INFO *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case PAC_TYPE_LOGON_INFO: { + NDR_CHECK(ndr_push_PAC_LOGON_INFO_CTR(ndr, NDR_SCALARS, &r->logon_info)); + break; } + + case PAC_TYPE_SRV_CHECKSUM: { + NDR_CHECK(ndr_push_PAC_SIGNATURE_DATA(ndr, NDR_SCALARS, &r->srv_cksum)); + break; } + + case PAC_TYPE_KDC_CHECKSUM: { + NDR_CHECK(ndr_push_PAC_SIGNATURE_DATA(ndr, NDR_SCALARS, &r->kdc_cksum)); + break; } + + case PAC_TYPE_LOGON_NAME: { + NDR_CHECK(ndr_push_PAC_LOGON_NAME(ndr, NDR_SCALARS, &r->logon_name)); + break; } + + case PAC_TYPE_UNKNOWN_12: { + NDR_CHECK(ndr_push_PAC_UNKNOWN_12(ndr, NDR_SCALARS, &r->unknown)); + break; } + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case PAC_TYPE_LOGON_INFO: + NDR_CHECK(ndr_push_PAC_LOGON_INFO_CTR(ndr, NDR_BUFFERS, &r->logon_info)); + break; + + case PAC_TYPE_SRV_CHECKSUM: + break; + + case PAC_TYPE_KDC_CHECKSUM: + break; + + case PAC_TYPE_LOGON_NAME: + break; + + case PAC_TYPE_UNKNOWN_12: + break; + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_PAC_INFO(struct ndr_pull *ndr, int ndr_flags, union PAC_INFO *r) +{ + int level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + switch (level) { + case PAC_TYPE_LOGON_INFO: { + NDR_CHECK(ndr_pull_PAC_LOGON_INFO_CTR(ndr, NDR_SCALARS, &r->logon_info)); + break; } + + case PAC_TYPE_SRV_CHECKSUM: { + NDR_CHECK(ndr_pull_PAC_SIGNATURE_DATA(ndr, NDR_SCALARS, &r->srv_cksum)); + break; } + + case PAC_TYPE_KDC_CHECKSUM: { + NDR_CHECK(ndr_pull_PAC_SIGNATURE_DATA(ndr, NDR_SCALARS, &r->kdc_cksum)); + break; } + + case PAC_TYPE_LOGON_NAME: { + NDR_CHECK(ndr_pull_PAC_LOGON_NAME(ndr, NDR_SCALARS, &r->logon_name)); + break; } + + case PAC_TYPE_UNKNOWN_12: { + NDR_CHECK(ndr_pull_PAC_UNKNOWN_12(ndr, NDR_SCALARS, &r->unknown)); + break; } + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case PAC_TYPE_LOGON_INFO: + NDR_CHECK(ndr_pull_PAC_LOGON_INFO_CTR(ndr, NDR_BUFFERS, &r->logon_info)); + break; + + case PAC_TYPE_SRV_CHECKSUM: + break; + + case PAC_TYPE_KDC_CHECKSUM: + break; + + case PAC_TYPE_LOGON_NAME: + break; + + case PAC_TYPE_UNKNOWN_12: + break; + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_INFO(struct ndr_print *ndr, const char *name, const union PAC_INFO *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "PAC_INFO"); + switch (level) { + case PAC_TYPE_LOGON_INFO: + ndr_print_PAC_LOGON_INFO_CTR(ndr, "logon_info", &r->logon_info); + break; + + case PAC_TYPE_SRV_CHECKSUM: + ndr_print_PAC_SIGNATURE_DATA(ndr, "srv_cksum", &r->srv_cksum); + break; + + case PAC_TYPE_KDC_CHECKSUM: + ndr_print_PAC_SIGNATURE_DATA(ndr, "kdc_cksum", &r->kdc_cksum); + break; + + case PAC_TYPE_LOGON_NAME: + ndr_print_PAC_LOGON_NAME(ndr, "logon_name", &r->logon_name); + break; + + case PAC_TYPE_UNKNOWN_12: + ndr_print_PAC_UNKNOWN_12(ndr, "unknown", &r->unknown); + break; + + default: + ndr_print_bad_level(ndr, name, level); + } +} + +_PUBLIC_ size_t ndr_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags) +{ + return ndr_size_union(r, flags, level, (ndr_push_flags_fn_t)ndr_push_PAC_INFO); +} + +_PUBLIC_ enum ndr_err_code ndr_push_PAC_DATA(struct ndr_push *ndr, int ndr_flags, const struct PAC_DATA *r) +{ + uint32_t cntr_buffers_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_buffers)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->version)); + for (cntr_buffers_0 = 0; cntr_buffers_0 < r->num_buffers; cntr_buffers_0++) { + NDR_CHECK(ndr_push_PAC_BUFFER(ndr, NDR_SCALARS, &r->buffers[cntr_buffers_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + for (cntr_buffers_0 = 0; cntr_buffers_0 < r->num_buffers; cntr_buffers_0++) { + NDR_CHECK(ndr_push_PAC_BUFFER(ndr, NDR_BUFFERS, &r->buffers[cntr_buffers_0])); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_PAC_DATA(struct ndr_pull *ndr, int ndr_flags, struct PAC_DATA *r) +{ + uint32_t cntr_buffers_0; + TALLOC_CTX *_mem_save_buffers_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_buffers)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); + NDR_PULL_ALLOC_N(ndr, r->buffers, r->num_buffers); + _mem_save_buffers_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->buffers, 0); + for (cntr_buffers_0 = 0; cntr_buffers_0 < r->num_buffers; cntr_buffers_0++) { + NDR_CHECK(ndr_pull_PAC_BUFFER(ndr, NDR_SCALARS, &r->buffers[cntr_buffers_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_buffers_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + _mem_save_buffers_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->buffers, 0); + for (cntr_buffers_0 = 0; cntr_buffers_0 < r->num_buffers; cntr_buffers_0++) { + NDR_CHECK(ndr_pull_PAC_BUFFER(ndr, NDR_BUFFERS, &r->buffers[cntr_buffers_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_buffers_0, 0); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_DATA(struct ndr_print *ndr, const char *name, const struct PAC_DATA *r) +{ + uint32_t cntr_buffers_0; + ndr_print_struct(ndr, name, "PAC_DATA"); + ndr->depth++; + ndr_print_uint32(ndr, "num_buffers", r->num_buffers); + ndr_print_uint32(ndr, "version", r->version); + ndr->print(ndr, "%s: ARRAY(%d)", "buffers", r->num_buffers); + ndr->depth++; + for (cntr_buffers_0=0;cntr_buffers_0<r->num_buffers;cntr_buffers_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_buffers_0) != -1) { + ndr_print_PAC_BUFFER(ndr, "buffers", &r->buffers[cntr_buffers_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +static enum ndr_err_code ndr_push_DATA_BLOB_REM(struct ndr_push *ndr, int ndr_flags, const struct DATA_BLOB_REM *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->remaining)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_DATA_BLOB_REM(struct ndr_pull *ndr, int ndr_flags, struct DATA_BLOB_REM *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->remaining)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_DATA_BLOB_REM(struct ndr_print *ndr, const char *name, const struct DATA_BLOB_REM *r) +{ + ndr_print_struct(ndr, name, "DATA_BLOB_REM"); + ndr->depth++; + ndr_print_DATA_BLOB(ndr, "remaining", r->remaining); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_PAC_BUFFER_RAW(struct ndr_push *ndr, int ndr_flags, const struct PAC_BUFFER_RAW *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ndr_size)); + { + uint32_t _flags_save_DATA_BLOB_REM = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->info)); + ndr->flags = _flags_save_DATA_BLOB_REM; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_DATA_BLOB_REM = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + if (r->info) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->info)); + { + struct ndr_push *_ndr_info; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 0, NDR_ROUND(r->ndr_size, 8))); + NDR_CHECK(ndr_push_DATA_BLOB_REM(_ndr_info, NDR_SCALARS, r->info)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 0, NDR_ROUND(r->ndr_size, 8))); + } + } + ndr->flags = _flags_save_DATA_BLOB_REM; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_PAC_BUFFER_RAW(struct ndr_pull *ndr, int ndr_flags, struct PAC_BUFFER_RAW *r) +{ + uint32_t _ptr_info; + TALLOC_CTX *_mem_save_info_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_PAC_TYPE(ndr, NDR_SCALARS, &r->type)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ndr_size)); + { + uint32_t _flags_save_DATA_BLOB_REM = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); + if (_ptr_info) { + NDR_PULL_ALLOC(ndr, r->info); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->info, _ptr_info)); + } else { + r->info = NULL; + } + ndr->flags = _flags_save_DATA_BLOB_REM; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_DATA_BLOB_REM = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + if (r->info) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->info)); + _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info, 0); + { + struct ndr_pull *_ndr_info; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 0, NDR_ROUND(r->ndr_size, 8))); + NDR_CHECK(ndr_pull_DATA_BLOB_REM(_ndr_info, NDR_SCALARS, r->info)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info, 0, NDR_ROUND(r->ndr_size, 8))); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_DATA_BLOB_REM; + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_BUFFER_RAW(struct ndr_print *ndr, const char *name, const struct PAC_BUFFER_RAW *r) +{ + ndr_print_struct(ndr, name, "PAC_BUFFER_RAW"); + ndr->depth++; + ndr_print_PAC_TYPE(ndr, "type", r->type); + ndr_print_uint32(ndr, "ndr_size", r->ndr_size); + ndr_print_ptr(ndr, "info", r->info); + ndr->depth++; + if (r->info) { + ndr_print_DATA_BLOB_REM(ndr, "info", r->info); + } + ndr->depth--; + ndr_print_uint32(ndr, "_pad", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?0:r->_pad); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_PAC_DATA_RAW(struct ndr_push *ndr, int ndr_flags, const struct PAC_DATA_RAW *r) +{ + uint32_t cntr_buffers_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_buffers)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->version)); + for (cntr_buffers_0 = 0; cntr_buffers_0 < r->num_buffers; cntr_buffers_0++) { + NDR_CHECK(ndr_push_PAC_BUFFER_RAW(ndr, NDR_SCALARS, &r->buffers[cntr_buffers_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + for (cntr_buffers_0 = 0; cntr_buffers_0 < r->num_buffers; cntr_buffers_0++) { + NDR_CHECK(ndr_push_PAC_BUFFER_RAW(ndr, NDR_BUFFERS, &r->buffers[cntr_buffers_0])); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_PAC_DATA_RAW(struct ndr_pull *ndr, int ndr_flags, struct PAC_DATA_RAW *r) +{ + uint32_t cntr_buffers_0; + TALLOC_CTX *_mem_save_buffers_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_buffers)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); + NDR_PULL_ALLOC_N(ndr, r->buffers, r->num_buffers); + _mem_save_buffers_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->buffers, 0); + for (cntr_buffers_0 = 0; cntr_buffers_0 < r->num_buffers; cntr_buffers_0++) { + NDR_CHECK(ndr_pull_PAC_BUFFER_RAW(ndr, NDR_SCALARS, &r->buffers[cntr_buffers_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_buffers_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + _mem_save_buffers_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->buffers, 0); + for (cntr_buffers_0 = 0; cntr_buffers_0 < r->num_buffers; cntr_buffers_0++) { + NDR_CHECK(ndr_pull_PAC_BUFFER_RAW(ndr, NDR_BUFFERS, &r->buffers[cntr_buffers_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_buffers_0, 0); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PAC_DATA_RAW(struct ndr_print *ndr, const char *name, const struct PAC_DATA_RAW *r) +{ + uint32_t cntr_buffers_0; + ndr_print_struct(ndr, name, "PAC_DATA_RAW"); + ndr->depth++; + ndr_print_uint32(ndr, "num_buffers", r->num_buffers); + ndr_print_uint32(ndr, "version", r->version); + ndr->print(ndr, "%s: ARRAY(%d)", "buffers", r->num_buffers); + ndr->depth++; + for (cntr_buffers_0=0;cntr_buffers_0<r->num_buffers;cntr_buffers_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_buffers_0) != -1) { + ndr_print_PAC_BUFFER_RAW(ndr, "buffers", &r->buffers[cntr_buffers_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_netsamlogoncache_entry(struct ndr_push *ndr, int ndr_flags, const struct netsamlogoncache_entry *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_time_t(ndr, NDR_SCALARS, r->timestamp)); + NDR_CHECK(ndr_push_netr_SamInfo3(ndr, NDR_SCALARS, &r->info3)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_netr_SamInfo3(ndr, NDR_BUFFERS, &r->info3)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_netsamlogoncache_entry(struct ndr_pull *ndr, int ndr_flags, struct netsamlogoncache_entry *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_time_t(ndr, NDR_SCALARS, &r->timestamp)); + NDR_CHECK(ndr_pull_netr_SamInfo3(ndr, NDR_SCALARS, &r->info3)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_netr_SamInfo3(ndr, NDR_BUFFERS, &r->info3)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_netsamlogoncache_entry(struct ndr_print *ndr, const char *name, const struct netsamlogoncache_entry *r) +{ + ndr_print_struct(ndr, name, "netsamlogoncache_entry"); + ndr->depth++; + ndr_print_time_t(ndr, "timestamp", r->timestamp); + ndr_print_netr_SamInfo3(ndr, "info3", &r->info3); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_decode_pac(struct ndr_push *ndr, int flags, const struct decode_pac *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_push_PAC_DATA(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.pac)); + } + if (flags & NDR_OUT) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_decode_pac(struct ndr_pull *ndr, int flags, struct decode_pac *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_pull_PAC_DATA(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.pac)); + } + if (flags & NDR_OUT) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_decode_pac(struct ndr_print *ndr, const char *name, int flags, const struct decode_pac *r) +{ + ndr_print_struct(ndr, name, "decode_pac"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "decode_pac"); + ndr->depth++; + ndr_print_PAC_DATA(ndr, "pac", &r->in.pac); + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "decode_pac"); + ndr->depth++; + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_decode_pac_raw(struct ndr_push *ndr, int flags, const struct decode_pac_raw *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_push_PAC_DATA_RAW(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.pac)); + } + if (flags & NDR_OUT) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_decode_pac_raw(struct ndr_pull *ndr, int flags, struct decode_pac_raw *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_pull_PAC_DATA_RAW(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.pac)); + } + if (flags & NDR_OUT) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_decode_pac_raw(struct ndr_print *ndr, const char *name, int flags, const struct decode_pac_raw *r) +{ + ndr_print_struct(ndr, name, "decode_pac_raw"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "decode_pac_raw"); + ndr->depth++; + ndr_print_PAC_DATA_RAW(ndr, "pac", &r->in.pac); + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "decode_pac_raw"); + ndr->depth++; + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_decode_login_info(struct ndr_push *ndr, int flags, const struct decode_login_info *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_push_PAC_LOGON_INFO(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.logon_info)); + } + if (flags & NDR_OUT) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_decode_login_info(struct ndr_pull *ndr, int flags, struct decode_login_info *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_pull_PAC_LOGON_INFO(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.logon_info)); + } + if (flags & NDR_OUT) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_decode_login_info(struct ndr_print *ndr, const char *name, int flags, const struct decode_login_info *r) +{ + ndr_print_struct(ndr, name, "decode_login_info"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "decode_login_info"); + ndr->depth++; + ndr_print_PAC_LOGON_INFO(ndr, "logon_info", &r->in.logon_info); + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "decode_login_info"); + ndr->depth++; + ndr->depth--; + } + ndr->depth--; +} + +static const struct ndr_interface_call krb5pac_calls[] = { + { + "decode_pac", + sizeof(struct decode_pac), + (ndr_push_flags_fn_t) ndr_push_decode_pac, + (ndr_pull_flags_fn_t) ndr_pull_decode_pac, + (ndr_print_function_t) ndr_print_decode_pac, + false, + }, + { + "decode_pac_raw", + sizeof(struct decode_pac_raw), + (ndr_push_flags_fn_t) ndr_push_decode_pac_raw, + (ndr_pull_flags_fn_t) ndr_pull_decode_pac_raw, + (ndr_print_function_t) ndr_print_decode_pac_raw, + false, + }, + { + "decode_login_info", + sizeof(struct decode_login_info), + (ndr_push_flags_fn_t) ndr_push_decode_login_info, + (ndr_pull_flags_fn_t) ndr_pull_decode_login_info, + (ndr_print_function_t) ndr_print_decode_login_info, + false, + }, + { NULL, 0, NULL, NULL, NULL, false } +}; + +static const char * const krb5pac_endpoint_strings[] = { + "ncacn_np:[\\pipe\\krb5pac]", +}; + +static const struct ndr_interface_string_array krb5pac_endpoints = { + .count = 1, + .names = krb5pac_endpoint_strings +}; + +static const char * const krb5pac_authservice_strings[] = { + "host", +}; + +static const struct ndr_interface_string_array krb5pac_authservices = { + .count = 1, + .names = krb5pac_authservice_strings +}; + + +const struct ndr_interface_table ndr_table_krb5pac = { + .name = "krb5pac", + .syntax_id = { + {0x12345778,0x1234,0xabcd,{0x00,0x00},{0x00,0x00,0x00,0x00}}, + NDR_KRB5PAC_VERSION + }, + .helpstring = NDR_KRB5PAC_HELPSTRING, + .num_calls = 3, + .calls = krb5pac_calls, + .endpoints = &krb5pac_endpoints, + .authservices = &krb5pac_authservices +}; + diff --git a/source3/librpc/gen_ndr/ndr_krb5pac.h b/source3/librpc/gen_ndr/ndr_krb5pac.h new file mode 100644 index 0000000000..1d60382dc3 --- /dev/null +++ b/source3/librpc/gen_ndr/ndr_krb5pac.h @@ -0,0 +1,56 @@ +/* header auto-generated by pidl */ + +#include "librpc/ndr/libndr.h" +#include "librpc/gen_ndr/krb5pac.h" + +#ifndef _HEADER_NDR_krb5pac +#define _HEADER_NDR_krb5pac + +#define NDR_KRB5PAC_UUID "12345778-1234-abcd-0000-00000000" +#define NDR_KRB5PAC_VERSION 0.0 +#define NDR_KRB5PAC_NAME "krb5pac" +#define NDR_KRB5PAC_HELPSTRING "Active Directory KRB5 PAC" +extern const struct ndr_interface_table ndr_table_krb5pac; +#define NDR_DECODE_PAC (0x00) + +#define NDR_DECODE_PAC_RAW (0x01) + +#define NDR_DECODE_LOGIN_INFO (0x02) + +#define NDR_KRB5PAC_CALL_COUNT (3) +void ndr_print_PAC_LOGON_NAME(struct ndr_print *ndr, const char *name, const struct PAC_LOGON_NAME *r); +enum ndr_err_code ndr_push_PAC_SIGNATURE_DATA(struct ndr_push *ndr, int ndr_flags, const struct PAC_SIGNATURE_DATA *r); +enum ndr_err_code ndr_pull_PAC_SIGNATURE_DATA(struct ndr_pull *ndr, int ndr_flags, struct PAC_SIGNATURE_DATA *r); +void ndr_print_PAC_SIGNATURE_DATA(struct ndr_print *ndr, const char *name, const struct PAC_SIGNATURE_DATA *r); +void ndr_print_PAC_LOGON_INFO(struct ndr_print *ndr, const char *name, const struct PAC_LOGON_INFO *r); +void ndr_print_PAC_UNKNOWN_12(struct ndr_print *ndr, const char *name, const struct PAC_UNKNOWN_12 *r); +enum ndr_err_code ndr_push_PAC_LOGON_INFO_CTR(struct ndr_push *ndr, int ndr_flags, const struct PAC_LOGON_INFO_CTR *r); +enum ndr_err_code ndr_pull_PAC_LOGON_INFO_CTR(struct ndr_pull *ndr, int ndr_flags, struct PAC_LOGON_INFO_CTR *r); +void ndr_print_PAC_LOGON_INFO_CTR(struct ndr_print *ndr, const char *name, const struct PAC_LOGON_INFO_CTR *r); +enum ndr_err_code ndr_push_PAC_TYPE(struct ndr_push *ndr, int ndr_flags, enum PAC_TYPE r); +enum ndr_err_code ndr_pull_PAC_TYPE(struct ndr_pull *ndr, int ndr_flags, enum PAC_TYPE *r); +void ndr_print_PAC_TYPE(struct ndr_print *ndr, const char *name, enum PAC_TYPE r); +enum ndr_err_code ndr_push_PAC_INFO(struct ndr_push *ndr, int ndr_flags, const union PAC_INFO *r); +enum ndr_err_code ndr_pull_PAC_INFO(struct ndr_pull *ndr, int ndr_flags, union PAC_INFO *r); +void ndr_print_PAC_INFO(struct ndr_print *ndr, const char *name, const union PAC_INFO *r); +size_t ndr_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags); +enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const struct PAC_BUFFER *r); +enum ndr_err_code ndr_pull_PAC_BUFFER(struct ndr_pull *ndr, int ndr_flags, struct PAC_BUFFER *r); +void ndr_print_PAC_BUFFER(struct ndr_print *ndr, const char *name, const struct PAC_BUFFER *r); +enum ndr_err_code ndr_push_PAC_DATA(struct ndr_push *ndr, int ndr_flags, const struct PAC_DATA *r); +enum ndr_err_code ndr_pull_PAC_DATA(struct ndr_pull *ndr, int ndr_flags, struct PAC_DATA *r); +void ndr_print_PAC_DATA(struct ndr_print *ndr, const char *name, const struct PAC_DATA *r); +void ndr_print_DATA_BLOB_REM(struct ndr_print *ndr, const char *name, const struct DATA_BLOB_REM *r); +enum ndr_err_code ndr_push_PAC_BUFFER_RAW(struct ndr_push *ndr, int ndr_flags, const struct PAC_BUFFER_RAW *r); +enum ndr_err_code ndr_pull_PAC_BUFFER_RAW(struct ndr_pull *ndr, int ndr_flags, struct PAC_BUFFER_RAW *r); +void ndr_print_PAC_BUFFER_RAW(struct ndr_print *ndr, const char *name, const struct PAC_BUFFER_RAW *r); +enum ndr_err_code ndr_push_PAC_DATA_RAW(struct ndr_push *ndr, int ndr_flags, const struct PAC_DATA_RAW *r); +enum ndr_err_code ndr_pull_PAC_DATA_RAW(struct ndr_pull *ndr, int ndr_flags, struct PAC_DATA_RAW *r); +void ndr_print_PAC_DATA_RAW(struct ndr_print *ndr, const char *name, const struct PAC_DATA_RAW *r); +enum ndr_err_code ndr_push_netsamlogoncache_entry(struct ndr_push *ndr, int ndr_flags, const struct netsamlogoncache_entry *r); +enum ndr_err_code ndr_pull_netsamlogoncache_entry(struct ndr_pull *ndr, int ndr_flags, struct netsamlogoncache_entry *r); +void ndr_print_netsamlogoncache_entry(struct ndr_print *ndr, const char *name, const struct netsamlogoncache_entry *r); +void ndr_print_decode_pac(struct ndr_print *ndr, const char *name, int flags, const struct decode_pac *r); +void ndr_print_decode_pac_raw(struct ndr_print *ndr, const char *name, int flags, const struct decode_pac_raw *r); +void ndr_print_decode_login_info(struct ndr_print *ndr, const char *name, int flags, const struct decode_login_info *r); +#endif /* _HEADER_NDR_krb5pac */ diff --git a/source3/librpc/gen_ndr/ndr_libnet_join.c b/source3/librpc/gen_ndr/ndr_libnet_join.c index 5345bc0ad4..ac8f7ee71d 100644 --- a/source3/librpc/gen_ndr/ndr_libnet_join.c +++ b/source3/librpc/gen_ndr/ndr_libnet_join.c @@ -36,6 +36,7 @@ _PUBLIC_ void ndr_print_libnet_JoinCtx(struct ndr_print *ndr, const char *name, ndr_print_ads_struct(ndr, "ads", r->in.ads); ndr->depth--; ndr_print_uint8(ndr, "debug", r->in.debug); + ndr_print_netr_SchannelType(ndr, "secure_channel_type", r->in.secure_channel_type); ndr->depth--; } if (flags & NDR_OUT) { @@ -95,6 +96,8 @@ _PUBLIC_ void ndr_print_libnet_UnjoinCtx(struct ndr_print *ndr, const char *name ndr_print_string(ndr, "dns_domain_name", r->out.dns_domain_name); ndr_print_uint8(ndr, "modified_config", r->out.modified_config); ndr_print_string(ndr, "error_string", r->out.error_string); + ndr_print_uint8(ndr, "disabled_machine_account", r->out.disabled_machine_account); + ndr_print_uint8(ndr, "deleted_machine_account", r->out.deleted_machine_account); ndr_print_WERROR(ndr, "result", r->out.result); ndr->depth--; } diff --git a/source3/librpc/gen_ndr/ndr_libnet_join.h b/source3/librpc/gen_ndr/ndr_libnet_join.h index 4a5fdf0d50..14c8a863aa 100644 --- a/source3/librpc/gen_ndr/ndr_libnet_join.h +++ b/source3/librpc/gen_ndr/ndr_libnet_join.h @@ -6,11 +6,7 @@ #ifndef _HEADER_NDR_libnetjoin #define _HEADER_NDR_libnetjoin -#define NDR_LIBNET_JOINCTX (0x00) - -#define NDR_LIBNET_UNJOINCTX (0x01) - -#define NDR_LIBNETJOIN_CALL_COUNT (2) +#define NDR_LIBNETJOIN_CALL_COUNT (0) enum ndr_err_code ndr_push_libnet_JoinCtx(struct ndr_push *ndr, int flags, const struct libnet_JoinCtx *r); enum ndr_err_code ndr_pull_libnet_JoinCtx(struct ndr_pull *ndr, int flags, struct libnet_JoinCtx *r); void ndr_print_libnet_JoinCtx(struct ndr_print *ndr, const char *name, int flags, const struct libnet_JoinCtx *r); diff --git a/source3/librpc/gen_ndr/ndr_lsa.c b/source3/librpc/gen_ndr/ndr_lsa.c index 84f99749fe..03e1c21e55 100644 --- a/source3/librpc/gen_ndr/ndr_lsa.c +++ b/source3/librpc/gen_ndr/ndr_lsa.c @@ -80,12 +80,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_StringLarge(struct ndr_push *ndr, int nd if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 2 * strlen_m(r->string))); - NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 2 * (strlen_m(r->string) + 1))); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 2 * strlen_m_term(r->string))); NDR_CHECK(ndr_push_unique_ptr(ndr, r->string)); } if (ndr_flags & NDR_BUFFERS) { if (r->string) { - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 2 * (strlen_m(r->string) + 1) / 2)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 2 * strlen_m_term(r->string) / 2)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 2 * strlen_m(r->string) / 2)); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->string, 2 * strlen_m(r->string) / 2, sizeof(uint16_t), CH_UTF16)); @@ -136,7 +136,7 @@ _PUBLIC_ void ndr_print_lsa_StringLarge(struct ndr_print *ndr, const char *name, ndr_print_struct(ndr, name, "lsa_StringLarge"); ndr->depth++; ndr_print_uint16(ndr, "length", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2 * strlen_m(r->string):r->length); - ndr_print_uint16(ndr, "size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2 * (strlen_m(r->string) + 1):r->size); + ndr_print_uint16(ndr, "size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?2 * strlen_m_term(r->string):r->size); ndr_print_ptr(ndr, "string", r->string); ndr->depth++; if (r->string) { @@ -221,8 +221,7 @@ _PUBLIC_ void ndr_print_lsa_Strings(struct ndr_print *ndr, const char *name, con ndr->depth++; for (cntr_names_1=0;cntr_names_1<r->count;cntr_names_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_names_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_names_1) != -1) { ndr_print_lsa_String(ndr, "names", &r->names[cntr_names_1]); free(idx_1); } @@ -239,21 +238,14 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_AsciiString(struct ndr_push *ndr, int nd NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, strlen_m(r->string))); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, strlen_m(r->string))); - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); - NDR_CHECK(ndr_push_unique_ptr(ndr, r->string)); - ndr->flags = _flags_save_string; - } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->string)); } if (ndr_flags & NDR_BUFFERS) { - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); - if (r->string) { - NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->string)); - } - ndr->flags = _flags_save_string; + if (r->string) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, strlen_m(r->string))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, strlen_m(r->string))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->string, strlen_m(r->string), sizeof(uint8_t), CH_DOS)); } } return NDR_ERR_SUCCESS; @@ -267,29 +259,30 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_AsciiString(struct ndr_pull *ndr, int nd NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->length)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_string)); - if (_ptr_string) { - NDR_PULL_ALLOC(ndr, r->string); - } else { - r->string = NULL; - } - ndr->flags = _flags_save_string; + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_string)); + if (_ptr_string) { + NDR_PULL_ALLOC(ndr, r->string); + } else { + r->string = NULL; } } if (ndr_flags & NDR_BUFFERS) { - { - uint32_t _flags_save_string = ndr->flags; - ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_LEN4); - if (r->string) { - _mem_save_string_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->string, 0); - NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->string)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_string_0, 0); + if (r->string) { + _mem_save_string_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->string, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->string)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->string)); + if (ndr_get_array_length(ndr, &r->string) > ndr_get_array_size(ndr, &r->string)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->string), ndr_get_array_length(ndr, &r->string)); } - ndr->flags = _flags_save_string; + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->string, ndr_get_array_length(ndr, &r->string), sizeof(uint8_t), CH_DOS)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_string_0, 0); + } + if (r->string) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->string, r->size)); + } + if (r->string) { + NDR_CHECK(ndr_check_array_length(ndr, (void*)&r->string, r->length)); } } return NDR_ERR_SUCCESS; @@ -310,6 +303,77 @@ _PUBLIC_ void ndr_print_lsa_AsciiString(struct ndr_print *ndr, const char *name, ndr->depth--; } +_PUBLIC_ enum ndr_err_code ndr_push_lsa_AsciiStringLarge(struct ndr_push *ndr, int ndr_flags, const struct lsa_AsciiStringLarge *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, strlen_m(r->string))); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, strlen_m_term(r->string))); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->string)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->string) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, strlen_m_term(r->string))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, strlen_m(r->string))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->string, strlen_m(r->string), sizeof(uint8_t), CH_DOS)); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_lsa_AsciiStringLarge(struct ndr_pull *ndr, int ndr_flags, struct lsa_AsciiStringLarge *r) +{ + uint32_t _ptr_string; + TALLOC_CTX *_mem_save_string_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->length)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_string)); + if (_ptr_string) { + NDR_PULL_ALLOC(ndr, r->string); + } else { + r->string = NULL; + } + } + if (ndr_flags & NDR_BUFFERS) { + if (r->string) { + _mem_save_string_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->string, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->string)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->string)); + if (ndr_get_array_length(ndr, &r->string) > ndr_get_array_size(ndr, &r->string)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->string), ndr_get_array_length(ndr, &r->string)); + } + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->string, ndr_get_array_length(ndr, &r->string), sizeof(uint8_t), CH_DOS)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_string_0, 0); + } + if (r->string) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->string, r->size)); + } + if (r->string) { + NDR_CHECK(ndr_check_array_length(ndr, (void*)&r->string, r->length)); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_lsa_AsciiStringLarge(struct ndr_print *ndr, const char *name, const struct lsa_AsciiStringLarge *r) +{ + ndr_print_struct(ndr, name, "lsa_AsciiStringLarge"); + ndr->depth++; + ndr_print_uint16(ndr, "length", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?strlen_m(r->string):r->length); + ndr_print_uint16(ndr, "size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?strlen_m_term(r->string):r->size); + ndr_print_ptr(ndr, "string", r->string); + ndr->depth++; + if (r->string) { + ndr_print_string(ndr, "string", r->string); + } + ndr->depth--; + ndr->depth--; +} + static enum ndr_err_code ndr_push_lsa_LUID(struct ndr_push *ndr, int ndr_flags, const struct lsa_LUID *r) { if (ndr_flags & NDR_SCALARS) { @@ -453,8 +517,7 @@ _PUBLIC_ void ndr_print_lsa_PrivArray(struct ndr_print *ndr, const char *name, c ndr->depth++; for (cntr_privs_1=0;cntr_privs_1<r->count;cntr_privs_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_privs_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_privs_1) != -1) { ndr_print_lsa_PrivEntry(ndr, "privs", &r->privs[cntr_privs_1]); free(idx_1); } @@ -642,6 +705,39 @@ _PUBLIC_ void ndr_print_lsa_ObjectAttribute(struct ndr_print *ndr, const char *n ndr->depth--; } +_PUBLIC_ enum ndr_err_code ndr_push_lsa_PolicyAccessMask(struct ndr_push *ndr, int ndr_flags, uint32_t r) +{ + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_lsa_PolicyAccessMask(struct ndr_pull *ndr, int ndr_flags, uint32_t *r) +{ + uint32_t v; + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_lsa_PolicyAccessMask(struct ndr_print *ndr, const char *name, uint32_t r) +{ + ndr_print_uint32(ndr, name, r); + ndr->depth++; + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_VIEW_LOCAL_INFORMATION", LSA_POLICY_VIEW_LOCAL_INFORMATION, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_VIEW_AUDIT_INFORMATION", LSA_POLICY_VIEW_AUDIT_INFORMATION, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_GET_PRIVATE_INFORMATION", LSA_POLICY_GET_PRIVATE_INFORMATION, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_TRUST_ADMIN", LSA_POLICY_TRUST_ADMIN, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_CREATE_ACCOUNT", LSA_POLICY_CREATE_ACCOUNT, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_CREATE_SECRET", LSA_POLICY_CREATE_SECRET, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_CREATE_PRIVILEGE", LSA_POLICY_CREATE_PRIVILEGE, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_SET_DEFAULT_QUOTA_LIMITS", LSA_POLICY_SET_DEFAULT_QUOTA_LIMITS, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_SET_AUDIT_REQUIREMENTS", LSA_POLICY_SET_AUDIT_REQUIREMENTS, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_AUDIT_LOG_ADMIN", LSA_POLICY_AUDIT_LOG_ADMIN, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_SERVER_ADMIN", LSA_POLICY_SERVER_ADMIN, r); + ndr_print_bitmap_flag(ndr, sizeof(uint32_t), "LSA_POLICY_LOOKUP_NAMES", LSA_POLICY_LOOKUP_NAMES, r); + ndr->depth--; +} + static enum ndr_err_code ndr_push_lsa_AuditLogInfo(struct ndr_push *ndr, int ndr_flags, const struct lsa_AuditLogInfo *r) { if (ndr_flags & NDR_SCALARS) { @@ -789,8 +885,7 @@ _PUBLIC_ void ndr_print_lsa_AuditEventsInfo(struct ndr_print *ndr, const char *n ndr->depth++; for (cntr_settings_1=0;cntr_settings_1<r->count;cntr_settings_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_settings_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_settings_1) != -1) { ndr_print_lsa_PolicyAuditPolicy(ndr, "settings", r->settings[cntr_settings_1]); free(idx_1); } @@ -1622,8 +1717,7 @@ _PUBLIC_ void ndr_print_lsa_SidArray(struct ndr_print *ndr, const char *name, co ndr->depth++; for (cntr_sids_1=0;cntr_sids_1<r->num_sids;cntr_sids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_sids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_sids_1) != -1) { ndr_print_lsa_SidPtr(ndr, "sids", &r->sids[cntr_sids_1]); free(idx_1); } @@ -1709,8 +1803,7 @@ _PUBLIC_ void ndr_print_lsa_DomainList(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_domains_1=0;cntr_domains_1<r->count;cntr_domains_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_domains_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_domains_1) != -1) { ndr_print_lsa_DomainInfo(ndr, "domains", &r->domains[cntr_domains_1]); free(idx_1); } @@ -1862,8 +1955,7 @@ _PUBLIC_ void ndr_print_lsa_TransSidArray(struct ndr_print *ndr, const char *nam ndr->depth++; for (cntr_sids_1=0;cntr_sids_1<r->count;cntr_sids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_sids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_sids_1) != -1) { ndr_print_lsa_TranslatedSid(ndr, "sids", &r->sids[cntr_sids_1]); free(idx_1); } @@ -1954,8 +2046,7 @@ _PUBLIC_ void ndr_print_lsa_RefDomainList(struct ndr_print *ndr, const char *nam ndr->depth++; for (cntr_domains_1=0;cntr_domains_1<r->count;cntr_domains_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_domains_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_domains_1) != -1) { ndr_print_lsa_DomainInfo(ndr, "domains", &r->domains[cntr_domains_1]); free(idx_1); } @@ -2112,8 +2203,7 @@ _PUBLIC_ void ndr_print_lsa_TransNameArray(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_names_1=0;cntr_names_1<r->count;cntr_names_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_names_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_names_1) != -1) { ndr_print_lsa_TranslatedName(ndr, "names", &r->names[cntr_names_1]); free(idx_1); } @@ -2213,8 +2303,7 @@ _PUBLIC_ void ndr_print_lsa_PrivilegeSet(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_set_0=0;cntr_set_0<r->count;cntr_set_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_set_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_set_0) != -1) { ndr_print_lsa_LUIDAttribute(ndr, "set", &r->set[cntr_set_0]); free(idx_0); } @@ -3288,6 +3377,9 @@ static enum ndr_err_code ndr_pull_lsa_RightSet(struct ndr_pull *ndr, int ndr_fla if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); + if (r->count < 0 || r->count > 256) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_names)); if (_ptr_names) { NDR_PULL_ALLOC(ndr, r->names); @@ -3332,8 +3424,7 @@ _PUBLIC_ void ndr_print_lsa_RightSet(struct ndr_print *ndr, const char *name, co ndr->depth++; for (cntr_names_1=0;cntr_names_1<r->count;cntr_names_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_names_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_names_1) != -1) { ndr_print_lsa_StringLarge(ndr, "names", &r->names[cntr_names_1]); free(idx_1); } @@ -3419,8 +3510,7 @@ _PUBLIC_ void ndr_print_lsa_DomainListEx(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_domains_1=0;cntr_domains_1<r->count;cntr_domains_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_domains_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_domains_1) != -1) { ndr_print_lsa_TrustDomainInfoInfoEx(ndr, "domains", &r->domains[cntr_domains_1]); free(idx_1); } @@ -3748,8 +3838,7 @@ _PUBLIC_ void ndr_print_lsa_TransNameArray2(struct ndr_print *ndr, const char *n ndr->depth++; for (cntr_names_1=0;cntr_names_1<r->count;cntr_names_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_names_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_names_1) != -1) { ndr_print_lsa_TranslatedName2(ndr, "names", &r->names[cntr_names_1]); free(idx_1); } @@ -3871,8 +3960,7 @@ _PUBLIC_ void ndr_print_lsa_TransSidArray2(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_sids_1=0;cntr_sids_1<r->count;cntr_sids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_sids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_sids_1) != -1) { ndr_print_lsa_TranslatedSid2(ndr, "sids", &r->sids[cntr_sids_1]); free(idx_1); } @@ -4021,8 +4109,7 @@ _PUBLIC_ void ndr_print_lsa_TransSidArray3(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_sids_1=0;cntr_sids_1<r->count;cntr_sids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_sids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_sids_1) != -1) { ndr_print_lsa_TranslatedSid3(ndr, "sids", &r->sids[cntr_sids_1]); free(idx_1); } @@ -4444,8 +4531,7 @@ _PUBLIC_ void ndr_print_lsa_ForestTrustInformation(struct ndr_print *ndr, const ndr->depth++; for (cntr_entries_1=0;cntr_entries_1<r->count;cntr_entries_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_entries_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_entries_1) != -1) { ndr_print_ptr(ndr, "entries", r->entries[cntr_entries_1]); ndr->depth++; if (r->entries[cntr_entries_1]) { @@ -4936,7 +5022,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, int fla return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.attr)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.access_mask)); + NDR_CHECK(ndr_push_lsa_PolicyAccessMask(ndr, NDR_SCALARS, r->in.access_mask)); } if (flags & NDR_OUT) { if (r->out.handle == NULL) { @@ -4976,7 +5062,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr, int fla NDR_PULL_SET_MEM_CTX(ndr, r->in.attr, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_lsa_ObjectAttribute(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.attr)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_attr_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.access_mask)); + NDR_CHECK(ndr_pull_lsa_PolicyAccessMask(ndr, NDR_SCALARS, &r->in.access_mask)); NDR_PULL_ALLOC(ndr, r->out.handle); ZERO_STRUCTP(r->out.handle); } @@ -5013,7 +5099,7 @@ _PUBLIC_ void ndr_print_lsa_OpenPolicy(struct ndr_print *ndr, const char *name, ndr->depth++; ndr_print_lsa_ObjectAttribute(ndr, "attr", r->in.attr); ndr->depth--; - ndr_print_uint32(ndr, "access_mask", r->in.access_mask); + ndr_print_lsa_PolicyAccessMask(ndr, "access_mask", r->in.access_mask); ndr->depth--; } if (flags & NDR_OUT) { @@ -5701,9 +5787,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupNames(struct ndr_push *ndr, int fl NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.count)); } if (flags & NDR_OUT) { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.domains)); - if (r->out.domains) { - NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); + if (r->out.domains == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.domains)); + if (*r->out.domains) { + NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); } if (r->out.sids == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -5725,6 +5814,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, int fl TALLOC_CTX *_mem_save_handle_0; TALLOC_CTX *_mem_save_names_0; TALLOC_CTX *_mem_save_domains_0; + TALLOC_CTX *_mem_save_domains_1; TALLOC_CTX *_mem_save_sids_0; TALLOC_CTX *_mem_save_count_0; if (flags & NDR_IN) { @@ -5767,6 +5857,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, int fl NDR_PULL_SET_MEM_CTX(ndr, r->in.count, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.count)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC); + NDR_PULL_ALLOC(ndr, r->out.domains); + ZERO_STRUCTP(r->out.domains); NDR_PULL_ALLOC(ndr, r->out.sids); *r->out.sids = *r->in.sids; NDR_PULL_ALLOC(ndr, r->out.count); @@ -5776,18 +5868,24 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, int fl } } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.domains); + } + _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_domains)); if (_ptr_domains) { - NDR_PULL_ALLOC(ndr, r->out.domains); + NDR_PULL_ALLOC(ndr, *r->out.domains); } else { - r->out.domains = NULL; + *r->out.domains = NULL; } - if (r->out.domains) { - _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, 0); - NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, 0); + if (*r->out.domains) { + _mem_save_domains_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.domains, 0); + NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_1, 0); } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.sids); } @@ -5827,8 +5925,7 @@ _PUBLIC_ void ndr_print_lsa_LookupNames(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_names_0=0;cntr_names_0<r->in.num_names;cntr_names_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_names_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_names_0) != -1) { ndr_print_lsa_String(ndr, "names", &r->in.names[cntr_names_0]); free(idx_0); } @@ -5850,10 +5947,13 @@ _PUBLIC_ void ndr_print_lsa_LookupNames(struct ndr_print *ndr, const char *name, ndr->depth++; ndr_print_ptr(ndr, "domains", r->out.domains); ndr->depth++; - if (r->out.domains) { - ndr_print_lsa_RefDomainList(ndr, "domains", r->out.domains); + ndr_print_ptr(ndr, "domains", *r->out.domains); + ndr->depth++; + if (*r->out.domains) { + ndr_print_lsa_RefDomainList(ndr, "domains", *r->out.domains); } ndr->depth--; + ndr->depth--; ndr_print_ptr(ndr, "sids", r->out.sids); ndr->depth++; ndr_print_lsa_TransSidArray(ndr, "sids", r->out.sids); @@ -5890,9 +5990,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupSids(struct ndr_push *ndr, int fla NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.count)); } if (flags & NDR_OUT) { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.domains)); - if (r->out.domains) { - NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); + if (r->out.domains == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.domains)); + if (*r->out.domains) { + NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); } if (r->out.names == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -5913,6 +6016,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupSids(struct ndr_pull *ndr, int fla TALLOC_CTX *_mem_save_handle_0; TALLOC_CTX *_mem_save_sids_0; TALLOC_CTX *_mem_save_domains_0; + TALLOC_CTX *_mem_save_domains_1; TALLOC_CTX *_mem_save_names_0; TALLOC_CTX *_mem_save_count_0; if (flags & NDR_IN) { @@ -5947,24 +6051,32 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupSids(struct ndr_pull *ndr, int fla NDR_PULL_SET_MEM_CTX(ndr, r->in.count, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.count)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC); + NDR_PULL_ALLOC(ndr, r->out.domains); + ZERO_STRUCTP(r->out.domains); NDR_PULL_ALLOC(ndr, r->out.names); *r->out.names = *r->in.names; NDR_PULL_ALLOC(ndr, r->out.count); *r->out.count = *r->in.count; } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.domains); + } + _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_domains)); if (_ptr_domains) { - NDR_PULL_ALLOC(ndr, r->out.domains); + NDR_PULL_ALLOC(ndr, *r->out.domains); } else { - r->out.domains = NULL; + *r->out.domains = NULL; } - if (r->out.domains) { - _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, 0); - NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, 0); + if (*r->out.domains) { + _mem_save_domains_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.domains, 0); + NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_1, 0); } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.names); } @@ -6018,10 +6130,13 @@ _PUBLIC_ void ndr_print_lsa_LookupSids(struct ndr_print *ndr, const char *name, ndr->depth++; ndr_print_ptr(ndr, "domains", r->out.domains); ndr->depth++; - if (r->out.domains) { - ndr_print_lsa_RefDomainList(ndr, "domains", r->out.domains); + ndr_print_ptr(ndr, "domains", *r->out.domains); + ndr->depth++; + if (*r->out.domains) { + ndr_print_lsa_RefDomainList(ndr, "domains", *r->out.domains); } ndr->depth--; + ndr->depth--; ndr_print_ptr(ndr, "names", r->out.names); ndr->depth++; ndr_print_lsa_TransNameArray(ndr, "names", r->out.names); @@ -6224,9 +6339,12 @@ static enum ndr_err_code ndr_push_lsa_EnumPrivsAccount(struct ndr_push *ndr, int NDR_CHECK(ndr_push_policy_handle(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.handle)); } if (flags & NDR_OUT) { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.privs)); - if (r->out.privs) { - NDR_CHECK(ndr_push_lsa_PrivilegeSet(ndr, NDR_SCALARS, r->out.privs)); + if (r->out.privs == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.privs)); + if (*r->out.privs) { + NDR_CHECK(ndr_push_lsa_PrivilegeSet(ndr, NDR_SCALARS, *r->out.privs)); } NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } @@ -6238,6 +6356,7 @@ static enum ndr_err_code ndr_pull_lsa_EnumPrivsAccount(struct ndr_pull *ndr, int uint32_t _ptr_privs; TALLOC_CTX *_mem_save_handle_0; TALLOC_CTX *_mem_save_privs_0; + TALLOC_CTX *_mem_save_privs_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -6248,20 +6367,28 @@ static enum ndr_err_code ndr_pull_lsa_EnumPrivsAccount(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_PULL_ALLOC(ndr, r->out.privs); + ZERO_STRUCTP(r->out.privs); } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.privs); + } + _mem_save_privs_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.privs, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_privs)); if (_ptr_privs) { - NDR_PULL_ALLOC(ndr, r->out.privs); + NDR_PULL_ALLOC(ndr, *r->out.privs); } else { - r->out.privs = NULL; + *r->out.privs = NULL; } - if (r->out.privs) { - _mem_save_privs_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.privs, 0); - NDR_CHECK(ndr_pull_lsa_PrivilegeSet(ndr, NDR_SCALARS, r->out.privs)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_privs_0, 0); + if (*r->out.privs) { + _mem_save_privs_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.privs, 0); + NDR_CHECK(ndr_pull_lsa_PrivilegeSet(ndr, NDR_SCALARS, *r->out.privs)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_privs_1, 0); } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_privs_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -6288,10 +6415,13 @@ _PUBLIC_ void ndr_print_lsa_EnumPrivsAccount(struct ndr_print *ndr, const char * ndr->depth++; ndr_print_ptr(ndr, "privs", r->out.privs); ndr->depth++; - if (r->out.privs) { - ndr_print_lsa_PrivilegeSet(ndr, "privs", r->out.privs); + ndr_print_ptr(ndr, "privs", *r->out.privs); + ndr->depth++; + if (*r->out.privs) { + ndr_print_lsa_PrivilegeSet(ndr, "privs", *r->out.privs); } ndr->depth--; + ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; } @@ -8031,7 +8161,7 @@ static enum ndr_err_code ndr_push_lsa_RemoveAccountRights(struct ndr_push *ndr, return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sid)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->in.remove_all)); if (r->in.rights == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } @@ -8063,7 +8193,7 @@ static enum ndr_err_code ndr_pull_lsa_RemoveAccountRights(struct ndr_pull *ndr, NDR_PULL_SET_MEM_CTX(ndr, r->in.sid, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.sid)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sid_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->in.remove_all)); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.rights); } @@ -8096,7 +8226,7 @@ _PUBLIC_ void ndr_print_lsa_RemoveAccountRights(struct ndr_print *ndr, const cha ndr->depth++; ndr_print_dom_sid2(ndr, "sid", r->in.sid); ndr->depth--; - ndr_print_uint32(ndr, "unknown", r->in.unknown); + ndr_print_uint8(ndr, "remove_all", r->in.remove_all); ndr_print_ptr(ndr, "rights", r->in.rights); ndr->depth++; ndr_print_lsa_RightSet(ndr, "rights", r->in.rights); @@ -8427,7 +8557,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, int fl return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.attr)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.access_mask)); + NDR_CHECK(ndr_push_lsa_PolicyAccessMask(ndr, NDR_SCALARS, r->in.access_mask)); } if (flags & NDR_OUT) { if (r->out.handle == NULL) { @@ -8473,7 +8603,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr, int fl NDR_PULL_SET_MEM_CTX(ndr, r->in.attr, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_lsa_ObjectAttribute(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.attr)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_attr_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.access_mask)); + NDR_CHECK(ndr_pull_lsa_PolicyAccessMask(ndr, NDR_SCALARS, &r->in.access_mask)); NDR_PULL_ALLOC(ndr, r->out.handle); ZERO_STRUCTP(r->out.handle); } @@ -8510,7 +8640,7 @@ _PUBLIC_ void ndr_print_lsa_OpenPolicy2(struct ndr_print *ndr, const char *name, ndr->depth++; ndr_print_lsa_ObjectAttribute(ndr, "attr", r->in.attr); ndr->depth--; - ndr_print_uint32(ndr, "access_mask", r->in.access_mask); + ndr_print_lsa_PolicyAccessMask(ndr, "access_mask", r->in.access_mask); ndr->depth--; } if (flags & NDR_OUT) { @@ -9686,9 +9816,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupSids2(struct ndr_push *ndr, int fl NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2)); } if (flags & NDR_OUT) { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.domains)); - if (r->out.domains) { - NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); + if (r->out.domains == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.domains)); + if (*r->out.domains) { + NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); } if (r->out.names == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -9709,6 +9842,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupSids2(struct ndr_pull *ndr, int fl TALLOC_CTX *_mem_save_handle_0; TALLOC_CTX *_mem_save_sids_0; TALLOC_CTX *_mem_save_domains_0; + TALLOC_CTX *_mem_save_domains_1; TALLOC_CTX *_mem_save_names_0; TALLOC_CTX *_mem_save_count_0; if (flags & NDR_IN) { @@ -9745,24 +9879,32 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupSids2(struct ndr_pull *ndr, int fl NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown1)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2)); + NDR_PULL_ALLOC(ndr, r->out.domains); + ZERO_STRUCTP(r->out.domains); NDR_PULL_ALLOC(ndr, r->out.names); *r->out.names = *r->in.names; NDR_PULL_ALLOC(ndr, r->out.count); *r->out.count = *r->in.count; } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.domains); + } + _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_domains)); if (_ptr_domains) { - NDR_PULL_ALLOC(ndr, r->out.domains); + NDR_PULL_ALLOC(ndr, *r->out.domains); } else { - r->out.domains = NULL; + *r->out.domains = NULL; } - if (r->out.domains) { - _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, 0); - NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, 0); + if (*r->out.domains) { + _mem_save_domains_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.domains, 0); + NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_1, 0); } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.names); } @@ -9818,10 +9960,13 @@ _PUBLIC_ void ndr_print_lsa_LookupSids2(struct ndr_print *ndr, const char *name, ndr->depth++; ndr_print_ptr(ndr, "domains", r->out.domains); ndr->depth++; - if (r->out.domains) { - ndr_print_lsa_RefDomainList(ndr, "domains", r->out.domains); + ndr_print_ptr(ndr, "domains", *r->out.domains); + ndr->depth++; + if (*r->out.domains) { + ndr_print_lsa_RefDomainList(ndr, "domains", *r->out.domains); } ndr->depth--; + ndr->depth--; ndr_print_ptr(ndr, "names", r->out.names); ndr->depth++; ndr_print_lsa_TransNameArray2(ndr, "names", r->out.names); @@ -9865,9 +10010,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupNames2(struct ndr_push *ndr, int f NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2)); } if (flags & NDR_OUT) { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.domains)); - if (r->out.domains) { - NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); + if (r->out.domains == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.domains)); + if (*r->out.domains) { + NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); } if (r->out.sids == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -9889,6 +10037,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames2(struct ndr_pull *ndr, int f TALLOC_CTX *_mem_save_handle_0; TALLOC_CTX *_mem_save_names_0; TALLOC_CTX *_mem_save_domains_0; + TALLOC_CTX *_mem_save_domains_1; TALLOC_CTX *_mem_save_sids_0; TALLOC_CTX *_mem_save_count_0; if (flags & NDR_IN) { @@ -9933,6 +10082,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames2(struct ndr_pull *ndr, int f NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown1)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2)); + NDR_PULL_ALLOC(ndr, r->out.domains); + ZERO_STRUCTP(r->out.domains); NDR_PULL_ALLOC(ndr, r->out.sids); *r->out.sids = *r->in.sids; NDR_PULL_ALLOC(ndr, r->out.count); @@ -9942,18 +10093,24 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames2(struct ndr_pull *ndr, int f } } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.domains); + } + _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_domains)); if (_ptr_domains) { - NDR_PULL_ALLOC(ndr, r->out.domains); + NDR_PULL_ALLOC(ndr, *r->out.domains); } else { - r->out.domains = NULL; + *r->out.domains = NULL; } - if (r->out.domains) { - _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, 0); - NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, 0); + if (*r->out.domains) { + _mem_save_domains_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.domains, 0); + NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_1, 0); } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.sids); } @@ -9993,8 +10150,7 @@ _PUBLIC_ void ndr_print_lsa_LookupNames2(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_names_0=0;cntr_names_0<r->in.num_names;cntr_names_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_names_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_names_0) != -1) { ndr_print_lsa_String(ndr, "names", &r->in.names[cntr_names_0]); free(idx_0); } @@ -10018,10 +10174,13 @@ _PUBLIC_ void ndr_print_lsa_LookupNames2(struct ndr_print *ndr, const char *name ndr->depth++; ndr_print_ptr(ndr, "domains", r->out.domains); ndr->depth++; - if (r->out.domains) { - ndr_print_lsa_RefDomainList(ndr, "domains", r->out.domains); + ndr_print_ptr(ndr, "domains", *r->out.domains); + ndr->depth++; + if (*r->out.domains) { + ndr_print_lsa_RefDomainList(ndr, "domains", *r->out.domains); } ndr->depth--; + ndr->depth--; ndr_print_ptr(ndr, "sids", r->out.sids); ndr->depth++; ndr_print_lsa_TransSidArray2(ndr, "sids", r->out.sids); @@ -10434,9 +10593,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupNames3(struct ndr_push *ndr, int f NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2)); } if (flags & NDR_OUT) { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.domains)); - if (r->out.domains) { - NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); + if (r->out.domains == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.domains)); + if (*r->out.domains) { + NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); } if (r->out.sids == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -10458,6 +10620,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames3(struct ndr_pull *ndr, int f TALLOC_CTX *_mem_save_handle_0; TALLOC_CTX *_mem_save_names_0; TALLOC_CTX *_mem_save_domains_0; + TALLOC_CTX *_mem_save_domains_1; TALLOC_CTX *_mem_save_sids_0; TALLOC_CTX *_mem_save_count_0; if (flags & NDR_IN) { @@ -10502,6 +10665,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames3(struct ndr_pull *ndr, int f NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown1)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2)); + NDR_PULL_ALLOC(ndr, r->out.domains); + ZERO_STRUCTP(r->out.domains); NDR_PULL_ALLOC(ndr, r->out.sids); *r->out.sids = *r->in.sids; NDR_PULL_ALLOC(ndr, r->out.count); @@ -10511,18 +10676,24 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupNames3(struct ndr_pull *ndr, int f } } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.domains); + } + _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_domains)); if (_ptr_domains) { - NDR_PULL_ALLOC(ndr, r->out.domains); + NDR_PULL_ALLOC(ndr, *r->out.domains); } else { - r->out.domains = NULL; + *r->out.domains = NULL; } - if (r->out.domains) { - _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, 0); - NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, 0); + if (*r->out.domains) { + _mem_save_domains_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.domains, 0); + NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_1, 0); } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.sids); } @@ -10562,8 +10733,7 @@ _PUBLIC_ void ndr_print_lsa_LookupNames3(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_names_0=0;cntr_names_0<r->in.num_names;cntr_names_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_names_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_names_0) != -1) { ndr_print_lsa_String(ndr, "names", &r->in.names[cntr_names_0]); free(idx_0); } @@ -10587,10 +10757,13 @@ _PUBLIC_ void ndr_print_lsa_LookupNames3(struct ndr_print *ndr, const char *name ndr->depth++; ndr_print_ptr(ndr, "domains", r->out.domains); ndr->depth++; - if (r->out.domains) { - ndr_print_lsa_RefDomainList(ndr, "domains", r->out.domains); + ndr_print_ptr(ndr, "domains", *r->out.domains); + ndr->depth++; + if (*r->out.domains) { + ndr_print_lsa_RefDomainList(ndr, "domains", *r->out.domains); } ndr->depth--; + ndr->depth--; ndr_print_ptr(ndr, "sids", r->out.sids); ndr->depth++; ndr_print_lsa_TransSidArray3(ndr, "sids", r->out.sids); @@ -10988,9 +11161,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_lsa_LookupSids3(struct ndr_push *ndr, int fl NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2)); } if (flags & NDR_OUT) { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.domains)); - if (r->out.domains) { - NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); + if (r->out.domains == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.domains)); + if (*r->out.domains) { + NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); } if (r->out.names == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -11010,6 +11186,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupSids3(struct ndr_pull *ndr, int fl uint32_t _ptr_domains; TALLOC_CTX *_mem_save_sids_0; TALLOC_CTX *_mem_save_domains_0; + TALLOC_CTX *_mem_save_domains_1; TALLOC_CTX *_mem_save_names_0; TALLOC_CTX *_mem_save_count_0; if (flags & NDR_IN) { @@ -11039,24 +11216,32 @@ _PUBLIC_ enum ndr_err_code ndr_pull_lsa_LookupSids3(struct ndr_pull *ndr, int fl NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown1)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2)); + NDR_PULL_ALLOC(ndr, r->out.domains); + ZERO_STRUCTP(r->out.domains); NDR_PULL_ALLOC(ndr, r->out.names); *r->out.names = *r->in.names; NDR_PULL_ALLOC(ndr, r->out.count); *r->out.count = *r->in.count; } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.domains); + } + _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_domains)); if (_ptr_domains) { - NDR_PULL_ALLOC(ndr, r->out.domains); + NDR_PULL_ALLOC(ndr, *r->out.domains); } else { - r->out.domains = NULL; + *r->out.domains = NULL; } - if (r->out.domains) { - _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, 0); - NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, 0); + if (*r->out.domains) { + _mem_save_domains_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.domains, 0); + NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_1, 0); } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.names); } @@ -11108,10 +11293,13 @@ _PUBLIC_ void ndr_print_lsa_LookupSids3(struct ndr_print *ndr, const char *name, ndr->depth++; ndr_print_ptr(ndr, "domains", r->out.domains); ndr->depth++; - if (r->out.domains) { - ndr_print_lsa_RefDomainList(ndr, "domains", r->out.domains); + ndr_print_ptr(ndr, "domains", *r->out.domains); + ndr->depth++; + if (*r->out.domains) { + ndr_print_lsa_RefDomainList(ndr, "domains", *r->out.domains); } ndr->depth--; + ndr->depth--; ndr_print_ptr(ndr, "names", r->out.names); ndr->depth++; ndr_print_lsa_TransNameArray2(ndr, "names", r->out.names); @@ -11151,9 +11339,12 @@ static enum ndr_err_code ndr_push_lsa_LookupNames4(struct ndr_push *ndr, int fla NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2)); } if (flags & NDR_OUT) { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.domains)); - if (r->out.domains) { - NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); + if (r->out.domains == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.domains)); + if (*r->out.domains) { + NDR_CHECK(ndr_push_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); } if (r->out.sids == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -11174,6 +11365,7 @@ static enum ndr_err_code ndr_pull_lsa_LookupNames4(struct ndr_pull *ndr, int fla uint32_t _ptr_domains; TALLOC_CTX *_mem_save_names_0; TALLOC_CTX *_mem_save_domains_0; + TALLOC_CTX *_mem_save_domains_1; TALLOC_CTX *_mem_save_sids_0; TALLOC_CTX *_mem_save_count_0; if (flags & NDR_IN) { @@ -11211,6 +11403,8 @@ static enum ndr_err_code ndr_pull_lsa_LookupNames4(struct ndr_pull *ndr, int fla NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown1)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2)); + NDR_PULL_ALLOC(ndr, r->out.domains); + ZERO_STRUCTP(r->out.domains); NDR_PULL_ALLOC(ndr, r->out.sids); *r->out.sids = *r->in.sids; NDR_PULL_ALLOC(ndr, r->out.count); @@ -11220,18 +11414,24 @@ static enum ndr_err_code ndr_pull_lsa_LookupNames4(struct ndr_pull *ndr, int fla } } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.domains); + } + _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_domains)); if (_ptr_domains) { - NDR_PULL_ALLOC(ndr, r->out.domains); + NDR_PULL_ALLOC(ndr, *r->out.domains); } else { - r->out.domains = NULL; + *r->out.domains = NULL; } - if (r->out.domains) { - _mem_save_domains_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.domains, 0); - NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.domains)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, 0); + if (*r->out.domains) { + _mem_save_domains_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.domains, 0); + NDR_CHECK(ndr_pull_lsa_RefDomainList(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.domains)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_1, 0); } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_domains_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.sids); } @@ -11267,8 +11467,7 @@ _PUBLIC_ void ndr_print_lsa_LookupNames4(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_names_0=0;cntr_names_0<r->in.num_names;cntr_names_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_names_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_names_0) != -1) { ndr_print_lsa_String(ndr, "names", &r->in.names[cntr_names_0]); free(idx_0); } @@ -11292,10 +11491,13 @@ _PUBLIC_ void ndr_print_lsa_LookupNames4(struct ndr_print *ndr, const char *name ndr->depth++; ndr_print_ptr(ndr, "domains", r->out.domains); ndr->depth++; - if (r->out.domains) { - ndr_print_lsa_RefDomainList(ndr, "domains", r->out.domains); + ndr_print_ptr(ndr, "domains", *r->out.domains); + ndr->depth++; + if (*r->out.domains) { + ndr_print_lsa_RefDomainList(ndr, "domains", *r->out.domains); } ndr->depth--; + ndr->depth--; ndr_print_ptr(ndr, "sids", r->out.sids); ndr->depth++; ndr_print_lsa_TransSidArray3(ndr, "sids", r->out.sids); diff --git a/source3/librpc/gen_ndr/ndr_lsa.h b/source3/librpc/gen_ndr/ndr_lsa.h index 76add459c2..a96f2d41b9 100644 --- a/source3/librpc/gen_ndr/ndr_lsa.h +++ b/source3/librpc/gen_ndr/ndr_lsa.h @@ -188,11 +188,17 @@ void ndr_print_lsa_Strings(struct ndr_print *ndr, const char *name, const struct enum ndr_err_code ndr_push_lsa_AsciiString(struct ndr_push *ndr, int ndr_flags, const struct lsa_AsciiString *r); enum ndr_err_code ndr_pull_lsa_AsciiString(struct ndr_pull *ndr, int ndr_flags, struct lsa_AsciiString *r); void ndr_print_lsa_AsciiString(struct ndr_print *ndr, const char *name, const struct lsa_AsciiString *r); +enum ndr_err_code ndr_push_lsa_AsciiStringLarge(struct ndr_push *ndr, int ndr_flags, const struct lsa_AsciiStringLarge *r); +enum ndr_err_code ndr_pull_lsa_AsciiStringLarge(struct ndr_pull *ndr, int ndr_flags, struct lsa_AsciiStringLarge *r); +void ndr_print_lsa_AsciiStringLarge(struct ndr_print *ndr, const char *name, const struct lsa_AsciiStringLarge *r); void ndr_print_lsa_LUID(struct ndr_print *ndr, const char *name, const struct lsa_LUID *r); void ndr_print_lsa_PrivEntry(struct ndr_print *ndr, const char *name, const struct lsa_PrivEntry *r); void ndr_print_lsa_PrivArray(struct ndr_print *ndr, const char *name, const struct lsa_PrivArray *r); void ndr_print_lsa_QosInfo(struct ndr_print *ndr, const char *name, const struct lsa_QosInfo *r); void ndr_print_lsa_ObjectAttribute(struct ndr_print *ndr, const char *name, const struct lsa_ObjectAttribute *r); +enum ndr_err_code ndr_push_lsa_PolicyAccessMask(struct ndr_push *ndr, int ndr_flags, uint32_t r); +enum ndr_err_code ndr_pull_lsa_PolicyAccessMask(struct ndr_pull *ndr, int ndr_flags, uint32_t *r); +void ndr_print_lsa_PolicyAccessMask(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_lsa_AuditLogInfo(struct ndr_print *ndr, const char *name, const struct lsa_AuditLogInfo *r); void ndr_print_lsa_PolicyAuditPolicy(struct ndr_print *ndr, const char *name, enum lsa_PolicyAuditPolicy r); void ndr_print_lsa_AuditEventsInfo(struct ndr_print *ndr, const char *name, const struct lsa_AuditEventsInfo *r); diff --git a/source3/librpc/gen_ndr/ndr_messaging.c b/source3/librpc/gen_ndr/ndr_messaging.c index 413421f770..db886316f1 100644 --- a/source3/librpc/gen_ndr/ndr_messaging.c +++ b/source3/librpc/gen_ndr/ndr_messaging.c @@ -103,8 +103,7 @@ _PUBLIC_ void ndr_print_messaging_array(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_messages_0=0;cntr_messages_0<r->num_messages;cntr_messages_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_messages_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_messages_0) != -1) { ndr_print_messaging_rec(ndr, "messages", &r->messages[cntr_messages_0]); free(idx_0); } diff --git a/source3/librpc/gen_ndr/ndr_netlogon.c b/source3/librpc/gen_ndr/ndr_netlogon.c index b12a347ded..4c46fb0735 100644 --- a/source3/librpc/gen_ndr/ndr_netlogon.c +++ b/source3/librpc/gen_ndr/ndr_netlogon.c @@ -315,8 +315,7 @@ _PUBLIC_ void ndr_print_netr_AcctLockStr(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_bindata_1=0;cntr_bindata_1<r->length / 2;cntr_bindata_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_bindata_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_bindata_1) != -1) { ndr_print_uint16(ndr, "bindata", r->bindata[cntr_bindata_1]); free(idx_1); } @@ -1111,8 +1110,7 @@ _PUBLIC_ void ndr_print_netr_SamBaseInfo(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_unknown_0=0;cntr_unknown_0<7;cntr_unknown_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_unknown_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_unknown_0) != -1) { ndr_print_uint32(ndr, "unknown", r->unknown[cntr_unknown_0]); free(idx_0); } @@ -1287,8 +1285,7 @@ _PUBLIC_ void ndr_print_netr_SamInfo3(struct ndr_print *ndr, const char *name, c ndr->depth++; for (cntr_sids_1=0;cntr_sids_1<r->sidcount;cntr_sids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_sids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_sids_1) != -1) { ndr_print_netr_SidAttr(ndr, "sids", &r->sids[cntr_sids_1]); free(idx_1); } @@ -1396,8 +1393,7 @@ _PUBLIC_ void ndr_print_netr_SamInfo6(struct ndr_print *ndr, const char *name, c ndr->depth++; for (cntr_sids_1=0;cntr_sids_1<r->sidcount;cntr_sids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_sids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_sids_1) != -1) { ndr_print_netr_SidAttr(ndr, "sids", &r->sids[cntr_sids_1]); free(idx_1); } @@ -1411,8 +1407,7 @@ _PUBLIC_ void ndr_print_netr_SamInfo6(struct ndr_print *ndr, const char *name, c ndr->depth++; for (cntr_unknown4_0=0;cntr_unknown4_0<20;cntr_unknown4_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_unknown4_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_unknown4_0) != -1) { ndr_print_uint32(ndr, "unknown4", r->unknown4[cntr_unknown4_0]); free(idx_0); } @@ -1558,8 +1553,7 @@ _PUBLIC_ void ndr_print_netr_PacInfo(struct ndr_print *ndr, const char *name, co ndr->depth++; for (cntr_expansionroom_0=0;cntr_expansionroom_0<10;cntr_expansionroom_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_expansionroom_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_expansionroom_0) != -1) { ndr_print_uint32(ndr, "expansionroom", r->expansionroom[cntr_expansionroom_0]); free(idx_0); } @@ -2810,8 +2804,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_GROUP_MEMBER(struct ndr_print *ndr, const cha ndr->depth++; for (cntr_rids_1=0;cntr_rids_1<r->num_rids;cntr_rids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_rids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_rids_1) != -1) { ndr_print_uint32(ndr, "rids", r->rids[cntr_rids_1]); free(idx_1); } @@ -2826,8 +2819,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_GROUP_MEMBER(struct ndr_print *ndr, const cha ndr->depth++; for (cntr_attribs_1=0;cntr_attribs_1<r->num_rids;cntr_attribs_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_attribs_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_attribs_1) != -1) { ndr_print_uint32(ndr, "attribs", r->attribs[cntr_attribs_1]); free(idx_1); } @@ -3143,8 +3135,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_POLICY(struct ndr_print *ndr, const char *nam ndr->depth++; for (cntr_eventauditoptions_1=0;cntr_eventauditoptions_1<r->maxauditeventcount + 1;cntr_eventauditoptions_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_eventauditoptions_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_eventauditoptions_1) != -1) { ndr_print_uint32(ndr, "eventauditoptions", r->eventauditoptions[cntr_eventauditoptions_1]); free(idx_1); } @@ -3285,8 +3276,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_TRUSTED_DOMAIN(struct ndr_print *ndr, const c ndr->depth++; for (cntr_controller_names_1=0;cntr_controller_names_1<r->num_controllers;cntr_controller_names_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_controller_names_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_controller_names_1) != -1) { ndr_print_lsa_String(ndr, "controller_names", &r->controller_names[cntr_controller_names_1]); free(idx_1); } @@ -3484,8 +3474,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_ACCOUNT(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_privilege_attrib_1=0;cntr_privilege_attrib_1<r->privilege_entries;cntr_privilege_attrib_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_privilege_attrib_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_privilege_attrib_1) != -1) { ndr_print_uint32(ndr, "privilege_attrib", r->privilege_attrib[cntr_privilege_attrib_1]); free(idx_1); } @@ -3500,8 +3489,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_ACCOUNT(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_privilege_name_1=0;cntr_privilege_name_1<r->privilege_entries;cntr_privilege_name_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_privilege_name_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_privilege_name_1) != -1) { ndr_print_lsa_String(ndr, "privilege_name", &r->privilege_name[cntr_privilege_name_1]); free(idx_1); } @@ -5291,8 +5279,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_ENUM_ARRAY(struct ndr_print *ndr, const char ndr->depth++; for (cntr_delta_enum_1=0;cntr_delta_enum_1<r->num_deltas;cntr_delta_enum_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_delta_enum_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_delta_enum_1) != -1) { ndr_print_netr_DELTA_ENUM(ndr, "delta_enum", &r->delta_enum[cntr_delta_enum_1]); free(idx_1); } @@ -5714,6 +5701,7 @@ _PUBLIC_ void ndr_print_netr_LogonControlCode(struct ndr_print *ndr, const char const char *val = NULL; switch (r) { + case NETLOGON_CONTROL_SYNC: val = "NETLOGON_CONTROL_SYNC"; break; case NETLOGON_CONTROL_REDISCOVER: val = "NETLOGON_CONTROL_REDISCOVER"; break; case NETLOGON_CONTROL_TC_QUERY: val = "NETLOGON_CONTROL_TC_QUERY"; break; case NETLOGON_CONTROL_TRANSPORT_NOTIFY: val = "NETLOGON_CONTROL_TRANSPORT_NOTIFY"; break; @@ -6428,8 +6416,7 @@ _PUBLIC_ void ndr_print_netr_BinaryString(struct ndr_print *ndr, const char *nam ndr->depth++; for (cntr_data_1=0;cntr_data_1<r->length / 2;cntr_data_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_data_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_data_1) != -1) { ndr_print_uint16(ndr, "data", r->data[cntr_data_1]); free(idx_1); } @@ -6702,8 +6689,7 @@ _PUBLIC_ void ndr_print_netr_DomainQuery1(struct ndr_print *ndr, const char *nam ndr->depth++; for (cntr_unknown7_0=0;cntr_unknown7_0<4;cntr_unknown7_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_unknown7_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_unknown7_0) != -1) { ndr_print_uint32(ndr, "unknown7", r->unknown7[cntr_unknown7_0]); free(idx_0); } @@ -6940,8 +6926,7 @@ _PUBLIC_ void ndr_print_netr_DomainTrustInfo(struct ndr_print *ndr, const char * ndr->depth++; for (cntr_unknown1_0=0;cntr_unknown1_0<4;cntr_unknown1_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_unknown1_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_unknown1_0) != -1) { ndr_print_netr_BinaryString(ndr, "unknown1", &r->unknown1[cntr_unknown1_0]); free(idx_0); } @@ -6951,8 +6936,7 @@ _PUBLIC_ void ndr_print_netr_DomainTrustInfo(struct ndr_print *ndr, const char * ndr->depth++; for (cntr_unknown_0=0;cntr_unknown_0<4;cntr_unknown_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_unknown_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_unknown_0) != -1) { ndr_print_uint32(ndr, "unknown", r->unknown[cntr_unknown_0]); free(idx_0); } @@ -7050,8 +7034,7 @@ _PUBLIC_ void ndr_print_netr_DomainInfo1(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_trusts_1=0;cntr_trusts_1<r->num_trusts;cntr_trusts_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_trusts_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_trusts_1) != -1) { ndr_print_netr_DomainTrustInfo(ndr, "trusts", &r->trusts[cntr_trusts_1]); free(idx_1); } @@ -7063,8 +7046,7 @@ _PUBLIC_ void ndr_print_netr_DomainInfo1(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_unknown_0=0;cntr_unknown_0<14;cntr_unknown_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_unknown_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_unknown_0) != -1) { ndr_print_uint32(ndr, "unknown", r->unknown[cntr_unknown_0]); free(idx_0); } @@ -7328,8 +7310,7 @@ _PUBLIC_ void ndr_print_netr_DsRAddressToSitenamesWCtr(struct ndr_print *ndr, co ndr->depth++; for (cntr_sitename_1=0;cntr_sitename_1<r->count;cntr_sitename_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_sitename_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_sitename_1) != -1) { ndr_print_lsa_String(ndr, "sitename", &r->sitename[cntr_sitename_1]); free(idx_1); } @@ -7691,8 +7672,7 @@ _PUBLIC_ void ndr_print_netr_DomainTrustList(struct ndr_print *ndr, const char * ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_netr_DomainTrust(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -7819,8 +7799,7 @@ _PUBLIC_ void ndr_print_netr_DsRAddressToSitenamesExWCtr(struct ndr_print *ndr, ndr->depth++; for (cntr_sitename_1=0;cntr_sitename_1<r->count;cntr_sitename_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_sitename_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_sitename_1) != -1) { ndr_print_lsa_String(ndr, "sitename", &r->sitename[cntr_sitename_1]); free(idx_1); } @@ -7835,8 +7814,7 @@ _PUBLIC_ void ndr_print_netr_DsRAddressToSitenamesExWCtr(struct ndr_print *ndr, ndr->depth++; for (cntr_subnetname_1=0;cntr_subnetname_1<r->count;cntr_subnetname_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_subnetname_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_subnetname_1) != -1) { ndr_print_lsa_String(ndr, "subnetname", &r->subnetname[cntr_subnetname_1]); free(idx_1); } @@ -7922,8 +7900,7 @@ _PUBLIC_ void ndr_print_DcSitesCtr(struct ndr_print *ndr, const char *name, cons ndr->depth++; for (cntr_sites_1=0;cntr_sites_1<r->num_sites;cntr_sites_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_sites_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_sites_1) != -1) { ndr_print_lsa_String(ndr, "sites", &r->sites[cntr_sites_1]); free(idx_1); } @@ -8196,8 +8173,11 @@ static enum ndr_err_code ndr_push_netr_LogonSamLogon(struct ndr_push *ndr, int f NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, r->in.return_authenticator)); } NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.logon_level)); - NDR_CHECK(ndr_push_set_switch_value(ndr, &r->in.logon, r->in.logon_level)); - NDR_CHECK(ndr_push_netr_LogonLevel(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.logon)); + if (r->in.logon == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_set_switch_value(ndr, r->in.logon, r->in.logon_level)); + NDR_CHECK(ndr_push_netr_LogonLevel(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.logon)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.validation_level)); } if (flags & NDR_OUT) { @@ -8229,6 +8209,7 @@ static enum ndr_err_code ndr_pull_netr_LogonSamLogon(struct ndr_pull *ndr, int f TALLOC_CTX *_mem_save_computer_name_0; TALLOC_CTX *_mem_save_credential_0; TALLOC_CTX *_mem_save_return_authenticator_0; + TALLOC_CTX *_mem_save_logon_0; TALLOC_CTX *_mem_save_validation_0; TALLOC_CTX *_mem_save_authoritative_0; if (flags & NDR_IN) { @@ -8295,8 +8276,14 @@ static enum ndr_err_code ndr_pull_netr_LogonSamLogon(struct ndr_pull *ndr, int f NDR_PULL_SET_MEM_CTX(ndr, _mem_save_return_authenticator_0, 0); } NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.logon_level)); - NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->in.logon, r->in.logon_level)); - NDR_CHECK(ndr_pull_netr_LogonLevel(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.logon)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.logon); + } + _mem_save_logon_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.logon, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_set_switch_value(ndr, r->in.logon, r->in.logon_level)); + NDR_CHECK(ndr_pull_netr_LogonLevel(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.logon)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_logon_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.validation_level)); NDR_PULL_ALLOC(ndr, r->out.validation); ZERO_STRUCTP(r->out.validation); @@ -8371,8 +8358,11 @@ _PUBLIC_ void ndr_print_netr_LogonSamLogon(struct ndr_print *ndr, const char *na } ndr->depth--; ndr_print_uint16(ndr, "logon_level", r->in.logon_level); - ndr_print_set_switch_value(ndr, &r->in.logon, r->in.logon_level); - ndr_print_netr_LogonLevel(ndr, "logon", &r->in.logon); + ndr_print_ptr(ndr, "logon", r->in.logon); + ndr->depth++; + ndr_print_set_switch_value(ndr, r->in.logon, r->in.logon_level); + ndr_print_netr_LogonLevel(ndr, "logon", r->in.logon); + ndr->depth--; ndr_print_uint16(ndr, "validation_level", r->in.validation_level); ndr->depth--; } @@ -8608,10 +8598,10 @@ static enum ndr_err_code ndr_push_netr_ServerReqChallenge(struct ndr_push *ndr, NDR_CHECK(ndr_push_netr_Credential(ndr, NDR_SCALARS, r->in.credentials)); } if (flags & NDR_OUT) { - if (r->out.credentials == NULL) { + if (r->out.return_credentials == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_netr_Credential(ndr, NDR_SCALARS, r->out.credentials)); + NDR_CHECK(ndr_push_netr_Credential(ndr, NDR_SCALARS, r->out.return_credentials)); NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -8622,6 +8612,7 @@ static enum ndr_err_code ndr_pull_netr_ServerReqChallenge(struct ndr_pull *ndr, uint32_t _ptr_server_name; TALLOC_CTX *_mem_save_server_name_0; TALLOC_CTX *_mem_save_credentials_0; + TALLOC_CTX *_mem_save_return_credentials_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -8657,17 +8648,17 @@ static enum ndr_err_code ndr_pull_netr_ServerReqChallenge(struct ndr_pull *ndr, NDR_PULL_SET_MEM_CTX(ndr, r->in.credentials, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_netr_Credential(ndr, NDR_SCALARS, r->in.credentials)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credentials_0, LIBNDR_FLAG_REF_ALLOC); - NDR_PULL_ALLOC(ndr, r->out.credentials); - *r->out.credentials = *r->in.credentials; + NDR_PULL_ALLOC(ndr, r->out.return_credentials); + ZERO_STRUCTP(r->out.return_credentials); } if (flags & NDR_OUT) { if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.credentials); + NDR_PULL_ALLOC(ndr, r->out.return_credentials); } - _mem_save_credentials_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.credentials, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_netr_Credential(ndr, NDR_SCALARS, r->out.credentials)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credentials_0, LIBNDR_FLAG_REF_ALLOC); + _mem_save_return_credentials_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.return_credentials, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_netr_Credential(ndr, NDR_SCALARS, r->out.return_credentials)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_return_credentials_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -8699,9 +8690,9 @@ _PUBLIC_ void ndr_print_netr_ServerReqChallenge(struct ndr_print *ndr, const cha if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "netr_ServerReqChallenge"); ndr->depth++; - ndr_print_ptr(ndr, "credentials", r->out.credentials); + ndr_print_ptr(ndr, "return_credentials", r->out.return_credentials); ndr->depth++; - ndr_print_netr_Credential(ndr, "credentials", r->out.credentials); + ndr_print_netr_Credential(ndr, "return_credentials", r->out.return_credentials); ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; @@ -8734,10 +8725,10 @@ static enum ndr_err_code ndr_push_netr_ServerAuthenticate(struct ndr_push *ndr, NDR_CHECK(ndr_push_netr_Credential(ndr, NDR_SCALARS, r->in.credentials)); } if (flags & NDR_OUT) { - if (r->out.credentials == NULL) { + if (r->out.return_credentials == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_netr_Credential(ndr, NDR_SCALARS, r->out.credentials)); + NDR_CHECK(ndr_push_netr_Credential(ndr, NDR_SCALARS, r->out.return_credentials)); NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -8748,6 +8739,7 @@ static enum ndr_err_code ndr_pull_netr_ServerAuthenticate(struct ndr_pull *ndr, uint32_t _ptr_server_name; TALLOC_CTX *_mem_save_server_name_0; TALLOC_CTX *_mem_save_credentials_0; + TALLOC_CTX *_mem_save_return_credentials_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -8791,17 +8783,17 @@ static enum ndr_err_code ndr_pull_netr_ServerAuthenticate(struct ndr_pull *ndr, NDR_PULL_SET_MEM_CTX(ndr, r->in.credentials, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_netr_Credential(ndr, NDR_SCALARS, r->in.credentials)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credentials_0, LIBNDR_FLAG_REF_ALLOC); - NDR_PULL_ALLOC(ndr, r->out.credentials); - *r->out.credentials = *r->in.credentials; + NDR_PULL_ALLOC(ndr, r->out.return_credentials); + ZERO_STRUCTP(r->out.return_credentials); } if (flags & NDR_OUT) { if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.credentials); + NDR_PULL_ALLOC(ndr, r->out.return_credentials); } - _mem_save_credentials_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.credentials, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_netr_Credential(ndr, NDR_SCALARS, r->out.credentials)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credentials_0, LIBNDR_FLAG_REF_ALLOC); + _mem_save_return_credentials_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.return_credentials, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_netr_Credential(ndr, NDR_SCALARS, r->out.return_credentials)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_return_credentials_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -8835,9 +8827,9 @@ _PUBLIC_ void ndr_print_netr_ServerAuthenticate(struct ndr_print *ndr, const cha if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "netr_ServerAuthenticate"); ndr->depth++; - ndr_print_ptr(ndr, "credentials", r->out.credentials); + ndr_print_ptr(ndr, "return_credentials", r->out.return_credentials); ndr->depth++; - ndr_print_netr_Credential(ndr, "credentials", r->out.credentials); + ndr_print_netr_Credential(ndr, "return_credentials", r->out.return_credentials); ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; @@ -8864,8 +8856,14 @@ static enum ndr_err_code ndr_push_netr_ServerPasswordSet(struct ndr_push *ndr, i NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.computer_name, CH_UTF16))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.computer_name, ndr_charset_length(r->in.computer_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); - NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.new_password)); + if (r->in.credential == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); + if (r->in.new_password == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.new_password)); } if (flags & NDR_OUT) { if (r->out.return_authenticator == NULL) { @@ -8881,7 +8879,9 @@ static enum ndr_err_code ndr_pull_netr_ServerPasswordSet(struct ndr_pull *ndr, i { uint32_t _ptr_server_name; TALLOC_CTX *_mem_save_server_name_0; + TALLOC_CTX *_mem_save_credential_0; TALLOC_CTX *_mem_save_return_authenticator_0; + TALLOC_CTX *_mem_save_new_password_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -8918,8 +8918,20 @@ static enum ndr_err_code ndr_pull_netr_ServerPasswordSet(struct ndr_pull *ndr, i } NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.computer_name), sizeof(uint16_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.computer_name, ndr_get_array_length(ndr, &r->in.computer_name), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); - NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.new_password)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.credential); + } + _mem_save_credential_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.credential, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credential_0, LIBNDR_FLAG_REF_ALLOC); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.new_password); + } + _mem_save_new_password_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.new_password, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.new_password)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_new_password_0, LIBNDR_FLAG_REF_ALLOC); NDR_PULL_ALLOC(ndr, r->out.return_authenticator); ZERO_STRUCTP(r->out.return_authenticator); } @@ -8955,8 +8967,14 @@ _PUBLIC_ void ndr_print_netr_ServerPasswordSet(struct ndr_print *ndr, const char ndr_print_string(ndr, "account_name", r->in.account_name); ndr_print_netr_SchannelType(ndr, "secure_channel_type", r->in.secure_channel_type); ndr_print_string(ndr, "computer_name", r->in.computer_name); - ndr_print_netr_Authenticator(ndr, "credential", &r->in.credential); - ndr_print_samr_Password(ndr, "new_password", &r->in.new_password); + ndr_print_ptr(ndr, "credential", r->in.credential); + ndr->depth++; + ndr_print_netr_Authenticator(ndr, "credential", r->in.credential); + ndr->depth--; + ndr_print_ptr(ndr, "new_password", r->in.new_password); + ndr->depth++; + ndr_print_samr_Password(ndr, "new_password", r->in.new_password); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { @@ -8983,7 +9001,10 @@ static enum ndr_err_code ndr_push_netr_DatabaseDeltas(struct ndr_push *ndr, int NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.computername, CH_UTF16))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.computername, ndr_charset_length(r->in.computername, CH_UTF16), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); + if (r->in.credential == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); if (r->in.return_authenticator == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } @@ -9007,7 +9028,10 @@ static enum ndr_err_code ndr_push_netr_DatabaseDeltas(struct ndr_push *ndr, int if (r->out.delta_enum_array == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.delta_enum_array)); + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.delta_enum_array)); + if (*r->out.delta_enum_array) { + NDR_CHECK(ndr_push_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.delta_enum_array)); + } NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -9015,9 +9039,12 @@ static enum ndr_err_code ndr_push_netr_DatabaseDeltas(struct ndr_push *ndr, int static enum ndr_err_code ndr_pull_netr_DatabaseDeltas(struct ndr_pull *ndr, int flags, struct netr_DatabaseDeltas *r) { + uint32_t _ptr_delta_enum_array; + TALLOC_CTX *_mem_save_credential_0; TALLOC_CTX *_mem_save_return_authenticator_0; TALLOC_CTX *_mem_save_sequence_num_0; TALLOC_CTX *_mem_save_delta_enum_array_0; + TALLOC_CTX *_mem_save_delta_enum_array_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -9035,7 +9062,13 @@ static enum ndr_err_code ndr_pull_netr_DatabaseDeltas(struct ndr_pull *ndr, int } NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.computername), sizeof(uint16_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.computername, ndr_get_array_length(ndr, &r->in.computername), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.credential); + } + _mem_save_credential_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.credential, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credential_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.return_authenticator); } @@ -9079,7 +9112,18 @@ static enum ndr_err_code ndr_pull_netr_DatabaseDeltas(struct ndr_pull *ndr, int } _mem_save_delta_enum_array_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.delta_enum_array, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.delta_enum_array)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_delta_enum_array)); + if (_ptr_delta_enum_array) { + NDR_PULL_ALLOC(ndr, *r->out.delta_enum_array); + } else { + *r->out.delta_enum_array = NULL; + } + if (*r->out.delta_enum_array) { + _mem_save_delta_enum_array_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.delta_enum_array, 0); + NDR_CHECK(ndr_pull_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.delta_enum_array)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_delta_enum_array_1, 0); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_delta_enum_array_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } @@ -9098,7 +9142,10 @@ _PUBLIC_ void ndr_print_netr_DatabaseDeltas(struct ndr_print *ndr, const char *n ndr->depth++; ndr_print_string(ndr, "logon_server", r->in.logon_server); ndr_print_string(ndr, "computername", r->in.computername); - ndr_print_netr_Authenticator(ndr, "credential", &r->in.credential); + ndr_print_ptr(ndr, "credential", r->in.credential); + ndr->depth++; + ndr_print_netr_Authenticator(ndr, "credential", r->in.credential); + ndr->depth--; ndr_print_ptr(ndr, "return_authenticator", r->in.return_authenticator); ndr->depth++; ndr_print_netr_Authenticator(ndr, "return_authenticator", r->in.return_authenticator); @@ -9124,7 +9171,12 @@ _PUBLIC_ void ndr_print_netr_DatabaseDeltas(struct ndr_print *ndr, const char *n ndr->depth--; ndr_print_ptr(ndr, "delta_enum_array", r->out.delta_enum_array); ndr->depth++; - ndr_print_netr_DELTA_ENUM_ARRAY(ndr, "delta_enum_array", r->out.delta_enum_array); + ndr_print_ptr(ndr, "delta_enum_array", *r->out.delta_enum_array); + ndr->depth++; + if (*r->out.delta_enum_array) { + ndr_print_netr_DELTA_ENUM_ARRAY(ndr, "delta_enum_array", *r->out.delta_enum_array); + } + ndr->depth--; ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; @@ -10166,8 +10218,11 @@ static enum ndr_err_code ndr_push_netr_LogonControl2(struct ndr_push *ndr, int f } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.function_code)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.level)); - NDR_CHECK(ndr_push_set_switch_value(ndr, &r->in.data, r->in.function_code)); - NDR_CHECK(ndr_push_netr_CONTROL_DATA_INFORMATION(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.data)); + if (r->in.data == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_set_switch_value(ndr, r->in.data, r->in.function_code)); + NDR_CHECK(ndr_push_netr_CONTROL_DATA_INFORMATION(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.data)); } if (flags & NDR_OUT) { if (r->out.query == NULL) { @@ -10184,6 +10239,7 @@ static enum ndr_err_code ndr_pull_netr_LogonControl2(struct ndr_pull *ndr, int f { uint32_t _ptr_logon_server; TALLOC_CTX *_mem_save_logon_server_0; + TALLOC_CTX *_mem_save_data_0; TALLOC_CTX *_mem_save_query_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -10208,8 +10264,14 @@ static enum ndr_err_code ndr_pull_netr_LogonControl2(struct ndr_pull *ndr, int f } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.function_code)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.level)); - NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->in.data, r->in.function_code)); - NDR_CHECK(ndr_pull_netr_CONTROL_DATA_INFORMATION(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.data)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.data); + } + _mem_save_data_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.data, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_set_switch_value(ndr, r->in.data, r->in.function_code)); + NDR_CHECK(ndr_pull_netr_CONTROL_DATA_INFORMATION(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.data)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_data_0, LIBNDR_FLAG_REF_ALLOC); NDR_PULL_ALLOC(ndr, r->out.query); ZERO_STRUCTP(r->out.query); } @@ -10245,8 +10307,11 @@ _PUBLIC_ void ndr_print_netr_LogonControl2(struct ndr_print *ndr, const char *na ndr->depth--; ndr_print_uint32(ndr, "function_code", r->in.function_code); ndr_print_uint32(ndr, "level", r->in.level); - ndr_print_set_switch_value(ndr, &r->in.data, r->in.function_code); - ndr_print_netr_CONTROL_DATA_INFORMATION(ndr, "data", &r->in.data); + ndr_print_ptr(ndr, "data", r->in.data); + ndr->depth++; + ndr_print_set_switch_value(ndr, r->in.data, r->in.function_code); + ndr_print_netr_CONTROL_DATA_INFORMATION(ndr, "data", r->in.data); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { @@ -10292,10 +10357,10 @@ static enum ndr_err_code ndr_push_netr_ServerAuthenticate2(struct ndr_push *ndr, NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.negotiate_flags)); } if (flags & NDR_OUT) { - if (r->out.credentials == NULL) { + if (r->out.return_credentials == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_netr_Credential(ndr, NDR_SCALARS, r->out.credentials)); + NDR_CHECK(ndr_push_netr_Credential(ndr, NDR_SCALARS, r->out.return_credentials)); if (r->out.negotiate_flags == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } @@ -10310,6 +10375,7 @@ static enum ndr_err_code ndr_pull_netr_ServerAuthenticate2(struct ndr_pull *ndr, uint32_t _ptr_server_name; TALLOC_CTX *_mem_save_server_name_0; TALLOC_CTX *_mem_save_credentials_0; + TALLOC_CTX *_mem_save_return_credentials_0; TALLOC_CTX *_mem_save_negotiate_flags_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -10361,19 +10427,19 @@ static enum ndr_err_code ndr_pull_netr_ServerAuthenticate2(struct ndr_pull *ndr, NDR_PULL_SET_MEM_CTX(ndr, r->in.negotiate_flags, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.negotiate_flags)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_negotiate_flags_0, LIBNDR_FLAG_REF_ALLOC); - NDR_PULL_ALLOC(ndr, r->out.credentials); - *r->out.credentials = *r->in.credentials; + NDR_PULL_ALLOC(ndr, r->out.return_credentials); + ZERO_STRUCTP(r->out.return_credentials); NDR_PULL_ALLOC(ndr, r->out.negotiate_flags); *r->out.negotiate_flags = *r->in.negotiate_flags; } if (flags & NDR_OUT) { if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.credentials); + NDR_PULL_ALLOC(ndr, r->out.return_credentials); } - _mem_save_credentials_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.credentials, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_netr_Credential(ndr, NDR_SCALARS, r->out.credentials)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credentials_0, LIBNDR_FLAG_REF_ALLOC); + _mem_save_return_credentials_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.return_credentials, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_netr_Credential(ndr, NDR_SCALARS, r->out.return_credentials)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_return_credentials_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.negotiate_flags); } @@ -10418,9 +10484,9 @@ _PUBLIC_ void ndr_print_netr_ServerAuthenticate2(struct ndr_print *ndr, const ch if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "netr_ServerAuthenticate2"); ndr->depth++; - ndr_print_ptr(ndr, "credentials", r->out.credentials); + ndr_print_ptr(ndr, "return_credentials", r->out.return_credentials); ndr->depth++; - ndr_print_netr_Credential(ndr, "credentials", r->out.credentials); + ndr_print_netr_Credential(ndr, "return_credentials", r->out.return_credentials); ndr->depth--; ndr_print_ptr(ndr, "negotiate_flags", r->out.negotiate_flags); ndr->depth++; @@ -10443,7 +10509,10 @@ static enum ndr_err_code ndr_push_netr_DatabaseSync2(struct ndr_push *ndr, int f NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.computername, CH_UTF16))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.computername, ndr_charset_length(r->in.computername, CH_UTF16), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); + if (r->in.credential == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); if (r->in.return_authenticator == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } @@ -10468,7 +10537,10 @@ static enum ndr_err_code ndr_push_netr_DatabaseSync2(struct ndr_push *ndr, int f if (r->out.delta_enum_array == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.delta_enum_array)); + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.delta_enum_array)); + if (*r->out.delta_enum_array) { + NDR_CHECK(ndr_push_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.delta_enum_array)); + } NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -10476,9 +10548,12 @@ static enum ndr_err_code ndr_push_netr_DatabaseSync2(struct ndr_push *ndr, int f static enum ndr_err_code ndr_pull_netr_DatabaseSync2(struct ndr_pull *ndr, int flags, struct netr_DatabaseSync2 *r) { + uint32_t _ptr_delta_enum_array; + TALLOC_CTX *_mem_save_credential_0; TALLOC_CTX *_mem_save_return_authenticator_0; TALLOC_CTX *_mem_save_sync_context_0; TALLOC_CTX *_mem_save_delta_enum_array_0; + TALLOC_CTX *_mem_save_delta_enum_array_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -10496,7 +10571,13 @@ static enum ndr_err_code ndr_pull_netr_DatabaseSync2(struct ndr_pull *ndr, int f } NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.computername), sizeof(uint16_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.computername, ndr_get_array_length(ndr, &r->in.computername), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.credential); + } + _mem_save_credential_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.credential, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credential_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.return_authenticator); } @@ -10541,7 +10622,18 @@ static enum ndr_err_code ndr_pull_netr_DatabaseSync2(struct ndr_pull *ndr, int f } _mem_save_delta_enum_array_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.delta_enum_array, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.delta_enum_array)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_delta_enum_array)); + if (_ptr_delta_enum_array) { + NDR_PULL_ALLOC(ndr, *r->out.delta_enum_array); + } else { + *r->out.delta_enum_array = NULL; + } + if (*r->out.delta_enum_array) { + _mem_save_delta_enum_array_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.delta_enum_array, 0); + NDR_CHECK(ndr_pull_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.delta_enum_array)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_delta_enum_array_1, 0); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_delta_enum_array_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } @@ -10560,7 +10652,10 @@ _PUBLIC_ void ndr_print_netr_DatabaseSync2(struct ndr_print *ndr, const char *na ndr->depth++; ndr_print_string(ndr, "logon_server", r->in.logon_server); ndr_print_string(ndr, "computername", r->in.computername); - ndr_print_netr_Authenticator(ndr, "credential", &r->in.credential); + ndr_print_ptr(ndr, "credential", r->in.credential); + ndr->depth++; + ndr_print_netr_Authenticator(ndr, "credential", r->in.credential); + ndr->depth--; ndr_print_ptr(ndr, "return_authenticator", r->in.return_authenticator); ndr->depth++; ndr_print_netr_Authenticator(ndr, "return_authenticator", r->in.return_authenticator); @@ -10587,7 +10682,12 @@ _PUBLIC_ void ndr_print_netr_DatabaseSync2(struct ndr_print *ndr, const char *na ndr->depth--; ndr_print_ptr(ndr, "delta_enum_array", r->out.delta_enum_array); ndr->depth++; - ndr_print_netr_DELTA_ENUM_ARRAY(ndr, "delta_enum_array", r->out.delta_enum_array); + ndr_print_ptr(ndr, "delta_enum_array", *r->out.delta_enum_array); + ndr->depth++; + if (*r->out.delta_enum_array) { + ndr_print_netr_DELTA_ENUM_ARRAY(ndr, "delta_enum_array", *r->out.delta_enum_array); + } + ndr->depth--; ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; @@ -12588,8 +12688,7 @@ _PUBLIC_ void ndr_print_netr_DsRAddressToSitenamesW(struct ndr_print *ndr, const ndr->depth++; for (cntr_addresses_1=0;cntr_addresses_1<r->in.count;cntr_addresses_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_addresses_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_addresses_1) != -1) { ndr_print_netr_DsRAddress(ndr, "addresses", &r->in.addresses[cntr_addresses_1]); free(idx_1); } @@ -13132,8 +13231,7 @@ _PUBLIC_ void ndr_print_netr_DsRAddressToSitenamesExW(struct ndr_print *ndr, con ndr->depth++; for (cntr_addresses_1=0;cntr_addresses_1<r->in.count;cntr_addresses_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_addresses_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_addresses_1) != -1) { ndr_print_netr_DsRAddress(ndr, "addresses", &r->in.addresses[cntr_addresses_1]); free(idx_1); } @@ -13272,8 +13370,11 @@ static enum ndr_err_code ndr_push_netr_LogonSamLogonEx(struct ndr_push *ndr, int NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.computer_name, ndr_charset_length(r->in.computer_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); } NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.logon_level)); - NDR_CHECK(ndr_push_set_switch_value(ndr, &r->in.logon, r->in.logon_level)); - NDR_CHECK(ndr_push_netr_LogonLevel(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.logon)); + if (r->in.logon == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_set_switch_value(ndr, r->in.logon, r->in.logon_level)); + NDR_CHECK(ndr_push_netr_LogonLevel(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.logon)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->in.validation_level)); if (r->in.flags == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -13305,6 +13406,7 @@ static enum ndr_err_code ndr_pull_netr_LogonSamLogonEx(struct ndr_pull *ndr, int uint32_t _ptr_computer_name; TALLOC_CTX *_mem_save_server_name_0; TALLOC_CTX *_mem_save_computer_name_0; + TALLOC_CTX *_mem_save_logon_0; TALLOC_CTX *_mem_save_validation_0; TALLOC_CTX *_mem_save_authoritative_0; TALLOC_CTX *_mem_save_flags_0; @@ -13348,8 +13450,14 @@ static enum ndr_err_code ndr_pull_netr_LogonSamLogonEx(struct ndr_pull *ndr, int NDR_PULL_SET_MEM_CTX(ndr, _mem_save_computer_name_0, 0); } NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.logon_level)); - NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->in.logon, r->in.logon_level)); - NDR_CHECK(ndr_pull_netr_LogonLevel(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.logon)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.logon); + } + _mem_save_logon_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.logon, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_set_switch_value(ndr, r->in.logon, r->in.logon_level)); + NDR_CHECK(ndr_pull_netr_LogonLevel(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.logon)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_logon_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->in.validation_level)); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.flags); @@ -13416,8 +13524,11 @@ _PUBLIC_ void ndr_print_netr_LogonSamLogonEx(struct ndr_print *ndr, const char * } ndr->depth--; ndr_print_uint16(ndr, "logon_level", r->in.logon_level); - ndr_print_set_switch_value(ndr, &r->in.logon, r->in.logon_level); - ndr_print_netr_LogonLevel(ndr, "logon", &r->in.logon); + ndr_print_ptr(ndr, "logon", r->in.logon); + ndr->depth++; + ndr_print_set_switch_value(ndr, r->in.logon, r->in.logon_level); + ndr_print_netr_LogonLevel(ndr, "logon", r->in.logon); + ndr->depth--; ndr_print_uint16(ndr, "validation_level", r->in.validation_level); ndr_print_ptr(ndr, "flags", r->in.flags); ndr->depth++; diff --git a/source3/librpc/gen_ndr/ndr_notify.c b/source3/librpc/gen_ndr/ndr_notify.c index 8abfdfdf92..195d421408 100644 --- a/source3/librpc/gen_ndr/ndr_notify.c +++ b/source3/librpc/gen_ndr/ndr_notify.c @@ -120,8 +120,7 @@ _PUBLIC_ void ndr_print_notify_depth(struct ndr_print *ndr, const char *name, co ndr->depth++; for (cntr_entries_0=0;cntr_entries_0<r->num_entries;cntr_entries_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_entries_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_entries_0) != -1) { ndr_print_notify_entry(ndr, "entries", &r->entries[cntr_entries_0]); free(idx_0); } @@ -184,8 +183,7 @@ _PUBLIC_ void ndr_print_notify_array(struct ndr_print *ndr, const char *name, co ndr->depth++; for (cntr_depth_0=0;cntr_depth_0<r->num_depths;cntr_depth_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_depth_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_depth_0) != -1) { ndr_print_notify_depth(ndr, "depth", &r->depth[cntr_depth_0]); free(idx_0); } diff --git a/source3/librpc/gen_ndr/ndr_ntsvcs.c b/source3/librpc/gen_ndr/ndr_ntsvcs.c new file mode 100644 index 0000000000..9a0e2bcf4f --- /dev/null +++ b/source3/librpc/gen_ndr/ndr_ntsvcs.c @@ -0,0 +1,3616 @@ +/* parser auto-generated by pidl */ + +#include "includes.h" +#include "librpc/gen_ndr/ndr_ntsvcs.h" + +static enum ndr_err_code ndr_push_PNP_HwProfInfo(struct ndr_push *ndr, int ndr_flags, const struct PNP_HwProfInfo *r) +{ + uint32_t cntr_unknown2_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown1)); + for (cntr_unknown2_0 = 0; cntr_unknown2_0 < 160; cntr_unknown2_0++) { + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->unknown2[cntr_unknown2_0])); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->unknown3)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_HwProfInfo(struct ndr_pull *ndr, int ndr_flags, struct PNP_HwProfInfo *r) +{ + uint32_t cntr_unknown2_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown1)); + for (cntr_unknown2_0 = 0; cntr_unknown2_0 < 160; cntr_unknown2_0++) { + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->unknown2[cntr_unknown2_0])); + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->unknown3)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_HwProfInfo(struct ndr_print *ndr, const char *name, const struct PNP_HwProfInfo *r) +{ + uint32_t cntr_unknown2_0; + ndr_print_struct(ndr, name, "PNP_HwProfInfo"); + ndr->depth++; + ndr_print_uint32(ndr, "unknown1", r->unknown1); + ndr->print(ndr, "%s: ARRAY(%d)", "unknown2", 160); + ndr->depth++; + for (cntr_unknown2_0=0;cntr_unknown2_0<160;cntr_unknown2_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_unknown2_0) != -1) { + ndr_print_uint16(ndr, "unknown2", r->unknown2[cntr_unknown2_0]); + free(idx_0); + } + } + ndr->depth--; + ndr_print_uint32(ndr, "unknown3", r->unknown3); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_Disconnect(struct ndr_push *ndr, int flags, const struct PNP_Disconnect *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_Disconnect(struct ndr_pull *ndr, int flags, struct PNP_Disconnect *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_Disconnect(struct ndr_print *ndr, const char *name, int flags, const struct PNP_Disconnect *r) +{ + ndr_print_struct(ndr, name, "PNP_Disconnect"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_Disconnect"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_Disconnect"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_Connect(struct ndr_push *ndr, int flags, const struct PNP_Connect *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_Connect(struct ndr_pull *ndr, int flags, struct PNP_Connect *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_Connect(struct ndr_print *ndr, const char *name, int flags, const struct PNP_Connect *r) +{ + ndr_print_struct(ndr, name, "PNP_Connect"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_Connect"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_Connect"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetVersion(struct ndr_push *ndr, int flags, const struct PNP_GetVersion *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + if (r->out.version == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, *r->out.version)); + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetVersion(struct ndr_pull *ndr, int flags, struct PNP_GetVersion *r) +{ + TALLOC_CTX *_mem_save_version_0; + if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + NDR_PULL_ALLOC(ndr, r->out.version); + ZERO_STRUCTP(r->out.version); + } + if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.version); + } + _mem_save_version_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.version, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, r->out.version)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_version_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetVersion(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetVersion *r) +{ + ndr_print_struct(ndr, name, "PNP_GetVersion"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetVersion"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetVersion"); + ndr->depth++; + ndr_print_ptr(ndr, "version", r->out.version); + ndr->depth++; + ndr_print_uint16(ndr, "version", *r->out.version); + ndr->depth--; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetGlobalState(struct ndr_push *ndr, int flags, const struct PNP_GetGlobalState *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetGlobalState(struct ndr_pull *ndr, int flags, struct PNP_GetGlobalState *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetGlobalState(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetGlobalState *r) +{ + ndr_print_struct(ndr, name, "PNP_GetGlobalState"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetGlobalState"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetGlobalState"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_InitDetection(struct ndr_push *ndr, int flags, const struct PNP_InitDetection *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_InitDetection(struct ndr_pull *ndr, int flags, struct PNP_InitDetection *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_InitDetection(struct ndr_print *ndr, const char *name, int flags, const struct PNP_InitDetection *r) +{ + ndr_print_struct(ndr, name, "PNP_InitDetection"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_InitDetection"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_InitDetection"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_ReportLogOn(struct ndr_push *ndr, int flags, const struct PNP_ReportLogOn *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_ReportLogOn(struct ndr_pull *ndr, int flags, struct PNP_ReportLogOn *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_ReportLogOn(struct ndr_print *ndr, const char *name, int flags, const struct PNP_ReportLogOn *r) +{ + ndr_print_struct(ndr, name, "PNP_ReportLogOn"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_ReportLogOn"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_ReportLogOn"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_ValidateDeviceInstance(struct ndr_push *ndr, int flags, const struct PNP_ValidateDeviceInstance *r) +{ + if (flags & NDR_IN) { + if (r->in.devicepath == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.devicepath, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.devicepath, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.devicepath, ndr_charset_length(r->in.devicepath, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.flags)); + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_ValidateDeviceInstance(struct ndr_pull *ndr, int flags, struct PNP_ValidateDeviceInstance *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.devicepath)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->in.devicepath)); + if (ndr_get_array_length(ndr, &r->in.devicepath) > ndr_get_array_size(ndr, &r->in.devicepath)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.devicepath), ndr_get_array_length(ndr, &r->in.devicepath)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.devicepath), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.devicepath, ndr_get_array_length(ndr, &r->in.devicepath), sizeof(uint16_t), CH_UTF16)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.flags)); + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_ValidateDeviceInstance(struct ndr_print *ndr, const char *name, int flags, const struct PNP_ValidateDeviceInstance *r) +{ + ndr_print_struct(ndr, name, "PNP_ValidateDeviceInstance"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_ValidateDeviceInstance"); + ndr->depth++; + ndr_print_ptr(ndr, "devicepath", r->in.devicepath); + ndr->depth++; + ndr_print_string(ndr, "devicepath", r->in.devicepath); + ndr->depth--; + ndr_print_uint32(ndr, "flags", r->in.flags); + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_ValidateDeviceInstance"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetRootDeviceInstance(struct ndr_push *ndr, int flags, const struct PNP_GetRootDeviceInstance *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetRootDeviceInstance(struct ndr_pull *ndr, int flags, struct PNP_GetRootDeviceInstance *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetRootDeviceInstance(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetRootDeviceInstance *r) +{ + ndr_print_struct(ndr, name, "PNP_GetRootDeviceInstance"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetRootDeviceInstance"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetRootDeviceInstance"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetRelatedDeviceInstance(struct ndr_push *ndr, int flags, const struct PNP_GetRelatedDeviceInstance *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetRelatedDeviceInstance(struct ndr_pull *ndr, int flags, struct PNP_GetRelatedDeviceInstance *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetRelatedDeviceInstance(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetRelatedDeviceInstance *r) +{ + ndr_print_struct(ndr, name, "PNP_GetRelatedDeviceInstance"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetRelatedDeviceInstance"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetRelatedDeviceInstance"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_EnumerateSubKeys(struct ndr_push *ndr, int flags, const struct PNP_EnumerateSubKeys *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_EnumerateSubKeys(struct ndr_pull *ndr, int flags, struct PNP_EnumerateSubKeys *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_EnumerateSubKeys(struct ndr_print *ndr, const char *name, int flags, const struct PNP_EnumerateSubKeys *r) +{ + ndr_print_struct(ndr, name, "PNP_EnumerateSubKeys"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_EnumerateSubKeys"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_EnumerateSubKeys"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetDeviceList(struct ndr_push *ndr, int flags, const struct PNP_GetDeviceList *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetDeviceList(struct ndr_pull *ndr, int flags, struct PNP_GetDeviceList *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetDeviceList(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDeviceList *r) +{ + ndr_print_struct(ndr, name, "PNP_GetDeviceList"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetDeviceList"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetDeviceList"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetDeviceListSize(struct ndr_push *ndr, int flags, const struct PNP_GetDeviceListSize *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.devicename)); + if (r->in.devicename) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.devicename, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.devicename, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.devicename, ndr_charset_length(r->in.devicename, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.flags)); + } + if (flags & NDR_OUT) { + if (r->out.size == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.size)); + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetDeviceListSize(struct ndr_pull *ndr, int flags, struct PNP_GetDeviceListSize *r) +{ + uint32_t _ptr_devicename; + TALLOC_CTX *_mem_save_devicename_0; + TALLOC_CTX *_mem_save_size_0; + if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_devicename)); + if (_ptr_devicename) { + NDR_PULL_ALLOC(ndr, r->in.devicename); + } else { + r->in.devicename = NULL; + } + if (r->in.devicename) { + _mem_save_devicename_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.devicename, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.devicename)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->in.devicename)); + if (ndr_get_array_length(ndr, &r->in.devicename) > ndr_get_array_size(ndr, &r->in.devicename)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.devicename), ndr_get_array_length(ndr, &r->in.devicename)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.devicename), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.devicename, ndr_get_array_length(ndr, &r->in.devicename), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_devicename_0, 0); + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.flags)); + NDR_PULL_ALLOC(ndr, r->out.size); + ZERO_STRUCTP(r->out.size); + } + if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.size); + } + _mem_save_size_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.size, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.size)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_size_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetDeviceListSize(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDeviceListSize *r) +{ + ndr_print_struct(ndr, name, "PNP_GetDeviceListSize"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetDeviceListSize"); + ndr->depth++; + ndr_print_ptr(ndr, "devicename", r->in.devicename); + ndr->depth++; + if (r->in.devicename) { + ndr_print_string(ndr, "devicename", r->in.devicename); + } + ndr->depth--; + ndr_print_uint32(ndr, "flags", r->in.flags); + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetDeviceListSize"); + ndr->depth++; + ndr_print_ptr(ndr, "size", r->out.size); + ndr->depth++; + ndr_print_uint32(ndr, "size", *r->out.size); + ndr->depth--; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetDepth(struct ndr_push *ndr, int flags, const struct PNP_GetDepth *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetDepth(struct ndr_pull *ndr, int flags, struct PNP_GetDepth *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetDepth(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDepth *r) +{ + ndr_print_struct(ndr, name, "PNP_GetDepth"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetDepth"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetDepth"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetDeviceRegProp(struct ndr_push *ndr, int flags, const struct PNP_GetDeviceRegProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetDeviceRegProp(struct ndr_pull *ndr, int flags, struct PNP_GetDeviceRegProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetDeviceRegProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDeviceRegProp *r) +{ + ndr_print_struct(ndr, name, "PNP_GetDeviceRegProp"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetDeviceRegProp"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetDeviceRegProp"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_SetDeviceRegProp(struct ndr_push *ndr, int flags, const struct PNP_SetDeviceRegProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_SetDeviceRegProp(struct ndr_pull *ndr, int flags, struct PNP_SetDeviceRegProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_SetDeviceRegProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_SetDeviceRegProp *r) +{ + ndr_print_struct(ndr, name, "PNP_SetDeviceRegProp"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_SetDeviceRegProp"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_SetDeviceRegProp"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetClassInstance(struct ndr_push *ndr, int flags, const struct PNP_GetClassInstance *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetClassInstance(struct ndr_pull *ndr, int flags, struct PNP_GetClassInstance *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetClassInstance(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetClassInstance *r) +{ + ndr_print_struct(ndr, name, "PNP_GetClassInstance"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetClassInstance"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetClassInstance"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_CreateKey(struct ndr_push *ndr, int flags, const struct PNP_CreateKey *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_CreateKey(struct ndr_pull *ndr, int flags, struct PNP_CreateKey *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_CreateKey(struct ndr_print *ndr, const char *name, int flags, const struct PNP_CreateKey *r) +{ + ndr_print_struct(ndr, name, "PNP_CreateKey"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_CreateKey"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_CreateKey"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_DeleteRegistryKey(struct ndr_push *ndr, int flags, const struct PNP_DeleteRegistryKey *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_DeleteRegistryKey(struct ndr_pull *ndr, int flags, struct PNP_DeleteRegistryKey *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_DeleteRegistryKey(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DeleteRegistryKey *r) +{ + ndr_print_struct(ndr, name, "PNP_DeleteRegistryKey"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_DeleteRegistryKey"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_DeleteRegistryKey"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetClassCount(struct ndr_push *ndr, int flags, const struct PNP_GetClassCount *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetClassCount(struct ndr_pull *ndr, int flags, struct PNP_GetClassCount *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetClassCount(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetClassCount *r) +{ + ndr_print_struct(ndr, name, "PNP_GetClassCount"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetClassCount"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetClassCount"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetClassName(struct ndr_push *ndr, int flags, const struct PNP_GetClassName *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetClassName(struct ndr_pull *ndr, int flags, struct PNP_GetClassName *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetClassName(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetClassName *r) +{ + ndr_print_struct(ndr, name, "PNP_GetClassName"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetClassName"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetClassName"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_DeleteClassKey(struct ndr_push *ndr, int flags, const struct PNP_DeleteClassKey *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_DeleteClassKey(struct ndr_pull *ndr, int flags, struct PNP_DeleteClassKey *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_DeleteClassKey(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DeleteClassKey *r) +{ + ndr_print_struct(ndr, name, "PNP_DeleteClassKey"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_DeleteClassKey"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_DeleteClassKey"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetInterfaceDeviceAlias(struct ndr_push *ndr, int flags, const struct PNP_GetInterfaceDeviceAlias *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetInterfaceDeviceAlias(struct ndr_pull *ndr, int flags, struct PNP_GetInterfaceDeviceAlias *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetInterfaceDeviceAlias(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetInterfaceDeviceAlias *r) +{ + ndr_print_struct(ndr, name, "PNP_GetInterfaceDeviceAlias"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetInterfaceDeviceAlias"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetInterfaceDeviceAlias"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetInterfaceDeviceList(struct ndr_push *ndr, int flags, const struct PNP_GetInterfaceDeviceList *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetInterfaceDeviceList(struct ndr_pull *ndr, int flags, struct PNP_GetInterfaceDeviceList *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetInterfaceDeviceList(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetInterfaceDeviceList *r) +{ + ndr_print_struct(ndr, name, "PNP_GetInterfaceDeviceList"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetInterfaceDeviceList"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetInterfaceDeviceList"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetInterfaceDeviceListSize(struct ndr_push *ndr, int flags, const struct PNP_GetInterfaceDeviceListSize *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetInterfaceDeviceListSize(struct ndr_pull *ndr, int flags, struct PNP_GetInterfaceDeviceListSize *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetInterfaceDeviceListSize(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetInterfaceDeviceListSize *r) +{ + ndr_print_struct(ndr, name, "PNP_GetInterfaceDeviceListSize"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetInterfaceDeviceListSize"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetInterfaceDeviceListSize"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_RegisterDeviceClassAssociation(struct ndr_push *ndr, int flags, const struct PNP_RegisterDeviceClassAssociation *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_RegisterDeviceClassAssociation(struct ndr_pull *ndr, int flags, struct PNP_RegisterDeviceClassAssociation *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_RegisterDeviceClassAssociation(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RegisterDeviceClassAssociation *r) +{ + ndr_print_struct(ndr, name, "PNP_RegisterDeviceClassAssociation"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_RegisterDeviceClassAssociation"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_RegisterDeviceClassAssociation"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_UnregisterDeviceClassAssociation(struct ndr_push *ndr, int flags, const struct PNP_UnregisterDeviceClassAssociation *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_UnregisterDeviceClassAssociation(struct ndr_pull *ndr, int flags, struct PNP_UnregisterDeviceClassAssociation *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_UnregisterDeviceClassAssociation(struct ndr_print *ndr, const char *name, int flags, const struct PNP_UnregisterDeviceClassAssociation *r) +{ + ndr_print_struct(ndr, name, "PNP_UnregisterDeviceClassAssociation"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_UnregisterDeviceClassAssociation"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_UnregisterDeviceClassAssociation"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetClassRegProp(struct ndr_push *ndr, int flags, const struct PNP_GetClassRegProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetClassRegProp(struct ndr_pull *ndr, int flags, struct PNP_GetClassRegProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetClassRegProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetClassRegProp *r) +{ + ndr_print_struct(ndr, name, "PNP_GetClassRegProp"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetClassRegProp"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetClassRegProp"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_SetClassRegProp(struct ndr_push *ndr, int flags, const struct PNP_SetClassRegProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_SetClassRegProp(struct ndr_pull *ndr, int flags, struct PNP_SetClassRegProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_SetClassRegProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_SetClassRegProp *r) +{ + ndr_print_struct(ndr, name, "PNP_SetClassRegProp"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_SetClassRegProp"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_SetClassRegProp"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_CreateDevInst(struct ndr_push *ndr, int flags, const struct PNP_CreateDevInst *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_CreateDevInst(struct ndr_pull *ndr, int flags, struct PNP_CreateDevInst *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_CreateDevInst(struct ndr_print *ndr, const char *name, int flags, const struct PNP_CreateDevInst *r) +{ + ndr_print_struct(ndr, name, "PNP_CreateDevInst"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_CreateDevInst"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_CreateDevInst"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_DeviceInstanceAction(struct ndr_push *ndr, int flags, const struct PNP_DeviceInstanceAction *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_DeviceInstanceAction(struct ndr_pull *ndr, int flags, struct PNP_DeviceInstanceAction *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_DeviceInstanceAction(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DeviceInstanceAction *r) +{ + ndr_print_struct(ndr, name, "PNP_DeviceInstanceAction"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_DeviceInstanceAction"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_DeviceInstanceAction"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetDeviceStatus(struct ndr_push *ndr, int flags, const struct PNP_GetDeviceStatus *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetDeviceStatus(struct ndr_pull *ndr, int flags, struct PNP_GetDeviceStatus *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetDeviceStatus(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDeviceStatus *r) +{ + ndr_print_struct(ndr, name, "PNP_GetDeviceStatus"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetDeviceStatus"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetDeviceStatus"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_SetDeviceProblem(struct ndr_push *ndr, int flags, const struct PNP_SetDeviceProblem *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_SetDeviceProblem(struct ndr_pull *ndr, int flags, struct PNP_SetDeviceProblem *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_SetDeviceProblem(struct ndr_print *ndr, const char *name, int flags, const struct PNP_SetDeviceProblem *r) +{ + ndr_print_struct(ndr, name, "PNP_SetDeviceProblem"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_SetDeviceProblem"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_SetDeviceProblem"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_DisableDevInst(struct ndr_push *ndr, int flags, const struct PNP_DisableDevInst *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_DisableDevInst(struct ndr_pull *ndr, int flags, struct PNP_DisableDevInst *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_DisableDevInst(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DisableDevInst *r) +{ + ndr_print_struct(ndr, name, "PNP_DisableDevInst"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_DisableDevInst"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_DisableDevInst"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_UninstallDevInst(struct ndr_push *ndr, int flags, const struct PNP_UninstallDevInst *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_UninstallDevInst(struct ndr_pull *ndr, int flags, struct PNP_UninstallDevInst *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_UninstallDevInst(struct ndr_print *ndr, const char *name, int flags, const struct PNP_UninstallDevInst *r) +{ + ndr_print_struct(ndr, name, "PNP_UninstallDevInst"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_UninstallDevInst"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_UninstallDevInst"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_AddID(struct ndr_push *ndr, int flags, const struct PNP_AddID *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_AddID(struct ndr_pull *ndr, int flags, struct PNP_AddID *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_AddID(struct ndr_print *ndr, const char *name, int flags, const struct PNP_AddID *r) +{ + ndr_print_struct(ndr, name, "PNP_AddID"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_AddID"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_AddID"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_RegisterDriver(struct ndr_push *ndr, int flags, const struct PNP_RegisterDriver *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_RegisterDriver(struct ndr_pull *ndr, int flags, struct PNP_RegisterDriver *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_RegisterDriver(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RegisterDriver *r) +{ + ndr_print_struct(ndr, name, "PNP_RegisterDriver"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_RegisterDriver"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_RegisterDriver"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_QueryRemove(struct ndr_push *ndr, int flags, const struct PNP_QueryRemove *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_QueryRemove(struct ndr_pull *ndr, int flags, struct PNP_QueryRemove *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_QueryRemove(struct ndr_print *ndr, const char *name, int flags, const struct PNP_QueryRemove *r) +{ + ndr_print_struct(ndr, name, "PNP_QueryRemove"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_QueryRemove"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_QueryRemove"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_RequestDeviceEject(struct ndr_push *ndr, int flags, const struct PNP_RequestDeviceEject *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_RequestDeviceEject(struct ndr_pull *ndr, int flags, struct PNP_RequestDeviceEject *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_RequestDeviceEject(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RequestDeviceEject *r) +{ + ndr_print_struct(ndr, name, "PNP_RequestDeviceEject"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_RequestDeviceEject"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_RequestDeviceEject"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_IsDockStationPresent(struct ndr_push *ndr, int flags, const struct PNP_IsDockStationPresent *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_IsDockStationPresent(struct ndr_pull *ndr, int flags, struct PNP_IsDockStationPresent *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_IsDockStationPresent(struct ndr_print *ndr, const char *name, int flags, const struct PNP_IsDockStationPresent *r) +{ + ndr_print_struct(ndr, name, "PNP_IsDockStationPresent"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_IsDockStationPresent"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_IsDockStationPresent"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_RequestEjectPC(struct ndr_push *ndr, int flags, const struct PNP_RequestEjectPC *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_RequestEjectPC(struct ndr_pull *ndr, int flags, struct PNP_RequestEjectPC *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_RequestEjectPC(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RequestEjectPC *r) +{ + ndr_print_struct(ndr, name, "PNP_RequestEjectPC"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_RequestEjectPC"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_RequestEjectPC"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_HwProfFlags(struct ndr_push *ndr, int flags, const struct PNP_HwProfFlags *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown1)); + if (r->in.devicepath == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.devicepath, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.devicepath, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.devicepath, ndr_charset_length(r->in.devicepath, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2)); + if (r->in.unknown3 == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.unknown3)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.unknown4)); + if (r->in.unknown4) { + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, *r->in.unknown4)); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.unknown5)); + if (r->in.unknown5) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.unknown5, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.unknown5, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.unknown5, ndr_charset_length(r->in.unknown5, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown6)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown7)); + } + if (flags & NDR_OUT) { + if (r->out.unknown3 == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.unknown3)); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.unknown4)); + if (r->out.unknown4) { + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, *r->out.unknown4)); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.unknown5a)); + if (r->out.unknown5a) { + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.unknown5a)); + if (*r->out.unknown5a) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.unknown5a, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.unknown5a, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, *r->out.unknown5a, ndr_charset_length(*r->out.unknown5a, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } + } + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_HwProfFlags(struct ndr_pull *ndr, int flags, struct PNP_HwProfFlags *r) +{ + uint32_t _ptr_unknown4; + uint32_t _ptr_unknown5; + uint32_t _ptr_unknown5a; + TALLOC_CTX *_mem_save_unknown3_0; + TALLOC_CTX *_mem_save_unknown4_0; + TALLOC_CTX *_mem_save_unknown5_0; + TALLOC_CTX *_mem_save_unknown5a_0; + TALLOC_CTX *_mem_save_unknown5a_1; + if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown1)); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.devicepath)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->in.devicepath)); + if (ndr_get_array_length(ndr, &r->in.devicepath) > ndr_get_array_size(ndr, &r->in.devicepath)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.devicepath), ndr_get_array_length(ndr, &r->in.devicepath)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.devicepath), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.devicepath, ndr_get_array_length(ndr, &r->in.devicepath), sizeof(uint16_t), CH_UTF16)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.unknown3); + } + _mem_save_unknown3_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.unknown3, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.unknown3)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown3_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown4)); + if (_ptr_unknown4) { + NDR_PULL_ALLOC(ndr, r->in.unknown4); + } else { + r->in.unknown4 = NULL; + } + if (r->in.unknown4) { + _mem_save_unknown4_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.unknown4, 0); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, r->in.unknown4)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown4_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown5)); + if (_ptr_unknown5) { + NDR_PULL_ALLOC(ndr, r->in.unknown5); + } else { + r->in.unknown5 = NULL; + } + if (r->in.unknown5) { + _mem_save_unknown5_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.unknown5, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.unknown5)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->in.unknown5)); + if (ndr_get_array_length(ndr, &r->in.unknown5) > ndr_get_array_size(ndr, &r->in.unknown5)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.unknown5), ndr_get_array_length(ndr, &r->in.unknown5)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.unknown5), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.unknown5, ndr_get_array_length(ndr, &r->in.unknown5), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown5_0, 0); + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown6)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown7)); + NDR_PULL_ALLOC(ndr, r->out.unknown3); + *r->out.unknown3 = *r->in.unknown3; + } + if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.unknown3); + } + _mem_save_unknown3_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.unknown3, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.unknown3)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown3_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown4)); + if (_ptr_unknown4) { + NDR_PULL_ALLOC(ndr, r->out.unknown4); + } else { + r->out.unknown4 = NULL; + } + if (r->out.unknown4) { + _mem_save_unknown4_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.unknown4, 0); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, r->out.unknown4)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown4_0, 0); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown5a)); + if (_ptr_unknown5a) { + NDR_PULL_ALLOC(ndr, r->out.unknown5a); + } else { + r->out.unknown5a = NULL; + } + if (r->out.unknown5a) { + _mem_save_unknown5a_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.unknown5a, 0); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_unknown5a)); + if (_ptr_unknown5a) { + NDR_PULL_ALLOC(ndr, *r->out.unknown5a); + } else { + *r->out.unknown5a = NULL; + } + if (*r->out.unknown5a) { + _mem_save_unknown5a_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.unknown5a, 0); + NDR_CHECK(ndr_pull_array_size(ndr, r->out.unknown5a)); + NDR_CHECK(ndr_pull_array_length(ndr, r->out.unknown5a)); + if (ndr_get_array_length(ndr, r->out.unknown5a) > ndr_get_array_size(ndr, r->out.unknown5a)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, r->out.unknown5a), ndr_get_array_length(ndr, r->out.unknown5a)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, r->out.unknown5a), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, r->out.unknown5a, ndr_get_array_length(ndr, r->out.unknown5a), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown5a_1, 0); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_unknown5a_0, 0); + } + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_HwProfFlags(struct ndr_print *ndr, const char *name, int flags, const struct PNP_HwProfFlags *r) +{ + ndr_print_struct(ndr, name, "PNP_HwProfFlags"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_HwProfFlags"); + ndr->depth++; + ndr_print_uint32(ndr, "unknown1", r->in.unknown1); + ndr_print_ptr(ndr, "devicepath", r->in.devicepath); + ndr->depth++; + ndr_print_string(ndr, "devicepath", r->in.devicepath); + ndr->depth--; + ndr_print_uint32(ndr, "unknown2", r->in.unknown2); + ndr_print_ptr(ndr, "unknown3", r->in.unknown3); + ndr->depth++; + ndr_print_uint32(ndr, "unknown3", *r->in.unknown3); + ndr->depth--; + ndr_print_ptr(ndr, "unknown4", r->in.unknown4); + ndr->depth++; + if (r->in.unknown4) { + ndr_print_uint16(ndr, "unknown4", *r->in.unknown4); + } + ndr->depth--; + ndr_print_ptr(ndr, "unknown5", r->in.unknown5); + ndr->depth++; + if (r->in.unknown5) { + ndr_print_string(ndr, "unknown5", r->in.unknown5); + } + ndr->depth--; + ndr_print_uint32(ndr, "unknown6", r->in.unknown6); + ndr_print_uint32(ndr, "unknown7", r->in.unknown7); + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_HwProfFlags"); + ndr->depth++; + ndr_print_ptr(ndr, "unknown3", r->out.unknown3); + ndr->depth++; + ndr_print_uint32(ndr, "unknown3", *r->out.unknown3); + ndr->depth--; + ndr_print_ptr(ndr, "unknown4", r->out.unknown4); + ndr->depth++; + if (r->out.unknown4) { + ndr_print_uint16(ndr, "unknown4", *r->out.unknown4); + } + ndr->depth--; + ndr_print_ptr(ndr, "unknown5a", r->out.unknown5a); + ndr->depth++; + if (r->out.unknown5a) { + ndr_print_ptr(ndr, "unknown5a", *r->out.unknown5a); + ndr->depth++; + if (*r->out.unknown5a) { + ndr_print_string(ndr, "unknown5a", *r->out.unknown5a); + } + ndr->depth--; + } + ndr->depth--; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetHwProfInfo(struct ndr_push *ndr, int flags, const struct PNP_GetHwProfInfo *r) +{ + if (flags & NDR_IN) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.idx)); + if (r->in.info == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_PNP_HwProfInfo(ndr, NDR_SCALARS, r->in.info)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown1)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.unknown2)); + } + if (flags & NDR_OUT) { + if (r->out.info == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_PNP_HwProfInfo(ndr, NDR_SCALARS, r->out.info)); + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetHwProfInfo(struct ndr_pull *ndr, int flags, struct PNP_GetHwProfInfo *r) +{ + TALLOC_CTX *_mem_save_info_0; + if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.idx)); + 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_PNP_HwProfInfo(ndr, NDR_SCALARS, r->in.info)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown1)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.unknown2)); + NDR_PULL_ALLOC(ndr, r->out.info); + *r->out.info = *r->in.info; + } + if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.info); + } + _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.info, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_PNP_HwProfInfo(ndr, NDR_SCALARS, r->out.info)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetHwProfInfo(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetHwProfInfo *r) +{ + ndr_print_struct(ndr, name, "PNP_GetHwProfInfo"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetHwProfInfo"); + ndr->depth++; + ndr_print_uint32(ndr, "idx", r->in.idx); + ndr_print_ptr(ndr, "info", r->in.info); + ndr->depth++; + ndr_print_PNP_HwProfInfo(ndr, "info", r->in.info); + ndr->depth--; + ndr_print_uint32(ndr, "unknown1", r->in.unknown1); + ndr_print_uint32(ndr, "unknown2", r->in.unknown2); + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetHwProfInfo"); + ndr->depth++; + ndr_print_ptr(ndr, "info", r->out.info); + ndr->depth++; + ndr_print_PNP_HwProfInfo(ndr, "info", r->out.info); + ndr->depth--; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_AddEmptyLogConf(struct ndr_push *ndr, int flags, const struct PNP_AddEmptyLogConf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_AddEmptyLogConf(struct ndr_pull *ndr, int flags, struct PNP_AddEmptyLogConf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_AddEmptyLogConf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_AddEmptyLogConf *r) +{ + ndr_print_struct(ndr, name, "PNP_AddEmptyLogConf"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_AddEmptyLogConf"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_AddEmptyLogConf"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_FreeLogConf(struct ndr_push *ndr, int flags, const struct PNP_FreeLogConf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_FreeLogConf(struct ndr_pull *ndr, int flags, struct PNP_FreeLogConf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_FreeLogConf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_FreeLogConf *r) +{ + ndr_print_struct(ndr, name, "PNP_FreeLogConf"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_FreeLogConf"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_FreeLogConf"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetFirstLogConf(struct ndr_push *ndr, int flags, const struct PNP_GetFirstLogConf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetFirstLogConf(struct ndr_pull *ndr, int flags, struct PNP_GetFirstLogConf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetFirstLogConf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetFirstLogConf *r) +{ + ndr_print_struct(ndr, name, "PNP_GetFirstLogConf"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetFirstLogConf"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetFirstLogConf"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetNextLogConf(struct ndr_push *ndr, int flags, const struct PNP_GetNextLogConf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetNextLogConf(struct ndr_pull *ndr, int flags, struct PNP_GetNextLogConf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetNextLogConf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetNextLogConf *r) +{ + ndr_print_struct(ndr, name, "PNP_GetNextLogConf"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetNextLogConf"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetNextLogConf"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetLogConfPriority(struct ndr_push *ndr, int flags, const struct PNP_GetLogConfPriority *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetLogConfPriority(struct ndr_pull *ndr, int flags, struct PNP_GetLogConfPriority *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetLogConfPriority(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetLogConfPriority *r) +{ + ndr_print_struct(ndr, name, "PNP_GetLogConfPriority"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetLogConfPriority"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetLogConfPriority"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_AddResDes(struct ndr_push *ndr, int flags, const struct PNP_AddResDes *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_AddResDes(struct ndr_pull *ndr, int flags, struct PNP_AddResDes *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_AddResDes(struct ndr_print *ndr, const char *name, int flags, const struct PNP_AddResDes *r) +{ + ndr_print_struct(ndr, name, "PNP_AddResDes"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_AddResDes"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_AddResDes"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_FreeResDes(struct ndr_push *ndr, int flags, const struct PNP_FreeResDes *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_FreeResDes(struct ndr_pull *ndr, int flags, struct PNP_FreeResDes *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_FreeResDes(struct ndr_print *ndr, const char *name, int flags, const struct PNP_FreeResDes *r) +{ + ndr_print_struct(ndr, name, "PNP_FreeResDes"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_FreeResDes"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_FreeResDes"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetNextResDes(struct ndr_push *ndr, int flags, const struct PNP_GetNextResDes *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetNextResDes(struct ndr_pull *ndr, int flags, struct PNP_GetNextResDes *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetNextResDes(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetNextResDes *r) +{ + ndr_print_struct(ndr, name, "PNP_GetNextResDes"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetNextResDes"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetNextResDes"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetResDesData(struct ndr_push *ndr, int flags, const struct PNP_GetResDesData *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetResDesData(struct ndr_pull *ndr, int flags, struct PNP_GetResDesData *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetResDesData(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetResDesData *r) +{ + ndr_print_struct(ndr, name, "PNP_GetResDesData"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetResDesData"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetResDesData"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetResDesDataSize(struct ndr_push *ndr, int flags, const struct PNP_GetResDesDataSize *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetResDesDataSize(struct ndr_pull *ndr, int flags, struct PNP_GetResDesDataSize *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetResDesDataSize(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetResDesDataSize *r) +{ + ndr_print_struct(ndr, name, "PNP_GetResDesDataSize"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetResDesDataSize"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetResDesDataSize"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_ModifyResDes(struct ndr_push *ndr, int flags, const struct PNP_ModifyResDes *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_ModifyResDes(struct ndr_pull *ndr, int flags, struct PNP_ModifyResDes *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_ModifyResDes(struct ndr_print *ndr, const char *name, int flags, const struct PNP_ModifyResDes *r) +{ + ndr_print_struct(ndr, name, "PNP_ModifyResDes"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_ModifyResDes"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_ModifyResDes"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_DetectResourceLimit(struct ndr_push *ndr, int flags, const struct PNP_DetectResourceLimit *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_DetectResourceLimit(struct ndr_pull *ndr, int flags, struct PNP_DetectResourceLimit *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_DetectResourceLimit(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DetectResourceLimit *r) +{ + ndr_print_struct(ndr, name, "PNP_DetectResourceLimit"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_DetectResourceLimit"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_DetectResourceLimit"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_QueryResConfList(struct ndr_push *ndr, int flags, const struct PNP_QueryResConfList *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_QueryResConfList(struct ndr_pull *ndr, int flags, struct PNP_QueryResConfList *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_QueryResConfList(struct ndr_print *ndr, const char *name, int flags, const struct PNP_QueryResConfList *r) +{ + ndr_print_struct(ndr, name, "PNP_QueryResConfList"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_QueryResConfList"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_QueryResConfList"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_SetHwProf(struct ndr_push *ndr, int flags, const struct PNP_SetHwProf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_SetHwProf(struct ndr_pull *ndr, int flags, struct PNP_SetHwProf *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_SetHwProf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_SetHwProf *r) +{ + ndr_print_struct(ndr, name, "PNP_SetHwProf"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_SetHwProf"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_SetHwProf"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_QueryArbitratorFreeData(struct ndr_push *ndr, int flags, const struct PNP_QueryArbitratorFreeData *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_QueryArbitratorFreeData(struct ndr_pull *ndr, int flags, struct PNP_QueryArbitratorFreeData *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_QueryArbitratorFreeData(struct ndr_print *ndr, const char *name, int flags, const struct PNP_QueryArbitratorFreeData *r) +{ + ndr_print_struct(ndr, name, "PNP_QueryArbitratorFreeData"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_QueryArbitratorFreeData"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_QueryArbitratorFreeData"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_QueryArbitratorFreeSize(struct ndr_push *ndr, int flags, const struct PNP_QueryArbitratorFreeSize *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_QueryArbitratorFreeSize(struct ndr_pull *ndr, int flags, struct PNP_QueryArbitratorFreeSize *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_QueryArbitratorFreeSize(struct ndr_print *ndr, const char *name, int flags, const struct PNP_QueryArbitratorFreeSize *r) +{ + ndr_print_struct(ndr, name, "PNP_QueryArbitratorFreeSize"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_QueryArbitratorFreeSize"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_QueryArbitratorFreeSize"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_RunDetection(struct ndr_push *ndr, int flags, const struct PNP_RunDetection *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_RunDetection(struct ndr_pull *ndr, int flags, struct PNP_RunDetection *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_RunDetection(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RunDetection *r) +{ + ndr_print_struct(ndr, name, "PNP_RunDetection"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_RunDetection"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_RunDetection"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_RegisterNotification(struct ndr_push *ndr, int flags, const struct PNP_RegisterNotification *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_RegisterNotification(struct ndr_pull *ndr, int flags, struct PNP_RegisterNotification *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_RegisterNotification(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RegisterNotification *r) +{ + ndr_print_struct(ndr, name, "PNP_RegisterNotification"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_RegisterNotification"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_RegisterNotification"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_UnregisterNotification(struct ndr_push *ndr, int flags, const struct PNP_UnregisterNotification *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_UnregisterNotification(struct ndr_pull *ndr, int flags, struct PNP_UnregisterNotification *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_UnregisterNotification(struct ndr_print *ndr, const char *name, int flags, const struct PNP_UnregisterNotification *r) +{ + ndr_print_struct(ndr, name, "PNP_UnregisterNotification"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_UnregisterNotification"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_UnregisterNotification"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetCustomDevProp(struct ndr_push *ndr, int flags, const struct PNP_GetCustomDevProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetCustomDevProp(struct ndr_pull *ndr, int flags, struct PNP_GetCustomDevProp *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetCustomDevProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetCustomDevProp *r) +{ + ndr_print_struct(ndr, name, "PNP_GetCustomDevProp"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetCustomDevProp"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetCustomDevProp"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetVersionInternal(struct ndr_push *ndr, int flags, const struct PNP_GetVersionInternal *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetVersionInternal(struct ndr_pull *ndr, int flags, struct PNP_GetVersionInternal *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetVersionInternal(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetVersionInternal *r) +{ + ndr_print_struct(ndr, name, "PNP_GetVersionInternal"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetVersionInternal"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetVersionInternal"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetBlockedDriverInfo(struct ndr_push *ndr, int flags, const struct PNP_GetBlockedDriverInfo *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetBlockedDriverInfo(struct ndr_pull *ndr, int flags, struct PNP_GetBlockedDriverInfo *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetBlockedDriverInfo(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetBlockedDriverInfo *r) +{ + ndr_print_struct(ndr, name, "PNP_GetBlockedDriverInfo"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetBlockedDriverInfo"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetBlockedDriverInfo"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static enum ndr_err_code ndr_push_PNP_GetServerSideDeviceInstallFlags(struct ndr_push *ndr, int flags, const struct PNP_GetServerSideDeviceInstallFlags *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_PNP_GetServerSideDeviceInstallFlags(struct ndr_pull *ndr, int flags, struct PNP_GetServerSideDeviceInstallFlags *r) +{ + if (flags & NDR_IN) { + } + if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_PNP_GetServerSideDeviceInstallFlags(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetServerSideDeviceInstallFlags *r) +{ + ndr_print_struct(ndr, name, "PNP_GetServerSideDeviceInstallFlags"); + ndr->depth++; + if (flags & NDR_SET_VALUES) { + ndr->flags |= LIBNDR_PRINT_SET_VALUES; + } + if (flags & NDR_IN) { + ndr_print_struct(ndr, "in", "PNP_GetServerSideDeviceInstallFlags"); + ndr->depth++; + ndr->depth--; + } + if (flags & NDR_OUT) { + ndr_print_struct(ndr, "out", "PNP_GetServerSideDeviceInstallFlags"); + ndr->depth++; + ndr_print_WERROR(ndr, "result", r->out.result); + ndr->depth--; + } + ndr->depth--; +} + +static const struct ndr_interface_call ntsvcs_calls[] = { + { + "PNP_Disconnect", + sizeof(struct PNP_Disconnect), + (ndr_push_flags_fn_t) ndr_push_PNP_Disconnect, + (ndr_pull_flags_fn_t) ndr_pull_PNP_Disconnect, + (ndr_print_function_t) ndr_print_PNP_Disconnect, + false, + }, + { + "PNP_Connect", + sizeof(struct PNP_Connect), + (ndr_push_flags_fn_t) ndr_push_PNP_Connect, + (ndr_pull_flags_fn_t) ndr_pull_PNP_Connect, + (ndr_print_function_t) ndr_print_PNP_Connect, + false, + }, + { + "PNP_GetVersion", + sizeof(struct PNP_GetVersion), + (ndr_push_flags_fn_t) ndr_push_PNP_GetVersion, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetVersion, + (ndr_print_function_t) ndr_print_PNP_GetVersion, + false, + }, + { + "PNP_GetGlobalState", + sizeof(struct PNP_GetGlobalState), + (ndr_push_flags_fn_t) ndr_push_PNP_GetGlobalState, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetGlobalState, + (ndr_print_function_t) ndr_print_PNP_GetGlobalState, + false, + }, + { + "PNP_InitDetection", + sizeof(struct PNP_InitDetection), + (ndr_push_flags_fn_t) ndr_push_PNP_InitDetection, + (ndr_pull_flags_fn_t) ndr_pull_PNP_InitDetection, + (ndr_print_function_t) ndr_print_PNP_InitDetection, + false, + }, + { + "PNP_ReportLogOn", + sizeof(struct PNP_ReportLogOn), + (ndr_push_flags_fn_t) ndr_push_PNP_ReportLogOn, + (ndr_pull_flags_fn_t) ndr_pull_PNP_ReportLogOn, + (ndr_print_function_t) ndr_print_PNP_ReportLogOn, + false, + }, + { + "PNP_ValidateDeviceInstance", + sizeof(struct PNP_ValidateDeviceInstance), + (ndr_push_flags_fn_t) ndr_push_PNP_ValidateDeviceInstance, + (ndr_pull_flags_fn_t) ndr_pull_PNP_ValidateDeviceInstance, + (ndr_print_function_t) ndr_print_PNP_ValidateDeviceInstance, + false, + }, + { + "PNP_GetRootDeviceInstance", + sizeof(struct PNP_GetRootDeviceInstance), + (ndr_push_flags_fn_t) ndr_push_PNP_GetRootDeviceInstance, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetRootDeviceInstance, + (ndr_print_function_t) ndr_print_PNP_GetRootDeviceInstance, + false, + }, + { + "PNP_GetRelatedDeviceInstance", + sizeof(struct PNP_GetRelatedDeviceInstance), + (ndr_push_flags_fn_t) ndr_push_PNP_GetRelatedDeviceInstance, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetRelatedDeviceInstance, + (ndr_print_function_t) ndr_print_PNP_GetRelatedDeviceInstance, + false, + }, + { + "PNP_EnumerateSubKeys", + sizeof(struct PNP_EnumerateSubKeys), + (ndr_push_flags_fn_t) ndr_push_PNP_EnumerateSubKeys, + (ndr_pull_flags_fn_t) ndr_pull_PNP_EnumerateSubKeys, + (ndr_print_function_t) ndr_print_PNP_EnumerateSubKeys, + false, + }, + { + "PNP_GetDeviceList", + sizeof(struct PNP_GetDeviceList), + (ndr_push_flags_fn_t) ndr_push_PNP_GetDeviceList, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDeviceList, + (ndr_print_function_t) ndr_print_PNP_GetDeviceList, + false, + }, + { + "PNP_GetDeviceListSize", + sizeof(struct PNP_GetDeviceListSize), + (ndr_push_flags_fn_t) ndr_push_PNP_GetDeviceListSize, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDeviceListSize, + (ndr_print_function_t) ndr_print_PNP_GetDeviceListSize, + false, + }, + { + "PNP_GetDepth", + sizeof(struct PNP_GetDepth), + (ndr_push_flags_fn_t) ndr_push_PNP_GetDepth, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDepth, + (ndr_print_function_t) ndr_print_PNP_GetDepth, + false, + }, + { + "PNP_GetDeviceRegProp", + sizeof(struct PNP_GetDeviceRegProp), + (ndr_push_flags_fn_t) ndr_push_PNP_GetDeviceRegProp, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDeviceRegProp, + (ndr_print_function_t) ndr_print_PNP_GetDeviceRegProp, + false, + }, + { + "PNP_SetDeviceRegProp", + sizeof(struct PNP_SetDeviceRegProp), + (ndr_push_flags_fn_t) ndr_push_PNP_SetDeviceRegProp, + (ndr_pull_flags_fn_t) ndr_pull_PNP_SetDeviceRegProp, + (ndr_print_function_t) ndr_print_PNP_SetDeviceRegProp, + false, + }, + { + "PNP_GetClassInstance", + sizeof(struct PNP_GetClassInstance), + (ndr_push_flags_fn_t) ndr_push_PNP_GetClassInstance, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetClassInstance, + (ndr_print_function_t) ndr_print_PNP_GetClassInstance, + false, + }, + { + "PNP_CreateKey", + sizeof(struct PNP_CreateKey), + (ndr_push_flags_fn_t) ndr_push_PNP_CreateKey, + (ndr_pull_flags_fn_t) ndr_pull_PNP_CreateKey, + (ndr_print_function_t) ndr_print_PNP_CreateKey, + false, + }, + { + "PNP_DeleteRegistryKey", + sizeof(struct PNP_DeleteRegistryKey), + (ndr_push_flags_fn_t) ndr_push_PNP_DeleteRegistryKey, + (ndr_pull_flags_fn_t) ndr_pull_PNP_DeleteRegistryKey, + (ndr_print_function_t) ndr_print_PNP_DeleteRegistryKey, + false, + }, + { + "PNP_GetClassCount", + sizeof(struct PNP_GetClassCount), + (ndr_push_flags_fn_t) ndr_push_PNP_GetClassCount, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetClassCount, + (ndr_print_function_t) ndr_print_PNP_GetClassCount, + false, + }, + { + "PNP_GetClassName", + sizeof(struct PNP_GetClassName), + (ndr_push_flags_fn_t) ndr_push_PNP_GetClassName, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetClassName, + (ndr_print_function_t) ndr_print_PNP_GetClassName, + false, + }, + { + "PNP_DeleteClassKey", + sizeof(struct PNP_DeleteClassKey), + (ndr_push_flags_fn_t) ndr_push_PNP_DeleteClassKey, + (ndr_pull_flags_fn_t) ndr_pull_PNP_DeleteClassKey, + (ndr_print_function_t) ndr_print_PNP_DeleteClassKey, + false, + }, + { + "PNP_GetInterfaceDeviceAlias", + sizeof(struct PNP_GetInterfaceDeviceAlias), + (ndr_push_flags_fn_t) ndr_push_PNP_GetInterfaceDeviceAlias, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetInterfaceDeviceAlias, + (ndr_print_function_t) ndr_print_PNP_GetInterfaceDeviceAlias, + false, + }, + { + "PNP_GetInterfaceDeviceList", + sizeof(struct PNP_GetInterfaceDeviceList), + (ndr_push_flags_fn_t) ndr_push_PNP_GetInterfaceDeviceList, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetInterfaceDeviceList, + (ndr_print_function_t) ndr_print_PNP_GetInterfaceDeviceList, + false, + }, + { + "PNP_GetInterfaceDeviceListSize", + sizeof(struct PNP_GetInterfaceDeviceListSize), + (ndr_push_flags_fn_t) ndr_push_PNP_GetInterfaceDeviceListSize, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetInterfaceDeviceListSize, + (ndr_print_function_t) ndr_print_PNP_GetInterfaceDeviceListSize, + false, + }, + { + "PNP_RegisterDeviceClassAssociation", + sizeof(struct PNP_RegisterDeviceClassAssociation), + (ndr_push_flags_fn_t) ndr_push_PNP_RegisterDeviceClassAssociation, + (ndr_pull_flags_fn_t) ndr_pull_PNP_RegisterDeviceClassAssociation, + (ndr_print_function_t) ndr_print_PNP_RegisterDeviceClassAssociation, + false, + }, + { + "PNP_UnregisterDeviceClassAssociation", + sizeof(struct PNP_UnregisterDeviceClassAssociation), + (ndr_push_flags_fn_t) ndr_push_PNP_UnregisterDeviceClassAssociation, + (ndr_pull_flags_fn_t) ndr_pull_PNP_UnregisterDeviceClassAssociation, + (ndr_print_function_t) ndr_print_PNP_UnregisterDeviceClassAssociation, + false, + }, + { + "PNP_GetClassRegProp", + sizeof(struct PNP_GetClassRegProp), + (ndr_push_flags_fn_t) ndr_push_PNP_GetClassRegProp, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetClassRegProp, + (ndr_print_function_t) ndr_print_PNP_GetClassRegProp, + false, + }, + { + "PNP_SetClassRegProp", + sizeof(struct PNP_SetClassRegProp), + (ndr_push_flags_fn_t) ndr_push_PNP_SetClassRegProp, + (ndr_pull_flags_fn_t) ndr_pull_PNP_SetClassRegProp, + (ndr_print_function_t) ndr_print_PNP_SetClassRegProp, + false, + }, + { + "PNP_CreateDevInst", + sizeof(struct PNP_CreateDevInst), + (ndr_push_flags_fn_t) ndr_push_PNP_CreateDevInst, + (ndr_pull_flags_fn_t) ndr_pull_PNP_CreateDevInst, + (ndr_print_function_t) ndr_print_PNP_CreateDevInst, + false, + }, + { + "PNP_DeviceInstanceAction", + sizeof(struct PNP_DeviceInstanceAction), + (ndr_push_flags_fn_t) ndr_push_PNP_DeviceInstanceAction, + (ndr_pull_flags_fn_t) ndr_pull_PNP_DeviceInstanceAction, + (ndr_print_function_t) ndr_print_PNP_DeviceInstanceAction, + false, + }, + { + "PNP_GetDeviceStatus", + sizeof(struct PNP_GetDeviceStatus), + (ndr_push_flags_fn_t) ndr_push_PNP_GetDeviceStatus, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetDeviceStatus, + (ndr_print_function_t) ndr_print_PNP_GetDeviceStatus, + false, + }, + { + "PNP_SetDeviceProblem", + sizeof(struct PNP_SetDeviceProblem), + (ndr_push_flags_fn_t) ndr_push_PNP_SetDeviceProblem, + (ndr_pull_flags_fn_t) ndr_pull_PNP_SetDeviceProblem, + (ndr_print_function_t) ndr_print_PNP_SetDeviceProblem, + false, + }, + { + "PNP_DisableDevInst", + sizeof(struct PNP_DisableDevInst), + (ndr_push_flags_fn_t) ndr_push_PNP_DisableDevInst, + (ndr_pull_flags_fn_t) ndr_pull_PNP_DisableDevInst, + (ndr_print_function_t) ndr_print_PNP_DisableDevInst, + false, + }, + { + "PNP_UninstallDevInst", + sizeof(struct PNP_UninstallDevInst), + (ndr_push_flags_fn_t) ndr_push_PNP_UninstallDevInst, + (ndr_pull_flags_fn_t) ndr_pull_PNP_UninstallDevInst, + (ndr_print_function_t) ndr_print_PNP_UninstallDevInst, + false, + }, + { + "PNP_AddID", + sizeof(struct PNP_AddID), + (ndr_push_flags_fn_t) ndr_push_PNP_AddID, + (ndr_pull_flags_fn_t) ndr_pull_PNP_AddID, + (ndr_print_function_t) ndr_print_PNP_AddID, + false, + }, + { + "PNP_RegisterDriver", + sizeof(struct PNP_RegisterDriver), + (ndr_push_flags_fn_t) ndr_push_PNP_RegisterDriver, + (ndr_pull_flags_fn_t) ndr_pull_PNP_RegisterDriver, + (ndr_print_function_t) ndr_print_PNP_RegisterDriver, + false, + }, + { + "PNP_QueryRemove", + sizeof(struct PNP_QueryRemove), + (ndr_push_flags_fn_t) ndr_push_PNP_QueryRemove, + (ndr_pull_flags_fn_t) ndr_pull_PNP_QueryRemove, + (ndr_print_function_t) ndr_print_PNP_QueryRemove, + false, + }, + { + "PNP_RequestDeviceEject", + sizeof(struct PNP_RequestDeviceEject), + (ndr_push_flags_fn_t) ndr_push_PNP_RequestDeviceEject, + (ndr_pull_flags_fn_t) ndr_pull_PNP_RequestDeviceEject, + (ndr_print_function_t) ndr_print_PNP_RequestDeviceEject, + false, + }, + { + "PNP_IsDockStationPresent", + sizeof(struct PNP_IsDockStationPresent), + (ndr_push_flags_fn_t) ndr_push_PNP_IsDockStationPresent, + (ndr_pull_flags_fn_t) ndr_pull_PNP_IsDockStationPresent, + (ndr_print_function_t) ndr_print_PNP_IsDockStationPresent, + false, + }, + { + "PNP_RequestEjectPC", + sizeof(struct PNP_RequestEjectPC), + (ndr_push_flags_fn_t) ndr_push_PNP_RequestEjectPC, + (ndr_pull_flags_fn_t) ndr_pull_PNP_RequestEjectPC, + (ndr_print_function_t) ndr_print_PNP_RequestEjectPC, + false, + }, + { + "PNP_HwProfFlags", + sizeof(struct PNP_HwProfFlags), + (ndr_push_flags_fn_t) ndr_push_PNP_HwProfFlags, + (ndr_pull_flags_fn_t) ndr_pull_PNP_HwProfFlags, + (ndr_print_function_t) ndr_print_PNP_HwProfFlags, + false, + }, + { + "PNP_GetHwProfInfo", + sizeof(struct PNP_GetHwProfInfo), + (ndr_push_flags_fn_t) ndr_push_PNP_GetHwProfInfo, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetHwProfInfo, + (ndr_print_function_t) ndr_print_PNP_GetHwProfInfo, + false, + }, + { + "PNP_AddEmptyLogConf", + sizeof(struct PNP_AddEmptyLogConf), + (ndr_push_flags_fn_t) ndr_push_PNP_AddEmptyLogConf, + (ndr_pull_flags_fn_t) ndr_pull_PNP_AddEmptyLogConf, + (ndr_print_function_t) ndr_print_PNP_AddEmptyLogConf, + false, + }, + { + "PNP_FreeLogConf", + sizeof(struct PNP_FreeLogConf), + (ndr_push_flags_fn_t) ndr_push_PNP_FreeLogConf, + (ndr_pull_flags_fn_t) ndr_pull_PNP_FreeLogConf, + (ndr_print_function_t) ndr_print_PNP_FreeLogConf, + false, + }, + { + "PNP_GetFirstLogConf", + sizeof(struct PNP_GetFirstLogConf), + (ndr_push_flags_fn_t) ndr_push_PNP_GetFirstLogConf, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetFirstLogConf, + (ndr_print_function_t) ndr_print_PNP_GetFirstLogConf, + false, + }, + { + "PNP_GetNextLogConf", + sizeof(struct PNP_GetNextLogConf), + (ndr_push_flags_fn_t) ndr_push_PNP_GetNextLogConf, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetNextLogConf, + (ndr_print_function_t) ndr_print_PNP_GetNextLogConf, + false, + }, + { + "PNP_GetLogConfPriority", + sizeof(struct PNP_GetLogConfPriority), + (ndr_push_flags_fn_t) ndr_push_PNP_GetLogConfPriority, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetLogConfPriority, + (ndr_print_function_t) ndr_print_PNP_GetLogConfPriority, + false, + }, + { + "PNP_AddResDes", + sizeof(struct PNP_AddResDes), + (ndr_push_flags_fn_t) ndr_push_PNP_AddResDes, + (ndr_pull_flags_fn_t) ndr_pull_PNP_AddResDes, + (ndr_print_function_t) ndr_print_PNP_AddResDes, + false, + }, + { + "PNP_FreeResDes", + sizeof(struct PNP_FreeResDes), + (ndr_push_flags_fn_t) ndr_push_PNP_FreeResDes, + (ndr_pull_flags_fn_t) ndr_pull_PNP_FreeResDes, + (ndr_print_function_t) ndr_print_PNP_FreeResDes, + false, + }, + { + "PNP_GetNextResDes", + sizeof(struct PNP_GetNextResDes), + (ndr_push_flags_fn_t) ndr_push_PNP_GetNextResDes, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetNextResDes, + (ndr_print_function_t) ndr_print_PNP_GetNextResDes, + false, + }, + { + "PNP_GetResDesData", + sizeof(struct PNP_GetResDesData), + (ndr_push_flags_fn_t) ndr_push_PNP_GetResDesData, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetResDesData, + (ndr_print_function_t) ndr_print_PNP_GetResDesData, + false, + }, + { + "PNP_GetResDesDataSize", + sizeof(struct PNP_GetResDesDataSize), + (ndr_push_flags_fn_t) ndr_push_PNP_GetResDesDataSize, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetResDesDataSize, + (ndr_print_function_t) ndr_print_PNP_GetResDesDataSize, + false, + }, + { + "PNP_ModifyResDes", + sizeof(struct PNP_ModifyResDes), + (ndr_push_flags_fn_t) ndr_push_PNP_ModifyResDes, + (ndr_pull_flags_fn_t) ndr_pull_PNP_ModifyResDes, + (ndr_print_function_t) ndr_print_PNP_ModifyResDes, + false, + }, + { + "PNP_DetectResourceLimit", + sizeof(struct PNP_DetectResourceLimit), + (ndr_push_flags_fn_t) ndr_push_PNP_DetectResourceLimit, + (ndr_pull_flags_fn_t) ndr_pull_PNP_DetectResourceLimit, + (ndr_print_function_t) ndr_print_PNP_DetectResourceLimit, + false, + }, + { + "PNP_QueryResConfList", + sizeof(struct PNP_QueryResConfList), + (ndr_push_flags_fn_t) ndr_push_PNP_QueryResConfList, + (ndr_pull_flags_fn_t) ndr_pull_PNP_QueryResConfList, + (ndr_print_function_t) ndr_print_PNP_QueryResConfList, + false, + }, + { + "PNP_SetHwProf", + sizeof(struct PNP_SetHwProf), + (ndr_push_flags_fn_t) ndr_push_PNP_SetHwProf, + (ndr_pull_flags_fn_t) ndr_pull_PNP_SetHwProf, + (ndr_print_function_t) ndr_print_PNP_SetHwProf, + false, + }, + { + "PNP_QueryArbitratorFreeData", + sizeof(struct PNP_QueryArbitratorFreeData), + (ndr_push_flags_fn_t) ndr_push_PNP_QueryArbitratorFreeData, + (ndr_pull_flags_fn_t) ndr_pull_PNP_QueryArbitratorFreeData, + (ndr_print_function_t) ndr_print_PNP_QueryArbitratorFreeData, + false, + }, + { + "PNP_QueryArbitratorFreeSize", + sizeof(struct PNP_QueryArbitratorFreeSize), + (ndr_push_flags_fn_t) ndr_push_PNP_QueryArbitratorFreeSize, + (ndr_pull_flags_fn_t) ndr_pull_PNP_QueryArbitratorFreeSize, + (ndr_print_function_t) ndr_print_PNP_QueryArbitratorFreeSize, + false, + }, + { + "PNP_RunDetection", + sizeof(struct PNP_RunDetection), + (ndr_push_flags_fn_t) ndr_push_PNP_RunDetection, + (ndr_pull_flags_fn_t) ndr_pull_PNP_RunDetection, + (ndr_print_function_t) ndr_print_PNP_RunDetection, + false, + }, + { + "PNP_RegisterNotification", + sizeof(struct PNP_RegisterNotification), + (ndr_push_flags_fn_t) ndr_push_PNP_RegisterNotification, + (ndr_pull_flags_fn_t) ndr_pull_PNP_RegisterNotification, + (ndr_print_function_t) ndr_print_PNP_RegisterNotification, + false, + }, + { + "PNP_UnregisterNotification", + sizeof(struct PNP_UnregisterNotification), + (ndr_push_flags_fn_t) ndr_push_PNP_UnregisterNotification, + (ndr_pull_flags_fn_t) ndr_pull_PNP_UnregisterNotification, + (ndr_print_function_t) ndr_print_PNP_UnregisterNotification, + false, + }, + { + "PNP_GetCustomDevProp", + sizeof(struct PNP_GetCustomDevProp), + (ndr_push_flags_fn_t) ndr_push_PNP_GetCustomDevProp, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetCustomDevProp, + (ndr_print_function_t) ndr_print_PNP_GetCustomDevProp, + false, + }, + { + "PNP_GetVersionInternal", + sizeof(struct PNP_GetVersionInternal), + (ndr_push_flags_fn_t) ndr_push_PNP_GetVersionInternal, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetVersionInternal, + (ndr_print_function_t) ndr_print_PNP_GetVersionInternal, + false, + }, + { + "PNP_GetBlockedDriverInfo", + sizeof(struct PNP_GetBlockedDriverInfo), + (ndr_push_flags_fn_t) ndr_push_PNP_GetBlockedDriverInfo, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetBlockedDriverInfo, + (ndr_print_function_t) ndr_print_PNP_GetBlockedDriverInfo, + false, + }, + { + "PNP_GetServerSideDeviceInstallFlags", + sizeof(struct PNP_GetServerSideDeviceInstallFlags), + (ndr_push_flags_fn_t) ndr_push_PNP_GetServerSideDeviceInstallFlags, + (ndr_pull_flags_fn_t) ndr_pull_PNP_GetServerSideDeviceInstallFlags, + (ndr_print_function_t) ndr_print_PNP_GetServerSideDeviceInstallFlags, + false, + }, + { NULL, 0, NULL, NULL, NULL, false } +}; + +static const char * const ntsvcs_endpoint_strings[] = { + "ncacn_np:[\\pipe\\ntsvcs]", +}; + +static const struct ndr_interface_string_array ntsvcs_endpoints = { + .count = 1, + .names = ntsvcs_endpoint_strings +}; + +static const char * const ntsvcs_authservice_strings[] = { + "host", +}; + +static const struct ndr_interface_string_array ntsvcs_authservices = { + .count = 1, + .names = ntsvcs_authservice_strings +}; + + +const struct ndr_interface_table ndr_table_ntsvcs = { + .name = "ntsvcs", + .syntax_id = { + {0x8d9f4e40,0xa03d,0x11ce,{0x8f,0x69},{0x08,0x00,0x3e,0x30,0x05,0x1b}}, + NDR_NTSVCS_VERSION + }, + .helpstring = NDR_NTSVCS_HELPSTRING, + .num_calls = 65, + .calls = ntsvcs_calls, + .endpoints = &ntsvcs_endpoints, + .authservices = &ntsvcs_authservices +}; + diff --git a/source3/librpc/gen_ndr/ndr_ntsvcs.h b/source3/librpc/gen_ndr/ndr_ntsvcs.h new file mode 100644 index 0000000000..0e3b6b91c4 --- /dev/null +++ b/source3/librpc/gen_ndr/ndr_ntsvcs.h @@ -0,0 +1,211 @@ +/* header auto-generated by pidl */ + +#include "librpc/ndr/libndr.h" +#include "librpc/gen_ndr/ntsvcs.h" + +#ifndef _HEADER_NDR_ntsvcs +#define _HEADER_NDR_ntsvcs + +#define NDR_NTSVCS_UUID "8d9f4e40-a03d-11ce-8f69-08003e30051b" +#define NDR_NTSVCS_VERSION 1.0 +#define NDR_NTSVCS_NAME "ntsvcs" +#define NDR_NTSVCS_HELPSTRING "Plug and Play services" +extern const struct ndr_interface_table ndr_table_ntsvcs; +#define NDR_PNP_DISCONNECT (0x00) + +#define NDR_PNP_CONNECT (0x01) + +#define NDR_PNP_GETVERSION (0x02) + +#define NDR_PNP_GETGLOBALSTATE (0x03) + +#define NDR_PNP_INITDETECTION (0x04) + +#define NDR_PNP_REPORTLOGON (0x05) + +#define NDR_PNP_VALIDATEDEVICEINSTANCE (0x06) + +#define NDR_PNP_GETROOTDEVICEINSTANCE (0x07) + +#define NDR_PNP_GETRELATEDDEVICEINSTANCE (0x08) + +#define NDR_PNP_ENUMERATESUBKEYS (0x09) + +#define NDR_PNP_GETDEVICELIST (0x0a) + +#define NDR_PNP_GETDEVICELISTSIZE (0x0b) + +#define NDR_PNP_GETDEPTH (0x0c) + +#define NDR_PNP_GETDEVICEREGPROP (0x0d) + +#define NDR_PNP_SETDEVICEREGPROP (0x0e) + +#define NDR_PNP_GETCLASSINSTANCE (0x0f) + +#define NDR_PNP_CREATEKEY (0x10) + +#define NDR_PNP_DELETEREGISTRYKEY (0x11) + +#define NDR_PNP_GETCLASSCOUNT (0x12) + +#define NDR_PNP_GETCLASSNAME (0x13) + +#define NDR_PNP_DELETECLASSKEY (0x14) + +#define NDR_PNP_GETINTERFACEDEVICEALIAS (0x15) + +#define NDR_PNP_GETINTERFACEDEVICELIST (0x16) + +#define NDR_PNP_GETINTERFACEDEVICELISTSIZE (0x17) + +#define NDR_PNP_REGISTERDEVICECLASSASSOCIATION (0x18) + +#define NDR_PNP_UNREGISTERDEVICECLASSASSOCIATION (0x19) + +#define NDR_PNP_GETCLASSREGPROP (0x1a) + +#define NDR_PNP_SETCLASSREGPROP (0x1b) + +#define NDR_PNP_CREATEDEVINST (0x1c) + +#define NDR_PNP_DEVICEINSTANCEACTION (0x1d) + +#define NDR_PNP_GETDEVICESTATUS (0x1e) + +#define NDR_PNP_SETDEVICEPROBLEM (0x1f) + +#define NDR_PNP_DISABLEDEVINST (0x20) + +#define NDR_PNP_UNINSTALLDEVINST (0x21) + +#define NDR_PNP_ADDID (0x22) + +#define NDR_PNP_REGISTERDRIVER (0x23) + +#define NDR_PNP_QUERYREMOVE (0x24) + +#define NDR_PNP_REQUESTDEVICEEJECT (0x25) + +#define NDR_PNP_ISDOCKSTATIONPRESENT (0x26) + +#define NDR_PNP_REQUESTEJECTPC (0x27) + +#define NDR_PNP_HWPROFFLAGS (0x28) + +#define NDR_PNP_GETHWPROFINFO (0x29) + +#define NDR_PNP_ADDEMPTYLOGCONF (0x2a) + +#define NDR_PNP_FREELOGCONF (0x2b) + +#define NDR_PNP_GETFIRSTLOGCONF (0x2c) + +#define NDR_PNP_GETNEXTLOGCONF (0x2d) + +#define NDR_PNP_GETLOGCONFPRIORITY (0x2e) + +#define NDR_PNP_ADDRESDES (0x2f) + +#define NDR_PNP_FREERESDES (0x30) + +#define NDR_PNP_GETNEXTRESDES (0x31) + +#define NDR_PNP_GETRESDESDATA (0x32) + +#define NDR_PNP_GETRESDESDATASIZE (0x33) + +#define NDR_PNP_MODIFYRESDES (0x34) + +#define NDR_PNP_DETECTRESOURCELIMIT (0x35) + +#define NDR_PNP_QUERYRESCONFLIST (0x36) + +#define NDR_PNP_SETHWPROF (0x37) + +#define NDR_PNP_QUERYARBITRATORFREEDATA (0x38) + +#define NDR_PNP_QUERYARBITRATORFREESIZE (0x39) + +#define NDR_PNP_RUNDETECTION (0x3a) + +#define NDR_PNP_REGISTERNOTIFICATION (0x3b) + +#define NDR_PNP_UNREGISTERNOTIFICATION (0x3c) + +#define NDR_PNP_GETCUSTOMDEVPROP (0x3d) + +#define NDR_PNP_GETVERSIONINTERNAL (0x3e) + +#define NDR_PNP_GETBLOCKEDDRIVERINFO (0x3f) + +#define NDR_PNP_GETSERVERSIDEDEVICEINSTALLFLAGS (0x40) + +#define NDR_NTSVCS_CALL_COUNT (65) +void ndr_print_PNP_HwProfInfo(struct ndr_print *ndr, const char *name, const struct PNP_HwProfInfo *r); +void ndr_print_PNP_Disconnect(struct ndr_print *ndr, const char *name, int flags, const struct PNP_Disconnect *r); +void ndr_print_PNP_Connect(struct ndr_print *ndr, const char *name, int flags, const struct PNP_Connect *r); +void ndr_print_PNP_GetVersion(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetVersion *r); +void ndr_print_PNP_GetGlobalState(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetGlobalState *r); +void ndr_print_PNP_InitDetection(struct ndr_print *ndr, const char *name, int flags, const struct PNP_InitDetection *r); +void ndr_print_PNP_ReportLogOn(struct ndr_print *ndr, const char *name, int flags, const struct PNP_ReportLogOn *r); +void ndr_print_PNP_ValidateDeviceInstance(struct ndr_print *ndr, const char *name, int flags, const struct PNP_ValidateDeviceInstance *r); +void ndr_print_PNP_GetRootDeviceInstance(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetRootDeviceInstance *r); +void ndr_print_PNP_GetRelatedDeviceInstance(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetRelatedDeviceInstance *r); +void ndr_print_PNP_EnumerateSubKeys(struct ndr_print *ndr, const char *name, int flags, const struct PNP_EnumerateSubKeys *r); +void ndr_print_PNP_GetDeviceList(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDeviceList *r); +void ndr_print_PNP_GetDeviceListSize(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDeviceListSize *r); +void ndr_print_PNP_GetDepth(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDepth *r); +void ndr_print_PNP_GetDeviceRegProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDeviceRegProp *r); +void ndr_print_PNP_SetDeviceRegProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_SetDeviceRegProp *r); +void ndr_print_PNP_GetClassInstance(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetClassInstance *r); +void ndr_print_PNP_CreateKey(struct ndr_print *ndr, const char *name, int flags, const struct PNP_CreateKey *r); +void ndr_print_PNP_DeleteRegistryKey(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DeleteRegistryKey *r); +void ndr_print_PNP_GetClassCount(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetClassCount *r); +void ndr_print_PNP_GetClassName(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetClassName *r); +void ndr_print_PNP_DeleteClassKey(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DeleteClassKey *r); +void ndr_print_PNP_GetInterfaceDeviceAlias(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetInterfaceDeviceAlias *r); +void ndr_print_PNP_GetInterfaceDeviceList(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetInterfaceDeviceList *r); +void ndr_print_PNP_GetInterfaceDeviceListSize(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetInterfaceDeviceListSize *r); +void ndr_print_PNP_RegisterDeviceClassAssociation(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RegisterDeviceClassAssociation *r); +void ndr_print_PNP_UnregisterDeviceClassAssociation(struct ndr_print *ndr, const char *name, int flags, const struct PNP_UnregisterDeviceClassAssociation *r); +void ndr_print_PNP_GetClassRegProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetClassRegProp *r); +void ndr_print_PNP_SetClassRegProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_SetClassRegProp *r); +void ndr_print_PNP_CreateDevInst(struct ndr_print *ndr, const char *name, int flags, const struct PNP_CreateDevInst *r); +void ndr_print_PNP_DeviceInstanceAction(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DeviceInstanceAction *r); +void ndr_print_PNP_GetDeviceStatus(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetDeviceStatus *r); +void ndr_print_PNP_SetDeviceProblem(struct ndr_print *ndr, const char *name, int flags, const struct PNP_SetDeviceProblem *r); +void ndr_print_PNP_DisableDevInst(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DisableDevInst *r); +void ndr_print_PNP_UninstallDevInst(struct ndr_print *ndr, const char *name, int flags, const struct PNP_UninstallDevInst *r); +void ndr_print_PNP_AddID(struct ndr_print *ndr, const char *name, int flags, const struct PNP_AddID *r); +void ndr_print_PNP_RegisterDriver(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RegisterDriver *r); +void ndr_print_PNP_QueryRemove(struct ndr_print *ndr, const char *name, int flags, const struct PNP_QueryRemove *r); +void ndr_print_PNP_RequestDeviceEject(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RequestDeviceEject *r); +void ndr_print_PNP_IsDockStationPresent(struct ndr_print *ndr, const char *name, int flags, const struct PNP_IsDockStationPresent *r); +void ndr_print_PNP_RequestEjectPC(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RequestEjectPC *r); +void ndr_print_PNP_HwProfFlags(struct ndr_print *ndr, const char *name, int flags, const struct PNP_HwProfFlags *r); +void ndr_print_PNP_GetHwProfInfo(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetHwProfInfo *r); +void ndr_print_PNP_AddEmptyLogConf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_AddEmptyLogConf *r); +void ndr_print_PNP_FreeLogConf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_FreeLogConf *r); +void ndr_print_PNP_GetFirstLogConf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetFirstLogConf *r); +void ndr_print_PNP_GetNextLogConf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetNextLogConf *r); +void ndr_print_PNP_GetLogConfPriority(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetLogConfPriority *r); +void ndr_print_PNP_AddResDes(struct ndr_print *ndr, const char *name, int flags, const struct PNP_AddResDes *r); +void ndr_print_PNP_FreeResDes(struct ndr_print *ndr, const char *name, int flags, const struct PNP_FreeResDes *r); +void ndr_print_PNP_GetNextResDes(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetNextResDes *r); +void ndr_print_PNP_GetResDesData(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetResDesData *r); +void ndr_print_PNP_GetResDesDataSize(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetResDesDataSize *r); +void ndr_print_PNP_ModifyResDes(struct ndr_print *ndr, const char *name, int flags, const struct PNP_ModifyResDes *r); +void ndr_print_PNP_DetectResourceLimit(struct ndr_print *ndr, const char *name, int flags, const struct PNP_DetectResourceLimit *r); +void ndr_print_PNP_QueryResConfList(struct ndr_print *ndr, const char *name, int flags, const struct PNP_QueryResConfList *r); +void ndr_print_PNP_SetHwProf(struct ndr_print *ndr, const char *name, int flags, const struct PNP_SetHwProf *r); +void ndr_print_PNP_QueryArbitratorFreeData(struct ndr_print *ndr, const char *name, int flags, const struct PNP_QueryArbitratorFreeData *r); +void ndr_print_PNP_QueryArbitratorFreeSize(struct ndr_print *ndr, const char *name, int flags, const struct PNP_QueryArbitratorFreeSize *r); +void ndr_print_PNP_RunDetection(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RunDetection *r); +void ndr_print_PNP_RegisterNotification(struct ndr_print *ndr, const char *name, int flags, const struct PNP_RegisterNotification *r); +void ndr_print_PNP_UnregisterNotification(struct ndr_print *ndr, const char *name, int flags, const struct PNP_UnregisterNotification *r); +void ndr_print_PNP_GetCustomDevProp(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetCustomDevProp *r); +void ndr_print_PNP_GetVersionInternal(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetVersionInternal *r); +void ndr_print_PNP_GetBlockedDriverInfo(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetBlockedDriverInfo *r); +void ndr_print_PNP_GetServerSideDeviceInstallFlags(struct ndr_print *ndr, const char *name, int flags, const struct PNP_GetServerSideDeviceInstallFlags *r); +#endif /* _HEADER_NDR_ntsvcs */ diff --git a/source3/librpc/gen_ndr/ndr_samr.c b/source3/librpc/gen_ndr/ndr_samr.c index eaa38e3a1f..3af589f393 100644 --- a/source3/librpc/gen_ndr/ndr_samr.c +++ b/source3/librpc/gen_ndr/ndr_samr.c @@ -299,8 +299,7 @@ _PUBLIC_ void ndr_print_samr_SamArray(struct ndr_print *ndr, const char *name, c ndr->depth++; for (cntr_entries_1=0;cntr_entries_1<r->count;cntr_entries_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_entries_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_entries_1) != -1) { ndr_print_samr_SamEntry(ndr, "entries", &r->entries[cntr_entries_1]); free(idx_1); } @@ -1161,8 +1160,7 @@ _PUBLIC_ void ndr_print_samr_Ids(struct ndr_print *ndr, const char *name, const ndr->depth++; for (cntr_ids_1=0;cntr_ids_1<r->count;cntr_ids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_ids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_ids_1) != -1) { ndr_print_uint32(ndr, "ids", r->ids[cntr_ids_1]); free(idx_1); } @@ -1559,8 +1557,7 @@ _PUBLIC_ void ndr_print_samr_RidTypeArray(struct ndr_print *ndr, const char *nam ndr->depth++; for (cntr_rids_1=0;cntr_rids_1<r->count;cntr_rids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_rids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_rids_1) != -1) { ndr_print_uint32(ndr, "rids", r->rids[cntr_rids_1]); free(idx_1); } @@ -1575,8 +1572,7 @@ _PUBLIC_ void ndr_print_samr_RidTypeArray(struct ndr_print *ndr, const char *nam ndr->depth++; for (cntr_types_1=0;cntr_types_1<r->count;cntr_types_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_types_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_types_1) != -1) { ndr_print_uint32(ndr, "types", r->types[cntr_types_1]); free(idx_1); } @@ -3711,8 +3707,7 @@ _PUBLIC_ void ndr_print_samr_RidWithAttributeArray(struct ndr_print *ndr, const ndr->depth++; for (cntr_rids_1=0;cntr_rids_1<r->count;cntr_rids_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_rids_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_rids_1) != -1) { ndr_print_samr_RidWithAttribute(ndr, "rids", &r->rids[cntr_rids_1]); free(idx_1); } @@ -3849,8 +3844,7 @@ _PUBLIC_ void ndr_print_samr_DispInfoGeneral(struct ndr_print *ndr, const char * ndr->depth++; for (cntr_entries_1=0;cntr_entries_1<r->count;cntr_entries_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_entries_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_entries_1) != -1) { ndr_print_samr_DispEntryGeneral(ndr, "entries", &r->entries[cntr_entries_1]); free(idx_1); } @@ -3982,8 +3976,7 @@ _PUBLIC_ void ndr_print_samr_DispInfoFull(struct ndr_print *ndr, const char *nam ndr->depth++; for (cntr_entries_1=0;cntr_entries_1<r->count;cntr_entries_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_entries_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_entries_1) != -1) { ndr_print_samr_DispEntryFull(ndr, "entries", &r->entries[cntr_entries_1]); free(idx_1); } @@ -4115,8 +4108,7 @@ _PUBLIC_ void ndr_print_samr_DispInfoFullGroups(struct ndr_print *ndr, const cha ndr->depth++; for (cntr_entries_1=0;cntr_entries_1<r->count;cntr_entries_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_entries_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_entries_1) != -1) { ndr_print_samr_DispEntryFullGroup(ndr, "entries", &r->entries[cntr_entries_1]); free(idx_1); } @@ -4132,10 +4124,10 @@ static enum ndr_err_code ndr_push_samr_DispEntryAscii(struct ndr_push *ndr, int if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->idx)); - NDR_CHECK(ndr_push_lsa_AsciiString(ndr, NDR_SCALARS, &r->account_name)); + NDR_CHECK(ndr_push_lsa_AsciiStringLarge(ndr, NDR_SCALARS, &r->account_name)); } if (ndr_flags & NDR_BUFFERS) { - NDR_CHECK(ndr_push_lsa_AsciiString(ndr, NDR_BUFFERS, &r->account_name)); + NDR_CHECK(ndr_push_lsa_AsciiStringLarge(ndr, NDR_BUFFERS, &r->account_name)); } return NDR_ERR_SUCCESS; } @@ -4145,10 +4137,10 @@ static enum ndr_err_code ndr_pull_samr_DispEntryAscii(struct ndr_pull *ndr, int if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->idx)); - NDR_CHECK(ndr_pull_lsa_AsciiString(ndr, NDR_SCALARS, &r->account_name)); + NDR_CHECK(ndr_pull_lsa_AsciiStringLarge(ndr, NDR_SCALARS, &r->account_name)); } if (ndr_flags & NDR_BUFFERS) { - NDR_CHECK(ndr_pull_lsa_AsciiString(ndr, NDR_BUFFERS, &r->account_name)); + NDR_CHECK(ndr_pull_lsa_AsciiStringLarge(ndr, NDR_BUFFERS, &r->account_name)); } return NDR_ERR_SUCCESS; } @@ -4158,7 +4150,7 @@ _PUBLIC_ void ndr_print_samr_DispEntryAscii(struct ndr_print *ndr, const char *n ndr_print_struct(ndr, name, "samr_DispEntryAscii"); ndr->depth++; ndr_print_uint32(ndr, "idx", r->idx); - ndr_print_lsa_AsciiString(ndr, "account_name", &r->account_name); + ndr_print_lsa_AsciiStringLarge(ndr, "account_name", &r->account_name); ndr->depth--; } @@ -4237,8 +4229,7 @@ _PUBLIC_ void ndr_print_samr_DispInfoAscii(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_entries_1=0;cntr_entries_1<r->count;cntr_entries_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_entries_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_entries_1) != -1) { ndr_print_samr_DispEntryAscii(ndr, "entries", &r->entries[cntr_entries_1]); free(idx_1); } @@ -4840,8 +4831,7 @@ _PUBLIC_ void ndr_print_samr_ValidatePasswordInfo(struct ndr_print *ndr, const c ndr->depth++; for (cntr_pwd_history_1=0;cntr_pwd_history_1<r->pwd_history_len;cntr_pwd_history_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_pwd_history_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_pwd_history_1) != -1) { ndr_print_samr_ValidationBlob(ndr, "pwd_history", &r->pwd_history[cntr_pwd_history_1]); free(idx_1); } @@ -7212,8 +7202,7 @@ _PUBLIC_ void ndr_print_samr_LookupNames(struct ndr_print *ndr, const char *name ndr->depth++; for (cntr_names_0=0;cntr_names_0<r->in.num_names;cntr_names_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_names_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_names_0) != -1) { ndr_print_lsa_String(ndr, "names", &r->in.names[cntr_names_0]); free(idx_0); } @@ -7352,8 +7341,7 @@ _PUBLIC_ void ndr_print_samr_LookupRids(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_rids_0=0;cntr_rids_0<r->in.num_rids;cntr_rids_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_rids_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_rids_0) != -1) { ndr_print_uint32(ndr, "rids", r->in.rids[cntr_rids_0]); free(idx_0); } diff --git a/source3/librpc/gen_ndr/ndr_security.c b/source3/librpc/gen_ndr/ndr_security.c index 8ab56dd914..cbeabf48e5 100644 --- a/source3/librpc/gen_ndr/ndr_security.c +++ b/source3/librpc/gen_ndr/ndr_security.c @@ -552,8 +552,7 @@ _PUBLIC_ void ndr_print_security_acl(struct ndr_print *ndr, const char *name, co ndr->depth++; for (cntr_aces_0=0;cntr_aces_0<r->num_aces;cntr_aces_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_aces_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_aces_0) != -1) { ndr_print_security_ace(ndr, "aces", &r->aces[cntr_aces_0]); free(idx_0); } @@ -981,8 +980,7 @@ _PUBLIC_ void ndr_print_security_token(struct ndr_print *ndr, const char *name, ndr->depth++; for (cntr_sids_0=0;cntr_sids_0<r->num_sids;cntr_sids_0++) { char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_sids_0); - if (idx_0) { + if (asprintf(&idx_0, "[%d]", cntr_sids_0) != -1) { ndr_print_ptr(ndr, "sids", r->sids[cntr_sids_0]); ndr->depth++; if (r->sids[cntr_sids_0]) { diff --git a/source3/librpc/gen_ndr/ndr_srvsvc.c b/source3/librpc/gen_ndr/ndr_srvsvc.c index 86d47a856c..22a04f86f8 100644 --- a/source3/librpc/gen_ndr/ndr_srvsvc.c +++ b/source3/librpc/gen_ndr/ndr_srvsvc.c @@ -140,8 +140,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetCharDevCtr0(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetCharDevInfo0(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -326,8 +325,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetCharDevCtr1(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetCharDevInfo1(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -749,8 +747,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetCharDevQCtr0(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetCharDevQInfo0(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -938,8 +935,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetCharDevQCtr1(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetCharDevQInfo1(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -1325,8 +1321,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetConnCtr0(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetConnInfo0(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -1520,8 +1515,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetConnCtr1(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetConnInfo1(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -1769,8 +1763,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetFileCtr2(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetFileInfo2(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -1958,8 +1951,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetFileCtr3(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetFileInfo3(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -2381,8 +2373,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetSessCtr0(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetSessInfo0(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -2573,8 +2564,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetSessCtr1(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetSessInfo1(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -2798,8 +2788,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetSessCtr2(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetSessInfo2(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -2984,8 +2973,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetSessCtr10(struct ndr_print *ndr, const char *n ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetSessInfo10(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -3242,8 +3230,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetSessCtr502(struct ndr_print *ndr, const char * ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetSessInfo502(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -3694,8 +3681,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr0(struct ndr_print *ndr, const char *n ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetShareInfo0(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -3877,8 +3863,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr1(struct ndr_print *ndr, const char *n ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetShareInfo1(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -4135,8 +4120,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr2(struct ndr_print *ndr, const char *n ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetShareInfo2(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -4321,8 +4305,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr501(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetShareInfo501(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -4616,8 +4599,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr502(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetShareInfo502(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -4763,8 +4745,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr1004(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetShareInfo1004(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -4897,8 +4878,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr1005(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetShareInfo1005(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -5008,8 +4988,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr1006(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetShareInfo1006(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -5158,8 +5137,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr1007(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetShareInfo1007(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -5245,8 +5223,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareCtr1501(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_sec_desc_buf(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -11487,8 +11464,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetDiskInfo(struct ndr_print *ndr, const char *na ndr->depth++; for (cntr_disks_1=0;cntr_disks_1<r->count;cntr_disks_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_disks_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_disks_1) != -1) { ndr_print_srvsvc_NetDiskInfo0(ndr, "disks", &r->disks[cntr_disks_1]); free(idx_1); } @@ -11781,8 +11757,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetTransportCtr0(struct ndr_print *ndr, const cha ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetTransportInfo0(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -12030,8 +12005,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetTransportCtr1(struct ndr_print *ndr, const cha ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetTransportInfo1(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -12282,8 +12256,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetTransportCtr2(struct ndr_print *ndr, const cha ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetTransportInfo2(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -12540,8 +12513,7 @@ _PUBLIC_ void ndr_print_srvsvc_NetTransportCtr3(struct ndr_print *ndr, const cha ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_srvsvc_NetTransportInfo3(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -15684,8 +15656,11 @@ static enum ndr_err_code ndr_push_srvsvc_NetShareSetInfo(struct ndr_push *ndr, i NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.share_name, CH_UTF16))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.share_name, ndr_charset_length(r->in.share_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.level)); - NDR_CHECK(ndr_push_set_switch_value(ndr, &r->in.info, r->in.level)); - NDR_CHECK(ndr_push_srvsvc_NetShareInfo(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.info)); + 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_srvsvc_NetShareInfo(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.info)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.parm_error)); if (r->in.parm_error) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.parm_error)); @@ -15706,6 +15681,7 @@ static enum ndr_err_code ndr_pull_srvsvc_NetShareSetInfo(struct ndr_pull *ndr, i uint32_t _ptr_server_unc; uint32_t _ptr_parm_error; TALLOC_CTX *_mem_save_server_unc_0; + TALLOC_CTX *_mem_save_info_0; TALLOC_CTX *_mem_save_parm_error_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -15736,8 +15712,14 @@ static enum ndr_err_code ndr_pull_srvsvc_NetShareSetInfo(struct ndr_pull *ndr, i NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.share_name), sizeof(uint16_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.share_name, ndr_get_array_length(ndr, &r->in.share_name), sizeof(uint16_t), CH_UTF16)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.level)); - NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->in.info, r->in.level)); - NDR_CHECK(ndr_pull_srvsvc_NetShareInfo(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.info)); + 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_srvsvc_NetShareInfo(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.info)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_parm_error)); if (_ptr_parm_error) { NDR_PULL_ALLOC(ndr, r->in.parm_error); @@ -15787,8 +15769,11 @@ _PUBLIC_ void ndr_print_srvsvc_NetShareSetInfo(struct ndr_print *ndr, const char ndr->depth--; ndr_print_string(ndr, "share_name", r->in.share_name); ndr_print_uint32(ndr, "level", r->in.level); - ndr_print_set_switch_value(ndr, &r->in.info, r->in.level); - ndr_print_srvsvc_NetShareInfo(ndr, "info", &r->in.info); + ndr_print_ptr(ndr, "info", r->in.info); + ndr->depth++; + ndr_print_set_switch_value(ndr, r->in.info, r->in.level); + ndr_print_srvsvc_NetShareInfo(ndr, "info", r->in.info); + ndr->depth--; ndr_print_ptr(ndr, "parm_error", r->in.parm_error); ndr->depth++; if (r->in.parm_error) { @@ -16207,8 +16192,11 @@ static enum ndr_err_code ndr_push_srvsvc_NetSrvSetInfo(struct ndr_push *ndr, int NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.server_unc, ndr_charset_length(r->in.server_unc, CH_UTF16), sizeof(uint16_t), CH_UTF16)); } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.level)); - NDR_CHECK(ndr_push_set_switch_value(ndr, &r->in.info, r->in.level)); - NDR_CHECK(ndr_push_srvsvc_NetSrvInfo(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.info)); + 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_srvsvc_NetSrvInfo(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.info)); NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.parm_error)); if (r->in.parm_error) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.parm_error)); @@ -16229,6 +16217,7 @@ static enum ndr_err_code ndr_pull_srvsvc_NetSrvSetInfo(struct ndr_pull *ndr, int uint32_t _ptr_server_unc; uint32_t _ptr_parm_error; TALLOC_CTX *_mem_save_server_unc_0; + TALLOC_CTX *_mem_save_info_0; TALLOC_CTX *_mem_save_parm_error_0; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -16252,8 +16241,14 @@ static enum ndr_err_code ndr_pull_srvsvc_NetSrvSetInfo(struct ndr_pull *ndr, int NDR_PULL_SET_MEM_CTX(ndr, _mem_save_server_unc_0, 0); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.level)); - NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->in.info, r->in.level)); - NDR_CHECK(ndr_pull_srvsvc_NetSrvInfo(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.info)); + 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_srvsvc_NetSrvInfo(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.info)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_parm_error)); if (_ptr_parm_error) { NDR_PULL_ALLOC(ndr, r->in.parm_error); @@ -16302,8 +16297,11 @@ _PUBLIC_ void ndr_print_srvsvc_NetSrvSetInfo(struct ndr_print *ndr, const char * } ndr->depth--; ndr_print_uint32(ndr, "level", r->in.level); - ndr_print_set_switch_value(ndr, &r->in.info, r->in.level); - ndr_print_srvsvc_NetSrvInfo(ndr, "info", &r->in.info); + ndr_print_ptr(ndr, "info", r->in.info); + ndr->depth++; + ndr_print_set_switch_value(ndr, r->in.info, r->in.level); + ndr_print_srvsvc_NetSrvInfo(ndr, "info", r->in.info); + ndr->depth--; ndr_print_ptr(ndr, "parm_error", r->in.parm_error); ndr->depth++; if (r->in.parm_error) { @@ -17029,9 +17027,12 @@ static enum ndr_err_code ndr_push_srvsvc_NetRemoteTOD(struct ndr_push *ndr, int } } if (flags & NDR_OUT) { - NDR_CHECK(ndr_push_unique_ptr(ndr, r->out.info)); - if (r->out.info) { - NDR_CHECK(ndr_push_srvsvc_NetRemoteTODInfo(ndr, NDR_SCALARS, r->out.info)); + if (r->out.info == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.info)); + if (*r->out.info) { + NDR_CHECK(ndr_push_srvsvc_NetRemoteTODInfo(ndr, NDR_SCALARS, *r->out.info)); } NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); } @@ -17044,6 +17045,7 @@ static enum ndr_err_code ndr_pull_srvsvc_NetRemoteTOD(struct ndr_pull *ndr, int uint32_t _ptr_info; TALLOC_CTX *_mem_save_server_unc_0; TALLOC_CTX *_mem_save_info_0; + TALLOC_CTX *_mem_save_info_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -17065,20 +17067,28 @@ static enum ndr_err_code ndr_pull_srvsvc_NetRemoteTOD(struct ndr_pull *ndr, int NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.server_unc, ndr_get_array_length(ndr, &r->in.server_unc), sizeof(uint16_t), CH_UTF16)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_server_unc_0, 0); } + NDR_PULL_ALLOC(ndr, r->out.info); + ZERO_STRUCTP(r->out.info); } if (flags & NDR_OUT) { + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.info); + } + _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.info, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); if (_ptr_info) { - NDR_PULL_ALLOC(ndr, r->out.info); + NDR_PULL_ALLOC(ndr, *r->out.info); } else { - r->out.info = NULL; + *r->out.info = NULL; } - if (r->out.info) { - _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.info, 0); - NDR_CHECK(ndr_pull_srvsvc_NetRemoteTODInfo(ndr, NDR_SCALARS, r->out.info)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); + if (*r->out.info) { + _mem_save_info_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.info, 0); + NDR_CHECK(ndr_pull_srvsvc_NetRemoteTODInfo(ndr, NDR_SCALARS, *r->out.info)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_1, 0); } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); } return NDR_ERR_SUCCESS; @@ -17107,10 +17117,13 @@ _PUBLIC_ void ndr_print_srvsvc_NetRemoteTOD(struct ndr_print *ndr, const char *n ndr->depth++; ndr_print_ptr(ndr, "info", r->out.info); ndr->depth++; - if (r->out.info) { - ndr_print_srvsvc_NetRemoteTODInfo(ndr, "info", r->out.info); + ndr_print_ptr(ndr, "info", *r->out.info); + ndr->depth++; + if (*r->out.info) { + ndr_print_srvsvc_NetRemoteTODInfo(ndr, "info", *r->out.info); } ndr->depth--; + ndr->depth--; ndr_print_WERROR(ndr, "result", r->out.result); ndr->depth--; } diff --git a/source3/librpc/gen_ndr/ndr_svcctl.c b/source3/librpc/gen_ndr/ndr_svcctl.c index b2dfd0eef4..16e0416288 100644 --- a/source3/librpc/gen_ndr/ndr_svcctl.c +++ b/source3/librpc/gen_ndr/ndr_svcctl.c @@ -588,8 +588,23 @@ _PUBLIC_ void ndr_print_svcctl_LockServiceDatabase(struct ndr_print *ndr, const static enum ndr_err_code ndr_push_svcctl_QueryServiceObjectSecurity(struct ndr_push *ndr, int flags, const struct svcctl_QueryServiceObjectSecurity *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_uint32(ndr, NDR_SCALARS, r->in.security_flags)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buffer_size)); } if (flags & NDR_OUT) { + if (r->out.buffer == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buffer_size)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buffer_size)); + if (r->out.needed == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.needed)); NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -597,10 +612,48 @@ static enum ndr_err_code ndr_push_svcctl_QueryServiceObjectSecurity(struct ndr_p static enum ndr_err_code ndr_pull_svcctl_QueryServiceObjectSecurity(struct ndr_pull *ndr, int flags, struct svcctl_QueryServiceObjectSecurity *r) { + TALLOC_CTX *_mem_save_handle_0; + TALLOC_CTX *_mem_save_needed_0; if (flags & NDR_IN) { + ZERO_STRUCT(r->out); + + 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_uint32(ndr, NDR_SCALARS, &r->in.security_flags)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buffer_size)); + if (r->in.buffer_size < 0 || r->in.buffer_size > 0x40000) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buffer_size); + memset(r->out.buffer, 0, (r->in.buffer_size) * sizeof(*r->out.buffer)); + NDR_PULL_ALLOC(ndr, r->out.needed); + ZERO_STRUCTP(r->out.needed); } if (flags & NDR_OUT) { + NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer)); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer))); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->out.needed); + } + _mem_save_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->out.needed, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.needed)); + if (*r->out.needed < 0 || *r->out.needed > 0x40000) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_needed_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + if (r->out.buffer) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.buffer, r->in.buffer_size)); + } } return NDR_ERR_SUCCESS; } @@ -615,11 +668,25 @@ _PUBLIC_ void ndr_print_svcctl_QueryServiceObjectSecurity(struct ndr_print *ndr, if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "svcctl_QueryServiceObjectSecurity"); 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_uint32(ndr, "security_flags", r->in.security_flags); + ndr_print_uint32(ndr, "buffer_size", r->in.buffer_size); ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "svcctl_QueryServiceObjectSecurity"); ndr->depth++; + ndr_print_ptr(ndr, "buffer", r->out.buffer); + ndr->depth++; + ndr_print_array_uint8(ndr, "buffer", r->out.buffer, r->in.buffer_size); + ndr->depth--; + ndr_print_ptr(ndr, "needed", r->out.needed); + ndr->depth++; + ndr_print_uint32(ndr, "needed", *r->out.needed); + ndr->depth--; ndr_print_WERROR(ndr, "result", r->out.result); ndr->depth--; } @@ -629,6 +696,17 @@ _PUBLIC_ void ndr_print_svcctl_QueryServiceObjectSecurity(struct ndr_print *ndr, static enum ndr_err_code ndr_push_svcctl_SetServiceObjectSecurity(struct ndr_push *ndr, int flags, const struct svcctl_SetServiceObjectSecurity *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_uint32(ndr, NDR_SCALARS, r->in.security_flags)); + if (r->in.buffer == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buffer_size)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->in.buffer, r->in.buffer_size)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buffer_size)); } if (flags & NDR_OUT) { NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); @@ -638,7 +716,25 @@ static enum ndr_err_code ndr_push_svcctl_SetServiceObjectSecurity(struct ndr_pus static enum ndr_err_code ndr_pull_svcctl_SetServiceObjectSecurity(struct ndr_pull *ndr, int flags, struct svcctl_SetServiceObjectSecurity *r) { + TALLOC_CTX *_mem_save_handle_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_uint32(ndr, NDR_SCALARS, &r->in.security_flags)); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.buffer)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->in.buffer, ndr_get_array_size(ndr, &r->in.buffer)); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->in.buffer, ndr_get_array_size(ndr, &r->in.buffer))); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buffer_size)); + if (r->in.buffer) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->in.buffer, r->in.buffer_size)); + } } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); @@ -656,6 +752,16 @@ _PUBLIC_ void ndr_print_svcctl_SetServiceObjectSecurity(struct ndr_print *ndr, c if (flags & NDR_IN) { ndr_print_struct(ndr, "in", "svcctl_SetServiceObjectSecurity"); 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_uint32(ndr, "security_flags", r->in.security_flags); + ndr_print_ptr(ndr, "buffer", r->in.buffer); + ndr->depth++; + ndr_print_array_uint8(ndr, "buffer", r->in.buffer, r->in.buffer_size); + ndr->depth--; + ndr_print_uint32(ndr, "buffer_size", r->in.buffer_size); ndr->depth--; } if (flags & NDR_OUT) { diff --git a/source3/librpc/gen_ndr/ndr_unixinfo.c b/source3/librpc/gen_ndr/ndr_unixinfo.c deleted file mode 100644 index 03a8d30f03..0000000000 --- a/source3/librpc/gen_ndr/ndr_unixinfo.c +++ /dev/null @@ -1,538 +0,0 @@ -/* parser auto-generated by pidl */ - -#include "includes.h" -#include "librpc/gen_ndr/ndr_unixinfo.h" - -#include "librpc/gen_ndr/ndr_security.h" -static enum ndr_err_code ndr_push_unixinfo_GetPWUidInfo(struct ndr_push *ndr, int ndr_flags, const struct unixinfo_GetPWUidInfo *r) -{ - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->status)); - { - 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->homedir)); - ndr->flags = _flags_save_string; - } - { - 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->shell)); - ndr->flags = _flags_save_string; - } - } - if (ndr_flags & NDR_BUFFERS) { - } - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_pull_unixinfo_GetPWUidInfo(struct ndr_pull *ndr, int ndr_flags, struct unixinfo_GetPWUidInfo *r) -{ - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->status)); - { - 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->homedir)); - ndr->flags = _flags_save_string; - } - { - 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->shell)); - ndr->flags = _flags_save_string; - } - } - if (ndr_flags & NDR_BUFFERS) { - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_unixinfo_GetPWUidInfo(struct ndr_print *ndr, const char *name, const struct unixinfo_GetPWUidInfo *r) -{ - ndr_print_struct(ndr, name, "unixinfo_GetPWUidInfo"); - ndr->depth++; - ndr_print_NTSTATUS(ndr, "status", r->status); - ndr_print_string(ndr, "homedir", r->homedir); - ndr_print_string(ndr, "shell", r->shell); - ndr->depth--; -} - -static enum ndr_err_code ndr_push_unixinfo_SidToUid(struct ndr_push *ndr, int flags, const struct unixinfo_SidToUid *r) -{ - if (flags & NDR_IN) { - NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.sid)); - } - if (flags & NDR_OUT) { - if (r->out.uid == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); - } - NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, *r->out.uid)); - NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); - } - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_pull_unixinfo_SidToUid(struct ndr_pull *ndr, int flags, struct unixinfo_SidToUid *r) -{ - TALLOC_CTX *_mem_save_uid_0; - if (flags & NDR_IN) { - ZERO_STRUCT(r->out); - - NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.sid)); - NDR_PULL_ALLOC(ndr, r->out.uid); - ZERO_STRUCTP(r->out.uid); - } - if (flags & NDR_OUT) { - if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.uid); - } - _mem_save_uid_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.uid, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, r->out.uid)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_uid_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_unixinfo_SidToUid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_SidToUid *r) -{ - ndr_print_struct(ndr, name, "unixinfo_SidToUid"); - ndr->depth++; - if (flags & NDR_SET_VALUES) { - ndr->flags |= LIBNDR_PRINT_SET_VALUES; - } - if (flags & NDR_IN) { - ndr_print_struct(ndr, "in", "unixinfo_SidToUid"); - ndr->depth++; - ndr_print_dom_sid(ndr, "sid", &r->in.sid); - ndr->depth--; - } - if (flags & NDR_OUT) { - ndr_print_struct(ndr, "out", "unixinfo_SidToUid"); - ndr->depth++; - ndr_print_ptr(ndr, "uid", r->out.uid); - ndr->depth++; - ndr_print_hyper(ndr, "uid", *r->out.uid); - ndr->depth--; - ndr_print_NTSTATUS(ndr, "result", r->out.result); - ndr->depth--; - } - ndr->depth--; -} - -static enum ndr_err_code ndr_push_unixinfo_UidToSid(struct ndr_push *ndr, int flags, const struct unixinfo_UidToSid *r) -{ - if (flags & NDR_IN) { - NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->in.uid)); - } - if (flags & NDR_OUT) { - if (r->out.sid == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); - } - NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid)); - NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); - } - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_pull_unixinfo_UidToSid(struct ndr_pull *ndr, int flags, struct unixinfo_UidToSid *r) -{ - TALLOC_CTX *_mem_save_sid_0; - if (flags & NDR_IN) { - ZERO_STRUCT(r->out); - - NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->in.uid)); - NDR_PULL_ALLOC(ndr, r->out.sid); - ZERO_STRUCTP(r->out.sid); - } - if (flags & NDR_OUT) { - if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.sid); - } - _mem_save_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.sid, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sid_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_unixinfo_UidToSid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_UidToSid *r) -{ - ndr_print_struct(ndr, name, "unixinfo_UidToSid"); - ndr->depth++; - if (flags & NDR_SET_VALUES) { - ndr->flags |= LIBNDR_PRINT_SET_VALUES; - } - if (flags & NDR_IN) { - ndr_print_struct(ndr, "in", "unixinfo_UidToSid"); - ndr->depth++; - ndr_print_hyper(ndr, "uid", r->in.uid); - ndr->depth--; - } - if (flags & NDR_OUT) { - ndr_print_struct(ndr, "out", "unixinfo_UidToSid"); - ndr->depth++; - ndr_print_ptr(ndr, "sid", r->out.sid); - ndr->depth++; - ndr_print_dom_sid(ndr, "sid", r->out.sid); - ndr->depth--; - ndr_print_NTSTATUS(ndr, "result", r->out.result); - ndr->depth--; - } - ndr->depth--; -} - -static enum ndr_err_code ndr_push_unixinfo_SidToGid(struct ndr_push *ndr, int flags, const struct unixinfo_SidToGid *r) -{ - if (flags & NDR_IN) { - NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.sid)); - } - if (flags & NDR_OUT) { - if (r->out.gid == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); - } - NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, *r->out.gid)); - NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); - } - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_pull_unixinfo_SidToGid(struct ndr_pull *ndr, int flags, struct unixinfo_SidToGid *r) -{ - TALLOC_CTX *_mem_save_gid_0; - if (flags & NDR_IN) { - ZERO_STRUCT(r->out); - - NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.sid)); - NDR_PULL_ALLOC(ndr, r->out.gid); - ZERO_STRUCTP(r->out.gid); - } - if (flags & NDR_OUT) { - if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.gid); - } - _mem_save_gid_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.gid, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, r->out.gid)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_gid_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_unixinfo_SidToGid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_SidToGid *r) -{ - ndr_print_struct(ndr, name, "unixinfo_SidToGid"); - ndr->depth++; - if (flags & NDR_SET_VALUES) { - ndr->flags |= LIBNDR_PRINT_SET_VALUES; - } - if (flags & NDR_IN) { - ndr_print_struct(ndr, "in", "unixinfo_SidToGid"); - ndr->depth++; - ndr_print_dom_sid(ndr, "sid", &r->in.sid); - ndr->depth--; - } - if (flags & NDR_OUT) { - ndr_print_struct(ndr, "out", "unixinfo_SidToGid"); - ndr->depth++; - ndr_print_ptr(ndr, "gid", r->out.gid); - ndr->depth++; - ndr_print_hyper(ndr, "gid", *r->out.gid); - ndr->depth--; - ndr_print_NTSTATUS(ndr, "result", r->out.result); - ndr->depth--; - } - ndr->depth--; -} - -static enum ndr_err_code ndr_push_unixinfo_GidToSid(struct ndr_push *ndr, int flags, const struct unixinfo_GidToSid *r) -{ - if (flags & NDR_IN) { - NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->in.gid)); - } - if (flags & NDR_OUT) { - if (r->out.sid == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); - } - NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid)); - NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); - } - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_pull_unixinfo_GidToSid(struct ndr_pull *ndr, int flags, struct unixinfo_GidToSid *r) -{ - TALLOC_CTX *_mem_save_sid_0; - if (flags & NDR_IN) { - ZERO_STRUCT(r->out); - - NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->in.gid)); - NDR_PULL_ALLOC(ndr, r->out.sid); - ZERO_STRUCTP(r->out.sid); - } - if (flags & NDR_OUT) { - if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.sid); - } - _mem_save_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.sid, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sid_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_unixinfo_GidToSid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_GidToSid *r) -{ - ndr_print_struct(ndr, name, "unixinfo_GidToSid"); - ndr->depth++; - if (flags & NDR_SET_VALUES) { - ndr->flags |= LIBNDR_PRINT_SET_VALUES; - } - if (flags & NDR_IN) { - ndr_print_struct(ndr, "in", "unixinfo_GidToSid"); - ndr->depth++; - ndr_print_hyper(ndr, "gid", r->in.gid); - ndr->depth--; - } - if (flags & NDR_OUT) { - ndr_print_struct(ndr, "out", "unixinfo_GidToSid"); - ndr->depth++; - ndr_print_ptr(ndr, "sid", r->out.sid); - ndr->depth++; - ndr_print_dom_sid(ndr, "sid", r->out.sid); - ndr->depth--; - ndr_print_NTSTATUS(ndr, "result", r->out.result); - ndr->depth--; - } - ndr->depth--; -} - -static enum ndr_err_code ndr_push_unixinfo_GetPWUid(struct ndr_push *ndr, int flags, const struct unixinfo_GetPWUid *r) -{ - uint32_t cntr_uids_0; - uint32_t cntr_infos_0; - if (flags & NDR_IN) { - if (r->in.count == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); - } - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.count)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.count)); - for (cntr_uids_0 = 0; cntr_uids_0 < *r->in.count; cntr_uids_0++) { - NDR_CHECK(ndr_push_hyper(ndr, NDR_SCALARS, r->in.uids[cntr_uids_0])); - } - } - if (flags & NDR_OUT) { - if (r->out.count == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); - } - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.count)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.count)); - for (cntr_infos_0 = 0; cntr_infos_0 < *r->out.count; cntr_infos_0++) { - NDR_CHECK(ndr_push_unixinfo_GetPWUidInfo(ndr, NDR_SCALARS, &r->out.infos[cntr_infos_0])); - } - NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); - } - return NDR_ERR_SUCCESS; -} - -static enum ndr_err_code ndr_pull_unixinfo_GetPWUid(struct ndr_pull *ndr, int flags, struct unixinfo_GetPWUid *r) -{ - uint32_t cntr_uids_0; - uint32_t cntr_infos_0; - TALLOC_CTX *_mem_save_count_0; - TALLOC_CTX *_mem_save_uids_0; - TALLOC_CTX *_mem_save_infos_0; - if (flags & NDR_IN) { - ZERO_STRUCT(r->out); - - if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->in.count); - } - _mem_save_count_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->in.count, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.count)); - if (*r->in.count < 0 || *r->in.count > 1023) { - return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); - } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_array_size(ndr, &r->in.uids)); - NDR_PULL_ALLOC_N(ndr, r->in.uids, ndr_get_array_size(ndr, &r->in.uids)); - _mem_save_uids_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->in.uids, 0); - for (cntr_uids_0 = 0; cntr_uids_0 < *r->in.count; cntr_uids_0++) { - NDR_CHECK(ndr_pull_hyper(ndr, NDR_SCALARS, &r->in.uids[cntr_uids_0])); - } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_uids_0, 0); - NDR_PULL_ALLOC(ndr, r->out.count); - *r->out.count = *r->in.count; - if (r->in.uids) { - NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->in.uids, *r->in.count)); - } - } - if (flags & NDR_OUT) { - if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.count); - } - _mem_save_count_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.count, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.count)); - if (*r->out.count < 0 || *r->out.count > 1023) { - return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); - } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_count_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_array_size(ndr, &r->out.infos)); - NDR_PULL_ALLOC_N(ndr, r->out.infos, ndr_get_array_size(ndr, &r->out.infos)); - _mem_save_infos_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.infos, 0); - for (cntr_infos_0 = 0; cntr_infos_0 < *r->out.count; cntr_infos_0++) { - NDR_CHECK(ndr_pull_unixinfo_GetPWUidInfo(ndr, NDR_SCALARS, &r->out.infos[cntr_infos_0])); - } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_infos_0, 0); - NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); - if (r->out.infos) { - NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.infos, *r->out.count)); - } - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ void ndr_print_unixinfo_GetPWUid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_GetPWUid *r) -{ - uint32_t cntr_uids_0; - uint32_t cntr_infos_0; - ndr_print_struct(ndr, name, "unixinfo_GetPWUid"); - ndr->depth++; - if (flags & NDR_SET_VALUES) { - ndr->flags |= LIBNDR_PRINT_SET_VALUES; - } - if (flags & NDR_IN) { - ndr_print_struct(ndr, "in", "unixinfo_GetPWUid"); - ndr->depth++; - ndr_print_ptr(ndr, "count", r->in.count); - ndr->depth++; - ndr_print_uint32(ndr, "count", *r->in.count); - ndr->depth--; - ndr->print(ndr, "%s: ARRAY(%d)", "uids", *r->in.count); - ndr->depth++; - for (cntr_uids_0=0;cntr_uids_0<*r->in.count;cntr_uids_0++) { - char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_uids_0); - if (idx_0) { - ndr_print_hyper(ndr, "uids", r->in.uids[cntr_uids_0]); - free(idx_0); - } - } - ndr->depth--; - ndr->depth--; - } - if (flags & NDR_OUT) { - ndr_print_struct(ndr, "out", "unixinfo_GetPWUid"); - ndr->depth++; - ndr_print_ptr(ndr, "count", r->out.count); - ndr->depth++; - ndr_print_uint32(ndr, "count", *r->out.count); - ndr->depth--; - ndr->print(ndr, "%s: ARRAY(%d)", "infos", *r->out.count); - ndr->depth++; - for (cntr_infos_0=0;cntr_infos_0<*r->out.count;cntr_infos_0++) { - char *idx_0=NULL; - asprintf(&idx_0, "[%d]", cntr_infos_0); - if (idx_0) { - ndr_print_unixinfo_GetPWUidInfo(ndr, "infos", &r->out.infos[cntr_infos_0]); - free(idx_0); - } - } - ndr->depth--; - ndr_print_NTSTATUS(ndr, "result", r->out.result); - ndr->depth--; - } - ndr->depth--; -} - -static const struct ndr_interface_call unixinfo_calls[] = { - { - "unixinfo_SidToUid", - sizeof(struct unixinfo_SidToUid), - (ndr_push_flags_fn_t) ndr_push_unixinfo_SidToUid, - (ndr_pull_flags_fn_t) ndr_pull_unixinfo_SidToUid, - (ndr_print_function_t) ndr_print_unixinfo_SidToUid, - false, - }, - { - "unixinfo_UidToSid", - sizeof(struct unixinfo_UidToSid), - (ndr_push_flags_fn_t) ndr_push_unixinfo_UidToSid, - (ndr_pull_flags_fn_t) ndr_pull_unixinfo_UidToSid, - (ndr_print_function_t) ndr_print_unixinfo_UidToSid, - false, - }, - { - "unixinfo_SidToGid", - sizeof(struct unixinfo_SidToGid), - (ndr_push_flags_fn_t) ndr_push_unixinfo_SidToGid, - (ndr_pull_flags_fn_t) ndr_pull_unixinfo_SidToGid, - (ndr_print_function_t) ndr_print_unixinfo_SidToGid, - false, - }, - { - "unixinfo_GidToSid", - sizeof(struct unixinfo_GidToSid), - (ndr_push_flags_fn_t) ndr_push_unixinfo_GidToSid, - (ndr_pull_flags_fn_t) ndr_pull_unixinfo_GidToSid, - (ndr_print_function_t) ndr_print_unixinfo_GidToSid, - false, - }, - { - "unixinfo_GetPWUid", - sizeof(struct unixinfo_GetPWUid), - (ndr_push_flags_fn_t) ndr_push_unixinfo_GetPWUid, - (ndr_pull_flags_fn_t) ndr_pull_unixinfo_GetPWUid, - (ndr_print_function_t) ndr_print_unixinfo_GetPWUid, - false, - }, - { NULL, 0, NULL, NULL, NULL, false } -}; - -static const char * const unixinfo_endpoint_strings[] = { - "ncacn_np:[\\pipe\\unixinfo]", - "ncacn_ip_tcp:", - "ncalrpc:", -}; - -static const struct ndr_interface_string_array unixinfo_endpoints = { - .count = 3, - .names = unixinfo_endpoint_strings -}; - -static const char * const unixinfo_authservice_strings[] = { - "host", -}; - -static const struct ndr_interface_string_array unixinfo_authservices = { - .count = 3, - .names = unixinfo_authservice_strings -}; - - -const struct ndr_interface_table ndr_table_unixinfo = { - .name = "unixinfo", - .syntax_id = { - {0x9c54e310,0xa955,0x4885,{0xbd,0x31},{0x78,0x78,0x71,0x47,0xdf,0xa6}}, - NDR_UNIXINFO_VERSION - }, - .helpstring = NDR_UNIXINFO_HELPSTRING, - .num_calls = 5, - .calls = unixinfo_calls, - .endpoints = &unixinfo_endpoints, - .authservices = &unixinfo_authservices -}; - diff --git a/source3/librpc/gen_ndr/ndr_unixinfo.h b/source3/librpc/gen_ndr/ndr_unixinfo.h deleted file mode 100644 index 17f8b811db..0000000000 --- a/source3/librpc/gen_ndr/ndr_unixinfo.h +++ /dev/null @@ -1,31 +0,0 @@ -/* header auto-generated by pidl */ - -#include "librpc/ndr/libndr.h" -#include "librpc/gen_ndr/unixinfo.h" - -#ifndef _HEADER_NDR_unixinfo -#define _HEADER_NDR_unixinfo - -#define NDR_UNIXINFO_UUID "9c54e310-a955-4885-bd31-78787147dfa6" -#define NDR_UNIXINFO_VERSION 0.0 -#define NDR_UNIXINFO_NAME "unixinfo" -#define NDR_UNIXINFO_HELPSTRING "Unixinfo specific stuff" -extern const struct ndr_interface_table ndr_table_unixinfo; -#define NDR_UNIXINFO_SIDTOUID (0x00) - -#define NDR_UNIXINFO_UIDTOSID (0x01) - -#define NDR_UNIXINFO_SIDTOGID (0x02) - -#define NDR_UNIXINFO_GIDTOSID (0x03) - -#define NDR_UNIXINFO_GETPWUID (0x04) - -#define NDR_UNIXINFO_CALL_COUNT (5) -void ndr_print_unixinfo_GetPWUidInfo(struct ndr_print *ndr, const char *name, const struct unixinfo_GetPWUidInfo *r); -void ndr_print_unixinfo_SidToUid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_SidToUid *r); -void ndr_print_unixinfo_UidToSid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_UidToSid *r); -void ndr_print_unixinfo_SidToGid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_SidToGid *r); -void ndr_print_unixinfo_GidToSid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_GidToSid *r); -void ndr_print_unixinfo_GetPWUid(struct ndr_print *ndr, const char *name, int flags, const struct unixinfo_GetPWUid *r); -#endif /* _HEADER_NDR_unixinfo */ diff --git a/source3/librpc/gen_ndr/ndr_winreg.c b/source3/librpc/gen_ndr/ndr_winreg.c index b63d410587..cd16a141b0 100644 --- a/source3/librpc/gen_ndr/ndr_winreg.c +++ b/source3/librpc/gen_ndr/ndr_winreg.c @@ -3700,7 +3700,7 @@ static enum ndr_err_code ndr_pull_winreg_QueryMultipleValues(struct ndr_pull *nd NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.buffer_size)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_buffer_size_0, LIBNDR_FLAG_REF_ALLOC); NDR_PULL_ALLOC_N(ndr, r->out.values, r->in.num_values); - memcpy(r->out.values, r->in.values, r->in.num_values * sizeof(*r->in.values)); + memcpy(r->out.values, r->in.values, (r->in.num_values) * sizeof(*r->in.values)); NDR_PULL_ALLOC(ndr, r->out.buffer_size); *r->out.buffer_size = *r->in.buffer_size; if (r->in.values) { @@ -3798,8 +3798,7 @@ _PUBLIC_ void ndr_print_winreg_QueryMultipleValues(struct ndr_print *ndr, const ndr->depth++; for (cntr_values_1=0;cntr_values_1<r->in.num_values;cntr_values_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_values_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_values_1) != -1) { ndr_print_QueryMultipleValue(ndr, "values", &r->in.values[cntr_values_1]); free(idx_1); } @@ -3828,8 +3827,7 @@ _PUBLIC_ void ndr_print_winreg_QueryMultipleValues(struct ndr_print *ndr, const ndr->depth++; for (cntr_values_1=0;cntr_values_1<r->in.num_values;cntr_values_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_values_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_values_1) != -1) { ndr_print_QueryMultipleValue(ndr, "values", &r->out.values[cntr_values_1]); free(idx_1); } diff --git a/source3/librpc/gen_ndr/ndr_wkssvc.c b/source3/librpc/gen_ndr/ndr_wkssvc.c index 096c0b2c72..80ea67526e 100644 --- a/source3/librpc/gen_ndr/ndr_wkssvc.c +++ b/source3/librpc/gen_ndr/ndr_wkssvc.c @@ -3071,8 +3071,7 @@ _PUBLIC_ void ndr_print_wkssvc_NetWkstaEnumUsersCtr0(struct ndr_print *ndr, cons ndr->depth++; for (cntr_user0_1=0;cntr_user0_1<r->entries_read;cntr_user0_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_user0_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_user0_1) != -1) { ndr_print_wkssvc_NetrWkstaUserInfo0(ndr, "user0", &r->user0[cntr_user0_1]); free(idx_1); } @@ -3317,8 +3316,7 @@ _PUBLIC_ void ndr_print_wkssvc_NetWkstaEnumUsersCtr1(struct ndr_print *ndr, cons ndr->depth++; for (cntr_user1_1=0;cntr_user1_1<r->entries_read;cntr_user1_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_user1_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_user1_1) != -1) { ndr_print_wkssvc_NetrWkstaUserInfo1(ndr, "user1", &r->user1[cntr_user1_1]); free(idx_1); } @@ -3909,8 +3907,7 @@ _PUBLIC_ void ndr_print_wkssvc_NetWkstaTransportCtr0(struct ndr_print *ndr, cons ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_wkssvc_NetWkstaTransportInfo0(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -4867,8 +4864,7 @@ _PUBLIC_ void ndr_print_wkssvc_NetrUseEnumCtr2(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_wkssvc_NetrUseInfo2(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -4954,8 +4950,7 @@ _PUBLIC_ void ndr_print_wkssvc_NetrUseEnumCtr1(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_wkssvc_NetrUseInfo1(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -5041,8 +5036,7 @@ _PUBLIC_ void ndr_print_wkssvc_NetrUseEnumCtr0(struct ndr_print *ndr, const char ndr->depth++; for (cntr_array_1=0;cntr_array_1<r->count;cntr_array_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_array_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_array_1) != -1) { ndr_print_wkssvc_NetrUseInfo0(ndr, "array", &r->array[cntr_array_1]); free(idx_1); } @@ -5666,8 +5660,7 @@ _PUBLIC_ void ndr_print_wkssvc_ComputerNamesCtr(struct ndr_print *ndr, const cha ndr->depth++; for (cntr_computer_name_1=0;cntr_computer_name_1<r->count;cntr_computer_name_1++) { char *idx_1=NULL; - asprintf(&idx_1, "[%d]", cntr_computer_name_1); - if (idx_1) { + if (asprintf(&idx_1, "[%d]", cntr_computer_name_1) != -1) { ndr_print_lsa_String(ndr, "computer_name", &r->computer_name[cntr_computer_name_1]); free(idx_1); } @@ -8836,8 +8829,7 @@ _PUBLIC_ void ndr_print_wkssvc_NetrGetJoinableOus(struct ndr_print *ndr, const c ndr->depth++; for (cntr_ous_2=0;cntr_ous_2<*r->out.num_ous;cntr_ous_2++) { char *idx_2=NULL; - asprintf(&idx_2, "[%d]", cntr_ous_2); - if (idx_2) { + if (asprintf(&idx_2, "[%d]", cntr_ous_2) != -1) { ndr_print_ptr(ndr, "ous", (*r->out.ous)[cntr_ous_2]); ndr->depth++; if ((*r->out.ous)[cntr_ous_2]) { @@ -9757,8 +9749,7 @@ _PUBLIC_ void ndr_print_wkssvc_NetrGetJoinableOus2(struct ndr_print *ndr, const ndr->depth++; for (cntr_ous_2=0;cntr_ous_2<*r->out.num_ous;cntr_ous_2++) { char *idx_2=NULL; - asprintf(&idx_2, "[%d]", cntr_ous_2); - if (idx_2) { + if (asprintf(&idx_2, "[%d]", cntr_ous_2) != -1) { ndr_print_ptr(ndr, "ous", (*r->out.ous)[cntr_ous_2]); ndr->depth++; if ((*r->out.ous)[cntr_ous_2]) { diff --git a/source3/librpc/gen_ndr/ndr_xattr.c b/source3/librpc/gen_ndr/ndr_xattr.c index 425ad814bf..46c4249d21 100644 --- a/source3/librpc/gen_ndr/ndr_xattr.c +++ b/source3/librpc/gen_ndr/ndr_xattr.c @@ -91,8 +91,7 @@ _PUBLIC_ void ndr_print_tdb_xattrs(struct ndr_print *ndr, const char *name, cons 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) { + if (asprintf(&idx_0, "[%d]", cntr_xattrs_0) != -1) { ndr_print_tdb_xattr(ndr, "xattrs", &r->xattrs[cntr_xattrs_0]); free(idx_0); } diff --git a/source3/librpc/gen_ndr/netlogon.h b/source3/librpc/gen_ndr/netlogon.h index ef2218c0f2..058e5e7fb0 100644 --- a/source3/librpc/gen_ndr/netlogon.h +++ b/source3/librpc/gen_ndr/netlogon.h @@ -603,6 +603,7 @@ union netr_CONTROL_QUERY_INFORMATION { enum netr_LogonControlCode #ifndef USE_UINT_ENUMS { + NETLOGON_CONTROL_SYNC=2, NETLOGON_CONTROL_REDISCOVER=5, NETLOGON_CONTROL_TC_QUERY=6, NETLOGON_CONTROL_TRANSPORT_NOTIFY=7, @@ -610,6 +611,7 @@ enum netr_LogonControlCode } #else { __donnot_use_enum_netr_LogonControlCode=0x7FFFFFFF} +#define NETLOGON_CONTROL_SYNC ( 2 ) #define NETLOGON_CONTROL_REDISCOVER ( 5 ) #define NETLOGON_CONTROL_TC_QUERY ( 6 ) #define NETLOGON_CONTROL_TRANSPORT_NOTIFY ( 7 ) @@ -849,7 +851,7 @@ struct netr_LogonSamLogon { const char *computer_name;/* [unique,charset(UTF16)] */ struct netr_Authenticator *credential;/* [unique] */ uint16_t logon_level; - union netr_LogonLevel logon;/* [switch_is(logon_level)] */ + union netr_LogonLevel *logon;/* [ref,switch_is(logon_level)] */ uint16_t validation_level; struct netr_Authenticator *return_authenticator;/* [unique] */ } in; @@ -890,7 +892,7 @@ struct netr_ServerReqChallenge { } in; struct { - struct netr_Credential *credentials;/* [ref] */ + struct netr_Credential *return_credentials;/* [ref] */ NTSTATUS result; } out; @@ -907,7 +909,7 @@ struct netr_ServerAuthenticate { } in; struct { - struct netr_Credential *credentials;/* [ref] */ + struct netr_Credential *return_credentials;/* [ref] */ NTSTATUS result; } out; @@ -920,8 +922,8 @@ struct netr_ServerPasswordSet { const char *account_name;/* [charset(UTF16)] */ enum netr_SchannelType secure_channel_type; const char *computer_name;/* [charset(UTF16)] */ - struct netr_Authenticator credential; - struct samr_Password new_password; + struct netr_Authenticator *credential;/* [ref] */ + struct samr_Password *new_password;/* [ref] */ } in; struct { @@ -936,7 +938,7 @@ struct netr_DatabaseDeltas { struct { const char *logon_server;/* [charset(UTF16)] */ const char *computername;/* [charset(UTF16)] */ - struct netr_Authenticator credential; + struct netr_Authenticator *credential;/* [ref] */ enum netr_SamDatabaseID database_id; uint32_t preferredmaximumlength; struct netr_Authenticator *return_authenticator;/* [ref] */ @@ -944,7 +946,7 @@ struct netr_DatabaseDeltas { } in; struct { - struct netr_DELTA_ENUM_ARRAY *delta_enum_array;/* [ref] */ + struct netr_DELTA_ENUM_ARRAY **delta_enum_array;/* [ref] */ struct netr_Authenticator *return_authenticator;/* [ref] */ uint64_t *sequence_num;/* [ref] */ NTSTATUS result; @@ -1071,7 +1073,7 @@ struct netr_LogonControl2 { const char *logon_server;/* [unique,charset(UTF16)] */ uint32_t function_code; uint32_t level; - union netr_CONTROL_DATA_INFORMATION data;/* [switch_is(function_code)] */ + union netr_CONTROL_DATA_INFORMATION *data;/* [ref,switch_is(function_code)] */ } in; struct { @@ -1093,7 +1095,7 @@ struct netr_ServerAuthenticate2 { } in; struct { - struct netr_Credential *credentials;/* [ref] */ + struct netr_Credential *return_credentials;/* [ref] */ uint32_t *negotiate_flags;/* [ref] */ NTSTATUS result; } out; @@ -1105,7 +1107,7 @@ struct netr_DatabaseSync2 { struct { const char *logon_server;/* [charset(UTF16)] */ const char *computername;/* [charset(UTF16)] */ - struct netr_Authenticator credential; + struct netr_Authenticator *credential;/* [ref] */ enum netr_SamDatabaseID database_id; uint16_t restart_state; uint32_t preferredmaximumlength; @@ -1114,7 +1116,7 @@ struct netr_DatabaseSync2 { } in; struct { - struct netr_DELTA_ENUM_ARRAY *delta_enum_array;/* [ref] */ + struct netr_DELTA_ENUM_ARRAY **delta_enum_array;/* [ref] */ struct netr_Authenticator *return_authenticator;/* [ref] */ uint32_t *sync_context;/* [ref] */ NTSTATUS result; @@ -1435,7 +1437,7 @@ struct netr_LogonSamLogonEx { const char *server_name;/* [unique,charset(UTF16)] */ const char *computer_name;/* [unique,charset(UTF16)] */ uint16_t logon_level; - union netr_LogonLevel logon;/* [switch_is(logon_level)] */ + union netr_LogonLevel *logon;/* [ref,switch_is(logon_level)] */ uint16_t validation_level; uint32_t *flags;/* [ref] */ } in; diff --git a/source3/librpc/gen_ndr/ntsvcs.h b/source3/librpc/gen_ndr/ntsvcs.h new file mode 100644 index 0000000000..9cdfa656b4 --- /dev/null +++ b/source3/librpc/gen_ndr/ntsvcs.h @@ -0,0 +1,568 @@ +/* header auto-generated by pidl */ + +#include <stdint.h> + +#ifndef _HEADER_ntsvcs +#define _HEADER_ntsvcs + +struct PNP_HwProfInfo { + uint32_t unknown1; + uint16_t unknown2[160]; + uint32_t unknown3; +}; + + +struct PNP_Disconnect { + struct { + WERROR result; + } out; + +}; + + +struct PNP_Connect { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetVersion { + struct { + uint16_t *version;/* [ref] */ + WERROR result; + } out; + +}; + + +struct PNP_GetGlobalState { + struct { + WERROR result; + } out; + +}; + + +struct PNP_InitDetection { + struct { + WERROR result; + } out; + +}; + + +struct PNP_ReportLogOn { + struct { + WERROR result; + } out; + +}; + + +struct PNP_ValidateDeviceInstance { + struct { + const char *devicepath;/* [ref,charset(UTF16)] */ + uint32_t flags; + } in; + + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetRootDeviceInstance { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetRelatedDeviceInstance { + struct { + WERROR result; + } out; + +}; + + +struct PNP_EnumerateSubKeys { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetDeviceList { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetDeviceListSize { + struct { + const char *devicename;/* [unique,charset(UTF16)] */ + uint32_t flags; + } in; + + struct { + uint32_t *size;/* [ref] */ + WERROR result; + } out; + +}; + + +struct PNP_GetDepth { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetDeviceRegProp { + struct { + WERROR result; + } out; + +}; + + +struct PNP_SetDeviceRegProp { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetClassInstance { + struct { + WERROR result; + } out; + +}; + + +struct PNP_CreateKey { + struct { + WERROR result; + } out; + +}; + + +struct PNP_DeleteRegistryKey { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetClassCount { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetClassName { + struct { + WERROR result; + } out; + +}; + + +struct PNP_DeleteClassKey { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetInterfaceDeviceAlias { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetInterfaceDeviceList { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetInterfaceDeviceListSize { + struct { + WERROR result; + } out; + +}; + + +struct PNP_RegisterDeviceClassAssociation { + struct { + WERROR result; + } out; + +}; + + +struct PNP_UnregisterDeviceClassAssociation { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetClassRegProp { + struct { + WERROR result; + } out; + +}; + + +struct PNP_SetClassRegProp { + struct { + WERROR result; + } out; + +}; + + +struct PNP_CreateDevInst { + struct { + WERROR result; + } out; + +}; + + +struct PNP_DeviceInstanceAction { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetDeviceStatus { + struct { + WERROR result; + } out; + +}; + + +struct PNP_SetDeviceProblem { + struct { + WERROR result; + } out; + +}; + + +struct PNP_DisableDevInst { + struct { + WERROR result; + } out; + +}; + + +struct PNP_UninstallDevInst { + struct { + WERROR result; + } out; + +}; + + +struct PNP_AddID { + struct { + WERROR result; + } out; + +}; + + +struct PNP_RegisterDriver { + struct { + WERROR result; + } out; + +}; + + +struct PNP_QueryRemove { + struct { + WERROR result; + } out; + +}; + + +struct PNP_RequestDeviceEject { + struct { + WERROR result; + } out; + +}; + + +struct PNP_IsDockStationPresent { + struct { + WERROR result; + } out; + +}; + + +struct PNP_RequestEjectPC { + struct { + WERROR result; + } out; + +}; + + +struct PNP_HwProfFlags { + struct { + uint32_t unknown1; + const char *devicepath;/* [ref,charset(UTF16)] */ + uint32_t unknown2; + const char *unknown5;/* [unique,charset(UTF16)] */ + uint32_t unknown6; + uint32_t unknown7; + uint32_t *unknown3;/* [ref] */ + uint16_t *unknown4;/* [unique] */ + } in; + + struct { + const char **unknown5a;/* [unique,charset(UTF16)] */ + uint32_t *unknown3;/* [ref] */ + uint16_t *unknown4;/* [unique] */ + WERROR result; + } out; + +}; + + +struct PNP_GetHwProfInfo { + struct { + uint32_t idx; + uint32_t unknown1; + uint32_t unknown2; + struct PNP_HwProfInfo *info;/* [ref] */ + } in; + + struct { + struct PNP_HwProfInfo *info;/* [ref] */ + WERROR result; + } out; + +}; + + +struct PNP_AddEmptyLogConf { + struct { + WERROR result; + } out; + +}; + + +struct PNP_FreeLogConf { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetFirstLogConf { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetNextLogConf { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetLogConfPriority { + struct { + WERROR result; + } out; + +}; + + +struct PNP_AddResDes { + struct { + WERROR result; + } out; + +}; + + +struct PNP_FreeResDes { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetNextResDes { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetResDesData { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetResDesDataSize { + struct { + WERROR result; + } out; + +}; + + +struct PNP_ModifyResDes { + struct { + WERROR result; + } out; + +}; + + +struct PNP_DetectResourceLimit { + struct { + WERROR result; + } out; + +}; + + +struct PNP_QueryResConfList { + struct { + WERROR result; + } out; + +}; + + +struct PNP_SetHwProf { + struct { + WERROR result; + } out; + +}; + + +struct PNP_QueryArbitratorFreeData { + struct { + WERROR result; + } out; + +}; + + +struct PNP_QueryArbitratorFreeSize { + struct { + WERROR result; + } out; + +}; + + +struct PNP_RunDetection { + struct { + WERROR result; + } out; + +}; + + +struct PNP_RegisterNotification { + struct { + WERROR result; + } out; + +}; + + +struct PNP_UnregisterNotification { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetCustomDevProp { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetVersionInternal { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetBlockedDriverInfo { + struct { + WERROR result; + } out; + +}; + + +struct PNP_GetServerSideDeviceInstallFlags { + struct { + WERROR result; + } out; + +}; + +#endif /* _HEADER_ntsvcs */ diff --git a/source3/librpc/gen_ndr/samr.h b/source3/librpc/gen_ndr/samr.h index dff4bf80f0..c0e2d9d9a9 100644 --- a/source3/librpc/gen_ndr/samr.h +++ b/source3/librpc/gen_ndr/samr.h @@ -8,7 +8,11 @@ #ifndef _HEADER_samr #define _HEADER_samr +#define MAX_SAM_ENTRIES_W2K ( 0x400 ) +#define MAX_SAM_ENTRIES_W95 ( 50 ) #define SAMR_ENUM_USERS_MULTIPLIER ( 54 ) +#define PASS_MUST_CHANGE_AT_NEXT_LOGON ( 0x01 ) +#define PASS_DONT_CHANGE_AT_NEXT_LOGON ( 0x00 ) /* bitmap samr_AcctFlags */ #define ACB_DISABLED ( 0x00000001 ) #define ACB_HOMDIRREQ ( 0x00000002 ) @@ -590,7 +594,7 @@ struct samr_DispInfoFullGroups { struct samr_DispEntryAscii { uint32_t idx; - struct lsa_AsciiString account_name; + struct lsa_AsciiStringLarge account_name; }; struct samr_DispInfoAscii { diff --git a/source3/librpc/gen_ndr/srv_lsa.c b/source3/librpc/gen_ndr/srv_lsa.c index b4600017bc..1ce0448469 100644 --- a/source3/librpc/gen_ndr/srv_lsa.c +++ b/source3/librpc/gen_ndr/srv_lsa.c @@ -1128,7 +1128,7 @@ static bool api_lsa_LookupNames(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.domains = talloc_zero(r, struct lsa_RefDomainList); + r->out.domains = talloc_zero(r, struct lsa_RefDomainList *); if (r->out.domains == NULL) { talloc_free(r); return false; @@ -1210,7 +1210,7 @@ static bool api_lsa_LookupSids(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.domains = talloc_zero(r, struct lsa_RefDomainList); + r->out.domains = talloc_zero(r, struct lsa_RefDomainList *); if (r->out.domains == NULL) { talloc_free(r); return false; @@ -1452,7 +1452,7 @@ static bool api_lsa_EnumPrivsAccount(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.privs = talloc_zero(r, struct lsa_PrivilegeSet); + r->out.privs = talloc_zero(r, struct lsa_PrivilegeSet *); if (r->out.privs == NULL) { talloc_free(r); return false; @@ -4437,7 +4437,7 @@ static bool api_lsa_LookupSids2(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.domains = talloc_zero(r, struct lsa_RefDomainList); + r->out.domains = talloc_zero(r, struct lsa_RefDomainList *); if (r->out.domains == NULL) { talloc_free(r); return false; @@ -4519,7 +4519,7 @@ static bool api_lsa_LookupNames2(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.domains = talloc_zero(r, struct lsa_RefDomainList); + r->out.domains = talloc_zero(r, struct lsa_RefDomainList *); if (r->out.domains == NULL) { talloc_free(r); return false; @@ -5258,7 +5258,7 @@ static bool api_lsa_LookupNames3(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.domains = talloc_zero(r, struct lsa_RefDomainList); + r->out.domains = talloc_zero(r, struct lsa_RefDomainList *); if (r->out.domains == NULL) { talloc_free(r); return false; @@ -5858,7 +5858,7 @@ static bool api_lsa_LookupSids3(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.domains = talloc_zero(r, struct lsa_RefDomainList); + r->out.domains = talloc_zero(r, struct lsa_RefDomainList *); if (r->out.domains == NULL) { talloc_free(r); return false; @@ -5940,7 +5940,7 @@ static bool api_lsa_LookupNames4(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.domains = talloc_zero(r, struct lsa_RefDomainList); + r->out.domains = talloc_zero(r, struct lsa_RefDomainList *); if (r->out.domains == NULL) { talloc_free(r); return false; diff --git a/source3/librpc/gen_ndr/srv_netlogon.c b/source3/librpc/gen_ndr/srv_netlogon.c index 808493463a..67876f11ef 100644 --- a/source3/librpc/gen_ndr/srv_netlogon.c +++ b/source3/librpc/gen_ndr/srv_netlogon.c @@ -367,7 +367,12 @@ static bool api_netr_ServerReqChallenge(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.credentials = r->in.credentials; + r->out.return_credentials = talloc_zero(r, struct netr_Credential); + if (r->out.return_credentials == NULL) { + talloc_free(r); + return false; + } + r->out.result = _netr_ServerReqChallenge(p, r); if (p->rng_fault_state) { @@ -442,7 +447,12 @@ static bool api_netr_ServerAuthenticate(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.credentials = r->in.credentials; + r->out.return_credentials = talloc_zero(r, struct netr_Credential); + if (r->out.return_credentials == NULL) { + talloc_free(r); + return false; + } + r->out.result = _netr_ServerAuthenticate(p, r); if (p->rng_fault_state) { @@ -599,7 +609,7 @@ static bool api_netr_DatabaseDeltas(pipes_struct *p) ZERO_STRUCT(r->out); r->out.return_authenticator = r->in.return_authenticator; r->out.sequence_num = r->in.sequence_num; - r->out.delta_enum_array = talloc_zero(r, struct netr_DELTA_ENUM_ARRAY); + r->out.delta_enum_array = talloc_zero(r, struct netr_DELTA_ENUM_ARRAY *); if (r->out.delta_enum_array == NULL) { talloc_free(r); return false; @@ -1280,7 +1290,12 @@ static bool api_netr_ServerAuthenticate2(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.credentials = r->in.credentials; + r->out.return_credentials = talloc_zero(r, struct netr_Credential); + if (r->out.return_credentials == NULL) { + talloc_free(r); + return false; + } + r->out.negotiate_flags = r->in.negotiate_flags; r->out.result = _netr_ServerAuthenticate2(p, r); @@ -1358,7 +1373,7 @@ static bool api_netr_DatabaseSync2(pipes_struct *p) ZERO_STRUCT(r->out); r->out.return_authenticator = r->in.return_authenticator; r->out.sync_context = r->in.sync_context; - r->out.delta_enum_array = talloc_zero(r, struct netr_DELTA_ENUM_ARRAY); + r->out.delta_enum_array = talloc_zero(r, struct netr_DELTA_ENUM_ARRAY *); if (r->out.delta_enum_array == NULL) { talloc_free(r); return false; diff --git a/source3/librpc/gen_ndr/srv_ntsvcs.c b/source3/librpc/gen_ndr/srv_ntsvcs.c new file mode 100644 index 0000000000..339de6c747 --- /dev/null +++ b/source3/librpc/gen_ndr/srv_ntsvcs.c @@ -0,0 +1,4859 @@ +/* + * Unix SMB/CIFS implementation. + * server auto-generated by pidl. DO NOT MODIFY! + */ + +#include "includes.h" +#include "librpc/gen_ndr/srv_ntsvcs.h" + +static bool api_PNP_Disconnect(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_Disconnect *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_DISCONNECT]; + + r = talloc(talloc_tos(), struct PNP_Disconnect); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_Disconnect, r); + } + + r->out.result = _PNP_Disconnect(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_Disconnect, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_Connect(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_Connect *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_CONNECT]; + + r = talloc(talloc_tos(), struct PNP_Connect); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_Connect, r); + } + + r->out.result = _PNP_Connect(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_Connect, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetVersion(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetVersion *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETVERSION]; + + r = talloc(talloc_tos(), struct PNP_GetVersion); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetVersion, r); + } + + ZERO_STRUCT(r->out); + r->out.version = talloc_zero(r, uint16_t); + if (r->out.version == NULL) { + talloc_free(r); + return false; + } + + r->out.result = _PNP_GetVersion(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetVersion, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetGlobalState(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetGlobalState *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETGLOBALSTATE]; + + r = talloc(talloc_tos(), struct PNP_GetGlobalState); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetGlobalState, r); + } + + r->out.result = _PNP_GetGlobalState(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetGlobalState, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_InitDetection(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_InitDetection *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_INITDETECTION]; + + r = talloc(talloc_tos(), struct PNP_InitDetection); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_InitDetection, r); + } + + r->out.result = _PNP_InitDetection(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_InitDetection, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_ReportLogOn(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_ReportLogOn *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_REPORTLOGON]; + + r = talloc(talloc_tos(), struct PNP_ReportLogOn); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_ReportLogOn, r); + } + + r->out.result = _PNP_ReportLogOn(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_ReportLogOn, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_ValidateDeviceInstance(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_ValidateDeviceInstance *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_VALIDATEDEVICEINSTANCE]; + + r = talloc(talloc_tos(), struct PNP_ValidateDeviceInstance); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_ValidateDeviceInstance, r); + } + + r->out.result = _PNP_ValidateDeviceInstance(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_ValidateDeviceInstance, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetRootDeviceInstance(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetRootDeviceInstance *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETROOTDEVICEINSTANCE]; + + r = talloc(talloc_tos(), struct PNP_GetRootDeviceInstance); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetRootDeviceInstance, r); + } + + r->out.result = _PNP_GetRootDeviceInstance(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetRootDeviceInstance, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetRelatedDeviceInstance(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetRelatedDeviceInstance *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETRELATEDDEVICEINSTANCE]; + + r = talloc(talloc_tos(), struct PNP_GetRelatedDeviceInstance); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetRelatedDeviceInstance, r); + } + + r->out.result = _PNP_GetRelatedDeviceInstance(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetRelatedDeviceInstance, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_EnumerateSubKeys(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_EnumerateSubKeys *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_ENUMERATESUBKEYS]; + + r = talloc(talloc_tos(), struct PNP_EnumerateSubKeys); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_EnumerateSubKeys, r); + } + + r->out.result = _PNP_EnumerateSubKeys(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_EnumerateSubKeys, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetDeviceList(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetDeviceList *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETDEVICELIST]; + + r = talloc(talloc_tos(), struct PNP_GetDeviceList); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDeviceList, r); + } + + r->out.result = _PNP_GetDeviceList(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDeviceList, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetDeviceListSize(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetDeviceListSize *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETDEVICELISTSIZE]; + + r = talloc(talloc_tos(), struct PNP_GetDeviceListSize); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDeviceListSize, r); + } + + ZERO_STRUCT(r->out); + r->out.size = talloc_zero(r, uint32_t); + if (r->out.size == NULL) { + talloc_free(r); + return false; + } + + r->out.result = _PNP_GetDeviceListSize(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDeviceListSize, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetDepth(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetDepth *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETDEPTH]; + + r = talloc(talloc_tos(), struct PNP_GetDepth); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDepth, r); + } + + r->out.result = _PNP_GetDepth(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDepth, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetDeviceRegProp(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetDeviceRegProp *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETDEVICEREGPROP]; + + r = talloc(talloc_tos(), struct PNP_GetDeviceRegProp); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDeviceRegProp, r); + } + + r->out.result = _PNP_GetDeviceRegProp(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDeviceRegProp, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_SetDeviceRegProp(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_SetDeviceRegProp *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_SETDEVICEREGPROP]; + + r = talloc(talloc_tos(), struct PNP_SetDeviceRegProp); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_SetDeviceRegProp, r); + } + + r->out.result = _PNP_SetDeviceRegProp(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_SetDeviceRegProp, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetClassInstance(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetClassInstance *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETCLASSINSTANCE]; + + r = talloc(talloc_tos(), struct PNP_GetClassInstance); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetClassInstance, r); + } + + r->out.result = _PNP_GetClassInstance(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetClassInstance, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_CreateKey(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_CreateKey *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_CREATEKEY]; + + r = talloc(talloc_tos(), struct PNP_CreateKey); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_CreateKey, r); + } + + r->out.result = _PNP_CreateKey(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_CreateKey, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_DeleteRegistryKey(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_DeleteRegistryKey *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_DELETEREGISTRYKEY]; + + r = talloc(talloc_tos(), struct PNP_DeleteRegistryKey); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DeleteRegistryKey, r); + } + + r->out.result = _PNP_DeleteRegistryKey(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DeleteRegistryKey, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetClassCount(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetClassCount *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETCLASSCOUNT]; + + r = talloc(talloc_tos(), struct PNP_GetClassCount); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetClassCount, r); + } + + r->out.result = _PNP_GetClassCount(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetClassCount, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetClassName(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetClassName *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETCLASSNAME]; + + r = talloc(talloc_tos(), struct PNP_GetClassName); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetClassName, r); + } + + r->out.result = _PNP_GetClassName(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetClassName, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_DeleteClassKey(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_DeleteClassKey *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_DELETECLASSKEY]; + + r = talloc(talloc_tos(), struct PNP_DeleteClassKey); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DeleteClassKey, r); + } + + r->out.result = _PNP_DeleteClassKey(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DeleteClassKey, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetInterfaceDeviceAlias(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetInterfaceDeviceAlias *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETINTERFACEDEVICEALIAS]; + + r = talloc(talloc_tos(), struct PNP_GetInterfaceDeviceAlias); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetInterfaceDeviceAlias, r); + } + + r->out.result = _PNP_GetInterfaceDeviceAlias(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetInterfaceDeviceAlias, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetInterfaceDeviceList(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetInterfaceDeviceList *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETINTERFACEDEVICELIST]; + + r = talloc(talloc_tos(), struct PNP_GetInterfaceDeviceList); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetInterfaceDeviceList, r); + } + + r->out.result = _PNP_GetInterfaceDeviceList(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetInterfaceDeviceList, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetInterfaceDeviceListSize(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetInterfaceDeviceListSize *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETINTERFACEDEVICELISTSIZE]; + + r = talloc(talloc_tos(), struct PNP_GetInterfaceDeviceListSize); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetInterfaceDeviceListSize, r); + } + + r->out.result = _PNP_GetInterfaceDeviceListSize(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetInterfaceDeviceListSize, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_RegisterDeviceClassAssociation(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_RegisterDeviceClassAssociation *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_REGISTERDEVICECLASSASSOCIATION]; + + r = talloc(talloc_tos(), struct PNP_RegisterDeviceClassAssociation); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RegisterDeviceClassAssociation, r); + } + + r->out.result = _PNP_RegisterDeviceClassAssociation(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RegisterDeviceClassAssociation, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_UnregisterDeviceClassAssociation(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_UnregisterDeviceClassAssociation *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_UNREGISTERDEVICECLASSASSOCIATION]; + + r = talloc(talloc_tos(), struct PNP_UnregisterDeviceClassAssociation); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_UnregisterDeviceClassAssociation, r); + } + + r->out.result = _PNP_UnregisterDeviceClassAssociation(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_UnregisterDeviceClassAssociation, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetClassRegProp(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetClassRegProp *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETCLASSREGPROP]; + + r = talloc(talloc_tos(), struct PNP_GetClassRegProp); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetClassRegProp, r); + } + + r->out.result = _PNP_GetClassRegProp(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetClassRegProp, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_SetClassRegProp(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_SetClassRegProp *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_SETCLASSREGPROP]; + + r = talloc(talloc_tos(), struct PNP_SetClassRegProp); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_SetClassRegProp, r); + } + + r->out.result = _PNP_SetClassRegProp(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_SetClassRegProp, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_CreateDevInst(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_CreateDevInst *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_CREATEDEVINST]; + + r = talloc(talloc_tos(), struct PNP_CreateDevInst); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_CreateDevInst, r); + } + + r->out.result = _PNP_CreateDevInst(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_CreateDevInst, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_DeviceInstanceAction(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_DeviceInstanceAction *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_DEVICEINSTANCEACTION]; + + r = talloc(talloc_tos(), struct PNP_DeviceInstanceAction); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DeviceInstanceAction, r); + } + + r->out.result = _PNP_DeviceInstanceAction(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DeviceInstanceAction, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetDeviceStatus(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetDeviceStatus *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETDEVICESTATUS]; + + r = talloc(talloc_tos(), struct PNP_GetDeviceStatus); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetDeviceStatus, r); + } + + r->out.result = _PNP_GetDeviceStatus(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetDeviceStatus, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_SetDeviceProblem(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_SetDeviceProblem *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_SETDEVICEPROBLEM]; + + r = talloc(talloc_tos(), struct PNP_SetDeviceProblem); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_SetDeviceProblem, r); + } + + r->out.result = _PNP_SetDeviceProblem(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_SetDeviceProblem, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_DisableDevInst(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_DisableDevInst *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_DISABLEDEVINST]; + + r = talloc(talloc_tos(), struct PNP_DisableDevInst); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DisableDevInst, r); + } + + r->out.result = _PNP_DisableDevInst(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DisableDevInst, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_UninstallDevInst(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_UninstallDevInst *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_UNINSTALLDEVINST]; + + r = talloc(talloc_tos(), struct PNP_UninstallDevInst); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_UninstallDevInst, r); + } + + r->out.result = _PNP_UninstallDevInst(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_UninstallDevInst, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_AddID(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_AddID *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_ADDID]; + + r = talloc(talloc_tos(), struct PNP_AddID); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_AddID, r); + } + + r->out.result = _PNP_AddID(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_AddID, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_RegisterDriver(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_RegisterDriver *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_REGISTERDRIVER]; + + r = talloc(talloc_tos(), struct PNP_RegisterDriver); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RegisterDriver, r); + } + + r->out.result = _PNP_RegisterDriver(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RegisterDriver, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_QueryRemove(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_QueryRemove *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_QUERYREMOVE]; + + r = talloc(talloc_tos(), struct PNP_QueryRemove); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_QueryRemove, r); + } + + r->out.result = _PNP_QueryRemove(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_QueryRemove, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_RequestDeviceEject(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_RequestDeviceEject *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_REQUESTDEVICEEJECT]; + + r = talloc(talloc_tos(), struct PNP_RequestDeviceEject); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RequestDeviceEject, r); + } + + r->out.result = _PNP_RequestDeviceEject(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RequestDeviceEject, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_IsDockStationPresent(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_IsDockStationPresent *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_ISDOCKSTATIONPRESENT]; + + r = talloc(talloc_tos(), struct PNP_IsDockStationPresent); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_IsDockStationPresent, r); + } + + r->out.result = _PNP_IsDockStationPresent(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_IsDockStationPresent, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_RequestEjectPC(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_RequestEjectPC *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_REQUESTEJECTPC]; + + r = talloc(talloc_tos(), struct PNP_RequestEjectPC); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RequestEjectPC, r); + } + + r->out.result = _PNP_RequestEjectPC(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RequestEjectPC, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_HwProfFlags(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_HwProfFlags *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_HWPROFFLAGS]; + + r = talloc(talloc_tos(), struct PNP_HwProfFlags); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_HwProfFlags, r); + } + + ZERO_STRUCT(r->out); + r->out.unknown3 = r->in.unknown3; + r->out.unknown4 = r->in.unknown4; + r->out.unknown5a = talloc_zero(r, const char *); + if (r->out.unknown5a == NULL) { + talloc_free(r); + return false; + } + + r->out.result = _PNP_HwProfFlags(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_HwProfFlags, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetHwProfInfo(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetHwProfInfo *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETHWPROFINFO]; + + r = talloc(talloc_tos(), struct PNP_GetHwProfInfo); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetHwProfInfo, r); + } + + ZERO_STRUCT(r->out); + r->out.info = r->in.info; + r->out.result = _PNP_GetHwProfInfo(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetHwProfInfo, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_AddEmptyLogConf(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_AddEmptyLogConf *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_ADDEMPTYLOGCONF]; + + r = talloc(talloc_tos(), struct PNP_AddEmptyLogConf); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_AddEmptyLogConf, r); + } + + r->out.result = _PNP_AddEmptyLogConf(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_AddEmptyLogConf, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_FreeLogConf(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_FreeLogConf *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_FREELOGCONF]; + + r = talloc(talloc_tos(), struct PNP_FreeLogConf); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_FreeLogConf, r); + } + + r->out.result = _PNP_FreeLogConf(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_FreeLogConf, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetFirstLogConf(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetFirstLogConf *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETFIRSTLOGCONF]; + + r = talloc(talloc_tos(), struct PNP_GetFirstLogConf); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetFirstLogConf, r); + } + + r->out.result = _PNP_GetFirstLogConf(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetFirstLogConf, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetNextLogConf(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetNextLogConf *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETNEXTLOGCONF]; + + r = talloc(talloc_tos(), struct PNP_GetNextLogConf); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetNextLogConf, r); + } + + r->out.result = _PNP_GetNextLogConf(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetNextLogConf, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetLogConfPriority(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetLogConfPriority *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETLOGCONFPRIORITY]; + + r = talloc(talloc_tos(), struct PNP_GetLogConfPriority); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetLogConfPriority, r); + } + + r->out.result = _PNP_GetLogConfPriority(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetLogConfPriority, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_AddResDes(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_AddResDes *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_ADDRESDES]; + + r = talloc(talloc_tos(), struct PNP_AddResDes); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_AddResDes, r); + } + + r->out.result = _PNP_AddResDes(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_AddResDes, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_FreeResDes(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_FreeResDes *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_FREERESDES]; + + r = talloc(talloc_tos(), struct PNP_FreeResDes); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_FreeResDes, r); + } + + r->out.result = _PNP_FreeResDes(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_FreeResDes, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetNextResDes(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetNextResDes *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETNEXTRESDES]; + + r = talloc(talloc_tos(), struct PNP_GetNextResDes); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetNextResDes, r); + } + + r->out.result = _PNP_GetNextResDes(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetNextResDes, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetResDesData(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetResDesData *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETRESDESDATA]; + + r = talloc(talloc_tos(), struct PNP_GetResDesData); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetResDesData, r); + } + + r->out.result = _PNP_GetResDesData(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetResDesData, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetResDesDataSize(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetResDesDataSize *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETRESDESDATASIZE]; + + r = talloc(talloc_tos(), struct PNP_GetResDesDataSize); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetResDesDataSize, r); + } + + r->out.result = _PNP_GetResDesDataSize(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetResDesDataSize, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_ModifyResDes(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_ModifyResDes *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_MODIFYRESDES]; + + r = talloc(talloc_tos(), struct PNP_ModifyResDes); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_ModifyResDes, r); + } + + r->out.result = _PNP_ModifyResDes(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_ModifyResDes, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_DetectResourceLimit(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_DetectResourceLimit *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_DETECTRESOURCELIMIT]; + + r = talloc(talloc_tos(), struct PNP_DetectResourceLimit); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_DetectResourceLimit, r); + } + + r->out.result = _PNP_DetectResourceLimit(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_DetectResourceLimit, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_QueryResConfList(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_QueryResConfList *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_QUERYRESCONFLIST]; + + r = talloc(talloc_tos(), struct PNP_QueryResConfList); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_QueryResConfList, r); + } + + r->out.result = _PNP_QueryResConfList(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_QueryResConfList, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_SetHwProf(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_SetHwProf *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_SETHWPROF]; + + r = talloc(talloc_tos(), struct PNP_SetHwProf); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_SetHwProf, r); + } + + r->out.result = _PNP_SetHwProf(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_SetHwProf, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_QueryArbitratorFreeData(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_QueryArbitratorFreeData *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_QUERYARBITRATORFREEDATA]; + + r = talloc(talloc_tos(), struct PNP_QueryArbitratorFreeData); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_QueryArbitratorFreeData, r); + } + + r->out.result = _PNP_QueryArbitratorFreeData(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_QueryArbitratorFreeData, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_QueryArbitratorFreeSize(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_QueryArbitratorFreeSize *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_QUERYARBITRATORFREESIZE]; + + r = talloc(talloc_tos(), struct PNP_QueryArbitratorFreeSize); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_QueryArbitratorFreeSize, r); + } + + r->out.result = _PNP_QueryArbitratorFreeSize(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_QueryArbitratorFreeSize, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_RunDetection(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_RunDetection *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_RUNDETECTION]; + + r = talloc(talloc_tos(), struct PNP_RunDetection); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RunDetection, r); + } + + r->out.result = _PNP_RunDetection(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RunDetection, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_RegisterNotification(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_RegisterNotification *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_REGISTERNOTIFICATION]; + + r = talloc(talloc_tos(), struct PNP_RegisterNotification); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_RegisterNotification, r); + } + + r->out.result = _PNP_RegisterNotification(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_RegisterNotification, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_UnregisterNotification(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_UnregisterNotification *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_UNREGISTERNOTIFICATION]; + + r = talloc(talloc_tos(), struct PNP_UnregisterNotification); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_UnregisterNotification, r); + } + + r->out.result = _PNP_UnregisterNotification(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_UnregisterNotification, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetCustomDevProp(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetCustomDevProp *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETCUSTOMDEVPROP]; + + r = talloc(talloc_tos(), struct PNP_GetCustomDevProp); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetCustomDevProp, r); + } + + r->out.result = _PNP_GetCustomDevProp(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetCustomDevProp, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetVersionInternal(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetVersionInternal *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETVERSIONINTERNAL]; + + r = talloc(talloc_tos(), struct PNP_GetVersionInternal); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetVersionInternal, r); + } + + r->out.result = _PNP_GetVersionInternal(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetVersionInternal, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetBlockedDriverInfo(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetBlockedDriverInfo *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETBLOCKEDDRIVERINFO]; + + r = talloc(talloc_tos(), struct PNP_GetBlockedDriverInfo); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetBlockedDriverInfo, r); + } + + r->out.result = _PNP_GetBlockedDriverInfo(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetBlockedDriverInfo, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + +static bool api_PNP_GetServerSideDeviceInstallFlags(pipes_struct *p) +{ + const struct ndr_interface_call *call; + struct ndr_pull *pull; + struct ndr_push *push; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct PNP_GetServerSideDeviceInstallFlags *r; + + call = &ndr_table_ntsvcs.calls[NDR_PNP_GETSERVERSIDEDEVICEINSTALLFLAGS]; + + r = talloc(talloc_tos(), struct PNP_GetServerSideDeviceInstallFlags); + if (r == NULL) { + return false; + } + + if (!prs_data_blob(&p->in_data.data, &blob, r)) { + talloc_free(r); + return false; + } + + pull = ndr_pull_init_blob(&blob, r); + if (pull == NULL) { + talloc_free(r); + return false; + } + + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + ndr_err = call->ndr_pull(pull, NDR_IN, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(PNP_GetServerSideDeviceInstallFlags, r); + } + + r->out.result = _PNP_GetServerSideDeviceInstallFlags(p, r); + + if (p->rng_fault_state) { + talloc_free(r); + /* Return true here, srv_pipe_hnd.c will take care */ + return true; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(PNP_GetServerSideDeviceInstallFlags, r); + } + + push = ndr_push_init_ctx(r); + if (push == NULL) { + talloc_free(r); + return false; + } + + ndr_err = call->ndr_push(push, NDR_OUT, r); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + talloc_free(r); + return false; + } + + blob = ndr_push_blob(push); + if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { + talloc_free(r); + return false; + } + + talloc_free(r); + + return true; +} + + +/* Tables */ +static struct api_struct api_ntsvcs_cmds[] = +{ + {"PNP_DISCONNECT", NDR_PNP_DISCONNECT, api_PNP_Disconnect}, + {"PNP_CONNECT", NDR_PNP_CONNECT, api_PNP_Connect}, + {"PNP_GETVERSION", NDR_PNP_GETVERSION, api_PNP_GetVersion}, + {"PNP_GETGLOBALSTATE", NDR_PNP_GETGLOBALSTATE, api_PNP_GetGlobalState}, + {"PNP_INITDETECTION", NDR_PNP_INITDETECTION, api_PNP_InitDetection}, + {"PNP_REPORTLOGON", NDR_PNP_REPORTLOGON, api_PNP_ReportLogOn}, + {"PNP_VALIDATEDEVICEINSTANCE", NDR_PNP_VALIDATEDEVICEINSTANCE, api_PNP_ValidateDeviceInstance}, + {"PNP_GETROOTDEVICEINSTANCE", NDR_PNP_GETROOTDEVICEINSTANCE, api_PNP_GetRootDeviceInstance}, + {"PNP_GETRELATEDDEVICEINSTANCE", NDR_PNP_GETRELATEDDEVICEINSTANCE, api_PNP_GetRelatedDeviceInstance}, + {"PNP_ENUMERATESUBKEYS", NDR_PNP_ENUMERATESUBKEYS, api_PNP_EnumerateSubKeys}, + {"PNP_GETDEVICELIST", NDR_PNP_GETDEVICELIST, api_PNP_GetDeviceList}, + {"PNP_GETDEVICELISTSIZE", NDR_PNP_GETDEVICELISTSIZE, api_PNP_GetDeviceListSize}, + {"PNP_GETDEPTH", NDR_PNP_GETDEPTH, api_PNP_GetDepth}, + {"PNP_GETDEVICEREGPROP", NDR_PNP_GETDEVICEREGPROP, api_PNP_GetDeviceRegProp}, + {"PNP_SETDEVICEREGPROP", NDR_PNP_SETDEVICEREGPROP, api_PNP_SetDeviceRegProp}, + {"PNP_GETCLASSINSTANCE", NDR_PNP_GETCLASSINSTANCE, api_PNP_GetClassInstance}, + {"PNP_CREATEKEY", NDR_PNP_CREATEKEY, api_PNP_CreateKey}, + {"PNP_DELETEREGISTRYKEY", NDR_PNP_DELETEREGISTRYKEY, api_PNP_DeleteRegistryKey}, + {"PNP_GETCLASSCOUNT", NDR_PNP_GETCLASSCOUNT, api_PNP_GetClassCount}, + {"PNP_GETCLASSNAME", NDR_PNP_GETCLASSNAME, api_PNP_GetClassName}, + {"PNP_DELETECLASSKEY", NDR_PNP_DELETECLASSKEY, api_PNP_DeleteClassKey}, + {"PNP_GETINTERFACEDEVICEALIAS", NDR_PNP_GETINTERFACEDEVICEALIAS, api_PNP_GetInterfaceDeviceAlias}, + {"PNP_GETINTERFACEDEVICELIST", NDR_PNP_GETINTERFACEDEVICELIST, api_PNP_GetInterfaceDeviceList}, + {"PNP_GETINTERFACEDEVICELISTSIZE", NDR_PNP_GETINTERFACEDEVICELISTSIZE, api_PNP_GetInterfaceDeviceListSize}, + {"PNP_REGISTERDEVICECLASSASSOCIATION", NDR_PNP_REGISTERDEVICECLASSASSOCIATION, api_PNP_RegisterDeviceClassAssociation}, + {"PNP_UNREGISTERDEVICECLASSASSOCIATION", NDR_PNP_UNREGISTERDEVICECLASSASSOCIATION, api_PNP_UnregisterDeviceClassAssociation}, + {"PNP_GETCLASSREGPROP", NDR_PNP_GETCLASSREGPROP, api_PNP_GetClassRegProp}, + {"PNP_SETCLASSREGPROP", NDR_PNP_SETCLASSREGPROP, api_PNP_SetClassRegProp}, + {"PNP_CREATEDEVINST", NDR_PNP_CREATEDEVINST, api_PNP_CreateDevInst}, + {"PNP_DEVICEINSTANCEACTION", NDR_PNP_DEVICEINSTANCEACTION, api_PNP_DeviceInstanceAction}, + {"PNP_GETDEVICESTATUS", NDR_PNP_GETDEVICESTATUS, api_PNP_GetDeviceStatus}, + {"PNP_SETDEVICEPROBLEM", NDR_PNP_SETDEVICEPROBLEM, api_PNP_SetDeviceProblem}, + {"PNP_DISABLEDEVINST", NDR_PNP_DISABLEDEVINST, api_PNP_DisableDevInst}, + {"PNP_UNINSTALLDEVINST", NDR_PNP_UNINSTALLDEVINST, api_PNP_UninstallDevInst}, + {"PNP_ADDID", NDR_PNP_ADDID, api_PNP_AddID}, + {"PNP_REGISTERDRIVER", NDR_PNP_REGISTERDRIVER, api_PNP_RegisterDriver}, + {"PNP_QUERYREMOVE", NDR_PNP_QUERYREMOVE, api_PNP_QueryRemove}, + {"PNP_REQUESTDEVICEEJECT", NDR_PNP_REQUESTDEVICEEJECT, api_PNP_RequestDeviceEject}, + {"PNP_ISDOCKSTATIONPRESENT", NDR_PNP_ISDOCKSTATIONPRESENT, api_PNP_IsDockStationPresent}, + {"PNP_REQUESTEJECTPC", NDR_PNP_REQUESTEJECTPC, api_PNP_RequestEjectPC}, + {"PNP_HWPROFFLAGS", NDR_PNP_HWPROFFLAGS, api_PNP_HwProfFlags}, + {"PNP_GETHWPROFINFO", NDR_PNP_GETHWPROFINFO, api_PNP_GetHwProfInfo}, + {"PNP_ADDEMPTYLOGCONF", NDR_PNP_ADDEMPTYLOGCONF, api_PNP_AddEmptyLogConf}, + {"PNP_FREELOGCONF", NDR_PNP_FREELOGCONF, api_PNP_FreeLogConf}, + {"PNP_GETFIRSTLOGCONF", NDR_PNP_GETFIRSTLOGCONF, api_PNP_GetFirstLogConf}, + {"PNP_GETNEXTLOGCONF", NDR_PNP_GETNEXTLOGCONF, api_PNP_GetNextLogConf}, + {"PNP_GETLOGCONFPRIORITY", NDR_PNP_GETLOGCONFPRIORITY, api_PNP_GetLogConfPriority}, + {"PNP_ADDRESDES", NDR_PNP_ADDRESDES, api_PNP_AddResDes}, + {"PNP_FREERESDES", NDR_PNP_FREERESDES, api_PNP_FreeResDes}, + {"PNP_GETNEXTRESDES", NDR_PNP_GETNEXTRESDES, api_PNP_GetNextResDes}, + {"PNP_GETRESDESDATA", NDR_PNP_GETRESDESDATA, api_PNP_GetResDesData}, + {"PNP_GETRESDESDATASIZE", NDR_PNP_GETRESDESDATASIZE, api_PNP_GetResDesDataSize}, + {"PNP_MODIFYRESDES", NDR_PNP_MODIFYRESDES, api_PNP_ModifyResDes}, + {"PNP_DETECTRESOURCELIMIT", NDR_PNP_DETECTRESOURCELIMIT, api_PNP_DetectResourceLimit}, + {"PNP_QUERYRESCONFLIST", NDR_PNP_QUERYRESCONFLIST, api_PNP_QueryResConfList}, + {"PNP_SETHWPROF", NDR_PNP_SETHWPROF, api_PNP_SetHwProf}, + {"PNP_QUERYARBITRATORFREEDATA", NDR_PNP_QUERYARBITRATORFREEDATA, api_PNP_QueryArbitratorFreeData}, + {"PNP_QUERYARBITRATORFREESIZE", NDR_PNP_QUERYARBITRATORFREESIZE, api_PNP_QueryArbitratorFreeSize}, + {"PNP_RUNDETECTION", NDR_PNP_RUNDETECTION, api_PNP_RunDetection}, + {"PNP_REGISTERNOTIFICATION", NDR_PNP_REGISTERNOTIFICATION, api_PNP_RegisterNotification}, + {"PNP_UNREGISTERNOTIFICATION", NDR_PNP_UNREGISTERNOTIFICATION, api_PNP_UnregisterNotification}, + {"PNP_GETCUSTOMDEVPROP", NDR_PNP_GETCUSTOMDEVPROP, api_PNP_GetCustomDevProp}, + {"PNP_GETVERSIONINTERNAL", NDR_PNP_GETVERSIONINTERNAL, api_PNP_GetVersionInternal}, + {"PNP_GETBLOCKEDDRIVERINFO", NDR_PNP_GETBLOCKEDDRIVERINFO, api_PNP_GetBlockedDriverInfo}, + {"PNP_GETSERVERSIDEDEVICEINSTALLFLAGS", NDR_PNP_GETSERVERSIDEDEVICEINSTALLFLAGS, api_PNP_GetServerSideDeviceInstallFlags}, +}; + +void ntsvcs_get_pipe_fns(struct api_struct **fns, int *n_fns) +{ + *fns = api_ntsvcs_cmds; + *n_fns = sizeof(api_ntsvcs_cmds) / sizeof(struct api_struct); +} + +NTSTATUS rpc_ntsvcs_init(void) +{ + return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "ntsvcs", "ntsvcs", api_ntsvcs_cmds, sizeof(api_ntsvcs_cmds) / sizeof(struct api_struct)); +} diff --git a/source3/librpc/gen_ndr/srv_ntsvcs.h b/source3/librpc/gen_ndr/srv_ntsvcs.h new file mode 100644 index 0000000000..c3969b11da --- /dev/null +++ b/source3/librpc/gen_ndr/srv_ntsvcs.h @@ -0,0 +1,71 @@ +#include "librpc/gen_ndr/ndr_ntsvcs.h" +#ifndef __SRV_NTSVCS__ +#define __SRV_NTSVCS__ +WERROR _PNP_Disconnect(pipes_struct *p, struct PNP_Disconnect *r); +WERROR _PNP_Connect(pipes_struct *p, struct PNP_Connect *r); +WERROR _PNP_GetVersion(pipes_struct *p, struct PNP_GetVersion *r); +WERROR _PNP_GetGlobalState(pipes_struct *p, struct PNP_GetGlobalState *r); +WERROR _PNP_InitDetection(pipes_struct *p, struct PNP_InitDetection *r); +WERROR _PNP_ReportLogOn(pipes_struct *p, struct PNP_ReportLogOn *r); +WERROR _PNP_ValidateDeviceInstance(pipes_struct *p, struct PNP_ValidateDeviceInstance *r); +WERROR _PNP_GetRootDeviceInstance(pipes_struct *p, struct PNP_GetRootDeviceInstance *r); +WERROR _PNP_GetRelatedDeviceInstance(pipes_struct *p, struct PNP_GetRelatedDeviceInstance *r); +WERROR _PNP_EnumerateSubKeys(pipes_struct *p, struct PNP_EnumerateSubKeys *r); +WERROR _PNP_GetDeviceList(pipes_struct *p, struct PNP_GetDeviceList *r); +WERROR _PNP_GetDeviceListSize(pipes_struct *p, struct PNP_GetDeviceListSize *r); +WERROR _PNP_GetDepth(pipes_struct *p, struct PNP_GetDepth *r); +WERROR _PNP_GetDeviceRegProp(pipes_struct *p, struct PNP_GetDeviceRegProp *r); +WERROR _PNP_SetDeviceRegProp(pipes_struct *p, struct PNP_SetDeviceRegProp *r); +WERROR _PNP_GetClassInstance(pipes_struct *p, struct PNP_GetClassInstance *r); +WERROR _PNP_CreateKey(pipes_struct *p, struct PNP_CreateKey *r); +WERROR _PNP_DeleteRegistryKey(pipes_struct *p, struct PNP_DeleteRegistryKey *r); +WERROR _PNP_GetClassCount(pipes_struct *p, struct PNP_GetClassCount *r); +WERROR _PNP_GetClassName(pipes_struct *p, struct PNP_GetClassName *r); +WERROR _PNP_DeleteClassKey(pipes_struct *p, struct PNP_DeleteClassKey *r); +WERROR _PNP_GetInterfaceDeviceAlias(pipes_struct *p, struct PNP_GetInterfaceDeviceAlias *r); +WERROR _PNP_GetInterfaceDeviceList(pipes_struct *p, struct PNP_GetInterfaceDeviceList *r); +WERROR _PNP_GetInterfaceDeviceListSize(pipes_struct *p, struct PNP_GetInterfaceDeviceListSize *r); +WERROR _PNP_RegisterDeviceClassAssociation(pipes_struct *p, struct PNP_RegisterDeviceClassAssociation *r); +WERROR _PNP_UnregisterDeviceClassAssociation(pipes_struct *p, struct PNP_UnregisterDeviceClassAssociation *r); +WERROR _PNP_GetClassRegProp(pipes_struct *p, struct PNP_GetClassRegProp *r); +WERROR _PNP_SetClassRegProp(pipes_struct *p, struct PNP_SetClassRegProp *r); +WERROR _PNP_CreateDevInst(pipes_struct *p, struct PNP_CreateDevInst *r); +WERROR _PNP_DeviceInstanceAction(pipes_struct *p, struct PNP_DeviceInstanceAction *r); +WERROR _PNP_GetDeviceStatus(pipes_struct *p, struct PNP_GetDeviceStatus *r); +WERROR _PNP_SetDeviceProblem(pipes_struct *p, struct PNP_SetDeviceProblem *r); +WERROR _PNP_DisableDevInst(pipes_struct *p, struct PNP_DisableDevInst *r); +WERROR _PNP_UninstallDevInst(pipes_struct *p, struct PNP_UninstallDevInst *r); +WERROR _PNP_AddID(pipes_struct *p, struct PNP_AddID *r); +WERROR _PNP_RegisterDriver(pipes_struct *p, struct PNP_RegisterDriver *r); +WERROR _PNP_QueryRemove(pipes_struct *p, struct PNP_QueryRemove *r); +WERROR _PNP_RequestDeviceEject(pipes_struct *p, struct PNP_RequestDeviceEject *r); +WERROR _PNP_IsDockStationPresent(pipes_struct *p, struct PNP_IsDockStationPresent *r); +WERROR _PNP_RequestEjectPC(pipes_struct *p, struct PNP_RequestEjectPC *r); +WERROR _PNP_HwProfFlags(pipes_struct *p, struct PNP_HwProfFlags *r); +WERROR _PNP_GetHwProfInfo(pipes_struct *p, struct PNP_GetHwProfInfo *r); +WERROR _PNP_AddEmptyLogConf(pipes_struct *p, struct PNP_AddEmptyLogConf *r); +WERROR _PNP_FreeLogConf(pipes_struct *p, struct PNP_FreeLogConf *r); +WERROR _PNP_GetFirstLogConf(pipes_struct *p, struct PNP_GetFirstLogConf *r); +WERROR _PNP_GetNextLogConf(pipes_struct *p, struct PNP_GetNextLogConf *r); +WERROR _PNP_GetLogConfPriority(pipes_struct *p, struct PNP_GetLogConfPriority *r); +WERROR _PNP_AddResDes(pipes_struct *p, struct PNP_AddResDes *r); +WERROR _PNP_FreeResDes(pipes_struct *p, struct PNP_FreeResDes *r); +WERROR _PNP_GetNextResDes(pipes_struct *p, struct PNP_GetNextResDes *r); +WERROR _PNP_GetResDesData(pipes_struct *p, struct PNP_GetResDesData *r); +WERROR _PNP_GetResDesDataSize(pipes_struct *p, struct PNP_GetResDesDataSize *r); +WERROR _PNP_ModifyResDes(pipes_struct *p, struct PNP_ModifyResDes *r); +WERROR _PNP_DetectResourceLimit(pipes_struct *p, struct PNP_DetectResourceLimit *r); +WERROR _PNP_QueryResConfList(pipes_struct *p, struct PNP_QueryResConfList *r); +WERROR _PNP_SetHwProf(pipes_struct *p, struct PNP_SetHwProf *r); +WERROR _PNP_QueryArbitratorFreeData(pipes_struct *p, struct PNP_QueryArbitratorFreeData *r); +WERROR _PNP_QueryArbitratorFreeSize(pipes_struct *p, struct PNP_QueryArbitratorFreeSize *r); +WERROR _PNP_RunDetection(pipes_struct *p, struct PNP_RunDetection *r); +WERROR _PNP_RegisterNotification(pipes_struct *p, struct PNP_RegisterNotification *r); +WERROR _PNP_UnregisterNotification(pipes_struct *p, struct PNP_UnregisterNotification *r); +WERROR _PNP_GetCustomDevProp(pipes_struct *p, struct PNP_GetCustomDevProp *r); +WERROR _PNP_GetVersionInternal(pipes_struct *p, struct PNP_GetVersionInternal *r); +WERROR _PNP_GetBlockedDriverInfo(pipes_struct *p, struct PNP_GetBlockedDriverInfo *r); +WERROR _PNP_GetServerSideDeviceInstallFlags(pipes_struct *p, struct PNP_GetServerSideDeviceInstallFlags *r); +void ntsvcs_get_pipe_fns(struct api_struct **fns, int *n_fns); +NTSTATUS rpc_ntsvcs_init(void); +#endif /* __SRV_NTSVCS__ */ diff --git a/source3/librpc/gen_ndr/srv_srvsvc.c b/source3/librpc/gen_ndr/srv_srvsvc.c index afd458765e..75e586c716 100644 --- a/source3/librpc/gen_ndr/srv_srvsvc.c +++ b/source3/librpc/gen_ndr/srv_srvsvc.c @@ -2225,7 +2225,7 @@ static bool api_srvsvc_NetRemoteTOD(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.info = talloc_zero(r, struct srvsvc_NetRemoteTODInfo); + r->out.info = talloc_zero(r, struct srvsvc_NetRemoteTODInfo *); if (r->out.info == NULL) { talloc_free(r); return false; diff --git a/source3/librpc/gen_ndr/srv_svcctl.c b/source3/librpc/gen_ndr/srv_svcctl.c index a7163917bd..10db320452 100644 --- a/source3/librpc/gen_ndr/srv_svcctl.c +++ b/source3/librpc/gen_ndr/srv_svcctl.c @@ -352,6 +352,19 @@ static bool api_svcctl_QueryServiceObjectSecurity(pipes_struct *p) NDR_PRINT_IN_DEBUG(svcctl_QueryServiceObjectSecurity, r); } + ZERO_STRUCT(r->out); + r->out.buffer = talloc_zero_array(r, uint8_t, r->in.buffer_size); + if (r->out.buffer == NULL) { + talloc_free(r); + return false; + } + + r->out.needed = talloc_zero(r, uint32_t); + if (r->out.needed == NULL) { + talloc_free(r); + return false; + } + r->out.result = _svcctl_QueryServiceObjectSecurity(p, r); if (p->rng_fault_state) { diff --git a/source3/librpc/gen_ndr/srv_unixinfo.c b/source3/librpc/gen_ndr/srv_unixinfo.c deleted file mode 100644 index 6142bb113f..0000000000 --- a/source3/librpc/gen_ndr/srv_unixinfo.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * server auto-generated by pidl. DO NOT MODIFY! - */ - -#include "includes.h" -#include "librpc/gen_ndr/srv_unixinfo.h" - -static bool api_unixinfo_SidToUid(pipes_struct *p) -{ - const struct ndr_interface_call *call; - struct ndr_pull *pull; - struct ndr_push *push; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - struct unixinfo_SidToUid *r; - - call = &ndr_table_unixinfo.calls[NDR_UNIXINFO_SIDTOUID]; - - r = talloc(talloc_tos(), struct unixinfo_SidToUid); - if (r == NULL) { - return false; - } - - if (!prs_data_blob(&p->in_data.data, &blob, r)) { - talloc_free(r); - return false; - } - - pull = ndr_pull_init_blob(&blob, r); - if (pull == NULL) { - talloc_free(r); - return false; - } - - pull->flags |= LIBNDR_FLAG_REF_ALLOC; - ndr_err = call->ndr_pull(pull, NDR_IN, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_SidToUid, r); - } - - ZERO_STRUCT(r->out); - r->out.uid = talloc_zero(r, uint64_t); - if (r->out.uid == NULL) { - talloc_free(r); - return false; - } - - r->out.result = _unixinfo_SidToUid(p, r); - - if (p->rng_fault_state) { - talloc_free(r); - /* Return true here, srv_pipe_hnd.c will take care */ - return true; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_SidToUid, r); - } - - push = ndr_push_init_ctx(r); - if (push == NULL) { - talloc_free(r); - return false; - } - - ndr_err = call->ndr_push(push, NDR_OUT, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - blob = ndr_push_blob(push); - if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { - talloc_free(r); - return false; - } - - talloc_free(r); - - return true; -} - -static bool api_unixinfo_UidToSid(pipes_struct *p) -{ - const struct ndr_interface_call *call; - struct ndr_pull *pull; - struct ndr_push *push; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - struct unixinfo_UidToSid *r; - - call = &ndr_table_unixinfo.calls[NDR_UNIXINFO_UIDTOSID]; - - r = talloc(talloc_tos(), struct unixinfo_UidToSid); - if (r == NULL) { - return false; - } - - if (!prs_data_blob(&p->in_data.data, &blob, r)) { - talloc_free(r); - return false; - } - - pull = ndr_pull_init_blob(&blob, r); - if (pull == NULL) { - talloc_free(r); - return false; - } - - pull->flags |= LIBNDR_FLAG_REF_ALLOC; - ndr_err = call->ndr_pull(pull, NDR_IN, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_UidToSid, r); - } - - ZERO_STRUCT(r->out); - r->out.sid = talloc_zero(r, struct dom_sid); - if (r->out.sid == NULL) { - talloc_free(r); - return false; - } - - r->out.result = _unixinfo_UidToSid(p, r); - - if (p->rng_fault_state) { - talloc_free(r); - /* Return true here, srv_pipe_hnd.c will take care */ - return true; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_UidToSid, r); - } - - push = ndr_push_init_ctx(r); - if (push == NULL) { - talloc_free(r); - return false; - } - - ndr_err = call->ndr_push(push, NDR_OUT, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - blob = ndr_push_blob(push); - if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { - talloc_free(r); - return false; - } - - talloc_free(r); - - return true; -} - -static bool api_unixinfo_SidToGid(pipes_struct *p) -{ - const struct ndr_interface_call *call; - struct ndr_pull *pull; - struct ndr_push *push; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - struct unixinfo_SidToGid *r; - - call = &ndr_table_unixinfo.calls[NDR_UNIXINFO_SIDTOGID]; - - r = talloc(talloc_tos(), struct unixinfo_SidToGid); - if (r == NULL) { - return false; - } - - if (!prs_data_blob(&p->in_data.data, &blob, r)) { - talloc_free(r); - return false; - } - - pull = ndr_pull_init_blob(&blob, r); - if (pull == NULL) { - talloc_free(r); - return false; - } - - pull->flags |= LIBNDR_FLAG_REF_ALLOC; - ndr_err = call->ndr_pull(pull, NDR_IN, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_SidToGid, r); - } - - ZERO_STRUCT(r->out); - r->out.gid = talloc_zero(r, uint64_t); - if (r->out.gid == NULL) { - talloc_free(r); - return false; - } - - r->out.result = _unixinfo_SidToGid(p, r); - - if (p->rng_fault_state) { - talloc_free(r); - /* Return true here, srv_pipe_hnd.c will take care */ - return true; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_SidToGid, r); - } - - push = ndr_push_init_ctx(r); - if (push == NULL) { - talloc_free(r); - return false; - } - - ndr_err = call->ndr_push(push, NDR_OUT, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - blob = ndr_push_blob(push); - if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { - talloc_free(r); - return false; - } - - talloc_free(r); - - return true; -} - -static bool api_unixinfo_GidToSid(pipes_struct *p) -{ - const struct ndr_interface_call *call; - struct ndr_pull *pull; - struct ndr_push *push; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - struct unixinfo_GidToSid *r; - - call = &ndr_table_unixinfo.calls[NDR_UNIXINFO_GIDTOSID]; - - r = talloc(talloc_tos(), struct unixinfo_GidToSid); - if (r == NULL) { - return false; - } - - if (!prs_data_blob(&p->in_data.data, &blob, r)) { - talloc_free(r); - return false; - } - - pull = ndr_pull_init_blob(&blob, r); - if (pull == NULL) { - talloc_free(r); - return false; - } - - pull->flags |= LIBNDR_FLAG_REF_ALLOC; - ndr_err = call->ndr_pull(pull, NDR_IN, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_GidToSid, r); - } - - ZERO_STRUCT(r->out); - r->out.sid = talloc_zero(r, struct dom_sid); - if (r->out.sid == NULL) { - talloc_free(r); - return false; - } - - r->out.result = _unixinfo_GidToSid(p, r); - - if (p->rng_fault_state) { - talloc_free(r); - /* Return true here, srv_pipe_hnd.c will take care */ - return true; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_GidToSid, r); - } - - push = ndr_push_init_ctx(r); - if (push == NULL) { - talloc_free(r); - return false; - } - - ndr_err = call->ndr_push(push, NDR_OUT, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - blob = ndr_push_blob(push); - if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { - talloc_free(r); - return false; - } - - talloc_free(r); - - return true; -} - -static bool api_unixinfo_GetPWUid(pipes_struct *p) -{ - const struct ndr_interface_call *call; - struct ndr_pull *pull; - struct ndr_push *push; - enum ndr_err_code ndr_err; - DATA_BLOB blob; - struct unixinfo_GetPWUid *r; - - call = &ndr_table_unixinfo.calls[NDR_UNIXINFO_GETPWUID]; - - r = talloc(talloc_tos(), struct unixinfo_GetPWUid); - if (r == NULL) { - return false; - } - - if (!prs_data_blob(&p->in_data.data, &blob, r)) { - talloc_free(r); - return false; - } - - pull = ndr_pull_init_blob(&blob, r); - if (pull == NULL) { - talloc_free(r); - return false; - } - - pull->flags |= LIBNDR_FLAG_REF_ALLOC; - ndr_err = call->ndr_pull(pull, NDR_IN, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_IN_DEBUG(unixinfo_GetPWUid, r); - } - - ZERO_STRUCT(r->out); - r->out.count = r->in.count; - r->out.infos = talloc_zero_array(r, struct unixinfo_GetPWUidInfo, *r->out.count); - if (r->out.infos == NULL) { - talloc_free(r); - return false; - } - - r->out.result = _unixinfo_GetPWUid(p, r); - - if (p->rng_fault_state) { - talloc_free(r); - /* Return true here, srv_pipe_hnd.c will take care */ - return true; - } - - if (DEBUGLEVEL >= 10) { - NDR_PRINT_OUT_DEBUG(unixinfo_GetPWUid, r); - } - - push = ndr_push_init_ctx(r); - if (push == NULL) { - talloc_free(r); - return false; - } - - ndr_err = call->ndr_push(push, NDR_OUT, r); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - talloc_free(r); - return false; - } - - blob = ndr_push_blob(push); - if (!prs_copy_data_in(&p->out_data.rdata, (const char *)blob.data, (uint32_t)blob.length)) { - talloc_free(r); - return false; - } - - talloc_free(r); - - return true; -} - - -/* Tables */ -static struct api_struct api_unixinfo_cmds[] = -{ - {"UNIXINFO_SIDTOUID", NDR_UNIXINFO_SIDTOUID, api_unixinfo_SidToUid}, - {"UNIXINFO_UIDTOSID", NDR_UNIXINFO_UIDTOSID, api_unixinfo_UidToSid}, - {"UNIXINFO_SIDTOGID", NDR_UNIXINFO_SIDTOGID, api_unixinfo_SidToGid}, - {"UNIXINFO_GIDTOSID", NDR_UNIXINFO_GIDTOSID, api_unixinfo_GidToSid}, - {"UNIXINFO_GETPWUID", NDR_UNIXINFO_GETPWUID, api_unixinfo_GetPWUid}, -}; - -void unixinfo_get_pipe_fns(struct api_struct **fns, int *n_fns) -{ - *fns = api_unixinfo_cmds; - *n_fns = sizeof(api_unixinfo_cmds) / sizeof(struct api_struct); -} - -NTSTATUS rpc_unixinfo_init(void) -{ - return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "unixinfo", "unixinfo", api_unixinfo_cmds, sizeof(api_unixinfo_cmds) / sizeof(struct api_struct)); -} diff --git a/source3/librpc/gen_ndr/srv_unixinfo.h b/source3/librpc/gen_ndr/srv_unixinfo.h deleted file mode 100644 index 6e5c033b61..0000000000 --- a/source3/librpc/gen_ndr/srv_unixinfo.h +++ /dev/null @@ -1,11 +0,0 @@ -#include "librpc/gen_ndr/ndr_unixinfo.h" -#ifndef __SRV_UNIXINFO__ -#define __SRV_UNIXINFO__ -NTSTATUS _unixinfo_SidToUid(pipes_struct *p, struct unixinfo_SidToUid *r); -NTSTATUS _unixinfo_UidToSid(pipes_struct *p, struct unixinfo_UidToSid *r); -NTSTATUS _unixinfo_SidToGid(pipes_struct *p, struct unixinfo_SidToGid *r); -NTSTATUS _unixinfo_GidToSid(pipes_struct *p, struct unixinfo_GidToSid *r); -NTSTATUS _unixinfo_GetPWUid(pipes_struct *p, struct unixinfo_GetPWUid *r); -void unixinfo_get_pipe_fns(struct api_struct **fns, int *n_fns); -NTSTATUS rpc_unixinfo_init(void); -#endif /* __SRV_UNIXINFO__ */ diff --git a/source3/librpc/gen_ndr/srvsvc.h b/source3/librpc/gen_ndr/srvsvc.h index 6e6c7829a0..cede81e837 100644 --- a/source3/librpc/gen_ndr/srvsvc.h +++ b/source3/librpc/gen_ndr/srvsvc.h @@ -1299,7 +1299,7 @@ struct srvsvc_NetShareSetInfo { const char *server_unc;/* [unique,charset(UTF16)] */ const char *share_name;/* [charset(UTF16)] */ uint32_t level; - union srvsvc_NetShareInfo info;/* [switch_is(level)] */ + union srvsvc_NetShareInfo *info;/* [ref,switch_is(level)] */ uint32_t *parm_error;/* [unique] */ } in; @@ -1371,7 +1371,7 @@ struct srvsvc_NetSrvSetInfo { struct { const char *server_unc;/* [unique,charset(UTF16)] */ uint32_t level; - union srvsvc_NetSrvInfo info;/* [switch_is(level)] */ + union srvsvc_NetSrvInfo *info;/* [ref,switch_is(level)] */ uint32_t *parm_error;/* [unique] */ } in; @@ -1472,7 +1472,7 @@ struct srvsvc_NetRemoteTOD { } in; struct { - struct srvsvc_NetRemoteTODInfo *info;/* [unique] */ + struct srvsvc_NetRemoteTODInfo **info;/* [ref] */ WERROR result; } out; diff --git a/source3/librpc/gen_ndr/svcctl.h b/source3/librpc/gen_ndr/svcctl.h index 7314be0a33..c13e96b2a0 100644 --- a/source3/librpc/gen_ndr/svcctl.h +++ b/source3/librpc/gen_ndr/svcctl.h @@ -134,6 +134,14 @@ struct svcctl_LockServiceDatabase { struct svcctl_QueryServiceObjectSecurity { struct { + struct policy_handle *handle;/* [ref] */ + uint32_t security_flags; + uint32_t buffer_size;/* [range(0,0x40000)] */ + } in; + + struct { + uint8_t *buffer;/* [ref,size_is(buffer_size)] */ + uint32_t *needed;/* [ref,range(0,0x40000)] */ WERROR result; } out; @@ -142,6 +150,13 @@ struct svcctl_QueryServiceObjectSecurity { struct svcctl_SetServiceObjectSecurity { struct { + struct policy_handle *handle;/* [ref] */ + uint32_t security_flags; + uint8_t *buffer;/* [ref,size_is(buffer_size)] */ + uint32_t buffer_size; + } in; + + struct { WERROR result; } out; diff --git a/source3/librpc/gen_ndr/unixinfo.h b/source3/librpc/gen_ndr/unixinfo.h deleted file mode 100644 index bfe0934ccd..0000000000 --- a/source3/librpc/gen_ndr/unixinfo.h +++ /dev/null @@ -1,82 +0,0 @@ -/* header auto-generated by pidl */ - -#include <stdint.h> - -#include "librpc/gen_ndr/security.h" -#ifndef _HEADER_unixinfo -#define _HEADER_unixinfo - -struct unixinfo_GetPWUidInfo { - NTSTATUS status; - const char * homedir;/* [flag(LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM)] */ - const char * shell;/* [flag(LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM)] */ -}; - - -struct unixinfo_SidToUid { - struct { - struct dom_sid sid; - } in; - - struct { - uint64_t *uid;/* [ref] */ - NTSTATUS result; - } out; - -}; - - -struct unixinfo_UidToSid { - struct { - uint64_t uid; - } in; - - struct { - struct dom_sid *sid;/* [ref] */ - NTSTATUS result; - } out; - -}; - - -struct unixinfo_SidToGid { - struct { - struct dom_sid sid; - } in; - - struct { - uint64_t *gid;/* [ref] */ - NTSTATUS result; - } out; - -}; - - -struct unixinfo_GidToSid { - struct { - uint64_t gid; - } in; - - struct { - struct dom_sid *sid;/* [ref] */ - NTSTATUS result; - } out; - -}; - - -struct unixinfo_GetPWUid { - struct { - uint64_t *uids;/* [size_is(*count)] */ - uint32_t *count;/* [ref,range(0,1023)] */ - } in; - - struct { - struct unixinfo_GetPWUidInfo *infos;/* [size_is(*count)] */ - uint32_t *count;/* [ref,range(0,1023)] */ - NTSTATUS result; - } out; - -}; - -#endif /* _HEADER_unixinfo */ diff --git a/source3/librpc/idl/krb5pac.idl b/source3/librpc/idl/krb5pac.idl new file mode 100644 index 0000000000..11f08e11aa --- /dev/null +++ b/source3/librpc/idl/krb5pac.idl @@ -0,0 +1,119 @@ +/* + krb5 PAC +*/ + +#include "idl_types.h" + +import "security.idl", "netlogon.idl", "samr.idl"; + +[ + uuid("12345778-1234-abcd-0000-00000000"), + version(0.0), + pointer_default(unique), + helpstring("Active Directory KRB5 PAC") +] +interface krb5pac +{ + typedef struct { + NTTIME logon_time; + [value(2*strlen_m(account_name))] uint16 size; + [charset(UTF16)] uint8 account_name[size]; + } PAC_LOGON_NAME; + + typedef [public,flag(NDR_PAHEX)] struct { + uint32 type; + [flag(NDR_REMAINING)] DATA_BLOB signature; + } PAC_SIGNATURE_DATA; + + typedef [gensize] struct { + netr_SamInfo3 info3; + dom_sid2 *res_group_dom_sid; + samr_RidWithAttributeArray res_groups; + } PAC_LOGON_INFO; + + typedef struct { + [value(2*strlen_m(upn_name))] uint16 upn_size; + uint16 unknown1; /* 0x10 */ + [value(2*strlen_m(domain_name))] uint16 domain_size; + uint16 unknown2; /* 0x50 */ + uint16 unknown3; /* 0x01 */ + uint16 unknown4; + uint32 unknown5; + [charset(UTF16)] uint8 upn_name[upn_size+2]; + [charset(UTF16)] uint8 domain_name[domain_size+2]; + uint32 unknown6; + } PAC_UNKNOWN_12; + + typedef [public] struct { + [value(0x00081001)] uint32 unknown1; + [value(0xCCCCCCCC)] uint32 unknown2; + [value(NDR_ROUND(ndr_size_PAC_LOGON_INFO(info, ndr->flags)+4,8))] uint32 _ndr_size; + [value(0x00000000)] uint32 unknown3; + PAC_LOGON_INFO *info; + } PAC_LOGON_INFO_CTR; + + typedef [public,v1_enum] enum { + PAC_TYPE_LOGON_INFO = 1, + PAC_TYPE_SRV_CHECKSUM = 6, + PAC_TYPE_KDC_CHECKSUM = 7, + PAC_TYPE_LOGON_NAME = 10, + PAC_TYPE_CONSTRAINED_DELEGATION = 11, + PAC_TYPE_UNKNOWN_12 = 12 + } PAC_TYPE; + + typedef [public,nodiscriminant,gensize] union { + [case(PAC_TYPE_LOGON_INFO)] PAC_LOGON_INFO_CTR logon_info; + [case(PAC_TYPE_SRV_CHECKSUM)] PAC_SIGNATURE_DATA srv_cksum; + [case(PAC_TYPE_KDC_CHECKSUM)] PAC_SIGNATURE_DATA kdc_cksum; + [case(PAC_TYPE_LOGON_NAME)] PAC_LOGON_NAME logon_name; + [case(PAC_TYPE_UNKNOWN_12)] PAC_UNKNOWN_12 unknown; + } PAC_INFO; + + typedef [public,nopush,nopull,noprint] struct { + PAC_TYPE type; + [value(_ndr_size_PAC_INFO(info, type, 0))] uint32 _ndr_size; + [relative,switch_is(type),subcontext(0),subcontext_size(_subcontext_size_PAC_INFO(r, ndr->flags)),flag(NDR_ALIGN8)] PAC_INFO *info; + [value(0)] uint32 _pad; /* Top half of a 64 bit pointer? */ + } PAC_BUFFER; + + typedef [public] struct { + uint32 num_buffers; + uint32 version; + PAC_BUFFER buffers[num_buffers]; + } PAC_DATA; + + typedef struct { + [flag(NDR_REMAINING)] DATA_BLOB remaining; + } DATA_BLOB_REM; + + typedef [public] struct { + PAC_TYPE type; + uint32 ndr_size; + [relative,subcontext(0),subcontext_size(NDR_ROUND(ndr_size,8)),flag(NDR_ALIGN8)] DATA_BLOB_REM *info; + [value(0)] uint32 _pad; /* Top half of a 64 bit pointer? */ + } PAC_BUFFER_RAW; + + typedef [public] struct { + uint32 num_buffers; + uint32 version; + PAC_BUFFER_RAW buffers[num_buffers]; + } PAC_DATA_RAW; + + void decode_pac( + [in] PAC_DATA pac + ); + + void decode_pac_raw( + [in] PAC_DATA_RAW pac + ); + + void decode_login_info( + [in] PAC_LOGON_INFO logon_info + ); + + /* used for samba3 netsamlogon cache */ + typedef [public] struct { + time_t timestamp; + netr_SamInfo3 info3; + } netsamlogoncache_entry; +} diff --git a/source3/librpc/idl/libnet_join.idl b/source3/librpc/idl/libnet_join.idl index 2741b7bd7b..3975d83a80 100644 --- a/source3/librpc/idl/libnet_join.idl +++ b/source3/librpc/idl/libnet_join.idl @@ -12,8 +12,9 @@ import "wkssvc.idl", "security.idl"; interface libnetjoin { typedef bitmap wkssvc_joinflags wkssvc_joinflags; + typedef enum netr_SchannelType netr_SchannelType; - [nopush,nopull] WERROR libnet_JoinCtx( + [nopush,nopull,noopnum] WERROR libnet_JoinCtx( [in] string dc_name, [in] string machine_name, [in,ref] string *domain_name, @@ -29,6 +30,7 @@ interface libnetjoin [in] boolean8 modify_config, [in] ads_struct *ads, [in] boolean8 debug, + [in] netr_SchannelType secure_channel_type, [out] string account_name, [out] string netbios_domain_name, [out] string dns_domain_name, @@ -39,7 +41,7 @@ interface libnetjoin [out] boolean8 domain_is_ad ); - [nopush,nopull] WERROR libnet_UnjoinCtx( + [nopush,nopull,noopnum] WERROR libnet_UnjoinCtx( [in] string dc_name, [in] string machine_name, [in] string domain_name, @@ -55,6 +57,8 @@ interface libnetjoin [out] string netbios_domain_name, [out] string dns_domain_name, [out] boolean8 modified_config, - [out] string error_string + [out] string error_string, + [out] boolean8 disabled_machine_account, + [out] boolean8 deleted_machine_account ); } diff --git a/source3/librpc/idl/lsa.idl b/source3/librpc/idl/lsa.idl index 305bab3d03..ee8a2fe6b2 100644 --- a/source3/librpc/idl/lsa.idl +++ b/source3/librpc/idl/lsa.idl @@ -23,7 +23,7 @@ import "security.idl"; typedef [public] struct { [value(2*strlen_m(string))] uint16 length; - [value(2*(strlen_m(string)+1))] uint16 size; + [value(2*strlen_m_term(string))] uint16 size; [charset(UTF16),size_is(size/2),length_is(length/2)] uint16 *string; } lsa_StringLarge; @@ -35,9 +35,15 @@ import "security.idl"; typedef [public] struct { [value(strlen_m(string))] uint16 length; [value(strlen_m(string))] uint16 size; - ascstr_noterm *string; + [charset(DOS),size_is(size),length_is(length)] uint8 *string; } lsa_AsciiString; + typedef [public] struct { + [value(strlen_m(string))] uint16 length; + [value(strlen_m_term(string))] uint16 size; + [charset(DOS),size_is(size),length_is(length)] uint8 *string; + } lsa_AsciiStringLarge; + /******************/ /* Function: 0x00 */ NTSTATUS lsa_Close ( @@ -117,12 +123,27 @@ import "security.idl"; lsa_QosInfo *sec_qos; } lsa_ObjectAttribute; + typedef [public,bitmap32bit] bitmap { + LSA_POLICY_VIEW_LOCAL_INFORMATION = 0x00000001, + LSA_POLICY_VIEW_AUDIT_INFORMATION = 0x00000002, + LSA_POLICY_GET_PRIVATE_INFORMATION = 0x00000004, + LSA_POLICY_TRUST_ADMIN = 0x00000008, + LSA_POLICY_CREATE_ACCOUNT = 0x00000010, + LSA_POLICY_CREATE_SECRET = 0x00000020, + LSA_POLICY_CREATE_PRIVILEGE = 0x00000040, + LSA_POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080, + LSA_POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100, + LSA_POLICY_AUDIT_LOG_ADMIN = 0x00000200, + LSA_POLICY_SERVER_ADMIN = 0x00000400, + LSA_POLICY_LOOKUP_NAMES = 0x00000800 + } lsa_PolicyAccessMask; + /* notice the screwup with the system_name - thats why MS created OpenPolicy2 */ [public] NTSTATUS lsa_OpenPolicy ( [in,unique] uint16 *system_name, [in] lsa_ObjectAttribute *attr, - [in] uint32 access_mask, + [in] lsa_PolicyAccessMask access_mask, [out] policy_handle *handle ); @@ -297,9 +318,9 @@ import "security.idl"; [public] NTSTATUS lsa_EnumAccounts ( [in] policy_handle *handle, - [in,out] uint32 *resume_handle, - [in,range(0,8192)] uint32 num_entries, - [out] lsa_SidArray *sids + [in,out,ref] uint32 *resume_handle, + [out,ref] lsa_SidArray *sids, + [in,range(0,8192)] uint32 num_entries ); @@ -360,6 +381,8 @@ import "security.idl"; } lsa_TransSidArray; const int LSA_REF_DOMAIN_LIST_MULTIPLIER = 32; + const int MAX_REF_DOMAINS = LSA_REF_DOMAIN_LIST_MULTIPLIER; + typedef struct { [range(0,1000)] uint32 count; [size_is(count)] lsa_DomainInfo *domains; @@ -387,10 +410,10 @@ import "security.idl"; [in] policy_handle *handle, [in,range(0,1000)] uint32 num_names, [in,size_is(num_names)] lsa_String names[], - [out,unique] lsa_RefDomainList *domains, - [in,out] lsa_TransSidArray *sids, + [out,ref] lsa_RefDomainList **domains, + [in,out,ref] lsa_TransSidArray *sids, [in] lsa_LookupNamesLevel level, - [in,out] uint32 *count + [in,out,ref] uint32 *count ); @@ -408,13 +431,16 @@ import "security.idl"; [size_is(count)] lsa_TranslatedName *names; } lsa_TransNameArray; + /* This number is based on Win2k and later maximum response allowed */ + const int MAX_LOOKUP_SIDS = 0x5000; /* 20480 */ + [public] NTSTATUS lsa_LookupSids ( [in] policy_handle *handle, - [in] lsa_SidArray *sids, - [out,unique] lsa_RefDomainList *domains, - [in,out] lsa_TransNameArray *names, + [in,ref] lsa_SidArray *sids, + [out,ref] lsa_RefDomainList **domains, + [in,out,ref] lsa_TransNameArray *names, [in] uint16 level, - [in,out] uint32 *count + [in,out,ref] uint32 *count ); @@ -453,7 +479,7 @@ import "security.idl"; NTSTATUS lsa_EnumPrivsAccount ( [in] policy_handle *handle, - [out,unique] lsa_PrivilegeSet *privs + [out,ref] lsa_PrivilegeSet **privs ); @@ -461,7 +487,7 @@ import "security.idl"; /* Function: 0x13 */ NTSTATUS lsa_AddPrivilegesToAccount( [in] policy_handle *handle, - [in] lsa_PrivilegeSet *privs + [in,ref] lsa_PrivilegeSet *privs ); @@ -637,8 +663,8 @@ import "security.idl"; /* Function: 0x1f */ NTSTATUS lsa_LookupPrivValue( [in] policy_handle *handle, - [in] lsa_String *name, - [out] lsa_LUID *luid + [in,ref] lsa_String *name, + [out,ref] lsa_LUID *luid ); @@ -682,14 +708,14 @@ import "security.idl"; } lsa_RightAttribute; typedef struct { - uint32 count; + [range(0,256)] uint32 count; [size_is(count)] lsa_StringLarge *names; } lsa_RightSet; NTSTATUS lsa_EnumAccountRights ( [in] policy_handle *handle, - [in] dom_sid2 *sid, - [out] lsa_RightSet *rights + [in,ref] dom_sid2 *sid, + [out,ref] lsa_RightSet *rights ); @@ -697,17 +723,17 @@ import "security.idl"; /* Function: 0x25 */ NTSTATUS lsa_AddAccountRights ( [in] policy_handle *handle, - [in] dom_sid2 *sid, - [in] lsa_RightSet *rights + [in,ref] dom_sid2 *sid, + [in,ref] lsa_RightSet *rights ); /**********************/ /* Function: 0x26 */ NTSTATUS lsa_RemoveAccountRights ( [in] policy_handle *handle, - [in] dom_sid2 *sid, - [in] uint32 unknown, - [in] lsa_RightSet *rights + [in,ref] dom_sid2 *sid, + [in] uint8 remove_all, + [in,ref] lsa_RightSet *rights ); /* Function: 0x27 */ @@ -737,7 +763,7 @@ import "security.idl"; [public] NTSTATUS lsa_OpenPolicy2 ( [in,unique] [string,charset(UTF16)] uint16 *system_name, [in] lsa_ObjectAttribute *attr, - [in] uint32 access_mask, + [in] lsa_PolicyAccessMask access_mask, [out] policy_handle *handle ); @@ -879,11 +905,11 @@ import "security.idl"; [public] NTSTATUS lsa_LookupSids2( [in] policy_handle *handle, - [in] lsa_SidArray *sids, - [out,unique] lsa_RefDomainList *domains, - [in,out] lsa_TransNameArray2 *names, + [in,ref] lsa_SidArray *sids, + [out,ref] lsa_RefDomainList **domains, + [in,out,ref] lsa_TransNameArray2 *names, [in] uint16 level, - [in,out] uint32 *count, + [in,out,ref] uint32 *count, [in] uint32 unknown1, [in] uint32 unknown2 ); @@ -907,10 +933,10 @@ import "security.idl"; [in] policy_handle *handle, [in,range(0,1000)] uint32 num_names, [in,size_is(num_names)] lsa_String names[], - [out,unique] lsa_RefDomainList *domains, - [in,out] lsa_TransSidArray2 *sids, + [out,ref] lsa_RefDomainList **domains, + [in,out,ref] lsa_TransSidArray2 *sids, [in] lsa_LookupNamesLevel level, - [in,out] uint32 *count, + [in,out,ref] uint32 *count, [in] uint32 unknown1, [in] uint32 unknown2 ); @@ -960,10 +986,10 @@ import "security.idl"; [in] policy_handle *handle, [in,range(0,1000)] uint32 num_names, [in,size_is(num_names)] lsa_String names[], - [out,unique] lsa_RefDomainList *domains, - [in,out] lsa_TransSidArray3 *sids, + [out,ref] lsa_RefDomainList **domains, + [in,out,ref] lsa_TransSidArray3 *sids, [in] lsa_LookupNamesLevel level, - [in,out] uint32 *count, + [in,out,ref] uint32 *count, [in] uint32 unknown1, [in] uint32 unknown2 ); @@ -1035,11 +1061,11 @@ import "security.idl"; /* Function 0x4c */ [public] NTSTATUS lsa_LookupSids3( - [in] lsa_SidArray *sids, - [out,unique] lsa_RefDomainList *domains, - [in,out] lsa_TransNameArray2 *names, + [in,ref] lsa_SidArray *sids, + [out,ref] lsa_RefDomainList **domains, + [in,out,ref] lsa_TransNameArray2 *names, [in] uint16 level, - [in,out] uint32 *count, + [in,out,ref] uint32 *count, [in] uint32 unknown1, [in] uint32 unknown2 ); @@ -1048,10 +1074,10 @@ import "security.idl"; NTSTATUS lsa_LookupNames4( [in,range(0,1000)] uint32 num_names, [in,size_is(num_names)] lsa_String names[], - [out,unique] lsa_RefDomainList *domains, - [in,out] lsa_TransSidArray3 *sids, + [out,ref] lsa_RefDomainList **domains, + [in,out,ref] lsa_TransSidArray3 *sids, [in] lsa_LookupNamesLevel level, - [in,out] uint32 *count, + [in,out,ref] uint32 *count, [in] uint32 unknown1, [in] uint32 unknown2 ); diff --git a/source3/librpc/idl/netlogon.idl b/source3/librpc/idl/netlogon.idl index ae16884896..5979701703 100644 --- a/source3/librpc/idl/netlogon.idl +++ b/source3/librpc/idl/netlogon.idl @@ -245,7 +245,7 @@ interface netlogon [in,unique] netr_Authenticator *credential, [in,out,unique] netr_Authenticator *return_authenticator, [in] uint16 logon_level, - [in] [switch_is(logon_level)] netr_LogonLevel logon, + [in,ref] [switch_is(logon_level)] netr_LogonLevel *logon, [in] uint16 validation_level, [out,ref] [switch_is(validation_level)] netr_Validation *validation, [out,ref] uint8 *authoritative @@ -272,7 +272,8 @@ interface netlogon NTSTATUS netr_ServerReqChallenge( [in,unique,string,charset(UTF16)] uint16 *server_name, [in,string,charset(UTF16)] uint16 computer_name[], - [in,out,ref] netr_Credential *credentials + [in,ref] netr_Credential *credentials, + [out,ref] netr_Credential *return_credentials ); @@ -286,7 +287,8 @@ interface netlogon [in,string,charset(UTF16)] uint16 account_name[], [in] netr_SchannelType secure_channel_type, [in,string,charset(UTF16)] uint16 computer_name[], - [in,out,ref] netr_Credential *credentials + [in,ref] netr_Credential *credentials, + [out,ref] netr_Credential *return_credentials ); @@ -298,9 +300,9 @@ interface netlogon [in] [string,charset(UTF16)] uint16 account_name[], [in] netr_SchannelType secure_channel_type, [in] [string,charset(UTF16)] uint16 computer_name[], - [in] netr_Authenticator credential, - [in] samr_Password new_password, - [out,ref] netr_Authenticator *return_authenticator + [in,ref] netr_Authenticator *credential, + [out,ref] netr_Authenticator *return_authenticator, + [in,ref] samr_Password *new_password ); @@ -680,12 +682,12 @@ interface netlogon NTSTATUS netr_DatabaseDeltas( [in] [string,charset(UTF16)] uint16 logon_server[], [in] [string,charset(UTF16)] uint16 computername[], - [in] netr_Authenticator credential, + [in,ref] netr_Authenticator *credential, [in,out,ref] netr_Authenticator *return_authenticator, [in] netr_SamDatabaseID database_id, [in,out,ref] udlong *sequence_num, - [in] uint32 preferredmaximumlength, - [out,ref] netr_DELTA_ENUM_ARRAY *delta_enum_array + [out,ref] netr_DELTA_ENUM_ARRAY **delta_enum_array, + [in] uint32 preferredmaximumlength ); @@ -796,6 +798,7 @@ interface netlogon /* function_code values */ typedef [v1_enum] enum { + NETLOGON_CONTROL_SYNC = 2, NETLOGON_CONTROL_REDISCOVER = 5, NETLOGON_CONTROL_TC_QUERY = 6, NETLOGON_CONTROL_TRANSPORT_NOTIFY = 7, @@ -834,7 +837,7 @@ interface netlogon [in,unique] [string,charset(UTF16)] uint16 *logon_server, [in] uint32 function_code, [in] uint32 level, - [in][switch_is(function_code)] netr_CONTROL_DATA_INFORMATION data, + [in,ref][switch_is(function_code)] netr_CONTROL_DATA_INFORMATION *data, [out,ref][switch_is(level)] netr_CONTROL_QUERY_INFORMATION *query ); @@ -854,7 +857,8 @@ interface netlogon [in] [string,charset(UTF16)] uint16 account_name[], [in] netr_SchannelType secure_channel_type, [in] [string,charset(UTF16)] uint16 computer_name[], - [in,out,ref] netr_Credential *credentials, + [in,ref] netr_Credential *credentials, + [out,ref] netr_Credential *return_credentials, [in,out,ref] uint32 *negotiate_flags ); @@ -865,13 +869,13 @@ interface netlogon NTSTATUS netr_DatabaseSync2( [in] [string,charset(UTF16)] uint16 logon_server[], [in] [string,charset(UTF16)] uint16 computername[], - [in] netr_Authenticator credential, + [in] netr_Authenticator *credential, [in,out,ref] netr_Authenticator *return_authenticator, [in] netr_SamDatabaseID database_id, [in] uint16 restart_state, [in,out,ref] uint32 *sync_context, - [in] uint32 preferredmaximumlength, - [out,ref] netr_DELTA_ENUM_ARRAY *delta_enum_array + [out,ref] netr_DELTA_ENUM_ARRAY **delta_enum_array, + [in] uint32 preferredmaximumlength ); @@ -1253,7 +1257,7 @@ interface netlogon [in,unique] [string,charset(UTF16)] uint16 *server_name, [in,unique] [string,charset(UTF16)] uint16 *computer_name, [in] uint16 logon_level, - [in] [switch_is(logon_level)] netr_LogonLevel logon, + [in,ref] [switch_is(logon_level)] netr_LogonLevel *logon, [in] uint16 validation_level, [out,ref] [switch_is(validation_level)] netr_Validation *validation, [out,ref] uint8 *authoritative, diff --git a/source3/librpc/idl/ntsvcs.idl b/source3/librpc/idl/ntsvcs.idl index 05ba68e727..af0c7032da 100644 --- a/source3/librpc/idl/ntsvcs.idl +++ b/source3/librpc/idl/ntsvcs.idl @@ -9,69 +9,358 @@ ] interface ntsvcs { - void PNP_Disconnect(); - void PNP_Connect(); - void PNP_GetVersion(); - void PNP_GetGlobalState(); - void PNP_InitDetection(); - void PNP_ReportLogOn(); - void PNP_ValidateDeviceInstance(); - void PNP_GetRootDeviceInstance(); - void PNP_GetRelatedDeviceInstance(); - void PNP_EnumerateSubKeys(); - void PNP_GetDeviceList(); - void PNP_GetDeviceListSize(); - void PNP_GetDepth(); - void PNP_GetDeviceRegProp(); - void PNP_SetDeviceRegProp(); - void PNP_GetClassInstance(); - void PNP_CreateKey(); - void PNP_DeleteRegistryKey(); - void PNP_GetClassCount(); - void PNP_GetClassName(); - void PNP_DeleteClassKey(); - void PNP_GetInterfaceDeviceAlias(); - void PNP_GetInterfaceDeviceList(); - void PNP_GetInterfaceDeviceListSize(); - void PNP_RegisterDeviceClassAssociation(); - void PNP_UnregisterDeviceClassAssociation(); - void PNP_GetClassRegProp(); - void PNP_SetClassRegProp(); - void PNP_CreateDevInst(); - void PNP_DeviceInstanceAction(); - void PNP_GetDeviceStatus(); - void PNP_SetDeviceProblem(); - void PNP_DisableDevInst(); - void PNP_UninstallDevInst(); - void PNP_AddID(); - void PNP_RegisterDriver(); - void PNP_QueryRemove(); - void PNP_RequestDeviceEject(); - void PNP_IsDockStationPresent(); - void PNP_RequestEjectPC(); - void PNP_HwProfFlags(); - void PNP_GetHwProfInfo(); - void PNP_AddEmptyLogConf(); - void PNP_FreeLogConf(); - void PNP_GetFirstLogConf(); - void PNP_GetNextLogConf(); - void PNP_GetLogConfPriority(); - void PNP_AddResDes(); - void PNP_FreeResDes(); - void PNP_GetNextResDes(); - void PNP_GetResDesData(); - void PNP_GetResDesDataSize(); - void PNP_ModifyResDes(); - void PNP_DetectResourceLimit(); - void PNP_QueryResConfList(); - void PNP_SetHwProf(); - void PNP_QueryArbitratorFreeData(); - void PNP_QueryArbitratorFreeSize(); - void PNP_RunDetection(); - void PNP_RegisterNotification(); - void PNP_UnregisterNotification(); - void PNP_GetCustomDevProp(); - void PNP_GetVersionInternal(); - void PNP_GetBlockedDriverInfo(); - void PNP_GetServerSideDeviceInstallFlags(); + /******************/ + /* Function: 0x00 */ + + WERROR PNP_Disconnect(); + + /******************/ + /* Function: 0x01 */ + + WERROR PNP_Connect(); + + /******************/ + /* Function: 0x02 */ + + WERROR PNP_GetVersion( + [out,ref] uint16 *version + ); + + /******************/ + /* Function: 0x03 */ + + WERROR PNP_GetGlobalState(); + + /******************/ + /* Function: 0x04 */ + + WERROR PNP_InitDetection(); + + /******************/ + /* Function: 0x05 */ + + WERROR PNP_ReportLogOn(); + + /******************/ + /* Function: 0x06 */ + + WERROR PNP_ValidateDeviceInstance( + [in,ref] [string,charset(UTF16)] uint16 *devicepath, + [in] uint32 flags + ); + + /******************/ + /* Function: 0x07 */ + + WERROR PNP_GetRootDeviceInstance(); + + /******************/ + /* Function: 0x08 */ + + WERROR PNP_GetRelatedDeviceInstance(); + + /******************/ + /* Function: 0x09 */ + + WERROR PNP_EnumerateSubKeys(); + + /******************/ + /* Function: 0x0a */ + + WERROR PNP_GetDeviceList(); + + /******************/ + /* Function: 0x0b */ + + WERROR PNP_GetDeviceListSize( + [in,unique] [string,charset(UTF16)] uint16 *devicename, + [out,ref] uint32 *size, + [in] uint32 flags + ); + + /******************/ + /* Function: 0x0c */ + + WERROR PNP_GetDepth(); + + /******************/ + /* Function: 0x0d */ + + WERROR PNP_GetDeviceRegProp(); + + /******************/ + /* Function: 0x0e */ + + WERROR PNP_SetDeviceRegProp(); + + /******************/ + /* Function: 0x0f */ + + WERROR PNP_GetClassInstance(); + + /******************/ + /* Function: 0x10 */ + + WERROR PNP_CreateKey(); + + /******************/ + /* Function: 0x11 */ + + WERROR PNP_DeleteRegistryKey(); + + /******************/ + /* Function: 0x12 */ + + WERROR PNP_GetClassCount(); + + /******************/ + /* Function: 0x13 */ + + WERROR PNP_GetClassName(); + + /******************/ + /* Function: 0x14 */ + + WERROR PNP_DeleteClassKey(); + + /******************/ + /* Function: 0x15 */ + + WERROR PNP_GetInterfaceDeviceAlias(); + + /******************/ + /* Function: 0x16 */ + + WERROR PNP_GetInterfaceDeviceList(); + + /******************/ + /* Function: 0x17 */ + + WERROR PNP_GetInterfaceDeviceListSize(); + + /******************/ + /* Function: 0x18 */ + + WERROR PNP_RegisterDeviceClassAssociation(); + + /******************/ + /* Function: 0x19 */ + + WERROR PNP_UnregisterDeviceClassAssociation(); + + /******************/ + /* Function: 0x1a */ + + WERROR PNP_GetClassRegProp(); + + /******************/ + /* Function: 0x1b */ + + WERROR PNP_SetClassRegProp(); + + /******************/ + /* Function: 0x1c */ + + WERROR PNP_CreateDevInst(); + + /******************/ + /* Function: 0x1d */ + + WERROR PNP_DeviceInstanceAction(); + + /******************/ + /* Function: 0x1e */ + + WERROR PNP_GetDeviceStatus(); + + /******************/ + /* Function: 0x1f */ + + WERROR PNP_SetDeviceProblem(); + + /******************/ + /* Function: 0x20 */ + + WERROR PNP_DisableDevInst(); + + /******************/ + /* Function: 0x21 */ + + WERROR PNP_UninstallDevInst(); + + /******************/ + /* Function: 0x22 */ + + WERROR PNP_AddID(); + + /******************/ + /* Function: 0x23 */ + + WERROR PNP_RegisterDriver(); + + /******************/ + /* Function: 0x24 */ + + WERROR PNP_QueryRemove(); + + /******************/ + /* Function: 0x25 */ + + WERROR PNP_RequestDeviceEject(); + + /******************/ + /* Function: 0x26 */ + + WERROR PNP_IsDockStationPresent(); + + /******************/ + /* Function: 0x27 */ + + WERROR PNP_RequestEjectPC(); + + /******************/ + /* Function: 0x28 */ + + WERROR PNP_HwProfFlags( + [in] uint32 unknown1, + [in,ref] [string,charset(UTF16)] uint16 *devicepath, + [in] uint32 unknown2, + [in,out,ref] uint32 *unknown3, + [in,out,unique] uint16 *unknown4, + [in,unique] [string,charset(UTF16)] uint16 *unknown5, + [out,unique] [string,charset(UTF16)] uint16 **unknown5a, + [in] uint32 unknown6, + [in] uint32 unknown7 + ); + + /******************/ + /* Function: 0x29 */ + + typedef struct { + uint32 unknown1; + uint16 unknown2[160]; + uint32 unknown3; + } PNP_HwProfInfo; + + WERROR PNP_GetHwProfInfo( + [in] uint32 idx, + [in,out,ref] PNP_HwProfInfo *info, + [in] uint32 unknown1, + [in] uint32 unknown2 + ); + + /******************/ + /* Function: 0x2a */ + + WERROR PNP_AddEmptyLogConf(); + + /******************/ + /* Function: 0x2b */ + + WERROR PNP_FreeLogConf(); + + /******************/ + /* Function: 0x2c */ + + WERROR PNP_GetFirstLogConf(); + + /******************/ + /* Function: 0x2d */ + + WERROR PNP_GetNextLogConf(); + + /******************/ + /* Function: 0x2e */ + + WERROR PNP_GetLogConfPriority(); + + /******************/ + /* Function: 0x2f */ + + WERROR PNP_AddResDes(); + + /******************/ + /* Function: 0x30 */ + + WERROR PNP_FreeResDes(); + + /******************/ + /* Function: 0x31 */ + + WERROR PNP_GetNextResDes(); + + /******************/ + /* Function: 0x32 */ + + WERROR PNP_GetResDesData(); + + /******************/ + /* Function: 0x33 */ + + WERROR PNP_GetResDesDataSize(); + + /******************/ + /* Function: 0x34 */ + + WERROR PNP_ModifyResDes(); + + /******************/ + /* Function: 0x35 */ + + WERROR PNP_DetectResourceLimit(); + + /******************/ + /* Function: 0x36 */ + + WERROR PNP_QueryResConfList(); + + /******************/ + /* Function: 0x37 */ + + WERROR PNP_SetHwProf(); + + /******************/ + /* Function: 0x38 */ + + WERROR PNP_QueryArbitratorFreeData(); + + /******************/ + /* Function: 0x39 */ + + WERROR PNP_QueryArbitratorFreeSize(); + + /******************/ + /* Function: 0x3a */ + + WERROR PNP_RunDetection(); + + /******************/ + /* Function: 0x3b */ + + WERROR PNP_RegisterNotification(); + + /******************/ + /* Function: 0x3c */ + + WERROR PNP_UnregisterNotification(); + + /******************/ + /* Function: 0x3d */ + + WERROR PNP_GetCustomDevProp(); + + /******************/ + /* Function: 0x3e */ + + WERROR PNP_GetVersionInternal(); + + /******************/ + /* Function: 0x3f */ + + WERROR PNP_GetBlockedDriverInfo(); + + /******************/ + /* Function: 0x40 */ + + WERROR PNP_GetServerSideDeviceInstallFlags(); } diff --git a/source3/librpc/idl/samr.idl b/source3/librpc/idl/samr.idl index ebd1975458..c2449d3088 100644 --- a/source3/librpc/idl/samr.idl +++ b/source3/librpc/idl/samr.idl @@ -316,6 +316,10 @@ import "misc.idl", "lsa.idl", "security.idl"; /************************/ /* Function 0x0b */ + + const int MAX_SAM_ENTRIES_W2K = 0x400; /* 1024 */ + const int MAX_SAM_ENTRIES_W95 = 50; + NTSTATUS samr_EnumDomainGroups( [in] policy_handle *domain_handle, [in,out,ref] uint32 *resume_handle, @@ -779,6 +783,10 @@ import "misc.idl", "lsa.idl", "security.idl"; SAMR_FIELD_OWF_PWD = 0x20000000 } samr_FieldsPresent; + /* used for 'password_expired' in samr_UserInfo21 */ + const int PASS_MUST_CHANGE_AT_NEXT_LOGON = 0x01; + const int PASS_DONT_CHANGE_AT_NEXT_LOGON = 0x00; + typedef struct { NTTIME last_logon; NTTIME last_logoff; @@ -968,7 +976,7 @@ import "misc.idl", "lsa.idl", "security.idl"; typedef struct { uint32 idx; - lsa_AsciiString account_name; + lsa_AsciiStringLarge account_name; } samr_DispEntryAscii; typedef struct { diff --git a/source3/librpc/idl/spoolss.idl b/source3/librpc/idl/spoolss.idl index b64dfa481b..2144393ebd 100644 --- a/source3/librpc/idl/spoolss.idl +++ b/source3/librpc/idl/spoolss.idl @@ -3,16 +3,17 @@ /* spoolss interface definitions */ +import "security.idl", "winreg.idl"; [ uuid("12345678-1234-abcd-ef00-0123456789ab"), version(1.0), endpoint("ncacn_np:[\\pipe\\spoolss]"), pointer_default(unique), helpstring("Spooler SubSystem"), - depends(security), helper("librpc/ndr/ndr_spoolss_buf.h") ] interface spoolss { + typedef [v1_enum] enum winreg_Type winreg_Type; typedef struct { uint16 year; uint16 month; @@ -57,7 +58,7 @@ } spoolss_PrinterInfo0; typedef [public,gensize] struct { - string32 devicename; + [charset(UTF16)] uint16 devicename[32]; uint16 specversion; uint16 driverversion; uint16 size; @@ -76,7 +77,7 @@ uint16 yresolution; uint16 ttoption; uint16 collate; - string32 formname; + [charset(UTF16)] uint16 formname[32]; uint16 logpixels; uint32 bitsperpel; uint32 pelswidth; @@ -103,7 +104,6 @@ PRINTER_ENUM_REMOTE = 0x00000010, PRINTER_ENUM_SHARED = 0x00000020, PRINTER_ENUM_NETWORK = 0x00000040, - PRINTER_ENUM_UNKNOWN_8 = 0x00000008, PRINTER_ENUM_EXPAND = 0x00004000, PRINTER_ENUM_CONTAINER = 0x00008000, PRINTER_ENUM_ICON1 = 0x00010000, @@ -253,13 +253,13 @@ /* we are using this as internal parsing code */ [public,noopnum,noprint] WERROR _spoolss_EnumPrinters( [in] spoolss_EnumPrinterFlags flags, - [in] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *server, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out] DATA_BLOB *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count ); [public,noopnum,noprint] void __spoolss_EnumPrinters( [in] uint32 level, @@ -268,16 +268,16 @@ ); [nopull,nopush] WERROR spoolss_EnumPrinters( [in] spoolss_EnumPrinterFlags flags, - [in] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *server, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, /* what we have here is a subcontext containing an array of no discriminant unions * and the array has no size in front */ - [out,switch_is(level),size_is(count)] spoolss_PrinterInfo *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique,switch_is(level),size_is(count)] spoolss_PrinterInfo *info, + [out] uint32 needed, + [out] uint32 count ); /******************/ @@ -287,9 +287,9 @@ [subcontext(4),subcontext_size(_ndr_size)] spoolss_DeviceMode *devmode; } spoolss_DevmodeContainer; - WERROR spoolss_OpenPrinter( - [in] [string,charset(UTF16)] uint16 *printername, - [in] [string,charset(UTF16)] uint16 *datatype, + [public] WERROR spoolss_OpenPrinter( + [in,unique] [string,charset(UTF16)] uint16 *printername, + [in,unique] [string,charset(UTF16)] uint16 *datatype, [in] spoolss_DevmodeContainer devmode_ctr, [in] uint32 access_mask, [out,ref] policy_handle *handle @@ -338,7 +338,7 @@ WERROR spoolss_SetJob( [in,ref] policy_handle *handle, [in] uint32 job_id, - [in] spoolss_JobInfoContainer *ctr, + [in,unique] spoolss_JobInfoContainer *ctr, [in] spoolss_JobControl command ); @@ -348,10 +348,10 @@ [in,ref] policy_handle *handle, [in] uint32 job_id, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_JobInfo *info, - [out] uint32 *needed + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_JobInfo *info, + [out] uint32 needed ); /******************/ @@ -361,11 +361,11 @@ [in] uint32 firstjob, [in] uint32 numjobs, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out] DATA_BLOB *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count ); [public,noopnum,noprint] void __spoolss_EnumJobs( [in] uint32 level, @@ -377,11 +377,11 @@ [in] uint32 firstjob, [in] uint32 numjobs, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,switch_is(level),size_is(count)] spoolss_JobInfo *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique,switch_is(level),size_is(count)] spoolss_JobInfo *info, + [out] uint32 needed, + [out] uint32 count ); /******************/ @@ -431,13 +431,13 @@ /******************/ /* Function: 0x08 */ - WERROR spoolss_GetPrinter( + [public] WERROR spoolss_GetPrinter( [in,ref] policy_handle *handle, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_PrinterInfo *info, - [out] uint32 *needed + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_PrinterInfo *info, + [out] uint32 needed ); /******************/ @@ -537,14 +537,14 @@ /******************/ /* Function: 0x0a */ [public,noopnum,noprint] WERROR _spoolss_EnumPrinterDrivers( - [in] [string,charset(UTF16)] uint16 *server, - [in] [string,charset(UTF16)] uint16 *environment, + [in,unique] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *environment, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out] DATA_BLOB *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count ); [public,noopnum,noprint] void __spoolss_EnumPrinterDrivers( [in] uint32 level, @@ -552,14 +552,14 @@ [out,switch_is(level)] spoolss_DriverInfo info[count] ); [nopull,nopush] WERROR spoolss_EnumPrinterDrivers( - [in] [string,charset(UTF16)] uint16 *server, - [in] [string,charset(UTF16)] uint16 *environment, + [in,unique] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *environment, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,switch_is(level),size_is(count)] spoolss_DriverInfo *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique,switch_is(level),size_is(count)] spoolss_DriverInfo *info, + [out] uint32 needed, + [out] uint32 count ); /******************/ @@ -581,21 +581,21 @@ [default] spoolss_DriverDirectoryInfo1 info1; } spoolss_DriverDirectoryInfo; - WERROR spoolss_GetPrinterDriverDirectory( - [in] [string,charset(UTF16)] uint16 *server, - [in] [string,charset(UTF16)] uint16 *environment, + [public] WERROR spoolss_GetPrinterDriverDirectory( + [in,unique] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *environment, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_DriverDirectoryInfo *info, - [out] uint32 *needed + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_DriverDirectoryInfo *info, + [out] uint32 needed ); /******************/ /* Function: 0x0d */ WERROR spoolss_DeletePrinterDriver( [in,ref] policy_handle *handle, - [in] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *server, [in] [string,charset(UTF16)] uint16 architecture[], [in] [string,charset(UTF16)] uint16 driver[] ); @@ -617,14 +617,14 @@ } spoolss_PrintProcessorInfo; [public,noopnum,noprint] WERROR _spoolss_EnumPrintProcessors( - [in] [string,charset(UTF16)] uint16 *servername, - [in] [string,charset(UTF16)] uint16 *environment, + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *environment, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out] DATA_BLOB *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count ); [public,noopnum,noprint] void __spoolss_EnumPrintProcessors( [in] uint32 level, @@ -632,14 +632,14 @@ [out,switch_is(level)] spoolss_PrintProcessorInfo info[count] ); [nopull,nopush] WERROR spoolss_EnumPrintProcessors( - [in] [string,charset(UTF16)] uint16 *servername, - [in] [string,charset(UTF16)] uint16 *environment, + [in,unique] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *environment, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,switch_is(level),size_is(count)] spoolss_PrintProcessorInfo *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique,switch_is(level),size_is(count)] spoolss_PrintProcessorInfo *info, + [out] uint32 needed, + [out] uint32 count ); /******************/ @@ -666,7 +666,7 @@ [in,ref] policy_handle *handle, [in] uint32 level, [in,switch_is(level)] spoolss_DocumentInfo info, - [out] uint32 *job_id + [out] uint32 job_id ); /******************/ @@ -681,7 +681,7 @@ [in,ref] policy_handle *handle, [in] DATA_BLOB data, [in,value(r->in.data.length)] uint32 _data_size, - [out] uint32 *num_written + [out] uint32 num_written ); /******************/ @@ -701,8 +701,8 @@ WERROR spoolss_ReadPrinter( [in,ref] policy_handle *handle, [in] uint32 data_size, - [out] DATA_BLOB *data, - [out,value(r->out.data.length)] uint32 *_data_size + [out] DATA_BLOB data, + [out,value(r->out.data.length)] uint32 _data_size ); /******************/ @@ -766,21 +766,21 @@ [in,ref] policy_handle *handle, [in] [string,charset(UTF16)] uint16 value_name[], [in] uint32 offered, - [out] spoolss_PrinterDataType *type, - [out] DATA_BLOB *data, - [out] uint32 *needed + [out] spoolss_PrinterDataType type, + [out] DATA_BLOB data, + [out] uint32 needed ); [noopnum,noprint,public] void __spoolss_GetPrinterData( [in] spoolss_PrinterDataType type, - [out,switch_is(type)] spoolss_PrinterData *data + [out,switch_is(type)] spoolss_PrinterData data ); - [nopull,nopush] WERROR spoolss_GetPrinterData( + [nopull,nopush,public] WERROR spoolss_GetPrinterData( [in,ref] policy_handle *handle, [in] [string,charset(UTF16)] uint16 value_name[], [in] uint32 offered, - [out] spoolss_PrinterDataType *type, - [out,subcontext(4),subcontext_size(offered),switch_is(type)] spoolss_PrinterData *data, - [out] uint32 *needed + [out] spoolss_PrinterDataType type, + [out,subcontext(4),subcontext_size(offered),switch_is(type)] spoolss_PrinterData data, + [out] uint32 needed ); /******************/ @@ -790,11 +790,11 @@ [in] [string,charset(UTF16)] uint16 value_name[], [in] spoolss_PrinterDataType type, [in] DATA_BLOB data, - [in] uint32 *_offered + [in] uint32 _offered ); [noopnum,nopull,noprint,public] void __spoolss_SetPrinterData( [in] spoolss_PrinterDataType type, - [out,switch_is(type)] spoolss_PrinterData *data + [out,switch_is(type)] spoolss_PrinterData data ); [nopush] WERROR spoolss_SetPrinterData( [in,ref] policy_handle *handle, @@ -811,7 +811,7 @@ /******************/ /* Function: 0x1d */ - WERROR spoolss_ClosePrinter( + [public] WERROR spoolss_ClosePrinter( [in,out,ref] policy_handle *handle ); @@ -877,10 +877,10 @@ [in,ref] policy_handle *handle, [in] [string,charset(UTF16)] uint16 form_name[], [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_FormInfo *info, - [out] uint32 *needed + [out,unique,subcontext(4),subcontext_size(offered),switch_is(level)] spoolss_FormInfo *info, + [out] uint32 needed ); /******************/ @@ -897,11 +897,11 @@ [public,noopnum,noprint] WERROR _spoolss_EnumForms( [in,ref] policy_handle *handle, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out] DATA_BLOB *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count ); [public,noopnum,noprint] void __spoolss_EnumForms( [in] uint32 level, @@ -911,11 +911,11 @@ [nopull,nopush] WERROR spoolss_EnumForms( [in,ref] policy_handle *handle, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,switch_is(level),size_is(count)] spoolss_FormInfo *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique,switch_is(level),size_is(count)] spoolss_FormInfo *info, + [out] uint32 needed, + [out] uint32 count ); typedef struct { @@ -947,13 +947,13 @@ /******************/ /* Function: 0x23 */ [public,noopnum,noprint] WERROR _spoolss_EnumPorts( - [in] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *servername, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out] DATA_BLOB *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count ); [public,noopnum,noprint] void __spoolss_EnumPorts( [in] uint32 level, @@ -961,13 +961,13 @@ [out,switch_is(level)] spoolss_PortInfo info[count] ); [nopull,nopush] WERROR spoolss_EnumPorts( - [in] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *servername, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,switch_is(level),size_is(count)] spoolss_PortInfo *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique,switch_is(level),size_is(count)] spoolss_PortInfo *info, + [out] uint32 needed, + [out] uint32 count ); /******************/ @@ -989,13 +989,13 @@ } spoolss_MonitorInfo; [public,noopnum,noprint] WERROR _spoolss_EnumMonitors( - [in] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *servername, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out] DATA_BLOB *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 count ); [public,noopnum,noprint] void __spoolss_EnumMonitors( [in] uint32 level, @@ -1003,19 +1003,19 @@ [out,switch_is(level)] spoolss_MonitorInfo info[count] ); [nopull,nopush] WERROR spoolss_EnumMonitors( - [in] [string,charset(UTF16)] uint16 *servername, + [in,unique] [string,charset(UTF16)] uint16 *servername, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, - [out,switch_is(level),size_is(count)] spoolss_MonitorInfo *info, - [out] uint32 *needed, - [out] uint32 *count + [out,unique,switch_is(level),size_is(count)] spoolss_MonitorInfo *info, + [out] uint32 needed, + [out] uint32 count ); /******************/ /* Function: 0x25 */ WERROR spoolss_AddPort( - [in] [string,charset(UTF16)] uint16 *server_name, + [in,unique] [string,charset(UTF16)] uint16 *server_name, [in] uint32 unknown, [in] [string,charset(UTF16)] uint16 monitor_name[] ); @@ -1101,16 +1101,16 @@ /* Function: 0x35 */ WERROR spoolss_GetPrinterDriver2( [in,ref] policy_handle *handle, - [in] [string,charset(UTF16)] uint16 *architecture, + [in,unique] [string,charset(UTF16)] uint16 *architecture, [in] uint32 level, - [in] DATA_BLOB *buffer, + [in,unique] DATA_BLOB *buffer, [in] uint32 offered, [in] uint32 client_major_version, [in] uint32 client_minor_version, - [out] DATA_BLOB *info, - [out] uint32 *needed, - [out] uint32 *server_major_version, - [out] uint32 *server_minor_version + [out,unique] DATA_BLOB *info, + [out] uint32 needed, + [out] uint32 server_major_version, + [out] uint32 server_minor_version ); /******************/ @@ -1125,7 +1125,8 @@ /******************/ /* Function: 0x38 */ - WERROR spoolss_FindClosePrinterNotify( + [public] WERROR spoolss_FindClosePrinterNotify( + [in,ref] policy_handle *handle ); /******************/ @@ -1135,7 +1136,13 @@ /******************/ /* Function: 0x3a */ - WERROR spoolss_ReplyOpenPrinter( + [public] WERROR spoolss_ReplyOpenPrinter( + [in,string,charset(UTF16)] uint16 server_name[], + [in] uint32 printer_local, + [in] winreg_Type type, + [in] uint32 unknown1, + [in] uint32 unknown2, + [out,ref] policy_handle *handle ); /******************/ @@ -1145,7 +1152,8 @@ /******************/ /* Function: 0x3c */ - WERROR spoolss_ReplyClosePrinter( + [public] WERROR spoolss_ReplyClosePrinter( + [in,out,ref] policy_handle *handle ); /******************/ @@ -1168,31 +1176,65 @@ WERROR spoolss_ResetPrinterEx( ); + typedef [enum16bit] enum { + SPOOLSS_FIELD_SERVER_NAME = 0, + SPOOLSS_FIELD_PRINTER_NAME = 1, + SPOOLSS_FIELD_SHARE_NAME = 2, + SPOOLSS_FIELD_PORT_NAME = 3, + SPOOLSS_FIELD_DRIVER_NAME = 4, + SPOOLSS_FIELD_COMMENT = 5, + SPOOLSS_FIELD_LOCATION = 6, + SPOOLSS_FIELD_DEVMODE = 7, + SPOOLSS_FIELD_SEPFILE = 8, + SPOOLSS_FIELD_PRINT_PROCESSOR = 9, + SPOOLSS_FIELD_PARAMETERS = 10, + SPOOLSS_FIELD_DATATYPE = 11, + SPOOLSS_FIELD_SECURITY_DESCRIPTOR=12, + SPOOLSS_FIELD_ATTRIBUTES = 13, + SPOOLSS_FIELD_PRIORITY = 14, + SPOOLSS_FIELD_DEFAULT_PRIORITY = 15, + SPOOLSS_FIELD_START_TIME = 16, + SPOOLSS_FIELD_UNTIL_TIME = 17, + SPOOLSS_FIELD_STATUS = 18, + SPOOLSS_FIELD_STATUS_STRING = 19, + SPOOLSS_FIELD_CJOBS = 20, + SPOOLSS_FIELD_AVERAGE_PPM = 21, + SPOOLSS_FIELD_TOTAL_PAGES = 22, + SPOOLSS_FIELD_PAGES_PRINTED = 23, + SPOOLSS_FIELD_TOTAL_BYTES = 24, + SPOOLSS_FIELD_BYTES_PRINTED = 25 + } spoolss_Field; + + typedef [enum16bit] enum { + SPOOLSS_NOTIFY_PRINTER = 0, + SPOOLSS_NOTIFY_JOB = 1 + } spoolss_NotifyType; + /******************/ /* Function: 0x41 */ - typedef [flag(NDR_PAHEX)] struct { + typedef struct { + spoolss_NotifyType type; uint16 u1; - uint16 u2; + uint32 u2; uint32 u3; - uint32 u4; uint32 count; - [size_is(count)] uint16 *array; - } spoolss_RemoteFindFirstPrinterChangeNotifyEx_t2; + [size_is(count)] spoolss_Field *fields; + } spoolss_NotifyOptionsArray; typedef struct { - uint32 u1; - uint32 u2; + uint32 version; + uint32 flags; uint32 count; - [size_is(count)] spoolss_RemoteFindFirstPrinterChangeNotifyEx_t2 *t2; - } spoolss_RemoteFindFirstPrinterChangeNotifyEx_t1; + [size_is(count)] spoolss_NotifyOptionsArray *options; + } spoolss_NotifyOptionsContainer; - WERROR spoolss_RemoteFindFirstPrinterChangeNotifyEx( + [public] WERROR spoolss_RemoteFindFirstPrinterChangeNotifyEx( [in,ref] policy_handle *handle, - [in] uint32 u1, - [in] uint32 u2, - [in] [string,charset(UTF16)] uint16 *str, - [in] uint32 u3, - [in] spoolss_RemoteFindFirstPrinterChangeNotifyEx_t1 *t1 + [in] uint32 flags, + [in] uint32 options, + [in,unique] [string,charset(UTF16)] uint16 *str, + [in] uint32 printer_local, + [in,unique] spoolss_NotifyOptionsContainer *t1 ); /******************/ @@ -1200,9 +1242,55 @@ WERROR spoolss_RouterRefreshPrinterChangeNotification( ); + typedef struct { + uint32 size; + [size_is(size/2),unique,charset(UTF16)] uint16 *string; + } spoolss_NotifyUTF16String; + + typedef struct { + uint32 size; + [size_is(size),charset(DOS)] uint8 *string; + } spoolss_NotifyDOSString; + + typedef struct { + uint16 data[8]; + } spoolss_NotifyBlobData; + + typedef struct { + uint32 len; + [unique] spoolss_NotifyBlobData *data; + } spoolss_NotifyBlob; + + typedef [switch_type(uint32)] union { + [case(1)] dlong integer; + [case(2)] spoolss_NotifyUTF16String utf16_string; + [case(3)] spoolss_NotifyDOSString ascii_string; + [case(4)] spoolss_NotifyBlob blob; + [case(5)] spoolss_NotifyDOSString ascii_string; + } spoolss_NotifyData; + + typedef struct { + spoolss_NotifyType type; + spoolss_Field field; + uint32 variable_type; + uint32 job_id; + [switch_is(variable_type)] spoolss_NotifyData data; + } spoolss_Notify; + + typedef struct { + uint32 version; + uint32 flags; + uint32 count; + [size_is(count)] spoolss_Notify notifies[]; + } spoolss_NotifyInfo; + /******************/ /* Function: 0x43 */ - WERROR spoolss_RemoteFindNextPrinterChangeNotifyEx( + [public] WERROR spoolss_RemoteFindNextPrinterChangeNotifyEx( + [in,ref] policy_handle *handle, + [in] uint32 change_low, + [in,unique] spoolss_NotifyOptionsContainer *container, + [out, unique] spoolss_NotifyInfo *info ); /******************/ @@ -1224,11 +1312,72 @@ [case(1)] spoolss_UserLevel1 *level1; } spoolss_UserLevel; + typedef bitmap { + SERVER_ACCESS_ADMINISTER = 0x00000001, + SERVER_ACCESS_ENUMERATE = 0x00000002, + PRINTER_ACCESS_ADMINISTER = 0x00000004, + PRINTER_ACCESS_USE = 0x00000008, + JOB_ACCESS_ADMINISTER = 0x00000010 + } spoolss_AccessRights; + + /* Access rights for print servers */ + const int SERVER_ALL_ACCESS = SEC_STD_REQUIRED | + SERVER_ACCESS_ADMINISTER | + SERVER_ACCESS_ENUMERATE; + + const int SERVER_READ = SEC_STD_READ_CONTROL | + SERVER_ACCESS_ENUMERATE; + + const int SERVER_WRITE = STANDARD_RIGHTS_WRITE_ACCESS | + SERVER_ACCESS_ADMINISTER | + SERVER_ACCESS_ENUMERATE; + + const int SERVER_EXECUTE = SEC_STD_READ_CONTROL | + SERVER_ACCESS_ENUMERATE; + + /* Access rights for printers */ + const int PRINTER_ALL_ACCESS = SEC_STD_REQUIRED | + PRINTER_ACCESS_ADMINISTER | + PRINTER_ACCESS_USE; + + const int PRINTER_READ = SEC_STD_READ_CONTROL | + PRINTER_ACCESS_USE; + + const int PRINTER_WRITE = STANDARD_RIGHTS_WRITE_ACCESS | + PRINTER_ACCESS_USE; + + const int PRINTER_EXECUTE = SEC_STD_READ_CONTROL | + PRINTER_ACCESS_USE; + + /* Access rights for jobs */ + const int JOB_ALL_ACCESS = SEC_STD_REQUIRED | + JOB_ACCESS_ADMINISTER; + + const int JOB_READ = SEC_STD_READ_CONTROL | + JOB_ACCESS_ADMINISTER; + + const int JOB_WRITE = STANDARD_RIGHTS_WRITE_ACCESS | + JOB_ACCESS_ADMINISTER; + + const int JOB_EXECUTE = SEC_STD_READ_CONTROL | + JOB_ACCESS_ADMINISTER; + + /* ACE masks for various print permissions */ + const int PRINTER_ACE_FULL_CONTROL = SEC_GENERIC_ALL | + PRINTER_ALL_ACCESS; + + const int PRINTER_ACE_MANAGE_DOCUMENTS = SEC_GENERIC_ALL | + READ_CONTROL_ACCESS; + + const int PRINTER_ACE_PRINT = GENERIC_EXECUTE_ACCESS | + READ_CONTROL_ACCESS | + PRINTER_ACCESS_USE; + /******************/ /* Function: 0x45 */ - WERROR spoolss_OpenPrinterEx( - [in] [string,charset(UTF16)] uint16 *printername, - [in] [string,charset(UTF16)] uint16 *datatype, + [public] WERROR spoolss_OpenPrinterEx( + [in,unique] [string,charset(UTF16)] uint16 *printername, + [in,unique] [string,charset(UTF16)] uint16 *datatype, [in] spoolss_DevmodeContainer devmode_ctr, [in] uint32 access_mask, [in] uint32 level, @@ -1239,11 +1388,11 @@ /******************/ /* Function: 0x46 */ WERROR spoolss_AddPrinterEx( - [in] [string,charset(UTF16)] uint16 *server, + [in,unique] [string,charset(UTF16)] uint16 *server, [in] uint32 level, - [in,switch_is(level)] spoolss_PrinterInfo *info, + [in,unique,switch_is(level)] spoolss_PrinterInfo *info, [in] spoolss_DevmodeContainer devmode_ctr, - [in] security_descriptor *secdesc, + [in,unique] security_descriptor *secdesc, [in] uint32 ulevel, [in,switch_is(ulevel)] spoolss_UserLevel userlevel ); @@ -1258,12 +1407,13 @@ WERROR spoolss_EnumPrinterData( [in,ref] policy_handle *handle, [in] uint32 enum_index, + [out,ref,size_is(value_offered/2),charset(UTF16)] uint16 *value_name, [in] uint32 value_offered, - [out] lstring *value_name, - [out] uint32 *value_needed, - [out] uint32 *printerdata_type, - [out] DATA_BLOB *buffer, - [in,out,ref] uint32 *data_size + [out,ref] uint32 *value_needed, + [out,ref] uint32 *printerdata_type, + [out,ref] DATA_BLOB *buffer, + [in] uint32 data_offered, + [out,ref] uint32 *data_needed ); /******************/ @@ -1306,25 +1456,30 @@ [in] [string,charset(UTF16)] uint16 key_name[], [in] [string,charset(UTF16)] uint16 value_name[], [in] uint32 offered, - [out] uint32 *type, - [out] DATA_BLOB *buffer, - [out] uint32 *needed + [out] uint32 type, + [out] DATA_BLOB buffer, + [out] uint32 needed ); /******************/ /* Function: 0x4f */ - WERROR spoolss_EnumPrinterDataEx( + [public] WERROR spoolss_EnumPrinterDataEx( [in,ref] policy_handle *handle, [in] [string,charset(UTF16)] uint16 key_name[], [in] uint32 offered, - [out] DATA_BLOB *buffer, - [out] uint32 *needed, - [out] uint32 *count + [out] DATA_BLOB buffer, + [out] uint32 needed, + [out] uint32 count ); /******************/ /* Function: 0x50 */ - WERROR spoolss_EnumPrinterKey( + [public] WERROR spoolss_EnumPrinterKey( + [in, ref] policy_handle *handle, + [in] [string,charset(UTF16)] uint16 key_name[], + [out] uint32 key_buffer_size, + [out] uint16 key_buffer[key_buffer_size], + [in,out] uint32 needed ); /******************/ @@ -1374,14 +1529,14 @@ [in,value(r->in.in_data.length)] uint32 _in_data_length, [in] uint32 offered, [in] uint32 unknown1, - [out] DATA_BLOB *out_data, - [out] uint32 *needed, - [out] uint32 *unknown2 + [out] DATA_BLOB out_data, + [out] uint32 needed, + [out] uint32 unknown2 ); /******************/ /* Function: 0x59 */ - WERROR spoolss_AddPrinterDriverEx( + [public] WERROR spoolss_AddPrinterDriverEx( ); /******************/ diff --git a/source3/librpc/idl/srvsvc.idl b/source3/librpc/idl/srvsvc.idl index 2f23fd1e70..4ad7bebdbd 100644 --- a/source3/librpc/idl/srvsvc.idl +++ b/source3/librpc/idl/srvsvc.idl @@ -577,7 +577,7 @@ import "security.idl", "svcctl.idl"; [in,unique] [string,charset(UTF16)] uint16 *server_unc, [in] [string,charset(UTF16)] uint16 share_name[], [in] uint32 level, - [in,switch_is(level)] srvsvc_NetShareInfo info, + [in,ref,switch_is(level)] srvsvc_NetShareInfo *info, [in,out,unique] uint32 *parm_error ); @@ -1120,7 +1120,7 @@ import "security.idl", "svcctl.idl"; WERROR srvsvc_NetSrvSetInfo( [in,unique] [string,charset(UTF16)] uint16 *server_unc, [in] uint32 level, - [in,switch_is(level)] srvsvc_NetSrvInfo info, + [in,ref,switch_is(level)] srvsvc_NetSrvInfo *info, [in,out,unique] uint32 *parm_error ); @@ -1299,7 +1299,7 @@ import "security.idl", "svcctl.idl"; /* Function: 0x1c */ WERROR srvsvc_NetRemoteTOD( [in,unique] [string,charset(UTF16)] uint16 *server_unc, - [out,unique] srvsvc_NetRemoteTODInfo *info + [out,ref] srvsvc_NetRemoteTODInfo **info ); /**************************/ diff --git a/source3/librpc/idl/svcctl.idl b/source3/librpc/idl/svcctl.idl index 97c9f0e24b..e36a0918bf 100644 --- a/source3/librpc/idl/svcctl.idl +++ b/source3/librpc/idl/svcctl.idl @@ -115,11 +115,20 @@ /*****************/ /* Function 0x04 */ WERROR svcctl_QueryServiceObjectSecurity( + [in] policy_handle *handle, + [in] uint32 security_flags, + [out,ref,size_is(buffer_size)] uint8 *buffer, + [in,range(0,0x40000)] uint32 buffer_size, + [out,ref,range(0,0x40000)] uint32 *needed ); /*****************/ /* Function 0x05 */ WERROR svcctl_SetServiceObjectSecurity( + [in] policy_handle *handle, + [in] uint32 security_flags, + [in,ref,size_is(buffer_size)] uint8 *buffer, + [in] uint32 buffer_size ); /*****************/ diff --git a/source3/librpc/idl/unixinfo.idl b/source3/librpc/idl/unixinfo.idl deleted file mode 100644 index 48bc565fff..0000000000 --- a/source3/librpc/idl/unixinfo.idl +++ /dev/null @@ -1,56 +0,0 @@ -#include "idl_types.h" -/* - Unixinfo interface definition -*/ - -import "security.idl"; - -[ uuid("9c54e310-a955-4885-bd31-78787147dfa6"), - version(0.0), - endpoint("ncacn_np:[\\pipe\\unixinfo]", "ncacn_ip_tcp:", "ncalrpc:"), - pointer_default(unique), - helpstring("Unixinfo specific stuff") -] interface unixinfo -{ - /******************/ - /* Function: 0x00 */ - NTSTATUS unixinfo_SidToUid ( - [in] dom_sid sid, - [out] hyper *uid - ); - - /******************/ - /* Function: 0x01 */ - NTSTATUS unixinfo_UidToSid ( - [in] hyper uid, - [out] dom_sid *sid - ); - - /******************/ - /* Function: 0x02 */ - NTSTATUS unixinfo_SidToGid ( - [in] dom_sid sid, - [out] hyper *gid - ); - - /******************/ - /* Function: 0x03 */ - NTSTATUS unixinfo_GidToSid ( - [in] hyper gid, - [out] dom_sid *sid - ); - - typedef struct { - NTSTATUS status; - utf8string homedir; - utf8string shell; - } unixinfo_GetPWUidInfo; - - /******************/ - /* Function: 0x04 */ - NTSTATUS unixinfo_GetPWUid ( - [in,out,ref,range(0,1023)] uint32 *count, - [in,size_is(*count)] hyper uids[], - [out,size_is(*count)] unixinfo_GetPWUidInfo infos[*] - ); -} diff --git a/source3/librpc/ndr/ndr.c b/source3/librpc/ndr/ndr.c index 62a88a8856..53eff00d59 100644 --- a/source3/librpc/ndr/ndr.c +++ b/source3/librpc/ndr/ndr.c @@ -176,12 +176,16 @@ _PUBLIC_ void ndr_print_debug_helper(struct ndr_print *ndr, const char *format, { va_list ap; char *s = NULL; - int i; + int i, ret; va_start(ap, format); - vasprintf(&s, format, ap); + ret = vasprintf(&s, format, ap); va_end(ap); + if (ret == -1) { + return; + } + for (i=0;i<ndr->depth;i++) { DEBUGADD(0,(" ")); } @@ -450,11 +454,16 @@ _PUBLIC_ enum ndr_err_code ndr_pull_error(struct ndr_pull *ndr, { char *s=NULL; va_list ap; + int ret; va_start(ap, format); - vasprintf(&s, format, ap); + ret = vasprintf(&s, format, ap); va_end(ap); + if (ret == -1) { + return NDR_ERR_ALLOC; + } + DEBUG(3,("ndr_pull_error(%u): %s\n", ndr_err, s)); free(s); @@ -471,11 +480,16 @@ _PUBLIC_ enum ndr_err_code ndr_push_error(struct ndr_push *ndr, { char *s=NULL; va_list ap; + int ret; va_start(ap, format); - vasprintf(&s, format, ap); + ret = vasprintf(&s, format, ap); va_end(ap); + if (ret == -1) { + return NDR_ERR_ALLOC; + } + DEBUG(3,("ndr_push_error(%u): %s\n", ndr_err, s)); free(s); diff --git a/source3/librpc/ndr/ndr_basic.c b/source3/librpc/ndr/ndr_basic.c index 54397c9469..f342c6e36f 100644 --- a/source3/librpc/ndr/ndr_basic.c +++ b/source3/librpc/ndr/ndr_basic.c @@ -773,8 +773,7 @@ _PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name, ndr->depth++; for (i=0;i<count;i++) { char *idx=NULL; - asprintf(&idx, "[%d]", i); - if (idx) { + if (asprintf(&idx, "[%d]", i) != -1) { ndr_print_uint8(ndr, idx, data[i]); free(idx); } diff --git a/source3/librpc/ndr/ndr_krb5pac.c b/source3/librpc/ndr/ndr_krb5pac.c new file mode 100644 index 0000000000..b0eab44012 --- /dev/null +++ b/source3/librpc/ndr/ndr_krb5pac.c @@ -0,0 +1,141 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling spoolss subcontext buffer structures + + Copyright (C) Stefan Metzmacher 2005 + + 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/ndr_krb5pac.h" + +static size_t _ndr_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags) +{ + size_t s = ndr_size_PAC_INFO(r, level, flags); + switch (level) { + case PAC_TYPE_LOGON_INFO: + return NDR_ROUND(s,8); + default: + return s; + } +} + +static size_t _subcontext_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags) +{ + size_t s = ndr_size_PAC_INFO(r, level, flags); + return NDR_ROUND(s,8); +} + +enum ndr_err_code ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const struct PAC_BUFFER *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,0))); + { + uint32_t _flags_save_PAC_INFO = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_push_relative_ptr1(ndr, r->info)); + ndr->flags = _flags_save_PAC_INFO; + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_PAC_INFO = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + if (r->info) { + NDR_CHECK(ndr_push_relative_ptr2(ndr, r->info)); + { + struct ndr_push *_ndr_info; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0))); + NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->info, r->type)); + NDR_CHECK(ndr_push_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0))); + } + } + ndr->flags = _flags_save_PAC_INFO; + } + } + return NDR_ERR_SUCCESS; +} + +enum ndr_err_code ndr_pull_PAC_BUFFER(struct ndr_pull *ndr, int ndr_flags, struct PAC_BUFFER *r) +{ + uint32_t _ptr_info; + TALLOC_CTX *_mem_save_info_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_PAC_TYPE(ndr, NDR_SCALARS, &r->type)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size)); + { + uint32_t _flags_save_PAC_INFO = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); + if (_ptr_info) { + NDR_PULL_ALLOC(ndr, r->info); + NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->info, _ptr_info)); + } else { + r->info = NULL; + } + ndr->flags = _flags_save_PAC_INFO; + } + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); + } + if (ndr_flags & NDR_BUFFERS) { + { + uint32_t _flags_save_PAC_INFO = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + if (r->info) { + uint32_t _relative_save_offset; + _relative_save_offset = ndr->offset; + NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->info)); + _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->info, 0); + { + struct ndr_pull *_ndr_info; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 0, r->_ndr_size)); + NDR_CHECK(ndr_pull_set_switch_value(_ndr_info, r->info, r->type)); + NDR_CHECK(ndr_pull_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_info, 0, r->_ndr_size)); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0); + ndr->offset = _relative_save_offset; + } + ndr->flags = _flags_save_PAC_INFO; + } + } + return NDR_ERR_SUCCESS; +} + +void ndr_print_PAC_BUFFER(struct ndr_print *ndr, const char *name, const struct PAC_BUFFER *r) +{ + ndr_print_struct(ndr, name, "PAC_BUFFER"); + ndr->depth++; + ndr_print_PAC_TYPE(ndr, "type", r->type); + ndr_print_uint32(ndr, "_ndr_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?_ndr_size_PAC_INFO(r->info,r->type,0):r->_ndr_size); + ndr_print_ptr(ndr, "info", r->info); + ndr->depth++; + if (r->info) { + ndr_print_set_switch_value(ndr, r->info, r->type); + ndr_print_PAC_INFO(ndr, "info", r->info); + } + ndr->depth--; + ndr_print_uint32(ndr, "_pad", r->_pad); + ndr->depth--; +} diff --git a/source3/librpc/ndr/ndr_string.c b/source3/librpc/ndr/ndr_string.c index 711dbce538..e553443bd8 100644 --- a/source3/librpc/ndr/ndr_string.c +++ b/source3/librpc/ndr/ndr_string.c @@ -633,8 +633,7 @@ _PUBLIC_ void ndr_print_string_array(struct ndr_print *ndr, const char *name, co ndr->depth++; for (i=0;i<count;i++) { char *idx=NULL; - asprintf(&idx, "[%d]", i); - if (idx) { + if (asprintf(&idx, "[%d]", i) != -1) { ndr_print_string(ndr, idx, a[i]); free(idx); } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e97be98fc1..912b841d5e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -581,8 +581,8 @@ static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B if (cli_is_error(cli) && !NT_STATUS_EQUAL( cli_get_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(0, ("cli_session_setup_blob: recieve failed (%s)\n", - nt_errstr(cli_get_nt_error(cli)) )); + DEBUG(0, ("cli_session_setup_blob: receive failed " + "(%s)\n", nt_errstr(cli_get_nt_error(cli)))); cli->vuid = 0; return False; } @@ -757,9 +757,9 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use /* 'resign' the last message, so we get the right sequence numbers for checking the first reply from the server */ - cli_calculate_sign_mac(cli); + cli_calculate_sign_mac(cli, cli->outbuf); - if (!cli_check_sign_mac(cli)) { + if (!cli_check_sign_mac(cli, cli->inbuf)) { nt_status = NT_STATUS_ACCESS_DENIED; } } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3b7669f33e..64191239d3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -164,7 +164,7 @@ bool cli_receive_smb(struct cli_state *cli) return false; } - if (!cli_check_sign_mac(cli)) { + if (!cli_check_sign_mac(cli, cli->inbuf)) { /* * If we get a signature failure in sessionsetup, then * the server sometimes just reflects the sent signature @@ -343,10 +343,11 @@ bool cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return false; - cli_calculate_sign_mac(cli); + cli_calculate_sign_mac(cli, cli->outbuf); if (enc_on) { - NTSTATUS status = cli_encrypt_message(cli, &buf_out); + NTSTATUS status = cli_encrypt_message(cli, cli->outbuf, + &buf_out); if (!NT_STATUS_IS_OK(status)) { close(cli->fd); cli->fd = -1; @@ -449,31 +450,41 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, Setup basics in a outgoing packet. ****************************************************************************/ -void cli_setup_packet(struct cli_state *cli) +void cli_setup_packet_buf(struct cli_state *cli, char *buf) { + uint16 flags2; cli->rap_error = 0; - SSVAL(cli->outbuf,smb_pid,cli->pid); - SSVAL(cli->outbuf,smb_uid,cli->vuid); - SSVAL(cli->outbuf,smb_mid,cli->mid); - if (cli->protocol > PROTOCOL_CORE) { - uint16 flags2; - if (cli->case_sensitive) { - SCVAL(cli->outbuf,smb_flg,0x0); - } else { - /* Default setting, case insensitive. */ - SCVAL(cli->outbuf,smb_flg,0x8); - } - flags2 = FLAGS2_LONG_PATH_COMPONENTS; - if (cli->capabilities & CAP_UNICODE) - flags2 |= FLAGS2_UNICODE_STRINGS; - if ((cli->capabilities & CAP_DFS) && cli->dfsroot) - flags2 |= FLAGS2_DFS_PATHNAMES; - if (cli->capabilities & CAP_STATUS32) - flags2 |= FLAGS2_32_BIT_ERROR_CODES; - if (cli->use_spnego) - flags2 |= FLAGS2_EXTENDED_SECURITY; - SSVAL(cli->outbuf,smb_flg2, flags2); + SIVAL(buf,smb_rcls,0); + SSVAL(buf,smb_pid,cli->pid); + memset(buf+smb_pidhigh, 0, 12); + SSVAL(buf,smb_uid,cli->vuid); + SSVAL(buf,smb_mid,cli->mid); + + if (cli->protocol <= PROTOCOL_CORE) { + return; + } + + if (cli->case_sensitive) { + SCVAL(buf,smb_flg,0x0); + } else { + /* Default setting, case insensitive. */ + SCVAL(buf,smb_flg,0x8); } + flags2 = FLAGS2_LONG_PATH_COMPONENTS; + if (cli->capabilities & CAP_UNICODE) + flags2 |= FLAGS2_UNICODE_STRINGS; + if ((cli->capabilities & CAP_DFS) && cli->dfsroot) + flags2 |= FLAGS2_DFS_PATHNAMES; + if (cli->capabilities & CAP_STATUS32) + flags2 |= FLAGS2_32_BIT_ERROR_CODES; + if (cli->use_spnego) + flags2 |= FLAGS2_EXTENDED_SECURITY; + SSVAL(buf,smb_flg2, flags2); +} + +void cli_setup_packet(struct cli_state *cli) +{ + cli_setup_packet_buf(cli, cli->outbuf); } /**************************************************************************** @@ -536,7 +547,7 @@ struct cli_state *cli_initialise(void) return NULL; } - cli = SMB_MALLOC_P(struct cli_state); + cli = talloc(NULL, struct cli_state); if (!cli) { return NULL; } @@ -694,7 +705,7 @@ void cli_shutdown(struct cli_state *cli) cli->fd = -1; cli->smb_rw_error = SMB_READ_OK; - SAFE_FREE(cli); + TALLOC_FREE(cli); } /**************************************************************************** diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 587abade59..36746419f7 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -483,3 +483,15 @@ void cli_set_nt_error(struct cli_state *cli, NTSTATUS status) SSVAL(cli->inbuf,smb_flg2, SVAL(cli->inbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES); SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status)); } + +/* Reset an error. */ + +void cli_reset_error(struct cli_state *cli) +{ + if (SVAL(cli->inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES) { + SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(NT_STATUS_OK)); + } else { + SCVAL(cli->inbuf,smb_rcls,0); + SSVAL(cli->inbuf,smb_err,0); + } +} diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 9b4c380d40..12c427a6fa 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -38,8 +38,15 @@ static bool cli_link_internal(struct cli_state *cli, const char *oldname, const size_t newlen = 2*(strlen(newname)+1); param = SMB_MALLOC_ARRAY(char, 6+newlen+2); + + if (!param) { + return false; + } + data = SMB_MALLOC_ARRAY(char, oldlen+2); - if (!param || !data) { + + if (!data) { + SAFE_FREE(param); return false; } @@ -882,6 +889,55 @@ bool cli_close(struct cli_state *cli, int fnum) /**************************************************************************** + Truncate a file to a specified size +****************************************************************************/ + +bool cli_ftruncate(struct cli_state *cli, int fnum, uint64_t size) +{ + unsigned int param_len = 6; + unsigned int data_len = 8; + uint16 setup = TRANSACT2_SETFILEINFO; + char param[6]; + unsigned char data[8]; + char *rparam=NULL, *rdata=NULL; + int saved_timeout = cli->timeout; + + SSVAL(param,0,fnum); + SSVAL(param,2,SMB_SET_FILE_END_OF_FILE_INFO); + SSVAL(param,4,0); + + SBVAL(data, 0, size); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len,/* data, length, ... */ + cli->max_xmit)) { /* ... max */ + cli->timeout = saved_timeout; + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + cli->timeout = saved_timeout; + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return False; + } + + cli->timeout = saved_timeout; + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + + +/**************************************************************************** send a lock with a specified locktype this is used for testing LOCKING_ANDX_CANCEL_LOCK ****************************************************************************/ diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index fb923378ab..0005c3908a 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -368,20 +368,16 @@ static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type sm ZERO_STRUCTP(es); es->smb_enc_type = smb_enc_type; - if (smb_enc_type == SMB_TRANS_ENC_GSS) { #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + if (smb_enc_type == SMB_TRANS_ENC_GSS) { es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss); if (!es->s.gss_state) { SAFE_FREE(es); return NULL; } ZERO_STRUCTP(es->s.gss_state); -#else - DEBUG(0,("make_cli_enc_state: no krb5 compiled.\n")); - SAFE_FREE(es); - return NULL; -#endif } +#endif return es; } @@ -497,8 +493,7 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, memset(&tok_out, '\0', sizeof(tok_out)); /* Get a ticket for the service@host */ - asprintf(&host_princ_s, "%s@%s", service, host); - if (host_princ_s == NULL) { + if (asprintf(&host_princ_s, "%s@%s", service, host) == -1) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 844a3b35c0..c289740ab2 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -835,22 +835,22 @@ failed: #endif } - void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum, - PAC_SIGNATURE_DATA *sig) + void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum, + struct PAC_SIGNATURE_DATA *sig) { #ifdef HAVE_CHECKSUM_IN_KRB5_CHECKSUM cksum->cksumtype = (krb5_cksumtype)sig->type; - cksum->checksum.length = sig->signature.buf_len; - cksum->checksum.data = sig->signature.buffer; + cksum->checksum.length = sig->signature.length; + cksum->checksum.data = sig->signature.data; #else cksum->checksum_type = (krb5_cksumtype)sig->type; - cksum->length = sig->signature.buf_len; - cksum->contents = sig->signature.buffer; + cksum->length = sig->signature.length; + cksum->contents = sig->signature.data; #endif } krb5_error_code smb_krb5_verify_checksum(krb5_context context, - krb5_keyblock *keyblock, + const krb5_keyblock *keyblock, krb5_keyusage usage, krb5_checksum *cksum, uint8 *data, diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e1b16154f2..50918458b0 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -328,7 +328,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &rparam, ¶m_len, &rdata, &data_len) && cli_is_dos_error(cli)) { - /* we need to work around a Win95 bug - sometimes + /* We need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; @@ -337,6 +337,20 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SAFE_FREE(rparam); cli_dos_error(cli, &eclass, &ecode); + + /* + * OS/2 might return "no more files", + * which just tells us, that searchcount is zero + * in this search. + * Guenter Kukkukk <linux@kukkukk.com> + */ + + if (eclass == ERRDOS && ecode == ERRnofiles) { + ff_searchcount = 0; + cli_reset_error(cli); + break; + } + if (eclass != ERRSRV || ecode != ERRerror) break; smb_msleep(100); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index f95b11e4cd..a75032a47d 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -498,11 +498,13 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (reply->data != NULL) { + if (mechOID) { asn1_push_tag(&data,ASN1_CONTEXT(1)); asn1_write_OID(&data, mechOID); asn1_pop_tag(&data); - + } + + if (reply && reply->data != NULL) { asn1_push_tag(&data,ASN1_CONTEXT(2)); asn1_write_OctetString(&data, reply->data, reply->length); asn1_pop_tag(&data); diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 1256a6210e..9d33e6d93d 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -42,9 +42,9 @@ char *credstr(const unsigned char *cred) ****************************************************************************/ static void creds_init_128(struct dcinfo *dc, - const DOM_CHAL *clnt_chal_in, - const DOM_CHAL *srv_chal_in, - const unsigned char mach_pw[16]) + const struct netr_Credential *clnt_chal_in, + const struct netr_Credential *srv_chal_in, + const unsigned char mach_pw[16]) { unsigned char zero[4], tmp[16]; HMACMD5Context ctx; @@ -94,9 +94,9 @@ static void creds_init_128(struct dcinfo *dc, ****************************************************************************/ static void creds_init_64(struct dcinfo *dc, - const DOM_CHAL *clnt_chal_in, - const DOM_CHAL *srv_chal_in, - const unsigned char mach_pw[16]) + const struct netr_Credential *clnt_chal_in, + const struct netr_Credential *srv_chal_in, + const unsigned char mach_pw[16]) { uint32 sum[2]; unsigned char sum2[8]; @@ -177,10 +177,10 @@ static void creds_step(struct dcinfo *dc) void creds_server_init(uint32 neg_flags, struct dcinfo *dc, - DOM_CHAL *clnt_chal, - DOM_CHAL *srv_chal, + struct netr_Credential *clnt_chal, + struct netr_Credential *srv_chal, const unsigned char mach_pw[16], - DOM_CHAL *init_chal_out) + struct netr_Credential *init_chal_out) { DEBUG(10,("creds_server_init: neg_flags : %x\n", (unsigned int)neg_flags)); DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) )); @@ -213,25 +213,28 @@ void creds_server_init(uint32 neg_flags, Check a credential sent by the client. ****************************************************************************/ -bool creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in) +bool netlogon_creds_server_check(const struct dcinfo *dc, + const struct netr_Credential *rcv_cli_chal_in) { if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) { - DEBUG(5,("creds_server_check: challenge : %s\n", credstr(rcv_cli_chal_in->data))); + DEBUG(5,("netlogon_creds_server_check: challenge : %s\n", + credstr(rcv_cli_chal_in->data))); DEBUG(5,("calculated: %s\n", credstr(dc->clnt_chal.data))); - DEBUG(2,("creds_server_check: credentials check failed.\n")); - return False; + DEBUG(2,("netlogon_creds_server_check: credentials check failed.\n")); + return false; } - DEBUG(10,("creds_server_check: credentials check OK.\n")); - return True; -} + DEBUG(10,("netlogon_creds_server_check: credentials check OK.\n")); + + return true; +} /**************************************************************************** Replace current seed chal. Internal function - due to split server step below. ****************************************************************************/ static void creds_reseed(struct dcinfo *dc) { - DOM_CHAL time_chal; + struct netr_Credential time_chal; SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1); SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4)); @@ -245,7 +248,9 @@ static void creds_reseed(struct dcinfo *dc) Step the server credential chain one forward. ****************************************************************************/ -bool creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out) +bool netlogon_creds_server_step(struct dcinfo *dc, + const struct netr_Authenticator *received_cred, + struct netr_Authenticator *cred_out) { bool ret; struct dcinfo tmp_dc = *dc; @@ -253,24 +258,24 @@ bool creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRE /* Do all operations on a temporary copy of the dc, which we throw away if the checks fail. */ - tmp_dc.sequence = received_cred->timestamp.time; + tmp_dc.sequence = received_cred->timestamp; creds_step(&tmp_dc); /* Create the outgoing credentials */ - cred_out->timestamp.time = tmp_dc.sequence + 1; - cred_out->challenge = tmp_dc.srv_chal; + cred_out->timestamp = tmp_dc.sequence + 1; + memcpy(&cred_out->cred, &tmp_dc.srv_chal, sizeof(cred_out->cred)); creds_reseed(&tmp_dc); - ret = creds_server_check(&tmp_dc, &received_cred->challenge); + ret = netlogon_creds_server_check(&tmp_dc, &received_cred->cred); if (!ret) { - return False; + return false; } /* creds step succeeded - replace the current creds. */ *dc = tmp_dc; - return True; + return true; } /**************************************************************************** @@ -279,10 +284,10 @@ bool creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRE void creds_client_init(uint32 neg_flags, struct dcinfo *dc, - DOM_CHAL *clnt_chal, - DOM_CHAL *srv_chal, + struct netr_Credential *clnt_chal, + struct netr_Credential *srv_chal, const unsigned char mach_pw[16], - DOM_CHAL *init_chal_out) + struct netr_Credential *init_chal_out) { dc->sequence = time(NULL); @@ -317,18 +322,25 @@ void creds_client_init(uint32 neg_flags, Check a credential returned by the server. ****************************************************************************/ -bool creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in) +bool netlogon_creds_client_check(const struct dcinfo *dc, + const struct netr_Credential *rcv_srv_chal_in) { - if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, 8)) { - DEBUG(5,("creds_client_check: challenge : %s\n", credstr(rcv_srv_chal_in->data))); - DEBUG(5,("calculated: %s\n", credstr(dc->srv_chal.data))); - DEBUG(0,("creds_client_check: credentials check failed.\n")); - return False; + if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, + sizeof(dc->srv_chal.data))) { + + DEBUG(0,("netlogon_creds_client_check: credentials check failed.\n")); + DEBUGADD(5,("netlogon_creds_client_check: challenge : %s\n", + credstr(rcv_srv_chal_in->data))); + DEBUGADD(5,("calculated: %s\n", credstr(dc->srv_chal.data))); + return false; } - DEBUG(10,("creds_client_check: credentials check OK.\n")); - return True; + + DEBUG(10,("netlogon_creds_client_check: credentials check OK.\n")); + + return true; } + /**************************************************************************** Step the client credentials to the next element in the chain, updating the current client and server credentials and the seed @@ -336,12 +348,14 @@ bool creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in the server ****************************************************************************/ -void creds_client_step(struct dcinfo *dc, DOM_CRED *next_cred_out) +void netlogon_creds_client_step(struct dcinfo *dc, + struct netr_Authenticator *next_cred_out) { - dc->sequence += 2; + dc->sequence += 2; creds_step(dc); creds_reseed(dc); - next_cred_out->challenge = dc->clnt_chal; - next_cred_out->timestamp.time = dc->sequence; + memcpy(&next_cred_out->cred.data, &dc->clnt_chal.data, + sizeof(next_cred_out->cred.data)); + next_cred_out->timestamp = dc->sequence; } diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index a3043a2152..203f682599 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -84,6 +84,7 @@ werror_code_struct dos_errs[] = { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, + { "WERR_TIME_SKEW", WERR_TIME_SKEW }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { "WERR_IO_PENDING", WERR_IO_PENDING }, @@ -121,6 +122,7 @@ werror_str_struct dos_err_strs[] = { { WERR_USER_EXISTS, "User account already exists" }, { WERR_PASSWORD_MUST_CHANGE, "The password must be changed" }, { WERR_ACCOUNT_LOCKED_OUT, "Account locked out" }, + { WERR_TIME_SKEW, "Time difference between client and server" }, }; /***************************************************************************** diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index e0be76cc85..bc9f4b92c8 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -110,7 +110,7 @@ void debug_dsdcinfo_flags(int lvl, uint32_t flags) /********************************************************************* ********************************************************************/ -static int pack_dsdcinfo(struct DS_DOMAIN_CONTROLLER_INFO *info, +static int pack_dsdcinfo(struct netr_DsRGetDCNameInfo *info, unsigned char **buf) { unsigned char *buffer = NULL; @@ -122,9 +122,8 @@ static int pack_dsdcinfo(struct DS_DOMAIN_CONTROLLER_INFO *info, ZERO_STRUCT(guid_flat); - if (info->domain_guid) { - const struct GUID *guid = info->domain_guid; - smb_uuid_pack(*guid, &guid_flat); + if (!GUID_all_zero(&info->domain_guid)) { + smb_uuid_pack(info->domain_guid, &guid_flat); } again: @@ -132,17 +131,17 @@ static int pack_dsdcinfo(struct DS_DOMAIN_CONTROLLER_INFO *info, if (buflen > 0) { DEBUG(10,("pack_dsdcinfo: Packing domain %s (%s)\n", - info->domain_name, info->domain_controller_name)); + info->domain_name, info->dc_unc)); } len += tdb_pack(buffer+len, buflen-len, "ffdBffdff", - info->domain_controller_name, - info->domain_controller_address, - info->domain_controller_address_type, + info->dc_unc, + info->dc_address, + info->dc_address_type, UUID_FLAT_SIZE, guid_flat.info, info->domain_name, - info->dns_forest_name, - info->flags, + info->forest_name, + info->dc_flags, info->dc_site_name, info->client_site_name); @@ -169,33 +168,33 @@ static int pack_dsdcinfo(struct DS_DOMAIN_CONTROLLER_INFO *info, static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, unsigned char *buf, int buflen, - struct DS_DOMAIN_CONTROLLER_INFO **info_ret) + struct netr_DsRGetDCNameInfo **info_ret) { int len = 0; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; uint32_t guid_len = 0; unsigned char *guid_buf = NULL; UUID_FLAT guid_flat; /* forgive me 6 times */ - fstring domain_controller_name; - fstring domain_controller_address; + fstring dc_unc; + fstring dc_address; fstring domain_name; - fstring dns_forest_name; + fstring forest_name; fstring dc_site_name; fstring client_site_name; - info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO); + info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); NT_STATUS_HAVE_NO_MEMORY(info); len += tdb_unpack(buf+len, buflen-len, "ffdBffdff", - &domain_controller_name, - &domain_controller_address, - &info->domain_controller_address_type, + &dc_unc, + &dc_address, + &info->dc_address_type, &guid_len, &guid_buf, &domain_name, - &dns_forest_name, - &info->flags, + &forest_name, + &info->dc_flags, &dc_site_name, &client_site_name); if (len == -1) { @@ -203,23 +202,23 @@ static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, goto failed; } - info->domain_controller_name = - talloc_strdup(mem_ctx, domain_controller_name); - info->domain_controller_address = - talloc_strdup(mem_ctx, domain_controller_address); + info->dc_unc = + talloc_strdup(mem_ctx, dc_unc); + info->dc_address = + talloc_strdup(mem_ctx, dc_address); info->domain_name = talloc_strdup(mem_ctx, domain_name); - info->dns_forest_name = - talloc_strdup(mem_ctx, dns_forest_name); + info->forest_name = + talloc_strdup(mem_ctx, forest_name); info->dc_site_name = talloc_strdup(mem_ctx, dc_site_name); info->client_site_name = talloc_strdup(mem_ctx, client_site_name); - if (!info->domain_controller_name || - !info->domain_controller_address || + if (!info->dc_unc || + !info->dc_address || !info->domain_name || - !info->dns_forest_name || + !info->forest_name || !info->dc_site_name || !info->client_site_name) { goto failed; @@ -235,16 +234,12 @@ static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, memcpy(&guid_flat.info, guid_buf, guid_len); smb_uuid_unpack(guid_flat, &guid); - info->domain_guid = (struct GUID *)talloc_memdup( - mem_ctx, &guid, sizeof(guid)); - if (!info->domain_guid) { - goto failed; - } + info->domain_guid = guid; SAFE_FREE(guid_buf); } DEBUG(10,("unpack_dcscinfo: Unpacked domain %s (%s)\n", - info->domain_name, info->domain_controller_name)); + info->domain_name, info->dc_unc)); *info_ret = info; @@ -297,7 +292,7 @@ static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx, static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, const char *domain_name, - struct DS_DOMAIN_CONTROLLER_INFO *info) + struct netr_DsRGetDCNameInfo *info) { time_t expire_time; char *key; @@ -346,7 +341,7 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct DS_DOMAIN_CONTROLLER_INFO *info) + struct netr_DsRGetDCNameInfo *info) { struct cldap_netlogon_reply r; @@ -355,7 +350,7 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, ZERO_STRUCT(r); - if (ads_cldap_netlogon(info->domain_controller_name, + if (ads_cldap_netlogon(info->dc_unc, info->domain_name, &r)) { dsgetdcname_cache_delete(mem_ctx, domain_name); @@ -409,7 +404,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct DS_DOMAIN_CONTROLLER_INFO **info, + struct netr_DsRGetDCNameInfo **info, bool *expired) { char *key; @@ -438,13 +433,13 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, data_blob_free(&blob); /* check flags */ - if (!check_cldap_reply_required_flags((*info)->flags, flags)) { + if (!check_cldap_reply_required_flags((*info)->dc_flags, flags)) { DEBUG(10,("invalid flags\n")); return NT_STATUS_INVALID_PARAMETER; } if ((flags & DS_IP_REQUIRED) && - ((*info)->domain_controller_address_type != ADS_INET_ADDRESS)) { + ((*info)->dc_address_type != DS_ADDRESS_TYPE_INET)) { return NT_STATUS_INVALID_PARAMETER_MIX; } @@ -459,7 +454,7 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { NTSTATUS status; bool expired = false; @@ -663,40 +658,36 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, ****************************************************************/ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, - const char *domain_controller_name, - const char *domain_controller_address, - uint32_t domain_controller_address_type, + const char *dc_unc, + const char *dc_address, + uint32_t dc_address_type, const struct GUID *domain_guid, const char *domain_name, - const char *dns_forest_name, + const char *forest_name, uint32_t flags, const char *dc_site_name, const char *client_site_name, - struct DS_DOMAIN_CONTROLLER_INFO **info_out) + struct netr_DsRGetDCNameInfo **info_out) { - struct DS_DOMAIN_CONTROLLER_INFO *info; + struct netr_DsRGetDCNameInfo *info; - info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO); + info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); NT_STATUS_HAVE_NO_MEMORY(info); - if (domain_controller_name) { - info->domain_controller_name = talloc_strdup(mem_ctx, - domain_controller_name); - NT_STATUS_HAVE_NO_MEMORY(info->domain_controller_name); + if (dc_unc) { + info->dc_unc = talloc_strdup(mem_ctx, dc_unc); + NT_STATUS_HAVE_NO_MEMORY(info->dc_unc); } - if (domain_controller_address) { - info->domain_controller_address = talloc_strdup(mem_ctx, - domain_controller_address); - NT_STATUS_HAVE_NO_MEMORY(info->domain_controller_address); + if (dc_address) { + info->dc_address = talloc_strdup(mem_ctx, dc_address); + NT_STATUS_HAVE_NO_MEMORY(info->dc_address); } - info->domain_controller_address_type = domain_controller_address_type; + info->dc_address_type = dc_address_type; if (domain_guid) { - info->domain_guid = (struct GUID *)talloc_memdup( - mem_ctx, domain_guid, sizeof(*domain_guid)); - NT_STATUS_HAVE_NO_MEMORY(info->domain_guid); + info->domain_guid = *domain_guid; } if (domain_name) { @@ -704,13 +695,12 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, NT_STATUS_HAVE_NO_MEMORY(info->domain_name); } - if (dns_forest_name) { - info->dns_forest_name = talloc_strdup(mem_ctx, - dns_forest_name); - NT_STATUS_HAVE_NO_MEMORY(info->dns_forest_name); + if (forest_name) { + info->forest_name = talloc_strdup(mem_ctx, forest_name); + NT_STATUS_HAVE_NO_MEMORY(info->forest_name); } - info->flags = flags; + info->dc_flags = flags; if (dc_site_name) { info->dc_site_name = talloc_strdup(mem_ctx, dc_site_name); @@ -736,7 +726,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, uint32_t flags, struct ip_service_name **dclist, int num_dcs, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { int i = 0; bool valid_dc = false; @@ -779,12 +769,12 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, } dc_hostname = r.hostname; dc_domain_name = r.domain; - dc_flags |= ADS_DNS_DOMAIN | ADS_DNS_CONTROLLER; + dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; } else { /* FIXME */ dc_hostname = r.hostname; dc_domain_name = r.domain; - dc_flags |= ADS_DNS_DOMAIN | ADS_DNS_CONTROLLER; + dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; } if (flags & DS_IP_REQUIRED) { @@ -792,17 +782,17 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, print_sockaddr(addr, sizeof(addr), &dclist[i]->ss); dc_address = talloc_asprintf(mem_ctx, "\\\\%s", addr); - dc_address_type = ADS_INET_ADDRESS; + dc_address_type = DS_ADDRESS_TYPE_INET; } else { dc_address = talloc_asprintf(mem_ctx, "\\\\%s", r.netbios_hostname); - dc_address_type = ADS_NETBIOS_ADDRESS; + dc_address_type = DS_ADDRESS_TYPE_NETBIOS; } NT_STATUS_HAVE_NO_MEMORY(dc_address); smb_uuid_unpack(r.guid, &dc_guid); if (r.forest) { - dc_flags |= ADS_DNS_FOREST; + dc_flags |= DS_DNS_FOREST; } return make_domain_controller_info(mem_ctx, @@ -827,7 +817,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, uint32_t flags, struct ip_service_name **dclist, int num_dcs, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { /* FIXME: code here */ @@ -842,7 +832,7 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct ip_service_name *dclist; @@ -901,10 +891,10 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, const char *site_name, uint32_t flags, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - struct DS_DOMAIN_CONTROLLER_INFO *myinfo = NULL; + struct netr_DsRGetDCNameInfo *myinfo = NULL; DEBUG(10,("dsgetdcname: domain_name: %s, " "domain_guid: %s, site_name: %s, flags: 0x%08x\n", diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index b98df024fa..bfacea368d 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -1,4 +1,3 @@ - /* Unix SMB/CIFS implementation. SMB client library implementation (server cache) @@ -22,11 +21,8 @@ */ #include "includes.h" - -#include "include/libsmbclient.h" -#include "../include/libsmb_internal.h" - -int smbc_default_cache_functions(SMBCCTX * context); +#include "libsmbclient.h" +#include "libsmb_internal.h" /* * Structure we use if internal caching mechanism is used @@ -38,66 +34,70 @@ struct smbc_server_cache { char *workgroup; char *username; SMBCSRV *server; - + struct smbc_server_cache *next, *prev; }; - + /* * Add a new connection to the server cache. * This function is only used if the external cache is not enabled */ -static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * newsrv, - const char * server, const char * share, - const char * workgroup, const char * username) +int +SMBC_add_cached_server(SMBCCTX * context, + SMBCSRV * newsrv, + const char * server, + const char * share, + const char * workgroup, + const char * username) { struct smbc_server_cache * srvcache = NULL; - + if (!(srvcache = SMB_MALLOC_P(struct smbc_server_cache))) { errno = ENOMEM; DEBUG(3, ("Not enough space for server cache allocation\n")); return 1; } - + ZERO_STRUCTP(srvcache); - + srvcache->server = newsrv; - + srvcache->server_name = SMB_STRDUP(server); if (!srvcache->server_name) { errno = ENOMEM; goto failed; } - + srvcache->share_name = SMB_STRDUP(share); if (!srvcache->share_name) { errno = ENOMEM; goto failed; } - + srvcache->workgroup = SMB_STRDUP(workgroup); if (!srvcache->workgroup) { errno = ENOMEM; goto failed; } - + srvcache->username = SMB_STRDUP(username); if (!srvcache->username) { errno = ENOMEM; goto failed; } - - DLIST_ADD((context->server_cache), srvcache); + + DLIST_ADD(context->internal->server_cache, srvcache); return 0; - - failed: + +failed: SAFE_FREE(srvcache->server_name); SAFE_FREE(srvcache->share_name); SAFE_FREE(srvcache->workgroup); SAFE_FREE(srvcache->username); SAFE_FREE(srvcache); - + return 1; } @@ -108,23 +108,27 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * newsrv, * returns server handle on success, NULL on error (not found) * This function is only used if the external cache is not enabled */ -static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, - const char * share, const char * workgroup, const char * user) +SMBCSRV * +SMBC_get_cached_server(SMBCCTX * context, + const char * server, + const char * share, + const char * workgroup, + const char * user) { struct smbc_server_cache * srv = NULL; - + /* Search the cache lines */ - for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) { - + for (srv = context->internal->server_cache; srv; srv = srv->next) { + if (strcmp(server,srv->server_name) == 0 && strcmp(workgroup,srv->workgroup) == 0 && strcmp(user, srv->username) == 0) { - + /* If the share name matches, we're cool */ if (strcmp(share, srv->share_name) == 0) { return srv->server; } - + /* * We only return an empty share name or the attribute * server on an exact match (which would have been @@ -132,7 +136,7 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, */ if (*share == '\0' || strcmp(share, "*IPC$") == 0) continue; - + /* * Never return an empty share name or the attribute * server if it wasn't what was requested. @@ -140,13 +144,13 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, if (*srv->share_name == '\0' || strcmp(srv->share_name, "*IPC$") == 0) continue; - + /* * If we're only allowing one share per server, then * a connection to the server (other than the * attribute server connection) is cool. */ - if (context->options.one_share_per_server) { + if (smbc_getOptionOneSharePerServer(context)) { /* * The currently connected share name * doesn't match the requested share, so @@ -156,10 +160,10 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, /* Sigh. Couldn't disconnect. */ cli_shutdown(srv->server->cli); srv->server->cli = NULL; - context->callbacks.remove_cached_srv_fn(context, srv->server); + smbc_getFunctionRemoveCachedServer(context)(context, srv->server); continue; } - + /* * Save the new share name. We've * disconnected from the old share, and are @@ -171,16 +175,16 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, /* Out of memory. */ cli_shutdown(srv->server->cli); srv->server->cli = NULL; - context->callbacks.remove_cached_srv_fn(context, srv->server); + smbc_getFunctionRemoveCachedServer(context)(context, srv->server); continue; } - - + + return srv->server; } } } - + return NULL; } @@ -190,15 +194,17 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, * returns 0 on success * This function is only used if the external cache is not enabled */ -static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) +int +SMBC_remove_cached_server(SMBCCTX * context, + SMBCSRV * server) { struct smbc_server_cache * srv = NULL; - - for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) { + + for (srv = context->internal->server_cache; srv; srv = srv->next) { if (server == srv->server) { - + /* remove this sucker */ - DLIST_REMOVE(context->server_cache, srv); + DLIST_REMOVE(context->internal->server_cache, srv); SAFE_FREE(srv->server_name); SAFE_FREE(srv->share_name); SAFE_FREE(srv->workgroup); @@ -216,40 +222,23 @@ static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) * Try to remove all the servers in cache * returns 1 on failure and 0 if all servers could be removed. */ -static int smbc_purge_cached(SMBCCTX * context) +int +SMBC_purge_cached_servers(SMBCCTX * context) { struct smbc_server_cache * srv; struct smbc_server_cache * next; int could_not_purge_all = 0; - - for (srv = ((struct smbc_server_cache *) context->server_cache), - next = (srv ? srv->next :NULL); + + for (srv = context->internal->server_cache, + next = (srv ? srv->next :NULL); srv; - srv = next, next = (srv ? srv->next : NULL)) { - - if (smbc_remove_unused_server(context, srv->server)) { + srv = next, + next = (srv ? srv->next : NULL)) { + + if (SMBC_remove_unused_server(context, srv->server)) { /* could not be removed */ could_not_purge_all = 1; } } return could_not_purge_all; } - - - -/* - * This functions initializes all server-cache related functions - * to the default (internal) system. - * - * We use this to make the rest of the cache system static. - */ - -int smbc_default_cache_functions(SMBCCTX * context) -{ - context->callbacks.add_cached_srv_fn = smbc_add_cached_server; - context->callbacks.get_cached_srv_fn = smbc_get_cached_server; - context->callbacks.remove_cached_srv_fn = smbc_remove_cached_server; - context->callbacks.purge_cached_fn = smbc_purge_cached; - - return 0; -} diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 573d087d6e..9ef5e51fa9 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -5,7 +5,7 @@ Copyright (C) Richard Sharpe 2000 Copyright (C) John Terpstra 2000 Copyright (C) Tom Jansen (Ninja ISD) 2002 - Copyright (C) Derrell Lipman 2003 + Copyright (C) Derrell Lipman 2003, 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 @@ -23,8 +23,7 @@ #include "includes.h" - -#include "include/libsmb_internal.h" +#include "libsmb_internal.h" struct smbc_compat_fdlist { SMBCFILE * file; @@ -39,7 +38,8 @@ static struct smbc_compat_fdlist * smbc_compat_fd_in_use = NULL; static struct smbc_compat_fdlist * smbc_compat_fd_avail = NULL; /* Find an fd and return the SMBCFILE * or NULL on failure */ -static SMBCFILE * find_fd(int fd) +static SMBCFILE * +find_fd(int fd) { struct smbc_compat_fdlist * f = smbc_compat_fd_in_use; while (f) { @@ -51,14 +51,15 @@ static SMBCFILE * find_fd(int fd) } /* Add an fd, returns 0 on success, -1 on error with errno set */ -static int add_fd(SMBCFILE * file) +static int +add_fd(SMBCFILE * file) { struct smbc_compat_fdlist * f = smbc_compat_fd_avail; - + if (f) { /* We found one that's available */ DLIST_REMOVE(smbc_compat_fd_avail, f); - + } else { /* * None were available, so allocate one. Keep the number of @@ -71,35 +72,36 @@ static int add_fd(SMBCFILE * file) errno = EMFILE; return -1; } - + f = SMB_MALLOC_P(struct smbc_compat_fdlist); if (!f) { errno = ENOMEM; return -1; } - + f->fd = SMBC_BASE_FD + smbc_compat_nextfd++; } - + f->file = file; DLIST_ADD(smbc_compat_fd_in_use, f); - + return f->fd; } /* Delete an fd, returns 0 on success */ -static int del_fd(int fd) +static int +del_fd(int fd) { struct smbc_compat_fdlist * f = smbc_compat_fd_in_use; - + while (f) { if (f->fd == fd) break; f = f->next; } - + if (f) { /* found */ DLIST_REMOVE(smbc_compat_fd_in_use, f); @@ -109,40 +111,43 @@ static int del_fd(int fd) } return 1; } - -int smbc_init(smbc_get_auth_data_fn fn, int debug) + +int +smbc_init(smbc_get_auth_data_fn fn, + int debug) { if (!smbc_compat_initialized) { statcont = smbc_new_context(); if (!statcont) return -1; - - statcont->debug = debug; - statcont->callbacks.auth_fn = fn; - + + smbc_setDebug(statcont, debug); + smbc_setFunctionAuthData(statcont, fn); + if (!smbc_init_context(statcont)) { smbc_free_context(statcont, False); return -1; } - + smbc_compat_initialized = 1; - + return 0; } return 0; } -SMBCCTX *smbc_set_context(SMBCCTX * context) +SMBCCTX * +smbc_set_context(SMBCCTX * context) { SMBCCTX *old_context = statcont; - + if (context) { /* Save provided context. It must have been initialized! */ statcont = context; - + /* You'd better know what you're doing. We won't help you. */ smbc_compat_initialized = 1; } @@ -151,301 +156,387 @@ SMBCCTX *smbc_set_context(SMBCCTX * context) } -int smbc_open(const char *furl, int flags, mode_t mode) +int +smbc_open(const char *furl, + int flags, + mode_t mode) { SMBCFILE * file; int fd; - - file = (statcont->open)(statcont, furl, flags, mode); + + file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode); if (!file) return -1; - + fd = add_fd(file); if (fd == -1) - (statcont->close_fn)(statcont, file); + smbc_getFunctionClose(statcont)(statcont, file); return fd; } -int smbc_creat(const char *furl, mode_t mode) +int +smbc_creat(const char *furl, + mode_t mode) { SMBCFILE * file; int fd; - - file = (statcont->creat)(statcont, furl, mode); + + file = smbc_getFunctionCreat(statcont)(statcont, furl, mode); if (!file) return -1; - + fd = add_fd(file); if (fd == -1) { /* Hmm... should we delete the file too ? I guess we could try */ - (statcont->close_fn)(statcont, file); - (statcont->unlink)(statcont, furl); + smbc_getFunctionClose(statcont)(statcont, file); + smbc_getFunctionUnlink(statcont)(statcont, furl); } return fd; } -ssize_t smbc_read(int fd, void *buf, size_t bufsize) +ssize_t +smbc_read(int fd, + void *buf, + size_t bufsize) { SMBCFILE * file = find_fd(fd); - return (statcont->read)(statcont, file, buf, bufsize); + return smbc_getFunctionRead(statcont)(statcont, file, buf, bufsize); } -ssize_t smbc_write(int fd, void *buf, size_t bufsize) +ssize_t +smbc_write(int fd, + void *buf, + size_t bufsize) { SMBCFILE * file = find_fd(fd); - return (statcont->write)(statcont, file, buf, bufsize); + return smbc_getFunctionWrite(statcont)(statcont, file, buf, bufsize); } -off_t smbc_lseek(int fd, off_t offset, int whence) +off_t +smbc_lseek(int fd, + off_t offset, + int whence) { SMBCFILE * file = find_fd(fd); - return (statcont->lseek)(statcont, file, offset, whence); + return smbc_getFunctionLseek(statcont)(statcont, file, offset, whence); } -int smbc_close(int fd) +int +smbc_close(int fd) { SMBCFILE * file = find_fd(fd); del_fd(fd); - return (statcont->close_fn)(statcont, file); + return smbc_getFunctionClose(statcont)(statcont, file); } -int smbc_unlink(const char *fname) +int +smbc_unlink(const char *fname) { - return (statcont->unlink)(statcont, fname); + return smbc_getFunctionUnlink(statcont)(statcont, fname); } -int smbc_rename(const char *ourl, const char *nurl) +int +smbc_rename(const char *ourl, + const char *nurl) { - return (statcont->rename)(statcont, ourl, statcont, nurl); + return smbc_getFunctionRename(statcont)(statcont, ourl, + statcont, nurl); } -int smbc_opendir(const char *durl) +int +smbc_opendir(const char *durl) { SMBCFILE * file; int fd; - - file = (statcont->opendir)(statcont, durl); + + file = smbc_getFunctionOpendir(statcont)(statcont, durl); if (!file) return -1; - + fd = add_fd(file); if (fd == -1) - (statcont->closedir)(statcont, file); - + smbc_getFunctionClosedir(statcont)(statcont, file); + return fd; } -int smbc_closedir(int dh) +int +smbc_closedir(int dh) { SMBCFILE * file = find_fd(dh); del_fd(dh); - return (statcont->closedir)(statcont, file); + return smbc_getFunctionClosedir(statcont)(statcont, file); } -int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count) +int +smbc_getdents(unsigned int dh, + struct smbc_dirent *dirp, + int count) { SMBCFILE * file = find_fd(dh); - return (statcont->getdents)(statcont, file,dirp, count); + return smbc_getFunctionGetdents(statcont)(statcont, file, dirp, count); } -struct smbc_dirent* smbc_readdir(unsigned int dh) +struct smbc_dirent * +smbc_readdir(unsigned int dh) { SMBCFILE * file = find_fd(dh); - return (statcont->readdir)(statcont, file); + return smbc_getFunctionReaddir(statcont)(statcont, file); } -off_t smbc_telldir(int dh) +off_t +smbc_telldir(int dh) { SMBCFILE * file = find_fd(dh); - return (statcont->telldir)(statcont, file); + return smbc_getFunctionTelldir(statcont)(statcont, file); } -int smbc_lseekdir(int fd, off_t offset) +int +smbc_lseekdir(int fd, + off_t offset) { SMBCFILE * file = find_fd(fd); - return (statcont->lseekdir)(statcont, file, offset); + return smbc_getFunctionLseekdir(statcont)(statcont, file, offset); } -int smbc_mkdir(const char *durl, mode_t mode) +int +smbc_mkdir(const char *durl, + mode_t mode) { - return (statcont->mkdir)(statcont, durl, mode); + return smbc_getFunctionMkdir(statcont)(statcont, durl, mode); } -int smbc_rmdir(const char *durl) +int +smbc_rmdir(const char *durl) { - return (statcont->rmdir)(statcont, durl); + return smbc_getFunctionRmdir(statcont)(statcont, durl); } -int smbc_stat(const char *url, struct stat *st) +int +smbc_stat(const char *url, + struct stat *st) { - return (statcont->stat)(statcont, url, st); + return smbc_getFunctionStat(statcont)(statcont, url, st); } -int smbc_fstat(int fd, struct stat *st) +int +smbc_fstat(int fd, + struct stat *st) { SMBCFILE * file = find_fd(fd); - return (statcont->fstat)(statcont, file, st); + return smbc_getFunctionFstat(statcont)(statcont, file, st); } -int smbc_chmod(const char *url, mode_t mode) +int +smbc_ftruncate(int fd, + off_t size) { - return (statcont->chmod)(statcont, url, mode); + SMBCFILE * file = find_fd(fd); + return smbc_getFunctionFtruncate(statcont)(statcont, file, size); +} + +int +smbc_chmod(const char *url, + mode_t mode) +{ + return smbc_getFunctionChmod(statcont)(statcont, url, mode); } -int smbc_utimes(const char *fname, struct timeval *tbuf) +int +smbc_utimes(const char *fname, + struct timeval *tbuf) { - return (statcont->utimes)(statcont, fname, tbuf); + return smbc_getFunctionUtimes(statcont)(statcont, fname, tbuf); } #ifdef HAVE_UTIME_H -int smbc_utime(const char *fname, struct utimbuf *utbuf) +int +smbc_utime(const char *fname, + struct utimbuf *utbuf) { struct timeval tv[2]; - + if (utbuf == NULL) - return (statcont->utimes)(statcont, fname, NULL); - + return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL); + tv[0].tv_sec = utbuf->actime; tv[1].tv_sec = utbuf->modtime; tv[0].tv_usec = tv[1].tv_usec = 0; - - return (statcont->utimes)(statcont, fname, tv); + + return smbc_getFunctionUtimes(statcont)(statcont, fname, tv); } #endif -int smbc_setxattr(const char *fname, - const char *name, - const void *value, - size_t size, - int flags) +int +smbc_setxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) { - return (statcont->setxattr)(statcont, fname, name, value, size, flags); + return smbc_getFunctionSetxattr(statcont)(statcont, + fname, name, + value, size, flags); } -int smbc_lsetxattr(const char *fname, - const char *name, - const void *value, - size_t size, - int flags) +int +smbc_lsetxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) { - return (statcont->setxattr)(statcont, fname, name, value, size, flags); + return smbc_getFunctionSetxattr(statcont)(statcont, + fname, name, + value, size, flags); } -int smbc_fsetxattr(int fd, - const char *name, - const void *value, - size_t size, - int flags) +int +smbc_fsetxattr(int fd, + const char *name, + const void *value, + size_t size, + int flags) { SMBCFILE * file = find_fd(fd); if (file == NULL) { errno = EBADF; return -1; } - return (statcont->setxattr)(statcont, file->fname, - name, value, size, flags); + return smbc_getFunctionSetxattr(statcont)(statcont, + file->fname, name, + value, size, flags); } -int smbc_getxattr(const char *fname, - const char *name, - const void *value, - size_t size) +int +smbc_getxattr(const char *fname, + const char *name, + const void *value, + size_t size) { - return (statcont->getxattr)(statcont, fname, name, value, size); + return smbc_getFunctionGetxattr(statcont)(statcont, + fname, name, + value, size); } -int smbc_lgetxattr(const char *fname, - const char *name, - const void *value, - size_t size) +int +smbc_lgetxattr(const char *fname, + const char *name, + const void *value, + size_t size) { - return (statcont->getxattr)(statcont, fname, name, value, size); + return smbc_getFunctionGetxattr(statcont)(statcont, + fname, name, + value, size); } -int smbc_fgetxattr(int fd, - const char *name, - const void *value, - size_t size) +int +smbc_fgetxattr(int fd, + const char *name, + const void *value, + size_t size) { SMBCFILE * file = find_fd(fd); if (file == NULL) { errno = EBADF; return -1; } - return (statcont->getxattr)(statcont, file->fname, name, value, size); + return smbc_getFunctionGetxattr(statcont)(statcont, + file->fname, name, + value, size); } -int smbc_removexattr(const char *fname, - const char *name) +int +smbc_removexattr(const char *fname, + const char *name) { - return (statcont->removexattr)(statcont, fname, name); + return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name); } -int smbc_lremovexattr(const char *fname, - const char *name) +int +smbc_lremovexattr(const char *fname, + const char *name) { - return (statcont->removexattr)(statcont, fname, name); + return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name); } -int smbc_fremovexattr(int fd, - const char *name) +int +smbc_fremovexattr(int fd, + const char *name) { SMBCFILE * file = find_fd(fd); if (file == NULL) { errno = EBADF; return -1; } - return (statcont->removexattr)(statcont, file->fname, name); + return smbc_getFunctionRemovexattr(statcont)(statcont, + file->fname, name); } -int smbc_listxattr(const char *fname, - char *list, - size_t size) +int +smbc_listxattr(const char *fname, + char *list, + size_t size) { - return (statcont->listxattr)(statcont, fname, list, size); + return smbc_getFunctionListxattr(statcont)(statcont, + fname, list, size); } -int smbc_llistxattr(const char *fname, - char *list, - size_t size) +int +smbc_llistxattr(const char *fname, + char *list, + size_t size) { - return (statcont->listxattr)(statcont, fname, list, size); + return smbc_getFunctionListxattr(statcont)(statcont, + fname, list, size); } -int smbc_flistxattr(int fd, - char *list, - size_t size) +int +smbc_flistxattr(int fd, + char *list, + size_t size) { SMBCFILE * file = find_fd(fd); if (file == NULL) { errno = EBADF; return -1; } - return (statcont->listxattr)(statcont, file->fname, list, size); + return smbc_getFunctionListxattr(statcont)(statcont, + file->fname, list, size); } -int smbc_print_file(const char *fname, const char *printq) +int +smbc_print_file(const char *fname, + const char *printq) { - return (statcont->print_file)(statcont, fname, statcont, printq); + return smbc_getFunctionPrintFile(statcont)(statcont, fname, + statcont, printq); } -int smbc_open_print_job(const char *fname) +int +smbc_open_print_job(const char *fname) { - SMBCFILE * file = (statcont->open_print_job)(statcont, fname); + SMBCFILE * file; + + file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname); if (!file) return -1; return file->cli_fd; } -int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn) +int +smbc_list_print_jobs(const char *purl, + smbc_list_print_job_fn fn) { - return (statcont->list_print_jobs)(statcont, purl, fn); + return smbc_getFunctionListPrintJobs(statcont)(statcont, purl, fn); } -int smbc_unlink_print_job(const char *purl, int id) +int +smbc_unlink_print_job(const char *purl, + int id) { - return (statcont->unlink_print_job)(statcont, purl, id); + return smbc_getFunctionUnlinkPrintJob(statcont)(statcont, purl, id); } diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c new file mode 100644 index 0000000000..c04f751696 --- /dev/null +++ b/source3/libsmb/libsmb_context.c @@ -0,0 +1,612 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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 "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Is the logging working / configfile read ? + */ +static int SMBC_initialized = 0; + + + +/* + * Get a new empty handle to fill in with your own info + */ +SMBCCTX * +smbc_new_context(void) +{ + SMBCCTX *context; + + /* + * All newly added context fields should be placed in + * SMBC_internal_data, not directly in SMBCCTX. + */ + context = SMB_MALLOC_P(SMBCCTX); + if (!context) { + errno = ENOMEM; + return NULL; + } + + ZERO_STRUCTP(context); + + context->internal = SMB_MALLOC_P(struct SMBC_internal_data); + if (!context->internal) { + SAFE_FREE(context); + errno = ENOMEM; + return NULL; + } + + /* Initialize the context and establish reasonable defaults */ + ZERO_STRUCTP(context->internal); + + smbc_setDebug(context, 0); + smbc_setTimeout(context, 20000); + + smbc_setOptionFullTimeNames(context, False); + smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE); + smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_NONE); + smbc_setOptionBrowseMaxLmbCount(context, 3); /* # LMBs to query */ + smbc_setOptionUrlEncodeReaddirEntries(context, False); + smbc_setOptionOneSharePerServer(context, False); + + smbc_setFunctionAuthData(context, SMBC_get_auth_data); + smbc_setFunctionCheckServer(context, SMBC_check_server); + smbc_setFunctionRemoveUnusedServer(context, SMBC_remove_unused_server); + + smbc_setOptionUserData(context, NULL); + smbc_setFunctionAddCachedServer(context, SMBC_add_cached_server); + smbc_setFunctionGetCachedServer(context, SMBC_get_cached_server); + smbc_setFunctionRemoveCachedServer(context, SMBC_remove_cached_server); + smbc_setFunctionPurgeCachedServers(context, SMBC_purge_cached_servers); + + smbc_setFunctionOpen(context, SMBC_open_ctx); + smbc_setFunctionCreat(context, SMBC_creat_ctx); + smbc_setFunctionRead(context, SMBC_read_ctx); + smbc_setFunctionWrite(context, SMBC_write_ctx); + smbc_setFunctionClose(context, SMBC_close_ctx); + smbc_setFunctionUnlink(context, SMBC_unlink_ctx); + smbc_setFunctionRename(context, SMBC_rename_ctx); + smbc_setFunctionLseek(context, SMBC_lseek_ctx); + smbc_setFunctionFtruncate(context, SMBC_ftruncate_ctx); + smbc_setFunctionStat(context, SMBC_stat_ctx); + smbc_setFunctionFstat(context, SMBC_fstat_ctx); + smbc_setFunctionOpendir(context, SMBC_opendir_ctx); + smbc_setFunctionClosedir(context, SMBC_closedir_ctx); + smbc_setFunctionReaddir(context, SMBC_readdir_ctx); + smbc_setFunctionGetdents(context, SMBC_getdents_ctx); + smbc_setFunctionMkdir(context, SMBC_mkdir_ctx); + smbc_setFunctionRmdir(context, SMBC_rmdir_ctx); + smbc_setFunctionTelldir(context, SMBC_telldir_ctx); + smbc_setFunctionLseekdir(context, SMBC_lseekdir_ctx); + smbc_setFunctionFstatdir(context, SMBC_fstatdir_ctx); + smbc_setFunctionChmod(context, SMBC_chmod_ctx); + smbc_setFunctionUtimes(context, SMBC_utimes_ctx); + smbc_setFunctionSetxattr(context, SMBC_setxattr_ctx); + smbc_setFunctionGetxattr(context, SMBC_getxattr_ctx); + smbc_setFunctionRemovexattr(context, SMBC_removexattr_ctx); + smbc_setFunctionListxattr(context, SMBC_listxattr_ctx); + + smbc_setFunctionOpenPrintJob(context, SMBC_open_print_job_ctx); + smbc_setFunctionPrintFile(context, SMBC_print_file_ctx); + smbc_setFunctionListPrintJobs(context, SMBC_list_print_jobs_ctx); + smbc_setFunctionUnlinkPrintJob(context, SMBC_unlink_print_job_ctx); + + return context; +} + +/* + * Free a context + * + * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed + * and thus you'll be leaking memory if not handled properly. + * + */ +int +smbc_free_context(SMBCCTX *context, + int shutdown_ctx) +{ + if (!context) { + errno = EBADF; + return 1; + } + + if (shutdown_ctx) { + SMBCFILE * f; + DEBUG(1,("Performing aggressive shutdown.\n")); + + f = context->internal->files; + while (f) { + smbc_getFunctionClose(context)(context, f); + f = f->next; + } + context->internal->files = NULL; + + /* First try to remove the servers the nice way. */ + if (smbc_getFunctionPurgeCachedServers(context)(context)) { + SMBCSRV * s; + SMBCSRV * next; + DEBUG(1, ("Could not purge all servers, " + "Nice way shutdown failed.\n")); + s = context->internal->servers; + while (s) { + DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", + s, s->cli->fd)); + cli_shutdown(s->cli); + smbc_getFunctionRemoveCachedServer(context)(context, + s); + next = s->next; + DLIST_REMOVE(context->internal->servers, s); + SAFE_FREE(s); + s = next; + } + context->internal->servers = NULL; + } + } + else { + /* This is the polite way */ + if (smbc_getFunctionPurgeCachedServers(context)(context)) { + DEBUG(1, ("Could not purge all servers, " + "free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->internal->servers) { + DEBUG(1, ("Active servers in context, " + "free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->internal->files) { + DEBUG(1, ("Active files in context, " + "free_context failed.\n")); + errno = EBUSY; + return 1; + } + } + + /* Things we have to clean up */ + free(smbc_getWorkgroup(context)); + smbc_setWorkgroup(context, NULL); + + free(smbc_getNetbiosName(context)); + smbc_setNetbiosName(context, NULL); + + free(smbc_getUser(context)); + smbc_setUser(context, NULL); + + DEBUG(3, ("Context %p successfully freed\n", context)); + SAFE_FREE(context); + return 0; +} + + +/** + * Deprecated interface. Do not use. Instead, use the various + * smbc_setOption*() functions or smbc_setFunctionAuthDataWithContext(). + */ +void +smbc_option_set(SMBCCTX *context, + char *option_name, + ... /* option_value */) +{ + va_list ap; + union { + int i; + bool b; + smbc_get_auth_data_with_context_fn auth_fn; + void *v; + const char *s; + } option_value; + + va_start(ap, option_name); + + if (strcmp(option_name, "debug_to_stderr") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionDebugToStderr(context, option_value.b); + + } else if (strcmp(option_name, "full_time_names") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionFullTimeNames(context, option_value.b); + + } else if (strcmp(option_name, "open_share_mode") == 0) { + option_value.i = va_arg(ap, int); + smbc_setOptionOpenShareMode(context, option_value.i); + + } else if (strcmp(option_name, "auth_function") == 0) { + option_value.auth_fn = + va_arg(ap, smbc_get_auth_data_with_context_fn); + smbc_setFunctionAuthDataWithContext(context, option_value.auth_fn); + + } else if (strcmp(option_name, "user_data") == 0) { + option_value.v = va_arg(ap, void *); + smbc_setOptionUserData(context, option_value.v); + + } else if (strcmp(option_name, "smb_encrypt_level") == 0) { + option_value.s = va_arg(ap, const char *); + if (strcmp(option_value.s, "none") == 0) { + smbc_setOptionSmbEncryptionLevel(context, + SMBC_ENCRYPTLEVEL_NONE); + } else if (strcmp(option_value.s, "request") == 0) { + smbc_setOptionSmbEncryptionLevel(context, + SMBC_ENCRYPTLEVEL_REQUEST); + } else if (strcmp(option_value.s, "require") == 0) { + smbc_setOptionSmbEncryptionLevel(context, + SMBC_ENCRYPTLEVEL_REQUIRE); + } + + } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { + option_value.i = va_arg(ap, int); + smbc_setOptionBrowseMaxLmbCount(context, option_value.i); + + } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionUrlEncodeReaddirEntries(context, option_value.b); + + } else if (strcmp(option_name, "one_share_per_server") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionOneSharePerServer(context, option_value.b); + + } else if (strcmp(option_name, "use_kerberos") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionUseKerberos(context, option_value.b); + + } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionFallbackAfterKerberos(context, option_value.b); + + } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionNoAutoAnonymousLogin(context, option_value.b); + } + + va_end(ap); +} + + +/* + * Deprecated interface. Do not use. Instead, use the various + * smbc_getOption*() functions. + */ +void * +smbc_option_get(SMBCCTX *context, + char *option_name) +{ + if (strcmp(option_name, "debug_stderr") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) smbc_getOptionDebugToStderr(context); +#else + return (void *) smbc_getOptionDebugToStderr(context); +#endif + + } else if (strcmp(option_name, "full_time_names") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) smbc_getOptionFullTimeNames(context); +#else + return (void *) smbc_getOptionFullTimeNames(context); +#endif + + } else if (strcmp(option_name, "open_share_mode") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) smbc_getOptionOpenShareMode(context); +#else + return (void *) smbc_getOptionOpenShareMode(context); +#endif + + } else if (strcmp(option_name, "auth_function") == 0) { + return (void *) smbc_getFunctionAuthDataWithContext(context); + + } else if (strcmp(option_name, "user_data") == 0) { + return smbc_getOptionUserData(context); + + } else if (strcmp(option_name, "smb_encrypt_level") == 0) { + switch(smbc_getOptionSmbEncryptionLevel(context)) + { + case 0: + return (void *) "none"; + case 1: + return (void *) "request"; + case 2: + return (void *) "require"; + } + + } else if (strcmp(option_name, "smb_encrypt_on") == 0) { + SMBCSRV *s; + unsigned int num_servers = 0; + + for (s = context->internal->servers; s; s = s->next) { + num_servers++; + if (s->cli->trans_enc_state == NULL) { + return (void *)false; + } + } +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) (bool) (num_servers > 0); +#else + return (void *) (bool) (num_servers > 0); +#endif + + } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) smbc_getOptionBrowseMaxLmbCount(context); +#else + return (void *) smbc_getOptionBrowseMaxLmbCount(context); +#endif + + } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *)(intptr_t) smbc_getOptionUrlEncodeReaddirEntries(context); +#else + return (void *) (bool) smbc_getOptionUrlEncodeReaddirEntries(context); +#endif + + } else if (strcmp(option_name, "one_share_per_server") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) smbc_getOptionOneSharePerServer(context); +#else + return (void *) (bool) smbc_getOptionOneSharePerServer(context); +#endif + + } else if (strcmp(option_name, "use_kerberos") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) smbc_getOptionUseKerberos(context); +#else + return (void *) (bool) smbc_getOptionUseKerberos(context); +#endif + + } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *)(intptr_t) smbc_getOptionFallbackAfterKerberos(context); +#else + return (void *) (bool) smbc_getOptionFallbackAfterKerberos(context); +#endif + + } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) smbc_getOptionNoAutoAnonymousLogin(context); +#else + return (void *) (bool) smbc_getOptionNoAutoAnonymousLogin(context); +#endif + } + + return NULL; +} + + +/* + * Initialize the library, etc. + * + * We accept a struct containing handle information. + * valid values for info->debug from 0 to 100, + * and insist that info->fn must be non-null. + */ +SMBCCTX * +smbc_init_context(SMBCCTX *context) +{ + int pid; + char *user = NULL; + char *home = NULL; + extern bool in_client; + + if (!context) { + errno = EBADF; + return NULL; + } + + /* Do not initialise the same client twice */ + if (context->internal->initialized) { + return NULL; + } + + if (!smbc_getFunctionAuthData(context) || + smbc_getDebug(context) < 0 || + smbc_getDebug(context) > 100) { + + errno = EINVAL; + return NULL; + + } + + if (!SMBC_initialized) { + /* + * Do some library-wide intializations the first time we get + * called + */ + bool conf_loaded = False; + TALLOC_CTX *frame = talloc_stackframe(); + + load_case_tables(); + + setup_logging("libsmbclient", True); + if (context->internal->debug_stderr) { + dbf = x_stderr; + x_setbuf(x_stderr, NULL); + } + + /* Here we would open the smb.conf file if needed ... */ + + in_client = True; /* FIXME, make a param */ + + home = getenv("HOME"); + if (home) { + char *conf = NULL; + if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) { + if (lp_load(conf, True, False, False, True)) { + conf_loaded = True; + } else { + DEBUG(5, ("Could not load config file: %s\n", + conf)); + } + SAFE_FREE(conf); + } + } + + if (!conf_loaded) { + /* + * Well, if that failed, try the get_dyn_CONFIGFILE + * Which points to the standard locn, and if that + * fails, silently ignore it and use the internal + * defaults ... + */ + + if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) { + DEBUG(5, ("Could not load config file: %s\n", + get_dyn_CONFIGFILE())); + } else if (home) { + char *conf; + /* + * We loaded the global config file. Now lets + * load user-specific modifications to the + * global config. + */ + if (asprintf(&conf, + "%s/.smb/smb.conf.append", + home) > 0) { + if (!lp_load(conf, True, False, False, False)) { + DEBUG(10, + ("Could not append config file: " + "%s\n", + conf)); + } + SAFE_FREE(conf); + } + } + } + + load_interfaces(); /* Load the list of interfaces ... */ + + reopen_logs(); /* Get logging working ... */ + + /* + * Block SIGPIPE (from lib/util_sock.c: write()) + * It is not needed and should not stop execution + */ + BlockSignals(True, SIGPIPE); + + /* Done with one-time initialisation */ + SMBC_initialized = 1; + + TALLOC_FREE(frame); + } + + if (!smbc_getUser(context)) { + /* + * FIXME: Is this the best way to get the user info? + */ + user = getenv("USER"); + /* walk around as "guest" if no username can be found */ + if (!user) { + user = SMB_STRDUP("guest"); + } else { + user = SMB_STRDUP(user); + } + + if (!user) { + errno = ENOMEM; + return NULL; + } + + smbc_setUser(context, user); + } + + if (!smbc_getNetbiosName(context)) { + /* + * We try to get our netbios name from the config. If that + * fails we fall back on constructing our netbios name from + * our hostname etc + */ + char *netbios_name; + if (global_myname()) { + netbios_name = SMB_STRDUP(global_myname()); + } else { + /* + * Hmmm, I want to get hostname as well, but I am too + * lazy for the moment + */ + pid = sys_getpid(); + netbios_name = (char *)SMB_MALLOC(17); + if (!netbios_name) { + errno = ENOMEM; + return NULL; + } + slprintf(netbios_name, 16, + "smbc%s%d", smbc_getUser(context), pid); + } + + if (!netbios_name) { + errno = ENOMEM; + return NULL; + } + + smbc_setNetbiosName(context, netbios_name); + } + + DEBUG(1, ("Using netbios name %s.\n", smbc_getNetbiosName(context))); + + if (!smbc_getWorkgroup(context)) { + char *workgroup; + + if (lp_workgroup()) { + workgroup = SMB_STRDUP(lp_workgroup()); + } + else { + /* TODO: Think about a decent default workgroup */ + workgroup = SMB_STRDUP("samba"); + } + + if (!workgroup) { + errno = ENOMEM; + return NULL; + } + + smbc_setWorkgroup(context, workgroup); + } + + DEBUG(1, ("Using workgroup %s.\n", smbc_getWorkgroup(context))); + + /* shortest timeout is 1 second */ + if (smbc_getTimeout(context) > 0 && smbc_getTimeout(context) < 1000) + smbc_setTimeout(context, 1000); + + /* + * FIXME: Should we check the function pointers here? + */ + + context->internal->initialized = True; + + return context; +} + + +/* Return the verion of samba, and thus libsmbclient */ +const char * +smbc_version(void) +{ + return samba_version_string(); +} + + diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c new file mode 100644 index 0000000000..1486097d51 --- /dev/null +++ b/source3/libsmb/libsmb_dir.c @@ -0,0 +1,1942 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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 "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Routine to open a directory + * We accept the URL syntax explained in SMBC_parse_path(), above. + */ + +static void +remove_dir(SMBCFILE *dir) +{ + struct smbc_dir_list *d,*f; + + d = dir->dir_list; + while (d) { + + f = d; d = d->next; + + SAFE_FREE(f->dirent); + SAFE_FREE(f); + + } + + dir->dir_list = dir->dir_end = dir->dir_next = NULL; + +} + +static int +add_dirent(SMBCFILE *dir, + const char *name, + const char *comment, + uint32 type) +{ + struct smbc_dirent *dirent; + int size; + int name_length = (name == NULL ? 0 : strlen(name)); + int comment_len = (comment == NULL ? 0 : strlen(comment)); + + /* + * Allocate space for the dirent, which must be increased by the + * size of the name and the comment and 1 each for the null terminator. + */ + + size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; + + dirent = (struct smbc_dirent *)SMB_MALLOC(size); + + if (!dirent) { + + dir->dir_error = ENOMEM; + return -1; + + } + + ZERO_STRUCTP(dirent); + + if (dir->dir_list == NULL) { + + dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list); + if (!dir->dir_list) { + + SAFE_FREE(dirent); + dir->dir_error = ENOMEM; + return -1; + + } + ZERO_STRUCTP(dir->dir_list); + + dir->dir_end = dir->dir_next = dir->dir_list; + } + else { + + dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list); + + if (!dir->dir_end->next) { + + SAFE_FREE(dirent); + dir->dir_error = ENOMEM; + return -1; + + } + ZERO_STRUCTP(dir->dir_end->next); + + dir->dir_end = dir->dir_end->next; + } + + dir->dir_end->next = NULL; + dir->dir_end->dirent = dirent; + + dirent->smbc_type = type; + dirent->namelen = name_length; + dirent->commentlen = comment_len; + dirent->dirlen = size; + + /* + * dirent->namelen + 1 includes the null (no null termination needed) + * Ditto for dirent->commentlen. + * The space for the two null bytes was allocated. + */ + strncpy(dirent->name, (name?name:""), dirent->namelen + 1); + dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); + strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); + + return 0; + +} + +static void +list_unique_wg_fn(const char *name, + uint32 type, + const char *comment, + void *state) +{ + SMBCFILE *dir = (SMBCFILE *)state; + struct smbc_dir_list *dir_list; + struct smbc_dirent *dirent; + int dirent_type; + int do_remove = 0; + + dirent_type = dir->dir_type; + + if (add_dirent(dir, name, comment, dirent_type) < 0) { + + /* An error occurred, what do we do? */ + /* FIXME: Add some code here */ + } + + /* Point to the one just added */ + dirent = dir->dir_end->dirent; + + /* See if this was a duplicate */ + for (dir_list = dir->dir_list; + dir_list != dir->dir_end; + dir_list = dir_list->next) { + if (! do_remove && + strcmp(dir_list->dirent->name, dirent->name) == 0) { + /* Duplicate. End end of list need to be removed. */ + do_remove = 1; + } + + if (do_remove && dir_list->next == dir->dir_end) { + /* Found the end of the list. Remove it. */ + dir->dir_end = dir_list; + free(dir_list->next); + free(dirent); + dir_list->next = NULL; + break; + } + } +} + +static void +list_fn(const char *name, + uint32 type, + const char *comment, + void *state) +{ + SMBCFILE *dir = (SMBCFILE *)state; + int dirent_type; + + /* + * We need to process the type a little ... + * + * Disk share = 0x00000000 + * Print share = 0x00000001 + * Comms share = 0x00000002 (obsolete?) + * IPC$ share = 0x00000003 + * + * administrative shares: + * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 + */ + + if (dir->dir_type == SMBC_FILE_SHARE) { + switch (type) { + case 0 | 0x80000000: + case 0: + dirent_type = SMBC_FILE_SHARE; + break; + + case 1: + dirent_type = SMBC_PRINTER_SHARE; + break; + + case 2: + dirent_type = SMBC_COMMS_SHARE; + break; + + case 3 | 0x80000000: + case 3: + dirent_type = SMBC_IPC_SHARE; + break; + + default: + dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ + break; + } + } + else { + dirent_type = dir->dir_type; + } + + if (add_dirent(dir, name, comment, dirent_type) < 0) { + + /* An error occurred, what do we do? */ + /* FIXME: Add some code here */ + + } +} + +static void +dir_list_fn(const char *mnt, + file_info *finfo, + const char *mask, + void *state) +{ + + if (add_dirent((SMBCFILE *)state, finfo->name, "", + (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { + + /* Handle an error ... */ + + /* FIXME: Add some code ... */ + + } + +} + +static int +net_share_enum_rpc(struct cli_state *cli, + void (*fn)(const char *name, + uint32 type, + const char *comment, + void *state), + void *state) +{ + int i; + WERROR result; + ENUM_HND enum_hnd; + uint32 info_level = 1; + uint32 preferred_len = 0xffffffff; + uint32 type; + SRV_SHARE_INFO_CTR ctr; + fstring name = ""; + fstring comment = ""; + struct rpc_pipe_client *pipe_hnd; + NTSTATUS nt_status; + + /* Open the server service pipe */ + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); + if (!pipe_hnd) { + DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); + return -1; + } + + /* Issue the NetShareEnum RPC call and retrieve the response */ + init_enum_hnd(&enum_hnd, 0); + result = rpccli_srvsvc_net_share_enum(pipe_hnd, + talloc_tos(), + info_level, + &ctr, + preferred_len, + &enum_hnd); + + /* Was it successful? */ + if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { + /* Nope. Go clean up. */ + goto done; + } + + /* For each returned entry... */ + for (i = 0; i < ctr.num_entries; i++) { + + /* pull out the share name */ + rpcstr_pull_unistr2_fstring( + name, &ctr.share.info1[i].info_1_str.uni_netname); + + /* pull out the share's comment */ + rpcstr_pull_unistr2_fstring( + comment, &ctr.share.info1[i].info_1_str.uni_remark); + + /* Get the type value */ + type = ctr.share.info1[i].info_1.type; + + /* Add this share to the list */ + (*fn)(name, type, comment, state); + } + +done: + /* Close the server service pipe */ + cli_rpc_pipe_close(pipe_hnd); + + /* Tell 'em if it worked */ + return W_ERROR_IS_OK(result) ? 0 : -1; +} + + +/* + * Verify that the options specified in a URL are valid + */ +int +SMBC_check_options(char *server, + char *share, + char *path, + char *options) +{ + DEBUG(4, ("SMBC_check_options(): server='%s' share='%s' " + "path='%s' options='%s'\n", + server, share, path, options)); + + /* No options at all is always ok */ + if (! *options) return 0; + + /* Currently, we don't support any options. */ + return -1; +} + + +SMBCFILE * +SMBC_opendir_ctx(SMBCCTX *context, + const char *fname) +{ + int saved_errno; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *options = NULL; + char *workgroup = NULL; + char *path = NULL; + uint16 mode; + char *p = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *dir = NULL; + struct sockaddr_storage rem_ss; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + DEBUG(4, ("no valid context\n")); + errno = EINVAL + 8192; + TALLOC_FREE(frame); + return NULL; + + } + + if (!fname) { + DEBUG(4, ("no valid fname\n")); + errno = EINVAL + 8193; + TALLOC_FREE(frame); + return NULL; + } + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + &options)) { + DEBUG(4, ("no valid path\n")); + errno = EINVAL + 8194; + TALLOC_FREE(frame); + return NULL; + } + + DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' " + "path='%s' options='%s'\n", + fname, server, share, path, options)); + + /* Ensure the options are valid */ + if (SMBC_check_options(server, share, path, options)) { + DEBUG(4, ("unacceptable options (%s)\n", options)); + errno = EINVAL + 8195; + TALLOC_FREE(frame); + return NULL; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + } + + dir = SMB_MALLOC_P(SMBCFILE); + + if (!dir) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + + ZERO_STRUCTP(dir); + + dir->cli_fd = 0; + dir->fname = SMB_STRDUP(fname); + dir->srv = NULL; + dir->offset = 0; + dir->file = False; + dir->dir_list = dir->dir_next = dir->dir_end = NULL; + + if (server[0] == (char)0) { + + int i; + int count; + int max_lmb_count; + struct ip_service *ip_list; + struct ip_service server_addr; + struct user_auth_info u_info; + + if (share[0] != (char)0 || path[0] != (char)0) { + + errno = EINVAL + 8196; + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + /* Determine how many local master browsers to query */ + max_lmb_count = (smbc_getOptionBrowseMaxLmbCount(context) == 0 + ? INT_MAX + : smbc_getOptionBrowseMaxLmbCount(context)); + + memset(&u_info, '\0', sizeof(u_info)); + u_info.username = talloc_strdup(frame,user); + u_info.password = talloc_strdup(frame,password); + if (!u_info.username || !u_info.password) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + /* + * We have server and share and path empty but options + * requesting that we scan all master browsers for their list + * of workgroups/domains. This implies that we must first try + * broadcast queries to find all master browsers, and if that + * doesn't work, then try our other methods which return only + * a single master browser. + */ + + ip_list = NULL; + if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, + &count))) + { + + SAFE_FREE(ip_list); + + if (!find_master_ip(workgroup, &server_addr.ss)) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + errno = ENOENT; + TALLOC_FREE(frame); + return NULL; + } + + ip_list = (struct ip_service *)memdup( + &server_addr, sizeof(server_addr)); + if (ip_list == NULL) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + count = 1; + } + + for (i = 0; i < count && i < max_lmb_count; i++) { + char addr[INET6_ADDRSTRLEN]; + char *wg_ptr = NULL; + struct cli_state *cli = NULL; + + print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); + DEBUG(99, ("Found master browser %d of %d: %s\n", + i+1, MAX(count, max_lmb_count), + addr)); + + cli = get_ipc_connect_master_ip(talloc_tos(), + &ip_list[i], + &u_info, + &wg_ptr); + /* cli == NULL is the master browser refused to talk or + could not be found */ + if (!cli) { + continue; + } + + workgroup = talloc_strdup(frame, wg_ptr); + server = talloc_strdup(frame, cli->desthost); + + cli_shutdown(cli); + + if (!workgroup || !server) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + + DEBUG(4, ("using workgroup %s %s\n", + workgroup, server)); + + /* + * For each returned master browser IP address, get a + * connection to IPC$ on the server if we do not + * already have one, and determine the + * workgroups/domains that it knows about. + */ + + srv = SMBC_server(frame, context, True, server, "IPC$", + &workgroup, &user, &password); + if (!srv) { + continue; + } + + dir->srv = srv; + dir->dir_type = SMBC_WORKGROUP; + + /* Now, list the stuff ... */ + + if (!cli_NetServerEnum(srv->cli, + workgroup, + SV_TYPE_DOMAIN_ENUM, + list_unique_wg_fn, + (void *)dir)) { + continue; + } + } + + SAFE_FREE(ip_list); + } else { + /* + * Server not an empty string ... Check the rest and see what + * gives + */ + if (*share == '\0') { + if (*path != '\0') { + + /* Should not have empty share with path */ + errno = EINVAL + 8197; + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + + } + + /* + * We don't know if <server> is really a server name + * or is a workgroup/domain name. If we already have + * a server structure for it, we'll use it. + * Otherwise, check to see if <server><1D>, + * <server><1B>, or <server><20> translates. We check + * to see if <server> is an IP address first. + */ + + /* + * See if we have an existing server. Do not + * establish a connection if one does not already + * exist. + */ + srv = SMBC_server(frame, context, False, + server, "IPC$", + &workgroup, &user, &password); + + /* + * If no existing server and not an IP addr, look for + * LMB or DMB + */ + if (!srv && + !is_ipaddress(server) && + (resolve_name(server, &rem_ss, 0x1d) || /* LMB */ + resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */ + + fstring buserver; + + dir->dir_type = SMBC_SERVER; + + /* + * Get the backup list ... + */ + if (!name_status_find(server, 0, 0, + &rem_ss, buserver)) { + + DEBUG(0,("Could not get name of " + "local/domain master browser " + "for server %s\n", server)); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + errno = EPERM; + TALLOC_FREE(frame); + return NULL; + + } + + /* + * Get a connection to IPC$ on the server if + * we do not already have one + */ + srv = SMBC_server(frame, context, True, + buserver, "IPC$", + &workgroup, + &user, &password); + if (!srv) { + DEBUG(0, ("got no contact to IPC$\n")); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + + } + + dir->srv = srv; + + /* Now, list the servers ... */ + if (!cli_NetServerEnum(srv->cli, server, + 0x0000FFFE, list_fn, + (void *)dir)) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + } else if (srv || + (resolve_name(server, &rem_ss, 0x20))) { + + /* + * If we hadn't found the server, get one now + */ + if (!srv) { + srv = SMBC_server(frame, context, True, + server, "IPC$", + &workgroup, + &user, &password); + } + + if (!srv) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + + } + + dir->dir_type = SMBC_FILE_SHARE; + dir->srv = srv; + + /* List the shares ... */ + + if (net_share_enum_rpc( + srv->cli, + list_fn, + (void *) dir) < 0 && + cli_RNetShareEnum( + srv->cli, + list_fn, + (void *)dir) < 0) { + + errno = cli_errno(srv->cli); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + + } + } else { + /* Neither the workgroup nor server exists */ + errno = ECONNREFUSED; + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + } + else { + /* + * The server and share are specified ... work from + * there ... + */ + char *targetpath; + struct cli_state *targetcli; + + /* We connect to the server and list the directory */ + dir->dir_type = SMBC_FILE_SHARE; + + srv = SMBC_server(frame, context, True, server, share, + &workgroup, &user, &password); + + if (!srv) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + dir->srv = srv; + + /* Now, list the files ... */ + + p = path + strlen(path); + path = talloc_asprintf_append(path, "\\*"); + if (!path) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + if (cli_list(targetcli, targetpath, + aDIR | aSYSTEM | aHIDDEN, + dir_list_fn, (void *)dir) < 0) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + saved_errno = SMBC_errno(context, targetcli); + + if (saved_errno == EINVAL) { + /* + * See if they asked to opendir + * something other than a directory. + * If so, the converted error value we + * got would have been EINVAL rather + * than ENOTDIR. + */ + *p = '\0'; /* restore original path */ + + if (SMBC_getatr(context, srv, path, + &mode, NULL, + NULL, NULL, NULL, NULL, + NULL) && + ! IS_DOS_DIR(mode)) { + + /* It is. Correct the error value */ + saved_errno = ENOTDIR; + } + } + + /* + * If there was an error and the server is no + * good any more... + */ + if (cli_is_error(targetcli) && + smbc_getFunctionCheckServer(context)(context, srv)) { + + /* ... then remove it. */ + if (smbc_getFunctionRemoveUnusedServer(context)(context, + srv)) { + /* + * We could not remove the + * server completely, remove + * it from the cache so we + * will not get it again. It + * will be removed when the + * last file/dir is closed. + */ + smbc_getFunctionRemoveCachedServer(context)(context, srv); + } + } + + errno = saved_errno; + TALLOC_FREE(frame); + return NULL; + } + } + + } + + DLIST_ADD(context->internal->files, dir); + TALLOC_FREE(frame); + return dir; + +} + +/* + * Routine to close a directory + */ + +int +SMBC_closedir_ctx(SMBCCTX *context, + SMBCFILE *dir) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + remove_dir(dir); /* Clean it up */ + + DLIST_REMOVE(context->internal->files, dir); + + if (dir) { + + SAFE_FREE(dir->fname); + SAFE_FREE(dir); /* Free the space too */ + } + + TALLOC_FREE(frame); + return 0; + +} + +static void +smbc_readdir_internal(SMBCCTX * context, + struct smbc_dirent *dest, + struct smbc_dirent *src, + int max_namebuf_len) +{ + if (smbc_getOptionUrlEncodeReaddirEntries(context)) { + + /* url-encode the name. get back remaining buffer space */ + max_namebuf_len = + SMBC_urlencode(dest->name, src->name, max_namebuf_len); + + /* We now know the name length */ + dest->namelen = strlen(dest->name); + + /* Save the pointer to the beginning of the comment */ + dest->comment = dest->name + dest->namelen + 1; + + /* Copy the comment */ + strncpy(dest->comment, src->comment, max_namebuf_len - 1); + dest->comment[max_namebuf_len - 1] = '\0'; + + /* Save other fields */ + dest->smbc_type = src->smbc_type; + dest->commentlen = strlen(dest->comment); + dest->dirlen = ((dest->comment + dest->commentlen + 1) - + (char *) dest); + } else { + + /* No encoding. Just copy the entry as is. */ + memcpy(dest, src, src->dirlen); + dest->comment = (char *)(&dest->name + src->namelen + 1); + } + +} + +/* + * Routine to get a directory entry + */ + +struct smbc_dirent * +SMBC_readdir_ctx(SMBCCTX *context, + SMBCFILE *dir) +{ + int maxlen; + struct smbc_dirent *dirp, *dirent; + TALLOC_CTX *frame = talloc_stackframe(); + + /* Check that all is ok first ... */ + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + DEBUG(0, ("Invalid context in SMBC_readdir_ctx()\n")); + TALLOC_FREE(frame); + return NULL; + + } + + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { + + errno = EBADF; + DEBUG(0, ("Invalid dir in SMBC_readdir_ctx()\n")); + TALLOC_FREE(frame); + return NULL; + + } + + if (dir->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + DEBUG(0, ("Found file vs directory in SMBC_readdir_ctx()\n")); + TALLOC_FREE(frame); + return NULL; + + } + + if (!dir->dir_next) { + TALLOC_FREE(frame); + return NULL; + } + + dirent = dir->dir_next->dirent; + if (!dirent) { + + errno = ENOENT; + TALLOC_FREE(frame); + return NULL; + + } + + dirp = (struct smbc_dirent *)context->internal->dirent; + maxlen = (sizeof(context->internal->dirent) - + sizeof(struct smbc_dirent)); + + smbc_readdir_internal(context, dirp, dirent, maxlen); + + dir->dir_next = dir->dir_next->next; + + TALLOC_FREE(frame); + return dirp; +} + +/* + * Routine to get directory entries + */ + +int +SMBC_getdents_ctx(SMBCCTX *context, + SMBCFILE *dir, + struct smbc_dirent *dirp, + int count) +{ + int rem = count; + int reqd; + int maxlen; + char *ndir = (char *)dirp; + struct smbc_dir_list *dirlist; + TALLOC_CTX *frame = talloc_stackframe(); + + /* Check that all is ok first ... */ + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { + + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + if (dir->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + TALLOC_FREE(frame); + return -1; + + } + + /* + * Now, retrieve the number of entries that will fit in what was passed + * We have to figure out if the info is in the list, or we need to + * send a request to the server to get the info. + */ + + while ((dirlist = dir->dir_next)) { + struct smbc_dirent *dirent; + + if (!dirlist->dirent) { + + errno = ENOENT; /* Bad error */ + TALLOC_FREE(frame); + return -1; + + } + + /* Do urlencoding of next entry, if so selected */ + dirent = (struct smbc_dirent *)context->internal->dirent; + maxlen = (sizeof(context->internal->dirent) - + sizeof(struct smbc_dirent)); + smbc_readdir_internal(context, dirent, + dirlist->dirent, maxlen); + + reqd = dirent->dirlen; + + if (rem < reqd) { + + if (rem < count) { /* We managed to copy something */ + + errno = 0; + TALLOC_FREE(frame); + return count - rem; + + } + else { /* Nothing copied ... */ + + errno = EINVAL; /* Not enough space ... */ + TALLOC_FREE(frame); + return -1; + + } + + } + + memcpy(ndir, dirent, reqd); /* Copy the data in ... */ + + ((struct smbc_dirent *)ndir)->comment = + (char *)(&((struct smbc_dirent *)ndir)->name + + dirent->namelen + + 1); + + ndir += reqd; + + rem -= reqd; + + dir->dir_next = dirlist = dirlist -> next; + } + + TALLOC_FREE(frame); + + if (rem == count) + return 0; + else + return count - rem; + +} + +/* + * Routine to create a directory ... + */ + +int +SMBC_mkdir_ctx(SMBCCTX *context, + const char *fname, + mode_t mode) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_mkdir(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + + } + + /*d_printf(">>>mkdir: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ + + if (!cli_mkdir(targetcli, targetpath)) { + + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return 0; + +} + +/* + * Our list function simply checks to see if a directory is not empty + */ + +static int smbc_rmdir_dirempty = True; + +static void +rmdir_list_fn(const char *mnt, + file_info *finfo, + const char *mask, + void *state) +{ + if (strncmp(finfo->name, ".", 1) != 0 && + strncmp(finfo->name, "..", 2) != 0) { + smbc_rmdir_dirempty = False; + } +} + +/* + * Routine to remove a directory + */ + +int +SMBC_rmdir_ctx(SMBCCTX *context, + const char *fname) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_rmdir(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + + } + + /*d_printf(">>>rmdir: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/ + + + if (!cli_rmdir(targetcli, targetpath)) { + + errno = SMBC_errno(context, targetcli); + + if (errno == EACCES) { /* Check if the dir empty or not */ + + /* Local storage to avoid buffer overflows */ + char *lpath; + + smbc_rmdir_dirempty = True; /* Make this so ... */ + + lpath = talloc_asprintf(frame, "%s\\*", + targetpath); + if (!lpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + + if (cli_list(targetcli, lpath, + aDIR | aSYSTEM | aHIDDEN, + rmdir_list_fn, NULL) < 0) { + + /* Fix errno to ignore latest error ... */ + DEBUG(5, ("smbc_rmdir: " + "cli_list returned an error: %d\n", + SMBC_errno(context, targetcli))); + errno = EACCES; + + } + + if (smbc_rmdir_dirempty) + errno = EACCES; + else + errno = ENOTEMPTY; + + } + + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return 0; + +} + +/* + * Routine to return the current directory position + */ + +off_t +SMBC_telldir_ctx(SMBCCTX *context, + SMBCFILE *dir) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { + + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + if (dir->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + TALLOC_FREE(frame); + return -1; + + } + + /* See if we're already at the end. */ + if (dir->dir_next == NULL) { + /* We are. */ + TALLOC_FREE(frame); + return -1; + } + + /* + * We return the pointer here as the offset + */ + TALLOC_FREE(frame); + return (off_t)(long)dir->dir_next->dirent; +} + +/* + * A routine to run down the list and see if the entry is OK + */ + +static struct smbc_dir_list * +check_dir_ent(struct smbc_dir_list *list, + struct smbc_dirent *dirent) +{ + + /* Run down the list looking for what we want */ + + if (dirent) { + + struct smbc_dir_list *tmp = list; + + while (tmp) { + + if (tmp->dirent == dirent) + return tmp; + + tmp = tmp->next; + + } + + } + + return NULL; /* Not found, or an error */ + +} + + +/* + * Routine to seek on a directory + */ + +int +SMBC_lseekdir_ctx(SMBCCTX *context, + SMBCFILE *dir, + off_t offset) +{ + long int l_offset = offset; /* Handle problems of size */ + struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; + struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (dir->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + TALLOC_FREE(frame); + return -1; + + } + + /* Now, check what we were passed and see if it is OK ... */ + + if (dirent == NULL) { /* Seek to the begining of the list */ + + dir->dir_next = dir->dir_list; + TALLOC_FREE(frame); + return 0; + + } + + if (offset == -1) { /* Seek to the end of the list */ + dir->dir_next = NULL; + TALLOC_FREE(frame); + return 0; + } + + /* Now, run down the list and make sure that the entry is OK */ + /* This may need to be changed if we change the format of the list */ + + if ((list_ent = check_dir_ent(dir->dir_list, dirent)) == NULL) { + errno = EINVAL; /* Bad entry */ + TALLOC_FREE(frame); + return -1; + } + + dir->dir_next = list_ent; + + TALLOC_FREE(frame); + return 0; +} + +/* + * Routine to fstat a dir + */ + +int +SMBC_fstatdir_ctx(SMBCCTX *context, + SMBCFILE *dir, + struct stat *st) +{ + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + return -1; + } + + /* No code yet ... */ + return 0; +} + +int +SMBC_chmod_ctx(SMBCCTX *context, + const char *fname, + mode_t newmode) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + uint16 mode; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + mode = 0; + + if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; + if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; + if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; + if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; + + if (!cli_setatr(srv->cli, path, mode, 0)) { + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; +} + +int +SMBC_utimes_ctx(SMBCCTX *context, + const char *fname, + struct timeval *tbuf) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + time_t access_time; + time_t write_time; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (tbuf == NULL) { + access_time = write_time = time(NULL); + } else { + access_time = tbuf[0].tv_sec; + write_time = tbuf[1].tv_sec; + } + + if (DEBUGLVL(4)) { + char *p; + char atimebuf[32]; + char mtimebuf[32]; + + strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1); + atimebuf[sizeof(atimebuf) - 1] = '\0'; + if ((p = strchr(atimebuf, '\n')) != NULL) { + *p = '\0'; + } + + strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1); + mtimebuf[sizeof(mtimebuf) - 1] = '\0'; + if ((p = strchr(mtimebuf, '\n')) != NULL) { + *p = '\0'; + } + + dbgtext("smbc_utimes(%s, atime = %s mtime = %s)\n", + fname, atimebuf, mtimebuf); + } + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (!SMBC_setatr(context, srv, path, + 0, access_time, write_time, 0, 0)) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_setatr */ + } + + TALLOC_FREE(frame); + return 0; +} + +/* + * Routine to unlink() a file + */ + +int +SMBC_unlink_ctx(SMBCCTX *context, + const char *fname) +{ + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + SMBCSRV *srv = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* SMBC_server sets errno */ + + } + + /*d_printf(">>>unlink: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ + + if (!cli_unlink(targetcli, targetpath)) { + + errno = SMBC_errno(context, targetcli); + + if (errno == EACCES) { /* Check if the file is a directory */ + + int saverr = errno; + SMB_OFF_T size = 0; + uint16 mode = 0; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; + SMB_INO_T ino = 0; + + if (!SMBC_getatr(context, srv, path, &mode, &size, + NULL, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { + + /* Hmmm, bad error ... What? */ + + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + else { + + if (IS_DOS_DIR(mode)) + errno = EISDIR; + else + errno = saverr; /* Restore this */ + + } + } + + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return 0; /* Success ... */ + +} + +/* + * Routine to rename() a file + */ + +int +SMBC_rename_ctx(SMBCCTX *ocontext, + const char *oname, + SMBCCTX *ncontext, + const char *nname) +{ + char *server1 = NULL; + char *share1 = NULL; + char *server2 = NULL; + char *share2 = NULL; + char *user1 = NULL; + char *user2 = NULL; + char *password1 = NULL; + char *password2 = NULL; + char *workgroup = NULL; + char *path1 = NULL; + char *path2 = NULL; + char *targetpath1 = NULL; + char *targetpath2 = NULL; + struct cli_state *targetcli1 = NULL; + struct cli_state *targetcli2 = NULL; + SMBCSRV *srv = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!ocontext || !ncontext || + !ocontext->internal->initialized || + !ncontext->internal->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!oname || !nname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); + + if (SMBC_parse_path(frame, + ocontext, + oname, + &workgroup, + &server1, + &share1, + &path1, + &user1, + &password1, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user1 || user1[0] == (char)0) { + user1 = talloc_strdup(frame, smbc_getUser(ocontext)); + if (!user1) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + if (SMBC_parse_path(frame, + ncontext, + nname, + NULL, + &server2, + &share2, + &path2, + &user2, + &password2, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user2 || user2[0] == (char)0) { + user2 = talloc_strdup(frame, smbc_getUser(ncontext)); + if (!user2) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + if (strcmp(server1, server2) || strcmp(share1, share2) || + strcmp(user1, user2)) { + /* Can't rename across file systems, or users?? */ + errno = EXDEV; + TALLOC_FREE(frame); + return -1; + } + + srv = SMBC_server(frame, ocontext, True, + server1, share1, &workgroup, &user1, &password1); + if (!srv) { + TALLOC_FREE(frame); + return -1; + + } + + /*d_printf(">>>rename: resolving %s\n", path1);*/ + if (!cli_resolve_path(frame, "", srv->cli, path1, + &targetcli1, &targetpath1)) { + d_printf("Could not resolve %s\n", path1); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ + /*d_printf(">>>rename: resolving %s\n", path2);*/ + if (!cli_resolve_path(frame, "", srv->cli, path2, + &targetcli2, &targetpath2)) { + d_printf("Could not resolve %s\n", path2); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ + + if (strcmp(targetcli1->desthost, targetcli2->desthost) || + strcmp(targetcli1->share, targetcli2->share)) + { + /* can't rename across file systems */ + errno = EXDEV; + TALLOC_FREE(frame); + return -1; + } + + if (!cli_rename(targetcli1, targetpath1, targetpath2)) { + int eno = SMBC_errno(ocontext, targetcli1); + + if (eno != EEXIST || + !cli_unlink(targetcli1, targetpath2) || + !cli_rename(targetcli1, targetpath1, targetpath2)) { + + errno = eno; + TALLOC_FREE(frame); + return -1; + + } + } + + TALLOC_FREE(frame); + return 0; /* Success */ +} + diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c new file mode 100644 index 0000000000..423450b23e --- /dev/null +++ b/source3/libsmb/libsmb_file.c @@ -0,0 +1,864 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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 "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Routine to open() a file ... + */ + +SMBCFILE * +SMBC_open_ctx(SMBCCTX *context, + const char *fname, + int flags, + mode_t mode) +{ + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *file = NULL; + int fd; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return NULL; + + } + + if (!fname) { + + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + + } + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + if (errno == EPERM) errno = EACCES; + TALLOC_FREE(frame); + return NULL; /* SMBC_server sets errno */ + } + + /* Hmmm, the test for a directory is suspect here ... FIXME */ + + if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { + fd = -1; + } else { + file = SMB_MALLOC_P(SMBCFILE); + + if (!file) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + + ZERO_STRUCTP(file); + + /*d_printf(">>>open: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + SAFE_FREE(file); + TALLOC_FREE(frame); + return NULL; + } + /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ + + if ((fd = cli_open(targetcli, targetpath, flags, + context->internal->share_mode)) < 0) { + + /* Handle the error ... */ + + SAFE_FREE(file); + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return NULL; + + } + + /* Fill in file struct */ + + file->cli_fd = fd; + file->fname = SMB_STRDUP(fname); + file->srv = srv; + file->offset = 0; + file->file = True; + + DLIST_ADD(context->internal->files, file); + + /* + * If the file was opened in O_APPEND mode, all write + * operations should be appended to the file. To do that, + * though, using this protocol, would require a getattrE() + * call for each and every write, to determine where the end + * of the file is. (There does not appear to be an append flag + * in the protocol.) Rather than add all of that overhead of + * retrieving the current end-of-file offset prior to each + * write operation, we'll assume that most append operations + * will continuously write, so we'll just set the offset to + * the end of the file now and hope that's adequate. + * + * Note to self: If this proves inadequate, and O_APPEND + * should, in some cases, be forced for each write, add a + * field in the context options structure, for + * "strict_append_mode" which would select between the current + * behavior (if FALSE) or issuing a getattrE() prior to each + * write and forcing the write to the end of the file (if + * TRUE). Adding that capability will likely require adding + * an "append" flag into the _SMBCFILE structure to track + * whether a file was opened in O_APPEND mode. -- djl + */ + if (flags & O_APPEND) { + if (SMBC_lseek_ctx(context, file, 0, SEEK_END) < 0) { + (void) SMBC_close_ctx(context, file); + errno = ENXIO; + TALLOC_FREE(frame); + return NULL; + } + } + + TALLOC_FREE(frame); + return file; + + } + + /* Check if opendir needed ... */ + + if (fd == -1) { + int eno = 0; + + eno = SMBC_errno(context, srv->cli); + file = smbc_getFunctionOpendir(context)(context, fname); + if (!file) errno = eno; + TALLOC_FREE(frame); + return file; + + } + + errno = EINVAL; /* FIXME, correct errno ? */ + TALLOC_FREE(frame); + return NULL; + +} + +/* + * Routine to create a file + */ + +SMBCFILE * +SMBC_creat_ctx(SMBCCTX *context, + const char *path, + mode_t mode) +{ + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + return NULL; + + } + + return SMBC_open_ctx(context, path, + O_WRONLY | O_CREAT | O_TRUNC, mode); +} + +/* + * Routine to read() a file ... + */ + +ssize_t +SMBC_read_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count) +{ + int ret; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + /* + * offset: + * + * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) -- + * appears to pass file->offset (which is type off_t) differently than + * a local variable of type off_t. Using local variable "offset" in + * the call to cli_read() instead of file->offset fixes a problem + * retrieving data at an offset greater than 4GB. + */ + off_t offset; + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); + + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + offset = file->offset; + + /* Check that the buffer exists ... */ + + if (buf == NULL) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + /*d_printf(">>>read: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>read: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); + + if (ret < 0) { + + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + + file->offset += ret; + + DEBUG(4, (" --> %d\n", ret)); + + TALLOC_FREE(frame); + return ret; /* Success, ret bytes of data ... */ + +} + +/* + * Routine to write() a file ... + */ + +ssize_t +SMBC_write_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count) +{ + int ret; + off_t offset; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + /* First check all pointers before dereferencing them */ + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + /* Check that the buffer exists ... */ + + if (buf == NULL) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + offset = file->offset; /* See "offset" comment in SMBC_read_ctx() */ + + /*d_printf(">>>write: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>write: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ + + ret = cli_write(targetcli, file->cli_fd, + 0, (char *)buf, offset, count); + + if (ret <= 0) { + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + + file->offset += ret; + + TALLOC_FREE(frame); + return ret; /* Success, 0 bytes of data ... */ +} + +/* + * Routine to close() a file ... + */ + +int +SMBC_close_ctx(SMBCCTX *context, + SMBCFILE *file) +{ + SMBCSRV *srv; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + /* IS a dir ... */ + if (!file->file) { + TALLOC_FREE(frame); + return smbc_getFunctionClosedir(context)(context, file); + } + + /*d_printf(">>>close: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>close: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ + + if (!cli_close(targetcli, file->cli_fd)) { + + DEBUG(3, ("cli_close failed on %s. purging server.\n", + file->fname)); + /* Deallocate slot and remove the server + * from the server cache if unused */ + errno = SMBC_errno(context, targetcli); + srv = file->srv; + DLIST_REMOVE(context->internal->files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + smbc_getFunctionRemoveUnusedServer(context)(context, srv); + TALLOC_FREE(frame); + return -1; + + } + + DLIST_REMOVE(context->internal->files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + TALLOC_FREE(frame); + + return 0; +} + +/* + * Get info from an SMB server on a file. Use a qpathinfo call first + * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo + */ +bool +SMBC_getatr(SMBCCTX * context, + SMBCSRV *srv, + char *path, + uint16 *mode, + SMB_OFF_T *size, + struct timespec *create_time_ts, + struct timespec *access_time_ts, + struct timespec *write_time_ts, + struct timespec *change_time_ts, + SMB_INO_T *ino) +{ + char *fixedpath = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + time_t write_time; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /* path fixup for . and .. */ + if (strequal(path, ".") || strequal(path, "..")) { + fixedpath = talloc_strdup(frame, "\\"); + if (!fixedpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } else { + fixedpath = talloc_strdup(frame, path); + if (!fixedpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + trim_string(fixedpath, NULL, "\\.."); + trim_string(fixedpath, NULL, "\\."); + } + DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); + + if (!cli_resolve_path(frame, "", srv->cli, fixedpath, + &targetcli, &targetpath)) { + d_printf("Couldn't resolve %s\n", path); + TALLOC_FREE(frame); + return False; + } + + if (!srv->no_pathinfo2 && + cli_qpathinfo2(targetcli, targetpath, + create_time_ts, + access_time_ts, + write_time_ts, + change_time_ts, + size, mode, ino)) { + TALLOC_FREE(frame); + return True; + } + + /* if this is NT then don't bother with the getatr */ + if (targetcli->capabilities & CAP_NT_SMBS) { + errno = EPERM; + TALLOC_FREE(frame); + return False; + } + + if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) { + + struct timespec w_time_ts; + + w_time_ts = convert_time_t_to_timespec(write_time); + + if (write_time_ts != NULL) { + *write_time_ts = w_time_ts; + } + + if (create_time_ts != NULL) { + *create_time_ts = w_time_ts; + } + + if (access_time_ts != NULL) { + *access_time_ts = w_time_ts; + } + + if (change_time_ts != NULL) { + *change_time_ts = w_time_ts; + } + + srv->no_pathinfo2 = True; + TALLOC_FREE(frame); + return True; + } + + errno = EPERM; + TALLOC_FREE(frame); + return False; + +} + +/* + * Set file info on an SMB server. Use setpathinfo call first. If that + * fails, use setattrE.. + * + * Access and modification time parameters are always used and must be + * provided. Create time, if zero, will be determined from the actual create + * time of the file. If non-zero, the create time will be set as well. + * + * "mode" (attributes) parameter may be set to -1 if it is not to be set. + */ +bool +SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, + time_t create_time, + time_t access_time, + time_t write_time, + time_t change_time, + uint16 mode) +{ + int fd; + int ret; + TALLOC_CTX *frame = talloc_stackframe(); + + /* + * First, try setpathinfo (if qpathinfo succeeded), for it is the + * modern function for "new code" to be using, and it works given a + * filename rather than requiring that the file be opened to have its + * attributes manipulated. + */ + if (srv->no_pathinfo || + ! cli_setpathinfo(srv->cli, path, + create_time, + access_time, + write_time, + change_time, + mode)) { + + /* + * setpathinfo is not supported; go to plan B. + * + * cli_setatr() does not work on win98, and it also doesn't + * support setting the access time (only the modification + * time), so in all cases, we open the specified file and use + * cli_setattrE() which should work on all OS versions, and + * supports both times. + */ + + /* Don't try {q,set}pathinfo() again, with this server */ + srv->no_pathinfo = True; + + /* Open the file */ + if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { + + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return -1; + } + + /* Set the new attributes */ + ret = cli_setattrE(srv->cli, fd, + change_time, + access_time, + write_time); + + /* Close the file */ + cli_close(srv->cli, fd); + + /* + * Unfortunately, setattrE() doesn't have a provision for + * setting the access mode (attributes). We'll have to try + * cli_setatr() for that, and with only this parameter, it + * seems to work on win98. + */ + if (ret && mode != (uint16) -1) { + ret = cli_setatr(srv->cli, path, mode, 0); + } + + if (! ret) { + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return False; + } + } + + TALLOC_FREE(frame); + return True; +} + +/* + * A routine to lseek() a file + */ + +off_t +SMBC_lseek_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t offset, + int whence) +{ + SMB_OFF_T size; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { + + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + if (!file->file) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; /* Can't lseek a dir ... */ + + } + + switch (whence) { + case SEEK_SET: + file->offset = offset; + break; + + case SEEK_CUR: + file->offset += offset; + break; + + case SEEK_END: + /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>lseek: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ + + if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, + &size, NULL, NULL, NULL, NULL, NULL)) + { + SMB_OFF_T b_size = size; + if (!cli_getattrE(targetcli, file->cli_fd, + NULL, &b_size, NULL, NULL, NULL)) + { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } else + size = b_size; + } + file->offset = size + offset; + break; + + default: + errno = EINVAL; + break; + + } + + TALLOC_FREE(frame); + return file->offset; + +} + + +/* + * Routine to truncate a file given by its file descriptor, to a specified size + */ + +int +SMBC_ftruncate_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t length) +{ + SMB_OFF_T size = length; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + if (!file->file) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + if (!cli_ftruncate(targetcli, file->cli_fd, size)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; + +} diff --git a/source3/libsmb/libsmb_misc.c b/source3/libsmb/libsmb_misc.c new file mode 100644 index 0000000000..dd7add5a61 --- /dev/null +++ b/source3/libsmb/libsmb_misc.c @@ -0,0 +1,73 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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 "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * check if an element is part of the list. + */ +int +SMBC_dlist_contains(SMBCFILE * list, SMBCFILE *p) +{ + if (!p || !list) return False; + do { + if (p == list) return True; + list = list->next; + } while (list); + return False; +} + + +/* + * Convert an SMB error into a UNIX error ... + */ +int +SMBC_errno(SMBCCTX *context, + struct cli_state *c) +{ + int ret = cli_errno(c); + + if (cli_is_dos_error(c)) { + uint8 eclass; + uint32 ecode; + + cli_dos_error(c, &eclass, &ecode); + + DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", + (int)eclass, (int)ecode, (int)ecode, ret)); + } else { + NTSTATUS status; + + status = cli_nt_error(c); + + DEBUG(3,("smbc errno %s -> %d\n", + nt_errstr(status), ret)); + } + + return ret; +} + diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c new file mode 100644 index 0000000000..2c3a5f8866 --- /dev/null +++ b/source3/libsmb/libsmb_path.c @@ -0,0 +1,400 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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 "libsmbclient.h" +#include "libsmb_internal.h" + + +/* Used by urldecode_talloc() */ +static int +hex2int( unsigned int _char ) +{ + if ( _char >= 'A' && _char <='F') + return _char - 'A' + 10; + if ( _char >= 'a' && _char <='f') + return _char - 'a' + 10; + if ( _char >= '0' && _char <='9') + return _char - '0'; + return -1; +} + +/* + * SMBC_urldecode() + * and urldecode_talloc() (internal fn.) + * + * Convert strings of %xx to their single character equivalent. Each 'x' must + * be a valid hexadecimal digit, or that % sequence is left undecoded. + * + * dest may, but need not be, the same pointer as src. + * + * Returns the number of % sequences which could not be converted due to lack + * of two following hexadecimal digits. + */ +static int +urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) +{ + int old_length = strlen(src); + int i = 0; + int err_count = 0; + size_t newlen = 1; + char *p, *dest; + + if (old_length == 0) { + return 0; + } + + *pp_dest = NULL; + for (i = 0; i < old_length; ) { + unsigned char character = src[i++]; + + if (character == '%') { + int a = i+1 < old_length ? hex2int(src[i]) : -1; + int b = i+1 < old_length ? hex2int(src[i+1]) : -1; + + /* Replace valid sequence */ + if (a != -1 && b != -1) { + /* Replace valid %xx sequence with %dd */ + character = (a * 16) + b; + if (character == '\0') { + break; /* Stop at %00 */ + } + i += 2; + } else { + err_count++; + } + } + newlen++; + } + + dest = TALLOC_ARRAY(ctx, char, newlen); + if (!dest) { + return err_count; + } + + err_count = 0; + for (p = dest, i = 0; i < old_length; ) { + unsigned char character = src[i++]; + + if (character == '%') { + int a = i+1 < old_length ? hex2int(src[i]) : -1; + int b = i+1 < old_length ? hex2int(src[i+1]) : -1; + + /* Replace valid sequence */ + if (a != -1 && b != -1) { + /* Replace valid %xx sequence with %dd */ + character = (a * 16) + b; + if (character == '\0') { + break; /* Stop at %00 */ + } + i += 2; + } else { + err_count++; + } + } + *p++ = character; + } + + *p = '\0'; + *pp_dest = dest; + return err_count; +} + +int +SMBC_urldecode(char *dest, + char *src, + size_t max_dest_len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + char *pdest; + int ret = urldecode_talloc(frame, &pdest, src); + + if (pdest) { + strlcpy(dest, pdest, max_dest_len); + } + TALLOC_FREE(frame); + return ret; +} + +/* + * SMBC_urlencode() + * + * Convert any characters not specifically allowed in a URL into their %xx + * equivalent. + * + * Returns the remaining buffer length. + */ +int +SMBC_urlencode(char *dest, + char *src, + int max_dest_len) +{ + char hex[] = "0123456789ABCDEF"; + + for (; *src != '\0' && max_dest_len >= 3; src++) { + + if ((*src < '0' && + *src != '-' && + *src != '.') || + (*src > '9' && + *src < 'A') || + (*src > 'Z' && + *src < 'a' && + *src != '_') || + (*src > 'z')) { + *dest++ = '%'; + *dest++ = hex[(*src >> 4) & 0x0f]; + *dest++ = hex[*src & 0x0f]; + max_dest_len -= 3; + } else { + *dest++ = *src; + max_dest_len--; + } + } + + *dest++ = '\0'; + max_dest_len--; + + return max_dest_len; +} + +/* + * Function to parse a path and turn it into components + * + * The general format of an SMB URI is explain in Christopher Hertel's CIFS + * book, at http://ubiqx.org/cifs/Appendix-D.html. We accept a subset of the + * general format ("smb:" only; we do not look for "cifs:"). + * + * + * We accept: + * smb://[[[domain;]user[:password]@]server[/share[/path[/file]]]][?options] + * + * Meaning of URLs: + * + * smb:// Show all workgroups. + * + * The method of locating the list of workgroups varies + * depending upon the setting of the context variable + * context->options.browse_max_lmb_count. This value + * determines the maximum number of local master browsers to + * query for the list of workgroups. In order to ensure that + * a complete list of workgroups is obtained, all master + * browsers must be queried, but if there are many + * workgroups, the time spent querying can begin to add up. + * For small networks (not many workgroups), it is suggested + * that this variable be set to 0, indicating query all local + * master browsers. When the network has many workgroups, a + * reasonable setting for this variable might be around 3. + * + * smb://name/ if name<1D> or name<1B> exists, list servers in + * workgroup, else, if name<20> exists, list all shares + * for server ... + * + * If "options" are provided, this function returns the entire option list as a + * string, for later parsing by the caller. Note that currently, no options + * are supported. + */ + +static const char *smbc_prefix = "smb:"; + +int +SMBC_parse_path(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *fname, + char **pp_workgroup, + char **pp_server, + char **pp_share, + char **pp_path, + char **pp_user, + char **pp_password, + char **pp_options) +{ + char *s; + const char *p; + char *q, *r; + int len; + + /* Ensure these returns are at least valid pointers. */ + *pp_server = talloc_strdup(ctx, ""); + *pp_share = talloc_strdup(ctx, ""); + *pp_path = talloc_strdup(ctx, ""); + *pp_user = talloc_strdup(ctx, ""); + *pp_password = talloc_strdup(ctx, ""); + + if (!*pp_server || !*pp_share || !*pp_path || + !*pp_user || !*pp_password) { + return -1; + } + + /* + * Assume we wont find an authentication domain to parse, so default + * to the workgroup in the provided context. + */ + if (pp_workgroup != NULL) { + *pp_workgroup = + talloc_strdup(ctx, smbc_getWorkgroup(context)); + } + + if (pp_options) { + *pp_options = talloc_strdup(ctx, ""); + } + s = talloc_strdup(ctx, fname); + + /* see if it has the right prefix */ + len = strlen(smbc_prefix); + if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { + return -1; /* What about no smb: ? */ + } + + p = s + len; + + /* Watch the test below, we are testing to see if we should exit */ + + if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { + DEBUG(1, ("Invalid path (does not begin with smb://")); + return -1; + } + + p += 2; /* Skip the double slash */ + + /* See if any options were specified */ + if ((q = strrchr(p, '?')) != NULL ) { + /* There are options. Null terminate here and point to them */ + *q++ = '\0'; + + DEBUG(4, ("Found options '%s'", q)); + + /* Copy the options */ + if (*pp_options != NULL) { + TALLOC_FREE(*pp_options); + *pp_options = talloc_strdup(ctx, q); + } + } + + if (*p == '\0') { + goto decoding; + } + + if (*p == '/') { + int wl = strlen(smbc_getWorkgroup(context)); + + if (wl > 16) { + wl = 16; + } + + *pp_server = talloc_strdup(ctx, smbc_getWorkgroup(context)); + if (!*pp_server) { + return -1; + } + *pp_server[wl] = '\0'; + return 0; + } + + /* + * ok, its for us. Now parse out the server, share etc. + * + * However, we want to parse out [[domain;]user[:password]@] if it + * exists ... + */ + + /* check that '@' occurs before '/', if '/' exists at all */ + q = strchr_m(p, '@'); + r = strchr_m(p, '/'); + if (q && (!r || q < r)) { + char *userinfo = NULL; + const char *u; + + next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@"); + if (!userinfo) { + return -1; + } + u = userinfo; + + if (strchr_m(u, ';')) { + char *workgroup; + next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";"); + if (!workgroup) { + return -1; + } + if (pp_workgroup) { + *pp_workgroup = workgroup; + } + } + + if (strchr_m(u, ':')) { + next_token_no_ltrim_talloc(ctx, &u, pp_user, ":"); + if (!*pp_user) { + return -1; + } + *pp_password = talloc_strdup(ctx, u); + if (!*pp_password) { + return -1; + } + } else { + *pp_user = talloc_strdup(ctx, u); + if (!*pp_user) { + return -1; + } + } + } + + if (!next_token_talloc(ctx, &p, pp_server, "/")) { + return -1; + } + + if (*p == (char)0) { + goto decoding; /* That's it ... */ + } + + if (!next_token_talloc(ctx, &p, pp_share, "/")) { + return -1; + } + + /* + * Prepend a leading slash if there's a file path, as required by + * NetApp filers. + */ + if (*p != '\0') { + *pp_path = talloc_asprintf(ctx, + "\\%s", + p); + } else { + *pp_path = talloc_strdup(ctx, ""); + } + if (!*pp_path) { + return -1; + } + string_replace(*pp_path, '/', '\\'); + +decoding: + + (void) urldecode_talloc(ctx, pp_path, *pp_path); + (void) urldecode_talloc(ctx, pp_server, *pp_server); + (void) urldecode_talloc(ctx, pp_share, *pp_share); + (void) urldecode_talloc(ctx, pp_user, *pp_user); + (void) urldecode_talloc(ctx, pp_password, *pp_password); + + return 0; +} + diff --git a/source3/libsmb/libsmb_printjob.c b/source3/libsmb/libsmb_printjob.c new file mode 100644 index 0000000000..c8d7ad039d --- /dev/null +++ b/source3/libsmb/libsmb_printjob.c @@ -0,0 +1,336 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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 "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Open a print file to be written to by other calls + */ + +SMBCFILE * +SMBC_open_print_job_ctx(SMBCCTX *context, + const char *fname) +{ + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + } + + DEBUG(4, ("SMBC_open_print_job_ctx(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + } + + /* What if the path is empty, or the file exists? */ + + TALLOC_FREE(frame); + return smbc_getFunctionOpen(context)(context, fname, O_WRONLY, 666); +} + +/* + * Routine to print a file on a remote server ... + * + * We open the file, which we assume to be on a remote server, and then + * copy it to a print file on the share specified by printq. + */ + +int +SMBC_print_file_ctx(SMBCCTX *c_file, + const char *fname, + SMBCCTX *c_print, + const char *printq) +{ + SMBCFILE *fid1; + SMBCFILE *fid2; + int bytes; + int saverr; + int tot_bytes = 0; + char buf[4096]; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!c_file || !c_file->internal->initialized || + !c_print || !c_print->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (!fname && !printq) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + /* Try to open the file for reading ... */ + + if ((long)(fid1 = smbc_getFunctionOpen(c_file)(c_file, fname, + O_RDONLY, 0666)) < 0) { + DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); + TALLOC_FREE(frame); + return -1; /* smbc_open sets errno */ + } + + /* Now, try to open the printer file for writing */ + + if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print, + printq)) < 0) { + + saverr = errno; /* Save errno */ + smbc_getFunctionClose(c_file)(c_file, fid1); + errno = saverr; + TALLOC_FREE(frame); + return -1; + + } + + while ((bytes = smbc_getFunctionRead(c_file)(c_file, fid1, + buf, sizeof(buf))) > 0) { + + tot_bytes += bytes; + + if ((smbc_getFunctionWrite(c_print)(c_print, fid2, + buf, bytes)) < 0) { + + saverr = errno; + smbc_getFunctionClose(c_file)(c_file, fid1); + smbc_getFunctionClose(c_print)(c_print, fid2); + errno = saverr; + + } + + } + + saverr = errno; + + smbc_getFunctionClose(c_file)(c_file, fid1); + smbc_getFunctionClose(c_print)(c_print, fid2); + + if (bytes < 0) { + + errno = saverr; + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return tot_bytes; + +} + +/* + * Routine to list print jobs on a printer share ... + */ + +int +SMBC_list_print_jobs_ctx(SMBCCTX *context, + const char *fname, + smbc_list_print_job_fn fn) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (cli_print_queue(srv->cli, + (void (*)(struct print_job_info *))fn) < 0) { + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; + +} + +/* + * Delete a print job from a remote printer share + */ + +int +SMBC_unlink_print_job_ctx(SMBCCTX *context, + const char *fname, + int id) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + int err; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + + } + + if ((err = cli_printjob_del(srv->cli, id)) != 0) { + + if (err < 0) + errno = SMBC_errno(context, srv->cli); + else if (err == ERRnosuchprintjob) + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return 0; + +} + diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c new file mode 100644 index 0000000000..64eb1ea584 --- /dev/null +++ b/source3/libsmb/libsmb_server.c @@ -0,0 +1,686 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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 "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Check a server for being alive and well. + * returns 0 if the server is in shape. Returns 1 on error + * + * Also useable outside libsmbclient to enable external cache + * to do some checks too. + */ +int +SMBC_check_server(SMBCCTX * context, + SMBCSRV * server) +{ + socklen_t size; + struct sockaddr addr; + + size = sizeof(addr); + return (getpeername(server->cli->fd, &addr, &size) == -1); +} + +/* + * Remove a server from the cached server list it's unused. + * On success, 0 is returned. 1 is returned if the server could not be removed. + * + * Also useable outside libsmbclient + */ +int +SMBC_remove_unused_server(SMBCCTX * context, + SMBCSRV * srv) +{ + SMBCFILE * file; + + /* are we being fooled ? */ + if (!context || !context->internal->initialized || !srv) { + return 1; + } + + /* Check all open files/directories for a relation with this server */ + for (file = context->internal->files; file; file = file->next) { + if (file->srv == srv) { + /* Still used */ + DEBUG(3, ("smbc_remove_usused_server: " + "%p still used by %p.\n", + srv, file)); + return 1; + } + } + + DLIST_REMOVE(context->internal->servers, srv); + + cli_shutdown(srv->cli); + srv->cli = NULL; + + DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); + + smbc_getFunctionRemoveCachedServer(context)(context, srv); + + SAFE_FREE(srv); + return 0; +} + +/**************************************************************** + * Call the auth_fn with fixed size (fstring) buffers. + ***************************************************************/ +void +SMBC_call_auth_fn(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password) +{ + fstring workgroup; + fstring username; + fstring password; + + strlcpy(workgroup, *pp_workgroup, sizeof(workgroup)); + strlcpy(username, *pp_username, sizeof(username)); + strlcpy(password, *pp_password, sizeof(password)); + + smbc_getFunctionAuthData(context)(server, share, + workgroup, sizeof(workgroup), + username, sizeof(username), + password, sizeof(password)); + + TALLOC_FREE(*pp_workgroup); + TALLOC_FREE(*pp_username); + TALLOC_FREE(*pp_password); + + *pp_workgroup = talloc_strdup(ctx, workgroup); + *pp_username = talloc_strdup(ctx, username); + *pp_password = talloc_strdup(ctx, password); +} + + +void +SMBC_get_auth_data(const char *server, const char *share, + char *workgroup_buf, int workgroup_buf_len, + char *username_buf, int username_buf_len, + char *password_buf, int password_buf_len) +{ + /* Default function just uses provided data. Nothing to do. */ +} + + + +SMBCSRV * +SMBC_find_server(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password) +{ + SMBCSRV *srv; + int auth_called = 0; + +check_server_cache: + + srv = smbc_getFunctionGetCachedServer(context)(context, + server, share, + *pp_workgroup, + *pp_username); + + if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] || + !*pp_password || !(*pp_password)[0])) { + SMBC_call_auth_fn(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); + + if (!pp_workgroup || !pp_username || !pp_password) { + return NULL; + } + + /* + * However, smbc_auth_fn may have picked up info relating to + * an existing connection, so try for an existing connection + * again ... + */ + auth_called = 1; + goto check_server_cache; + + } + + if (srv) { + if (smbc_getFunctionCheckServer(context)(context, srv)) { + /* + * This server is no good anymore + * Try to remove it and check for more possible + * servers in the cache + */ + if (smbc_getFunctionRemoveUnusedServer(context)(context, + srv)) { + /* + * We could not remove the server completely, + * remove it from the cache so we will not get + * it again. It will be removed when the last + * file/dir is closed. + */ + smbc_getFunctionRemoveCachedServer(context)(context, + srv); + } + + /* + * Maybe there are more cached connections to this + * server + */ + goto check_server_cache; + } + + return srv; + } + + return NULL; +} + +/* + * Connect to a server, possibly on an existing connection + * + * Here, what we want to do is: If the server and username + * match an existing connection, reuse that, otherwise, establish a + * new connection. + * + * If we have to create a new connection, call the auth_fn to get the + * info we need, unless the username and password were passed in. + */ + +SMBCSRV * +SMBC_server(TALLOC_CTX *ctx, + SMBCCTX *context, + bool connect_if_not_found, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password) +{ + SMBCSRV *srv=NULL; + struct cli_state *c; + struct nmb_name called, calling; + const char *server_n = server; + struct sockaddr_storage ss; + int tried_reverse = 0; + int port_try_first; + int port_try_next; + const char *username_used; + NTSTATUS status; + + zero_addr(&ss); + ZERO_STRUCT(c); + + if (server[0] == 0) { + errno = EPERM; + return NULL; + } + + /* Look for a cached connection */ + srv = SMBC_find_server(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); + + /* + * If we found a connection and we're only allowed one share per + * server... + */ + if (srv && + *share != '\0' && + smbc_getOptionOneSharePerServer(context)) { + + /* + * ... then if there's no current connection to the share, + * connect to it. SMBC_find_server(), or rather the function + * pointed to by context->get_cached_srv_fn which + * was called by SMBC_find_server(), will have issued a tree + * disconnect if the requested share is not the same as the + * one that was already connected. + */ + if (srv->cli->cnum == (uint16) -1) { + /* Ensure we have accurate auth info */ + SMBC_call_auth_fn(ctx, context, server, share, + pp_workgroup, + pp_username, + pp_password); + + if (!*pp_workgroup || !*pp_username || !*pp_password) { + errno = ENOMEM; + cli_shutdown(srv->cli); + srv->cli = NULL; + smbc_getFunctionRemoveCachedServer(context)(context, + srv); + return NULL; + } + + /* + * We don't need to renegotiate encryption + * here as the encryption context is not per + * tid. + */ + + if (!cli_send_tconX(srv->cli, share, "?????", + *pp_password, + strlen(*pp_password)+1)) { + + errno = SMBC_errno(context, srv->cli); + cli_shutdown(srv->cli); + srv->cli = NULL; + smbc_getFunctionRemoveCachedServer(context)(context, + srv); + srv = NULL; + } + + /* + * Regenerate the dev value since it's based on both + * server and share + */ + if (srv) { + srv->dev = (dev_t)(str_checksum(server) ^ + str_checksum(share)); + } + } + } + + /* If we have a connection... */ + if (srv) { + + /* ... then we're done here. Give 'em what they came for. */ + return srv; + } + + /* If we're not asked to connect when a connection doesn't exist... */ + if (! connect_if_not_found) { + /* ... then we're done here. */ + return NULL; + } + + if (!*pp_workgroup || !*pp_username || !*pp_password) { + errno = ENOMEM; + return NULL; + } + + make_nmb_name(&calling, smbc_getNetbiosName(context), 0x0); + make_nmb_name(&called , server, 0x20); + + DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server)); + + DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); + +again: + + zero_addr(&ss); + + /* have to open a new connection */ + if ((c = cli_initialise()) == NULL) { + errno = ENOMEM; + return NULL; + } + + if (smbc_getOptionUseKerberos(context)) { + c->use_kerberos = True; + } + + if (smbc_getOptionFallbackAfterKerberos(context)) { + c->fallback_after_kerberos = True; + } + + c->timeout = smbc_getTimeout(context); + + /* + * Force use of port 139 for first try if share is $IPC, empty, or + * null, so browse lists can work + */ + if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) { + port_try_first = 139; + port_try_next = 445; + } else { + port_try_first = 445; + port_try_next = 139; + } + + c->port = port_try_first; + + status = cli_connect(c, server_n, &ss); + if (!NT_STATUS_IS_OK(status)) { + + /* First connection attempt failed. Try alternate port. */ + c->port = port_try_next; + + status = cli_connect(c, server_n, &ss); + if (!NT_STATUS_IS_OK(status)) { + cli_shutdown(c); + errno = ETIMEDOUT; + return NULL; + } + } + + if (!cli_session_request(c, &calling, &called)) { + cli_shutdown(c); + if (strcmp(called.name, "*SMBSERVER")) { + make_nmb_name(&called , "*SMBSERVER", 0x20); + goto again; + } else { /* Try one more time, but ensure we don't loop */ + + /* Only try this if server is an IP address ... */ + + if (is_ipaddress(server) && !tried_reverse) { + fstring remote_name; + struct sockaddr_storage rem_ss; + + if (!interpret_string_addr(&rem_ss, server, + NI_NUMERICHOST)) { + DEBUG(4, ("Could not convert IP address " + "%s to struct sockaddr_storage\n", + server)); + errno = ETIMEDOUT; + return NULL; + } + + tried_reverse++; /* Yuck */ + + if (name_status_find("*", 0, 0, + &rem_ss, remote_name)) { + make_nmb_name(&called, + remote_name, + 0x20); + goto again; + } + } + } + errno = ETIMEDOUT; + return NULL; + } + + DEBUG(4,(" session request ok\n")); + + if (!cli_negprot(c)) { + cli_shutdown(c); + errno = ETIMEDOUT; + return NULL; + } + + username_used = *pp_username; + + if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, + *pp_password, + strlen(*pp_password), + *pp_password, + strlen(*pp_password), + *pp_workgroup))) { + + /* Failed. Try an anonymous login, if allowed by flags. */ + username_used = ""; + + if (smbc_getOptionNoAutoAnonymousLogin(context) || + !NT_STATUS_IS_OK(cli_session_setup(c, username_used, + *pp_password, 1, + *pp_password, 0, + *pp_workgroup))) { + + cli_shutdown(c); + errno = EPERM; + return NULL; + } + } + + DEBUG(4,(" session setup ok\n")); + + if (!cli_send_tconX(c, share, "?????", + *pp_password, strlen(*pp_password)+1)) { + errno = SMBC_errno(context, c); + cli_shutdown(c); + return NULL; + } + + DEBUG(4,(" tconx ok\n")); + + if (context->internal->smb_encryption_level) { + /* Attempt UNIX smb encryption. */ + if (!NT_STATUS_IS_OK(cli_force_encryption(c, + username_used, + *pp_password, + *pp_workgroup))) { + + /* + * context->smb_encryption_level == 1 + * means don't fail if encryption can't be negotiated, + * == 2 means fail if encryption can't be negotiated. + */ + + DEBUG(4,(" SMB encrypt failed\n")); + + if (context->internal->smb_encryption_level == 2) { + cli_shutdown(c); + errno = EPERM; + return NULL; + } + } + DEBUG(4,(" SMB encrypt ok\n")); + } + + /* + * Ok, we have got a nice connection + * Let's allocate a server structure. + */ + + srv = SMB_MALLOC_P(SMBCSRV); + if (!srv) { + errno = ENOMEM; + goto failed; + } + + ZERO_STRUCTP(srv); + srv->cli = c; + srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); + srv->no_pathinfo = False; + srv->no_pathinfo2 = False; + srv->no_nt_session = False; + + /* now add it to the cache (internal or external) */ + /* Let the cache function set errno if it wants to */ + errno = 0; + if (smbc_getFunctionAddCachedServer(context)(context, srv, + server, share, + *pp_workgroup, + *pp_username)) { + int saved_errno = errno; + DEBUG(3, (" Failed to add server to cache\n")); + errno = saved_errno; + if (errno == 0) { + errno = ENOMEM; + } + goto failed; + } + + DEBUG(2, ("Server connect ok: //%s/%s: %p\n", + server, share, srv)); + + DLIST_ADD(context->internal->servers, srv); + return srv; + +failed: + cli_shutdown(c); + if (!srv) { + return NULL; + } + + SAFE_FREE(srv); + return NULL; +} + +/* + * Connect to a server for getting/setting attributes, possibly on an existing + * connection. This works similarly to SMBC_server(). + */ +SMBCSRV * +SMBC_attr_server(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password) +{ + int flags; + struct sockaddr_storage ss; + struct cli_state *ipc_cli; + struct rpc_pipe_client *pipe_hnd; + NTSTATUS nt_status; + SMBCSRV *ipc_srv=NULL; + + /* + * See if we've already created this special connection. Reference + * our "special" share name '*IPC$', which is an impossible real share + * name due to the leading asterisk. + */ + ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", + pp_workgroup, pp_username, pp_password); + if (!ipc_srv) { + + /* We didn't find a cached connection. Get the password */ + if (!*pp_password || (*pp_password)[0] == '\0') { + /* ... then retrieve it now. */ + SMBC_call_auth_fn(ctx, context, server, share, + pp_workgroup, + pp_username, + pp_password); + if (!*pp_workgroup || !*pp_username || !*pp_password) { + errno = ENOMEM; + return NULL; + } + } + + flags = 0; + if (smbc_getOptionUseKerberos(context)) { + flags |= CLI_FULL_CONNECTION_USE_KERBEROS; + } + + zero_addr(&ss); + nt_status = cli_full_connection(&ipc_cli, + global_myname(), server, + &ss, 0, "IPC$", "?????", + *pp_username, + *pp_workgroup, + *pp_password, + flags, + Undefined, NULL); + if (! NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("cli_full_connection failed! (%s)\n", + nt_errstr(nt_status))); + errno = ENOTSUP; + return NULL; + } + + if (context->internal->smb_encryption_level) { + /* Attempt UNIX smb encryption. */ + if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, + *pp_username, + *pp_password, + *pp_workgroup))) { + + /* + * context->smb_encryption_level == + * 1 means don't fail if encryption can't be + * negotiated, == 2 means fail if encryption + * can't be negotiated. + */ + + DEBUG(4,(" SMB encrypt failed on IPC$\n")); + + if (context->internal->smb_encryption_level == 2) { + cli_shutdown(ipc_cli); + errno = EPERM; + return NULL; + } + } + DEBUG(4,(" SMB encrypt ok on IPC$\n")); + } + + ipc_srv = SMB_MALLOC_P(SMBCSRV); + if (!ipc_srv) { + errno = ENOMEM; + cli_shutdown(ipc_cli); + return NULL; + } + + ZERO_STRUCTP(ipc_srv); + ipc_srv->cli = ipc_cli; + + pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, + PI_LSARPC, + &nt_status); + if (!pipe_hnd) { + DEBUG(1, ("cli_nt_session_open fail!\n")); + errno = ENOTSUP; + cli_shutdown(ipc_srv->cli); + free(ipc_srv); + return NULL; + } + + /* + * Some systems don't support + * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 + * so we might as well do it too. + */ + + nt_status = rpccli_lsa_open_policy( + pipe_hnd, + talloc_tos(), + True, + GENERIC_EXECUTE_ACCESS, + &ipc_srv->pol); + + if (!NT_STATUS_IS_OK(nt_status)) { + errno = SMBC_errno(context, ipc_srv->cli); + cli_shutdown(ipc_srv->cli); + return NULL; + } + + /* now add it to the cache (internal or external) */ + + errno = 0; /* let cache function set errno if it likes */ + if (smbc_getFunctionAddCachedServer(context)(context, ipc_srv, + server, + "*IPC$", + *pp_workgroup, + *pp_username)) { + DEBUG(3, (" Failed to add server to cache\n")); + if (errno == 0) { + errno = ENOMEM; + } + cli_shutdown(ipc_srv->cli); + free(ipc_srv); + return NULL; + } + + DLIST_ADD(context->internal->servers, ipc_srv); + } + + return ipc_srv; +} diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c new file mode 100644 index 0000000000..d0823bd77e --- /dev/null +++ b/source3/libsmb/libsmb_setget.c @@ -0,0 +1,905 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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" +#define __LIBSMBCLIENT_INTERNAL__ +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/** Get the netbios name used for making connections */ +char * +smbc_getNetbiosName(SMBCCTX *c) +{ + return c->netbios_name; +} + +/** Set the netbios name used for making connections */ +void +smbc_setNetbiosName(SMBCCTX *c, char * netbios_name) +{ + c->netbios_name = netbios_name; +} + +/** Get the workgroup used for making connections */ +char * +smbc_getWorkgroup(SMBCCTX *c) +{ + return c->workgroup; +} + +/** Set the workgroup used for making connections */ +void +smbc_setWorkgroup(SMBCCTX *c, char * workgroup) +{ + c->workgroup = workgroup; +} + +/** Get the username used for making connections */ +char * +smbc_getUser(SMBCCTX *c) +{ + return c->user; +} + +/** Set the username used for making connections */ +void +smbc_setUser(SMBCCTX *c, char * user) +{ + c->user = user; +} + +/** Get the debug level */ +int +smbc_getDebug(SMBCCTX *c) +{ + return c->debug; +} + +/** Set the debug level */ +void +smbc_setDebug(SMBCCTX *c, int debug) +{ + c->debug = debug; + DEBUGLEVEL = debug; +} + +/** + * Get the timeout used for waiting on connections and response data + * (in milliseconds) + */ +int +smbc_getTimeout(SMBCCTX *c) +{ + return c->timeout; +} + +/** + * Set the timeout used for waiting on connections and response data + * (in milliseconds) + */ +void +smbc_setTimeout(SMBCCTX *c, int timeout) +{ + c->timeout = timeout; +} + +/** Get whether to log to standard error instead of standard output */ +smbc_bool +smbc_getOptionDebugToStderr(SMBCCTX *c) +{ + return c->internal->debug_stderr; +} + +/** Set whether to log to standard error instead of standard output */ +void +smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b) +{ + c->internal->debug_stderr = b; +} + +/** + * Get whether to use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also setting/getting + * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME + * was supposed to be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +smbc_bool +smbc_getOptionFullTimeNames(SMBCCTX *c) +{ + return c->internal->full_time_names; +} + +/** + * Set whether to use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also setting/getting + * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME + * was supposed to be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +void +smbc_setOptionFullTimeNames(SMBCCTX *c, smbc_bool b) +{ + c->internal->full_time_names = b; +} + +/** + * Get the share mode to use for files opened with SMBC_open_ctx(). The + * default is SMBC_SHAREMODE_DENY_NONE. + */ +smbc_share_mode +smbc_getOptionOpenShareMode(SMBCCTX *c) +{ + return c->internal->share_mode; +} + +/** + * Set the share mode to use for files opened with SMBC_open_ctx(). The + * default is SMBC_SHAREMODE_DENY_NONE. + */ +void +smbc_setOptionOpenShareMode(SMBCCTX *c, smbc_share_mode share_mode) +{ + c->internal->share_mode = share_mode; +} + +/** Retrieve a previously set user data handle */ +void * +smbc_getOptionUserData(SMBCCTX *c) +{ + return c->internal->user_data; +} + +/** Save a user data handle */ +void +smbc_setOptionUserData(SMBCCTX *c, void *user_data) +{ + c->internal->user_data = user_data; +} + +/** Get the encoded value for encryption level. */ +smbc_smb_encrypt_level +smbc_getOptionSmbEncryptionLevel(SMBCCTX *c) +{ + return c->internal->smb_encryption_level; +} + +/** Set the encoded value for encryption level. */ +void +smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level) +{ + c->internal->smb_encryption_level = level; +} + +/** + * Get from how many local master browsers should the list of workgroups be + * retrieved. It can take up to 12 minutes or longer after a server becomes a + * local master browser, for it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client never knows + * which local master browser will be found first, the one which is found + * first and used to retrieve a browse list may have an incomplete or empty + * browse list. By requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small networks (few + * workgroups), it is recommended that this value be set to 0, causing the + * browse lists from all found local master browsers to be retrieved and + * merged. For networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ +int +smbc_getOptionBrowseMaxLmbCount(SMBCCTX *c) +{ + return c->options.browse_max_lmb_count; +} + +/** + * Set from how many local master browsers should the list of workgroups be + * retrieved. It can take up to 12 minutes or longer after a server becomes a + * local master browser, for it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client never knows + * which local master browser will be found first, the one which is found + * first and used to retrieve a browse list may have an incomplete or empty + * browse list. By requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small networks (few + * workgroups), it is recommended that this value be set to 0, causing the + * browse lists from all found local master browsers to be retrieved and + * merged. For networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ +void +smbc_setOptionBrowseMaxLmbCount(SMBCCTX *c, int count) +{ + c->options.browse_max_lmb_count = count; +} + +/** + * Get whether to url-encode readdir entries. + * + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ +smbc_bool +smbc_getOptionUrlEncodeReaddirEntries(SMBCCTX *c) +{ + return c->options.urlencode_readdir_entries; +} + +/** + * Set whether to url-encode readdir entries. + * + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ +void +smbc_setOptionUrlEncodeReaddirEntries(SMBCCTX *c, smbc_bool b) +{ + c->options.urlencode_readdir_entries = b; +} + +/** + * Get whether to use the same connection for all shares on a server. + * + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ +smbc_bool +smbc_getOptionOneSharePerServer(SMBCCTX *c) +{ + return c->options.one_share_per_server; +} + +/** + * Set whether to use the same connection for all shares on a server. + * + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ +void +smbc_setOptionOneSharePerServer(SMBCCTX *c, smbc_bool b) +{ + c->options.one_share_per_server = b; +} + +/** Get whether to enable use of kerberos */ +smbc_bool +smbc_getOptionUseKerberos(SMBCCTX *c) +{ + return c->flags & SMB_CTX_FLAG_USE_KERBEROS ? True : False; +} + +/** Set whether to enable use of kerberos */ +void +smbc_setOptionUseKerberos(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags |= SMB_CTX_FLAG_USE_KERBEROS; + } else { + c->flags &= ~SMB_CTX_FLAG_USE_KERBEROS; + } +} + +/** Get whether to fallback after kerberos */ +smbc_bool +smbc_getOptionFallbackAfterKerberos(SMBCCTX *c) +{ + return c->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS ? True : False; +} + +/** Set whether to fallback after kerberos */ +void +smbc_setOptionFallbackAfterKerberos(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; + } else { + c->flags &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; + } +} + +/** Get whether to automatically select anonymous login */ +smbc_bool +smbc_getOptionNoAutoAnonymousLogin(SMBCCTX *c) +{ + return c->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON ? True : False; +} + +/** Set whether to automatically select anonymous login */ +void +smbc_setOptionNoAutoAnonymousLogin(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; + } else { + c->flags &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; + } +} + +/** Get the function for obtaining authentication data */ +smbc_get_auth_data_fn +smbc_getFunctionAuthData(SMBCCTX *c) +{ + return c->callbacks.auth_fn; +} + +/** Set the function for obtaining authentication data */ +void +smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn) +{ + c->internal->auth_fn_with_context = NULL; + c->callbacks.auth_fn = fn; +} + +/** Get the new-style authentication function which includes the context. */ +smbc_get_auth_data_with_context_fn +smbc_getFunctionAuthDataWithContext(SMBCCTX *c) +{ + return c->internal->auth_fn_with_context; +} + +/** Set the new-style authentication function which includes the context. */ +void +smbc_setFunctionAuthDataWithContext(SMBCCTX *c, + smbc_get_auth_data_with_context_fn fn) +{ + c->callbacks.auth_fn = NULL; + c->internal->auth_fn_with_context = fn; +} + +/** Get the function for checking if a server is still good */ +smbc_check_server_fn +smbc_getFunctionCheckServer(SMBCCTX *c) +{ + return c->callbacks.check_server_fn; +} + +/** Set the function for checking if a server is still good */ +void +smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn) +{ + c->callbacks.check_server_fn = fn; +} + +/** Get the function for removing a server if unused */ +smbc_remove_unused_server_fn +smbc_getFunctionRemoveUnusedServer(SMBCCTX *c) +{ + return c->callbacks.remove_unused_server_fn; +} + +/** Set the function for removing a server if unused */ +void +smbc_setFunctionRemoveUnusedServer(SMBCCTX *c, + smbc_remove_unused_server_fn fn) +{ + c->callbacks.remove_unused_server_fn = fn; +} + +/** Get the function for adding a cached server */ +smbc_add_cached_srv_fn +smbc_getFunctionAddCachedServer(SMBCCTX *c) +{ + return c->callbacks.add_cached_srv_fn; +} + +/** Set the function for adding a cached server */ +void +smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn) +{ + c->callbacks.add_cached_srv_fn = fn; +} + +/** Get the function for server cache lookup */ +smbc_get_cached_srv_fn +smbc_getFunctionGetCachedServer(SMBCCTX *c) +{ + return c->callbacks.get_cached_srv_fn; +} + +/** Set the function for server cache lookup */ +void +smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn) +{ + c->callbacks.get_cached_srv_fn = fn; +} + +/** Get the function for server cache removal */ +smbc_remove_cached_srv_fn +smbc_getFunctionRemoveCachedServer(SMBCCTX *c) +{ + return c->callbacks.remove_cached_srv_fn; +} + +/** Set the function for server cache removal */ +void +smbc_setFunctionRemoveCachedServer(SMBCCTX *c, + smbc_remove_cached_srv_fn fn) +{ + c->callbacks.remove_cached_srv_fn = fn; +} + +/** + * Get the function for server cache purging. This function tries to + * remove all cached servers (e.g. on disconnect) + */ +smbc_purge_cached_fn +smbc_getFunctionPurgeCachedServers(SMBCCTX *c) +{ + return c->callbacks.purge_cached_fn; +} + +/** Set the function to store private data of the server cache */ +void smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache) +{ + c->internal->server_cache = cache; +} + +/** Get the function to store private data of the server cache */ +struct smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c) +{ + return c->internal->server_cache; +} + + +/** + * Set the function for server cache purging. This function tries to + * remove all cached servers (e.g. on disconnect) + */ +void +smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_fn fn) +{ + c->callbacks.purge_cached_fn = fn; +} + +/** + * Callable functions for files. + */ + +smbc_open_fn +smbc_getFunctionOpen(SMBCCTX *c) +{ + return c->open; +} + +void +smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn) +{ + c->open = fn; +} + +smbc_creat_fn +smbc_getFunctionCreat(SMBCCTX *c) +{ + return c->creat; +} + +void +smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn) +{ + c->creat = fn; +} + +smbc_read_fn +smbc_getFunctionRead(SMBCCTX *c) +{ + return c->read; +} + +void +smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn) +{ + c->read = fn; +} + +smbc_write_fn +smbc_getFunctionWrite(SMBCCTX *c) +{ + return c->write; +} + +void +smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn) +{ + c->write = fn; +} + +smbc_unlink_fn +smbc_getFunctionUnlink(SMBCCTX *c) +{ + return c->unlink; +} + +void +smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn) +{ + c->unlink = fn; +} + +smbc_rename_fn +smbc_getFunctionRename(SMBCCTX *c) +{ + return c->rename; +} + +void +smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn) +{ + c->rename = fn; +} + +smbc_lseek_fn +smbc_getFunctionLseek(SMBCCTX *c) +{ + return c->lseek; +} + +void +smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn) +{ + c->lseek = fn; +} + +smbc_stat_fn +smbc_getFunctionStat(SMBCCTX *c) +{ + return c->stat; +} + +void +smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn) +{ + c->stat = fn; +} + +smbc_fstat_fn +smbc_getFunctionFstat(SMBCCTX *c) +{ + return c->fstat; +} + +void +smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn) +{ + c->fstat = fn; +} + +smbc_ftruncate_fn +smbc_getFunctionFtruncate(SMBCCTX *c) +{ + return c->internal->posix_emu.ftruncate_fn; +} + +void +smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn) +{ + c->internal->posix_emu.ftruncate_fn = fn; +} + +smbc_close_fn +smbc_getFunctionClose(SMBCCTX *c) +{ + return c->close_fn; +} + +void +smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn) +{ + c->close_fn = fn; +} + + +/** + * Callable functions for directories. + */ + +smbc_opendir_fn +smbc_getFunctionOpendir(SMBCCTX *c) +{ + return c->opendir; +} + +void +smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn) +{ + c->opendir = fn; +} + +smbc_closedir_fn +smbc_getFunctionClosedir(SMBCCTX *c) +{ + return c->closedir; +} + +void +smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn) +{ + c->closedir = fn; +} + +smbc_readdir_fn +smbc_getFunctionReaddir(SMBCCTX *c) +{ + return c->readdir; +} + +void +smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn) +{ + c->readdir = fn; +} + +smbc_getdents_fn +smbc_getFunctionGetdents(SMBCCTX *c) +{ + return c->getdents; +} + +void +smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn) +{ + c->getdents = fn; +} + +smbc_mkdir_fn +smbc_getFunctionMkdir(SMBCCTX *c) +{ + return c->mkdir; +} + +void +smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn) +{ + c->mkdir = fn; +} + +smbc_rmdir_fn +smbc_getFunctionRmdir(SMBCCTX *c) +{ + return c->rmdir; +} + +void +smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn) +{ + c->rmdir = fn; +} + +smbc_telldir_fn +smbc_getFunctionTelldir(SMBCCTX *c) +{ + return c->telldir; +} + +void +smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn) +{ + c->telldir = fn; +} + +smbc_lseekdir_fn +smbc_getFunctionLseekdir(SMBCCTX *c) +{ + return c->lseekdir; +} + +void +smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn) +{ + c->lseekdir = fn; +} + +smbc_fstatdir_fn +smbc_getFunctionFstatdir(SMBCCTX *c) +{ + return c->fstatdir; +} + +void +smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn) +{ + c->fstatdir = fn; +} + + +/** + * Callable functions applicable to both files and directories. + */ + +smbc_chmod_fn +smbc_getFunctionChmod(SMBCCTX *c) +{ + return c->chmod; +} + +void +smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn) +{ + c->chmod = fn; +} + +smbc_utimes_fn +smbc_getFunctionUtimes(SMBCCTX *c) +{ + return c->utimes; +} + +void +smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn) +{ + c->utimes = fn; +} + +smbc_setxattr_fn +smbc_getFunctionSetxattr(SMBCCTX *c) +{ + return c->setxattr; +} + +void +smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn) +{ + c->setxattr = fn; +} + +smbc_getxattr_fn +smbc_getFunctionGetxattr(SMBCCTX *c) +{ + return c->getxattr; +} + +void +smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn) +{ + c->getxattr = fn; +} + +smbc_removexattr_fn +smbc_getFunctionRemovexattr(SMBCCTX *c) +{ + return c->removexattr; +} + +void +smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn) +{ + c->removexattr = fn; +} + +smbc_listxattr_fn +smbc_getFunctionListxattr(SMBCCTX *c) +{ + return c->listxattr; +} + +void +smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn) +{ + c->listxattr = fn; +} + + +/** + * Callable functions related to printing + */ + +smbc_print_file_fn +smbc_getFunctionPrintFile(SMBCCTX *c) +{ + return c->print_file; +} + +void +smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn) +{ + c->print_file = fn; +} + +smbc_open_print_job_fn +smbc_getFunctionOpenPrintJob(SMBCCTX *c) +{ + return c->open_print_job; +} + +void +smbc_setFunctionOpenPrintJob(SMBCCTX *c, + smbc_open_print_job_fn fn) +{ + c->open_print_job = fn; +} + +smbc_list_print_jobs_fn +smbc_getFunctionListPrintJobs(SMBCCTX *c) +{ + return c->list_print_jobs; +} + +void +smbc_setFunctionListPrintJobs(SMBCCTX *c, + smbc_list_print_jobs_fn fn) +{ + c->list_print_jobs = fn; +} + +smbc_unlink_print_job_fn +smbc_getFunctionUnlinkPrintJob(SMBCCTX *c) +{ + return c->unlink_print_job; +} + +void +smbc_setFunctionUnlinkPrintJob(SMBCCTX *c, + smbc_unlink_print_job_fn fn) +{ + c->unlink_print_job = fn; +} + diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c new file mode 100644 index 0000000000..27546f687e --- /dev/null +++ b/source3/libsmb/libsmb_stat.c @@ -0,0 +1,302 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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 "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Generate an inode number from file name for those things that need it + */ + +static ino_t +generate_inode(SMBCCTX *context, + const char *name) +{ + if (!context || !context->internal->initialized) { + + errno = EINVAL; + return -1; + + } + + if (!*name) return 2; /* FIXME, why 2 ??? */ + return (ino_t)str_checksum(name); + +} + +/* + * Routine to put basic stat info into a stat structure ... Used by stat and + * fstat below. + */ + +static int +setup_stat(SMBCCTX *context, + struct stat *st, + char *fname, + SMB_OFF_T size, + int mode) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + st->st_mode = 0; + + if (IS_DOS_DIR(mode)) { + st->st_mode = SMBC_DIR_MODE; + } else { + st->st_mode = SMBC_FILE_MODE; + } + + if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; + if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; + if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; + if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; + + st->st_size = size; +#ifdef HAVE_STAT_ST_BLKSIZE + st->st_blksize = 512; +#endif +#ifdef HAVE_STAT_ST_BLOCKS + st->st_blocks = (size+511)/512; +#endif +#ifdef HAVE_STRUCT_STAT_ST_RDEV + st->st_rdev = 0; +#endif + st->st_uid = getuid(); + st->st_gid = getgid(); + + if (IS_DOS_DIR(mode)) { + st->st_nlink = 2; + } else { + st->st_nlink = 1; + } + + if (st->st_ino == 0) { + st->st_ino = generate_inode(context, fname); + } + + TALLOC_FREE(frame); + return True; /* FIXME: Is this needed ? */ + +} + +/* + * Routine to stat a file given a name + */ + +int +SMBC_stat_ctx(SMBCCTX *context, + const char *fname, + struct stat *st) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; + SMB_OFF_T size = 0; + uint16 mode = 0; + SMB_INO_T ino = 0; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_stat(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (!SMBC_getatr(context, srv, path, &mode, &size, + NULL, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return -1; + } + + st->st_ino = ino; + + setup_stat(context, st, (char *) fname, size, mode); + + set_atimespec(st, access_time_ts); + set_ctimespec(st, change_time_ts); + set_mtimespec(st, write_time_ts); + st->st_dev = srv->dev; + + TALLOC_FREE(frame); + return 0; + +} + +/* + * Routine to stat a file given an fd + */ + +int +SMBC_fstat_ctx(SMBCCTX *context, + SMBCFILE *file, + struct stat *st) +{ + struct timespec change_time_ts; + struct timespec access_time_ts; + struct timespec write_time_ts; + SMB_OFF_T size; + uint16 mode; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + SMB_INO_T ino = 0; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + if (!file->file) { + TALLOC_FREE(frame); + return smbc_getFunctionFstatdir(context)(context, file, st); + } + + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, + NULL, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { + + time_t change_time, access_time, write_time; + + if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, + &change_time, &access_time, &write_time)) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + change_time_ts = convert_time_t_to_timespec(change_time); + access_time_ts = convert_time_t_to_timespec(access_time); + write_time_ts = convert_time_t_to_timespec(write_time); + } + + st->st_ino = ino; + + setup_stat(context, st, file->fname, size, mode); + + set_atimespec(st, access_time_ts); + set_ctimespec(st, change_time_ts); + set_mtimespec(st, write_time_ts); + st->st_dev = file->srv->dev; + + TALLOC_FREE(frame); + return 0; + +} diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c new file mode 100644 index 0000000000..e17146e611 --- /dev/null +++ b/source3/libsmb/libsmb_xattr.c @@ -0,0 +1,2301 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 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 + 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 "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Find an lsa pipe handle associated with a cli struct. + */ +static struct rpc_pipe_client * +find_lsa_pipe_hnd(struct cli_state *ipc_cli) +{ + struct rpc_pipe_client *pipe_hnd; + + for (pipe_hnd = ipc_cli->pipe_list; + pipe_hnd; + pipe_hnd = pipe_hnd->next) { + + if (pipe_hnd->pipe_idx == PI_LSARPC) { + return pipe_hnd; + } + } + + return NULL; +} + +/* + * Sort ACEs according to the documentation at + * http://support.microsoft.com/kb/269175, at least as far as it defines the + * order. + */ + +static int +ace_compare(SEC_ACE *ace1, + SEC_ACE *ace2) +{ + bool b1; + bool b2; + + /* If the ACEs are equal, we have nothing more to do. */ + if (sec_ace_equal(ace1, ace2)) { + return 0; + } + + /* Inherited follow non-inherited */ + b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); + b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * What shall we do with AUDITs and ALARMs? It's undefined. We'll + * sort them after DENY and ALLOW. + */ + b1 = (ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED && + ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && + ace1->type != SEC_ACE_TYPE_ACCESS_DENIED && + ace1->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + b2 = (ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED && + ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && + ace2->type != SEC_ACE_TYPE_ACCESS_DENIED && + ace2->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* Allowed ACEs follow denied ACEs */ + b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || + ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); + b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED || + ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * ACEs applying to an entity's object follow those applying to the + * entity itself + */ + b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + ace1->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + ace2->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * If we get this far, the ACEs are similar as far as the + * characteristics we typically care about (those defined by the + * referenced MS document). We'll now sort by characteristics that + * just seems reasonable. + */ + + if (ace1->type != ace2->type) { + return ace2->type - ace1->type; + } + + if (sid_compare(&ace1->trustee, &ace2->trustee)) { + return sid_compare(&ace1->trustee, &ace2->trustee); + } + + if (ace1->flags != ace2->flags) { + return ace1->flags - ace2->flags; + } + + if (ace1->access_mask != ace2->access_mask) { + return ace1->access_mask - ace2->access_mask; + } + + if (ace1->size != ace2->size) { + return ace1->size - ace2->size; + } + + return memcmp(ace1, ace2, sizeof(SEC_ACE)); +} + + +static void +sort_acl(SEC_ACL *the_acl) +{ + uint32 i; + if (!the_acl) return; + + qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), + QSORT_CAST ace_compare); + + for (i=1;i<the_acl->num_aces;) { + if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { + int j; + for (j=i; j<the_acl->num_aces-1; j++) { + the_acl->aces[j] = the_acl->aces[j+1]; + } + the_acl->num_aces--; + } else { + i++; + } + } +} + +/* convert a SID to a string, either numeric or username/group */ +static void +convert_sid_to_string(struct cli_state *ipc_cli, + POLICY_HND *pol, + fstring str, + bool numeric, + DOM_SID *sid) +{ + char **domains = NULL; + char **names = NULL; + enum lsa_SidType *types = NULL; + struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); + TALLOC_CTX *ctx; + + sid_to_fstring(str, sid); + + if (numeric) { + return; /* no lookup desired */ + } + + if (!pipe_hnd) { + return; + } + + /* Ask LSA to convert the sid to a name */ + + ctx = talloc_stackframe(); + + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, + pol, 1, sid, &domains, + &names, &types)) || + !domains || !domains[0] || !names || !names[0]) { + TALLOC_FREE(ctx); + return; + } + + TALLOC_FREE(ctx); + /* Converted OK */ + + slprintf(str, sizeof(fstring) - 1, "%s%s%s", + domains[0], lp_winbind_separator(), + names[0]); +} + +/* convert a string to a SID, either numeric or username/group */ +static bool +convert_string_to_sid(struct cli_state *ipc_cli, + POLICY_HND *pol, + bool numeric, + DOM_SID *sid, + const char *str) +{ + enum lsa_SidType *types = NULL; + DOM_SID *sids = NULL; + bool result = True; + TALLOC_CTX *ctx = NULL; + struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); + + if (!pipe_hnd) { + return False; + } + + if (numeric) { + if (strncmp(str, "S-", 2) == 0) { + return string_to_sid(sid, str); + } + + result = False; + goto done; + } + + ctx = talloc_stackframe(); + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, + pol, 1, &str, + NULL, 1, &sids, + &types))) { + result = False; + goto done; + } + + sid_copy(sid, &sids[0]); +done: + + TALLOC_FREE(ctx); + return result; +} + + +/* parse an ACE in the same format as print_ace() */ +static bool +parse_ace(struct cli_state *ipc_cli, + POLICY_HND *pol, + SEC_ACE *ace, + bool numeric, + char *str) +{ + char *p; + const char *cp; + char *tok; + unsigned int atype; + unsigned int aflags; + unsigned int amask; + DOM_SID sid; + SEC_ACCESS mask; + const struct perm_value *v; + struct perm_value { + const char *perm; + uint32 mask; + }; + TALLOC_CTX *frame = talloc_stackframe(); + + /* These values discovered by inspection */ + static const struct perm_value special_values[] = { + { "R", 0x00120089 }, + { "W", 0x00120116 }, + { "X", 0x001200a0 }, + { "D", 0x00010000 }, + { "P", 0x00040000 }, + { "O", 0x00080000 }, + { NULL, 0 }, + }; + + static const struct perm_value standard_values[] = { + { "READ", 0x001200a9 }, + { "CHANGE", 0x001301bf }, + { "FULL", 0x001f01ff }, + { NULL, 0 }, + }; + + + ZERO_STRUCTP(ace); + p = strchr_m(str,':'); + if (!p) { + TALLOC_FREE(frame); + return False; + } + *p = '\0'; + p++; + /* Try to parse numeric form */ + + if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && + convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { + goto done; + } + + /* Try to parse text form */ + + if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { + TALLOC_FREE(frame); + return false; + } + + cp = p; + if (!next_token_talloc(frame, &cp, &tok, "/")) { + TALLOC_FREE(frame); + return false; + } + + if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { + atype = SEC_ACE_TYPE_ACCESS_ALLOWED; + } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { + atype = SEC_ACE_TYPE_ACCESS_DENIED; + } else { + TALLOC_FREE(frame); + return false; + } + + /* Only numeric form accepted for flags at present */ + + if (!(next_token_talloc(frame, &cp, &tok, "/") && + sscanf(tok, "%i", &aflags))) { + TALLOC_FREE(frame); + return false; + } + + if (!next_token_talloc(frame, &cp, &tok, "/")) { + TALLOC_FREE(frame); + return false; + } + + if (strncmp(tok, "0x", 2) == 0) { + if (sscanf(tok, "%i", &amask) != 1) { + TALLOC_FREE(frame); + return false; + } + goto done; + } + + for (v = standard_values; v->perm; v++) { + if (strcmp(tok, v->perm) == 0) { + amask = v->mask; + goto done; + } + } + + p = tok; + + while(*p) { + bool found = False; + + for (v = special_values; v->perm; v++) { + if (v->perm[0] == *p) { + amask |= v->mask; + found = True; + } + } + + if (!found) { + TALLOC_FREE(frame); + return false; + } + p++; + } + + if (*p) { + TALLOC_FREE(frame); + return false; + } + +done: + mask = amask; + init_sec_ace(ace, &sid, atype, mask, aflags); + TALLOC_FREE(frame); + return true; +} + +/* add an ACE to a list of ACEs in a SEC_ACL */ +static bool +add_ace(SEC_ACL **the_acl, + SEC_ACE *ace, + TALLOC_CTX *ctx) +{ + SEC_ACL *newacl; + SEC_ACE *aces; + + if (! *the_acl) { + (*the_acl) = make_sec_acl(ctx, 3, 1, ace); + return True; + } + + if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, + 1+(*the_acl)->num_aces)) == NULL) { + return False; + } + memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE)); + memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); + newacl = make_sec_acl(ctx, (*the_acl)->revision, + 1+(*the_acl)->num_aces, aces); + SAFE_FREE(aces); + (*the_acl) = newacl; + return True; +} + + +/* parse a ascii version of a security descriptor */ +static SEC_DESC * +sec_desc_parse(TALLOC_CTX *ctx, + struct cli_state *ipc_cli, + POLICY_HND *pol, + bool numeric, + char *str) +{ + const char *p = str; + char *tok; + SEC_DESC *ret = NULL; + size_t sd_size; + DOM_SID *group_sid=NULL; + DOM_SID *owner_sid=NULL; + SEC_ACL *dacl=NULL; + int revision=1; + + while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { + + if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { + revision = strtol(tok+9, NULL, 16); + continue; + } + + if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { + if (owner_sid) { + DEBUG(5,("OWNER specified more than once!\n")); + goto done; + } + owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!owner_sid || + !convert_string_to_sid(ipc_cli, pol, + numeric, + owner_sid, tok+6)) { + DEBUG(5, ("Failed to parse owner sid\n")); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { + if (owner_sid) { + DEBUG(5,("OWNER specified more than once!\n")); + goto done; + } + owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!owner_sid || + !convert_string_to_sid(ipc_cli, pol, + False, + owner_sid, tok+7)) { + DEBUG(5, ("Failed to parse owner sid\n")); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { + if (group_sid) { + DEBUG(5,("GROUP specified more than once!\n")); + goto done; + } + group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!group_sid || + !convert_string_to_sid(ipc_cli, pol, + numeric, + group_sid, tok+6)) { + DEBUG(5, ("Failed to parse group sid\n")); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { + if (group_sid) { + DEBUG(5,("GROUP specified more than once!\n")); + goto done; + } + group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!group_sid || + !convert_string_to_sid(ipc_cli, pol, + False, + group_sid, tok+6)) { + DEBUG(5, ("Failed to parse group sid\n")); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"ACL:", 4) == 0) { + SEC_ACE ace; + if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { + DEBUG(5, ("Failed to parse ACL %s\n", tok)); + goto done; + } + if(!add_ace(&dacl, &ace, ctx)) { + DEBUG(5, ("Failed to add ACL %s\n", tok)); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { + SEC_ACE ace; + if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { + DEBUG(5, ("Failed to parse ACL %s\n", tok)); + goto done; + } + if(!add_ace(&dacl, &ace, ctx)) { + DEBUG(5, ("Failed to add ACL %s\n", tok)); + goto done; + } + continue; + } + + DEBUG(5, ("Failed to parse security descriptor\n")); + goto done; + } + + ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, + owner_sid, group_sid, NULL, dacl, &sd_size); + +done: + SAFE_FREE(group_sid); + SAFE_FREE(owner_sid); + + return ret; +} + + +/* Obtain the current dos attributes */ +static DOS_ATTR_DESC * +dos_attr_query(SMBCCTX *context, + TALLOC_CTX *ctx, + const char *filename, + SMBCSRV *srv) +{ + struct timespec create_time_ts; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; + SMB_OFF_T size = 0; + uint16 mode = 0; + SMB_INO_T inode = 0; + DOS_ATTR_DESC *ret; + + ret = TALLOC_P(ctx, DOS_ATTR_DESC); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + /* Obtain the DOS attributes */ + if (!SMBC_getatr(context, srv, CONST_DISCARD(char *, filename), + &mode, &size, + &create_time_ts, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &inode)) { + errno = SMBC_errno(context, srv->cli); + DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); + return NULL; + } + + ret->mode = mode; + ret->size = size; + ret->create_time = convert_timespec_to_time_t(create_time_ts); + ret->access_time = convert_timespec_to_time_t(access_time_ts); + ret->write_time = convert_timespec_to_time_t(write_time_ts); + ret->change_time = convert_timespec_to_time_t(change_time_ts); + ret->inode = inode; + + return ret; +} + + +/* parse a ascii version of a security descriptor */ +static void +dos_attr_parse(SMBCCTX *context, + DOS_ATTR_DESC *dad, + SMBCSRV *srv, + char *str) +{ + int n; + const char *p = str; + char *tok = NULL; + TALLOC_CTX *frame = NULL; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + + /* Determine whether to use old-style or new-style attribute names */ + if (context->internal->full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "CREATE_TIME"; + attr_strings.access_time_attr = "ACCESS_TIME"; + attr_strings.write_time_attr = "WRITE_TIME"; + attr_strings.change_time_attr = "CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "A_TIME"; + attr_strings.write_time_attr = "M_TIME"; + attr_strings.change_time_attr = "C_TIME"; + } + + /* if this is to set the entire ACL... */ + if (*str == '*') { + /* ... then increment past the first colon if there is one */ + if ((p = strchr(str, ':')) != NULL) { + ++p; + } else { + p = str; + } + } + + frame = talloc_stackframe(); + while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { + if (StrnCaseCmp(tok, "MODE:", 5) == 0) { + long request = strtol(tok+5, NULL, 16); + if (request == 0) { + dad->mode = (request | + (IS_DOS_DIR(dad->mode) + ? FILE_ATTRIBUTE_DIRECTORY + : FILE_ATTRIBUTE_NORMAL)); + } else { + dad->mode = request; + } + continue; + } + + if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { + dad->size = (SMB_OFF_T)atof(tok+5); + continue; + } + + n = strlen(attr_strings.access_time_attr); + if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { + dad->access_time = (time_t)strtol(tok+n+1, NULL, 10); + continue; + } + + n = strlen(attr_strings.change_time_attr); + if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { + dad->change_time = (time_t)strtol(tok+n+1, NULL, 10); + continue; + } + + n = strlen(attr_strings.write_time_attr); + if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { + dad->write_time = (time_t)strtol(tok+n+1, NULL, 10); + continue; + } + + if (attr_strings.create_time_attr != NULL) { + n = strlen(attr_strings.create_time_attr); + if (StrnCaseCmp(tok, attr_strings.create_time_attr, + n) == 0) { + dad->create_time = (time_t)strtol(tok+n+1, + NULL, 10); + continue; + } + } + + if (StrnCaseCmp(tok, "INODE:", 6) == 0) { + dad->inode = (SMB_INO_T)atof(tok+6); + continue; + } + } + TALLOC_FREE(frame); +} + +/***************************************************** + Retrieve the acls for a file. +*******************************************************/ + +static int +cacl_get(SMBCCTX *context, + TALLOC_CTX *ctx, + SMBCSRV *srv, + struct cli_state *ipc_cli, + POLICY_HND *pol, + char *filename, + char *attr_name, + char *buf, + int bufsize) +{ + uint32 i; + int n = 0; + int n_used; + bool all; + bool all_nt; + bool all_nt_acls; + bool all_dos; + bool some_nt; + bool some_dos; + bool exclude_nt_revision = False; + bool exclude_nt_owner = False; + bool exclude_nt_group = False; + bool exclude_nt_acl = False; + bool exclude_dos_mode = False; + bool exclude_dos_size = False; + bool exclude_dos_create_time = False; + bool exclude_dos_access_time = False; + bool exclude_dos_write_time = False; + bool exclude_dos_change_time = False; + bool exclude_dos_inode = False; + bool numeric = True; + bool determine_size = (bufsize == 0); + int fnum = -1; + SEC_DESC *sd; + fstring sidstr; + fstring name_sandbox; + char *name; + char *pExclude; + char *p; + struct timespec create_time_ts; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; + time_t create_time = (time_t)0; + time_t write_time = (time_t)0; + time_t access_time = (time_t)0; + time_t change_time = (time_t)0; + SMB_OFF_T size = 0; + uint16 mode = 0; + SMB_INO_T ino = 0; + struct cli_state *cli = srv->cli; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } excl_attr_strings; + + /* Determine whether to use old-style or new-style attribute names */ + if (context->internal->full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "CREATE_TIME"; + attr_strings.access_time_attr = "ACCESS_TIME"; + attr_strings.write_time_attr = "WRITE_TIME"; + attr_strings.change_time_attr = "CHANGE_TIME"; + + excl_attr_strings.create_time_attr = "CREATE_TIME"; + excl_attr_strings.access_time_attr = "ACCESS_TIME"; + excl_attr_strings.write_time_attr = "WRITE_TIME"; + excl_attr_strings.change_time_attr = "CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "A_TIME"; + attr_strings.write_time_attr = "M_TIME"; + attr_strings.change_time_attr = "C_TIME"; + + excl_attr_strings.create_time_attr = NULL; + excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; + excl_attr_strings.write_time_attr = "dos_attr.M_TIME"; + excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; + } + + /* Copy name so we can strip off exclusions (if any are specified) */ + strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); + + /* Ensure name is null terminated */ + name_sandbox[sizeof(name_sandbox) - 1] = '\0'; + + /* Play in the sandbox */ + name = name_sandbox; + + /* If there are any exclusions, point to them and mask them from name */ + if ((pExclude = strchr(name, '!')) != NULL) + { + *pExclude++ = '\0'; + } + + all = (StrnCaseCmp(name, "system.*", 8) == 0); + all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); + all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0); + all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0); + some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); + some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); + numeric = (* (name + strlen(name) - 1) != '+'); + + /* Look for exclusions from "all" requests */ + if (all || all_nt || all_dos) { + + /* Exclusions are delimited by '!' */ + for (; + pExclude != NULL; + pExclude = (p == NULL ? NULL : p + 1)) { + + /* Find end of this exclusion name */ + if ((p = strchr(pExclude, '!')) != NULL) + { + *p = '\0'; + } + + /* Which exclusion name is this? */ + if (StrCaseCmp(pExclude, + "nt_sec_desc.revision") == 0) { + exclude_nt_revision = True; + } + else if (StrCaseCmp(pExclude, + "nt_sec_desc.owner") == 0) { + exclude_nt_owner = True; + } + else if (StrCaseCmp(pExclude, + "nt_sec_desc.group") == 0) { + exclude_nt_group = True; + } + else if (StrCaseCmp(pExclude, + "nt_sec_desc.acl") == 0) { + exclude_nt_acl = True; + } + else if (StrCaseCmp(pExclude, + "dos_attr.mode") == 0) { + exclude_dos_mode = True; + } + else if (StrCaseCmp(pExclude, + "dos_attr.size") == 0) { + exclude_dos_size = True; + } + else if (excl_attr_strings.create_time_attr != NULL && + StrCaseCmp(pExclude, + excl_attr_strings.change_time_attr) == 0) { + exclude_dos_create_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.access_time_attr) == 0) { + exclude_dos_access_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.write_time_attr) == 0) { + exclude_dos_write_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.change_time_attr) == 0) { + exclude_dos_change_time = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { + exclude_dos_inode = True; + } + else { + DEBUG(5, ("cacl_get received unknown exclusion: %s\n", + pExclude)); + errno = ENOATTR; + return -1; + } + } + } + + n_used = 0; + + /* + * If we are (possibly) talking to an NT or new system and some NT + * attributes have been requested... + */ + if (ipc_cli && (all || some_nt || all_nt_acls)) { + /* Point to the portion after "system.nt_sec_desc." */ + name += 19; /* if (all) this will be invalid but unused */ + + /* ... then obtain any NT attributes which were requested */ + fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); + + if (fnum == -1) { + DEBUG(5, ("cacl_get failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; + } + + sd = cli_query_secdesc(cli, fnum, ctx); + + if (!sd) { + DEBUG(5, + ("cacl_get Failed to query old descriptor\n")); + errno = 0; + return -1; + } + + cli_close(cli, fnum); + + if (! exclude_nt_revision) { + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, + "REVISION:%d", + sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "REVISION:%d", + sd->revision); + } + } else if (StrCaseCmp(name, "revision") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%d", + sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%d", + sd->revision); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_nt_owner) { + /* Get owner and group sid */ + if (sd->owner_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, + numeric, + sd->owner_sid); + } else { + fstrcpy(sidstr, ""); + } + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, ",OWNER:%s", + sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else if (sidstr[0] != '\0') { + n = snprintf(buf, bufsize, + ",OWNER:%s", sidstr); + } + } else if (StrnCaseCmp(name, "owner", 5) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%s", + sidstr); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_nt_group) { + if (sd->group_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, + sd->group_sid); + } else { + fstrcpy(sidstr, ""); + } + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, ",GROUP:%s", + sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else if (sidstr[0] != '\0') { + n = snprintf(buf, bufsize, + ",GROUP:%s", sidstr); + } + } else if (StrnCaseCmp(name, "group", 5) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%s", sidstr); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_nt_acl) { + /* Add aces to value buffer */ + for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { + + SEC_ACE *ace = &sd->dacl->aces[i]; + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, + &ace->trustee); + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf( + ctx, + ",ACL:" + "%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->access_mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf( + buf, bufsize, + ",ACL:%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->access_mask); + } + } else if ((StrnCaseCmp(name, "acl", 3) == 0 && + StrCaseCmp(name+3, sidstr) == 0) || + (StrnCaseCmp(name, "acl+", 4) == 0 && + StrCaseCmp(name+4, sidstr) == 0)) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%d/%d/0x%08x", + ace->type, + ace->flags, + ace->access_mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%d/%d/0x%08x", + ace->type, + ace->flags, + ace->access_mask); + } + } else if (all_nt_acls) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%s%s:%d/%d/0x%08x", + i ? "," : "", + sidstr, + ace->type, + ace->flags, + ace->access_mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%s%s:%d/%d/0x%08x", + i ? "," : "", + sidstr, + ace->type, + ace->flags, + ace->access_mask); + } + } + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + } + + /* Restore name pointer to its original value */ + name -= 19; + } + + if (all || some_dos) { + /* Point to the portion after "system.dos_attr." */ + name += 16; /* if (all) this will be invalid but unused */ + + /* Obtain the DOS attributes */ + if (!SMBC_getatr(context, srv, filename, &mode, &size, + &create_time_ts, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { + + errno = SMBC_errno(context, srv->cli); + return -1; + + } + + create_time = convert_timespec_to_time_t(create_time_ts); + access_time = convert_timespec_to_time_t(access_time_ts); + write_time = convert_timespec_to_time_t(write_time_ts); + change_time = convert_timespec_to_time_t(change_time_ts); + + if (! exclude_dos_mode) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + "%sMODE:0x%x", + (ipc_cli && + (all || some_nt) + ? "," + : ""), + mode); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%sMODE:0x%x", + (ipc_cli && + (all || some_nt) + ? "," + : ""), + mode); + } + } else if (StrCaseCmp(name, "mode") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "0x%x", mode); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "0x%x", mode); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_size) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf( + ctx, + ",SIZE:%.0f", + (double)size); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",SIZE:%.0f", + (double)size); + } + } else if (StrCaseCmp(name, "size") == 0) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%.0f", + (double)size); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%.0f", + (double)size); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_create_time && + attr_strings.create_time_attr != NULL) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",%s:%lu", + attr_strings.create_time_attr, + create_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",%s:%lu", + attr_strings.create_time_attr, + create_time); + } + } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", create_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%lu", create_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_access_time) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",%s:%lu", + attr_strings.access_time_attr, + access_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",%s:%lu", + attr_strings.access_time_attr, + access_time); + } + } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", access_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%lu", access_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_write_time) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",%s:%lu", + attr_strings.write_time_attr, + write_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",%s:%lu", + attr_strings.write_time_attr, + write_time); + } + } else if (StrCaseCmp(name, attr_strings.write_time_attr) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", write_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%lu", write_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_change_time) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",%s:%lu", + attr_strings.change_time_attr, + change_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",%s:%lu", + attr_strings.change_time_attr, + change_time); + } + } else if (StrCaseCmp(name, attr_strings.change_time_attr) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", change_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%lu", change_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_inode) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf( + ctx, + ",INODE:%.0f", + (double)ino); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",INODE:%.0f", + (double) ino); + } + } else if (StrCaseCmp(name, "inode") == 0) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%.0f", + (double) ino); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%.0f", + (double) ino); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + /* Restore name pointer to its original value */ + name -= 16; + } + + if (n_used == 0) { + errno = ENOATTR; + return -1; + } + + return n_used; +} + +/***************************************************** +set the ACLs on a file given an ascii description +*******************************************************/ +static int +cacl_set(TALLOC_CTX *ctx, + struct cli_state *cli, + struct cli_state *ipc_cli, + POLICY_HND *pol, + const char *filename, + const char *the_acl, + int mode, + int flags) +{ + int fnum; + int err = 0; + SEC_DESC *sd = NULL, *old; + SEC_ACL *dacl = NULL; + DOM_SID *owner_sid = NULL; + DOM_SID *group_sid = NULL; + uint32 i, j; + size_t sd_size; + int ret = 0; + char *p; + bool numeric = True; + + /* the_acl will be null for REMOVE_ALL operations */ + if (the_acl) { + numeric = ((p = strchr(the_acl, ':')) != NULL && + p > the_acl && + p[-1] != '+'); + + /* if this is to set the entire ACL... */ + if (*the_acl == '*') { + /* ... then increment past the first colon */ + the_acl = p + 1; + } + + sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, + CONST_DISCARD(char *, the_acl)); + + if (!sd) { + errno = EINVAL; + return -1; + } + } + + /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller + that doesn't deref sd */ + + if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { + errno = EINVAL; + return -1; + } + + /* The desired access below is the only one I could find that works + with NT4, W2KP and Samba */ + + fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); + + if (fnum == -1) { + DEBUG(5, ("cacl_set failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; + } + + old = cli_query_secdesc(cli, fnum, ctx); + + if (!old) { + DEBUG(5, ("cacl_set Failed to query old descriptor\n")); + errno = 0; + return -1; + } + + cli_close(cli, fnum); + + switch (mode) { + case SMBC_XATTR_MODE_REMOVE_ALL: + old->dacl->num_aces = 0; + dacl = old->dacl; + break; + + case SMBC_XATTR_MODE_REMOVE: + for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { + bool found = False; + + for (j=0;old->dacl && j<old->dacl->num_aces;j++) { + if (sec_ace_equal(&sd->dacl->aces[i], + &old->dacl->aces[j])) { + uint32 k; + for (k=j; k<old->dacl->num_aces-1;k++) { + old->dacl->aces[k] = + old->dacl->aces[k+1]; + } + old->dacl->num_aces--; + found = True; + dacl = old->dacl; + break; + } + } + + if (!found) { + err = ENOATTR; + ret = -1; + goto failed; + } + } + break; + + case SMBC_XATTR_MODE_ADD: + for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { + bool found = False; + + for (j=0;old->dacl && j<old->dacl->num_aces;j++) { + if (sid_equal(&sd->dacl->aces[i].trustee, + &old->dacl->aces[j].trustee)) { + if (!(flags & SMBC_XATTR_FLAG_CREATE)) { + err = EEXIST; + ret = -1; + goto failed; + } + old->dacl->aces[j] = sd->dacl->aces[i]; + ret = -1; + found = True; + } + } + + if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { + err = ENOATTR; + ret = -1; + goto failed; + } + + for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { + add_ace(&old->dacl, &sd->dacl->aces[i], ctx); + } + } + dacl = old->dacl; + break; + + case SMBC_XATTR_MODE_SET: + old = sd; + owner_sid = old->owner_sid; + group_sid = old->group_sid; + dacl = old->dacl; + break; + + case SMBC_XATTR_MODE_CHOWN: + owner_sid = sd->owner_sid; + break; + + case SMBC_XATTR_MODE_CHGRP: + group_sid = sd->group_sid; + break; + } + + /* Denied ACE entries must come before allowed ones */ + sort_acl(old->dacl); + + /* Create new security descriptor and set it */ + sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, + owner_sid, group_sid, NULL, dacl, &sd_size); + + fnum = cli_nt_create(cli, filename, + WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS); + + if (fnum == -1) { + DEBUG(5, ("cacl_set failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; + } + + if (!cli_set_secdesc(cli, fnum, sd)) { + DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli))); + ret = -1; + } + + /* Clean up */ + +failed: + cli_close(cli, fnum); + + if (err != 0) { + errno = err; + } + + return ret; +} + + +int +SMBC_setxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size, + int flags) +{ + int ret; + int ret2; + SMBCSRV *srv = NULL; + SMBCSRV *ipc_srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + DOS_ATTR_DESC *dad = NULL; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", + fname, name, (int) size, (const char*)value)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (! srv->no_nt_session) { + ipc_srv = SMBC_attr_server(frame, context, server, share, + &workgroup, &user, &password); + if (! ipc_srv) { + srv->no_nt_session = True; + } + } else { + ipc_srv = NULL; + } + + /* + * Are they asking to set the entire set of known attributes? + */ + if (StrCaseCmp(name, "system.*") == 0 || + StrCaseCmp(name, "system.*+") == 0) { + /* Yup. */ + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+7, (const char *) value); + if (! namevalue) { + errno = ENOMEM; + ret = -1; + TALLOC_FREE(frame); + return -1; + } + + if (ipc_srv) { + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + namevalue, + (*namevalue == '*' + ? SMBC_XATTR_MODE_SET + : SMBC_XATTR_MODE_ADD), + flags); + } else { + ret = 0; + } + + /* get a DOS Attribute Descriptor with current attributes */ + dad = dos_attr_query(context, talloc_tos(), path, srv); + if (dad) { + /* Overwrite old with new, using what was provided */ + dos_attr_parse(context, dad, srv, namevalue); + + /* Set the new DOS attributes */ + if (! SMBC_setatr(context, srv, path, + dad->create_time, + dad->access_time, + dad->write_time, + dad->change_time, + dad->mode)) { + + /* cause failure if NT failed too */ + dad = NULL; + } + } + + /* we only fail if both NT and DOS sets failed */ + if (ret < 0 && ! dad) { + ret = -1; /* in case dad was null */ + } + else { + ret = 0; + } + + TALLOC_FREE(frame); + return ret; + } + + /* + * Are they asking to set an access control element or to set + * the entire access control list? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + + /* Yup. */ + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+19, (const char *) value); + + if (! ipc_srv) { + ret = -1; /* errno set by SMBC_server() */ + } + else if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + namevalue, + (*namevalue == '*' + ? SMBC_XATTR_MODE_SET + : SMBC_XATTR_MODE_ADD), + flags); + } + TALLOC_FREE(frame); + return ret; + } + + /* + * Are they asking to set the owner? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { + + /* Yup. */ + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+19, (const char *) value); + + if (! ipc_srv) { + ret = -1; /* errno set by SMBC_server() */ + } + else if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + namevalue, SMBC_XATTR_MODE_CHOWN, 0); + } + TALLOC_FREE(frame); + return ret; + } + + /* + * Are they asking to set the group? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { + + /* Yup. */ + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+19, (const char *) value); + + if (! ipc_srv) { + /* errno set by SMBC_server() */ + ret = -1; + } + else if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + namevalue, SMBC_XATTR_MODE_CHGRP, 0); + } + TALLOC_FREE(frame); + return ret; + } + + /* Determine whether to use old-style or new-style attribute names */ + if (context->internal->full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; + attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; + attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; + attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "system.dos_attr.A_TIME"; + attr_strings.write_time_attr = "system.dos_attr.M_TIME"; + attr_strings.change_time_attr = "system.dos_attr.C_TIME"; + } + + /* + * Are they asking to set a DOS attribute? + */ + if (StrCaseCmp(name, "system.dos_attr.*") == 0 || + StrCaseCmp(name, "system.dos_attr.mode") == 0 || + (attr_strings.create_time_attr != NULL && + StrCaseCmp(name, attr_strings.create_time_attr) == 0) || + StrCaseCmp(name, attr_strings.access_time_attr) == 0 || + StrCaseCmp(name, attr_strings.write_time_attr) == 0 || + StrCaseCmp(name, attr_strings.change_time_attr) == 0) { + + /* get a DOS Attribute Descriptor with current attributes */ + dad = dos_attr_query(context, talloc_tos(), path, srv); + if (dad) { + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+16, (const char *) value); + if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + /* Overwrite old with provided new params */ + dos_attr_parse(context, dad, srv, namevalue); + + /* Set the new DOS attributes */ + ret2 = SMBC_setatr(context, srv, path, + dad->create_time, + dad->access_time, + dad->write_time, + dad->change_time, + dad->mode); + + /* ret2 has True (success) / False (failure) */ + if (ret2) { + ret = 0; + } else { + ret = -1; + } + } + } else { + ret = -1; + } + + TALLOC_FREE(frame); + return ret; + } + + /* Unsupported attribute name */ + errno = EINVAL; + TALLOC_FREE(frame); + return -1; +} + +int +SMBC_getxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size) +{ + int ret; + SMBCSRV *srv = NULL; + SMBCSRV *ipc_srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (! srv->no_nt_session) { + ipc_srv = SMBC_attr_server(frame, context, server, share, + &workgroup, &user, &password); + if (! ipc_srv) { + srv->no_nt_session = True; + } + } else { + ipc_srv = NULL; + } + + /* Determine whether to use old-style or new-style attribute names */ + if (context->internal->full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; + attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; + attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; + attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "system.dos_attr.A_TIME"; + attr_strings.write_time_attr = "system.dos_attr.M_TIME"; + attr_strings.change_time_attr = "system.dos_attr.C_TIME"; + } + + /* Are they requesting a supported attribute? */ + if (StrCaseCmp(name, "system.*") == 0 || + StrnCaseCmp(name, "system.*!", 9) == 0 || + StrCaseCmp(name, "system.*+") == 0 || + StrnCaseCmp(name, "system.*+!", 10) == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 || + StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 || + StrCaseCmp(name, "system.dos_attr.*") == 0 || + StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 || + StrCaseCmp(name, "system.dos_attr.mode") == 0 || + StrCaseCmp(name, "system.dos_attr.size") == 0 || + (attr_strings.create_time_attr != NULL && + StrCaseCmp(name, attr_strings.create_time_attr) == 0) || + StrCaseCmp(name, attr_strings.access_time_attr) == 0 || + StrCaseCmp(name, attr_strings.write_time_attr) == 0 || + StrCaseCmp(name, attr_strings.change_time_attr) == 0 || + StrCaseCmp(name, "system.dos_attr.inode") == 0) { + + /* Yup. */ + ret = cacl_get(context, talloc_tos(), srv, + ipc_srv == NULL ? NULL : ipc_srv->cli, + &ipc_srv->pol, path, + CONST_DISCARD(char *, name), + CONST_DISCARD(char *, value), size); + if (ret < 0 && errno == 0) { + errno = SMBC_errno(context, srv->cli); + } + TALLOC_FREE(frame); + return ret; + } + + /* Unsupported attribute name */ + errno = EINVAL; + TALLOC_FREE(frame); + return -1; +} + + +int +SMBC_removexattr_ctx(SMBCCTX *context, + const char *fname, + const char *name) +{ + int ret; + SMBCSRV *srv = NULL; + SMBCSRV *ipc_srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, smbc_getUser(context)); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (! srv->no_nt_session) { + ipc_srv = SMBC_attr_server(frame, context, server, share, + &workgroup, &user, &password); + if (! ipc_srv) { + srv->no_nt_session = True; + } + } else { + ipc_srv = NULL; + } + + if (! ipc_srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_attr_server */ + } + + /* Are they asking to set the entire ACL? */ + if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { + + /* Yup. */ + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); + TALLOC_FREE(frame); + return ret; + } + + /* + * Are they asking to remove one or more spceific security descriptor + * attributes? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + + /* Yup. */ + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + name + 19, SMBC_XATTR_MODE_REMOVE, 0); + TALLOC_FREE(frame); + return ret; + } + + /* Unsupported attribute name */ + errno = EINVAL; + TALLOC_FREE(frame); + return -1; +} + +int +SMBC_listxattr_ctx(SMBCCTX *context, + const char *fname, + char *list, + size_t size) +{ + /* + * This isn't quite what listxattr() is supposed to do. This returns + * the complete set of attribute names, always, rather than only those + * attribute names which actually exist for a file. Hmmm... + */ + size_t retsize; + const char supported_old[] = + "system.*\0" + "system.*+\0" + "system.nt_sec_desc.revision\0" + "system.nt_sec_desc.owner\0" + "system.nt_sec_desc.owner+\0" + "system.nt_sec_desc.group\0" + "system.nt_sec_desc.group+\0" + "system.nt_sec_desc.acl.*\0" + "system.nt_sec_desc.acl\0" + "system.nt_sec_desc.acl+\0" + "system.nt_sec_desc.*\0" + "system.nt_sec_desc.*+\0" + "system.dos_attr.*\0" + "system.dos_attr.mode\0" + "system.dos_attr.c_time\0" + "system.dos_attr.a_time\0" + "system.dos_attr.m_time\0" + ; + const char supported_new[] = + "system.*\0" + "system.*+\0" + "system.nt_sec_desc.revision\0" + "system.nt_sec_desc.owner\0" + "system.nt_sec_desc.owner+\0" + "system.nt_sec_desc.group\0" + "system.nt_sec_desc.group+\0" + "system.nt_sec_desc.acl.*\0" + "system.nt_sec_desc.acl\0" + "system.nt_sec_desc.acl+\0" + "system.nt_sec_desc.*\0" + "system.nt_sec_desc.*+\0" + "system.dos_attr.*\0" + "system.dos_attr.mode\0" + "system.dos_attr.create_time\0" + "system.dos_attr.access_time\0" + "system.dos_attr.write_time\0" + "system.dos_attr.change_time\0" + ; + const char * supported; + + if (context->internal->full_time_names) { + supported = supported_new; + retsize = sizeof(supported_new); + } else { + supported = supported_old; + retsize = sizeof(supported_old); + } + + if (size == 0) { + return retsize; + } + + if (retsize > size) { + errno = ERANGE; + return -1; + } + + /* this can't be strcpy() because there are embedded null characters */ + memcpy(list, supported, retsize); + return retsize; +} diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c deleted file mode 100644 index e84de59637..0000000000 --- a/source3/libsmb/libsmbclient.c +++ /dev/null @@ -1,7158 +0,0 @@ -/* - Unix SMB/Netbios implementation. - SMB client library implementation - Copyright (C) Andrew Tridgell 1998 - Copyright (C) Richard Sharpe 2000, 2002 - Copyright (C) John Terpstra 2000 - Copyright (C) Tom Jansen (Ninja ISD) 2002 - Copyright (C) Derrell Lipman 2003, 2004 - Copyright (C) Jeremy Allison 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 - 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 "include/libsmb_internal.h" - -struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir); -struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, - struct smbc_dirent *dirent); - -/* - * DOS Attribute values (used internally) - */ -typedef struct DOS_ATTR_DESC { - int mode; - SMB_OFF_T size; - time_t create_time; - time_t access_time; - time_t write_time; - time_t change_time; - SMB_INO_T inode; -} DOS_ATTR_DESC; - - -/* - * Internal flags for extended attributes - */ - -/* internal mode values */ -#define SMBC_XATTR_MODE_ADD 1 -#define SMBC_XATTR_MODE_REMOVE 2 -#define SMBC_XATTR_MODE_REMOVE_ALL 3 -#define SMBC_XATTR_MODE_SET 4 -#define SMBC_XATTR_MODE_CHOWN 5 -#define SMBC_XATTR_MODE_CHGRP 6 - -#define CREATE_ACCESS_READ READ_CONTROL_ACCESS - -/*We should test for this in configure ... */ -#ifndef ENOTSUP -#define ENOTSUP EOPNOTSUPP -#endif - -/* - * Functions exported by libsmb_cache.c that we need here - */ -int smbc_default_cache_functions(SMBCCTX *context); - -/* - * check if an element is part of the list. - * FIXME: Does not belong here ! - * Can anyone put this in a macro in dlinklist.h ? - * -- Tom - */ -static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { - if (!p || !list) return False; - do { - if (p == list) return True; - list = list->next; - } while (list); - return False; -} - -/* - * Find an lsa pipe handle associated with a cli struct. - */ -static struct rpc_pipe_client * -find_lsa_pipe_hnd(struct cli_state *ipc_cli) -{ - struct rpc_pipe_client *pipe_hnd; - - for (pipe_hnd = ipc_cli->pipe_list; - pipe_hnd; - pipe_hnd = pipe_hnd->next) { - - if (pipe_hnd->pipe_idx == PI_LSARPC) { - return pipe_hnd; - } - } - - return NULL; -} - -static int -smbc_close_ctx(SMBCCTX *context, - SMBCFILE *file); -static off_t -smbc_lseek_ctx(SMBCCTX *context, - SMBCFILE *file, - off_t offset, - int whence); - -extern bool in_client; - -/* - * Is the logging working / configfile read ? - */ -static int smbc_initialized = 0; - -static int -hex2int( unsigned int _char ) -{ - if ( _char >= 'A' && _char <='F') - return _char - 'A' + 10; - if ( _char >= 'a' && _char <='f') - return _char - 'a' + 10; - if ( _char >= '0' && _char <='9') - return _char - '0'; - return -1; -} - -/* - * smbc_urldecode() - * and smbc_urldecode_talloc() (internal fn.) - * - * Convert strings of %xx to their single character equivalent. Each 'x' must - * be a valid hexadecimal digit, or that % sequence is left undecoded. - * - * dest may, but need not be, the same pointer as src. - * - * Returns the number of % sequences which could not be converted due to lack - * of two following hexadecimal digits. - */ -static int -smbc_urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) -{ - int old_length = strlen(src); - int i = 0; - int err_count = 0; - size_t newlen = 1; - char *p, *dest; - - if (old_length == 0) { - return 0; - } - - *pp_dest = NULL; - for (i = 0; i < old_length; ) { - unsigned char character = src[i++]; - - if (character == '%') { - int a = i+1 < old_length ? hex2int(src[i]) : -1; - int b = i+1 < old_length ? hex2int(src[i+1]) : -1; - - /* Replace valid sequence */ - if (a != -1 && b != -1) { - /* Replace valid %xx sequence with %dd */ - character = (a * 16) + b; - if (character == '\0') { - break; /* Stop at %00 */ - } - i += 2; - } else { - err_count++; - } - } - newlen++; - } - - dest = TALLOC_ARRAY(ctx, char, newlen); - if (!dest) { - return err_count; - } - - err_count = 0; - for (p = dest, i = 0; i < old_length; ) { - unsigned char character = src[i++]; - - if (character == '%') { - int a = i+1 < old_length ? hex2int(src[i]) : -1; - int b = i+1 < old_length ? hex2int(src[i+1]) : -1; - - /* Replace valid sequence */ - if (a != -1 && b != -1) { - /* Replace valid %xx sequence with %dd */ - character = (a * 16) + b; - if (character == '\0') { - break; /* Stop at %00 */ - } - i += 2; - } else { - err_count++; - } - } - *p++ = character; - } - - *p = '\0'; - *pp_dest = dest; - return err_count; -} - -int -smbc_urldecode(char *dest, char *src, size_t max_dest_len) -{ - TALLOC_CTX *frame = talloc_stackframe(); - char *pdest; - int ret = smbc_urldecode_talloc(frame, &pdest, src); - - if (pdest) { - strlcpy(dest, pdest, max_dest_len); - } - TALLOC_FREE(frame); - return ret; -} - -/* - * smbc_urlencode() - * - * Convert any characters not specifically allowed in a URL into their %xx - * equivalent. - * - * Returns the remaining buffer length. - */ -int -smbc_urlencode(char *dest, char *src, int max_dest_len) -{ - char hex[] = "0123456789ABCDEF"; - - for (; *src != '\0' && max_dest_len >= 3; src++) { - - if ((*src < '0' && - *src != '-' && - *src != '.') || - (*src > '9' && - *src < 'A') || - (*src > 'Z' && - *src < 'a' && - *src != '_') || - (*src > 'z')) { - *dest++ = '%'; - *dest++ = hex[(*src >> 4) & 0x0f]; - *dest++ = hex[*src & 0x0f]; - max_dest_len -= 3; - } else { - *dest++ = *src; - max_dest_len--; - } - } - - *dest++ = '\0'; - max_dest_len--; - - return max_dest_len; -} - -/* - * Function to parse a path and turn it into components - * - * The general format of an SMB URI is explain in Christopher Hertel's CIFS - * book, at http://ubiqx.org/cifs/Appendix-D.html. We accept a subset of the - * general format ("smb:" only; we do not look for "cifs:"). - * - * - * We accept: - * smb://[[[domain;]user[:password]@]server[/share[/path[/file]]]][?options] - * - * Meaning of URLs: - * - * smb:// Show all workgroups. - * - * The method of locating the list of workgroups varies - * depending upon the setting of the context variable - * context->options.browse_max_lmb_count. This value - * determine the maximum number of local master browsers to - * query for the list of workgroups. In order to ensure that - * a complete list of workgroups is obtained, all master - * browsers must be queried, but if there are many - * workgroups, the time spent querying can begin to add up. - * For small networks (not many workgroups), it is suggested - * that this variable be set to 0, indicating query all local - * master browsers. When the network has many workgroups, a - * reasonable setting for this variable might be around 3. - * - * smb://name/ if name<1D> or name<1B> exists, list servers in - * workgroup, else, if name<20> exists, list all shares - * for server ... - * - * If "options" are provided, this function returns the entire option list as a - * string, for later parsing by the caller. Note that currently, no options - * are supported. - */ - -static const char *smbc_prefix = "smb:"; - -static int -smbc_parse_path(TALLOC_CTX *ctx, - SMBCCTX *context, - const char *fname, - char **pp_workgroup, - char **pp_server, - char **pp_share, - char **pp_path, - char **pp_user, - char **pp_password, - char **pp_options) -{ - char *s; - const char *p; - char *q, *r; - int len; - - /* Ensure these returns are at least valid pointers. */ - *pp_server = talloc_strdup(ctx, ""); - *pp_share = talloc_strdup(ctx, ""); - *pp_path = talloc_strdup(ctx, ""); - *pp_user = talloc_strdup(ctx, ""); - *pp_password = talloc_strdup(ctx, ""); - - if (!*pp_server || !*pp_share || !*pp_path || - !*pp_user || !*pp_password) { - return -1; - } - - /* - * Assume we wont find an authentication domain to parse, so default - * to the workgroup in the provided context. - */ - if (pp_workgroup != NULL) { - *pp_workgroup = talloc_strdup(ctx, context->workgroup); - } - - if (pp_options) { - *pp_options = talloc_strdup(ctx, ""); - } - s = talloc_strdup(ctx, fname); - - /* see if it has the right prefix */ - len = strlen(smbc_prefix); - if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { - return -1; /* What about no smb: ? */ - } - - p = s + len; - - /* Watch the test below, we are testing to see if we should exit */ - - if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { - DEBUG(1, ("Invalid path (does not begin with smb://")); - return -1; - } - - p += 2; /* Skip the double slash */ - - /* See if any options were specified */ - if ((q = strrchr(p, '?')) != NULL ) { - /* There are options. Null terminate here and point to them */ - *q++ = '\0'; - - DEBUG(4, ("Found options '%s'", q)); - - /* Copy the options */ - if (*pp_options != NULL) { - TALLOC_FREE(*pp_options); - *pp_options = talloc_strdup(ctx, q); - } - } - - if (*p == '\0') { - goto decoding; - } - - if (*p == '/') { - int wl = strlen(context->workgroup); - - if (wl > 16) { - wl = 16; - } - - *pp_server = talloc_strdup(ctx, context->workgroup); - if (!*pp_server) { - return -1; - } - *pp_server[wl] = '\0'; - return 0; - } - - /* - * ok, its for us. Now parse out the server, share etc. - * - * However, we want to parse out [[domain;]user[:password]@] if it - * exists ... - */ - - /* check that '@' occurs before '/', if '/' exists at all */ - q = strchr_m(p, '@'); - r = strchr_m(p, '/'); - if (q && (!r || q < r)) { - char *userinfo = NULL; - const char *u; - - next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@"); - if (!userinfo) { - return -1; - } - u = userinfo; - - if (strchr_m(u, ';')) { - char *workgroup; - next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";"); - if (!workgroup) { - return -1; - } - if (pp_workgroup) { - *pp_workgroup = workgroup; - } - } - - if (strchr_m(u, ':')) { - next_token_no_ltrim_talloc(ctx, &u, pp_user, ":"); - if (!*pp_user) { - return -1; - } - *pp_password = talloc_strdup(ctx, u); - if (!*pp_password) { - return -1; - } - } else { - *pp_user = talloc_strdup(ctx, u); - if (!*pp_user) { - return -1; - } - } - } - - if (!next_token_talloc(ctx, &p, pp_server, "/")) { - return -1; - } - - if (*p == (char)0) { - goto decoding; /* That's it ... */ - } - - if (!next_token_talloc(ctx, &p, pp_share, "/")) { - return -1; - } - - /* - * Prepend a leading slash if there's a file path, as required by - * NetApp filers. - */ - if (*p != '\0') { - *pp_path = talloc_asprintf(ctx, - "\\%s", - p); - } else { - *pp_path = talloc_strdup(ctx, ""); - } - if (!*pp_path) { - return -1; - } - string_replace(*pp_path, '/', '\\'); - - decoding: - - (void) smbc_urldecode_talloc(ctx, pp_path, *pp_path); - (void) smbc_urldecode_talloc(ctx, pp_server, *pp_server); - (void) smbc_urldecode_talloc(ctx, pp_share, *pp_share); - (void) smbc_urldecode_talloc(ctx, pp_user, *pp_user); - (void) smbc_urldecode_talloc(ctx, pp_password, *pp_password); - - return 0; -} - -/* - * Verify that the options specified in a URL are valid - */ -static int -smbc_check_options(char *server, - char *share, - char *path, - char *options) -{ - DEBUG(4, ("smbc_check_options(): server='%s' share='%s' " - "path='%s' options='%s'\n", - server, share, path, options)); - - /* No options at all is always ok */ - if (! *options) return 0; - - /* Currently, we don't support any options. */ - return -1; -} - -/* - * Convert an SMB error into a UNIX error ... - */ -static int -smbc_errno(SMBCCTX *context, - struct cli_state *c) -{ - int ret = cli_errno(c); - - if (cli_is_dos_error(c)) { - uint8 eclass; - uint32 ecode; - - cli_dos_error(c, &eclass, &ecode); - - DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", - (int)eclass, (int)ecode, (int)ecode, ret)); - } else { - NTSTATUS status; - - status = cli_nt_error(c); - - DEBUG(3,("smbc errno %s -> %d\n", - nt_errstr(status), ret)); - } - - return ret; -} - -/* - * Check a server for being alive and well. - * returns 0 if the server is in shape. Returns 1 on error - * - * Also useable outside libsmbclient to enable external cache - * to do some checks too. - */ -static int -smbc_check_server(SMBCCTX * context, - SMBCSRV * server) -{ - socklen_t size; - struct sockaddr addr; - - size = sizeof(addr); - return (getpeername(server->cli->fd, &addr, &size) == -1); -} - -/* - * Remove a server from the cached server list it's unused. - * On success, 0 is returned. 1 is returned if the server could not be removed. - * - * Also useable outside libsmbclient - */ -int -smbc_remove_unused_server(SMBCCTX * context, - SMBCSRV * srv) -{ - SMBCFILE * file; - - /* are we being fooled ? */ - if (!context || !context->internal || - !context->internal->_initialized || !srv) return 1; - - - /* Check all open files/directories for a relation with this server */ - for (file = context->internal->_files; file; file=file->next) { - if (file->srv == srv) { - /* Still used */ - DEBUG(3, ("smbc_remove_usused_server: " - "%p still used by %p.\n", - srv, file)); - return 1; - } - } - - DLIST_REMOVE(context->internal->_servers, srv); - - cli_shutdown(srv->cli); - srv->cli = NULL; - - DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); - - (context->callbacks.remove_cached_srv_fn)(context, srv); - - SAFE_FREE(srv); - return 0; -} - -/**************************************************************** - * Call the auth_fn with fixed size (fstring) buffers. - ***************************************************************/ - -static void call_auth_fn(TALLOC_CTX *ctx, - SMBCCTX *context, - const char *server, - const char *share, - char **pp_workgroup, - char **pp_username, - char **pp_password) -{ - fstring workgroup; - fstring username; - fstring password; - - strlcpy(workgroup, *pp_workgroup, sizeof(workgroup)); - strlcpy(username, *pp_username, sizeof(username)); - strlcpy(password, *pp_password, sizeof(password)); - - if (context->internal->_auth_fn_with_context != NULL) { - (context->internal->_auth_fn_with_context)( - context, - server, share, - workgroup, sizeof(workgroup), - username, sizeof(username), - password, sizeof(password)); - } else { - (context->callbacks.auth_fn)( - server, share, - workgroup, sizeof(workgroup), - username, sizeof(username), - password, sizeof(password)); - } - - TALLOC_FREE(*pp_workgroup); - TALLOC_FREE(*pp_username); - TALLOC_FREE(*pp_password); - - *pp_workgroup = talloc_strdup(ctx, workgroup); - *pp_username = talloc_strdup(ctx, username); - *pp_password = talloc_strdup(ctx, password); -} - -static SMBCSRV * -find_server(TALLOC_CTX *ctx, - SMBCCTX *context, - const char *server, - const char *share, - char **pp_workgroup, - char **pp_username, - char **pp_password) -{ - SMBCSRV *srv; - int auth_called = 0; - - check_server_cache: - - srv = (context->callbacks.get_cached_srv_fn)(context, server, share, - *pp_workgroup, *pp_username); - - if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] || - !*pp_password || !(*pp_password)[0])) { - call_auth_fn(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - - if (!pp_workgroup || !pp_username || !pp_password) { - return NULL; - } - - /* - * However, smbc_auth_fn may have picked up info relating to - * an existing connection, so try for an existing connection - * again ... - */ - auth_called = 1; - goto check_server_cache; - - } - - if (srv) { - if ((context->callbacks.check_server_fn)(context, srv)) { - /* - * This server is no good anymore - * Try to remove it and check for more possible - * servers in the cache - */ - if ((context->callbacks.remove_unused_server_fn)(context, - srv)) { - /* - * We could not remove the server completely, - * remove it from the cache so we will not get - * it again. It will be removed when the last - * file/dir is closed. - */ - (context->callbacks.remove_cached_srv_fn)(context, - srv); - } - - /* - * Maybe there are more cached connections to this - * server - */ - goto check_server_cache; - } - - return srv; - } - - return NULL; -} - -/* - * Connect to a server, possibly on an existing connection - * - * Here, what we want to do is: If the server and username - * match an existing connection, reuse that, otherwise, establish a - * new connection. - * - * If we have to create a new connection, call the auth_fn to get the - * info we need, unless the username and password were passed in. - */ - -static SMBCSRV * -smbc_server(TALLOC_CTX *ctx, - SMBCCTX *context, - bool connect_if_not_found, - const char *server, - const char *share, - char **pp_workgroup, - char **pp_username, - char **pp_password) -{ - SMBCSRV *srv=NULL; - struct cli_state *c; - struct nmb_name called, calling; - const char *server_n = server; - struct sockaddr_storage ss; - int tried_reverse = 0; - int port_try_first; - int port_try_next; - const char *username_used; - NTSTATUS status; - - zero_addr(&ss); - ZERO_STRUCT(c); - - if (server[0] == 0) { - errno = EPERM; - return NULL; - } - - /* Look for a cached connection */ - srv = find_server(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - - /* - * If we found a connection and we're only allowed one share per - * server... - */ - if (srv && *share != '\0' && context->options.one_share_per_server) { - - /* - * ... then if there's no current connection to the share, - * connect to it. find_server(), or rather the function - * pointed to by context->callbacks.get_cached_srv_fn which - * was called by find_server(), will have issued a tree - * disconnect if the requested share is not the same as the - * one that was already connected. - */ - if (srv->cli->cnum == (uint16) -1) { - /* Ensure we have accurate auth info */ - call_auth_fn(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - - if (!*pp_workgroup || !*pp_username || !*pp_password) { - errno = ENOMEM; - cli_shutdown(srv->cli); - srv->cli = NULL; - (context->callbacks.remove_cached_srv_fn)(context, - srv); - return NULL; - } - - /* - * We don't need to renegotiate encryption - * here as the encryption context is not per - * tid. - */ - - if (!cli_send_tconX(srv->cli, share, "?????", - *pp_password, - strlen(*pp_password)+1)) { - - errno = smbc_errno(context, srv->cli); - cli_shutdown(srv->cli); - srv->cli = NULL; - (context->callbacks.remove_cached_srv_fn)(context, - srv); - srv = NULL; - } - - /* - * Regenerate the dev value since it's based on both - * server and share - */ - if (srv) { - srv->dev = (dev_t)(str_checksum(server) ^ - str_checksum(share)); - } - } - } - - /* If we have a connection... */ - if (srv) { - - /* ... then we're done here. Give 'em what they came for. */ - return srv; - } - - /* If we're not asked to connect when a connection doesn't exist... */ - if (! connect_if_not_found) { - /* ... then we're done here. */ - return NULL; - } - - if (!*pp_workgroup || !*pp_username || !*pp_password) { - errno = ENOMEM; - return NULL; - } - - make_nmb_name(&calling, context->netbios_name, 0x0); - make_nmb_name(&called , server, 0x20); - - DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); - - DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); - - again: - - zero_addr(&ss); - - /* have to open a new connection */ - if ((c = cli_initialise()) == NULL) { - errno = ENOMEM; - return NULL; - } - - if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { - c->use_kerberos = True; - } - if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { - c->fallback_after_kerberos = True; - } - - c->timeout = context->timeout; - - /* - * Force use of port 139 for first try if share is $IPC, empty, or - * null, so browse lists can work - */ - if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) { - port_try_first = 139; - port_try_next = 445; - } else { - port_try_first = 445; - port_try_next = 139; - } - - c->port = port_try_first; - - status = cli_connect(c, server_n, &ss); - if (!NT_STATUS_IS_OK(status)) { - - /* First connection attempt failed. Try alternate port. */ - c->port = port_try_next; - - status = cli_connect(c, server_n, &ss); - if (!NT_STATUS_IS_OK(status)) { - cli_shutdown(c); - errno = ETIMEDOUT; - return NULL; - } - } - - if (!cli_session_request(c, &calling, &called)) { - cli_shutdown(c); - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } else { /* Try one more time, but ensure we don't loop */ - - /* Only try this if server is an IP address ... */ - - if (is_ipaddress(server) && !tried_reverse) { - fstring remote_name; - struct sockaddr_storage rem_ss; - - if (!interpret_string_addr(&rem_ss, server, - NI_NUMERICHOST)) { - DEBUG(4, ("Could not convert IP address " - "%s to struct sockaddr_storage\n", - server)); - errno = ETIMEDOUT; - return NULL; - } - - tried_reverse++; /* Yuck */ - - if (name_status_find("*", 0, 0, &rem_ss, remote_name)) { - make_nmb_name(&called, remote_name, 0x20); - goto again; - } - } - } - errno = ETIMEDOUT; - return NULL; - } - - DEBUG(4,(" session request ok\n")); - - if (!cli_negprot(c)) { - cli_shutdown(c); - errno = ETIMEDOUT; - return NULL; - } - - username_used = *pp_username; - - if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, - *pp_password, strlen(*pp_password), - *pp_password, strlen(*pp_password), - *pp_workgroup))) { - - /* Failed. Try an anonymous login, if allowed by flags. */ - username_used = ""; - - if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || - !NT_STATUS_IS_OK(cli_session_setup(c, username_used, - *pp_password, 1, - *pp_password, 0, - *pp_workgroup))) { - - cli_shutdown(c); - errno = EPERM; - return NULL; - } - } - - DEBUG(4,(" session setup ok\n")); - - if (!cli_send_tconX(c, share, "?????", - *pp_password, strlen(*pp_password)+1)) { - errno = smbc_errno(context, c); - cli_shutdown(c); - return NULL; - } - - DEBUG(4,(" tconx ok\n")); - - if (context->internal->_smb_encryption_level) { - /* Attempt UNIX smb encryption. */ - if (!NT_STATUS_IS_OK(cli_force_encryption(c, - username_used, - *pp_password, - *pp_workgroup))) { - - /* - * context->internal->_smb_encryption_level == 1 - * means don't fail if encryption can't be negotiated, - * == 2 means fail if encryption can't be negotiated. - */ - - DEBUG(4,(" SMB encrypt failed\n")); - - if (context->internal->_smb_encryption_level == 2) { - cli_shutdown(c); - errno = EPERM; - return NULL; - } - } - DEBUG(4,(" SMB encrypt ok\n")); - } - - /* - * Ok, we have got a nice connection - * Let's allocate a server structure. - */ - - srv = SMB_MALLOC_P(SMBCSRV); - if (!srv) { - errno = ENOMEM; - goto failed; - } - - ZERO_STRUCTP(srv); - srv->cli = c; - srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); - srv->no_pathinfo = False; - srv->no_pathinfo2 = False; - srv->no_nt_session = False; - - /* now add it to the cache (internal or external) */ - /* Let the cache function set errno if it wants to */ - errno = 0; - if ((context->callbacks.add_cached_srv_fn)(context, srv, - server, share, - *pp_workgroup, - *pp_username)) { - int saved_errno = errno; - DEBUG(3, (" Failed to add server to cache\n")); - errno = saved_errno; - if (errno == 0) { - errno = ENOMEM; - } - goto failed; - } - - DEBUG(2, ("Server connect ok: //%s/%s: %p\n", - server, share, srv)); - - DLIST_ADD(context->internal->_servers, srv); - return srv; - - failed: - cli_shutdown(c); - if (!srv) { - return NULL; - } - - SAFE_FREE(srv); - return NULL; -} - -/* - * Connect to a server for getting/setting attributes, possibly on an existing - * connection. This works similarly to smbc_server(). - */ -static SMBCSRV * -smbc_attr_server(TALLOC_CTX *ctx, - SMBCCTX *context, - const char *server, - const char *share, - char **pp_workgroup, - char **pp_username, - char **pp_password) -{ - int flags; - struct sockaddr_storage ss; - struct cli_state *ipc_cli; - struct rpc_pipe_client *pipe_hnd; - NTSTATUS nt_status; - SMBCSRV *ipc_srv=NULL; - - /* - * See if we've already created this special connection. Reference - * our "special" share name '*IPC$', which is an impossible real share - * name due to the leading asterisk. - */ - ipc_srv = find_server(ctx, context, server, "*IPC$", - pp_workgroup, pp_username, pp_password); - if (!ipc_srv) { - - /* We didn't find a cached connection. Get the password */ - if (!*pp_password || (*pp_password)[0] == '\0') { - /* ... then retrieve it now. */ - call_auth_fn(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - if (!*pp_workgroup || !*pp_username || !*pp_password) { - errno = ENOMEM; - return NULL; - } - } - - flags = 0; - if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { - flags |= CLI_FULL_CONNECTION_USE_KERBEROS; - } - - zero_addr(&ss); - nt_status = cli_full_connection(&ipc_cli, - global_myname(), server, - &ss, 0, "IPC$", "?????", - *pp_username, - *pp_workgroup, - *pp_password, - flags, - Undefined, NULL); - if (! NT_STATUS_IS_OK(nt_status)) { - DEBUG(1,("cli_full_connection failed! (%s)\n", - nt_errstr(nt_status))); - errno = ENOTSUP; - return NULL; - } - - if (context->internal->_smb_encryption_level) { - /* Attempt UNIX smb encryption. */ - if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, - *pp_username, - *pp_password, - *pp_workgroup))) { - - /* - * context->internal->_smb_encryption_level == 1 - * means don't fail if encryption can't be negotiated, - * == 2 means fail if encryption can't be negotiated. - */ - - DEBUG(4,(" SMB encrypt failed on IPC$\n")); - - if (context->internal->_smb_encryption_level == 2) { - cli_shutdown(ipc_cli); - errno = EPERM; - return NULL; - } - } - DEBUG(4,(" SMB encrypt ok on IPC$\n")); - } - - ipc_srv = SMB_MALLOC_P(SMBCSRV); - if (!ipc_srv) { - errno = ENOMEM; - cli_shutdown(ipc_cli); - return NULL; - } - - ZERO_STRUCTP(ipc_srv); - ipc_srv->cli = ipc_cli; - - pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, - PI_LSARPC, - &nt_status); - if (!pipe_hnd) { - DEBUG(1, ("cli_nt_session_open fail!\n")); - errno = ENOTSUP; - cli_shutdown(ipc_srv->cli); - free(ipc_srv); - return NULL; - } - - /* - * Some systems don't support - * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 - * so we might as well do it too. - */ - - nt_status = rpccli_lsa_open_policy( - pipe_hnd, - talloc_tos(), - True, - GENERIC_EXECUTE_ACCESS, - &ipc_srv->pol); - - if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, ipc_srv->cli); - cli_shutdown(ipc_srv->cli); - return NULL; - } - - /* now add it to the cache (internal or external) */ - - errno = 0; /* let cache function set errno if it likes */ - if ((context->callbacks.add_cached_srv_fn)(context, ipc_srv, - server, - "*IPC$", - *pp_workgroup, - *pp_username)) { - DEBUG(3, (" Failed to add server to cache\n")); - if (errno == 0) { - errno = ENOMEM; - } - cli_shutdown(ipc_srv->cli); - free(ipc_srv); - return NULL; - } - - DLIST_ADD(context->internal->_servers, ipc_srv); - } - - return ipc_srv; -} - -/* - * Routine to open() a file ... - */ - -static SMBCFILE * -smbc_open_ctx(SMBCCTX *context, - const char *fname, - int flags, - mode_t mode) -{ - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - SMBCSRV *srv = NULL; - SMBCFILE *file = NULL; - int fd; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return NULL; - - } - - if (!fname) { - - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - - } - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - if (errno == EPERM) errno = EACCES; - TALLOC_FREE(frame); - return NULL; /* smbc_server sets errno */ - } - - /* Hmmm, the test for a directory is suspect here ... FIXME */ - - if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { - fd = -1; - } else { - file = SMB_MALLOC_P(SMBCFILE); - - if (!file) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - - ZERO_STRUCTP(file); - - /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - SAFE_FREE(file); - TALLOC_FREE(frame); - return NULL; - } - /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ - - if ((fd = cli_open(targetcli, targetpath, flags, - context->internal->_share_mode)) < 0) { - - /* Handle the error ... */ - - SAFE_FREE(file); - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return NULL; - - } - - /* Fill in file struct */ - - file->cli_fd = fd; - file->fname = SMB_STRDUP(fname); - file->srv = srv; - file->offset = 0; - file->file = True; - - DLIST_ADD(context->internal->_files, file); - - /* - * If the file was opened in O_APPEND mode, all write - * operations should be appended to the file. To do that, - * though, using this protocol, would require a getattrE() - * call for each and every write, to determine where the end - * of the file is. (There does not appear to be an append flag - * in the protocol.) Rather than add all of that overhead of - * retrieving the current end-of-file offset prior to each - * write operation, we'll assume that most append operations - * will continuously write, so we'll just set the offset to - * the end of the file now and hope that's adequate. - * - * Note to self: If this proves inadequate, and O_APPEND - * should, in some cases, be forced for each write, add a - * field in the context options structure, for - * "strict_append_mode" which would select between the current - * behavior (if FALSE) or issuing a getattrE() prior to each - * write and forcing the write to the end of the file (if - * TRUE). Adding that capability will likely require adding - * an "append" flag into the _SMBCFILE structure to track - * whether a file was opened in O_APPEND mode. -- djl - */ - if (flags & O_APPEND) { - if (smbc_lseek_ctx(context, file, 0, SEEK_END) < 0) { - (void) smbc_close_ctx(context, file); - errno = ENXIO; - TALLOC_FREE(frame); - return NULL; - } - } - - TALLOC_FREE(frame); - return file; - - } - - /* Check if opendir needed ... */ - - if (fd == -1) { - int eno = 0; - - eno = smbc_errno(context, srv->cli); - file = (context->opendir)(context, fname); - if (!file) errno = eno; - TALLOC_FREE(frame); - return file; - - } - - errno = EINVAL; /* FIXME, correct errno ? */ - TALLOC_FREE(frame); - return NULL; - -} - -/* - * Routine to create a file - */ - -static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ - -static SMBCFILE * -smbc_creat_ctx(SMBCCTX *context, - const char *path, - mode_t mode) -{ - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - return NULL; - - } - - return smbc_open_ctx(context, path, creat_bits, mode); -} - -/* - * Routine to read() a file ... - */ - -static ssize_t -smbc_read_ctx(SMBCCTX *context, - SMBCFILE *file, - void *buf, - size_t count) -{ - int ret; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - /* - * offset: - * - * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) -- - * appears to pass file->offset (which is type off_t) differently than - * a local variable of type off_t. Using local variable "offset" in - * the call to cli_read() instead of file->offset fixes a problem - * retrieving data at an offset greater than 4GB. - */ - off_t offset; - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - - } - - offset = file->offset; - - /* Check that the buffer exists ... */ - - if (buf == NULL) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - /*d_printf(">>>read: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>read: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - - ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); - - if (ret < 0) { - - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return -1; - - } - - file->offset += ret; - - DEBUG(4, (" --> %d\n", ret)); - - TALLOC_FREE(frame); - return ret; /* Success, ret bytes of data ... */ - -} - -/* - * Routine to write() a file ... - */ - -static ssize_t -smbc_write_ctx(SMBCCTX *context, - SMBCFILE *file, - void *buf, - size_t count) -{ - int ret; - off_t offset; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - /* First check all pointers before dereferencing them */ - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - } - - /* Check that the buffer exists ... */ - - if (buf == NULL) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ - - /*d_printf(">>>write: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>write: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - - ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); - - if (ret <= 0) { - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return -1; - - } - - file->offset += ret; - - TALLOC_FREE(frame); - return ret; /* Success, 0 bytes of data ... */ -} - -/* - * Routine to close() a file ... - */ - -static int -smbc_close_ctx(SMBCCTX *context, - SMBCFILE *file) -{ - SMBCSRV *srv; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - } - - /* IS a dir ... */ - if (!file->file) { - TALLOC_FREE(frame); - return (context->closedir)(context, file); - } - - /*d_printf(">>>close: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>close: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ - - if (!cli_close(targetcli, file->cli_fd)) { - - DEBUG(3, ("cli_close failed on %s. purging server.\n", - file->fname)); - /* Deallocate slot and remove the server - * from the server cache if unused */ - errno = smbc_errno(context, targetcli); - srv = file->srv; - DLIST_REMOVE(context->internal->_files, file); - SAFE_FREE(file->fname); - SAFE_FREE(file); - (context->callbacks.remove_unused_server_fn)(context, srv); - TALLOC_FREE(frame); - return -1; - - } - - DLIST_REMOVE(context->internal->_files, file); - SAFE_FREE(file->fname); - SAFE_FREE(file); - TALLOC_FREE(frame); - - return 0; -} - -/* - * Get info from an SMB server on a file. Use a qpathinfo call first - * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo - */ -static bool -smbc_getatr(SMBCCTX * context, - SMBCSRV *srv, - char *path, - uint16 *mode, - SMB_OFF_T *size, - struct timespec *create_time_ts, - struct timespec *access_time_ts, - struct timespec *write_time_ts, - struct timespec *change_time_ts, - SMB_INO_T *ino) -{ - char *fixedpath = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - time_t write_time; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /* path fixup for . and .. */ - if (strequal(path, ".") || strequal(path, "..")) { - fixedpath = talloc_strdup(frame, "\\"); - if (!fixedpath) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } else { - fixedpath = talloc_strdup(frame, path); - if (!fixedpath) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - trim_string(fixedpath, NULL, "\\.."); - trim_string(fixedpath, NULL, "\\."); - } - DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - - if (!cli_resolve_path(frame, "", srv->cli, fixedpath, - &targetcli, &targetpath)) { - d_printf("Couldn't resolve %s\n", path); - TALLOC_FREE(frame); - return False; - } - - if (!srv->no_pathinfo2 && - cli_qpathinfo2(targetcli, targetpath, - create_time_ts, - access_time_ts, - write_time_ts, - change_time_ts, - size, mode, ino)) { - TALLOC_FREE(frame); - return True; - } - - /* if this is NT then don't bother with the getatr */ - if (targetcli->capabilities & CAP_NT_SMBS) { - errno = EPERM; - TALLOC_FREE(frame); - return False; - } - - if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) { - - struct timespec w_time_ts; - - w_time_ts = convert_time_t_to_timespec(write_time); - - if (write_time_ts != NULL) { - *write_time_ts = w_time_ts; - } - - if (create_time_ts != NULL) { - *create_time_ts = w_time_ts; - } - - if (access_time_ts != NULL) { - *access_time_ts = w_time_ts; - } - - if (change_time_ts != NULL) { - *change_time_ts = w_time_ts; - } - - srv->no_pathinfo2 = True; - TALLOC_FREE(frame); - return True; - } - - errno = EPERM; - TALLOC_FREE(frame); - return False; - -} - -/* - * Set file info on an SMB server. Use setpathinfo call first. If that - * fails, use setattrE.. - * - * Access and modification time parameters are always used and must be - * provided. Create time, if zero, will be determined from the actual create - * time of the file. If non-zero, the create time will be set as well. - * - * "mode" (attributes) parameter may be set to -1 if it is not to be set. - */ -static bool -smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, - time_t create_time, - time_t access_time, - time_t write_time, - time_t change_time, - uint16 mode) -{ - int fd; - int ret; - TALLOC_CTX *frame = talloc_stackframe(); - - /* - * First, try setpathinfo (if qpathinfo succeeded), for it is the - * modern function for "new code" to be using, and it works given a - * filename rather than requiring that the file be opened to have its - * attributes manipulated. - */ - if (srv->no_pathinfo || - ! cli_setpathinfo(srv->cli, path, - create_time, - access_time, - write_time, - change_time, - mode)) { - - /* - * setpathinfo is not supported; go to plan B. - * - * cli_setatr() does not work on win98, and it also doesn't - * support setting the access time (only the modification - * time), so in all cases, we open the specified file and use - * cli_setattrE() which should work on all OS versions, and - * supports both times. - */ - - /* Don't try {q,set}pathinfo() again, with this server */ - srv->no_pathinfo = True; - - /* Open the file */ - if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { - - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return -1; - } - - /* Set the new attributes */ - ret = cli_setattrE(srv->cli, fd, - change_time, - access_time, - write_time); - - /* Close the file */ - cli_close(srv->cli, fd); - - /* - * Unfortunately, setattrE() doesn't have a provision for - * setting the access mode (attributes). We'll have to try - * cli_setatr() for that, and with only this parameter, it - * seems to work on win98. - */ - if (ret && mode != (uint16) -1) { - ret = cli_setatr(srv->cli, path, mode, 0); - } - - if (! ret) { - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return False; - } - } - - TALLOC_FREE(frame); - return True; -} - - /* - * Routine to unlink() a file - */ - -static int -smbc_unlink_ctx(SMBCCTX *context, - const char *fname) -{ - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - SMBCSRV *srv = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* smbc_server sets errno */ - - } - - /*d_printf(">>>unlink: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ - - if (!cli_unlink(targetcli, targetpath)) { - - errno = smbc_errno(context, targetcli); - - if (errno == EACCES) { /* Check if the file is a directory */ - - int saverr = errno; - SMB_OFF_T size = 0; - uint16 mode = 0; - struct timespec write_time_ts; - struct timespec access_time_ts; - struct timespec change_time_ts; - SMB_INO_T ino = 0; - - if (!smbc_getatr(context, srv, path, &mode, &size, - NULL, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &ino)) { - - /* Hmmm, bad error ... What? */ - - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return -1; - - } - else { - - if (IS_DOS_DIR(mode)) - errno = EISDIR; - else - errno = saverr; /* Restore this */ - - } - } - - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return 0; /* Success ... */ - -} - -/* - * Routine to rename() a file - */ - -static int -smbc_rename_ctx(SMBCCTX *ocontext, - const char *oname, - SMBCCTX *ncontext, - const char *nname) -{ - char *server1 = NULL; - char *share1 = NULL; - char *server2 = NULL; - char *share2 = NULL; - char *user1 = NULL; - char *user2 = NULL; - char *password1 = NULL; - char *password2 = NULL; - char *workgroup = NULL; - char *path1 = NULL; - char *path2 = NULL; - char *targetpath1 = NULL; - char *targetpath2 = NULL; - struct cli_state *targetcli1 = NULL; - struct cli_state *targetcli2 = NULL; - SMBCSRV *srv = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!ocontext || !ncontext || - !ocontext->internal || !ncontext->internal || - !ocontext->internal->_initialized || - !ncontext->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!oname || !nname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - - if (smbc_parse_path(frame, - ocontext, - oname, - &workgroup, - &server1, - &share1, - &path1, - &user1, - &password1, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user1 || user1[0] == (char)0) { - user1 = talloc_strdup(frame, ocontext->user); - if (!user1) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - if (smbc_parse_path(frame, - ncontext, - nname, - NULL, - &server2, - &share2, - &path2, - &user2, - &password2, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user2 || user2[0] == (char)0) { - user2 = talloc_strdup(frame, ncontext->user); - if (!user2) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - if (strcmp(server1, server2) || strcmp(share1, share2) || - strcmp(user1, user2)) { - /* Can't rename across file systems, or users?? */ - errno = EXDEV; - TALLOC_FREE(frame); - return -1; - } - - srv = smbc_server(frame, ocontext, True, - server1, share1, &workgroup, &user1, &password1); - if (!srv) { - TALLOC_FREE(frame); - return -1; - - } - - /*d_printf(">>>rename: resolving %s\n", path1);*/ - if (!cli_resolve_path(frame, "", srv->cli, path1, - &targetcli1, &targetpath1)) { - d_printf("Could not resolve %s\n", path1); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ - /*d_printf(">>>rename: resolving %s\n", path2);*/ - if (!cli_resolve_path(frame, "", srv->cli, path2, - &targetcli2, &targetpath2)) { - d_printf("Could not resolve %s\n", path2); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ - - if (strcmp(targetcli1->desthost, targetcli2->desthost) || - strcmp(targetcli1->share, targetcli2->share)) - { - /* can't rename across file systems */ - errno = EXDEV; - TALLOC_FREE(frame); - return -1; - } - - if (!cli_rename(targetcli1, targetpath1, targetpath2)) { - int eno = smbc_errno(ocontext, targetcli1); - - if (eno != EEXIST || - !cli_unlink(targetcli1, targetpath2) || - !cli_rename(targetcli1, targetpath1, targetpath2)) { - - errno = eno; - TALLOC_FREE(frame); - return -1; - - } - } - - TALLOC_FREE(frame); - return 0; /* Success */ -} - -/* - * A routine to lseek() a file - */ - -static off_t -smbc_lseek_ctx(SMBCCTX *context, - SMBCFILE *file, - off_t offset, - int whence) -{ - SMB_OFF_T size; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - - errno = EBADF; - TALLOC_FREE(frame); - return -1; - - } - - if (!file->file) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; /* Can't lseek a dir ... */ - - } - - switch (whence) { - case SEEK_SET: - file->offset = offset; - break; - - case SEEK_CUR: - file->offset += offset; - break; - - case SEEK_END: - /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>lseek: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ - - if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, - &size, NULL, NULL, NULL, NULL, NULL)) - { - SMB_OFF_T b_size = size; - if (!cli_getattrE(targetcli, file->cli_fd, - NULL, &b_size, NULL, NULL, NULL)) - { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } else - size = b_size; - } - file->offset = size + offset; - break; - - default: - errno = EINVAL; - break; - - } - - TALLOC_FREE(frame); - return file->offset; - -} - -/* - * Generate an inode number from file name for those things that need it - */ - -static ino_t -smbc_inode(SMBCCTX *context, - const char *name) -{ - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - return -1; - - } - - if (!*name) return 2; /* FIXME, why 2 ??? */ - return (ino_t)str_checksum(name); - -} - -/* - * Routine to put basic stat info into a stat structure ... Used by stat and - * fstat below. - */ - -static int -smbc_setup_stat(SMBCCTX *context, - struct stat *st, - char *fname, - SMB_OFF_T size, - int mode) -{ - TALLOC_CTX *frame = talloc_stackframe(); - - st->st_mode = 0; - - if (IS_DOS_DIR(mode)) { - st->st_mode = SMBC_DIR_MODE; - } else { - st->st_mode = SMBC_FILE_MODE; - } - - if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; - if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; - if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; - if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; - - st->st_size = size; -#ifdef HAVE_STAT_ST_BLKSIZE - st->st_blksize = 512; -#endif -#ifdef HAVE_STAT_ST_BLOCKS - st->st_blocks = (size+511)/512; -#endif -#ifdef HAVE_STRUCT_STAT_ST_RDEV - st->st_rdev = 0; -#endif - st->st_uid = getuid(); - st->st_gid = getgid(); - - if (IS_DOS_DIR(mode)) { - st->st_nlink = 2; - } else { - st->st_nlink = 1; - } - - if (st->st_ino == 0) { - st->st_ino = smbc_inode(context, fname); - } - - TALLOC_FREE(frame); - return True; /* FIXME: Is this needed ? */ - -} - -/* - * Routine to stat a file given a name - */ - -static int -smbc_stat_ctx(SMBCCTX *context, - const char *fname, - struct stat *st) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - struct timespec write_time_ts; - struct timespec access_time_ts; - struct timespec change_time_ts; - SMB_OFF_T size = 0; - uint16 mode = 0; - SMB_INO_T ino = 0; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_stat(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame,context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (!smbc_getatr(context, srv, path, &mode, &size, - NULL, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &ino)) { - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return -1; - } - - st->st_ino = ino; - - smbc_setup_stat(context, st, (char *) fname, size, mode); - - set_atimespec(st, access_time_ts); - set_ctimespec(st, change_time_ts); - set_mtimespec(st, write_time_ts); - st->st_dev = srv->dev; - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Routine to stat a file given an fd - */ - -static int -smbc_fstat_ctx(SMBCCTX *context, - SMBCFILE *file, - struct stat *st) -{ - struct timespec change_time_ts; - struct timespec access_time_ts; - struct timespec write_time_ts; - SMB_OFF_T size; - uint16 mode; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - SMB_INO_T ino = 0; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - } - - if (!file->file) { - TALLOC_FREE(frame); - return (context->fstatdir)(context, file, st); - } - - /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - - if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, - NULL, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &ino)) { - - time_t change_time, access_time, write_time; - - if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, - &change_time, &access_time, &write_time)) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - change_time_ts = convert_time_t_to_timespec(change_time); - access_time_ts = convert_time_t_to_timespec(access_time); - write_time_ts = convert_time_t_to_timespec(write_time); - } - - st->st_ino = ino; - - smbc_setup_stat(context, st, file->fname, size, mode); - - set_atimespec(st, access_time_ts); - set_ctimespec(st, change_time_ts); - set_mtimespec(st, write_time_ts); - st->st_dev = file->srv->dev; - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Routine to open a directory - * We accept the URL syntax explained in smbc_parse_path(), above. - */ - -static void -smbc_remove_dir(SMBCFILE *dir) -{ - struct smbc_dir_list *d,*f; - - d = dir->dir_list; - while (d) { - - f = d; d = d->next; - - SAFE_FREE(f->dirent); - SAFE_FREE(f); - - } - - dir->dir_list = dir->dir_end = dir->dir_next = NULL; - -} - -static int -add_dirent(SMBCFILE *dir, - const char *name, - const char *comment, - uint32 type) -{ - struct smbc_dirent *dirent; - int size; - int name_length = (name == NULL ? 0 : strlen(name)); - int comment_len = (comment == NULL ? 0 : strlen(comment)); - - /* - * Allocate space for the dirent, which must be increased by the - * size of the name and the comment and 1 each for the null terminator. - */ - - size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; - - dirent = (struct smbc_dirent *)SMB_MALLOC(size); - - if (!dirent) { - - dir->dir_error = ENOMEM; - return -1; - - } - - ZERO_STRUCTP(dirent); - - if (dir->dir_list == NULL) { - - dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list); - if (!dir->dir_list) { - - SAFE_FREE(dirent); - dir->dir_error = ENOMEM; - return -1; - - } - ZERO_STRUCTP(dir->dir_list); - - dir->dir_end = dir->dir_next = dir->dir_list; - } - else { - - dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list); - - if (!dir->dir_end->next) { - - SAFE_FREE(dirent); - dir->dir_error = ENOMEM; - return -1; - - } - ZERO_STRUCTP(dir->dir_end->next); - - dir->dir_end = dir->dir_end->next; - } - - dir->dir_end->next = NULL; - dir->dir_end->dirent = dirent; - - dirent->smbc_type = type; - dirent->namelen = name_length; - dirent->commentlen = comment_len; - dirent->dirlen = size; - - /* - * dirent->namelen + 1 includes the null (no null termination needed) - * Ditto for dirent->commentlen. - * The space for the two null bytes was allocated. - */ - strncpy(dirent->name, (name?name:""), dirent->namelen + 1); - dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); - strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); - - return 0; - -} - -static void -list_unique_wg_fn(const char *name, - uint32 type, - const char *comment, - void *state) -{ - SMBCFILE *dir = (SMBCFILE *)state; - struct smbc_dir_list *dir_list; - struct smbc_dirent *dirent; - int dirent_type; - int do_remove = 0; - - dirent_type = dir->dir_type; - - if (add_dirent(dir, name, comment, dirent_type) < 0) { - - /* An error occurred, what do we do? */ - /* FIXME: Add some code here */ - } - - /* Point to the one just added */ - dirent = dir->dir_end->dirent; - - /* See if this was a duplicate */ - for (dir_list = dir->dir_list; - dir_list != dir->dir_end; - dir_list = dir_list->next) { - if (! do_remove && - strcmp(dir_list->dirent->name, dirent->name) == 0) { - /* Duplicate. End end of list need to be removed. */ - do_remove = 1; - } - - if (do_remove && dir_list->next == dir->dir_end) { - /* Found the end of the list. Remove it. */ - dir->dir_end = dir_list; - free(dir_list->next); - free(dirent); - dir_list->next = NULL; - break; - } - } -} - -static void -list_fn(const char *name, - uint32 type, - const char *comment, - void *state) -{ - SMBCFILE *dir = (SMBCFILE *)state; - int dirent_type; - - /* - * We need to process the type a little ... - * - * Disk share = 0x00000000 - * Print share = 0x00000001 - * Comms share = 0x00000002 (obsolete?) - * IPC$ share = 0x00000003 - * - * administrative shares: - * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 - */ - - if (dir->dir_type == SMBC_FILE_SHARE) { - switch (type) { - case 0 | 0x80000000: - case 0: - dirent_type = SMBC_FILE_SHARE; - break; - - case 1: - dirent_type = SMBC_PRINTER_SHARE; - break; - - case 2: - dirent_type = SMBC_COMMS_SHARE; - break; - - case 3 | 0x80000000: - case 3: - dirent_type = SMBC_IPC_SHARE; - break; - - default: - dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ - break; - } - } - else { - dirent_type = dir->dir_type; - } - - if (add_dirent(dir, name, comment, dirent_type) < 0) { - - /* An error occurred, what do we do? */ - /* FIXME: Add some code here */ - - } -} - -static void -dir_list_fn(const char *mnt, - file_info *finfo, - const char *mask, - void *state) -{ - - if (add_dirent((SMBCFILE *)state, finfo->name, "", - (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { - - /* Handle an error ... */ - - /* FIXME: Add some code ... */ - - } - -} - -static int -net_share_enum_rpc(struct cli_state *cli, - void (*fn)(const char *name, - uint32 type, - const char *comment, - void *state), - void *state) -{ - int i; - WERROR result; - ENUM_HND enum_hnd; - uint32 info_level = 1; - uint32 preferred_len = 0xffffffff; - uint32 type; - SRV_SHARE_INFO_CTR ctr; - fstring name = ""; - fstring comment = ""; - struct rpc_pipe_client *pipe_hnd; - NTSTATUS nt_status; - - /* Open the server service pipe */ - pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); - if (!pipe_hnd) { - DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); - return -1; - } - - /* Issue the NetShareEnum RPC call and retrieve the response */ - init_enum_hnd(&enum_hnd, 0); - result = rpccli_srvsvc_net_share_enum(pipe_hnd, - talloc_tos(), - info_level, - &ctr, - preferred_len, - &enum_hnd); - - /* Was it successful? */ - if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { - /* Nope. Go clean up. */ - goto done; - } - - /* For each returned entry... */ - for (i = 0; i < ctr.num_entries; i++) { - - /* pull out the share name */ - rpcstr_pull_unistr2_fstring( - name, &ctr.share.info1[i].info_1_str.uni_netname); - - /* pull out the share's comment */ - rpcstr_pull_unistr2_fstring( - comment, &ctr.share.info1[i].info_1_str.uni_remark); - - /* Get the type value */ - type = ctr.share.info1[i].info_1.type; - - /* Add this share to the list */ - (*fn)(name, type, comment, state); - } - -done: - /* Close the server service pipe */ - cli_rpc_pipe_close(pipe_hnd); - - /* Tell 'em if it worked */ - return W_ERROR_IS_OK(result) ? 0 : -1; -} - - - -static SMBCFILE * -smbc_opendir_ctx(SMBCCTX *context, - const char *fname) -{ - int saved_errno; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *options = NULL; - char *workgroup = NULL; - char *path = NULL; - uint16 mode; - char *p = NULL; - SMBCSRV *srv = NULL; - SMBCFILE *dir = NULL; - struct _smbc_callbacks *cb = NULL; - struct sockaddr_storage rem_ss; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - DEBUG(4, ("no valid context\n")); - errno = EINVAL + 8192; - TALLOC_FREE(frame); - return NULL; - - } - - if (!fname) { - DEBUG(4, ("no valid fname\n")); - errno = EINVAL + 8193; - TALLOC_FREE(frame); - return NULL; - } - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - &options)) { - DEBUG(4, ("no valid path\n")); - errno = EINVAL + 8194; - TALLOC_FREE(frame); - return NULL; - } - - DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' " - "path='%s' options='%s'\n", - fname, server, share, path, options)); - - /* Ensure the options are valid */ - if (smbc_check_options(server, share, path, options)) { - DEBUG(4, ("unacceptable options (%s)\n", options)); - errno = EINVAL + 8195; - TALLOC_FREE(frame); - return NULL; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - } - - dir = SMB_MALLOC_P(SMBCFILE); - - if (!dir) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - - ZERO_STRUCTP(dir); - - dir->cli_fd = 0; - dir->fname = SMB_STRDUP(fname); - dir->srv = NULL; - dir->offset = 0; - dir->file = False; - dir->dir_list = dir->dir_next = dir->dir_end = NULL; - - if (server[0] == (char)0) { - - int i; - int count; - int max_lmb_count; - struct ip_service *ip_list; - struct ip_service server_addr; - struct user_auth_info u_info; - - if (share[0] != (char)0 || path[0] != (char)0) { - - errno = EINVAL + 8196; - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - /* Determine how many local master browsers to query */ - max_lmb_count = (context->options.browse_max_lmb_count == 0 - ? INT_MAX - : context->options.browse_max_lmb_count); - - memset(&u_info, '\0', sizeof(u_info)); - u_info.username = talloc_strdup(frame,user); - u_info.password = talloc_strdup(frame,password); - if (!u_info.username || !u_info.password) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - /* - * We have server and share and path empty but options - * requesting that we scan all master browsers for their list - * of workgroups/domains. This implies that we must first try - * broadcast queries to find all master browsers, and if that - * doesn't work, then try our other methods which return only - * a single master browser. - */ - - ip_list = NULL; - if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, - &count))) - { - - SAFE_FREE(ip_list); - - if (!find_master_ip(workgroup, &server_addr.ss)) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - errno = ENOENT; - TALLOC_FREE(frame); - return NULL; - } - - ip_list = (struct ip_service *)memdup( - &server_addr, sizeof(server_addr)); - if (ip_list == NULL) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - count = 1; - } - - for (i = 0; i < count && i < max_lmb_count; i++) { - char addr[INET6_ADDRSTRLEN]; - char *wg_ptr = NULL; - struct cli_state *cli = NULL; - - print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); - DEBUG(99, ("Found master browser %d of %d: %s\n", - i+1, MAX(count, max_lmb_count), - addr)); - - cli = get_ipc_connect_master_ip(talloc_tos(), - &ip_list[i], - &u_info, - &wg_ptr); - /* cli == NULL is the master browser refused to talk or - could not be found */ - if (!cli) { - continue; - } - - workgroup = talloc_strdup(frame, wg_ptr); - server = talloc_strdup(frame, cli->desthost); - - cli_shutdown(cli); - - if (!workgroup || !server) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - - DEBUG(4, ("using workgroup %s %s\n", - workgroup, server)); - - /* - * For each returned master browser IP address, get a - * connection to IPC$ on the server if we do not - * already have one, and determine the - * workgroups/domains that it knows about. - */ - - srv = smbc_server(frame, context, True, server, "IPC$", - &workgroup, &user, &password); - if (!srv) { - continue; - } - - dir->srv = srv; - dir->dir_type = SMBC_WORKGROUP; - - /* Now, list the stuff ... */ - - if (!cli_NetServerEnum(srv->cli, - workgroup, - SV_TYPE_DOMAIN_ENUM, - list_unique_wg_fn, - (void *)dir)) { - continue; - } - } - - SAFE_FREE(ip_list); - } else { - /* - * Server not an empty string ... Check the rest and see what - * gives - */ - if (*share == '\0') { - if (*path != '\0') { - - /* Should not have empty share with path */ - errno = EINVAL + 8197; - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - - } - - /* - * We don't know if <server> is really a server name - * or is a workgroup/domain name. If we already have - * a server structure for it, we'll use it. - * Otherwise, check to see if <server><1D>, - * <server><1B>, or <server><20> translates. We check - * to see if <server> is an IP address first. - */ - - /* - * See if we have an existing server. Do not - * establish a connection if one does not already - * exist. - */ - srv = smbc_server(frame, context, False, server, "IPC$", - &workgroup, &user, &password); - - /* - * If no existing server and not an IP addr, look for - * LMB or DMB - */ - if (!srv && - !is_ipaddress(server) && - (resolve_name(server, &rem_ss, 0x1d) || /* LMB */ - resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */ - - fstring buserver; - - dir->dir_type = SMBC_SERVER; - - /* - * Get the backup list ... - */ - if (!name_status_find(server, 0, 0, - &rem_ss, buserver)) { - - DEBUG(0, ("Could not get name of " - "local/domain master browser " - "for server %s\n", server)); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - errno = EPERM; - TALLOC_FREE(frame); - return NULL; - - } - - /* - * Get a connection to IPC$ on the server if - * we do not already have one - */ - srv = smbc_server(frame, context, True, - buserver, "IPC$", - &workgroup, &user, &password); - if (!srv) { - DEBUG(0, ("got no contact to IPC$\n")); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - - } - - dir->srv = srv; - - /* Now, list the servers ... */ - if (!cli_NetServerEnum(srv->cli, server, - 0x0000FFFE, list_fn, - (void *)dir)) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - } else if (srv || - (resolve_name(server, &rem_ss, 0x20))) { - - /* If we hadn't found the server, get one now */ - if (!srv) { - srv = smbc_server(frame, context, True, - server, "IPC$", - &workgroup, - &user, &password); - } - - if (!srv) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - - } - - dir->dir_type = SMBC_FILE_SHARE; - dir->srv = srv; - - /* List the shares ... */ - - if (net_share_enum_rpc( - srv->cli, - list_fn, - (void *) dir) < 0 && - cli_RNetShareEnum( - srv->cli, - list_fn, - (void *)dir) < 0) { - - errno = cli_errno(srv->cli); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - - } - } else { - /* Neither the workgroup nor server exists */ - errno = ECONNREFUSED; - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - } - else { - /* - * The server and share are specified ... work from - * there ... - */ - char *targetpath; - struct cli_state *targetcli; - - /* We connect to the server and list the directory */ - dir->dir_type = SMBC_FILE_SHARE; - - srv = smbc_server(frame, context, True, server, share, - &workgroup, &user, &password); - - if (!srv) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - dir->srv = srv; - - /* Now, list the files ... */ - - p = path + strlen(path); - path = talloc_asprintf_append(path, "\\*"); - if (!path) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - if (cli_list(targetcli, targetpath, - aDIR | aSYSTEM | aHIDDEN, - dir_list_fn, (void *)dir) < 0) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - saved_errno = smbc_errno(context, targetcli); - - if (saved_errno == EINVAL) { - /* - * See if they asked to opendir something - * other than a directory. If so, the - * converted error value we got would have - * been EINVAL rather than ENOTDIR. - */ - *p = '\0'; /* restore original path */ - - if (smbc_getatr(context, srv, path, - &mode, NULL, - NULL, NULL, NULL, NULL, - NULL) && - ! IS_DOS_DIR(mode)) { - - /* It is. Correct the error value */ - saved_errno = ENOTDIR; - } - } - - /* - * If there was an error and the server is no - * good any more... - */ - cb = &context->callbacks; - if (cli_is_error(targetcli) && - (cb->check_server_fn)(context, srv)) { - - /* ... then remove it. */ - if ((cb->remove_unused_server_fn)(context, - srv)) { - /* - * We could not remove the - * server completely, remove - * it from the cache so we - * will not get it again. It - * will be removed when the - * last file/dir is closed. - */ - (cb->remove_cached_srv_fn)(context, - srv); - } - } - - errno = saved_errno; - TALLOC_FREE(frame); - return NULL; - } - } - - } - - DLIST_ADD(context->internal->_files, dir); - TALLOC_FREE(frame); - return dir; - -} - -/* - * Routine to close a directory - */ - -static int -smbc_closedir_ctx(SMBCCTX *context, - SMBCFILE *dir) -{ - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - } - - smbc_remove_dir(dir); /* Clean it up */ - - DLIST_REMOVE(context->internal->_files, dir); - - if (dir) { - - SAFE_FREE(dir->fname); - SAFE_FREE(dir); /* Free the space too */ - } - - TALLOC_FREE(frame); - return 0; - -} - -static void -smbc_readdir_internal(SMBCCTX * context, - struct smbc_dirent *dest, - struct smbc_dirent *src, - int max_namebuf_len) -{ - if (context->options.urlencode_readdir_entries) { - - /* url-encode the name. get back remaining buffer space */ - max_namebuf_len = - smbc_urlencode(dest->name, src->name, max_namebuf_len); - - /* We now know the name length */ - dest->namelen = strlen(dest->name); - - /* Save the pointer to the beginning of the comment */ - dest->comment = dest->name + dest->namelen + 1; - - /* Copy the comment */ - strncpy(dest->comment, src->comment, max_namebuf_len - 1); - dest->comment[max_namebuf_len - 1] = '\0'; - - /* Save other fields */ - dest->smbc_type = src->smbc_type; - dest->commentlen = strlen(dest->comment); - dest->dirlen = ((dest->comment + dest->commentlen + 1) - - (char *) dest); - } else { - - /* No encoding. Just copy the entry as is. */ - memcpy(dest, src, src->dirlen); - dest->comment = (char *)(&dest->name + src->namelen + 1); - } - -} - -/* - * Routine to get a directory entry - */ - -struct smbc_dirent * -smbc_readdir_ctx(SMBCCTX *context, - SMBCFILE *dir) -{ - int maxlen; - struct smbc_dirent *dirp, *dirent; - TALLOC_CTX *frame = talloc_stackframe(); - - /* Check that all is ok first ... */ - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - DEBUG(0, ("Invalid context in smbc_readdir_ctx()\n")); - TALLOC_FREE(frame); - return NULL; - - } - - if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { - - errno = EBADF; - DEBUG(0, ("Invalid dir in smbc_readdir_ctx()\n")); - TALLOC_FREE(frame); - return NULL; - - } - - if (dir->file != False) { /* FIXME, should be dir, perhaps */ - - errno = ENOTDIR; - DEBUG(0, ("Found file vs directory in smbc_readdir_ctx()\n")); - TALLOC_FREE(frame); - return NULL; - - } - - if (!dir->dir_next) { - TALLOC_FREE(frame); - return NULL; - } - - dirent = dir->dir_next->dirent; - if (!dirent) { - - errno = ENOENT; - TALLOC_FREE(frame); - return NULL; - - } - - dirp = (struct smbc_dirent *)context->internal->_dirent; - maxlen = (sizeof(context->internal->_dirent) - - sizeof(struct smbc_dirent)); - - smbc_readdir_internal(context, dirp, dirent, maxlen); - - dir->dir_next = dir->dir_next->next; - - TALLOC_FREE(frame); - return dirp; -} - -/* - * Routine to get directory entries - */ - -static int -smbc_getdents_ctx(SMBCCTX *context, - SMBCFILE *dir, - struct smbc_dirent *dirp, - int count) -{ - int rem = count; - int reqd; - int maxlen; - char *ndir = (char *)dirp; - struct smbc_dir_list *dirlist; - TALLOC_CTX *frame = talloc_stackframe(); - - /* Check that all is ok first ... */ - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { - - errno = EBADF; - TALLOC_FREE(frame); - return -1; - - } - - if (dir->file != False) { /* FIXME, should be dir, perhaps */ - - errno = ENOTDIR; - TALLOC_FREE(frame); - return -1; - - } - - /* - * Now, retrieve the number of entries that will fit in what was passed - * We have to figure out if the info is in the list, or we need to - * send a request to the server to get the info. - */ - - while ((dirlist = dir->dir_next)) { - struct smbc_dirent *dirent; - - if (!dirlist->dirent) { - - errno = ENOENT; /* Bad error */ - TALLOC_FREE(frame); - return -1; - - } - - /* Do urlencoding of next entry, if so selected */ - dirent = (struct smbc_dirent *)context->internal->_dirent; - maxlen = (sizeof(context->internal->_dirent) - - sizeof(struct smbc_dirent)); - smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen); - - reqd = dirent->dirlen; - - if (rem < reqd) { - - if (rem < count) { /* We managed to copy something */ - - errno = 0; - TALLOC_FREE(frame); - return count - rem; - - } - else { /* Nothing copied ... */ - - errno = EINVAL; /* Not enough space ... */ - TALLOC_FREE(frame); - return -1; - - } - - } - - memcpy(ndir, dirent, reqd); /* Copy the data in ... */ - - ((struct smbc_dirent *)ndir)->comment = - (char *)(&((struct smbc_dirent *)ndir)->name + - dirent->namelen + - 1); - - ndir += reqd; - - rem -= reqd; - - dir->dir_next = dirlist = dirlist -> next; - } - - TALLOC_FREE(frame); - - if (rem == count) - return 0; - else - return count - rem; - -} - -/* - * Routine to create a directory ... - */ - -static int -smbc_mkdir_ctx(SMBCCTX *context, - const char *fname, - mode_t mode) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - - } - - /*d_printf(">>>mkdir: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ - - if (!cli_mkdir(targetcli, targetpath)) { - - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Our list function simply checks to see if a directory is not empty - */ - -static int smbc_rmdir_dirempty = True; - -static void -rmdir_list_fn(const char *mnt, - file_info *finfo, - const char *mask, - void *state) -{ - if (strncmp(finfo->name, ".", 1) != 0 && - strncmp(finfo->name, "..", 2) != 0) { - smbc_rmdir_dirempty = False; - } -} - -/* - * Routine to remove a directory - */ - -static int -smbc_rmdir_ctx(SMBCCTX *context, - const char *fname) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - - } - - /*d_printf(">>>rmdir: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/ - - - if (!cli_rmdir(targetcli, targetpath)) { - - errno = smbc_errno(context, targetcli); - - if (errno == EACCES) { /* Check if the dir empty or not */ - - /* Local storage to avoid buffer overflows */ - char *lpath; - - smbc_rmdir_dirempty = True; /* Make this so ... */ - - lpath = talloc_asprintf(frame, "%s\\*", - targetpath); - if (!lpath) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - - if (cli_list(targetcli, lpath, - aDIR | aSYSTEM | aHIDDEN, - rmdir_list_fn, NULL) < 0) { - - /* Fix errno to ignore latest error ... */ - DEBUG(5, ("smbc_rmdir: " - "cli_list returned an error: %d\n", - smbc_errno(context, targetcli))); - errno = EACCES; - - } - - if (smbc_rmdir_dirempty) - errno = EACCES; - else - errno = ENOTEMPTY; - - } - - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Routine to return the current directory position - */ - -static off_t -smbc_telldir_ctx(SMBCCTX *context, - SMBCFILE *dir) -{ - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { - - errno = EBADF; - TALLOC_FREE(frame); - return -1; - - } - - if (dir->file != False) { /* FIXME, should be dir, perhaps */ - - errno = ENOTDIR; - TALLOC_FREE(frame); - return -1; - - } - - /* See if we're already at the end. */ - if (dir->dir_next == NULL) { - /* We are. */ - TALLOC_FREE(frame); - return -1; - } - - /* - * We return the pointer here as the offset - */ - TALLOC_FREE(frame); - return (off_t)(long)dir->dir_next->dirent; -} - -/* - * A routine to run down the list and see if the entry is OK - */ - -struct smbc_dir_list * -smbc_check_dir_ent(struct smbc_dir_list *list, - struct smbc_dirent *dirent) -{ - - /* Run down the list looking for what we want */ - - if (dirent) { - - struct smbc_dir_list *tmp = list; - - while (tmp) { - - if (tmp->dirent == dirent) - return tmp; - - tmp = tmp->next; - - } - - } - - return NULL; /* Not found, or an error */ - -} - - -/* - * Routine to seek on a directory - */ - -static int -smbc_lseekdir_ctx(SMBCCTX *context, - SMBCFILE *dir, - off_t offset) -{ - long int l_offset = offset; /* Handle problems of size */ - struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; - struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (dir->file != False) { /* FIXME, should be dir, perhaps */ - - errno = ENOTDIR; - TALLOC_FREE(frame); - return -1; - - } - - /* Now, check what we were passed and see if it is OK ... */ - - if (dirent == NULL) { /* Seek to the begining of the list */ - - dir->dir_next = dir->dir_list; - TALLOC_FREE(frame); - return 0; - - } - - if (offset == -1) { /* Seek to the end of the list */ - dir->dir_next = NULL; - TALLOC_FREE(frame); - return 0; - } - - /* Now, run down the list and make sure that the entry is OK */ - /* This may need to be changed if we change the format of the list */ - - if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) { - errno = EINVAL; /* Bad entry */ - TALLOC_FREE(frame); - return -1; - } - - dir->dir_next = list_ent; - - TALLOC_FREE(frame); - return 0; -} - -/* - * Routine to fstat a dir - */ - -static int -smbc_fstatdir_ctx(SMBCCTX *context, - SMBCFILE *dir, - struct stat *st) -{ - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - return -1; - } - - /* No code yet ... */ - return 0; -} - -static int -smbc_chmod_ctx(SMBCCTX *context, - const char *fname, - mode_t newmode) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - uint16 mode; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - mode = 0; - - if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; - if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; - if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; - if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; - - if (!cli_setatr(srv->cli, path, mode, 0)) { - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return -1; - } - - TALLOC_FREE(frame); - return 0; -} - -static int -smbc_utimes_ctx(SMBCCTX *context, - const char *fname, - struct timeval *tbuf) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - time_t access_time; - time_t write_time; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (tbuf == NULL) { - access_time = write_time = time(NULL); - } else { - access_time = tbuf[0].tv_sec; - write_time = tbuf[1].tv_sec; - } - - if (DEBUGLVL(4)) { - char *p; - char atimebuf[32]; - char mtimebuf[32]; - - strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1); - atimebuf[sizeof(atimebuf) - 1] = '\0'; - if ((p = strchr(atimebuf, '\n')) != NULL) { - *p = '\0'; - } - - strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1); - mtimebuf[sizeof(mtimebuf) - 1] = '\0'; - if ((p = strchr(mtimebuf, '\n')) != NULL) { - *p = '\0'; - } - - dbgtext("smbc_utimes(%s, atime = %s mtime = %s)\n", - fname, atimebuf, mtimebuf); - } - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (!smbc_setatr(context, srv, path, - 0, access_time, write_time, 0, 0)) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_setatr */ - } - - TALLOC_FREE(frame); - return 0; -} - - -/* - * Sort ACEs according to the documentation at - * http://support.microsoft.com/kb/269175, at least as far as it defines the - * order. - */ - -static int -ace_compare(SEC_ACE *ace1, - SEC_ACE *ace2) -{ - bool b1; - bool b2; - - /* If the ACEs are equal, we have nothing more to do. */ - if (sec_ace_equal(ace1, ace2)) { - return 0; - } - - /* Inherited follow non-inherited */ - b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); - b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); - if (b1 != b2) { - return (b1 ? 1 : -1); - } - - /* - * What shall we do with AUDITs and ALARMs? It's undefined. We'll - * sort them after DENY and ALLOW. - */ - b1 = (ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED && - ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && - ace1->type != SEC_ACE_TYPE_ACCESS_DENIED && - ace1->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); - b2 = (ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED && - ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && - ace2->type != SEC_ACE_TYPE_ACCESS_DENIED && - ace2->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); - if (b1 != b2) { - return (b1 ? 1 : -1); - } - - /* Allowed ACEs follow denied ACEs */ - b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || - ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); - b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED || - ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); - if (b1 != b2) { - return (b1 ? 1 : -1); - } - - /* - * ACEs applying to an entity's object follow those applying to the - * entity itself - */ - b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || - ace1->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); - b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || - ace2->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); - if (b1 != b2) { - return (b1 ? 1 : -1); - } - - /* - * If we get this far, the ACEs are similar as far as the - * characteristics we typically care about (those defined by the - * referenced MS document). We'll now sort by characteristics that - * just seems reasonable. - */ - - if (ace1->type != ace2->type) { - return ace2->type - ace1->type; - } - - if (sid_compare(&ace1->trustee, &ace2->trustee)) { - return sid_compare(&ace1->trustee, &ace2->trustee); - } - - if (ace1->flags != ace2->flags) { - return ace1->flags - ace2->flags; - } - - if (ace1->access_mask != ace2->access_mask) { - return ace1->access_mask - ace2->access_mask; - } - - if (ace1->size != ace2->size) { - return ace1->size - ace2->size; - } - - return memcmp(ace1, ace2, sizeof(SEC_ACE)); -} - - -static void -sort_acl(SEC_ACL *the_acl) -{ - uint32 i; - if (!the_acl) return; - - qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), - QSORT_CAST ace_compare); - - for (i=1;i<the_acl->num_aces;) { - if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { - int j; - for (j=i; j<the_acl->num_aces-1; j++) { - the_acl->aces[j] = the_acl->aces[j+1]; - } - the_acl->num_aces--; - } else { - i++; - } - } -} - -/* convert a SID to a string, either numeric or username/group */ -static void -convert_sid_to_string(struct cli_state *ipc_cli, - POLICY_HND *pol, - fstring str, - bool numeric, - DOM_SID *sid) -{ - char **domains = NULL; - char **names = NULL; - enum lsa_SidType *types = NULL; - struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); - TALLOC_CTX *ctx; - - sid_to_fstring(str, sid); - - if (numeric) { - return; /* no lookup desired */ - } - - if (!pipe_hnd) { - return; - } - - /* Ask LSA to convert the sid to a name */ - - ctx = talloc_stackframe(); - - if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, - pol, 1, sid, &domains, - &names, &types)) || - !domains || !domains[0] || !names || !names[0]) { - TALLOC_FREE(ctx); - return; - } - - TALLOC_FREE(ctx); - /* Converted OK */ - - slprintf(str, sizeof(fstring) - 1, "%s%s%s", - domains[0], lp_winbind_separator(), - names[0]); -} - -/* convert a string to a SID, either numeric or username/group */ -static bool -convert_string_to_sid(struct cli_state *ipc_cli, - POLICY_HND *pol, - bool numeric, - DOM_SID *sid, - const char *str) -{ - enum lsa_SidType *types = NULL; - DOM_SID *sids = NULL; - bool result = True; - TALLOC_CTX *ctx = NULL; - struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); - - if (!pipe_hnd) { - return False; - } - - if (numeric) { - if (strncmp(str, "S-", 2) == 0) { - return string_to_sid(sid, str); - } - - result = False; - goto done; - } - - ctx = talloc_stackframe(); - if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, - pol, 1, &str, NULL, 1, &sids, - &types))) { - result = False; - goto done; - } - - sid_copy(sid, &sids[0]); - done: - - TALLOC_FREE(ctx); - return result; -} - - -/* parse an ACE in the same format as print_ace() */ -static bool -parse_ace(struct cli_state *ipc_cli, - POLICY_HND *pol, - SEC_ACE *ace, - bool numeric, - char *str) -{ - char *p; - const char *cp; - char *tok; - unsigned int atype; - unsigned int aflags; - unsigned int amask; - DOM_SID sid; - SEC_ACCESS mask; - const struct perm_value *v; - struct perm_value { - const char *perm; - uint32 mask; - }; - TALLOC_CTX *frame = talloc_stackframe(); - - /* These values discovered by inspection */ - static const struct perm_value special_values[] = { - { "R", 0x00120089 }, - { "W", 0x00120116 }, - { "X", 0x001200a0 }, - { "D", 0x00010000 }, - { "P", 0x00040000 }, - { "O", 0x00080000 }, - { NULL, 0 }, - }; - - static const struct perm_value standard_values[] = { - { "READ", 0x001200a9 }, - { "CHANGE", 0x001301bf }, - { "FULL", 0x001f01ff }, - { NULL, 0 }, - }; - - - ZERO_STRUCTP(ace); - p = strchr_m(str,':'); - if (!p) { - TALLOC_FREE(frame); - return False; - } - *p = '\0'; - p++; - /* Try to parse numeric form */ - - if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && - convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { - goto done; - } - - /* Try to parse text form */ - - if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { - TALLOC_FREE(frame); - return false; - } - - cp = p; - if (!next_token_talloc(frame, &cp, &tok, "/")) { - TALLOC_FREE(frame); - return false; - } - - if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { - atype = SEC_ACE_TYPE_ACCESS_ALLOWED; - } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { - atype = SEC_ACE_TYPE_ACCESS_DENIED; - } else { - TALLOC_FREE(frame); - return false; - } - - /* Only numeric form accepted for flags at present */ - - if (!(next_token_talloc(frame, &cp, &tok, "/") && - sscanf(tok, "%i", &aflags))) { - TALLOC_FREE(frame); - return false; - } - - if (!next_token_talloc(frame, &cp, &tok, "/")) { - TALLOC_FREE(frame); - return false; - } - - if (strncmp(tok, "0x", 2) == 0) { - if (sscanf(tok, "%i", &amask) != 1) { - TALLOC_FREE(frame); - return false; - } - goto done; - } - - for (v = standard_values; v->perm; v++) { - if (strcmp(tok, v->perm) == 0) { - amask = v->mask; - goto done; - } - } - - p = tok; - - while(*p) { - bool found = False; - - for (v = special_values; v->perm; v++) { - if (v->perm[0] == *p) { - amask |= v->mask; - found = True; - } - } - - if (!found) { - TALLOC_FREE(frame); - return false; - } - p++; - } - - if (*p) { - TALLOC_FREE(frame); - return false; - } - - done: - mask = amask; - init_sec_ace(ace, &sid, atype, mask, aflags); - TALLOC_FREE(frame); - return true; -} - -/* add an ACE to a list of ACEs in a SEC_ACL */ -static bool -add_ace(SEC_ACL **the_acl, - SEC_ACE *ace, - TALLOC_CTX *ctx) -{ - SEC_ACL *newacl; - SEC_ACE *aces; - - if (! *the_acl) { - (*the_acl) = make_sec_acl(ctx, 3, 1, ace); - return True; - } - - if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { - return False; - } - memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE)); - memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); - newacl = make_sec_acl(ctx, (*the_acl)->revision, - 1+(*the_acl)->num_aces, aces); - SAFE_FREE(aces); - (*the_acl) = newacl; - return True; -} - - -/* parse a ascii version of a security descriptor */ -static SEC_DESC * -sec_desc_parse(TALLOC_CTX *ctx, - struct cli_state *ipc_cli, - POLICY_HND *pol, - bool numeric, - char *str) -{ - const char *p = str; - char *tok; - SEC_DESC *ret = NULL; - size_t sd_size; - DOM_SID *group_sid=NULL; - DOM_SID *owner_sid=NULL; - SEC_ACL *dacl=NULL; - int revision=1; - - while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { - - if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { - revision = strtol(tok+9, NULL, 16); - continue; - } - - if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { - if (owner_sid) { - DEBUG(5, ("OWNER specified more than once!\n")); - goto done; - } - owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!owner_sid || - !convert_string_to_sid(ipc_cli, pol, - numeric, - owner_sid, tok+6)) { - DEBUG(5, ("Failed to parse owner sid\n")); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { - if (owner_sid) { - DEBUG(5, ("OWNER specified more than once!\n")); - goto done; - } - owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!owner_sid || - !convert_string_to_sid(ipc_cli, pol, - False, - owner_sid, tok+7)) { - DEBUG(5, ("Failed to parse owner sid\n")); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { - if (group_sid) { - DEBUG(5, ("GROUP specified more than once!\n")); - goto done; - } - group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!group_sid || - !convert_string_to_sid(ipc_cli, pol, - numeric, - group_sid, tok+6)) { - DEBUG(5, ("Failed to parse group sid\n")); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { - if (group_sid) { - DEBUG(5, ("GROUP specified more than once!\n")); - goto done; - } - group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!group_sid || - !convert_string_to_sid(ipc_cli, pol, - False, - group_sid, tok+6)) { - DEBUG(5, ("Failed to parse group sid\n")); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"ACL:", 4) == 0) { - SEC_ACE ace; - if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { - DEBUG(5, ("Failed to parse ACL %s\n", tok)); - goto done; - } - if(!add_ace(&dacl, &ace, ctx)) { - DEBUG(5, ("Failed to add ACL %s\n", tok)); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { - SEC_ACE ace; - if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { - DEBUG(5, ("Failed to parse ACL %s\n", tok)); - goto done; - } - if(!add_ace(&dacl, &ace, ctx)) { - DEBUG(5, ("Failed to add ACL %s\n", tok)); - goto done; - } - continue; - } - - DEBUG(5, ("Failed to parse security descriptor\n")); - goto done; - } - - ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, - owner_sid, group_sid, NULL, dacl, &sd_size); - - done: - SAFE_FREE(group_sid); - SAFE_FREE(owner_sid); - - return ret; -} - - -/* Obtain the current dos attributes */ -static DOS_ATTR_DESC * -dos_attr_query(SMBCCTX *context, - TALLOC_CTX *ctx, - const char *filename, - SMBCSRV *srv) -{ - struct timespec create_time_ts; - struct timespec write_time_ts; - struct timespec access_time_ts; - struct timespec change_time_ts; - SMB_OFF_T size = 0; - uint16 mode = 0; - SMB_INO_T inode = 0; - DOS_ATTR_DESC *ret; - - ret = TALLOC_P(ctx, DOS_ATTR_DESC); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - /* Obtain the DOS attributes */ - if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename), - &mode, &size, - &create_time_ts, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &inode)) { - errno = smbc_errno(context, srv->cli); - DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); - return NULL; - } - - ret->mode = mode; - ret->size = size; - ret->create_time = convert_timespec_to_time_t(create_time_ts); - ret->access_time = convert_timespec_to_time_t(access_time_ts); - ret->write_time = convert_timespec_to_time_t(write_time_ts); - ret->change_time = convert_timespec_to_time_t(change_time_ts); - ret->inode = inode; - - return ret; -} - - -/* parse a ascii version of a security descriptor */ -static void -dos_attr_parse(SMBCCTX *context, - DOS_ATTR_DESC *dad, - SMBCSRV *srv, - char *str) -{ - int n; - const char *p = str; - char *tok = NULL; - TALLOC_CTX *frame = NULL; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } attr_strings; - - /* Determine whether to use old-style or new-style attribute names */ - if (context->internal->_full_time_names) { - /* new-style names */ - attr_strings.create_time_attr = "CREATE_TIME"; - attr_strings.access_time_attr = "ACCESS_TIME"; - attr_strings.write_time_attr = "WRITE_TIME"; - attr_strings.change_time_attr = "CHANGE_TIME"; - } else { - /* old-style names */ - attr_strings.create_time_attr = NULL; - attr_strings.access_time_attr = "A_TIME"; - attr_strings.write_time_attr = "M_TIME"; - attr_strings.change_time_attr = "C_TIME"; - } - - /* if this is to set the entire ACL... */ - if (*str == '*') { - /* ... then increment past the first colon if there is one */ - if ((p = strchr(str, ':')) != NULL) { - ++p; - } else { - p = str; - } - } - - frame = talloc_stackframe(); - while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { - if (StrnCaseCmp(tok, "MODE:", 5) == 0) { - long request = strtol(tok+5, NULL, 16); - if (request == 0) { - dad->mode = (request | - (IS_DOS_DIR(dad->mode) - ? FILE_ATTRIBUTE_DIRECTORY - : FILE_ATTRIBUTE_NORMAL)); - } else { - dad->mode = request; - } - continue; - } - - if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { - dad->size = (SMB_OFF_T)atof(tok+5); - continue; - } - - n = strlen(attr_strings.access_time_attr); - if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { - dad->access_time = (time_t)strtol(tok+n+1, NULL, 10); - continue; - } - - n = strlen(attr_strings.change_time_attr); - if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { - dad->change_time = (time_t)strtol(tok+n+1, NULL, 10); - continue; - } - - n = strlen(attr_strings.write_time_attr); - if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { - dad->write_time = (time_t)strtol(tok+n+1, NULL, 10); - continue; - } - - if (attr_strings.create_time_attr != NULL) { - n = strlen(attr_strings.create_time_attr); - if (StrnCaseCmp(tok, attr_strings.create_time_attr, - n) == 0) { - dad->create_time = (time_t)strtol(tok+n+1, - NULL, 10); - continue; - } - } - - if (StrnCaseCmp(tok, "INODE:", 6) == 0) { - dad->inode = (SMB_INO_T)atof(tok+6); - continue; - } - } - TALLOC_FREE(frame); -} - -/***************************************************** - Retrieve the acls for a file. -*******************************************************/ - -static int -cacl_get(SMBCCTX *context, - TALLOC_CTX *ctx, - SMBCSRV *srv, - struct cli_state *ipc_cli, - POLICY_HND *pol, - char *filename, - char *attr_name, - char *buf, - int bufsize) -{ - uint32 i; - int n = 0; - int n_used; - bool all; - bool all_nt; - bool all_nt_acls; - bool all_dos; - bool some_nt; - bool some_dos; - bool exclude_nt_revision = False; - bool exclude_nt_owner = False; - bool exclude_nt_group = False; - bool exclude_nt_acl = False; - bool exclude_dos_mode = False; - bool exclude_dos_size = False; - bool exclude_dos_create_time = False; - bool exclude_dos_access_time = False; - bool exclude_dos_write_time = False; - bool exclude_dos_change_time = False; - bool exclude_dos_inode = False; - bool numeric = True; - bool determine_size = (bufsize == 0); - int fnum = -1; - SEC_DESC *sd; - fstring sidstr; - fstring name_sandbox; - char *name; - char *pExclude; - char *p; - struct timespec create_time_ts; - struct timespec write_time_ts; - struct timespec access_time_ts; - struct timespec change_time_ts; - time_t create_time = (time_t)0; - time_t write_time = (time_t)0; - time_t access_time = (time_t)0; - time_t change_time = (time_t)0; - SMB_OFF_T size = 0; - uint16 mode = 0; - SMB_INO_T ino = 0; - struct cli_state *cli = srv->cli; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } attr_strings; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } excl_attr_strings; - - /* Determine whether to use old-style or new-style attribute names */ - if (context->internal->_full_time_names) { - /* new-style names */ - attr_strings.create_time_attr = "CREATE_TIME"; - attr_strings.access_time_attr = "ACCESS_TIME"; - attr_strings.write_time_attr = "WRITE_TIME"; - attr_strings.change_time_attr = "CHANGE_TIME"; - - excl_attr_strings.create_time_attr = "CREATE_TIME"; - excl_attr_strings.access_time_attr = "ACCESS_TIME"; - excl_attr_strings.write_time_attr = "WRITE_TIME"; - excl_attr_strings.change_time_attr = "CHANGE_TIME"; - } else { - /* old-style names */ - attr_strings.create_time_attr = NULL; - attr_strings.access_time_attr = "A_TIME"; - attr_strings.write_time_attr = "M_TIME"; - attr_strings.change_time_attr = "C_TIME"; - - excl_attr_strings.create_time_attr = NULL; - excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; - excl_attr_strings.write_time_attr = "dos_attr.M_TIME"; - excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; - } - - /* Copy name so we can strip off exclusions (if any are specified) */ - strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); - - /* Ensure name is null terminated */ - name_sandbox[sizeof(name_sandbox) - 1] = '\0'; - - /* Play in the sandbox */ - name = name_sandbox; - - /* If there are any exclusions, point to them and mask them from name */ - if ((pExclude = strchr(name, '!')) != NULL) - { - *pExclude++ = '\0'; - } - - all = (StrnCaseCmp(name, "system.*", 8) == 0); - all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); - all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0); - all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0); - some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); - some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); - numeric = (* (name + strlen(name) - 1) != '+'); - - /* Look for exclusions from "all" requests */ - if (all || all_nt || all_dos) { - - /* Exclusions are delimited by '!' */ - for (; - pExclude != NULL; - pExclude = (p == NULL ? NULL : p + 1)) { - - /* Find end of this exclusion name */ - if ((p = strchr(pExclude, '!')) != NULL) - { - *p = '\0'; - } - - /* Which exclusion name is this? */ - if (StrCaseCmp(pExclude, "nt_sec_desc.revision") == 0) { - exclude_nt_revision = True; - } - else if (StrCaseCmp(pExclude, "nt_sec_desc.owner") == 0) { - exclude_nt_owner = True; - } - else if (StrCaseCmp(pExclude, "nt_sec_desc.group") == 0) { - exclude_nt_group = True; - } - else if (StrCaseCmp(pExclude, "nt_sec_desc.acl") == 0) { - exclude_nt_acl = True; - } - else if (StrCaseCmp(pExclude, "dos_attr.mode") == 0) { - exclude_dos_mode = True; - } - else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) { - exclude_dos_size = True; - } - else if (excl_attr_strings.create_time_attr != NULL && - StrCaseCmp(pExclude, - excl_attr_strings.change_time_attr) == 0) { - exclude_dos_create_time = True; - } - else if (StrCaseCmp(pExclude, - excl_attr_strings.access_time_attr) == 0) { - exclude_dos_access_time = True; - } - else if (StrCaseCmp(pExclude, - excl_attr_strings.write_time_attr) == 0) { - exclude_dos_write_time = True; - } - else if (StrCaseCmp(pExclude, - excl_attr_strings.change_time_attr) == 0) { - exclude_dos_change_time = True; - } - else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { - exclude_dos_inode = True; - } - else { - DEBUG(5, ("cacl_get received unknown exclusion: %s\n", - pExclude)); - errno = ENOATTR; - return -1; - } - } - } - - n_used = 0; - - /* - * If we are (possibly) talking to an NT or new system and some NT - * attributes have been requested... - */ - if (ipc_cli && (all || some_nt || all_nt_acls)) { - /* Point to the portion after "system.nt_sec_desc." */ - name += 19; /* if (all) this will be invalid but unused */ - - /* ... then obtain any NT attributes which were requested */ - fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - - if (fnum == -1) { - DEBUG(5, ("cacl_get failed to open %s: %s\n", - filename, cli_errstr(cli))); - errno = 0; - return -1; - } - - sd = cli_query_secdesc(cli, fnum, ctx); - - if (!sd) { - DEBUG(5, - ("cacl_get Failed to query old descriptor\n")); - errno = 0; - return -1; - } - - cli_close(cli, fnum); - - if (! exclude_nt_revision) { - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf(ctx, - "REVISION:%d", - sd->revision); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "REVISION:%d", - sd->revision); - } - } else if (StrCaseCmp(name, "revision") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%d", - sd->revision); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%d", - sd->revision); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_nt_owner) { - /* Get owner and group sid */ - if (sd->owner_sid) { - convert_sid_to_string(ipc_cli, pol, - sidstr, - numeric, - sd->owner_sid); - } else { - fstrcpy(sidstr, ""); - } - - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf(ctx, ",OWNER:%s", - sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else if (sidstr[0] != '\0') { - n = snprintf(buf, bufsize, - ",OWNER:%s", sidstr); - } - } else if (StrnCaseCmp(name, "owner", 5) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%s", - sidstr); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_nt_group) { - if (sd->group_sid) { - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, - sd->group_sid); - } else { - fstrcpy(sidstr, ""); - } - - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf(ctx, ",GROUP:%s", - sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else if (sidstr[0] != '\0') { - n = snprintf(buf, bufsize, - ",GROUP:%s", sidstr); - } - } else if (StrnCaseCmp(name, "group", 5) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%s", sidstr); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_nt_acl) { - /* Add aces to value buffer */ - for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { - - SEC_ACE *ace = &sd->dacl->aces[i]; - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, - &ace->trustee); - - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf( - ctx, - ",ACL:" - "%s:%d/%d/0x%08x", - sidstr, - ace->type, - ace->flags, - ace->access_mask); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf( - buf, bufsize, - ",ACL:%s:%d/%d/0x%08x", - sidstr, - ace->type, - ace->flags, - ace->access_mask); - } - } else if ((StrnCaseCmp(name, "acl", 3) == 0 && - StrCaseCmp(name+3, sidstr) == 0) || - (StrnCaseCmp(name, "acl+", 4) == 0 && - StrCaseCmp(name+4, sidstr) == 0)) { - if (determine_size) { - p = talloc_asprintf( - ctx, - "%d/%d/0x%08x", - ace->type, - ace->flags, - ace->access_mask); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%d/%d/0x%08x", - ace->type, - ace->flags, - ace->access_mask); - } - } else if (all_nt_acls) { - if (determine_size) { - p = talloc_asprintf( - ctx, - "%s%s:%d/%d/0x%08x", - i ? "," : "", - sidstr, - ace->type, - ace->flags, - ace->access_mask); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%s%s:%d/%d/0x%08x", - i ? "," : "", - sidstr, - ace->type, - ace->flags, - ace->access_mask); - } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - } - - /* Restore name pointer to its original value */ - name -= 19; - } - - if (all || some_dos) { - /* Point to the portion after "system.dos_attr." */ - name += 16; /* if (all) this will be invalid but unused */ - - /* Obtain the DOS attributes */ - if (!smbc_getatr(context, srv, filename, &mode, &size, - &create_time_ts, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &ino)) { - - errno = smbc_errno(context, srv->cli); - return -1; - - } - - create_time = convert_timespec_to_time_t(create_time_ts); - access_time = convert_timespec_to_time_t(access_time_ts); - write_time = convert_timespec_to_time_t(write_time_ts); - change_time = convert_timespec_to_time_t(change_time_ts); - - if (! exclude_dos_mode) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - "%sMODE:0x%x", - (ipc_cli && - (all || some_nt) - ? "," - : ""), - mode); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%sMODE:0x%x", - (ipc_cli && - (all || some_nt) - ? "," - : ""), - mode); - } - } else if (StrCaseCmp(name, "mode") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "0x%x", mode); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "0x%x", mode); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_size) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf( - ctx, - ",SIZE:%.0f", - (double)size); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",SIZE:%.0f", - (double)size); - } - } else if (StrCaseCmp(name, "size") == 0) { - if (determine_size) { - p = talloc_asprintf( - ctx, - "%.0f", - (double)size); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%.0f", - (double)size); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_create_time && - attr_strings.create_time_attr != NULL) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",%s:%lu", - attr_strings.create_time_attr, - create_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",%s:%lu", - attr_strings.create_time_attr, - create_time); - } - } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", create_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%lu", create_time); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_access_time) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",%s:%lu", - attr_strings.access_time_attr, - access_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",%s:%lu", - attr_strings.access_time_attr, - access_time); - } - } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", access_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%lu", access_time); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_write_time) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",%s:%lu", - attr_strings.write_time_attr, - write_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",%s:%lu", - attr_strings.write_time_attr, - write_time); - } - } else if (StrCaseCmp(name, attr_strings.write_time_attr) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", write_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%lu", write_time); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_change_time) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",%s:%lu", - attr_strings.change_time_attr, - change_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",%s:%lu", - attr_strings.change_time_attr, - change_time); - } - } else if (StrCaseCmp(name, attr_strings.change_time_attr) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", change_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%lu", change_time); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_inode) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf( - ctx, - ",INODE:%.0f", - (double)ino); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",INODE:%.0f", - (double) ino); - } - } else if (StrCaseCmp(name, "inode") == 0) { - if (determine_size) { - p = talloc_asprintf( - ctx, - "%.0f", - (double) ino); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%.0f", - (double) ino); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - /* Restore name pointer to its original value */ - name -= 16; - } - - if (n_used == 0) { - errno = ENOATTR; - return -1; - } - - return n_used; -} - -/***************************************************** -set the ACLs on a file given an ascii description -*******************************************************/ -static int -cacl_set(TALLOC_CTX *ctx, - struct cli_state *cli, - struct cli_state *ipc_cli, - POLICY_HND *pol, - const char *filename, - const char *the_acl, - int mode, - int flags) -{ - int fnum; - int err = 0; - SEC_DESC *sd = NULL, *old; - SEC_ACL *dacl = NULL; - DOM_SID *owner_sid = NULL; - DOM_SID *group_sid = NULL; - uint32 i, j; - size_t sd_size; - int ret = 0; - char *p; - bool numeric = True; - - /* the_acl will be null for REMOVE_ALL operations */ - if (the_acl) { - numeric = ((p = strchr(the_acl, ':')) != NULL && - p > the_acl && - p[-1] != '+'); - - /* if this is to set the entire ACL... */ - if (*the_acl == '*') { - /* ... then increment past the first colon */ - the_acl = p + 1; - } - - sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, - CONST_DISCARD(char *, the_acl)); - - if (!sd) { - errno = EINVAL; - return -1; - } - } - - /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller - that doesn't deref sd */ - - if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { - errno = EINVAL; - return -1; - } - - /* The desired access below is the only one I could find that works - with NT4, W2KP and Samba */ - - fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - - if (fnum == -1) { - DEBUG(5, ("cacl_set failed to open %s: %s\n", - filename, cli_errstr(cli))); - errno = 0; - return -1; - } - - old = cli_query_secdesc(cli, fnum, ctx); - - if (!old) { - DEBUG(5, ("cacl_set Failed to query old descriptor\n")); - errno = 0; - return -1; - } - - cli_close(cli, fnum); - - switch (mode) { - case SMBC_XATTR_MODE_REMOVE_ALL: - old->dacl->num_aces = 0; - dacl = old->dacl; - break; - - case SMBC_XATTR_MODE_REMOVE: - for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { - bool found = False; - - for (j=0;old->dacl && j<old->dacl->num_aces;j++) { - if (sec_ace_equal(&sd->dacl->aces[i], - &old->dacl->aces[j])) { - uint32 k; - for (k=j; k<old->dacl->num_aces-1;k++) { - old->dacl->aces[k] = - old->dacl->aces[k+1]; - } - old->dacl->num_aces--; - found = True; - dacl = old->dacl; - break; - } - } - - if (!found) { - err = ENOATTR; - ret = -1; - goto failed; - } - } - break; - - case SMBC_XATTR_MODE_ADD: - for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { - bool found = False; - - for (j=0;old->dacl && j<old->dacl->num_aces;j++) { - if (sid_equal(&sd->dacl->aces[i].trustee, - &old->dacl->aces[j].trustee)) { - if (!(flags & SMBC_XATTR_FLAG_CREATE)) { - err = EEXIST; - ret = -1; - goto failed; - } - old->dacl->aces[j] = sd->dacl->aces[i]; - ret = -1; - found = True; - } - } - - if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { - err = ENOATTR; - ret = -1; - goto failed; - } - - for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) { - add_ace(&old->dacl, &sd->dacl->aces[i], ctx); - } - } - dacl = old->dacl; - break; - - case SMBC_XATTR_MODE_SET: - old = sd; - owner_sid = old->owner_sid; - group_sid = old->group_sid; - dacl = old->dacl; - break; - - case SMBC_XATTR_MODE_CHOWN: - owner_sid = sd->owner_sid; - break; - - case SMBC_XATTR_MODE_CHGRP: - group_sid = sd->group_sid; - break; - } - - /* Denied ACE entries must come before allowed ones */ - sort_acl(old->dacl); - - /* Create new security descriptor and set it */ - sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, - owner_sid, group_sid, NULL, dacl, &sd_size); - - fnum = cli_nt_create(cli, filename, - WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS); - - if (fnum == -1) { - DEBUG(5, ("cacl_set failed to open %s: %s\n", - filename, cli_errstr(cli))); - errno = 0; - return -1; - } - - if (!cli_set_secdesc(cli, fnum, sd)) { - DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli))); - ret = -1; - } - - /* Clean up */ - - failed: - cli_close(cli, fnum); - - if (err != 0) { - errno = err; - } - - return ret; -} - - -static int -smbc_setxattr_ctx(SMBCCTX *context, - const char *fname, - const char *name, - const void *value, - size_t size, - int flags) -{ - int ret; - int ret2; - SMBCSRV *srv = NULL; - SMBCSRV *ipc_srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - DOS_ATTR_DESC *dad = NULL; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } attr_strings; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", - fname, name, (int) size, (const char*)value)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (! srv->no_nt_session) { - ipc_srv = smbc_attr_server(frame, context, server, share, - &workgroup, &user, &password); - if (! ipc_srv) { - srv->no_nt_session = True; - } - } else { - ipc_srv = NULL; - } - - /* - * Are they asking to set the entire set of known attributes? - */ - if (StrCaseCmp(name, "system.*") == 0 || - StrCaseCmp(name, "system.*+") == 0) { - /* Yup. */ - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+7, (const char *) value); - if (! namevalue) { - errno = ENOMEM; - ret = -1; - TALLOC_FREE(frame); - return -1; - } - - if (ipc_srv) { - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - namevalue, - (*namevalue == '*' - ? SMBC_XATTR_MODE_SET - : SMBC_XATTR_MODE_ADD), - flags); - } else { - ret = 0; - } - - /* get a DOS Attribute Descriptor with current attributes */ - dad = dos_attr_query(context, talloc_tos(), path, srv); - if (dad) { - /* Overwrite old with new, using what was provided */ - dos_attr_parse(context, dad, srv, namevalue); - - /* Set the new DOS attributes */ - if (! smbc_setatr(context, srv, path, - dad->create_time, - dad->access_time, - dad->write_time, - dad->change_time, - dad->mode)) { - - /* cause failure if NT failed too */ - dad = NULL; - } - } - - /* we only fail if both NT and DOS sets failed */ - if (ret < 0 && ! dad) { - ret = -1; /* in case dad was null */ - } - else { - ret = 0; - } - - TALLOC_FREE(frame); - return ret; - } - - /* - * Are they asking to set an access control element or to set - * the entire access control list? - */ - if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { - - /* Yup. */ - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+19, (const char *) value); - - if (! ipc_srv) { - ret = -1; /* errno set by smbc_server() */ - } - else if (! namevalue) { - errno = ENOMEM; - ret = -1; - } else { - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - namevalue, - (*namevalue == '*' - ? SMBC_XATTR_MODE_SET - : SMBC_XATTR_MODE_ADD), - flags); - } - TALLOC_FREE(frame); - return ret; - } - - /* - * Are they asking to set the owner? - */ - if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { - - /* Yup. */ - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+19, (const char *) value); - - if (! ipc_srv) { - ret = -1; /* errno set by smbc_server() */ - } - else if (! namevalue) { - errno = ENOMEM; - ret = -1; - } else { - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - namevalue, SMBC_XATTR_MODE_CHOWN, 0); - } - TALLOC_FREE(frame); - return ret; - } - - /* - * Are they asking to set the group? - */ - if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { - - /* Yup. */ - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+19, (const char *) value); - - if (! ipc_srv) { - /* errno set by smbc_server() */ - ret = -1; - } - else if (! namevalue) { - errno = ENOMEM; - ret = -1; - } else { - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - namevalue, SMBC_XATTR_MODE_CHGRP, 0); - } - TALLOC_FREE(frame); - return ret; - } - - /* Determine whether to use old-style or new-style attribute names */ - if (context->internal->_full_time_names) { - /* new-style names */ - attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; - attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; - attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; - attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; - } else { - /* old-style names */ - attr_strings.create_time_attr = NULL; - attr_strings.access_time_attr = "system.dos_attr.A_TIME"; - attr_strings.write_time_attr = "system.dos_attr.M_TIME"; - attr_strings.change_time_attr = "system.dos_attr.C_TIME"; - } - - /* - * Are they asking to set a DOS attribute? - */ - if (StrCaseCmp(name, "system.dos_attr.*") == 0 || - StrCaseCmp(name, "system.dos_attr.mode") == 0 || - (attr_strings.create_time_attr != NULL && - StrCaseCmp(name, attr_strings.create_time_attr) == 0) || - StrCaseCmp(name, attr_strings.access_time_attr) == 0 || - StrCaseCmp(name, attr_strings.write_time_attr) == 0 || - StrCaseCmp(name, attr_strings.change_time_attr) == 0) { - - /* get a DOS Attribute Descriptor with current attributes */ - dad = dos_attr_query(context, talloc_tos(), path, srv); - if (dad) { - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+16, (const char *) value); - if (! namevalue) { - errno = ENOMEM; - ret = -1; - } else { - /* Overwrite old with provided new params */ - dos_attr_parse(context, dad, srv, namevalue); - - /* Set the new DOS attributes */ - ret2 = smbc_setatr(context, srv, path, - dad->create_time, - dad->access_time, - dad->write_time, - dad->change_time, - dad->mode); - - /* ret2 has True (success) / False (failure) */ - if (ret2) { - ret = 0; - } else { - ret = -1; - } - } - } else { - ret = -1; - } - - TALLOC_FREE(frame); - return ret; - } - - /* Unsupported attribute name */ - errno = EINVAL; - TALLOC_FREE(frame); - return -1; -} - -static int -smbc_getxattr_ctx(SMBCCTX *context, - const char *fname, - const char *name, - const void *value, - size_t size) -{ - int ret; - SMBCSRV *srv = NULL; - SMBCSRV *ipc_srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } attr_strings; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (! srv->no_nt_session) { - ipc_srv = smbc_attr_server(frame, context, server, share, - &workgroup, &user, &password); - if (! ipc_srv) { - srv->no_nt_session = True; - } - } else { - ipc_srv = NULL; - } - - /* Determine whether to use old-style or new-style attribute names */ - if (context->internal->_full_time_names) { - /* new-style names */ - attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; - attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; - attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; - attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; - } else { - /* old-style names */ - attr_strings.create_time_attr = NULL; - attr_strings.access_time_attr = "system.dos_attr.A_TIME"; - attr_strings.write_time_attr = "system.dos_attr.M_TIME"; - attr_strings.change_time_attr = "system.dos_attr.C_TIME"; - } - - /* Are they requesting a supported attribute? */ - if (StrCaseCmp(name, "system.*") == 0 || - StrnCaseCmp(name, "system.*!", 9) == 0 || - StrCaseCmp(name, "system.*+") == 0 || - StrnCaseCmp(name, "system.*+!", 10) == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 || - StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 || - StrCaseCmp(name, "system.dos_attr.*") == 0 || - StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 || - StrCaseCmp(name, "system.dos_attr.mode") == 0 || - StrCaseCmp(name, "system.dos_attr.size") == 0 || - (attr_strings.create_time_attr != NULL && - StrCaseCmp(name, attr_strings.create_time_attr) == 0) || - StrCaseCmp(name, attr_strings.access_time_attr) == 0 || - StrCaseCmp(name, attr_strings.write_time_attr) == 0 || - StrCaseCmp(name, attr_strings.change_time_attr) == 0 || - StrCaseCmp(name, "system.dos_attr.inode") == 0) { - - /* Yup. */ - ret = cacl_get(context, talloc_tos(), srv, - ipc_srv == NULL ? NULL : ipc_srv->cli, - &ipc_srv->pol, path, - CONST_DISCARD(char *, name), - CONST_DISCARD(char *, value), size); - if (ret < 0 && errno == 0) { - errno = smbc_errno(context, srv->cli); - } - TALLOC_FREE(frame); - return ret; - } - - /* Unsupported attribute name */ - errno = EINVAL; - TALLOC_FREE(frame); - return -1; -} - - -static int -smbc_removexattr_ctx(SMBCCTX *context, - const char *fname, - const char *name) -{ - int ret; - SMBCSRV *srv = NULL; - SMBCSRV *ipc_srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (! srv->no_nt_session) { - ipc_srv = smbc_attr_server(frame, context, server, share, - &workgroup, &user, &password); - if (! ipc_srv) { - srv->no_nt_session = True; - } - } else { - ipc_srv = NULL; - } - - if (! ipc_srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_attr_server */ - } - - /* Are they asking to set the entire ACL? */ - if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { - - /* Yup. */ - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); - TALLOC_FREE(frame); - return ret; - } - - /* - * Are they asking to remove one or more spceific security descriptor - * attributes? - */ - if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { - - /* Yup. */ - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - name + 19, SMBC_XATTR_MODE_REMOVE, 0); - TALLOC_FREE(frame); - return ret; - } - - /* Unsupported attribute name */ - errno = EINVAL; - TALLOC_FREE(frame); - return -1; -} - -static int -smbc_listxattr_ctx(SMBCCTX *context, - const char *fname, - char *list, - size_t size) -{ - /* - * This isn't quite what listxattr() is supposed to do. This returns - * the complete set of attribute names, always, rather than only those - * attribute names which actually exist for a file. Hmmm... - */ - size_t retsize; - const char supported_old[] = - "system.*\0" - "system.*+\0" - "system.nt_sec_desc.revision\0" - "system.nt_sec_desc.owner\0" - "system.nt_sec_desc.owner+\0" - "system.nt_sec_desc.group\0" - "system.nt_sec_desc.group+\0" - "system.nt_sec_desc.acl.*\0" - "system.nt_sec_desc.acl\0" - "system.nt_sec_desc.acl+\0" - "system.nt_sec_desc.*\0" - "system.nt_sec_desc.*+\0" - "system.dos_attr.*\0" - "system.dos_attr.mode\0" - "system.dos_attr.c_time\0" - "system.dos_attr.a_time\0" - "system.dos_attr.m_time\0" - ; - const char supported_new[] = - "system.*\0" - "system.*+\0" - "system.nt_sec_desc.revision\0" - "system.nt_sec_desc.owner\0" - "system.nt_sec_desc.owner+\0" - "system.nt_sec_desc.group\0" - "system.nt_sec_desc.group+\0" - "system.nt_sec_desc.acl.*\0" - "system.nt_sec_desc.acl\0" - "system.nt_sec_desc.acl+\0" - "system.nt_sec_desc.*\0" - "system.nt_sec_desc.*+\0" - "system.dos_attr.*\0" - "system.dos_attr.mode\0" - "system.dos_attr.create_time\0" - "system.dos_attr.access_time\0" - "system.dos_attr.write_time\0" - "system.dos_attr.change_time\0" - ; - const char * supported; - - if (context->internal->_full_time_names) { - supported = supported_new; - retsize = sizeof(supported_new); - } else { - supported = supported_old; - retsize = sizeof(supported_old); - } - - if (size == 0) { - return retsize; - } - - if (retsize > size) { - errno = ERANGE; - return -1; - } - - /* this can't be strcpy() because there are embedded null characters */ - memcpy(list, supported, retsize); - return retsize; -} - - -/* - * Open a print file to be written to by other calls - */ - -static SMBCFILE * -smbc_open_print_job_ctx(SMBCCTX *context, - const char *fname) -{ - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *path = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - } - - DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - } - - /* What if the path is empty, or the file exists? */ - - TALLOC_FREE(frame); - return (context->open)(context, fname, O_WRONLY, 666); -} - -/* - * Routine to print a file on a remote server ... - * - * We open the file, which we assume to be on a remote server, and then - * copy it to a print file on the share specified by printq. - */ - -static int -smbc_print_file_ctx(SMBCCTX *c_file, - const char *fname, - SMBCCTX *c_print, - const char *printq) -{ - SMBCFILE *fid1; - SMBCFILE *fid2; - int bytes; - int saverr; - int tot_bytes = 0; - char buf[4096]; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!c_file || !c_file->internal->_initialized || !c_print || - !c_print->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (!fname && !printq) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - /* Try to open the file for reading ... */ - - if ((long)(fid1 = (c_file->open)(c_file, fname, O_RDONLY, 0666)) < 0) { - DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); - TALLOC_FREE(frame); - return -1; /* smbc_open sets errno */ - } - - /* Now, try to open the printer file for writing */ - - if ((long)(fid2 = (c_print->open_print_job)(c_print, printq)) < 0) { - - saverr = errno; /* Save errno */ - (c_file->close_fn)(c_file, fid1); - errno = saverr; - TALLOC_FREE(frame); - return -1; - - } - - while ((bytes = (c_file->read)(c_file, fid1, buf, sizeof(buf))) > 0) { - - tot_bytes += bytes; - - if (((c_print->write)(c_print, fid2, buf, bytes)) < 0) { - - saverr = errno; - (c_file->close_fn)(c_file, fid1); - (c_print->close_fn)(c_print, fid2); - errno = saverr; - - } - - } - - saverr = errno; - - (c_file->close_fn)(c_file, fid1); /* We have to close these anyway */ - (c_print->close_fn)(c_print, fid2); - - if (bytes < 0) { - - errno = saverr; - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return tot_bytes; - -} - -/* - * Routine to list print jobs on a printer share ... - */ - -static int -smbc_list_print_jobs_ctx(SMBCCTX *context, - const char *fname, - smbc_list_print_job_fn fn) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (cli_print_queue(srv->cli, - (void (*)(struct print_job_info *))fn) < 0) { - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return -1; - } - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Delete a print job from a remote printer share - */ - -static int -smbc_unlink_print_job_ctx(SMBCCTX *context, - const char *fname, - int id) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - int err; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - - } - - if ((err = cli_printjob_del(srv->cli, id)) != 0) { - - if (err < 0) - errno = smbc_errno(context, srv->cli); - else if (err == ERRnosuchprintjob) - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Get a new empty handle to fill in with your own info - */ -SMBCCTX * -smbc_new_context(void) -{ - SMBCCTX *context; - - context = SMB_MALLOC_P(SMBCCTX); - if (!context) { - errno = ENOMEM; - return NULL; - } - - ZERO_STRUCTP(context); - - context->internal = SMB_MALLOC_P(struct smbc_internal_data); - if (!context->internal) { - SAFE_FREE(context); - errno = ENOMEM; - return NULL; - } - - ZERO_STRUCTP(context->internal); - - /* ADD REASONABLE DEFAULTS */ - context->debug = 0; - context->timeout = 20000; /* 20 seconds */ - - context->options.browse_max_lmb_count = 3; /* # LMBs to query */ - context->options.urlencode_readdir_entries = False;/* backward compat */ - context->options.one_share_per_server = False;/* backward compat */ - context->internal->_share_mode = SMBC_SHAREMODE_DENY_NONE; - /* backward compat */ - - context->open = smbc_open_ctx; - context->creat = smbc_creat_ctx; - context->read = smbc_read_ctx; - context->write = smbc_write_ctx; - context->close_fn = smbc_close_ctx; - context->unlink = smbc_unlink_ctx; - context->rename = smbc_rename_ctx; - context->lseek = smbc_lseek_ctx; - context->stat = smbc_stat_ctx; - context->fstat = smbc_fstat_ctx; - context->opendir = smbc_opendir_ctx; - context->closedir = smbc_closedir_ctx; - context->readdir = smbc_readdir_ctx; - context->getdents = smbc_getdents_ctx; - context->mkdir = smbc_mkdir_ctx; - context->rmdir = smbc_rmdir_ctx; - context->telldir = smbc_telldir_ctx; - context->lseekdir = smbc_lseekdir_ctx; - context->fstatdir = smbc_fstatdir_ctx; - context->chmod = smbc_chmod_ctx; - context->utimes = smbc_utimes_ctx; - context->setxattr = smbc_setxattr_ctx; - context->getxattr = smbc_getxattr_ctx; - context->removexattr = smbc_removexattr_ctx; - context->listxattr = smbc_listxattr_ctx; - context->open_print_job = smbc_open_print_job_ctx; - context->print_file = smbc_print_file_ctx; - context->list_print_jobs = smbc_list_print_jobs_ctx; - context->unlink_print_job = smbc_unlink_print_job_ctx; - - context->callbacks.check_server_fn = smbc_check_server; - context->callbacks.remove_unused_server_fn = smbc_remove_unused_server; - - smbc_default_cache_functions(context); - - return context; -} - -/* - * Free a context - * - * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed - * and thus you'll be leaking memory if not handled properly. - * - */ -int -smbc_free_context(SMBCCTX *context, - int shutdown_ctx) -{ - if (!context) { - errno = EBADF; - return 1; - } - - if (shutdown_ctx) { - SMBCFILE * f; - DEBUG(1,("Performing aggressive shutdown.\n")); - - f = context->internal->_files; - while (f) { - (context->close_fn)(context, f); - f = f->next; - } - context->internal->_files = NULL; - - /* First try to remove the servers the nice way. */ - if (context->callbacks.purge_cached_fn(context)) { - SMBCSRV * s; - SMBCSRV * next; - DEBUG(1, ("Could not purge all servers, " - "Nice way shutdown failed.\n")); - s = context->internal->_servers; - while (s) { - DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", - s, s->cli->fd)); - cli_shutdown(s->cli); - (context->callbacks.remove_cached_srv_fn)(context, - s); - next = s->next; - DLIST_REMOVE(context->internal->_servers, s); - SAFE_FREE(s); - s = next; - } - context->internal->_servers = NULL; - } - } - else { - /* This is the polite way */ - if ((context->callbacks.purge_cached_fn)(context)) { - DEBUG(1, ("Could not purge all servers, " - "free_context failed.\n")); - errno = EBUSY; - return 1; - } - if (context->internal->_servers) { - DEBUG(1, ("Active servers in context, " - "free_context failed.\n")); - errno = EBUSY; - return 1; - } - if (context->internal->_files) { - DEBUG(1, ("Active files in context, " - "free_context failed.\n")); - errno = EBUSY; - return 1; - } - } - - /* Things we have to clean up */ - SAFE_FREE(context->workgroup); - SAFE_FREE(context->netbios_name); - SAFE_FREE(context->user); - - DEBUG(3, ("Context %p successfully freed\n", context)); - SAFE_FREE(context->internal); - SAFE_FREE(context); - return 0; -} - - -/* - * Each time the context structure is changed, we have binary backward - * compatibility issues. Instead of modifying the public portions of the - * context structure to add new options, instead, we put them in the internal - * portion of the context structure and provide a set function for these new - * options. - */ -void -smbc_option_set(SMBCCTX *context, - char *option_name, - ... /* option_value */) -{ - va_list ap; - union { - int i; - bool b; - smbc_get_auth_data_with_context_fn auth_fn; - void *v; - const char *s; - } option_value; - - va_start(ap, option_name); - - if (strcmp(option_name, "debug_to_stderr") == 0) { - /* - * Log to standard error instead of standard output. - */ - option_value.b = (bool) va_arg(ap, int); - context->internal->_debug_stderr = option_value.b; - - } else if (strcmp(option_name, "full_time_names") == 0) { - /* - * Use new-style time attribute names, e.g. WRITE_TIME rather - * than the old-style names such as M_TIME. This allows also - * setting/getting CREATE_TIME which was previously - * unimplemented. (Note that the old C_TIME was supposed to - * be CHANGE_TIME but was confused and sometimes referred to - * CREATE_TIME.) - */ - option_value.b = (bool) va_arg(ap, int); - context->internal->_full_time_names = option_value.b; - - } else if (strcmp(option_name, "open_share_mode") == 0) { - /* - * The share mode to use for files opened with - * smbc_open_ctx(). The default is SMBC_SHAREMODE_DENY_NONE. - */ - option_value.i = va_arg(ap, int); - context->internal->_share_mode = - (smbc_share_mode) option_value.i; - - } else if (strcmp(option_name, "auth_function") == 0) { - /* - * Use the new-style authentication function which includes - * the context. - */ - option_value.auth_fn = - va_arg(ap, smbc_get_auth_data_with_context_fn); - context->internal->_auth_fn_with_context = - option_value.auth_fn; - } else if (strcmp(option_name, "user_data") == 0) { - /* - * Save a user data handle which may be retrieved by the user - * with smbc_option_get() - */ - option_value.v = va_arg(ap, void *); - context->internal->_user_data = option_value.v; - } else if (strcmp(option_name, "smb_encrypt_level") == 0) { - /* - * Save an encoded value for encryption level. - * 0 = off, 1 = attempt, 2 = required. - */ - option_value.s = va_arg(ap, const char *); - if (strcmp(option_value.s, "none") == 0) { - context->internal->_smb_encryption_level = 0; - } else if (strcmp(option_value.s, "request") == 0) { - context->internal->_smb_encryption_level = 1; - } else if (strcmp(option_value.s, "require") == 0) { - context->internal->_smb_encryption_level = 2; - } - } - - va_end(ap); -} - - -/* - * Retrieve the current value of an option - */ -void * -smbc_option_get(SMBCCTX *context, - char *option_name) -{ - if (strcmp(option_name, "debug_stderr") == 0) { - /* - * Log to standard error instead of standard output. - */ -#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->_debug_stderr; -#else - return (void *) context->internal->_debug_stderr; -#endif - } else if (strcmp(option_name, "full_time_names") == 0) { - /* - * Use new-style time attribute names, e.g. WRITE_TIME rather - * than the old-style names such as M_TIME. This allows also - * setting/getting CREATE_TIME which was previously - * unimplemented. (Note that the old C_TIME was supposed to - * be CHANGE_TIME but was confused and sometimes referred to - * CREATE_TIME.) - */ -#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->_full_time_names; -#else - return (void *) context->internal->_full_time_names; -#endif - - } else if (strcmp(option_name, "auth_function") == 0) { - /* - * Use the new-style authentication function which includes - * the context. - */ - return (void *) context->internal->_auth_fn_with_context; - } else if (strcmp(option_name, "user_data") == 0) { - /* - * Save a user data handle which may be retrieved by the user - * with smbc_option_get() - */ - return context->internal->_user_data; - } else if (strcmp(option_name, "smb_encrypt_level") == 0) { - /* - * Return the current smb encrypt negotiate option as a string. - */ - switch (context->internal->_smb_encryption_level) { - case 0: - return (void *) "none"; - case 1: - return (void *) "request"; - case 2: - return (void *) "require"; - } - } else if (strcmp(option_name, "smb_encrypt_on") == 0) { - /* - * Return the current smb encrypt status option as a bool. - * false = off, true = on. We don't know what server is - * being requested, so we only return true if all servers - * are using an encrypted connection. - */ - SMBCSRV *s; - unsigned int num_servers = 0; - - for (s = context->internal->_servers; s; s = s->next) { - num_servers++; - if (s->cli->trans_enc_state == NULL) { - return (void *)false; - } - } - return (void *) (bool) (num_servers > 0); - } - - return NULL; -} - - -/* - * Initialise the library etc - * - * We accept a struct containing handle information. - * valid values for info->debug from 0 to 100, - * and insist that info->fn must be non-null. - */ -SMBCCTX * -smbc_init_context(SMBCCTX *context) -{ - int pid; - char *user = NULL; - char *home = NULL; - - if (!context || !context->internal) { - errno = EBADF; - return NULL; - } - - /* Do not initialise the same client twice */ - if (context->internal->_initialized) { - return 0; - } - - if ((!context->callbacks.auth_fn && - !context->internal->_auth_fn_with_context) || - context->debug < 0 || - context->debug > 100) { - - errno = EINVAL; - return NULL; - - } - - if (!smbc_initialized) { - /* - * Do some library-wide intializations the first time we get - * called - */ - bool conf_loaded = False; - TALLOC_CTX *frame = talloc_stackframe(); - - /* Set this to what the user wants */ - DEBUGLEVEL = context->debug; - - load_case_tables(); - - setup_logging("libsmbclient", True); - if (context->internal->_debug_stderr) { - dbf = x_stderr; - x_setbuf(x_stderr, NULL); - } - - /* Here we would open the smb.conf file if needed ... */ - - in_client = True; /* FIXME, make a param */ - - home = getenv("HOME"); - if (home) { - char *conf = NULL; - if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) { - if (lp_load(conf, True, False, False, True)) { - conf_loaded = True; - } else { - DEBUG(5, ("Could not load config file: %s\n", - conf)); - } - SAFE_FREE(conf); - } - } - - if (!conf_loaded) { - /* - * Well, if that failed, try the get_dyn_CONFIGFILE - * Which points to the standard locn, and if that - * fails, silently ignore it and use the internal - * defaults ... - */ - - if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) { - DEBUG(5, ("Could not load config file: %s\n", - get_dyn_CONFIGFILE())); - } else if (home) { - char *conf; - /* - * We loaded the global config file. Now lets - * load user-specific modifications to the - * global config. - */ - if (asprintf(&conf, - "%s/.smb/smb.conf.append", - home) > 0) { - if (!lp_load(conf, True, False, False, False)) { - DEBUG(10, - ("Could not append config file: " - "%s\n", - conf)); - } - SAFE_FREE(conf); - } - } - } - - load_interfaces(); /* Load the list of interfaces ... */ - - reopen_logs(); /* Get logging working ... */ - - /* - * Block SIGPIPE (from lib/util_sock.c: write()) - * It is not needed and should not stop execution - */ - BlockSignals(True, SIGPIPE); - - /* Done with one-time initialisation */ - smbc_initialized = 1; - - TALLOC_FREE(frame); - } - - if (!context->user) { - /* - * FIXME: Is this the best way to get the user info? - */ - user = getenv("USER"); - /* walk around as "guest" if no username can be found */ - if (!user) context->user = SMB_STRDUP("guest"); - else context->user = SMB_STRDUP(user); - } - - if (!context->netbios_name) { - /* - * We try to get our netbios name from the config. If that - * fails we fall back on constructing our netbios name from - * our hostname etc - */ - if (global_myname()) { - context->netbios_name = SMB_STRDUP(global_myname()); - } - else { - /* - * Hmmm, I want to get hostname as well, but I am too - * lazy for the moment - */ - pid = sys_getpid(); - context->netbios_name = (char *)SMB_MALLOC(17); - if (!context->netbios_name) { - errno = ENOMEM; - return NULL; - } - slprintf(context->netbios_name, 16, - "smbc%s%d", context->user, pid); - } - } - - DEBUG(1, ("Using netbios name %s.\n", context->netbios_name)); - - if (!context->workgroup) { - if (lp_workgroup()) { - context->workgroup = SMB_STRDUP(lp_workgroup()); - } - else { - /* TODO: Think about a decent default workgroup */ - context->workgroup = SMB_STRDUP("samba"); - } - } - - DEBUG(1, ("Using workgroup %s.\n", context->workgroup)); - - /* shortest timeout is 1 second */ - if (context->timeout > 0 && context->timeout < 1000) - context->timeout = 1000; - - /* - * FIXME: Should we check the function pointers here? - */ - - context->internal->_initialized = True; - - return context; -} - - -/* Return the verion of samba, and thus libsmbclient */ -const char * -smbc_version(void) -{ - return samba_version_string(); -} diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 35c20ed647..7082ea7e4e 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -566,13 +566,16 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname = get_mydnsdomname(ntlmssp_state->mem_ctx); if (!dnsdomname) { - return NT_STATUS_BAD_NETWORK_NAME; + dnsdomname = talloc_strdup(ntlmssp_state->mem_ctx, ""); + } + if (!dnsdomname) { + return NT_STATUS_NO_MEMORY; } strlower_m(dnsdomname); dnsname = get_mydnsfullname(); - if (!dnsdomname) { - return NT_STATUS_INVALID_COMPUTER_NAME; + if (!dnsname) { + dnsname = ""; } /* This creates the 'blob' of names that appears at the end of the packet */ diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 4f791f66f6..73b570c383 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -1,21 +1,22 @@ -/* +/* Unix SMB/CIFS implementation. Net_sam_logon info3 helpers Copyright (C) Alexander Bokovoy 2002. Copyright (C) Andrew Bartlett 2002. Copyright (C) Gerald Carter 2003. Copyright (C) Tim Potter 2003. - + Copyright (C) Guenther Deschner 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/>. */ @@ -29,12 +30,12 @@ static TDB_CONTEXT *netsamlogon_tdb = NULL; /*********************************************************************** open the tdb ***********************************************************************/ - + bool netsamlogon_cache_init(void) { if (!netsamlogon_tdb) { netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0, - TDB_DEFAULT, O_RDWR | O_CREAT, 0600); + TDB_DEFAULT, O_RDWR | O_CREAT, 0600); } return (netsamlogon_tdb != NULL); @@ -47,37 +48,39 @@ bool netsamlogon_cache_init(void) bool netsamlogon_cache_shutdown(void) { - if(netsamlogon_tdb) + if (netsamlogon_tdb) { return (tdb_close(netsamlogon_tdb) == 0); - - return True; + } + + return true; } /*********************************************************************** Clear cache getpwnam and getgroups entries from the winbindd cache ***********************************************************************/ -void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) + +void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, struct netr_SamInfo3 *info3) { - bool got_tdb = False; + bool got_tdb = false; DOM_SID sid; fstring key_str, sid_string; /* We may need to call this function from smbd which will not have - winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ + winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ if (!tdb) { - tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), + tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, TDB_DEFAULT, O_RDWR, 0600); if (!tdb) { DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n")); return; } - got_tdb = True; + got_tdb = true; } - sid_copy(&sid, &user->dom_sid.sid); - sid_append_rid(&sid, user->user_rid); + sid_copy(&sid, info3->base.domain_sid); + sid_append_rid(&sid, info3->base.rid); /* Clear U/SID cache entry */ @@ -95,157 +98,178 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) tdb_delete(tdb, string_tdb_data(key_str)); - if (got_tdb) + if (got_tdb) { tdb_close(tdb); + } } /*********************************************************************** - Store a NET_USER_INFO_3 structure in a tdb for later user + Store a netr_SamInfo3 structure in a tdb for later user username should be in UTF-8 format ***********************************************************************/ -bool netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) +bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3) { - TDB_DATA data; - fstring keystr, tmp; - prs_struct ps; - bool result = False; - DOM_SID user_sid; - time_t t = time(NULL); - TALLOC_CTX *mem_ctx; - + TDB_DATA data; + fstring keystr, tmp; + bool result = false; + DOM_SID user_sid; + time_t t = time(NULL); + TALLOC_CTX *mem_ctx; + DATA_BLOB blob; + enum ndr_err_code ndr_err; + struct netsamlogoncache_entry r; + + if (!info3) { + return false; + } if (!netsamlogon_cache_init()) { - DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); - return False; + DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", + NETSAMLOGON_TDB)); + return false; } - sid_copy( &user_sid, &user->dom_sid.sid ); - sid_append_rid( &user_sid, user->user_rid ); + sid_copy(&user_sid, info3->base.domain_sid); + sid_append_rid(&user_sid, info3->base.rid); /* Prepare key as DOMAIN-SID/USER-RID string */ slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid)); DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); - + + /* Prepare data */ + + if (!(mem_ctx = TALLOC_P( NULL, int))) { + DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n")); + return false; + } + /* only Samba fills in the username, not sure why NT doesn't */ /* so we fill it in since winbindd_getpwnam() makes use of it */ - - if ( !user->uni_user_name.buffer ) { - init_unistr2( &user->uni_user_name, username, UNI_STR_TERMINATE ); - init_uni_hdr( &user->hdr_user_name, &user->uni_user_name ); + + if (!info3->base.account_name.string) { + info3->base.account_name.string = talloc_strdup(mem_ctx, username); } - - /* Prepare data */ - - if ( !(mem_ctx = TALLOC_P( NULL, int )) ) { - DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n")); - return False; + + r.timestamp = t; + r.info3 = *info3; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(netsamlogoncache_entry, &r); } - prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - - { - uint32 ts = (uint32)t; - if ( !prs_uint32( "timestamp", &ps, 0, &ts ) ) - return False; + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &r, + (ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0,("netsamlogon_cache_store: failed to push entry to cache\n")); + TALLOC_FREE(mem_ctx); + return false; } - - if ( net_io_user_info3("", user, &ps, 0, 3, 0) ) - { - data.dsize = prs_offset( &ps ); - data.dptr = (uint8 *)prs_data_p( &ps ); - if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) - result = True; - - prs_mem_free( &ps ); + data.dsize = blob.length; + data.dptr = blob.data; + + if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) { + result = true; } - TALLOC_FREE( mem_ctx ); - + TALLOC_FREE(mem_ctx); + return result; } /*********************************************************************** - Retrieves a NET_USER_INFO_3 structure from a tdb. Caller must + Retrieves a netr_SamInfo3 structure from a tdb. Caller must free the user_info struct (malloc()'d memory) ***********************************************************************/ -NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) +struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) { - NET_USER_INFO_3 *user = NULL; - TDB_DATA data; - prs_struct ps; - fstring keystr, tmp; - uint32 t; - + struct netr_SamInfo3 *info3 = NULL; + TDB_DATA data; + fstring keystr, tmp; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct netsamlogoncache_entry r; + if (!netsamlogon_cache_init()) { - DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n", NETSAMLOGON_TDB)); - return False; + DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n", + NETSAMLOGON_TDB)); + return false; } /* Prepare key as DOMAIN-SID/USER-RID string */ slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, user_sid)); DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr)); data = tdb_fetch_bystring( netsamlogon_tdb, keystr ); - - if ( data.dptr ) { - user = TALLOC_ZERO_P(mem_ctx, NET_USER_INFO_3); - if (user == NULL) { - return NULL; - } + if (!data.dptr) { + return NULL; + } - prs_init( &ps, 0, mem_ctx, UNMARSHALL ); - prs_give_memory( &ps, (char *)data.dptr, data.dsize, True ); - - if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) { - prs_mem_free( &ps ); - TALLOC_FREE(user); - return False; - } - - if ( !net_io_user_info3("", user, &ps, 0, 3, 0) ) { - TALLOC_FREE( user ); - } - - prs_mem_free( &ps ); + info3 = TALLOC_ZERO_P(mem_ctx, struct netr_SamInfo3); + if (!info3) { + goto done; + } + + blob.data = (uint8 *)data.dptr; + blob.length = data.dsize; + + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, + (ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry); -#if 0 /* The netsamlogon cache needs to hang around. Something about + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(netsamlogoncache_entry, &r); + } + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0,("netsamlogon_cache_get: failed to pull entry from cache\n")); + tdb_delete(netsamlogon_tdb, data); + TALLOC_FREE(info3); + goto done; + } + + info3 = (struct netr_SamInfo3 *)talloc_memdup(mem_ctx, &r.info3, + sizeof(r.info3)); + + done: + SAFE_FREE(data.dptr); + + return info3; + +#if 0 /* The netsamlogon cache needs to hang around. Something about this feels wrong, but it is the only way we can get all of the groups. The old universal groups cache didn't expire either. --jerry */ { time_t now = time(NULL); uint32 time_diff; - + /* is the entry expired? */ time_diff = now - t; - + if ( (time_diff < 0 ) || (time_diff > lp_winbind_cache_time()) ) { DEBUG(10,("netsamlogon_cache_get: cache entry expired \n")); tdb_delete( netsamlogon_tdb, key ); TALLOC_FREE( user ); } -#endif } - - return user; +#endif } bool netsamlogon_cache_have(const DOM_SID *user_sid) { TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); - NET_USER_INFO_3 *user = NULL; + struct netr_SamInfo3 *info3 = NULL; bool result; if (!mem_ctx) return False; - user = netsamlogon_cache_get(mem_ctx, user_sid); + info3 = netsamlogon_cache_get(mem_ctx, user_sid); - result = (user != NULL); + result = (info3 != NULL); talloc_destroy(mem_ctx); diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index b5befbf7cd..a81ae9afd5 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -483,15 +483,15 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. ******************************************************************************/ -NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) +NTSTATUS cli_encrypt_message(struct cli_state *cli, char *buf, char **buf_out) { /* Ignore non-session messages. */ - if(CVAL(cli->outbuf,0)) { + if (CVAL(buf,0)) { return NT_STATUS_OK; } /* If we supported multiple encrytion contexts * here we'd look up based on tid. */ - return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); + return common_encrypt_buffer(cli->trans_enc_state, buf, buf_out); } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index f03c21bd0e..bd6d97123d 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -573,9 +573,9 @@ void cli_free_signing_context(struct cli_state *cli) * Sign a packet with the current mechanism */ -void cli_calculate_sign_mac(struct cli_state *cli) +void cli_calculate_sign_mac(struct cli_state *cli, char *buf) { - cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); + cli->sign_info.sign_outgoing_message(buf, &cli->sign_info); } /** @@ -584,9 +584,9 @@ void cli_calculate_sign_mac(struct cli_state *cli) * which had a bad checksum, True otherwise. */ -bool cli_check_sign_mac(struct cli_state *cli) +bool cli_check_sign_mac(struct cli_state *cli, char *buf) { - if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { + if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); return False; } diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 11f691bee6..c079fb149a 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -58,7 +58,32 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX } } - result = rpccli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); + { + struct netr_Authenticator clnt_creds, srv_cred; + struct samr_Password new_password; + + netlogon_creds_client_step(cli->dc, &clnt_creds); + + cred_hash3(new_password.hash, + new_trust_passwd_hash, + cli->dc->sess_key, 1); + + result = rpccli_netr_ServerPasswordSet(cli, mem_ctx, + cli->dc->remote_machine, + cli->dc->mach_acct, + sec_channel_type, + global_myname(), + &clnt_creds, + &srv_cred, + &new_password); + + /* Always check returned credentials. */ + if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { + DEBUG(0,("rpccli_netr_ServerPasswordSet: " + "credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + } if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", @@ -184,7 +209,7 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* get a handle */ result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True, - POLICY_VIEW_LOCAL_INFORMATION, &pol); + LSA_POLICY_VIEW_LOCAL_INFORMATION, &pol); if ( !NT_STATUS_IS_OK(result) ) goto done; diff --git a/source3/m4/aclocal.m4 b/source3/m4/aclocal.m4 index fd9efb60e6..888c49db37 100644 --- a/source3/m4/aclocal.m4 +++ b/source3/m4/aclocal.m4 @@ -53,6 +53,73 @@ AC_DEFUN(SMB_SUBSYSTEM, ifelse([$2], , :, [rm -f $2]) ]) + +dnl SMB_LIBRARY(name) +dnl +dnl configure build and use of an (internal) shared library +dnl +AC_DEFUN([SMB_LIBRARY], +[ +m4_pushdef([LIBNAME], [lib$1]) +m4_pushdef([LIBUC], [m4_toupper(LIBNAME)]) +m4_pushdef([LIBLIBS], [-l$1]) + +LIBUC[_SHARED_TARGET]=bin/LIBNAME.$SHLIBEXT +LIBUC[_STATIC_TARGET]=bin/LIBNAME.a +LIBUC[_SHARED]= +LIBUC[_STATIC]= +LIBUC[_LIBS]= + +AC_SUBST(LIBUC[_SHARED_TARGET]) +AC_SUBST(LIBUC[_STATIC_TARGET]) +AC_SUBST(LIBUC[_SHARED]) +AC_SUBST(LIBUC[_STATIC]) +AC_SUBST(LIBUC[_LIBS]) + +AC_MSG_CHECKING([whether to build the LIBNAME shared library]) +AC_ARG_WITH(LIBNAME, +[AS_HELP_STRING([--with-LIBNAME], + [Build the LIBNAME shared library (default=yes if shared libs supported)])], +[ +case "$withval" in + *) + AC_MSG_RESULT(no) + build_lib=no + ;; + yes) + build_lib=yes + ;; +esac +], +[ +# if unspecified, default is to build it if possible. +build_lib=yes +] +) + +if eval test x"$build_lib" = "xyes" -a $BLDSHARED = true; then + LIBUC[_SHARED]=$LIBUC[_SHARED_TARGET] + AC_MSG_RESULT(yes) + if test x"$USESHARED" != x"true" -o x"$LINK_LIBUC" = "xSTATIC" ; then + LIBUC[_STATIC]=$LIBUC[_STATIC_TARGET] + else + LIBUC[_LIBS]=LIBLIBS + fi +else + enable_static=yes + AC_MSG_RESULT(no shared library support -- will supply static library) +fi +if test $enable_static = yes; then + LIBUC[_STATIC]=$LIBUC[_STATIC_TARGET] +fi + +m4_popdef([LIBNAME]) +m4_popdef([LIBUC]) +m4_popdef([LIBLIBS]) + +]) + + dnl AC_LIBTESTFUNC(lib, function, [actions if found], [actions if not found]) dnl Check for a function in a library, but don't keep adding the same library dnl to the LIBS variable. Check whether the function is available in the diff --git a/source3/m4/check_gnu_make.m4 b/source3/m4/check_gnu_make.m4 deleted file mode 100644 index 44e1d9aa20..0000000000 --- a/source3/m4/check_gnu_make.m4 +++ /dev/null @@ -1,78 +0,0 @@ -##### http://autoconf-archive.cryp.to/check_gnu_make.html -# -# SYNOPSIS -# -# CHECK_GNU_MAKE() -# -# DESCRIPTION -# -# This macro searches for a GNU version of make. If a match is found, -# the makefile variable `ifGNUmake' is set to the empty string, -# otherwise it is set to "#". This is useful for including a special -# features in a Makefile, which cannot be handled by other versions -# of make. The variable _cv_gnu_make_command is set to the command to -# invoke GNU make if it exists, the empty string otherwise. -# -# Here is an example of its use: -# -# Makefile.in might contain: -# -# # A failsafe way of putting a dependency rule into a makefile -# $(DEPEND): -# $(CC) -MM $(srcdir)/*.c > $(DEPEND) -# -# @ifGNUmake@ ifeq ($(DEPEND),$(wildcard $(DEPEND))) -# @ifGNUmake@ include $(DEPEND) -# @ifGNUmake@ endif -# -# Then configure.in would normally contain: -# -# CHECK_GNU_MAKE() -# AC_OUTPUT(Makefile) -# -# Then perhaps to cause gnu make to override any other make, we could -# do something like this (note that GNU make always looks for -# GNUmakefile first): -# -# if ! test x$_cv_gnu_make_command = x ; then -# mv Makefile GNUmakefile -# echo .DEFAULT: > Makefile ; -# echo \ $_cv_gnu_make_command \$@ >> Makefile; -# fi -# -# Then, if any (well almost any) other make is called, and GNU make -# also exists, then the other make wraps the GNU make. -# -# LAST MODIFICATION -# -# 2002-01-04 -# -# COPYLEFT -# -# Copyright (c) 2002 John Darrington <j.darrington@elvis.murdoch.edu.au> -# -# Copying and distribution of this file, with or without -# modification, are permitted in any medium without royalty provided -# the copyright notice and this notice are preserved. - -AC_DEFUN( - [CHECK_GNU_MAKE], [ AC_CACHE_CHECK( for GNU make,_cv_gnu_make_command, - _cv_gnu_make_command='' ; -dnl Search all the common names for GNU make - for a in "$MAKE" make gmake gnumake ; do - if test -z "$a" ; then continue ; fi ; - if ( sh -c "$a --version" 2> /dev/null | grep GNU 2>&1 > /dev/null ) ; then - _cv_gnu_make_command=$a ; - break; - fi - done ; - ) ; -dnl If there was a GNU version, then set @ifGNUmake@ to the empty string, '#' otherwise - if test "x$_cv_gnu_make_command" != "x" ; then - ifGNUmake='' ; - else - ifGNUmake='#' ; - AC_MSG_RESULT("Not found"); - fi - AC_SUBST(ifGNUmake) -] ) diff --git a/source3/m4/check_path.m4 b/source3/m4/check_path.m4 new file mode 100644 index 0000000000..ccf21271c8 --- /dev/null +++ b/source3/m4/check_path.m4 @@ -0,0 +1,316 @@ +dnl +dnl Samba3 build environment path checks +dnl +dnl Copyright (C) Michael Adam 2008 +dnl +dnl Released under the GNU General Public License +dnl http://www.gnu.org/licenses/ +dnl + +AC_LIBREPLACE_LOCATION_CHECKS + +################################################# +# Directory handling stuff to support both the +# legacy SAMBA directories and FHS compliant +# ones... +AC_PREFIX_DEFAULT(/usr/local/samba) + +rootsbindir="\${SBINDIR}" +lockdir="\${VARDIR}/locks" +piddir="\${VARDIR}/locks" +test "${mandir}" || mandir="\${prefix}/man" +logfilebase="\${VARDIR}" +privatedir="\${prefix}/private" +test "${libdir}" || libdir="\${prefix}/lib" +pammodulesdir="\${LIBDIR}/security" +configdir="\${LIBDIR}" +swatdir="\${prefix}/swat" +codepagedir="\${LIBDIR}" +statedir="\${LOCKDIR}" +cachedir="\${LOCKDIR}" + +AC_ARG_WITH(fhs, +[AS_HELP_STRING([--with-fhs],[Use FHS-compliant paths (default=no)])], +[ case "$withval" in + yes) + lockdir="\${VARDIR}/lib/samba" + piddir="\${VARDIR}/run" + mandir="\${prefix}/share/man" + logfilebase="\${VARDIR}/log/samba" + privatedir="\${CONFIGDIR}/private" + test "${libdir}" || libdir="\${prefix}/lib/samba" + configdir="\${sysconfdir}/samba" + swatdir="\${DATADIR}/samba/swat" + codepagedir="\${LIBDIR}" + statedir="\${VARDIR}/lib/samba" + cachedir="\${VARDIR}/lib/samba" + AC_DEFINE(FHS_COMPATIBLE, 1, [Whether to use fully FHS-compatible paths]) + ;; + esac]) + +################################################# +# set private directory location +AC_ARG_WITH(privatedir, +[AS_HELP_STRING([--with-privatedir=DIR], [Where to put smbpasswd ($ac_default_prefix/private)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-privatedir called without argument - will use default]) + ;; + * ) + privatedir="$withval" + ;; + esac]) + +################################################# +# set root sbin directory location +AC_ARG_WITH(rootsbindir, +[AS_HELP_STRING([--with-rootsbindir=DIR], [Which directory to use for root sbin ($ac_default_prefix/sbin)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-rootsbindir called without argument - will use default]) + ;; + * ) + rootsbindir="$withval" + ;; + esac]) + +################################################# +# set lock directory location +AC_ARG_WITH(lockdir, +[AS_HELP_STRING([--with-lockdir=DIR], [Where to put lock files ($ac_default_prefix/var/locks)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-lockdir called without argument - will use default]) + ;; + * ) + lockdir="$withval" + ;; + esac]) + +################################################# +# set pid directory location +AC_ARG_WITH(piddir, +[AS_HELP_STRING([--with-piddir=DIR], [Where to put pid files ($ac_default_prefix/var/locks)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-piddir called without argument - will use default]) + ;; + * ) + piddir="$withval" + ;; + esac]) + +################################################# +# set SWAT directory location +AC_ARG_WITH(swatdir, +[AS_HELP_STRING([--with-swatdir=DIR], [Where to put SWAT files ($ac_default_prefix/swat)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody does it + # + AC_MSG_WARN([--with-swatdir called without argument - will use default]) + ;; + * ) + swatdir="$withval" + ;; + esac]) + +################################################# +# set configuration directory location +AC_ARG_WITH(configdir, +[AS_HELP_STRING([--with-configdir=DIR], [Where to put configuration files ($libdir)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody does it + # + AC_MSG_WARN([--with-configdir called without argument - will use default]) + ;; + * ) + configdir="$withval" + ;; + esac]) + +################################################# +# set log directory location +AC_ARG_WITH(logfilebase, +[AS_HELP_STRING([--with-logfilebase=DIR], [Where to put log files ($VARDIR)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody does it + # + AC_MSG_WARN([--with-logfilebase called without argument - will use default]) + ;; + * ) + logfilebase="$withval" + ;; + esac]) + + +################################################# +# set ctdb source directory location +AC_ARG_WITH(ctdb, +[AS_HELP_STRING([--with-ctdb=DIR], [Where to find ctdb sources])], +[ case "$withval" in + yes|no) + AC_MSG_WARN([--with-ctdb called without argument]) + ;; + * ) + ctdbdir="$withval" + ;; + esac]) + +################################################# +# set lib directory location +AC_ARG_WITH(libdir, +[AS_HELP_STRING([--with-libdir=DIR], [Where to put libdir ($libdir)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody does it + # + AC_MSG_WARN([--with-libdir without argument - will use default]) + ;; + * ) + libdir="$withval" + ;; + esac]) + +################################################# +# set PAM modules directory location +AC_ARG_WITH(pammodulesdir, +[AS_HELP_STRING([--with-pammodulesdir=DIR], [Which directory to use for PAM modules ($ac_default_prefix/$libdir/security)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody calls it without argument + # + AC_MSG_WARN([--with-pammodulesdir called without argument - will use default]) + ;; + * ) + pammodulesdir="$withval" + ;; + esac]) + +################################################# +# set man directory location +AC_ARG_WITH(mandir, +[AS_HELP_STRING([--with-mandir=DIR], [Where to put man pages ($mandir)])], +[ case "$withval" in + yes|no) + # + # Just in case anybody does it + # + AC_MSG_WARN([--with-mandir without argument - will use default]) + ;; + * ) + mandir="$withval" + ;; + esac]) + +AC_SUBST(configdir) +AC_SUBST(lockdir) +AC_SUBST(piddir) +AC_SUBST(logfilebase) +AC_SUBST(ctdbdir) +AC_SUBST(privatedir) +AC_SUBST(swatdir) +AC_SUBST(bindir) +AC_SUBST(sbindir) +AC_SUBST(codepagedir) +AC_SUBST(statedir) +AC_SUBST(cachedir) +AC_SUBST(rootsbindir) +AC_SUBST(pammodulesdir) + +################################################# +# set prefix for 'make test' +selftest_prefix="./st" +AC_SUBST(selftest_prefix) +AC_ARG_WITH(selftest-prefix, +[AS_HELP_STRING([--with-selftest-prefix=DIR], [The prefix where make test will be run ($selftest_prefix)])], +[ case "$withval" in + yes|no) + AC_MSG_WARN([--with-selftest-prefix called without argument - will use default]) + ;; + * ) + selftest_prefix="$withval" + ;; + esac +]) + +################################################# +# set path of samba4's smbtorture +smbtorture4_path="" +AC_SUBST(smbtorture4_path) +AC_ARG_WITH(smbtorture4_path, +[AS_HELP_STRING([--with-smbtorture4-path=PATH], [The path to a samba4 smbtorture for make test (none)])], +[ case "$withval" in + yes|no) + AC_MSG_ERROR([--with-smbtorture4-path should take a path]) + ;; + * ) + smbtorture4_path="$withval" + if test -z "$smbtorture4_path" -a ! -f $smbtorture4_path; then + AC_MSG_ERROR(['$smbtorture_path' does not exist!]) + fi + ;; + esac +]) + +## check for --enable-debug first before checking CFLAGS before +## so that we don't mix -O and -g +debug=no +AC_ARG_ENABLE(debug, +[AS_HELP_STRING([--enable-debug], [Turn on compiler debugging information (default=no)])], + [if eval "test x$enable_debug = xyes"; then + debug=yes + fi]) + +developer=no +AC_ARG_ENABLE(developer, [AS_HELP_STRING([--enable-developer], [Turn on developer warnings and debugging (default=no)])], + [if eval "test x$enable_developer = xyes"; then + debug=yes + developer=yes + fi]) + +krb5developer=no +AC_ARG_ENABLE(krb5developer, [AS_HELP_STRING([--enable-krb5developer], [Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)])], + [if eval "test x$enable_krb5developer = xyes"; then + debug=yes + developer=yes + krb5_developer=yes + fi]) + +AC_ARG_WITH(cfenc, +[AS_HELP_STRING([--with-cfenc=HEADERDIR], [Use internal CoreFoundation encoding API for optimization (Mac OS X/Darwin only)])], +[ +# May be in source $withval/CoreFoundation/StringEncodings.subproj. +# Should have been in framework $withval/CoreFoundation.framework/Headers. +for d in \ + $withval/CoreFoundation/StringEncodings.subproj \ + $withval/StringEncodings.subproj \ + $withval/CoreFoundation.framework/Headers \ + $withval/Headers \ + $withval +do + if test -r $d/CFStringEncodingConverter.h; then + ln -sfh $d include/CoreFoundation + fi +done +]) + diff --git a/source3/m4/cond.m4 b/source3/m4/cond.m4 deleted file mode 100644 index d9a58d2f39..0000000000 --- a/source3/m4/cond.m4 +++ /dev/null @@ -1,34 +0,0 @@ -# AM_CONDITIONAL -*- Autoconf -*- - -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 8 - -# AM_CONDITIONAL(NAME, SHELL-CONDITION) -# ------------------------------------- -# Define a conditional. -AC_DEFUN([AM_CONDITIONAL], -[AC_PREREQ(2.52)dnl - ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], - [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl -AC_SUBST([$1_TRUE])dnl -AC_SUBST([$1_FALSE])dnl -_AM_SUBST_NOTMAKE([$1_TRUE])dnl -_AM_SUBST_NOTMAKE([$1_FALSE])dnl -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi -AC_CONFIG_COMMANDS_PRE( -[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) -fi])]) diff --git a/source3/m4/depend.m4 b/source3/m4/depend.m4 deleted file mode 100644 index fd0937330d..0000000000 --- a/source3/m4/depend.m4 +++ /dev/null @@ -1,158 +0,0 @@ -## -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 9 - -# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be -# written in clear, in which case automake, when reading aclocal.m4, -# will think it sees a *use*, and therefore will trigger all it's -# C support machinery. Also note that it means that autoscan, seeing -# CC etc. in the Makefile, will ask for an AC_PROG_CC use... - - -# _AM_DEPENDENCIES(NAME) -# ---------------------- -# See how the compiler implements dependency checking. -# NAME is "CC", "CXX", "GCJ", or "OBJC". -# We try a few techniques and use that to set a single cache variable. -# -# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was -# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular -# dependency, and given that the user is not expected to run this macro, -# just rely on AC_PROG_CC. -AC_DEFUN([_AM_DEPENDENCIES], -[AC_REQUIRE([AM_SET_DEPDIR])dnl -AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl -AC_REQUIRE([AM_MAKE_INCLUDE])dnl -AC_REQUIRE([AM_DEP_TRACK])dnl - -ifelse([$1], CC, [depcc="$CC" am_compiler_list=], - [$1], CXX, [depcc="$CXX" am_compiler_list=], - [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], - [$1], UPC, [depcc="$UPC" am_compiler_list=], - [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], - [depcc="$$1" am_compiler_list=]) - -AC_CACHE_CHECK([dependency style of $depcc], - [am_cv_$1_dependencies_compiler_type], -[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_$1_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` - fi - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - case $depmode in - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - none) break ;; - esac - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. - if depmode=$depmode \ - source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_$1_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_$1_dependencies_compiler_type=none -fi -]) -AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) -AM_CONDITIONAL([am__fastdep$1], [ - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) -]) - - -# AM_SET_DEPDIR -# ------------- -# Choose a directory name for dependency files. -# This macro is AC_REQUIREd in _AM_DEPENDENCIES -AC_DEFUN([AM_SET_DEPDIR], -[AC_REQUIRE([AM_SET_LEADING_DOT])dnl -AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl -]) - - -# AM_DEP_TRACK -# ------------ -AC_DEFUN([AM_DEP_TRACK], -[AC_ARG_ENABLE(dependency-tracking, -[ --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors]) -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' -fi -AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) -AC_SUBST([AMDEPBACKSLASH])dnl -_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl -]) diff --git a/source3/m4/depout.m4 b/source3/m4/depout.m4 deleted file mode 100644 index 0d9717a100..0000000000 --- a/source3/m4/depout.m4 +++ /dev/null @@ -1,68 +0,0 @@ -# Generate code to set up dependency tracking. -*- Autoconf -*- - -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -#serial 3 - -# _AM_OUTPUT_DEPENDENCY_COMMANDS -# ------------------------------ -AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], -[for mf in $CONFIG_FILES; do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named `Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # When using ansi2knr, U may be empty or an underscore; expand it - U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done -done -])# _AM_OUTPUT_DEPENDENCY_COMMANDS - - -# AM_OUTPUT_DEPENDENCY_COMMANDS -# ----------------------------- -# This macro should only be invoked once -- use via AC_REQUIRE. -# -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each `.P' file that we will -# need in order to bootstrap the dependency handling code. -AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], -[AC_CONFIG_COMMANDS([depfiles], - [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) diff --git a/source3/m4/lead-dot.m4 b/source3/m4/lead-dot.m4 deleted file mode 100644 index d83bfa0b08..0000000000 --- a/source3/m4/lead-dot.m4 +++ /dev/null @@ -1,21 +0,0 @@ -## -*- Autoconf -*- -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# Check whether the underlying file-system supports filenames -# with a leading dot. For instance MS-DOS doesn't. -AC_DEFUN([AM_SET_LEADING_DOT], -[rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null -AC_SUBST([am__leading_dot])]) diff --git a/source3/m4/make.m4 b/source3/m4/make.m4 deleted file mode 100644 index 0969d9a795..0000000000 --- a/source3/m4/make.m4 +++ /dev/null @@ -1,51 +0,0 @@ -# Check to see how 'make' treats includes. -*- Autoconf -*- - -# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 3 - -# AM_MAKE_INCLUDE() -# ----------------- -# Check to see how make treats includes. -AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo done -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# We grep out `Entering directory' and `Leaving directory' -# messages which can occur if `w' ends up in MAKEFLAGS. -# In particular we don't look at `^make:' because GNU make might -# be invoked under some other name (usually "gmake"), in which -# case it prints its new name instead of `make'. -if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then - am__include=include - am__quote= - _am_result=GNU -fi -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then - am__include=.include - am__quote="\"" - _am_result=BSD - fi -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) diff --git a/source3/m4/samba_version.m4 b/source3/m4/samba_version.m4 new file mode 100644 index 0000000000..4d749e9bb9 --- /dev/null +++ b/source3/m4/samba_version.m4 @@ -0,0 +1,29 @@ +dnl +dnl Samba3 build environment - Samba version variables +dnl +dnl Copyright (C) Michael Adam 2008 +dnl +dnl Released under the GNU General Public License +dnl http://www.gnu.org/licenses/ +dnl +dnl + +SMB_VERSION_STRING=`cat $srcdir/include/version.h | grep 'SAMBA_VERSION_OFFICIAL_STRING' | cut -d '"' -f2` +echo "SAMBA VERSION: ${SMB_VERSION_STRING}" + +SAMBA_VERSION_GIT_COMMIT_FULLREV=`cat $srcdir/include/version.h | grep 'SAMBA_VERSION_GIT_COMMIT_FULLREV' | cut -d ' ' -f3- | cut -d '"' -f2` +if test -n "${SAMBA_VERSION_GIT_COMMIT_FULLREV}";then + echo "BUILD COMMIT REVISION: ${SAMBA_VERSION_GIT_COMMIT_FULLREV}" +fi +SAMBA_VERSION_GIT_COMMIT_DATE=`cat $srcdir/include/version.h | grep 'SAMBA_VERSION_GIT_COMMIT_DATE' | cut -d ' ' -f3-` +if test -n "${SAMBA_VERSION_GIT_COMMIT_DATE}";then + echo "BUILD COMMIT DATE: ${SAMBA_VERSION_GIT_COMMIT_DATE}" +fi +SAMBA_VERSION_GIT_COMMIT_TIME=`cat $srcdir/include/version.h | grep 'SAMBA_VERSION_GIT_COMMIT_TIME' | cut -d ' ' -f3-` +if test -n "${SAMBA_VERSION_GIT_COMMIT_TIME}";then + echo "BUILD COMMIT TIME: ${SAMBA_VERSION_GIT_COMMIT_TIME}" + + # just to keep the build-farm gui happy for now... + echo "BUILD REVISION: ${SAMBA_VERSION_GIT_COMMIT_TIME}" +fi + diff --git a/source3/m4/substnot.m4 b/source3/m4/substnot.m4 deleted file mode 100644 index 27d3f1fbef..0000000000 --- a/source3/m4/substnot.m4 +++ /dev/null @@ -1,12 +0,0 @@ -## -*- Autoconf -*- -# Copyright (C) 2006 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# _AM_SUBST_NOTMAKE(VARIABLE) -# --------------------------- -# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. -# This macro is traced by Automake. -AC_DEFUN([_AM_SUBST_NOTMAKE]) diff --git a/source3/m4/swat.m4 b/source3/m4/swat.m4 new file mode 100644 index 0000000000..2fdd82eda2 --- /dev/null +++ b/source3/m4/swat.m4 @@ -0,0 +1,27 @@ +dnl +dnl Samba3 build environment SWAT configuration +dnl +dnl Copyright (C) Michael Adam 2008 +dnl +dnl Released under the GNU General Public License +dnl http://www.gnu.org/licenses/ +dnl + + +SWAT_SBIN_TARGETS='bin/swat$(EXEEXT)' +SWAT_INSTALL_TARGETS=installswat + +AC_ARG_ENABLE(swat, +[AS_HELP_STRING([--enable-swat], [Build the SWAT tool (default=yes)])], +[ + case "$enable_swat" in + no) + SWAT_SBIN_TARGETS='' + SWAT_INSTALL_TARGETS='' + ;; + esac +]) + +AC_SUBST(SWAT_SBIN_TARGETS) +AC_SUBST(SWAT_INSTALL_TARGETS) + diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c new file mode 100644 index 0000000000..21f63d0b87 --- /dev/null +++ b/source3/modules/vfs_aio_fork.c @@ -0,0 +1,728 @@ +/* + * Simulate the Posix AIO using mmap/fork + * + * Copyright (C) Volker Lendecke 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +struct mmap_area { + size_t size; + volatile void *ptr; +}; + +static int mmap_area_destructor(struct mmap_area *area) +{ + munmap((void *)area->ptr, area->size); + return 0; +} + +static struct mmap_area *mmap_area_init(TALLOC_CTX *mem_ctx, size_t size) +{ + struct mmap_area *result; + int fd; + + result = talloc(mem_ctx, struct mmap_area); + if (result == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; + } + + fd = open("/dev/zero", O_RDWR); + if (fd == -1) { + DEBUG(3, ("open(\"/dev/zero\") failed: %s\n", + strerror(errno))); + goto fail; + } + + result->ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, + MAP_SHARED|MAP_FILE, fd, 0); + if (result->ptr == MAP_FAILED) { + DEBUG(1, ("mmap failed: %s\n", strerror(errno))); + goto fail; + } + + result->size = size; + talloc_set_destructor(result, mmap_area_destructor); + + return result; + +fail: + TALLOC_FREE(result); + return NULL; +} + +struct rw_cmd { + size_t n; + SMB_OFF_T offset; + bool read_cmd; +}; + +struct rw_ret { + ssize_t size; + int ret_errno; +}; + +struct aio_child_list; + +struct aio_child { + struct aio_child *prev, *next; + struct aio_child_list *list; + SMB_STRUCT_AIOCB *aiocb; + pid_t pid; + int sockfd; + struct fd_event *sock_event; + struct rw_ret retval; + struct mmap_area *map; /* ==NULL means write request */ + bool dont_delete; /* Marked as in use since last cleanup */ + bool cancelled; + bool read_cmd; +}; + +struct aio_child_list { + struct aio_child *children; + struct timed_event *cleanup_event; +}; + +static void free_aio_children(void **p) +{ + TALLOC_FREE(*p); +} + +static ssize_t read_fd(int fd, void *ptr, size_t nbytes, int *recvfd) +{ + struct msghdr msg; + struct iovec iov[1]; + ssize_t n; +#ifndef HAVE_MSGHDR_MSG_CONTROL + int newfd; +#endif + +#ifdef HAVE_MSGHDR_MSG_CONTROL + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof(int))]; + } control_un; + struct cmsghdr *cmptr; + + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof(control_un.control); +#else +#if HAVE_MSGHDR_MSG_ACCTRIGHTS + msg.msg_accrights = (caddr_t) &newfd; + msg.msg_accrightslen = sizeof(int); +#else +#error Can not pass file descriptors +#endif +#endif + + msg.msg_name = NULL; + msg.msg_namelen = 0; + + iov[0].iov_base = ptr; + iov[0].iov_len = nbytes; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + if ( (n = recvmsg(fd, &msg, 0)) <= 0) { + return(n); + } + +#ifdef HAVE_MSGHDR_MSG_CONTROL + if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL + && cmptr->cmsg_len == CMSG_LEN(sizeof(int))) { + if (cmptr->cmsg_level != SOL_SOCKET) { + DEBUG(10, ("control level != SOL_SOCKET")); + errno = EINVAL; + return -1; + } + if (cmptr->cmsg_type != SCM_RIGHTS) { + DEBUG(10, ("control type != SCM_RIGHTS")); + errno = EINVAL; + return -1; + } + *recvfd = *((int *) CMSG_DATA(cmptr)); + } else { + *recvfd = -1; /* descriptor was not passed */ + } +#else + if (msg.msg_accrightslen == sizeof(int)) { + *recvfd = newfd; + } + else { + *recvfd = -1; /* descriptor was not passed */ + } +#endif + + return(n); +} + +static ssize_t write_fd(int fd, void *ptr, size_t nbytes, int sendfd) +{ + struct msghdr msg; + struct iovec iov[1]; + +#ifdef HAVE_MSGHDR_MSG_CONTROL + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof(int))]; + } control_un; + struct cmsghdr *cmptr; + + ZERO_STRUCT(msg); + ZERO_STRUCT(control_un); + + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof(control_un.control); + + cmptr = CMSG_FIRSTHDR(&msg); + cmptr->cmsg_len = CMSG_LEN(sizeof(int)); + cmptr->cmsg_level = SOL_SOCKET; + cmptr->cmsg_type = SCM_RIGHTS; + *((int *) CMSG_DATA(cmptr)) = sendfd; +#else + ZERO_STRUCT(msg); + msg.msg_accrights = (caddr_t) &sendfd; + msg.msg_accrightslen = sizeof(int); +#endif + + msg.msg_name = NULL; + msg.msg_namelen = 0; + + ZERO_STRUCT(iov); + iov[0].iov_base = ptr; + iov[0].iov_len = nbytes; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + return (sendmsg(fd, &msg, 0)); +} + +static void aio_child_cleanup(struct event_context *event_ctx, + struct timed_event *te, + const struct timeval *now, + void *private_data) +{ + struct aio_child_list *list = talloc_get_type_abort( + private_data, struct aio_child_list); + struct aio_child *child, *next; + + TALLOC_FREE(list->cleanup_event); + + for (child = list->children; child != NULL; child = next) { + next = child->next; + + if (child->aiocb != NULL) { + DEBUG(10, ("child %d currently active\n", + (int)child->pid)); + continue; + } + + if (child->dont_delete) { + DEBUG(10, ("Child %d was active since last cleanup\n", + (int)child->pid)); + child->dont_delete = false; + continue; + } + + DEBUG(10, ("Child %d idle for more than 30 seconds, " + "deleting\n", (int)child->pid)); + + TALLOC_FREE(child); + } + + if (list->children != NULL) { + /* + * Re-schedule the next cleanup round + */ + list->cleanup_event = event_add_timed(smbd_event_context(), list, + timeval_add(now, 30, 0), + "aio_child_cleanup", + aio_child_cleanup, list); + + } +} + +static struct aio_child_list *init_aio_children(struct vfs_handle_struct *handle) +{ + struct aio_child_list *data = NULL; + + if (SMB_VFS_HANDLE_TEST_DATA(handle)) { + SMB_VFS_HANDLE_GET_DATA(handle, data, struct aio_child_list, + return NULL); + } + + if (data == NULL) { + data = TALLOC_ZERO_P(NULL, struct aio_child_list); + if (data == NULL) { + return NULL; + } + } + + /* + * Regardless of whether the child_list had been around or not, make + * sure that we have a cleanup timed event. This timed event will + * delete itself when it finds that no children are around anymore. + */ + + if (data->cleanup_event == NULL) { + data->cleanup_event = event_add_timed(smbd_event_context(), data, + timeval_current_ofs(30, 0), + "aio_child_cleanup", + aio_child_cleanup, data); + if (data->cleanup_event == NULL) { + TALLOC_FREE(data); + return NULL; + } + } + + if (!SMB_VFS_HANDLE_TEST_DATA(handle)) { + SMB_VFS_HANDLE_SET_DATA(handle, data, free_aio_children, + struct aio_child_list, return False); + } + + return data; +} + +static void aio_child_loop(int sockfd, struct mmap_area *map) +{ + while (true) { + int fd = -1; + ssize_t ret; + struct rw_cmd cmd_struct; + struct rw_ret ret_struct; + + ret = read_fd(sockfd, &cmd_struct, sizeof(cmd_struct), &fd); + if (ret != sizeof(cmd_struct)) { + DEBUG(10, ("read_fd returned %d: %s\n", (int)ret, + strerror(errno))); + exit(1); + } + + DEBUG(10, ("aio_child_loop: %s %d bytes at %d from fd %d\n", + cmd_struct.read_cmd ? "read" : "write", + (int)cmd_struct.n, (int)cmd_struct.offset, fd)); + +#ifdef ENABLE_BUILD_FARM_HACKS + { + /* + * In the build farm, we want erratic behaviour for + * async I/O times + */ + uint8_t randval; + unsigned msecs; + /* + * use generate_random_buffer, we just forked from a + * common parent state + */ + generate_random_buffer(&randval, sizeof(randval)); + msecs = randval + 20; + DEBUG(10, ("delaying for %u msecs\n", msecs)); + smb_msleep(msecs); + } +#endif + + + ZERO_STRUCT(ret_struct); + + if (cmd_struct.read_cmd) { + ret_struct.size = sys_pread( + fd, (void *)map->ptr, cmd_struct.n, + cmd_struct.offset); + } + else { + ret_struct.size = sys_pwrite( + fd, (void *)map->ptr, cmd_struct.n, + cmd_struct.offset); + } + + DEBUG(10, ("aio_child_loop: syscall returned %d\n", + (int)ret_struct.size)); + + if (ret_struct.size == -1) { + ret_struct.ret_errno = errno; + } + + ret = write_data(sockfd, (char *)&ret_struct, + sizeof(ret_struct)); + if (ret != sizeof(ret_struct)) { + DEBUG(10, ("could not write ret_struct: %s\n", + strerror(errno))); + exit(2); + } + + close(fd); + } +} + +static void handle_aio_completion(struct event_context *event_ctx, + struct fd_event *event, uint16 flags, + void *p) +{ + struct aio_child *child = (struct aio_child *)p; + uint16 mid; + + DEBUG(10, ("handle_aio_completion called with flags=%d\n", flags)); + + if ((flags & EVENT_FD_READ) == 0) { + return; + } + + if (!NT_STATUS_IS_OK(read_data(child->sockfd, + (char *)&child->retval, + sizeof(child->retval)))) { + DEBUG(0, ("aio child %d died\n", (int)child->pid)); + child->retval.size = -1; + child->retval.ret_errno = EIO; + } + + if (child->cancelled) { + child->aiocb = NULL; + child->cancelled = false; + return; + } + + if (child->read_cmd && (child->retval.size > 0)) { + SMB_ASSERT(child->retval.size <= child->aiocb->aio_nbytes); + memcpy((void *)child->aiocb->aio_buf, (void *)child->map->ptr, + child->retval.size); + } + + mid = child->aiocb->aio_sigevent.sigev_value.sival_int; + + DEBUG(10, ("mid %d finished\n", (int)mid)); + + aio_request_done(mid); + process_aio_queue(); +} + +static int aio_child_destructor(struct aio_child *child) +{ + SMB_ASSERT((child->aiocb == NULL) || child->cancelled); + close(child->sockfd); + DLIST_REMOVE(child->list->children, child); + return 0; +} + +static NTSTATUS create_aio_child(struct aio_child_list *children, + size_t map_size, + struct aio_child **presult) +{ + struct aio_child *result; + int fdpair[2]; + NTSTATUS status; + + fdpair[0] = fdpair[1] = -1; + + result = TALLOC_ZERO_P(children, struct aio_child); + NT_STATUS_HAVE_NO_MEMORY(result); + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) == -1) { + status = map_nt_error_from_unix(errno); + DEBUG(10, ("socketpair() failed: %s\n", strerror(errno))); + TALLOC_FREE(result); + goto fail; + } + + DEBUG(10, ("fdpair = %d/%d\n", fdpair[0], fdpair[1])); + + result->map = mmap_area_init(result, map_size); + if (result->map == NULL) { + status = map_nt_error_from_unix(errno); + DEBUG(0, ("Could not create mmap area\n")); + goto fail; + } + + result->pid = sys_fork(); + if (result->pid == -1) { + status = map_nt_error_from_unix(errno); + DEBUG(0, ("fork failed: %s\n", strerror(errno))); + goto fail; + } + + if (result->pid == 0) { + close(fdpair[0]); + result->sockfd = fdpair[1]; + aio_child_loop(result->sockfd, result->map); + } + + DEBUG(10, ("Child %d created\n", result->pid)); + + result->sockfd = fdpair[0]; + close(fdpair[1]); + + result->sock_event = event_add_fd(smbd_event_context(), result, + result->sockfd, EVENT_FD_READ, + handle_aio_completion, + result); + if (result->sock_event == NULL) { + status = NT_STATUS_NO_MEMORY; + DEBUG(0, ("event_add_fd failed\n")); + goto fail; + } + + result->list = children; + DLIST_ADD(children->children, result); + + talloc_set_destructor(result, aio_child_destructor); + + *presult = result; + + return NT_STATUS_OK; + + fail: + if (fdpair[0] != -1) close(fdpair[0]); + if (fdpair[1] != -1) close(fdpair[1]); + TALLOC_FREE(result); + + return status; +} + +static NTSTATUS get_idle_child(struct vfs_handle_struct *handle, + struct aio_child **pchild) +{ + struct aio_child_list *children; + struct aio_child *child; + NTSTATUS status; + + children = init_aio_children(handle); + if (children == NULL) { + return NT_STATUS_NO_MEMORY; + } + + for (child = children->children; child != NULL; child = child->next) { + if (child->aiocb == NULL) { + /* idle */ + break; + } + } + + if (child == NULL) { + DEBUG(10, ("no idle child found, creating new one\n")); + + status = create_aio_child(children, 128*1024, &child); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("create_aio_child failed: %s\n", + nt_errstr(status))); + return status; + } + } + + child->dont_delete = true; + + *pchild = child; + return NT_STATUS_OK; +} + +static int aio_fork_read(struct vfs_handle_struct *handle, + struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + struct aio_child *child; + struct rw_cmd cmd; + ssize_t ret; + NTSTATUS status; + + if (aiocb->aio_nbytes > 128*1024) { + /* TODO: support variable buffers */ + errno = EINVAL; + return -1; + } + + status = get_idle_child(handle, &child); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("Could not get an idle child\n")); + return -1; + } + + child->read_cmd = true; + child->aiocb = aiocb; + child->retval.ret_errno = EINPROGRESS; + + ZERO_STRUCT(cmd); + cmd.n = aiocb->aio_nbytes; + cmd.offset = aiocb->aio_offset; + cmd.read_cmd = child->read_cmd; + + DEBUG(10, ("sending fd %d to child %d\n", fsp->fh->fd, + (int)child->pid)); + + ret = write_fd(child->sockfd, &cmd, sizeof(cmd), fsp->fh->fd); + if (ret == -1) { + DEBUG(10, ("write_fd failed: %s\n", strerror(errno))); + return -1; + } + + return 0; +} + +static int aio_fork_write(struct vfs_handle_struct *handle, + struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +{ + struct aio_child *child; + struct rw_cmd cmd; + ssize_t ret; + NTSTATUS status; + + if (aiocb->aio_nbytes > 128*1024) { + /* TODO: support variable buffers */ + errno = EINVAL; + return -1; + } + + status = get_idle_child(handle, &child); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("Could not get an idle child\n")); + return -1; + } + + child->read_cmd = false; + child->aiocb = aiocb; + child->retval.ret_errno = EINPROGRESS; + + memcpy((void *)child->map->ptr, (void *)aiocb->aio_buf, + aiocb->aio_nbytes); + + ZERO_STRUCT(cmd); + cmd.n = aiocb->aio_nbytes; + cmd.offset = aiocb->aio_offset; + cmd.read_cmd = child->read_cmd; + + DEBUG(10, ("sending fd %d to child %d\n", fsp->fh->fd, + (int)child->pid)); + + ret = write_fd(child->sockfd, &cmd, sizeof(cmd), fsp->fh->fd); + if (ret == -1) { + DEBUG(10, ("write_fd failed: %s\n", strerror(errno))); + return -1; + } + + return 0; +} + +static struct aio_child *aio_fork_find_child(struct vfs_handle_struct *handle, + SMB_STRUCT_AIOCB *aiocb) +{ + struct aio_child_list *children; + struct aio_child *child; + + children = init_aio_children(handle); + if (children == NULL) { + return NULL; + } + + for (child = children->children; child != NULL; child = child->next) { + if (child->aiocb == aiocb) { + return child; + } + } + + return NULL; +} + +static ssize_t aio_fork_return_fn(struct vfs_handle_struct *handle, + struct files_struct *fsp, + SMB_STRUCT_AIOCB *aiocb) +{ + struct aio_child *child = aio_fork_find_child(handle, aiocb); + + if (child == NULL) { + errno = EINVAL; + DEBUG(0, ("returning EINVAL\n")); + return -1; + } + + child->aiocb = NULL; + + if (child->retval.size == -1) { + errno = child->retval.ret_errno; + } + + return child->retval.size; +} + +static int aio_fork_cancel(struct vfs_handle_struct *handle, + struct files_struct *fsp, + SMB_STRUCT_AIOCB *aiocb) +{ + struct aio_child_list *children; + struct aio_child *child; + + children = init_aio_children(handle); + if (children == NULL) { + errno = EINVAL; + return -1; + } + + for (child = children->children; child != NULL; child = child->next) { + if (child->aiocb == NULL) { + continue; + } + if (child->aiocb->aio_fildes != fsp->fh->fd) { + continue; + } + if ((aiocb != NULL) && (child->aiocb != aiocb)) { + continue; + } + + /* + * We let the child do its job, but we discard the result when + * it's finished. + */ + + child->cancelled = true; + } + + return AIO_CANCELED; +} + +static int aio_fork_error_fn(struct vfs_handle_struct *handle, + struct files_struct *fsp, + SMB_STRUCT_AIOCB *aiocb) +{ + struct aio_child *child = aio_fork_find_child(handle, aiocb); + + if (child == NULL) { + errno = EINVAL; + return -1; + } + + return child->retval.ret_errno; +} + +/* VFS operations structure */ + +static vfs_op_tuple aio_fork_ops[] = { + {SMB_VFS_OP(aio_fork_read), SMB_VFS_OP_AIO_READ, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(aio_fork_write), SMB_VFS_OP_AIO_WRITE, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(aio_fork_return_fn), SMB_VFS_OP_AIO_RETURN, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(aio_fork_cancel), SMB_VFS_OP_AIO_CANCEL, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(aio_fork_error_fn), SMB_VFS_OP_AIO_ERROR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, + SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_aio_fork_init(void); +NTSTATUS vfs_aio_fork_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, + "aio_fork", aio_fork_ops); +} diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index cf135dfd03..31ebb6352a 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -468,7 +468,7 @@ static int vfswrap_rename(vfs_handle_struct *handle, const char *oldname, const START_PROFILE(syscall_rename); result = rename(oldname, newname); - if (errno == EXDEV) { + if ((result == -1) && (errno == EXDEV)) { /* Rename across filesystems needed. */ result = copy_reg(oldname, newname); } diff --git a/source3/modules/vfs_prealloc.c b/source3/modules/vfs_prealloc.c index cb3508dc30..2a06e3d81b 100644 --- a/source3/modules/vfs_prealloc.c +++ b/source3/modules/vfs_prealloc.c @@ -199,7 +199,7 @@ static int prealloc_ftruncate(vfs_handle_struct * handle, /* Maintain the allocated space even in the face of truncates. */ if ((psize = VFS_FETCH_FSP_EXTENSION(handle, fsp))) { - preallocate_space(fd, *psize); + preallocate_space(fsp->fh->fd, *psize); } return ret; @@ -218,4 +218,3 @@ NTSTATUS vfs_prealloc_init(void) return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE, prealloc_op_tuples); } - diff --git a/source3/modules/vfs_xattr_tdb.c b/source3/modules/vfs_xattr_tdb.c index 171022b01b..7b5e510747 100644 --- a/source3/modules/vfs_xattr_tdb.c +++ b/source3/modules/vfs_xattr_tdb.c @@ -575,7 +575,7 @@ static bool xattr_tdb_init(int snum, struct db_context **p_db) struct db_context *db; const char *dbname; - dbname = lp_parm_const_string(snum, "xattr", "tdb", + dbname = lp_parm_const_string(snum, "xattr_tdb", "file", lock_path("xattr.tdb")); if (dbname == NULL) { @@ -588,7 +588,11 @@ static bool xattr_tdb_init(int snum, struct db_context **p_db) unbecome_root(); if (db == NULL) { +#if defined(ENOTSUP) errno = ENOTSUP; +#else + errno = ENOSYS; +#endif return false; } diff --git a/source3/nmbd/nmbd_namelistdb.c b/source3/nmbd/nmbd_namelistdb.c index f9cbcf4f59..6570fd4ec7 100644 --- a/source3/nmbd/nmbd_namelistdb.c +++ b/source3/nmbd/nmbd_namelistdb.c @@ -297,7 +297,6 @@ void standard_success_register(struct subnet_record *subrec, ******************************************************************/ void standard_fail_register( struct subnet_record *subrec, - struct response_record *rrec, struct nmb_name *nmbname ) { struct name_record *namerec; diff --git a/source3/nmbd/nmbd_nameregister.c b/source3/nmbd/nmbd_nameregister.c index edcf258519..98f129aa89 100644 --- a/source3/nmbd/nmbd_nameregister.c +++ b/source3/nmbd/nmbd_nameregister.c @@ -152,10 +152,11 @@ static void register_name_response(struct subnet_record *subrec, if( rrec->success_fn) (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip); } else { + struct nmb_name qname = *question_name; if( rrec->fail_fn) (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name); /* Remove the name. */ - standard_fail_register( subrec, rrec, question_name); + standard_fail_register( subrec, &qname); } /* Ensure we don't retry. */ @@ -280,10 +281,11 @@ static void register_name_timeout_response(struct subnet_record *subrec, if( rrec->success_fn) (*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip); } else { + struct nmb_name qname = *question_name; if( rrec->fail_fn) (*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name); /* Remove the name. */ - standard_fail_register( subrec, rrec, question_name); + standard_fail_register( subrec, &qname); } /* Ensure we don't retry. */ diff --git a/source3/nmbd/nmbd_responserecordsdb.c b/source3/nmbd/nmbd_responserecordsdb.c index 6498ce04cf..b042fb41ed 100644 --- a/source3/nmbd/nmbd_responserecordsdb.c +++ b/source3/nmbd/nmbd_responserecordsdb.c @@ -46,6 +46,24 @@ static void add_response_record(struct subnet_record *subrec, void remove_response_record(struct subnet_record *subrec, struct response_record *rrec) { + /* It is possible this can be called twice, + with a rrec pointer that has been freed. So + before we inderect into rrec, search for it + on the responselist first. Bug #3617. JRA. */ + + struct response_record *p = NULL; + + for (p = subrec->responselist; p; p = p->next) { + if (p == rrec) { + break; + } + } + + if (p == NULL) { + /* We didn't find rrec on the list. */ + return; + } + DLIST_REMOVE(subrec->responselist, rrec); if(rrec->userdata) { diff --git a/source3/nsswitch/libwbclient/wbc_pam.c b/source3/nsswitch/libwbclient/wbc_pam.c index 7f7c7b8140..1164ab173a 100644 --- a/source3/nsswitch/libwbclient/wbc_pam.c +++ b/source3/nsswitch/libwbclient/wbc_pam.c @@ -34,32 +34,389 @@ wbcErr wbcAuthenticateUser(const char *username, const char *password) { + wbcErr wbc_status = WBC_ERR_SUCCESS; + struct wbcAuthUserParams params; + + ZERO_STRUCT(params); + + params.account_name = username; + params.level = WBC_AUTH_USER_LEVEL_PLAIN; + params.password.plaintext = password; + + wbc_status = wbcAuthenticateUserEx(¶ms, NULL, NULL); + BAIL_ON_WBC_ERROR(wbc_status); + +done: + return wbc_status; +} + +static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx, + const struct winbindd_response *resp, + struct wbcAuthUserInfo **_i) +{ + wbcErr wbc_status = WBC_ERR_SUCCESS; + struct wbcAuthUserInfo *i; + struct wbcDomainSid domain_sid; + char *p; + uint32_t sn = 0; + uint32_t j; + + i = talloc(mem_ctx, struct wbcAuthUserInfo); + BAIL_ON_PTR_ERROR(i, wbc_status); + + i->user_flags = resp->data.auth.info3.user_flgs; + + i->account_name = talloc_strdup(i, resp->data.auth.info3.user_name); + BAIL_ON_PTR_ERROR(i->account_name, wbc_status); + i->user_principal= NULL; + i->full_name = talloc_strdup(i, resp->data.auth.info3.full_name); + BAIL_ON_PTR_ERROR(i->full_name, wbc_status); + i->domain_name = talloc_strdup(i, resp->data.auth.info3.logon_dom); + BAIL_ON_PTR_ERROR(i->domain_name, wbc_status); + i->dns_domain_name= NULL; + + i->acct_flags = resp->data.auth.info3.acct_flags; + memcpy(i->user_session_key, + resp->data.auth.user_session_key, + sizeof(i->user_session_key)); + memcpy(i->lm_session_key, + resp->data.auth.first_8_lm_hash, + sizeof(i->lm_session_key)); + + i->logon_count = resp->data.auth.info3.logon_count; + i->bad_password_count = resp->data.auth.info3.bad_pw_count; + + i->logon_time = resp->data.auth.info3.logon_time; + i->logoff_time = resp->data.auth.info3.logoff_time; + i->kickoff_time = resp->data.auth.info3.kickoff_time; + i->pass_last_set_time = resp->data.auth.info3.pass_last_set_time; + i->pass_can_change_time = resp->data.auth.info3.pass_can_change_time; + i->pass_must_change_time= resp->data.auth.info3.pass_must_change_time; + + i->logon_server = talloc_strdup(i, resp->data.auth.info3.logon_srv); + BAIL_ON_PTR_ERROR(i->logon_server, wbc_status); + i->logon_script = talloc_strdup(i, resp->data.auth.info3.logon_script); + BAIL_ON_PTR_ERROR(i->logon_script, wbc_status); + i->profile_path = talloc_strdup(i, resp->data.auth.info3.profile_path); + BAIL_ON_PTR_ERROR(i->profile_path, wbc_status); + i->home_directory= talloc_strdup(i, resp->data.auth.info3.home_dir); + BAIL_ON_PTR_ERROR(i->home_directory, wbc_status); + i->home_drive = talloc_strdup(i, resp->data.auth.info3.dir_drive); + BAIL_ON_PTR_ERROR(i->home_drive, wbc_status); + + i->num_sids = 2; + i->num_sids += resp->data.auth.info3.num_groups; + i->num_sids += resp->data.auth.info3.num_other_sids; + + i->sids = talloc_array(i, struct wbcSidWithAttr, i->num_sids); + BAIL_ON_PTR_ERROR(i->sids, wbc_status); + + wbc_status = wbcStringToSid(resp->data.auth.info3.dom_sid, + &domain_sid); + BAIL_ON_WBC_ERROR(wbc_status); + +#define _SID_COMPOSE(s, d, r, a) { \ + (s).sid = d; \ + if ((s).sid.num_auths < MAXSUBAUTHS) { \ + (s).sid.sub_auths[(s).sid.num_auths++] = r; \ + } else { \ + wbc_status = WBC_ERR_INVALID_SID; \ + BAIL_ON_WBC_ERROR(wbc_status); \ + } \ + (s).attributes = a; \ +} while (0) + + sn = 0; + _SID_COMPOSE(i->sids[sn], domain_sid, + resp->data.auth.info3.user_rid, + 0); + sn++; + _SID_COMPOSE(i->sids[sn], domain_sid, + resp->data.auth.info3.group_rid, + 0); + sn++; + + p = (char *)resp->extra_data.data; + if (!p) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + + for (j=0; j < resp->data.auth.info3.num_groups; j++) { + uint32_t rid; + uint32_t attrs; + int ret; + char *s = p; + char *e = strchr(p, '\n'); + if (!e) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + e[0] = '\0'; + p = &e[1]; + + ret = sscanf(s, "0x%08X:0x%08X", &rid, &attrs); + if (ret != 2) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + + _SID_COMPOSE(i->sids[sn], domain_sid, + rid, attrs); + sn++; + } + + for (j=0; j < resp->data.auth.info3.num_other_sids; j++) { + uint32_t attrs; + int ret; + char *s = p; + char *a; + char *e = strchr(p, '\n'); + if (!e) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + e[0] = '\0'; + p = &e[1]; + + e = strchr(s, ':'); + if (!e) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + e[0] = '\0'; + a = &e[1]; + + ret = sscanf(a, "0x%08X", + &attrs); + if (ret != 1) { + wbc_status = WBC_INVALID_RESPONSE; + BAIL_ON_WBC_ERROR(wbc_status); + } + + wbc_status = wbcStringToSid(s, &i->sids[sn].sid); + BAIL_ON_WBC_ERROR(wbc_status); + + i->sids[sn].attributes = attrs; + sn++; + } + + i->num_sids = sn; + + *_i = i; + i = NULL; +done: + talloc_free(i); + return wbc_status; +} + +static wbcErr wbc_create_error_info(TALLOC_CTX *mem_ctx, + const struct winbindd_response *resp, + struct wbcAuthErrorInfo **_e) +{ + wbcErr wbc_status = WBC_ERR_SUCCESS; + struct wbcAuthErrorInfo *e; + + e = talloc(mem_ctx, struct wbcAuthErrorInfo); + BAIL_ON_PTR_ERROR(e, wbc_status); + + e->nt_status = resp->data.auth.nt_status; + e->pam_error = resp->data.auth.pam_error; + e->nt_string = talloc_strdup(e, resp->data.auth.nt_status_string); + BAIL_ON_PTR_ERROR(e->nt_string, wbc_status); + + e->display_string = talloc_strdup(e, resp->data.auth.error_string); + BAIL_ON_PTR_ERROR(e->display_string, wbc_status); + + *_e = e; + e = NULL; + +done: + talloc_free(e); + return wbc_status; +} + +/** @brief Authenticate with more detailed information + * + * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH + * is not supported yet + * @param info Output details on WBC_ERR_SUCCESS + * @param error Output details on WBC_ERR_AUTH_ERROR + * + * @return #wbcErr + **/ + +wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, + struct wbcAuthUserInfo **info, + struct wbcAuthErrorInfo **error) +{ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + int cmd = 0; struct winbindd_request request; struct winbindd_response response; - if (!username) { + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + if (error) { + *error = NULL; + } + + if (!params) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + if (!params->account_name) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } /* Initialize request */ - ZERO_STRUCT(request); - ZERO_STRUCT(response); + switch (params->level) { + case WBC_AUTH_USER_LEVEL_PLAIN: + cmd = WINBINDD_PAM_AUTH; + request.flags = WBFLAG_PAM_INFO3_TEXT | + WBFLAG_PAM_USER_SESSION_KEY | + WBFLAG_PAM_LMKEY; + + if (!params->password.plaintext) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + if (params->domain_name && params->domain_name[0]) { + /* We need to get the winbind separator :-( */ + struct winbindd_response sep_response; - /* dst is already null terminated from the memset above */ + ZERO_STRUCT(sep_response); - strncpy(request.data.auth.user, username, - sizeof(request.data.auth.user)-1); - strncpy(request.data.auth.pass, password, - sizeof(request.data.auth.user)-1); + wbc_status = wbcRequestResponse(WINBINDD_INFO, + NULL, &sep_response); + BAIL_ON_WBC_ERROR(wbc_status); - wbc_status = wbcRequestResponse(WINBINDD_PAM_AUTH, + snprintf(request.data.auth.user, + sizeof(request.data.auth.user)-1, + "%s%c%s", + params->domain_name, + sep_response.data.info.winbind_separator, + params->account_name); + } else { + strncpy(request.data.auth.user, + params->account_name, + sizeof(request.data.auth.user)-1); + } + strncpy(request.data.auth.pass, + params->password.plaintext, + sizeof(request.data.auth.user)-1); + break; + + case WBC_AUTH_USER_LEVEL_HASH: + wbc_status = WBC_ERR_NOT_IMPLEMENTED; + BAIL_ON_WBC_ERROR(wbc_status); + break; + + case WBC_AUTH_USER_LEVEL_RESPONSE: + cmd = WINBINDD_PAM_AUTH_CRAP; + request.flags = WBFLAG_PAM_INFO3_TEXT | + WBFLAG_PAM_USER_SESSION_KEY | + WBFLAG_PAM_LMKEY; + + if (params->password.response.lm_length && + params->password.response.lm_data) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + if (params->password.response.lm_length == 0 && + params->password.response.lm_data) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + if (params->password.response.nt_length && + !params->password.response.nt_data) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + if (params->password.response.nt_length == 0&& + params->password.response.nt_data) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + strncpy(request.data.auth_crap.user, + params->account_name, + sizeof(request.data.auth_crap.user)-1); + if (params->domain_name) { + strncpy(request.data.auth_crap.domain, + params->domain_name, + sizeof(request.data.auth_crap.domain)-1); + } + if (params->workstation_name) { + strncpy(request.data.auth_crap.workstation, + params->workstation_name, + sizeof(request.data.auth_crap.workstation)-1); + } + + request.data.auth_crap.logon_parameters = + params->parameter_control; + + memcpy(request.data.auth_crap.chal, + params->password.response.challenge, + sizeof(request.data.auth_crap.chal)); + + request.data.auth_crap.lm_resp_len = + MIN(params->password.response.lm_length, + sizeof(request.data.auth_crap.lm_resp)); + request.data.auth_crap.nt_resp_len = + MIN(params->password.response.nt_length, + sizeof(request.data.auth_crap.nt_resp)); + if (params->password.response.lm_data) { + memcpy(request.data.auth_crap.lm_resp, + params->password.response.lm_data, + request.data.auth_crap.lm_resp_len); + } + if (params->password.response.nt_data) { + memcpy(request.data.auth_crap.nt_resp, + params->password.response.nt_data, + request.data.auth_crap.nt_resp_len); + } + break; + default: + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + if (cmd == 0) { + wbc_status = WBC_ERR_INVALID_PARAM; + BAIL_ON_WBC_ERROR(wbc_status); + } + + wbc_status = wbcRequestResponse(cmd, &request, &response); + if (response.data.auth.nt_status != 0) { + if (error) { + wbc_status = wbc_create_error_info(NULL, + &response, + error); + BAIL_ON_WBC_ERROR(wbc_status); + } + + wbc_status = WBC_ERR_AUTH_ERROR; + BAIL_ON_WBC_ERROR(wbc_status); + } BAIL_ON_WBC_ERROR(wbc_status); + if (info) { + wbc_status = wbc_create_auth_info(NULL, + &response, + info); + BAIL_ON_WBC_ERROR(wbc_status); + } + done: + return wbc_status; } diff --git a/source3/nsswitch/libwbclient/wbclient.c b/source3/nsswitch/libwbclient/wbclient.c index 5aad378ad0..e17296283f 100644 --- a/source3/nsswitch/libwbclient/wbclient.c +++ b/source3/nsswitch/libwbclient/wbclient.c @@ -110,6 +110,8 @@ const char *wbcErrorString(wbcErr error) return "WBC_INVALID_RESPONSE"; case WBC_ERR_NSS_ERROR: return "WBC_ERR_NSS_ERROR"; + case WBC_ERR_AUTH_ERROR: + return "WBC_ERR_AUTH_ERROR"; } return "unknown wbcErr value"; diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h index ef9e3557da..c01db9618d 100644 --- a/source3/nsswitch/libwbclient/wbclient.h +++ b/source3/nsswitch/libwbclient/wbclient.h @@ -41,7 +41,8 @@ enum _wbcErrType { 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 **/ + WBC_ERR_NSS_ERROR, /**< NSS_STATUS error **/ + WBC_ERR_AUTH_ERROR /**< Authentication failed **/ }; typedef enum _wbcErrType wbcErr; @@ -88,6 +89,25 @@ enum wbcSidType { }; /** + * @brief Security Identifier with attributes + **/ + +struct wbcSidWithAttr { + struct wbcDomainSid sid; + uint32_t attributes; +}; + +/* wbcSidWithAttr->attributes */ + +#define WBC_SID_ATTR_GROUP_MANDATORY 0x00000001 +#define WBC_SID_ATTR_GROUP_ENABLED_BY_DEFAULT 0x00000002 +#define WBC_SID_ATTR_GROUP_ENABLED 0x00000004 +#define WBC_SID_ATTR_GROUP_OWNER 0x00000008 +#define WBC_SID_ATTR_GROUP_USEFOR_DENY_ONLY 0x00000010 +#define WBC_SID_ATTR_GROUP_RESOURCE 0x20000000 +#define WBC_SID_ATTR_GROUP_LOGON_ID 0xC0000000 + +/** * @brief Domain Information **/ @@ -104,6 +124,140 @@ struct wbcDomainInfo { #define WBC_DOMINFO_AD 0x00000002 #define WBC_DOMINFO_PRIMARY 0x00000004 +/** + * @brief Auth User Parameters + **/ + +struct wbcAuthUserParams { + const char *account_name; + const char *domain_name; + const char *workstation_name; + + uint32_t flags; + + uint32_t parameter_control; + + enum wbcAuthUserLevel { + WBC_AUTH_USER_LEVEL_PLAIN = 1, + WBC_AUTH_USER_LEVEL_HASH = 2, + WBC_AUTH_USER_LEVEL_RESPONSE = 3 + } level; + union { + const char *plaintext; + struct { + uint8_t nt_hash[16]; + uint8_t lm_hash[16]; + } hash; + struct { + uint8_t challenge[8]; + uint32_t nt_length; + uint8_t *nt_data; + uint32_t lm_length; + uint8_t *lm_data; + } response; + } password; +}; + +/* wbcAuthUserParams->parameter_control */ + +#define WBC_MSV1_0_CLEARTEXT_PASSWORD_ALLOWED 0x00000002 +#define WBC_MSV1_0_UPDATE_LOGON_STATISTICS 0x00000004 +#define WBC_MSV1_0_RETURN_USER_PARAMETERS 0x00000008 +#define WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT 0x00000020 +#define WBC_MSV1_0_RETURN_PROFILE_PATH 0x00000200 +#define WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT 0x00000800 + +/* wbcAuthUserParams->flags */ + +#define WBC_AUTH_PARAM_FLAGS_INTERACTIVE_LOGON 0x00000001 + +/** + * @brief Auth User Information + * + * Some of the strings are maybe NULL + **/ + +struct wbcAuthUserInfo { + uint32_t user_flags; + + char *account_name; + char *user_principal; + char *full_name; + char *domain_name; + char *dns_domain_name; + + uint32_t acct_flags; + uint8_t user_session_key[16]; + uint8_t lm_session_key[8]; + + uint16_t logon_count; + uint16_t bad_password_count; + + uint64_t logon_time; + uint64_t logoff_time; + uint64_t kickoff_time; + uint64_t pass_last_set_time; + uint64_t pass_can_change_time; + uint64_t pass_must_change_time; + + char *logon_server; + char *logon_script; + char *profile_path; + char *home_directory; + char *home_drive; + + /* + * the 1st one is the account sid + * the 2nd one is the primary_group sid + * followed by the rest of the groups + */ + uint32_t num_sids; + struct wbcSidWithAttr *sids; +}; + +/* wbcAuthUserInfo->user_flags */ + +#define WBC_AUTH_USER_INFO_GUEST 0x00000001 +#define WBC_AUTH_USER_INFO_NOENCRYPTION 0x00000002 +#define WBC_AUTH_USER_INFO_CACHED_ACCOUNT 0x00000004 +#define WBC_AUTH_USER_INFO_USED_LM_PASSWORD 0x00000008 +#define WBC_AUTH_USER_INFO_EXTRA_SIDS 0x00000020 +#define WBC_AUTH_USER_INFO_SUBAUTH_SESSION_KEY 0x00000040 +#define WBC_AUTH_USER_INFO_SERVER_TRUST_ACCOUNT 0x00000080 +#define WBC_AUTH_USER_INFO_NTLMV2_ENABLED 0x00000100 +#define WBC_AUTH_USER_INFO_RESOURCE_GROUPS 0x00000200 +#define WBC_AUTH_USER_INFO_PROFILE_PATH_RETURNED 0x00000400 +#define WBC_AUTH_USER_INFO_GRACE_LOGON 0x01000000 + +/* wbcAuthUserInfo->acct_flags */ + +#define WBC_ACB_DISABLED 0x00000001 /* 1 User account disabled */ +#define WBC_ACB_HOMDIRREQ 0x00000002 /* 1 Home directory required */ +#define WBC_ACB_PWNOTREQ 0x00000004 /* 1 User password not required */ +#define WBC_ACB_TEMPDUP 0x00000008 /* 1 Temporary duplicate account */ +#define WBC_ACB_NORMAL 0x00000010 /* 1 Normal user account */ +#define WBC_ACB_MNS 0x00000020 /* 1 MNS logon user account */ +#define WBC_ACB_DOMTRUST 0x00000040 /* 1 Interdomain trust account */ +#define WBC_ACB_WSTRUST 0x00000080 /* 1 Workstation trust account */ +#define WBC_ACB_SVRTRUST 0x00000100 /* 1 Server trust account */ +#define WBC_ACB_PWNOEXP 0x00000200 /* 1 User password does not expire */ +#define WBC_ACB_AUTOLOCK 0x00000400 /* 1 Account auto locked */ +#define WBC_ACB_ENC_TXT_PWD_ALLOWED 0x00000800 /* 1 Encryped text password is allowed */ +#define WBC_ACB_SMARTCARD_REQUIRED 0x00001000 /* 1 Smart Card required */ +#define WBC_ACB_TRUSTED_FOR_DELEGATION 0x00002000 /* 1 Trusted for Delegation */ +#define WBC_ACB_NOT_DELEGATED 0x00004000 /* 1 Not delegated */ +#define WBC_ACB_USE_DES_KEY_ONLY 0x00008000 /* 1 Use DES key only */ +#define WBC_ACB_DONT_REQUIRE_PREAUTH 0x00010000 /* 1 Preauth not required */ +#define WBC_ACB_PW_EXPIRED 0x00020000 /* 1 Password Expired */ +#define WBC_ACB_NO_AUTH_DATA_REQD 0x00080000 /* 1 = No authorization data required */ + +struct wbcAuthErrorInfo { + uint32_t nt_status; + char *nt_string; + int32_t pam_error; + char *display_string; +}; + /* * Memory Management */ @@ -205,5 +359,8 @@ wbcErr wbcDomainSequenceNumbers(void); wbcErr wbcAuthenticateUser(const char *username, const char *password); +wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, + struct wbcAuthUserInfo **info, + struct wbcAuthErrorInfo **error); #endif /* _WBCLIENT_H */ diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index 89db0773ae..81f5227410 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -1341,9 +1341,10 @@ static int winbind_auth_request(pam_handle_t * pamh, /* If winbindd returned a username, return the pointer to it * here. */ - if (user_ret && response.extra_data.data) { + if (user_ret && response.data.auth.unix_username[0]) { /* We have to trust it's a null terminated string. */ - *user_ret = (char *)response.extra_data.data; + *user_ret = strndup(response.data.auth.unix_username, + sizeof(response.data.auth.unix_username) - 1); } } diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 9d1a56536b..ee51cce835 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -904,19 +904,17 @@ static bool wbinfo_auth(char *username) static bool wbinfo_auth_crap(char *username) { - struct winbindd_request request; - struct winbindd_response response; - NSS_STATUS result; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcAuthUserParams params; + struct wbcAuthUserInfo *info = NULL; + struct wbcAuthErrorInfo *err = NULL; + DATA_BLOB lm = data_blob_null; + DATA_BLOB nt = data_blob_null; fstring name_user; fstring name_domain; fstring pass; char *p; - /* Send off request */ - - ZERO_STRUCT(request); - ZERO_STRUCT(response); - p = strchr(username, '%'); if (p) { @@ -926,29 +924,30 @@ static bool wbinfo_auth_crap(char *username) parse_wbinfo_domain_user(username, name_domain, name_user); - request.data.auth_crap.logon_parameters = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT; + params.account_name = name_user; + params.domain_name = name_domain; + params.workstation_name = NULL; - fstrcpy(request.data.auth_crap.user, name_user); + params.flags = 0; + params.parameter_control= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | + WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT; - fstrcpy(request.data.auth_crap.domain, name_domain); + params.level = WBC_AUTH_USER_LEVEL_RESPONSE; - generate_random_buffer(request.data.auth_crap.chal, 8); + generate_random_buffer(params.password.response.challenge, 8); if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; DATA_BLOB names_blob; - DATA_BLOB lm_response; - DATA_BLOB nt_response; - - server_chal = data_blob(request.data.auth_crap.chal, 8); + server_chal = data_blob(params.password.response.challenge, 8); /* Pretend this is a login to 'us', for blob purposes */ names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup()); if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal, &names_blob, - &lm_response, &nt_response, NULL)) { + &lm, &nt, NULL)) { data_blob_free(&names_blob); data_blob_free(&server_chal); return false; @@ -956,47 +955,47 @@ static bool wbinfo_auth_crap(char *username) data_blob_free(&names_blob); data_blob_free(&server_chal); - memcpy(request.data.auth_crap.nt_resp, nt_response.data, - MIN(nt_response.length, - sizeof(request.data.auth_crap.nt_resp))); - request.data.auth_crap.nt_resp_len = nt_response.length; - - memcpy(request.data.auth_crap.lm_resp, lm_response.data, - MIN(lm_response.length, - sizeof(request.data.auth_crap.lm_resp))); - request.data.auth_crap.lm_resp_len = lm_response.length; - - data_blob_free(&nt_response); - data_blob_free(&lm_response); - } else { - if (lp_client_lanman_auth() - && SMBencrypt(pass, request.data.auth_crap.chal, - (uchar *)request.data.auth_crap.lm_resp)) { - request.data.auth_crap.lm_resp_len = 24; - } else { - request.data.auth_crap.lm_resp_len = 0; + if (lp_client_lanman_auth()) { + bool ok; + lm = data_blob(NULL, 24); + ok = SMBencrypt(pass, params.password.response.challenge, + lm.data); + if (!ok) { + data_blob_free(&lm); + } } - SMBNTencrypt(pass, request.data.auth_crap.chal, - (uchar *)request.data.auth_crap.nt_resp); - - request.data.auth_crap.nt_resp_len = 24; + nt = data_blob(NULL, 24); + SMBNTencrypt(pass, params.password.response.challenge, + nt.data); } - result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response); + params.password.response.nt_length = nt.length; + params.password.response.nt_data = nt.data; + params.password.response.lm_length = lm.length; + params.password.response.lm_data = lm.data; + + wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); /* Display response */ d_printf("challenge/response password authentication %s\n", - (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); + WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); - if (response.data.auth.nt_status) + if (wbc_status == WBC_ERR_AUTH_ERROR) { d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n", - response.data.auth.nt_status_string, - response.data.auth.nt_status, - response.data.auth.error_string); + err->nt_string, + err->nt_status, + err->display_string); + wbcFreeMemory(err); + } else if (WBC_ERROR_IS_OK(wbc_status)) { + wbcFreeMemory(info); + } - return result == NSS_STATUS_SUCCESS; + data_blob_free(&nt); + data_blob_free(&lm); + + return WBC_ERROR_IS_OK(wbc_status); } /* Authenticate a user with a plaintext password and set a token */ diff --git a/source3/nsswitch/winbind_struct_protocol.h b/source3/nsswitch/winbind_struct_protocol.h index 12ca1e55c8..e81813c77b 100644 --- a/source3/nsswitch/winbind_struct_protocol.h +++ b/source3/nsswitch/winbind_struct_protocol.h @@ -431,6 +431,7 @@ struct winbindd_response { fstring logon_srv; fstring logon_dom; } info3; + fstring unix_username; } auth; struct { fstring name; diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c index c822fc78b9..35649dfda2 100644 --- a/source3/nsswitch/wins.c +++ b/source3/nsswitch/wins.c @@ -147,7 +147,7 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count) { int fd; - struct in_addr ip; + struct sockaddr_storage ss; struct nmb_name nname; NODE_STATUS_STRUCT *status; @@ -160,8 +160,10 @@ static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count) return NULL; make_nmb_name(&nname, "*", 0); - (void)interpret_addr2(&ip,addr); - status = node_status_query(fd,&nname,ip, count, NULL); + if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) { + return NULL; + } + status = node_status_query(fd, &nname, &ss, count, NULL); close(fd); return status; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 3737224275..5651a435de 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -52,6 +52,7 @@ */ #include "includes.h" +#include "libnet/libnet.h" bool in_client = False; /* Not in the client by default */ bool bLoaded = False; @@ -71,7 +72,8 @@ extern userdom_struct current_user_info; #define HOMES_NAME "homes" #endif -static int regdb_last_seqnum = 0; +static uint64_t conf_last_seqnum = 0; +static struct libnet_conf_ctx *conf_ctx = NULL; #define CONFIG_BACKEND_FILE 0 #define CONFIG_BACKEND_REGISTRY 1 @@ -418,6 +420,7 @@ typedef struct { bool bRead_only; bool bNo_set_dir; bool bGuest_only; + bool bAdministrative_share; bool bGuest_ok; bool bPrint_ok; bool bMap_system; @@ -560,6 +563,7 @@ static service sDefault = { True, /* bRead_only */ True, /* bNo_set_dir */ False, /* bGuest_only */ + False, /* bAdministrative_share */ False, /* bGuest_ok */ False, /* bPrint_ok */ False, /* bMap_system */ @@ -969,6 +973,7 @@ static struct parm_struct parm_table[] = { {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE}, + {"administrative share", P_BOOL, P_LOCAL, &sDefault.bAdministrative_share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE}, @@ -2135,6 +2140,7 @@ FN_LOCAL_BOOL(lp_readonly, bRead_only) FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir) FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok) FN_LOCAL_BOOL(lp_guest_only, bGuest_only) +FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share) FN_LOCAL_BOOL(lp_print_ok, bPrint_ok) FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden) FN_LOCAL_BOOL(lp_map_archive, bMap_archive) @@ -2249,8 +2255,7 @@ static param_opt_struct *get_parametrics(int snum, const char *type, const char data = ServicePtrs[snum]->param_opt; } - asprintf(¶m_key, "%s:%s", type, option); - if (!param_key) { + if (asprintf(¶m_key, "%s:%s", type, option) == -1) { DEBUG(0,("asprintf failed!\n")); return NULL; } @@ -2773,6 +2778,7 @@ static bool lp_add_ipc(const char *ipc_name, bool guest_ok) ServicePtrs[i]->bAvailable = True; ServicePtrs[i]->bRead_only = True; ServicePtrs[i]->bGuest_only = False; + ServicePtrs[i]->bAdministrative_share = True; ServicePtrs[i]->bGuest_ok = guest_ok; ServicePtrs[i]->bPrint_ok = False; ServicePtrs[i]->bBrowseable = sDefault.bBrowseable; @@ -3378,241 +3384,46 @@ bool service_ok(int iService) } /* - * lp_regdb_open - regdb helper function - * - * this should be considered an interim solution that becomes - * superfluous once the registry code has been rewritten - * do allow use of the tdb portion of the registry alone. - * - * in the meanwhile this provides a lean access - * to the registry globals. - */ - -static struct tdb_wrap *lp_regdb_open(void) -{ - struct tdb_wrap *reg_tdb = NULL; - const char *vstring = "INFO/version"; - uint32 vers_id; - - become_root(); - reg_tdb = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, - REG_TDB_FLAGS, O_RDWR, 0600); - unbecome_root(); - if (!reg_tdb) { - DEBUG(1, ("lp_regdb_open: failed to open %s: %s\n", - state_path("registry.tdb"), strerror(errno))); - goto done; - } - else { - DEBUG(10, ("lp_regdb_open: reg tdb opened.\n")); - } - - vers_id = tdb_fetch_int32(reg_tdb->tdb, vstring); - if (vers_id != REGVER_V1) { - DEBUG(10, ("lp_regdb_open: INFO: registry tdb %s has wrong " - "INFO/version (got %d, expected %d)\n", - state_path("registry.tdb"), vers_id, REGVER_V1)); - /* this is apparently not implemented in the tdb */ - } - -done: - return reg_tdb; -} - -/* * process_registry_globals - * - * this is the interim version of process_registry globals - * - * until we can do it as we would like using the api and only - * using the tdb portion of the registry (see below), - * this just provides the needed functionality of regdb_fetch_values - * and regdb_unpack_values, circumventing any fancy stuff, to - * give us access to the registry globals. */ static bool process_registry_globals(bool (*pfunc)(const char *, const char *)) { - bool ret = False; - struct tdb_wrap *reg_tdb = NULL; - WERROR err; - char *keystr; - TDB_DATA data; - /* vars for the tdb unpack loop */ - int len = 0; - int i; - int buflen; - uint8 *buf; - uint32 type; - uint32 size; - uint32 num_values = 0; - uint8 *data_p; - char * valstr; - struct registry_value *value = NULL; - - ZERO_STRUCT(data); - - reg_tdb = lp_regdb_open(); - if (!reg_tdb) { - DEBUG(1, ("Error opening the registry!\n")); - goto done; - } - - /* reg_tdb is from now on used as talloc ctx. - * freeing it closes the tdb (if refcount is 0) */ - - keystr = talloc_asprintf(reg_tdb,"%s/%s/%s", REG_VALUE_PREFIX, - KEY_SMBCONF, GLOBAL_NAME); - normalize_dbkey(keystr); - - DEBUG(10, ("process_registry_globals: fetching key '%s'\n", - keystr)); - - data = tdb_fetch_bystring(reg_tdb->tdb, keystr); - if (!data.dptr) { - ret = True; - goto done; - } - - buf = data.dptr; - buflen = data.dsize; - - /* unpack number of values */ - len = tdb_unpack(buf, buflen, "d", &num_values); - DEBUG(10, ("process_registry_globals: got %d values from tdb\n", - num_values)); - - /* unpack the values */ - for (i=0; i < num_values; i++) { - fstring valname; - type = REG_NONE; - size = 0; - data_p = NULL; - len += tdb_unpack(buf+len, buflen-len, "fdB", - valname, - &type, - &size, - &data_p); - if (registry_smbconf_valname_forbidden(valname)) { - DEBUG(10, ("process_registry_globals: Ignoring " - "parameter '%s' in registry.\n", valname)); - continue; - } - DEBUG(10, ("process_registry_globals: got value '%s'\n", - valname)); - if (size && data_p) { - err = registry_pull_value(reg_tdb, - &value, - (enum winreg_Type)type, - data_p, - size, - size); - SAFE_FREE(data_p); - if (!W_ERROR_IS_OK(err)) { - goto done; - } - switch(type) { - case REG_DWORD: - valstr = talloc_asprintf(reg_tdb, "%d", - value->v.dword); - pfunc(valname, valstr); - break; - case REG_SZ: - pfunc(valname, value->v.sz.str); - break; - default: - /* ignore other types */ - break; - } + WERROR werr; + char **param_names; + char **param_values; + uint32_t num_params; + uint32_t count; + TALLOC_CTX *mem_ctx = talloc_stackframe(); + bool ret = false; + + if (conf_ctx == NULL) { + /* first time */ + werr = libnet_conf_open(NULL, &conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + goto done; } } - ret = pfunc("registry shares", "yes"); - regdb_last_seqnum = tdb_get_seqnum(reg_tdb->tdb); - -done: - TALLOC_FREE(reg_tdb); - SAFE_FREE(data.dptr); - return ret; -} - -#if 0 -/* - * this is process_registry_globals as it _should_ be (roughly) - * using the reg_api functions... - * - * We are *not* currently doing it like this due to the large - * linker dependecies of the registry code (see above). - */ -static bool process_registry_globals(bool (*pfunc)(const char *, const char *)) -{ - bool ret = False; - TALLOC_CTX *ctx = NULL; - char *regpath = NULL; - WERROR werr = WERR_OK; - struct registry_key *key = NULL; - struct registry_value *value = NULL; - char *valname = NULL; - char *valstr = NULL; - uint32 idx = 0; - NT_USER_TOKEN *token = NULL; - - ctx = talloc_init("process_registry_globals"); - if (!ctx) { - smb_panic("Failed to create talloc context!"); - } - - if (!registry_init_regdb()) { - DEBUG(1, ("Error initializing the registry.\n")); - goto done; - } - - werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token)); + werr = libnet_conf_get_share(mem_ctx, conf_ctx, GLOBAL_NAME, + &num_params, ¶m_names, ¶m_values); if (!W_ERROR_IS_OK(werr)) { - DEBUG(1, ("Error creating admin token: %s\n",dos_errstr(werr))); goto done; } - regpath = talloc_asprintf(ctx,"%s\\%s", KEY_SMBCONF, GLOBAL_NAME); - werr = reg_open_path(ctx, regpath, REG_KEY_READ, token, &key); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(1, ("Registry smbconf global section does not exist.\n")); - DEBUGADD(1, ("Error opening registry path '%s\\%s: %s\n", - KEY_SMBCONF, GLOBAL_NAME, dos_errstr(werr))); - goto done; - } - - for (idx = 0; - W_ERROR_IS_OK(werr = reg_enumvalue(ctx, key, idx, &valname, - &value)); - idx++) - { - DEBUG(5, ("got global registry parameter '%s'\n", valname)); - switch(value->type) { - case REG_DWORD: - valstr = talloc_asprintf(ctx, "%d", value->v.dword); - pfunc(valname, valstr); - TALLOC_FREE(valstr); - break; - case REG_SZ: - pfunc(valname, value->v.sz.str); - break; - default: - /* ignore other types */ - break; + for (count = 0; count < num_params; count++) { + ret = pfunc(param_names[count], param_values[count]); + if (ret != true) { + goto done; } - TALLOC_FREE(value); - TALLOC_FREE(valstr); } ret = pfunc("registry shares", "yes"); - - regdb_last_seqnum = regdb_get_seqnum(); + conf_last_seqnum = libnet_conf_get_seqnum(conf_ctx, NULL, NULL); done: - talloc_destroy(ctx); + TALLOC_FREE(mem_ctx); return ret; } -#endif /* if 0 */ static struct file_lists { struct file_lists *next; @@ -3675,17 +3486,26 @@ bool lp_config_backend_is_registry(void) bool lp_file_list_changed(void) { struct file_lists *f = file_lists; - struct tdb_wrap *reg_tdb = NULL; DEBUG(6, ("lp_file_list_changed()\n")); if (lp_config_backend() == CONFIG_BACKEND_REGISTRY) { - reg_tdb = lp_regdb_open(); - if (reg_tdb && (regdb_last_seqnum != tdb_get_seqnum(reg_tdb->tdb))) - { - DEBUGADD(6, ("regdb seqnum changed: old = %d, new = %d\n", - regdb_last_seqnum, tdb_get_seqnum(reg_tdb->tdb))); - TALLOC_FREE(reg_tdb); + uint64_t conf_cur_seqnum; + if (conf_ctx == NULL) { + WERROR werr; + werr = libnet_conf_open(NULL, &conf_ctx); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0, ("error opening configuration: %s\n", + dos_errstr(werr))); + return false; + } + } + conf_cur_seqnum = libnet_conf_get_seqnum(conf_ctx, NULL, NULL); + if (conf_last_seqnum != conf_cur_seqnum) { + DEBUGADD(6, ("regdb seqnum changed: old = %llu, " + "new = %llu\n", + (unsigned long long)conf_last_seqnum, + (unsigned long long)conf_cur_seqnum)); return true; } else { /* diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index d1599047a7..8fafcbbbd4 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -128,7 +128,10 @@ static DOM_SID *pdb_generate_sam_sid(void) } /* check for an old MACHINE.SID file for backwards compatibility */ - asprintf(&fname, "%s/MACHINE.SID", lp_private_dir()); + if (asprintf(&fname, "%s/MACHINE.SID", lp_private_dir()) == -1) { + SAFE_FREE(sam_sid); + return NULL; + } if (read_sid_from_file(fname, sam_sid)) { /* remember it for future reference and unlink the old MACHINE.SID */ diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 70b9dcd3b5..46dab156ee 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -206,7 +206,7 @@ static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *p /* Now deal with the user SID. If we have a backend that can generate RIDs, then do so. But sometimes the caller just wanted a structure initialized and will fill in these fields later (such as from a - NET_USER_INFO_3 structure) */ + netr_SamInfo3 structure) */ if ( create && !pdb_rid_algorithm() ) { uint32 user_rid; diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 3b55dd478f..c427d41e23 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -538,7 +538,7 @@ bool pdb_set_user_sid_from_string(struct samu *sampass, fstring u_sid, enum pdb_ We never fill this in from a passdb backend but rather set is based on the user's primary group membership. However, the struct samu* is overloaded and reused in domain memship code - as well and built from the NET_USER_INFO_3 or PAC so we + as well and built from the netr_SamInfo3 or PAC so we have to allow the explicitly setting of a group SID here. ********************************************************************/ diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index da2f9f30da..dec9b5bafb 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -349,6 +349,7 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, filter = talloc_asprintf(talloc_tos(), "(&%s%s)", "(uid=%u)", get_objclass_filter(ldap_state->schema_ver)); if (!filter) { + SAFE_FREE(escape_user); return LDAP_NO_MEMORY; } /* @@ -358,10 +359,10 @@ int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, filter = talloc_all_string_sub(talloc_tos(), filter, "%u", escape_user); + SAFE_FREE(escape_user); if (!filter) { return LDAP_NO_MEMORY; } - SAFE_FREE(escape_user); ret = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result); @@ -2683,7 +2684,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, goto done; } - rc = smbldap_search(conn, lp_ldap_user_suffix(), + rc = smbldap_search(conn, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0, &result); @@ -2739,7 +2740,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, LDAP_OBJ_SAMBASAMACCOUNT, gidstr); - rc = smbldap_search(conn, lp_ldap_user_suffix(), + rc = smbldap_search(conn, lp_ldap_suffix(), LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0, &result); @@ -6264,7 +6265,7 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location) entry, get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), - NULL); + talloc_tos()); if (domain_sid_string) { bool found_sid; @@ -6300,7 +6301,7 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location) entry, get_attr_key2string( dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE ), - NULL); + talloc_tos()); if (alg_rid_base_string) { alg_rid_base = (uint32)atol(alg_rid_base_string); if (alg_rid_base != algorithmic_rid_base()) { diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 9c4009368d..e52aaacb4d 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -43,8 +43,8 @@ * 0x10 winreg_QueryInfoKey reg_queryinfokey * 0x11 winreg_QueryValue reg_queryvalue * 0x12 winreg_ReplaceKey - * 0x13 winreg_RestoreKey - * 0x14 winreg_SaveKey + * 0x13 winreg_RestoreKey reg_restorekey + * 0x14 winreg_SaveKey reg_savekey * 0x15 winreg_SetKeySecurity reg_setkeysecurity * 0x16 winreg_SetValue reg_setvalue * 0x17 winreg_UnLoadKey @@ -63,6 +63,7 @@ */ #include "includes.h" +#include "regfio.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY @@ -696,6 +697,279 @@ WERROR reg_getversion(uint32_t *version) return WERR_OK; } +/******************************************************************* + Note: topkeypat is the *full* path that this *key will be + loaded into (including the name of the key) + ********************************************************************/ + +static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, + REGF_NK_REC *key) +{ + REGF_NK_REC *subkey; + REGISTRY_KEY registry_key; + REGVAL_CTR *values; + REGSUBKEY_CTR *subkeys; + int i; + char *path = NULL; + WERROR result = WERR_OK; + + /* initialize the REGISTRY_KEY structure */ + + registry_key.hook = reghook_cache_find(topkeypath); + if (!registry_key.hook) { + DEBUG(0, ("reg_load_tree: Failed to assigned a REGISTRY_HOOK " + "to [%s]\n", topkeypath)); + return WERR_BADFILE; + } + + registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath); + if (!registry_key.name) { + DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n")); + return WERR_NOMEM; + } + + /* now start parsing the values and subkeys */ + + subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); + if (subkeys == NULL) { + return WERR_NOMEM; + } + + values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); + if (values == NULL) { + return WERR_NOMEM; + } + + /* copy values into the REGVAL_CTR */ + + for (i=0; i<key->num_values; i++) { + regval_ctr_addvalue(values, key->values[i].valuename, + key->values[i].type, + (char*)key->values[i].data, + (key->values[i].data_size & ~VK_DATA_IN_OFFSET)); + } + + /* copy subkeys into the REGSUBKEY_CTR */ + + key->subkey_index = 0; + while ((subkey = regfio_fetch_subkey( regfile, key ))) { + regsubkey_ctr_addkey(subkeys, subkey->keyname); + } + + /* write this key and values out */ + + if (!store_reg_values(®istry_key, values) + || !store_reg_keys(®istry_key, subkeys)) + { + DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); + result = WERR_REG_IO_FAILURE; + } + + TALLOC_FREE(subkeys); + + if (!W_ERROR_IS_OK(result)) { + return result; + } + + /* now continue to load each subkey registry tree */ + + key->subkey_index = 0; + while ((subkey = regfio_fetch_subkey(regfile, key))) { + path = talloc_asprintf(regfile->mem_ctx, + "%s\\%s", + topkeypath, + subkey->keyname); + if (path == NULL) { + return WERR_NOMEM; + } + result = reg_load_tree(regfile, path, subkey); + if (!W_ERROR_IS_OK(result)) { + break; + } + } + + return result; +} + +/******************************************************************* + ********************************************************************/ + +static WERROR restore_registry_key(REGISTRY_KEY *krecord, const char *fname) +{ + REGF_FILE *regfile; + REGF_NK_REC *rootkey; + WERROR result; + + /* open the registry file....fail if the file already exists */ + + regfile = regfio_open(fname, (O_RDONLY), 0); + if (regfile == NULL) { + DEBUG(0, ("restore_registry_key: failed to open \"%s\" (%s)\n", + fname, strerror(errno))); + return ntstatus_to_werror(map_nt_error_from_unix(errno)); + } + + /* get the rootkey from the regf file and then load the tree + via recursive calls */ + + if (!(rootkey = regfio_rootkey(regfile))) { + regfio_close(regfile); + return WERR_REG_FILE_INVALID; + } + + result = reg_load_tree(regfile, krecord->name, rootkey); + + /* cleanup */ + + regfio_close(regfile); + + return result; +} + +WERROR reg_restorekey(struct registry_key *key, const char *fname) +{ + return restore_registry_key(key->key, fname); +} + +/******************************************************************** +********************************************************************/ + +static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, + REGF_NK_REC *parent) +{ + REGF_NK_REC *key; + REGVAL_CTR *values; + REGSUBKEY_CTR *subkeys; + int i, num_subkeys; + char *key_tmp = NULL; + char *keyname, *parentpath; + char *subkeypath = NULL; + char *subkeyname; + REGISTRY_KEY registry_key; + WERROR result = WERR_OK; + SEC_DESC *sec_desc = NULL; + + if (!regfile) { + return WERR_GENERAL_FAILURE; + } + + if (!keypath) { + return WERR_OBJECT_PATH_INVALID; + } + + /* split up the registry key path */ + + key_tmp = talloc_strdup(regfile->mem_ctx, keypath); + if (!key_tmp) { + return WERR_NOMEM; + } + if (!reg_split_key(key_tmp, &parentpath, &keyname)) { + return WERR_OBJECT_PATH_INVALID; + } + + if (!keyname) { + keyname = parentpath; + } + + /* we need a REGISTRY_KEY object here to enumerate subkeys and values */ + + ZERO_STRUCT(registry_key); + + registry_key.name = talloc_strdup(regfile->mem_ctx, keypath); + if (registry_key.name == NULL) { + return WERR_NOMEM; + } + + registry_key.hook = reghook_cache_find(registry_key.name); + if (registry_key.hook == NULL) { + return WERR_BADFILE; + } + + /* lookup the values and subkeys */ + + subkeys = TALLOC_ZERO_P(regfile->mem_ctx, REGSUBKEY_CTR); + if (subkeys == NULL) { + return WERR_NOMEM; + } + + values = TALLOC_ZERO_P(subkeys, REGVAL_CTR); + if (values == NULL) { + return WERR_NOMEM; + } + + fetch_reg_keys(®istry_key, subkeys); + fetch_reg_values(®istry_key, values); + + result = regkey_get_secdesc(regfile->mem_ctx, ®istry_key, &sec_desc); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* write out this key */ + + key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc, + parent); + if (key == NULL) { + result = WERR_CAN_NOT_COMPLETE; + goto done; + } + + /* write each one of the subkeys out */ + + num_subkeys = regsubkey_ctr_numkeys(subkeys); + for (i=0; i<num_subkeys; i++) { + subkeyname = regsubkey_ctr_specific_key(subkeys, i); + subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s", + keypath, subkeyname); + if (subkeypath == NULL) { + result = WERR_NOMEM; + goto done; + } + result = reg_write_tree(regfile, subkeypath, key); + if (!W_ERROR_IS_OK(result)) + goto done; + } + + DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath)); + +done: + TALLOC_FREE(subkeys); + TALLOC_FREE(registry_key.name); + + return result; +} + +static WERROR backup_registry_key(REGISTRY_KEY *krecord, const char *fname) +{ + REGF_FILE *regfile; + WERROR result; + + /* open the registry file....fail if the file already exists */ + + regfile = regfio_open(fname, (O_RDWR|O_CREAT|O_EXCL), + (S_IREAD|S_IWRITE)); + if (regfile == NULL) { + DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", + fname, strerror(errno) )); + return ntstatus_to_werror(map_nt_error_from_unix(errno)); + } + + /* write the registry tree to the file */ + + result = reg_write_tree(regfile, krecord->name, NULL); + + /* cleanup */ + + regfio_close(regfile); + + return result; +} + +WERROR reg_savekey(struct registry_key *key, const char *fname) +{ + return backup_registry_key(key->key, fname); +} + /********************************************************************** * Higher level utility functions **********************************************************************/ @@ -726,9 +1000,7 @@ WERROR reg_deleteallvalues(struct registry_key *key) } /* - * Utility function to open a complete registry path including the hive - * prefix. This should become the replacement function for - * regkey_open_internal. + * Utility function to open a complete registry path including the hive prefix. */ WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path, diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index e162fb587f..518078a062 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -258,8 +258,11 @@ bool regdb_init( void ) const char *vstring = "INFO/version"; uint32 vers_id; - if ( tdb_reg ) + if ( tdb_reg ) { + DEBUG(10,("regdb_init: incrementing refcount (%d)\n", tdb_refcount)); + tdb_refcount++; return true; + } if ( !(tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600)) ) { @@ -451,7 +454,8 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) regdb_fetch_keys(key, old_subkeys); - if (ctr->num_subkeys == old_subkeys->num_subkeys) { + if ((ctr->num_subkeys && old_subkeys->num_subkeys) && + (ctr->num_subkeys == old_subkeys->num_subkeys)) { for (i = 0; i<ctr->num_subkeys; i++) { if (strcmp(ctr->subkeys[i], @@ -547,6 +551,22 @@ bool regdb_store_keys(const char *key, REGSUBKEY_CTR *ctr) /* now create records for any subkeys that don't already exist */ num_subkeys = regsubkey_ctr_numkeys(ctr); + + if (num_subkeys == 0) { + if (!(subkeys = TALLOC_ZERO_P(ctr, REGSUBKEY_CTR)) ) { + DEBUG(0,("regdb_store_keys: talloc() failure!\n")); + goto fail; + } + + if (!regdb_store_keys_internal(key, subkeys)) { + DEBUG(0,("regdb_store_keys: Failed to store " + "new record for key [%s]\n", key)); + goto fail; + } + TALLOC_FREE(subkeys); + + } + for (i=0; i<num_subkeys; i++) { path = talloc_asprintf(ctx, "%s/%s", key, diff --git a/source3/registry/reg_dispatcher.c b/source3/registry/reg_dispatcher.c index e6e7613457..cdcd045904 100644 --- a/source3/registry/reg_dispatcher.c +++ b/source3/registry/reg_dispatcher.c @@ -34,7 +34,7 @@ static const struct generic_mapping reg_generic_map = /******************************************************************** ********************************************************************/ -static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx ) +static WERROR construct_registry_sd(TALLOC_CTX *ctx, SEC_DESC **psd) { SEC_ACE ace[3]; SEC_ACCESS mask; @@ -45,28 +45,39 @@ static SEC_DESC* construct_registry_sd( TALLOC_CTX *ctx ) /* basic access for Everyone */ - init_sec_access(&mask, REG_KEY_READ ); - init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + init_sec_access(&mask, REG_KEY_READ); + init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, + mask, 0); /* Full Access 'BUILTIN\Administrators' */ - init_sec_access(&mask, REG_KEY_ALL ); - init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + init_sec_access(&mask, REG_KEY_ALL); + init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, + SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); /* Full Access 'NT Authority\System' */ init_sec_access(&mask, REG_KEY_ALL ); - init_sec_ace(&ace[i++], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); + init_sec_ace(&ace[i++], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED, + mask, 0); /* create the security descriptor */ - if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) ) - return NULL; + acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace); + if (acl == NULL) { + return WERR_NOMEM; + } - if ( !(sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, acl, &sd_size)) ) - return NULL; + sd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, + &global_sid_Builtin_Administrators, + &global_sid_System, NULL, acl, + &sd_size); + if (sd == NULL) { + return WERR_NOMEM; + } - return sd; + *psd = sd; + return WERR_OK; } /*********************************************************************** @@ -176,19 +187,19 @@ WERROR regkey_get_secdesc(TALLOC_CTX *mem_ctx, REGISTRY_KEY *key, struct security_descriptor **psecdesc) { struct security_descriptor *secdesc; + WERROR werr; if (key->hook && key->hook->ops && key->hook->ops->get_secdesc) { - WERROR err; - - err = key->hook->ops->get_secdesc(mem_ctx, key->name, - psecdesc); - if (W_ERROR_IS_OK(err)) { + werr = key->hook->ops->get_secdesc(mem_ctx, key->name, + psecdesc); + if (W_ERROR_IS_OK(werr)) { return WERR_OK; } } - if (!(secdesc = construct_registry_sd(mem_ctx))) { - return WERR_NOMEM; + werr = construct_registry_sd(mem_ctx, &secdesc); + if (!W_ERROR_IS_OK(werr)) { + return werr; } *psecdesc = secdesc; diff --git a/source3/registry/reg_init_smbconf.c b/source3/registry/reg_init_smbconf.c index 6452b0b15b..b7e6add112 100644 --- a/source3/registry/reg_init_smbconf.c +++ b/source3/registry/reg_init_smbconf.c @@ -67,13 +67,13 @@ done: * for use in places where not the whole registry is needed, * e.g. utils/net_conf.c and loadparm.c */ -bool registry_init_regdb(void) +bool registry_init_smbconf(void) { bool ret = false; int saved_errno = 0; static REGISTRY_HOOK smbconf_reg_hook = {KEY_SMBCONF, &smbconf_reg_ops}; - DEBUG(10, ("registry_init_regdb called\n")); + DEBUG(10, ("registry_init_smbconf called\n")); if (!regdb_init()) { saved_errno = errno; diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c index 3740ff0ee4..1c3aad7a25 100644 --- a/source3/registry/regfio.c +++ b/source3/registry/regfio.c @@ -1171,7 +1171,6 @@ out: if ( !(rb->mem_ctx = talloc_init( "read_regf_block" )) ) { regfio_close( rb ); - SAFE_FREE(rb); return NULL; } @@ -1182,7 +1181,6 @@ out: if ( (rb->fd = open(filename, flags, mode)) == -1 ) { DEBUG(0,("regfio_open: failure to open %s (%s)\n", filename, strerror(errno))); regfio_close( rb ); - SAFE_FREE(rb); return NULL; } @@ -1192,7 +1190,6 @@ out: if ( !init_regf_block( rb ) ) { DEBUG(0,("regfio_open: Failed to read initial REGF block\n")); regfio_close( rb ); - SAFE_FREE(rb); return NULL; } @@ -1205,7 +1202,6 @@ out: if ( !read_regf_block( rb ) ) { DEBUG(0,("regfio_open: Failed to read initial REGF block\n")); regfio_close( rb ); - SAFE_FREE(rb); return NULL; } diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index c42938d6e9..2759881dd3 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -6,6 +6,7 @@ Copyright (C) Rafal Szczesniak 2002 Copyright (C) Jeremy Allison 2005. Copyright (C) Michael Adam 2007. + Copyright (C) Guenther Deschner 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 @@ -128,13 +129,16 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, char **names, enum lsa_SidType *types) { - prs_struct qbuf, rbuf; - LSA_Q_LOOKUP_SIDS q; - LSA_R_LOOKUP_SIDS r; - DOM_R_REF ref; NTSTATUS result = NT_STATUS_OK; TALLOC_CTX *tmp_ctx = NULL; int i; + struct lsa_SidArray sid_array; + struct lsa_RefDomainList *ref_domains = NULL; + struct lsa_TransNameArray lsa_names; + uint32_t count = 0; + uint16_t level = 1; + + ZERO_STRUCT(lsa_names); tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { @@ -143,38 +147,42 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, goto done; } - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - init_q_lookup_sids(tmp_ctx, &q, pol, num_sids, sids, 1); - - ZERO_STRUCT(ref); + sid_array.num_sids = num_sids; + sid_array.sids = TALLOC_ARRAY(mem_ctx, struct lsa_SidPtr, num_sids); + if (!sid_array.sids) { + return NT_STATUS_NO_MEMORY; + } - r.dom_ref = &ref; + for (i = 0; i<num_sids; i++) { + sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]); + if (!sid_array.sids[i].sid) { + return NT_STATUS_NO_MEMORY; + } + } - CLI_DO_RPC( cli, tmp_ctx, PI_LSARPC, LSA_LOOKUPSIDS, - q, r, - qbuf, rbuf, - lsa_io_q_lookup_sids, - lsa_io_r_lookup_sids, - NT_STATUS_UNSUCCESSFUL ); + result = rpccli_lsa_LookupSids(cli, mem_ctx, + pol, + &sid_array, + &ref_domains, + &lsa_names, + level, + &count); DEBUG(10, ("LSA_LOOKUPSIDS returned '%s', mapped count = %d'\n", - nt_errstr(r.status), r.mapped_count)); + nt_errstr(result), count)); - if (!NT_STATUS_IS_OK(r.status) && - !NT_STATUS_EQUAL(r.status, NT_STATUS_NONE_MAPPED) && - !NT_STATUS_EQUAL(r.status, STATUS_SOME_UNMAPPED)) + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) && + !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { /* An actual error occured */ - result = r.status; goto done; } /* Return output parameters */ - if (NT_STATUS_EQUAL(r.status, NT_STATUS_NONE_MAPPED) || - (r.mapped_count == 0)) + if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) || + (count == 0)) { for (i = 0; i < num_sids; i++) { (names)[i] = NULL; @@ -186,21 +194,19 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, } for (i = 0; i < num_sids; i++) { - fstring name, dom_name; - uint32 dom_idx = r.names.name[i].domain_idx; + const char *name, *dom_name; + uint32_t dom_idx = lsa_names.names[i].sid_index; /* Translate optimised name through domain index array */ if (dom_idx != 0xffffffff) { - rpcstr_pull_unistr2_fstring( - dom_name, &ref.ref_dom[dom_idx].uni_dom_name); - rpcstr_pull_unistr2_fstring( - name, &r.names.uni_name[i]); + dom_name = ref_domains->domains[dom_idx].name.string; + name = lsa_names.names[i].name.string; (names)[i] = talloc_strdup(mem_ctx, name); (domains)[i] = talloc_strdup(mem_ctx, dom_name); - (types)[i] = r.names.name[i].sid_name_use; + (types)[i] = lsa_names.names[i].sid_type; if (((names)[i] == NULL) || ((domains)[i] == NULL)) { DEBUG(0, ("cli_lsa_lookup_sids_noalloc(): out of memory\n")); @@ -348,29 +354,32 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, DOM_SID **sids, enum lsa_SidType **types) { - prs_struct qbuf, rbuf; - LSA_Q_LOOKUP_NAMES q; - LSA_R_LOOKUP_NAMES r; - DOM_R_REF ref; NTSTATUS result; int i; + struct lsa_String *lsa_names = NULL; + struct lsa_RefDomainList *domains = NULL; + struct lsa_TransSidArray sid_array; + uint32_t count = 0; - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - ZERO_STRUCT(ref); - r.dom_ref = &ref; + ZERO_STRUCT(sid_array); - init_q_lookup_names(mem_ctx, &q, pol, num_names, names, level); + lsa_names = TALLOC_ARRAY(mem_ctx, struct lsa_String, num_names); + if (!lsa_names) { + return NT_STATUS_NO_MEMORY; + } - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPNAMES, - q, r, - qbuf, rbuf, - lsa_io_q_lookup_names, - lsa_io_r_lookup_names, - NT_STATUS_UNSUCCESSFUL); + for (i=0; i<num_names; i++) { + init_lsa_String(&lsa_names[i], names[i]); + } - result = r.status; + result = rpccli_lsa_LookupNames(cli, mem_ctx, + pol, + num_names, + lsa_names, + &domains, + &sid_array, + level, + &count); if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { @@ -382,7 +391,7 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, /* Return output parameters */ - if (r.mapped_count == 0) { + if (count == 0) { result = NT_STATUS_NONE_MAPPED; goto done; } @@ -417,9 +426,8 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, } for (i = 0; i < num_names; i++) { - DOM_RID *t_rids = r.dom_rid; - uint32 dom_idx = t_rids[i].rid_idx; - uint32 dom_rid = t_rids[i].rid; + uint32_t dom_idx = sid_array.sids[i].sid_index; + uint32_t dom_rid = sid_array.sids[i].rid; DOM_SID *sid = &(*sids)[i]; /* Translate optimised sid through domain index array */ @@ -431,320 +439,26 @@ NTSTATUS rpccli_lsa_lookup_names(struct rpc_pipe_client *cli, continue; } - sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid); + sid_copy(sid, domains->domains[dom_idx].sid); if (dom_rid != 0xffffffff) { sid_append_rid(sid, dom_rid); } - (*types)[i] = t_rids[i].type; + (*types)[i] = sid_array.sids[i].sid_type; if (dom_names == NULL) { continue; } - (*dom_names)[i] = rpcstr_pull_unistr2_talloc( - *dom_names, &ref.ref_dom[dom_idx].uni_dom_name); - } - - done: - - return result; -} - -/** Enumerate list of SIDs */ - -NTSTATUS rpccli_lsa_enum_sids(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length, - uint32 *num_sids, DOM_SID **sids) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_ACCOUNTS q; - LSA_R_ENUM_ACCOUNTS r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUM_ACCOUNTS, - q, r, - qbuf, rbuf, - lsa_io_q_enum_accounts, - lsa_io_r_enum_accounts, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - if (r.sids.num_entries==0) - goto done; - - /* Return output parameters */ - - *sids = TALLOC_ARRAY(mem_ctx, DOM_SID, r.sids.num_entries); - if (!*sids) { - DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Copy across names and sids */ - - for (i = 0; i < r.sids.num_entries; i++) { - sid_copy(&(*sids)[i], &r.sids.sid[i].sid); - } - - *num_sids= r.sids.num_entries; - *enum_ctx = r.enum_context; - - done: - - return result; -} - -/** Enumerate user privileges - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS rpccli_lsa_enum_privsaccount(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *count, LUID_ATTR **set) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUMPRIVSACCOUNT q; - LSA_R_ENUMPRIVSACCOUNT r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - init_lsa_q_enum_privsaccount(&q, pol); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMPRIVSACCOUNT, - q, r, - qbuf, rbuf, - lsa_io_q_enum_privsaccount, - lsa_io_r_enum_privsaccount, - NT_STATUS_UNSUCCESSFUL); - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - if (r.count == 0) - goto done; - - if (!((*set = TALLOC_ARRAY(mem_ctx, LUID_ATTR, r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i=0; i<r.count; i++) { - (*set)[i].luid.low = r.set.set[i].luid.low; - (*set)[i].luid.high = r.set.set[i].luid.high; - (*set)[i].attr = r.set.set[i].attr; + (*dom_names)[i] = domains->domains[dom_idx].name.string; } - *count=r.count; done: return result; } -/** Get a privilege value given its name */ - -NTSTATUS rpccli_lsa_lookup_priv_value(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, const char *name, LUID *luid) -{ - prs_struct qbuf, rbuf; - LSA_Q_LOOKUP_PRIV_VALUE q; - LSA_R_LOOKUP_PRIV_VALUE r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Marshall data and send request */ - - init_lsa_q_lookup_priv_value(&q, pol, name); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPPRIVVALUE, - q, r, - qbuf, rbuf, - lsa_io_q_lookup_priv_value, - lsa_io_r_lookup_priv_value, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - /* Return output parameters */ - - (*luid).low=r.luid.low; - (*luid).high=r.luid.high; - - done: - - return result; -} - -/* Enumerate account rights This is similar to enum_privileges but - takes a SID directly, avoiding the open_account call. -*/ - -NTSTATUS rpccli_lsa_enum_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, DOM_SID *sid, - uint32 *count, char ***priv_names) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_ACCT_RIGHTS q; - LSA_R_ENUM_ACCT_RIGHTS r; - NTSTATUS result; - int i; - fstring *privileges; - char **names; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Marshall data and send request */ - init_q_enum_acct_rights(&q, pol, 2, sid); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ENUMACCTRIGHTS, - q, r, - qbuf, rbuf, - lsa_io_q_enum_acct_rights, - lsa_io_r_enum_acct_rights, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - - *count = r.count; - if (! *count) { - goto done; - } - - - privileges = TALLOC_ARRAY( mem_ctx, fstring, *count ); - names = TALLOC_ARRAY( mem_ctx, char *, *count ); - - if ((privileges == NULL) || (names == NULL)) { - TALLOC_FREE(privileges); - TALLOC_FREE(names); - return NT_STATUS_NO_MEMORY; - } - - for ( i=0; i<*count; i++ ) { - UNISTR4 *uni_string = &r.rights->strings[i]; - - if ( !uni_string->string ) - continue; - - rpcstr_pull( privileges[i], uni_string->string->buffer, sizeof(privileges[i]), -1, STR_TERMINATE ); - - /* now copy to the return array */ - names[i] = talloc_strdup( mem_ctx, privileges[i] ); - } - - *priv_names = names; - -done: - - return result; -} - - - -/* add account rights to an account. */ - -NTSTATUS rpccli_lsa_add_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, DOM_SID sid, - uint32 count, const char **privs_name) -{ - prs_struct qbuf, rbuf; - LSA_Q_ADD_ACCT_RIGHTS q; - LSA_R_ADD_ACCT_RIGHTS r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Marshall data and send request */ - init_q_add_acct_rights(&q, pol, &sid, count, privs_name); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_ADDACCTRIGHTS, - q, r, - qbuf, rbuf, - lsa_io_q_add_acct_rights, - lsa_io_r_add_acct_rights, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } -done: - - return result; -} - - -/* remove account rights for an account. */ - -NTSTATUS rpccli_lsa_remove_account_rights(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, DOM_SID sid, bool removeall, - uint32 count, const char **privs_name) -{ - prs_struct qbuf, rbuf; - LSA_Q_REMOVE_ACCT_RIGHTS q; - LSA_R_REMOVE_ACCT_RIGHTS r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Marshall data and send request */ - init_q_remove_acct_rights(&q, pol, &sid, removeall?1:0, count, privs_name); - - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_REMOVEACCTRIGHTS, - q, r, - qbuf, rbuf, - lsa_io_q_remove_acct_rights, - lsa_io_r_remove_acct_rights, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - goto done; - } -done: - - return result; -} - - #if 0 /** An example of how to use the routines in this file. Fetch a DOMAIN diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index a6167bb851..2af514320e 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -1,20 +1,21 @@ -/* +/* Unix SMB/CIFS implementation. NT Domain Authentication SMB / MSRPC client Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Jeremy Allison 1998. Largely re-written by Jeremy Allison (C) 2005. + Copyright (C) Guenther Deschner 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/>. */ @@ -27,57 +28,19 @@ private data. Only call this via rpccli_netlogon_setup_creds(). JRA. */ -static NTSTATUS rpccli_net_req_chal(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *server_name, - const char *clnt_name, - const DOM_CHAL *clnt_chal_in, - DOM_CHAL *srv_chal_out) -{ - prs_struct qbuf, rbuf; - NET_Q_REQ_CHAL q; - NET_R_REQ_CHAL r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - /* create and send a MSRPC command with api NET_REQCHAL */ - - DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s\n", - clnt_name, server_name)); - - /* store the parameters */ - init_q_req_chal(&q, server_name, clnt_name, clnt_chal_in); - - /* Marshall data and send request */ - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_REQCHAL, - q, r, - qbuf, rbuf, - net_io_q_req_chal, - net_io_r_req_chal, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - /* Return result */ - - if (NT_STATUS_IS_OK(result)) { - /* Store the returned server challenge. */ - *srv_chal_out = r.srv_chal; - } - - return result; -} +/* instead of rpccli_net_req_chal() we use rpccli_netr_ServerReqChallenge() now - gd */ #if 0 /**************************************************************************** LSA Authenticate 2 Send the client credential, receive back a server credential. -Ensure that the server credential returned matches the session key +Ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ - NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli, - uint16 sec_chan, + NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli, + uint16 sec_chan, uint32 *neg_flags, DOM_CHAL *srv_chal) { prs_struct qbuf, rbuf; @@ -90,7 +53,7 @@ encrypt of the server challenge originally received. JRA. fstr_sprintf( machine_acct, "%s$", lp_workgroup() ); else fstrcpy( machine_acct, cli->mach_acct ); - + /* create and send a MSRPC command with api NET_AUTH2 */ DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", @@ -99,8 +62,8 @@ encrypt of the server challenge originally received. JRA. /* store the parameters */ - init_q_auth_2(&q, cli->srv_name_slash, machine_acct, - sec_chan, global_myname(), &cli->clnt_cred.challenge, + init_q_auth_2(&q, cli->srv_name_slash, machine_acct, + sec_chan, global_myname(), &cli->clnt_cred.challenge, *neg_flags); /* turn parameters into data stream */ @@ -116,7 +79,7 @@ encrypt of the server challenge originally received. JRA. if (NT_STATUS_IS_OK(result)) { UTIME zerotime; - + /* * Check the returned value using the initial * server received challenge. @@ -143,106 +106,12 @@ password ?).\n", cli->cli->desthost )); LSA Authenticate 2 Send the client credential, receive back a server credential. - The caller *must* ensure that the server credential returned matches the session key - encrypt of the server challenge originally received. JRA. -****************************************************************************/ - -static NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *server_name, - const char *account_name, - uint16 sec_chan_type, - const char *computer_name, - uint32 *neg_flags_inout, - const DOM_CHAL *clnt_chal_in, - DOM_CHAL *srv_chal_out) -{ - prs_struct qbuf, rbuf; - NET_Q_AUTH_2 q; - NET_R_AUTH_2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - /* create and send a MSRPC command with api NET_AUTH2 */ - - DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s neg: %x\n", - server_name, account_name, sec_chan_type, computer_name, - *neg_flags_inout)); - - /* store the parameters */ - - init_q_auth_2(&q, server_name, account_name, sec_chan_type, - computer_name, clnt_chal_in, *neg_flags_inout); - - /* turn parameters into data stream */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2, - q, r, - qbuf, rbuf, - net_io_q_auth_2, - net_io_r_auth_2, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - *srv_chal_out = r.srv_chal; - *neg_flags_inout = r.srv_flgs.neg_flags; - } - - return result; -} - -#if 0 /* not currebntly used */ -/**************************************************************************** - LSA Authenticate 3 - - Send the client credential, receive back a server credential. - The caller *must* ensure that the server credential returned matches the session key + The caller *must* ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ -static NTSTATUS rpccli_net_auth3(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *server_name, - const char *account_name, - uint16 sec_chan_type, - const char *computer_name, - uint32 *neg_flags_inout, - const DOM_CHAL *clnt_chal_in, - DOM_CHAL *srv_chal_out) -{ - prs_struct qbuf, rbuf; - NET_Q_AUTH_3 q; - NET_R_AUTH_3 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - /* create and send a MSRPC command with api NET_AUTH2 */ - - DEBUG(4,("cli_net_auth3: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", - server_name, account_name, sec_chan_type, computer_name, - credstr(clnt_chal_in->data), *neg_flags_inout)); - - /* store the parameters */ - init_q_auth_3(&q, server_name, account_name, sec_chan_type, - computer_name, clnt_chal_in, *neg_flags_inout); +/* instead of rpccli_net_auth2() we use rpccli_netr_ServerAuthenticate2() now - gd */ - /* turn parameters into data stream */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH3, - q, r, - qbuf, rbuf, - net_io_q_auth_3, - net_io_r_auth_3, - NT_STATUS_UNSUCCESSFUL); - - if (NT_STATUS_IS_OK(result)) { - *srv_chal_out = r.srv_chal; - *neg_flags_inout = r.srv_flgs.neg_flags; - } - - return result; -} -#endif /* not currebntly used */ /**************************************************************************** Wrapper function that uses the auth and auth2 calls to set up a NETLOGON @@ -251,17 +120,17 @@ static NTSTATUS rpccli_net_auth3(struct rpc_pipe_client *cli, ****************************************************************************/ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, - const char *server_name, - const char *domain, - const char *clnt_name, - const char *machine_account, - const unsigned char machine_pwd[16], - uint32 sec_chan_type, - uint32 *neg_flags_inout) + const char *server_name, + const char *domain, + const char *clnt_name, + const char *machine_account, + const unsigned char machine_pwd[16], + enum netr_SchannelType sec_chan_type, + uint32_t *neg_flags_inout) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CHAL clnt_chal_send; - DOM_CHAL srv_chal_recv; + struct netr_Credential clnt_chal_send; + struct netr_Credential srv_chal_recv; struct dcinfo *dc; SMB_ASSERT(cli->pipe_idx == PI_NETLOGON); @@ -288,13 +157,11 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, generate_random_buffer(clnt_chal_send.data, 8); /* Get the server challenge. */ - result = rpccli_net_req_chal(cli, - cli->mem_ctx, - dc->remote_machine, - clnt_name, - &clnt_chal_send, - &srv_chal_recv); - + result = rpccli_netr_ServerReqChallenge(cli, cli->mem_ctx, + dc->remote_machine, + clnt_name, + &clnt_chal_send, + &srv_chal_recv); if (!NT_STATUS_IS_OK(result)) { return result; } @@ -307,20 +174,18 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, machine_pwd, &clnt_chal_send); - /* - * Send client auth-2 challenge and receive server repy. - */ - - result = rpccli_net_auth2(cli, - cli->mem_ctx, - dc->remote_machine, - dc->mach_acct, - sec_chan_type, - clnt_name, - neg_flags_inout, - &clnt_chal_send, /* input. */ - &srv_chal_recv); /* output */ + /* + * Send client auth-2 challenge and receive server repy. + */ + result = rpccli_netr_ServerAuthenticate2(cli, cli->mem_ctx, + dc->remote_machine, + dc->mach_acct, + sec_chan_type, + clnt_name, + &clnt_chal_send, /* input. */ + &srv_chal_recv, /* output. */ + neg_flags_inout); if (!NT_STATUS_IS_OK(result)) { return result; } @@ -330,7 +195,7 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, * server received challenge. */ - if (!creds_client_check(dc, &srv_chal_recv)) { + if (!netlogon_creds_client_check(dc, &srv_chal_recv)) { /* * Server replied with bad credential. Fail. */ @@ -347,143 +212,6 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, return NT_STATUS_OK; } -/* Logon Control 2 */ - -NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 query_level) -{ - prs_struct qbuf, rbuf; - NET_Q_LOGON_CTRL2 q; - NET_R_LOGON_CTRL2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost); - init_net_q_logon_ctrl2(&q, server, query_level); - - /* Marshall data and send request */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_LOGON_CTRL2, - q, r, - qbuf, rbuf, - net_io_q_logon_ctrl2, - net_io_r_logon_ctrl2, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - return result; -} - -/* Sam synchronisation */ - -NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 database_id, uint32 next_rid, uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_SYNC q; - NET_R_SAM_SYNC r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - DOM_CRED ret_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - ZERO_STRUCT(ret_creds); - - /* Initialise input parameters */ - - creds_client_step(cli->dc, &clnt_creds); - - init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(), - &clnt_creds, &ret_creds, database_id, next_rid); - - /* Marshall data and send request */ - - CLI_DO_RPC_COPY_SESS_KEY(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC, - q, r, - qbuf, rbuf, - net_io_q_sam_sync, - net_io_r_sam_sync, - NT_STATUS_UNSUCCESSFUL); - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - if (!NT_STATUS_IS_ERR(result)) { - /* Check returned credentials. */ - if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) { - DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; - } - } - - return result; -} - -/* Sam synchronisation */ - -NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 database_id, uint64 seqnum, - uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_DELTAS q; - NET_R_SAM_DELTAS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - creds_client_step(cli->dc, &clnt_creds); - - init_net_q_sam_deltas(&q, cli->dc->remote_machine, - global_myname(), &clnt_creds, - database_id, seqnum); - - /* Marshall data and send request */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS, - q, r, - qbuf, rbuf, - net_io_q_sam_deltas, - net_io_r_sam_deltas, - NT_STATUS_UNSUCCESSFUL); - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - if (!NT_STATUS_IS_ERR(result)) { - /* Check returned credentials. */ - if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) { - DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; - } - } - - return result; -} - /* Logon domain user */ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, @@ -495,20 +223,23 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, const char *workstation, int logon_type) { - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - DOM_CRED ret_creds; - NET_ID_INFO_CTR ctr; - NET_USER_INFO_3 user; - int validation_level = 3; + struct netr_Authenticator clnt_creds; + struct netr_Authenticator ret_creds; + union netr_LogonLevel *logon; + union netr_Validation validation; + uint8_t authoritative; + int validation_level = 3; fstring clnt_name_slash; + uint8 zeros[16]; - ZERO_STRUCT(q); - ZERO_STRUCT(r); ZERO_STRUCT(ret_creds); + ZERO_STRUCT(zeros); + + logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel); + if (!logon) { + return NT_STATUS_NO_MEMORY; + } if (workstation) { fstr_sprintf( clnt_name_slash, "\\\\%s", workstation ); @@ -516,85 +247,143 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() ); } - /* Initialise input parameters */ + /* Initialise input parameters */ - creds_client_step(cli->dc, &clnt_creds); + netlogon_creds_client_step(cli->dc, &clnt_creds); - q.validation_level = validation_level; + switch (logon_type) { + case INTERACTIVE_LOGON_TYPE: { - ctr.switch_value = logon_type; + struct netr_PasswordInfo *password_info; - switch (logon_type) { - case INTERACTIVE_LOGON_TYPE: { - unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16]; + struct samr_Password lmpassword; + struct samr_Password ntpassword; - nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); + unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16]; - init_id_info1(&ctr.auth.id1, domain, - logon_parameters, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, clnt_name_slash, - (const char *)cli->dc->sess_key, lm_owf_user_pwd, - nt_owf_user_pwd); + unsigned char lm_owf[16]; + unsigned char nt_owf[16]; + unsigned char key[16]; - break; - } - case NET_LOGON_TYPE: { - uint8 chal[8]; - unsigned char local_lm_response[24]; - unsigned char local_nt_response[24]; - - generate_random_buffer(chal, 8); - - SMBencrypt(password, chal, local_lm_response); - SMBNTencrypt(password, chal, local_nt_response); - - init_id_info2(&ctr.auth.id2, domain, - logon_parameters, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, clnt_name_slash, chal, - local_lm_response, 24, local_nt_response, 24); - break; - } - default: - DEBUG(0, ("switch value %d not supported\n", - ctr.switch_value)); - return NT_STATUS_INVALID_INFO_CLASS; - } + password_info = TALLOC_ZERO_P(mem_ctx, struct netr_PasswordInfo); + if (!password_info) { + return NT_STATUS_NO_MEMORY; + } - r.user = &user; + nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); - init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(), - &clnt_creds, &ret_creds, logon_type, - &ctr); +#ifdef DEBUG_PASSWORD + DEBUG(100,("lm cypher:")); + dump_data(100, lm_owf_user_pwd, 16); - /* Marshall data and send request */ + DEBUG(100,("nt cypher:")); + dump_data(100, nt_owf_user_pwd, 16); +#endif + memset(key, 0, 16); + memcpy(key, cli->dc->sess_key, 8); - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON, - q, r, - qbuf, rbuf, - net_io_q_sam_logon, - net_io_r_sam_logon, - NT_STATUS_UNSUCCESSFUL); + memcpy(lm_owf, lm_owf_user_pwd, 16); + SamOEMhash(lm_owf, key, 16); + memcpy(nt_owf, nt_owf_user_pwd, 16); + SamOEMhash(nt_owf, key, 16); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("encrypt of lm owf password:")); + dump_data(100, lm_owf, 16); + + DEBUG(100,("encrypt of nt owf password:")); + dump_data(100, nt_owf, 16); +#endif + memcpy(lmpassword.hash, lm_owf, 16); + memcpy(ntpassword.hash, nt_owf, 16); + + init_netr_PasswordInfo(password_info, + domain, + logon_parameters, + 0xdead, + 0xbeef, + username, + clnt_name_slash, + lmpassword, + ntpassword); + + logon->password = password_info; + + break; + } + case NET_LOGON_TYPE: { + struct netr_NetworkInfo *network_info; + uint8 chal[8]; + unsigned char local_lm_response[24]; + unsigned char local_nt_response[24]; + struct netr_ChallengeResponse lm; + struct netr_ChallengeResponse nt; + + ZERO_STRUCT(lm); + ZERO_STRUCT(nt); + + network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo); + if (!network_info) { + return NT_STATUS_NO_MEMORY; + } + + generate_random_buffer(chal, 8); - /* Return results */ + SMBencrypt(password, chal, local_lm_response); + SMBNTencrypt(password, chal, local_nt_response); - result = r.status; + lm.length = 24; + lm.data = local_lm_response; - if (r.buffer_creds) { + nt.length = 24; + nt.data = local_nt_response; + + init_netr_NetworkInfo(network_info, + domain, + logon_parameters, + 0xdead, + 0xbeef, + username, + clnt_name_slash, + chal, + nt, + lm); + + logon->network = network_info; + + break; + } + default: + DEBUG(0, ("switch value %d not supported\n", + logon_type)); + return NT_STATUS_INVALID_INFO_CLASS; + } + + result = rpccli_netr_LogonSamLogon(cli, mem_ctx, + cli->dc->remote_machine, + global_myname(), + &clnt_creds, + &ret_creds, + logon_type, + logon, + validation_level, + &validation, + &authoritative); + + if (memcmp(zeros, &ret_creds.cred.data, sizeof(ret_creds.cred.data)) != 0) { /* Check returned credentials if present. */ - if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) { + if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) { DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n")); return NT_STATUS_ACCESS_DENIED; } } - return result; + return result; } -/** - * Logon domain user with an 'network' SAM logon +/** + * Logon domain user with an 'network' SAM logon * * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller. **/ @@ -605,31 +394,47 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli, const char *server, const char *username, const char *domain, - const char *workstation, - const uint8 chal[8], + const char *workstation, + const uint8 chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 **info3) { - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - NET_ID_INFO_CTR ctr; int validation_level = 3; const char *workstation_name_slash; const char *server_name_slash; uint8 zeros[16]; - DOM_CRED clnt_creds; - DOM_CRED ret_creds; - int i; + struct netr_Authenticator clnt_creds; + struct netr_Authenticator ret_creds; + union netr_LogonLevel *logon = NULL; + struct netr_NetworkInfo *network_info; + uint8_t authoritative; + union netr_Validation validation; + struct netr_ChallengeResponse lm; + struct netr_ChallengeResponse nt; + struct netr_UserSessionKey user_session_key; + struct netr_LMSessionKey lmsesskey; + + *info3 = NULL; ZERO_STRUCT(zeros); - ZERO_STRUCT(q); - ZERO_STRUCT(r); ZERO_STRUCT(ret_creds); - creds_client_step(cli->dc, &clnt_creds); + ZERO_STRUCT(lm); + ZERO_STRUCT(nt); + + logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel); + if (!logon) { + return NT_STATUS_NO_MEMORY; + } + + network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo); + if (!network_info) { + return NT_STATUS_NO_MEMORY; + } + + netlogon_creds_client_step(cli->dc, &clnt_creds); if (server[0] != '\\' && server[1] != '\\') { server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server); @@ -650,60 +455,62 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli, /* Initialise input parameters */ - q.validation_level = validation_level; + lm.data = lm_response.data; + lm.length = lm_response.length; + nt.data = nt_response.data; + nt.length = nt_response.length; - ctr.switch_value = NET_LOGON_TYPE; + init_netr_NetworkInfo(network_info, + domain, + logon_parameters, + 0xdead, + 0xbeef, + username, + workstation_name_slash, + (uint8_t *) chal, + nt, + lm); - init_id_info2(&ctr.auth.id2, domain, - logon_parameters, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, workstation_name_slash, (const uchar*)chal, - lm_response.data, lm_response.length, nt_response.data, nt_response.length); - - init_sam_info(&q.sam_id, server_name_slash, global_myname(), - &clnt_creds, &ret_creds, NET_LOGON_TYPE, - &ctr); + logon->network = network_info; - r.user = info3; - - /* Marshall data and send request */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON, - q, r, - qbuf, rbuf, - net_io_q_sam_logon, - net_io_r_sam_logon, - NT_STATUS_UNSUCCESSFUL); + /* Marshall data and send request */ - if (memcmp(zeros, info3->user_sess_key, 16) != 0) { - SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16); - } else { - memset(info3->user_sess_key, '\0', 16); + result = rpccli_netr_LogonSamLogon(cli, mem_ctx, + server_name_slash, + global_myname(), + &clnt_creds, + &ret_creds, + NET_LOGON_TYPE, + logon, + validation_level, + &validation, + &authoritative); + if (!NT_STATUS_IS_OK(result)) { + return result; } - if (memcmp(zeros, info3->lm_sess_key, 8) != 0) { - SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8); - } else { - memset(info3->lm_sess_key, '\0', 8); - } + user_session_key = validation.sam3->base.key; + lmsesskey = validation.sam3->base.LMSessKey; - for (i=0; i < 7; i++) { - memset(&info3->unknown[i], '\0', 4); + if (memcmp(zeros, user_session_key.key, 16) != 0) { + SamOEMhash(user_session_key.key, cli->dc->sess_key, 16); } - /* Return results */ - - result = r.status; + if (memcmp(zeros, lmsesskey.key, 8) != 0) { + SamOEMhash(lmsesskey.key, cli->dc->sess_key, 8); + } - if (r.buffer_creds) { + if (memcmp(zeros, ret_creds.cred.data, sizeof(ret_creds.cred.data)) != 0) { /* Check returned credentials if present. */ - if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) { + if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) { DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n")); return NT_STATUS_ACCESS_DENIED; } } - return result; + *info3 = validation.sam3; + + return result; } NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, @@ -712,26 +519,43 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, const char *server, const char *username, const char *domain, - const char *workstation, - const uint8 chal[8], + const char *workstation, + const uint8 chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 **info3) { - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON_EX q; - NET_R_SAM_LOGON_EX r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - NET_ID_INFO_CTR ctr; int validation_level = 3; const char *workstation_name_slash; const char *server_name_slash; uint8 zeros[16]; - int i; + union netr_LogonLevel *logon = NULL; + struct netr_NetworkInfo *network_info; + uint8_t authoritative; + union netr_Validation validation; + struct netr_ChallengeResponse lm; + struct netr_ChallengeResponse nt; + struct netr_UserSessionKey user_session_key; + struct netr_LMSessionKey lmsesskey; + uint32_t flags = 0; + + *info3 = NULL; ZERO_STRUCT(zeros); - ZERO_STRUCT(q); - ZERO_STRUCT(r); + + ZERO_STRUCT(lm); + ZERO_STRUCT(nt); + + logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel); + if (!logon) { + return NT_STATUS_NO_MEMORY; + } + + network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo); + if (!network_info) { + return NT_STATUS_NO_MEMORY; + } if (server[0] != '\\' && server[1] != '\\') { server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server); @@ -752,97 +576,53 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, /* Initialise input parameters */ - q.validation_level = validation_level; - - ctr.switch_value = NET_LOGON_TYPE; + lm.data = lm_response.data; + lm.length = lm_response.length; + nt.data = nt_response.data; + nt.length = nt_response.length; - init_id_info2(&ctr.auth.id2, domain, - logon_parameters, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, workstation_name_slash, (const uchar*)chal, - lm_response.data, lm_response.length, nt_response.data, - nt_response.length); - - init_sam_info_ex(&q.sam_id, server_name_slash, global_myname(), - NET_LOGON_TYPE, &ctr); + init_netr_NetworkInfo(network_info, + domain, + logon_parameters, + 0xdead, + 0xbeef, + username, + workstation_name_slash, + (uint8_t *) chal, + nt, + lm); - r.user = info3; + logon->network = network_info; /* Marshall data and send request */ - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON_EX, - q, r, qbuf, rbuf, - net_io_q_sam_logon_ex, - net_io_r_sam_logon_ex, - NT_STATUS_UNSUCCESSFUL); - - if (memcmp(zeros, info3->user_sess_key, 16) != 0) { - SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16); - } else { - memset(info3->user_sess_key, '\0', 16); + result = rpccli_netr_LogonSamLogonEx(cli, mem_ctx, + server_name_slash, + global_myname(), + NET_LOGON_TYPE, + logon, + validation_level, + &validation, + &authoritative, + &flags); + if (!NT_STATUS_IS_OK(result)) { + return result; } - if (memcmp(zeros, info3->lm_sess_key, 8) != 0) { - SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8); - } else { - memset(info3->lm_sess_key, '\0', 8); - } + user_session_key = validation.sam3->base.key; + lmsesskey = validation.sam3->base.LMSessKey; - for (i=0; i < 7; i++) { - memset(&info3->unknown[i], '\0', 4); + if (memcmp(zeros, user_session_key.key, 16) != 0) { + SamOEMhash(user_session_key.key, cli->dc->sess_key, 16); } - /* Return results */ - - result = r.status; - - return result; -} - -/*************************************************************************** -LSA Server Password Set. -****************************************************************************/ - -NTSTATUS rpccli_net_srv_pwset(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - const char *machine_name, const uint8 hashed_mach_pwd[16]) -{ - prs_struct rbuf; - prs_struct qbuf; - DOM_CRED clnt_creds; - NET_Q_SRV_PWSET q; - NET_R_SRV_PWSET r; - uint16 sec_chan_type = 2; - NTSTATUS result; - - creds_client_step(cli->dc, &clnt_creds); - - DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n", - cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name)); - - /* store the parameters */ - init_q_srv_pwset(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key, - cli->dc->mach_acct, sec_chan_type, machine_name, - &clnt_creds, hashed_mach_pwd); - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET, - q, r, - qbuf, rbuf, - net_io_q_srv_pwset, - net_io_r_srv_pwset, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - /* report error code */ - DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result))); + if (memcmp(zeros, lmsesskey.key, 8) != 0) { + SamOEMhash(lmsesskey.key, cli->dc->sess_key, 8); } - /* Always check returned credentials. */ - if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) { - DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; - } + *info3 = validation.sam3; return result; + + return result; } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 40d0ac5da9..c89c5531d7 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -1807,6 +1807,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n")); + data_blob_free(&server_response); return nt_status; } diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index c805f00efb..62a5c72d81 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -5,6 +5,7 @@ Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Rafal Szczesniak 2002. Copyright (C) Jeremy Allison 2005. + Copyright (C) Guenther Deschner 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 diff --git a/source3/rpc_client/cli_srvsvc.c b/source3/rpc_client/cli_srvsvc.c index e5d9b4cdad..524678c122 100644 --- a/source3/rpc_client/cli_srvsvc.c +++ b/source3/rpc_client/cli_srvsvc.c @@ -24,40 +24,6 @@ #include "includes.h" -WERROR rpccli_srvsvc_net_srv_get_info(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - uint32 switch_value, SRV_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SRV_GET_INFO q; - SRV_R_NET_SRV_GET_INFO r; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost); - strupper_m(server); - - init_srv_q_net_srv_get_info(&q, server, switch_value); - r.ctr = ctr; - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SRV_GET_INFO, - q, r, - qbuf, rbuf, - srv_io_q_net_srv_get_info, - srv_io_r_net_srv_get_info, - WERR_GENERAL_FAILURE); - - result = r.status; - return result; -} - WERROR rpccli_srvsvc_net_share_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 info_level, SRV_SHARE_INFO_CTR *ctr, int preferred_len, ENUM_HND *hnd) @@ -464,39 +430,6 @@ WERROR rpccli_srvsvc_net_share_add(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ return result; } -WERROR rpccli_srvsvc_net_remote_tod(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - char *server, TIME_OF_DAY_INFO *tod) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_REMOTE_TOD q; - SRV_R_NET_REMOTE_TOD r; - WERROR result = W_ERROR(ERRgeneral); - fstring server_slash; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - slprintf(server_slash, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost); - strupper_m(server_slash); - - init_srv_q_net_remote_tod(&q, server_slash); - r.tod = tod; - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_REMOTE_TOD, - q, r, - qbuf, rbuf, - srv_io_q_net_remote_tod, - srv_io_r_net_remote_tod, - WERR_GENERAL_FAILURE); - - result = r.status; - return result; -} - WERROR rpccli_srvsvc_net_file_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, uint32 file_level, const char *user_name, SRV_FILE_INFO_CTR *ctr, int preferred_len, diff --git a/source3/rpc_client/cli_svcctl.c b/source3/rpc_client/cli_svcctl.c index 95673c1565..b21909fd03 100644 --- a/source3/rpc_client/cli_svcctl.c +++ b/source3/rpc_client/cli_svcctl.c @@ -57,81 +57,6 @@ const char* svc_status_string( uint32 state ) return talloc_strdup(talloc_tos(), msg); } -/******************************************************************** -********************************************************************/ - -WERROR rpccli_svcctl_open_scm(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hSCM, uint32 access_desired ) -{ - SVCCTL_Q_OPEN_SCMANAGER in; - SVCCTL_R_OPEN_SCMANAGER out; - prs_struct qbuf, rbuf; - fstring server; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - /* leave the database name NULL to get the default service db */ - - in.database = NULL; - - /* set the server name */ - - if ( !(in.servername = TALLOC_P( mem_ctx, UNISTR2 )) ) - return WERR_NOMEM; - fstr_sprintf( server, "\\\\%s", cli->cli->desthost ); - init_unistr2( in.servername, server, UNI_STR_TERMINATE ); - - in.access = access_desired; - - CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SCMANAGER_W, - in, out, - qbuf, rbuf, - svcctl_io_q_open_scmanager, - svcctl_io_r_open_scmanager, - WERR_GENERAL_FAILURE ); - - if ( !W_ERROR_IS_OK( out.status ) ) - return out.status; - - memcpy( hSCM, &out.handle, sizeof(POLICY_HND) ); - - return out.status; -} - -/******************************************************************** -********************************************************************/ - -WERROR rpccli_svcctl_open_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hSCM, POLICY_HND *hService, - const char *servicename, uint32 access_desired ) -{ - SVCCTL_Q_OPEN_SERVICE in; - SVCCTL_R_OPEN_SERVICE out; - prs_struct qbuf, rbuf; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - memcpy( &in.handle, hSCM, sizeof(POLICY_HND) ); - init_unistr2( &in.servicename, servicename, UNI_STR_TERMINATE ); - in.access = access_desired; - - CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_OPEN_SERVICE_W, - in, out, - qbuf, rbuf, - svcctl_io_q_open_service, - svcctl_io_r_open_service, - WERR_GENERAL_FAILURE ); - - if ( !W_ERROR_IS_OK( out.status ) ) - return out.status; - - memcpy( hService, &out.handle, sizeof(POLICY_HND) ); - - return out.status; -} - /******************************************************************* *******************************************************************/ @@ -204,36 +129,6 @@ WERROR rpccli_svcctl_enumerate_services( struct rpc_pipe_client *cli, TALLOC_CTX /******************************************************************* *******************************************************************/ -WERROR rpccli_svcctl_query_status( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hService, SERVICE_STATUS *status ) -{ - SVCCTL_Q_QUERY_STATUS in; - SVCCTL_R_QUERY_STATUS out; - prs_struct qbuf, rbuf; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - memcpy( &in.handle, hService, sizeof(POLICY_HND) ); - - CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_QUERY_STATUS, - in, out, - qbuf, rbuf, - svcctl_io_q_query_status, - svcctl_io_r_query_status, - WERR_GENERAL_FAILURE ); - - if ( !W_ERROR_IS_OK( out.status ) ) - return out.status; - - memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) ); - - return out.status; -} - -/******************************************************************* -*******************************************************************/ - WERROR rpccli_svcctl_query_config(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService, SERVICE_CONFIG *config ) { @@ -304,109 +199,3 @@ WERROR rpccli_svcctl_query_config(struct rpc_pipe_client *cli, TALLOC_CTX *mem_c return out.status; } - -/******************************************************************* -*******************************************************************/ - -WERROR rpccli_svcctl_start_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hService, - const char **parm_array, uint32 parmcount ) -{ - SVCCTL_Q_START_SERVICE in; - SVCCTL_R_START_SERVICE out; - prs_struct qbuf, rbuf; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - memcpy( &in.handle, hService, sizeof(POLICY_HND) ); - - in.parmcount = 0; - in.parameters = NULL; - - CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_START_SERVICE_W, - in, out, - qbuf, rbuf, - svcctl_io_q_start_service, - svcctl_io_r_start_service, - WERR_GENERAL_FAILURE ); - - return out.status; -} - -/******************************************************************* -*******************************************************************/ - -WERROR rpccli_svcctl_control_service( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hService, uint32 control, - SERVICE_STATUS *status ) -{ - SVCCTL_Q_CONTROL_SERVICE in; - SVCCTL_R_CONTROL_SERVICE out; - prs_struct qbuf, rbuf; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - memcpy( &in.handle, hService, sizeof(POLICY_HND) ); - in.control = control; - - CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_CONTROL_SERVICE, - in, out, - qbuf, rbuf, - svcctl_io_q_control_service, - svcctl_io_r_control_service, - WERR_GENERAL_FAILURE ); - - if ( !W_ERROR_IS_OK( out.status ) ) - return out.status; - - memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) ); - - return out.status; -} - - -/******************************************************************* -*******************************************************************/ - -WERROR rpccli_svcctl_get_dispname( struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hService, fstring displayname ) -{ - SVCCTL_Q_GET_DISPLAY_NAME in; - SVCCTL_R_GET_DISPLAY_NAME out; - prs_struct qbuf, rbuf; - - ZERO_STRUCT(in); - ZERO_STRUCT(out); - - memcpy( &in.handle, hService, sizeof(POLICY_HND) ); - in.display_name_len = 0; - - CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME, - in, out, - qbuf, rbuf, - svcctl_io_q_get_display_name, - svcctl_io_r_get_display_name, - WERR_GENERAL_FAILURE ); - - /* second time with correct buffer size...should be ok */ - - if ( W_ERROR_EQUAL( out.status, WERR_INSUFFICIENT_BUFFER ) ) { - in.display_name_len = out.display_name_len; - - CLI_DO_RPC_WERR( cli, mem_ctx, PI_SVCCTL, SVCCTL_GET_DISPLAY_NAME, - in, out, - qbuf, rbuf, - svcctl_io_q_get_display_name, - svcctl_io_r_get_display_name, - WERR_GENERAL_FAILURE ); - } - - if ( !W_ERROR_IS_OK( out.status ) ) - return out.status; - - rpcstr_pull( displayname, out.displayname.buffer, sizeof(displayname), -1, STR_TERMINATE ); - - return out.status; -} diff --git a/source3/rpc_client/init_lsa.c b/source3/rpc_client/init_lsa.c index 0af85c0373..2637158fd0 100644 --- a/source3/rpc_client/init_lsa.c +++ b/source3/rpc_client/init_lsa.c @@ -46,3 +46,81 @@ void init_lsa_AsciiString(struct lsa_AsciiString *name, const char *s) name->string = s; } +/******************************************************************* + inits a structure. +********************************************************************/ + +void init_lsa_AsciiStringLarge(struct lsa_AsciiStringLarge *name, const char *s) +{ + name->string = s; +} + +/******************************************************************* + Inits an lsa_QosInfo structure. +********************************************************************/ + +void init_lsa_sec_qos(struct lsa_QosInfo *r, + uint32_t len, + uint16_t impersonation_level, + uint8_t context_mode, + uint8_t effective_only) +{ + DEBUG(5, ("init_lsa_sec_qos\n")); + + r->len = len; + r->impersonation_level = impersonation_level; + r->context_mode = context_mode; + r->effective_only = effective_only; +} + +/******************************************************************* + Inits an lsa_ObjectAttribute structure. +********************************************************************/ + +void init_lsa_obj_attr(struct lsa_ObjectAttribute *r, + uint32_t len, + uint8_t *root_dir, + const char *object_name, + uint32_t attributes, + struct security_descriptor *sec_desc, + struct lsa_QosInfo *sec_qos) +{ + DEBUG(5,("init_lsa_obj_attr\n")); + + r->len = len; + r->root_dir = root_dir; + r->object_name = object_name; + r->attributes = attributes; + r->sec_desc = sec_desc; + r->sec_qos = sec_qos; +} + +/******************************************************************* + Inits a lsa_TranslatedSid structure. +********************************************************************/ + +void init_lsa_translated_sid(struct lsa_TranslatedSid *r, + enum lsa_SidType sid_type, + uint32_t rid, + uint32_t sid_index) +{ + r->sid_type = sid_type; + r->rid = rid; + r->sid_index = sid_index; +} + +/******************************************************************* + Inits a lsa_TranslatedName2 structure. +********************************************************************/ + +void init_lsa_translated_name2(struct lsa_TranslatedName2 *r, + enum lsa_SidType sid_type, + const char *name, + uint32_t sid_index, + uint32_t unknown) +{ + r->sid_type = sid_type; + init_lsa_String(&r->name, name); + r->sid_index = sid_index; + r->unknown = unknown; +} diff --git a/source3/rpc_client/init_netlogon.c b/source3/rpc_client/init_netlogon.c new file mode 100644 index 0000000000..62f1fac626 --- /dev/null +++ b/source3/rpc_client/init_netlogon.c @@ -0,0 +1,220 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Guenther Deschner 2008. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "includes.h" + +/******************************************************************* + inits a structure. +********************************************************************/ + +void init_netr_SamBaseInfo(struct netr_SamBaseInfo *r, + NTTIME last_logon, + NTTIME last_logoff, + NTTIME acct_expiry, + NTTIME last_password_change, + NTTIME allow_password_change, + NTTIME force_password_change, + const char *account_name, + const char *full_name, + const char *logon_script, + const char *profile_path, + const char *home_directory, + const char *home_drive, + uint16_t logon_count, + uint16_t bad_password_count, + uint32_t rid, + uint32_t primary_gid, + struct samr_RidWithAttributeArray groups, + uint32_t user_flags, + struct netr_UserSessionKey key, + const char *logon_server, + const char *domain, + struct dom_sid2 *domain_sid, + struct netr_LMSessionKey LMSessKey, + uint32_t acct_flags) +{ + r->last_logon = last_logon; + r->last_logoff = last_logoff; + r->acct_expiry = acct_expiry; + r->last_password_change = last_password_change; + r->allow_password_change = allow_password_change; + r->force_password_change = force_password_change; + init_lsa_String(&r->account_name, account_name); + init_lsa_String(&r->full_name, full_name); + init_lsa_String(&r->logon_script, logon_script); + init_lsa_String(&r->profile_path, profile_path); + init_lsa_String(&r->home_directory, home_directory); + init_lsa_String(&r->home_drive, home_drive); + r->logon_count = logon_count; + r->bad_password_count = bad_password_count; + r->rid = rid; + r->primary_gid = primary_gid; + r->groups = groups; + r->user_flags = user_flags; + r->key = key; + init_lsa_StringLarge(&r->logon_server, logon_server); + init_lsa_StringLarge(&r->domain, domain); + r->domain_sid = domain_sid; + r->LMSessKey = LMSessKey; + r->acct_flags = acct_flags; +} + +/******************************************************************* + inits a structure. +********************************************************************/ + +void init_netr_SamInfo3(struct netr_SamInfo3 *r, + NTTIME last_logon, + NTTIME last_logoff, + NTTIME acct_expiry, + NTTIME last_password_change, + NTTIME allow_password_change, + NTTIME force_password_change, + const char *account_name, + const char *full_name, + const char *logon_script, + const char *profile_path, + const char *home_directory, + const char *home_drive, + uint16_t logon_count, + uint16_t bad_password_count, + uint32_t rid, + uint32_t primary_gid, + struct samr_RidWithAttributeArray groups, + uint32_t user_flags, + struct netr_UserSessionKey key, + const char *logon_server, + const char *domain, + struct dom_sid2 *domain_sid, + struct netr_LMSessionKey LMSessKey, + uint32_t acct_flags, + uint32_t sidcount, + struct netr_SidAttr *sids) +{ + init_netr_SamBaseInfo(&r->base, + last_logon, + last_logoff, + acct_expiry, + last_password_change, + allow_password_change, + force_password_change, + account_name, + full_name, + logon_script, + profile_path, + home_directory, + home_drive, + logon_count, + bad_password_count, + rid, + primary_gid, + groups, + user_flags, + key, + logon_server, + domain, + domain_sid, + LMSessKey, + acct_flags); + r->sidcount = sidcount; + r->sids = sids; +} + +/******************************************************************* + inits a structure. +********************************************************************/ + +void init_netr_IdentityInfo(struct netr_IdentityInfo *r, + const char *domain_name, + uint32_t parameter_control, + uint32_t logon_id_low, + uint32_t logon_id_high, + const char *account_name, + const char *workstation) +{ + init_lsa_String(&r->domain_name, domain_name); + r->parameter_control = parameter_control; + r->logon_id_low = logon_id_low; + r->logon_id_high = logon_id_high; + init_lsa_String(&r->account_name, account_name); + init_lsa_String(&r->workstation, workstation); +} + +/******************************************************************* + inits a structure. + This is a network logon packet. The log_id parameters + are what an NT server would generate for LUID once the + user is logged on. I don't think we care about them. + + Note that this has no access to the NT and LM hashed passwords, + so it forwards the challenge, and the NT and LM responses (24 + bytes each) over the secure channel to the Domain controller + for it to say yea or nay. This is the preferred method of + checking for a logon as it doesn't export the password + hashes to anyone who has compromised the secure channel. JRA. + +********************************************************************/ + +void init_netr_NetworkInfo(struct netr_NetworkInfo *r, + const char *domain_name, + uint32_t parameter_control, + uint32_t logon_id_low, + uint32_t logon_id_high, + const char *account_name, + const char *workstation, + uint8_t challenge[8], + struct netr_ChallengeResponse nt, + struct netr_ChallengeResponse lm) +{ + init_netr_IdentityInfo(&r->identity_info, + domain_name, + parameter_control, + logon_id_low, + logon_id_high, + account_name, + workstation); + memcpy(r->challenge, challenge, 8); + r->nt = nt; + r->lm = lm; +} + +/******************************************************************* + inits a structure. +********************************************************************/ + +void init_netr_PasswordInfo(struct netr_PasswordInfo *r, + const char *domain_name, + uint32_t parameter_control, + uint32_t logon_id_low, + uint32_t logon_id_high, + const char *account_name, + const char *workstation, + struct samr_Password lmpassword, + struct samr_Password ntpassword) +{ + init_netr_IdentityInfo(&r->identity_info, + domain_name, + parameter_control, + logon_id_low, + logon_id_high, + account_name, + workstation); + r->lmpassword = lmpassword; + r->ntpassword = ntpassword; +} diff --git a/source3/rpc_client/init_srvsvc.c b/source3/rpc_client/init_srvsvc.c new file mode 100644 index 0000000000..5e868ffd2b --- /dev/null +++ b/source3/rpc_client/init_srvsvc.c @@ -0,0 +1,119 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Guenther Deschner 2008. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "includes.h" + +/******************************************************************* + inits a srvsvc_NetSrvInfo102 structure +********************************************************************/ + +void init_srvsvc_NetSrvInfo102(struct srvsvc_NetSrvInfo102 *r, + enum srvsvc_PlatformId platform_id, + const char *server_name, + uint32_t version_major, + uint32_t version_minor, + uint32_t server_type, + const char *comment, + uint32_t users, + uint32_t disc, + uint32_t hidden, + uint32_t announce, + uint32_t anndelta, + uint32_t licenses, + const char *userpath) +{ + r->platform_id = platform_id; + r->server_name = server_name; + r->version_major = version_major; + r->version_minor = version_minor; + r->server_type = server_type; + r->comment = comment; + r->users = users; + r->disc = disc; + r->hidden = hidden; + r->announce = announce; + r->anndelta = anndelta; + r->licenses = licenses; + r->userpath = userpath; +} + +/******************************************************************* + inits a srvsvc_NetSrvInfo101 structure +********************************************************************/ + +void init_srvsvc_NetSrvInfo101(struct srvsvc_NetSrvInfo101 *r, + enum srvsvc_PlatformId platform_id, + const char *server_name, + uint32_t version_major, + uint32_t version_minor, + uint32_t server_type, + const char *comment) +{ + r->platform_id = platform_id; + r->server_name = server_name; + r->version_major = version_major; + r->version_minor = version_minor; + r->server_type = server_type; + r->comment = comment; +} + +/******************************************************************* + inits a srvsvc_NetSrvInfo100 structure +********************************************************************/ + +void init_srvsvc_NetSrvInfo100(struct srvsvc_NetSrvInfo100 *r, + enum srvsvc_PlatformId platform_id, + const char *server_name) +{ + r->platform_id = platform_id; + r->server_name = server_name; +} + +/******************************************************************* + inits a srvsvc_NetRemoteTODInfo structure + ********************************************************************/ + +void init_srvsvc_NetRemoteTODInfo(struct srvsvc_NetRemoteTODInfo *r, + uint32_t elapsed, + uint32_t msecs, + uint32_t hours, + uint32_t mins, + uint32_t secs, + uint32_t hunds, + int32_t ttimezone, + uint32_t tinterval, + uint32_t day, + uint32_t month, + uint32_t year, + uint32_t weekday) +{ + r->elapsed = elapsed; + r->msecs = msecs; + r->hours = hours; + r->mins = mins; + r->secs = secs; + r->hunds = hunds; + r->timezone = ttimezone; + r->tinterval = tinterval; + r->day = day; + r->month = month; + r->year = year; + r->weekday = weekday; +} + diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c deleted file mode 100644 index c4a7c057a6..0000000000 --- a/source3/rpc_parse/parse_lsa.c +++ /dev/null @@ -1,1893 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1997, - * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, - * Copyright (C) Paul Ashton 1997, - * Copyright (C) Andrew Bartlett 2002, - * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002. - * Copyright (C) Gerald )Jerry) Carter 2005 - * - * 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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_PARSE - -static bool lsa_io_trans_names(const char *desc, LSA_TRANS_NAME_ENUM *trn, prs_struct *ps, int depth); -static bool lsa_io_trans_names2(const char *desc, LSA_TRANS_NAME_ENUM2 *trn, prs_struct *ps, int depth); - -/******************************************************************* - Inits a LSA_TRANS_NAME structure. -********************************************************************/ - -void init_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name, - uint16 sid_name_use, const char *name, uint32 idx) -{ - trn->sid_name_use = sid_name_use; - init_unistr2(uni_name, name, UNI_FLAGS_NONE); - init_uni_hdr(&trn->hdr_name, uni_name); - trn->domain_idx = idx; -} - -/******************************************************************* - Reads or writes a LSA_TRANS_NAME structure. -********************************************************************/ - -static bool lsa_io_trans_name(const char *desc, LSA_TRANS_NAME *trn, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_trans_name"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint16("sid_name_use", ps, depth, &trn->sid_name_use)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unihdr ("hdr_name", &trn->hdr_name, ps, depth)) - return False; - if(!prs_uint32("domain_idx ", ps, depth, &trn->domain_idx)) - return False; - - return True; -} - -/******************************************************************* - Inits a LSA_TRANS_NAME2 structure. -********************************************************************/ - -void init_lsa_trans_name2(LSA_TRANS_NAME2 *trn, UNISTR2 *uni_name, - uint16 sid_name_use, const char *name, uint32 idx) -{ - trn->sid_name_use = sid_name_use; - init_unistr2(uni_name, name, UNI_FLAGS_NONE); - init_uni_hdr(&trn->hdr_name, uni_name); - trn->domain_idx = idx; - trn->unknown = 0; -} - -/******************************************************************* - Reads or writes a LSA_TRANS_NAME2 structure. -********************************************************************/ - -static bool lsa_io_trans_name2(const char *desc, LSA_TRANS_NAME2 *trn, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_trans_name2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint16("sid_name_use", ps, depth, &trn->sid_name_use)) - return False; - if(!prs_align(ps)) - return False; - - if(!smb_io_unihdr ("hdr_name", &trn->hdr_name, ps, depth)) - return False; - if(!prs_uint32("domain_idx ", ps, depth, &trn->domain_idx)) - return False; - if(!prs_uint32("unknown ", ps, depth, &trn->unknown)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a DOM_R_REF structure. -********************************************************************/ - -static bool lsa_io_dom_r_ref(const char *desc, DOM_R_REF *dom, prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_dom_r_ref"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("num_ref_doms_1", ps, depth, &dom->num_ref_doms_1)) /* num referenced domains? */ - return False; - if(!prs_uint32("ptr_ref_dom ", ps, depth, &dom->ptr_ref_dom)) /* undocumented buffer pointer. */ - return False; - if(!prs_uint32("max_entries ", ps, depth, &dom->max_entries)) /* 32 - max number of entries */ - return False; - - SMB_ASSERT_ARRAY(dom->hdr_ref_dom, dom->num_ref_doms_1); - - if (dom->ptr_ref_dom != 0) { - - if(!prs_uint32("num_ref_doms_2", ps, depth, &dom->num_ref_doms_2)) /* 4 - num referenced domains? */ - return False; - - SMB_ASSERT_ARRAY(dom->ref_dom, dom->num_ref_doms_2); - - for (i = 0; i < dom->num_ref_doms_1; i++) { - fstring t; - - slprintf(t, sizeof(t) - 1, "dom_ref[%d] ", i); - if(!smb_io_unihdr(t, &dom->hdr_ref_dom[i].hdr_dom_name, ps, depth)) - return False; - - slprintf(t, sizeof(t) - 1, "sid_ptr[%d] ", i); - if(!prs_uint32(t, ps, depth, &dom->hdr_ref_dom[i].ptr_dom_sid)) - return False; - } - - for (i = 0; i < dom->num_ref_doms_2; i++) { - fstring t; - - if (dom->hdr_ref_dom[i].hdr_dom_name.buffer != 0) { - slprintf(t, sizeof(t) - 1, "dom_ref[%d] ", i); - if(!smb_io_unistr2(t, &dom->ref_dom[i].uni_dom_name, True, ps, depth)) /* domain name unicode string */ - return False; - if(!prs_align(ps)) - return False; - } - - if (dom->hdr_ref_dom[i].ptr_dom_sid != 0) { - slprintf(t, sizeof(t) - 1, "sid_ptr[%d] ", i); - if(!smb_io_dom_sid2(t, &dom->ref_dom[i].ref_dom, ps, depth)) /* referenced domain SIDs */ - return False; - } - } - } - - return True; -} - -/******************************************************************* - Inits an lsa_QosInfo structure. -********************************************************************/ - -void init_lsa_sec_qos(struct lsa_QosInfo *r, - uint32_t len, - uint16_t impersonation_level, - uint8_t context_mode, - uint8_t effective_only) -{ - DEBUG(5, ("init_lsa_sec_qos\n")); - - r->len = len; - r->impersonation_level = impersonation_level; - r->context_mode = context_mode; - r->effective_only = effective_only; -} - -/******************************************************************* - Inits an lsa_ObjectAttribute structure. -********************************************************************/ - -void init_lsa_obj_attr(struct lsa_ObjectAttribute *r, - uint32_t len, - uint8_t *root_dir, - const char *object_name, - uint32_t attributes, - struct security_descriptor *sec_desc, - struct lsa_QosInfo *sec_qos) -{ - DEBUG(5,("init_lsa_obj_attr\n")); - - r->len = len; - r->root_dir = root_dir; - r->object_name = object_name; - r->attributes = attributes; - r->sec_desc = sec_desc; - r->sec_qos = sec_qos; -} - -/******************************************************************* - Inits a LSA_SID_ENUM structure. -********************************************************************/ - -static void init_lsa_sid_enum(TALLOC_CTX *mem_ctx, LSA_SID_ENUM *sen, - int num_entries, const DOM_SID *sids) -{ - int i; - - DEBUG(5, ("init_lsa_sid_enum\n")); - - sen->num_entries = num_entries; - sen->ptr_sid_enum = (num_entries != 0); - sen->num_entries2 = num_entries; - - /* Allocate memory for sids and sid pointers */ - - if (num_entries) { - if ((sen->ptr_sid = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_entries )) == NULL) { - DEBUG(3, ("init_lsa_sid_enum(): out of memory for ptr_sid\n")); - return; - } - - if ((sen->sid = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID2, num_entries)) == NULL) { - DEBUG(3, ("init_lsa_sid_enum(): out of memory for sids\n")); - return; - } - } - - /* Copy across SIDs and SID pointers */ - - for (i = 0; i < num_entries; i++) { - sen->ptr_sid[i] = 1; - init_dom_sid2(&sen->sid[i], &sids[i]); - } -} - -/******************************************************************* - Reads or writes a LSA_SID_ENUM structure. -********************************************************************/ - -static bool lsa_io_sid_enum(const char *desc, LSA_SID_ENUM *sen, prs_struct *ps, - int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_sid_enum"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("num_entries ", ps, depth, &sen->num_entries)) - return False; - if(!prs_uint32("ptr_sid_enum", ps, depth, &sen->ptr_sid_enum)) - return False; - - /* - if the ptr is NULL, leave here. checked from a real w2k trace. - JFM, 11/23/2001 - */ - - if (sen->ptr_sid_enum==0) - return True; - - if(!prs_uint32("num_entries2", ps, depth, &sen->num_entries2)) - return False; - - /* Mallocate memory if we're unpacking from the wire */ - - if (UNMARSHALLING(ps) && sen->num_entries) { - if ((sen->ptr_sid = PRS_ALLOC_MEM( ps, uint32, sen->num_entries)) == NULL) { - DEBUG(3, ("init_lsa_sid_enum(): out of memory for " - "ptr_sid\n")); - return False; - } - - if ((sen->sid = PRS_ALLOC_MEM( ps, DOM_SID2, sen->num_entries)) == NULL) { - DEBUG(3, ("init_lsa_sid_enum(): out of memory for " - "sids\n")); - return False; - } - } - - for (i = 0; i < sen->num_entries; i++) { - fstring temp; - - slprintf(temp, sizeof(temp) - 1, "ptr_sid[%d]", i); - if(!prs_uint32(temp, ps, depth, &sen->ptr_sid[i])) { - return False; - } - } - - for (i = 0; i < sen->num_entries; i++) { - fstring temp; - - slprintf(temp, sizeof(temp) - 1, "sid[%d]", i); - if(!smb_io_dom_sid2(temp, &sen->sid[i], ps, depth)) { - return False; - } - } - - return True; -} - -/******************************************************************* - Inits an LSA_R_ENUM_TRUST_DOM structure. -********************************************************************/ - -void init_q_lookup_sids(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_SIDS *q_l, - POLICY_HND *hnd, int num_sids, const DOM_SID *sids, - uint16 level) -{ - DEBUG(5, ("init_q_lookup_sids\n")); - - ZERO_STRUCTP(q_l); - - memcpy(&q_l->pol, hnd, sizeof(q_l->pol)); - init_lsa_sid_enum(mem_ctx, &q_l->sids, num_sids, sids); - - q_l->level = level; -} - -/******************************************************************* - Reads or writes a LSA_Q_LOOKUP_SIDS structure. -********************************************************************/ - -bool lsa_io_q_lookup_sids(const char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_lookup_sids"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol_hnd", &q_s->pol, ps, depth)) /* policy handle */ - return False; - if(!lsa_io_sid_enum("sids ", &q_s->sids, ps, depth)) /* sids to be looked up */ - return False; - if(!lsa_io_trans_names("names ", &q_s->names, ps, depth)) /* translated names */ - return False; - - if(!prs_uint16("level", ps, depth, &q_s->level)) /* lookup level */ - return False; - if(!prs_align(ps)) - return False; - - if(!prs_uint32("mapped_count", ps, depth, &q_s->mapped_count)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a LSA_Q_LOOKUP_SIDS2 structure. -********************************************************************/ - -bool lsa_io_q_lookup_sids2(const char *desc, LSA_Q_LOOKUP_SIDS2 *q_s, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_lookup_sids2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol_hnd", &q_s->pol, ps, depth)) /* policy handle */ - return False; - if(!lsa_io_sid_enum("sids ", &q_s->sids, ps, depth)) /* sids to be looked up */ - return False; - if(!lsa_io_trans_names2("names ", &q_s->names, ps, depth)) /* translated names */ - return False; - - if(!prs_uint16("level", ps, depth, &q_s->level)) /* lookup level */ - return False; - if(!prs_align(ps)) - return False; - - if(!prs_uint32("mapped_count", ps, depth, &q_s->mapped_count)) - return False; - if(!prs_uint32("unknown1", ps, depth, &q_s->unknown1)) - return False; - if(!prs_uint32("unknown2", ps, depth, &q_s->unknown2)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a LSA_Q_LOOKUP_SIDS3 structure. -********************************************************************/ - -bool lsa_io_q_lookup_sids3(const char *desc, LSA_Q_LOOKUP_SIDS3 *q_s, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_lookup_sids3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!lsa_io_sid_enum("sids ", &q_s->sids, ps, depth)) /* sids to be looked up */ - return False; - if(!lsa_io_trans_names2("names ", &q_s->names, ps, depth)) /* translated names */ - return False; - - if(!prs_uint16("level", ps, depth, &q_s->level)) /* lookup level */ - return False; - if(!prs_align(ps)) - return False; - - if(!prs_uint32("mapped_count", ps, depth, &q_s->mapped_count)) - return False; - if(!prs_uint32("unknown1", ps, depth, &q_s->unknown1)) - return False; - if(!prs_uint32("unknown2", ps, depth, &q_s->unknown2)) - return False; - - return True; -} - - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -static bool lsa_io_trans_names(const char *desc, LSA_TRANS_NAME_ENUM *trn, - prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_trans_names"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("num_entries ", ps, depth, &trn->num_entries)) - return False; - if(!prs_uint32("ptr_trans_names", ps, depth, &trn->ptr_trans_names)) - return False; - - if (trn->ptr_trans_names != 0) { - if(!prs_uint32("num_entries2 ", ps, depth, - &trn->num_entries2)) - return False; - - if (trn->num_entries2 != trn->num_entries) { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps) && trn->num_entries2) { - if ((trn->name = PRS_ALLOC_MEM(ps, LSA_TRANS_NAME, trn->num_entries2)) == NULL) { - return False; - } - - if ((trn->uni_name = PRS_ALLOC_MEM(ps, UNISTR2, trn->num_entries2)) == NULL) { - return False; - } - } - - for (i = 0; i < trn->num_entries2; i++) { - fstring t; - slprintf(t, sizeof(t) - 1, "name[%d] ", i); - - if(!lsa_io_trans_name(t, &trn->name[i], ps, depth)) /* translated name */ - return False; - } - - for (i = 0; i < trn->num_entries2; i++) { - fstring t; - slprintf(t, sizeof(t) - 1, "name[%d] ", i); - - if(!smb_io_unistr2(t, &trn->uni_name[i], trn->name[i].hdr_name.buffer, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - } - } - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -static bool lsa_io_trans_names2(const char *desc, LSA_TRANS_NAME_ENUM2 *trn, - prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_trans_names2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("num_entries ", ps, depth, &trn->num_entries)) - return False; - if(!prs_uint32("ptr_trans_names", ps, depth, &trn->ptr_trans_names)) - return False; - - if (trn->ptr_trans_names != 0) { - if(!prs_uint32("num_entries2 ", ps, depth, - &trn->num_entries2)) - return False; - - if (trn->num_entries2 != trn->num_entries) { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps) && trn->num_entries2) { - if ((trn->name = PRS_ALLOC_MEM(ps, LSA_TRANS_NAME2, trn->num_entries2)) == NULL) { - return False; - } - - if ((trn->uni_name = PRS_ALLOC_MEM(ps, UNISTR2, trn->num_entries2)) == NULL) { - return False; - } - } - - for (i = 0; i < trn->num_entries2; i++) { - fstring t; - slprintf(t, sizeof(t) - 1, "name[%d] ", i); - - if(!lsa_io_trans_name2(t, &trn->name[i], ps, depth)) /* translated name */ - return False; - } - - for (i = 0; i < trn->num_entries2; i++) { - fstring t; - slprintf(t, sizeof(t) - 1, "name[%d] ", i); - - if(!smb_io_unistr2(t, &trn->uni_name[i], trn->name[i].hdr_name.buffer, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - } - } - - return True; -} - - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool lsa_io_r_lookup_sids(const char *desc, LSA_R_LOOKUP_SIDS *r_s, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_lookup_sids"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_dom_ref", ps, depth, &r_s->ptr_dom_ref)) - return False; - - if (r_s->ptr_dom_ref != 0) - if(!lsa_io_dom_r_ref ("dom_ref", r_s->dom_ref, ps, depth)) /* domain reference info */ - return False; - - if(!lsa_io_trans_names("names ", &r_s->names, ps, depth)) /* translated names */ - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("mapped_count", ps, depth, &r_s->mapped_count)) - return False; - - if(!prs_ntstatus("status ", ps, depth, &r_s->status)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool lsa_io_r_lookup_sids2(const char *desc, LSA_R_LOOKUP_SIDS2 *r_s, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_lookup_sids2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_dom_ref", ps, depth, &r_s->ptr_dom_ref)) - return False; - - if (r_s->ptr_dom_ref != 0) - if(!lsa_io_dom_r_ref ("dom_ref", r_s->dom_ref, ps, depth)) /* domain reference info */ - return False; - - if(!lsa_io_trans_names2("names ", &r_s->names, ps, depth)) /* translated names */ - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("mapped_count", ps, depth, &r_s->mapped_count)) - return False; - - if(!prs_ntstatus("status ", ps, depth, &r_s->status)) - return False; - - return True; -} - - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool lsa_io_r_lookup_sids3(const char *desc, LSA_R_LOOKUP_SIDS3 *r_s, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_lookup_sids3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_dom_ref", ps, depth, &r_s->ptr_dom_ref)) - return False; - - if (r_s->ptr_dom_ref != 0) - if(!lsa_io_dom_r_ref ("dom_ref", r_s->dom_ref, ps, depth)) /* domain reference info */ - return False; - - if(!lsa_io_trans_names2("names ", &r_s->names, ps, depth)) /* translated names */ - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("mapped_count", ps, depth, &r_s->mapped_count)) - return False; - - if(!prs_ntstatus("status ", ps, depth, &r_s->status)) - return False; - - return True; -} - -/******************************************************************* -makes a structure. -********************************************************************/ - -void init_q_lookup_names(TALLOC_CTX *mem_ctx, LSA_Q_LOOKUP_NAMES *q_l, - POLICY_HND *hnd, int num_names, const char **names, - int level) -{ - unsigned int i; - - DEBUG(5, ("init_q_lookup_names\n")); - - ZERO_STRUCTP(q_l); - - q_l->pol = *hnd; - q_l->num_entries = num_names; - q_l->num_entries2 = num_names; - q_l->lookup_level = level; - - if (num_names) { - if ((q_l->uni_name = TALLOC_ZERO_ARRAY(mem_ctx, UNISTR2, num_names)) == NULL) { - DEBUG(3, ("init_q_lookup_names(): out of memory\n")); - return; - } - - if ((q_l->hdr_name = TALLOC_ZERO_ARRAY(mem_ctx, UNIHDR, num_names)) == NULL) { - DEBUG(3, ("init_q_lookup_names(): out of memory\n")); - return; - } - } else { - q_l->uni_name = NULL; - q_l->hdr_name = NULL; - } - - for (i = 0; i < num_names; i++) { - init_unistr2(&q_l->uni_name[i], names[i], UNI_FLAGS_NONE); - init_uni_hdr(&q_l->hdr_name[i], &q_l->uni_name[i]); - } -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ - -bool lsa_io_q_lookup_names(const char *desc, LSA_Q_LOOKUP_NAMES *q_r, - prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_q_lookup_names"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("", &q_r->pol, ps, depth)) /* policy handle */ - return False; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("num_entries ", ps, depth, &q_r->num_entries)) - return False; - if(!prs_uint32("num_entries2 ", ps, depth, &q_r->num_entries2)) - return False; - - if (UNMARSHALLING(ps)) { - if (q_r->num_entries) { - if ((q_r->hdr_name = PRS_ALLOC_MEM(ps, UNIHDR, q_r->num_entries)) == NULL) - return False; - if ((q_r->uni_name = PRS_ALLOC_MEM(ps, UNISTR2, q_r->num_entries)) == NULL) - return False; - } - } - - for (i = 0; i < q_r->num_entries; i++) { - if(!prs_align(ps)) - return False; - if(!smb_io_unihdr("hdr_name", &q_r->hdr_name[i], ps, depth)) /* pointer names */ - return False; - } - - for (i = 0; i < q_r->num_entries; i++) { - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("dom_name", &q_r->uni_name[i], q_r->hdr_name[i].buffer, ps, depth)) /* names to be looked up */ - return False; - } - - if(!prs_align(ps)) - return False; - if(!prs_uint32("num_trans_entries ", ps, depth, &q_r->num_trans_entries)) - return False; - if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids)) - return False; - if(!prs_uint16("lookup_level ", ps, depth, &q_r->lookup_level)) - return False; - if(!prs_align(ps)) - return False; - if(!prs_uint32("mapped_count ", ps, depth, &q_r->mapped_count)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ - -bool lsa_io_r_lookup_names(const char *desc, LSA_R_LOOKUP_NAMES *out, prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_r_lookup_names"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_dom_ref", ps, depth, &out->ptr_dom_ref)) - return False; - - if (out->ptr_dom_ref != 0) - if(!lsa_io_dom_r_ref("", out->dom_ref, ps, depth)) - return False; - - if(!prs_uint32("num_entries", ps, depth, &out->num_entries)) - return False; - if(!prs_uint32("ptr_entries", ps, depth, &out->ptr_entries)) - return False; - - if (out->ptr_entries != 0) { - if(!prs_uint32("num_entries2", ps, depth, &out->num_entries2)) - return False; - - if (out->num_entries2 != out->num_entries) { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps) && out->num_entries2) { - if ((out->dom_rid = PRS_ALLOC_MEM(ps, DOM_RID, out->num_entries2)) - == NULL) { - DEBUG(3, ("lsa_io_r_lookup_names(): out of memory\n")); - return False; - } - } - - for (i = 0; i < out->num_entries2; i++) - if(!smb_io_dom_rid("", &out->dom_rid[i], ps, depth)) /* domain RIDs being looked up */ - return False; - } - - if(!prs_uint32("mapped_count", ps, depth, &out->mapped_count)) - return False; - - if(!prs_ntstatus("status ", ps, depth, &out->status)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ - -bool lsa_io_q_lookup_names2(const char *desc, LSA_Q_LOOKUP_NAMES2 *q_r, - prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_q_lookup_names2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("", &q_r->pol, ps, depth)) /* policy handle */ - return False; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("num_entries ", ps, depth, &q_r->num_entries)) - return False; - if(!prs_uint32("num_entries2 ", ps, depth, &q_r->num_entries2)) - return False; - - if (UNMARSHALLING(ps)) { - if (q_r->num_entries) { - if ((q_r->hdr_name = PRS_ALLOC_MEM(ps, UNIHDR, q_r->num_entries)) == NULL) - return False; - if ((q_r->uni_name = PRS_ALLOC_MEM(ps, UNISTR2, q_r->num_entries)) == NULL) - return False; - } - } - - for (i = 0; i < q_r->num_entries; i++) { - if(!prs_align(ps)) - return False; - if(!smb_io_unihdr("hdr_name", &q_r->hdr_name[i], ps, depth)) /* pointer names */ - return False; - } - - for (i = 0; i < q_r->num_entries; i++) { - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("dom_name", &q_r->uni_name[i], q_r->hdr_name[i].buffer, ps, depth)) /* names to be looked up */ - return False; - } - - if(!prs_align(ps)) - return False; - if(!prs_uint32("num_trans_entries ", ps, depth, &q_r->num_trans_entries)) - return False; - if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids)) - return False; - if(!prs_uint16("lookup_level ", ps, depth, &q_r->lookup_level)) - return False; - if(!prs_align(ps)) - return False; - if(!prs_uint32("mapped_count ", ps, depth, &q_r->mapped_count)) - return False; - if(!prs_uint32("unknown1 ", ps, depth, &q_r->unknown1)) - return False; - if(!prs_uint32("unknown2 ", ps, depth, &q_r->unknown2)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ - -bool lsa_io_r_lookup_names2(const char *desc, LSA_R_LOOKUP_NAMES2 *out, prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_r_lookup_names2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_dom_ref", ps, depth, &out->ptr_dom_ref)) - return False; - - if (out->ptr_dom_ref != 0) - if(!lsa_io_dom_r_ref("", out->dom_ref, ps, depth)) - return False; - - if(!prs_uint32("num_entries", ps, depth, &out->num_entries)) - return False; - if(!prs_uint32("ptr_entries", ps, depth, &out->ptr_entries)) - return False; - - if (out->ptr_entries != 0) { - if(!prs_uint32("num_entries2", ps, depth, &out->num_entries2)) - return False; - - if (out->num_entries2 != out->num_entries) { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps) && out->num_entries2) { - if ((out->dom_rid = PRS_ALLOC_MEM(ps, DOM_RID2, out->num_entries2)) - == NULL) { - DEBUG(3, ("lsa_io_r_lookup_names2(): out of memory\n")); - return False; - } - } - - for (i = 0; i < out->num_entries2; i++) - if(!smb_io_dom_rid2("", &out->dom_rid[i], ps, depth)) /* domain RIDs being looked up */ - return False; - } - - if(!prs_uint32("mapped_count", ps, depth, &out->mapped_count)) - return False; - - if(!prs_ntstatus("status ", ps, depth, &out->status)) - return False; - - return True; -} - -/******************************************************************* - Internal lsa data type io. - Following pass must read DOM_SID2 types. -********************************************************************/ - -bool smb_io_lsa_translated_sids3(const char *desc, LSA_TRANSLATED_SID3 *q_r, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "smb_io_lsa_translated_sids3"); - depth++; - - if(!prs_align(ps)) - return False; - if(!prs_uint8 ("sid_type ", ps, depth, &q_r->sid_type )) - return False; - if(!prs_align(ps)) - return False; - /* Second pass will read/write these. */ - if (!smb_io_dom_sid2_p("sid_header", ps, depth, &q_r->sid2)) - return False; - if(!prs_uint32("sid_idx ", ps, depth, &q_r->sid_idx )) - return False; - if(!prs_uint32("unknown ", ps, depth, &q_r->unknown )) - return False; - - return True; -} - -/******************************************************************* - Identical to lsa_io_q_lookup_names2. -********************************************************************/ - -bool lsa_io_q_lookup_names3(const char *desc, LSA_Q_LOOKUP_NAMES3 *q_r, - prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_q_lookup_names3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("", &q_r->pol, ps, depth)) /* policy handle */ - return False; - - if(!prs_align(ps)) - return False; - if(!prs_uint32("num_entries ", ps, depth, &q_r->num_entries)) - return False; - if(!prs_uint32("num_entries2 ", ps, depth, &q_r->num_entries2)) - return False; - - if (UNMARSHALLING(ps)) { - if (q_r->num_entries) { - if ((q_r->hdr_name = PRS_ALLOC_MEM(ps, UNIHDR, q_r->num_entries)) == NULL) - return False; - if ((q_r->uni_name = PRS_ALLOC_MEM(ps, UNISTR2, q_r->num_entries)) == NULL) - return False; - } - } - - for (i = 0; i < q_r->num_entries; i++) { - if(!prs_align(ps)) - return False; - if(!smb_io_unihdr("hdr_name", &q_r->hdr_name[i], ps, depth)) /* pointer names */ - return False; - } - - for (i = 0; i < q_r->num_entries; i++) { - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("dom_name", &q_r->uni_name[i], q_r->hdr_name[i].buffer, ps, depth)) /* names to be looked up */ - return False; - } - - if(!prs_align(ps)) - return False; - if(!prs_uint32("num_trans_entries ", ps, depth, &q_r->num_trans_entries)) - return False; - if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids)) - return False; - if(!prs_uint16("lookup_level ", ps, depth, &q_r->lookup_level)) - return False; - if(!prs_align(ps)) - return False; - if(!prs_uint32("mapped_count ", ps, depth, &q_r->mapped_count)) - return False; - if(!prs_uint32("unknown1 ", ps, depth, &q_r->unknown1)) - return False; - if(!prs_uint32("unknown2 ", ps, depth, &q_r->unknown2)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ - -bool lsa_io_r_lookup_names3(const char *desc, LSA_R_LOOKUP_NAMES3 *out, prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_r_lookup_names3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_dom_ref", ps, depth, &out->ptr_dom_ref)) - return False; - - if (out->ptr_dom_ref != 0) - if(!lsa_io_dom_r_ref("", out->dom_ref, ps, depth)) - return False; - - if(!prs_uint32("num_entries", ps, depth, &out->num_entries)) - return False; - if(!prs_uint32("ptr_entries", ps, depth, &out->ptr_entries)) - return False; - - if (out->ptr_entries != 0) { - if(!prs_uint32("num_entries2", ps, depth, &out->num_entries2)) - return False; - - if (out->num_entries2 != out->num_entries) { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps) && out->num_entries2) { - if ((out->trans_sids = PRS_ALLOC_MEM(ps, LSA_TRANSLATED_SID3, out->num_entries2)) - == NULL) { - DEBUG(3, ("lsa_io_r_lookup_names3(): out of memory\n")); - return False; - } - } - - for (i = 0; i < out->num_entries2; i++) { - if(!smb_io_lsa_translated_sids3("", &out->trans_sids[i], ps, depth)) { - return False; - } - } - /* Now process the DOM_SID2 entries. */ - for (i = 0; i < out->num_entries2; i++) { - if (out->trans_sids[i].sid2) { - if( !smb_io_dom_sid2("sid2", out->trans_sids[i].sid2, ps, depth) ) { - return False; - } - } - } - } - - if(!prs_uint32("mapped_count", ps, depth, &out->mapped_count)) - return False; - - if(!prs_ntstatus("status ", ps, depth, &out->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool lsa_io_q_lookup_names4(const char *desc, LSA_Q_LOOKUP_NAMES4 *q_r, - prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_q_lookup_names4"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("num_entries ", ps, depth, &q_r->num_entries)) - return False; - if(!prs_uint32("num_entries2 ", ps, depth, &q_r->num_entries2)) - return False; - - if (UNMARSHALLING(ps)) { - if (q_r->num_entries) { - if ((q_r->hdr_name = PRS_ALLOC_MEM(ps, UNIHDR, q_r->num_entries)) == NULL) - return False; - if ((q_r->uni_name = PRS_ALLOC_MEM(ps, UNISTR2, q_r->num_entries)) == NULL) - return False; - } - } - - for (i = 0; i < q_r->num_entries; i++) { - if(!prs_align(ps)) - return False; - if(!smb_io_unihdr("hdr_name", &q_r->hdr_name[i], ps, depth)) /* pointer names */ - return False; - } - - for (i = 0; i < q_r->num_entries; i++) { - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("dom_name", &q_r->uni_name[i], q_r->hdr_name[i].buffer, ps, depth)) /* names to be looked up */ - return False; - } - - if(!prs_align(ps)) - return False; - if(!prs_uint32("num_trans_entries ", ps, depth, &q_r->num_trans_entries)) - return False; - if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids)) - return False; - if(!prs_uint16("lookup_level ", ps, depth, &q_r->lookup_level)) - return False; - if(!prs_align(ps)) - return False; - if(!prs_uint32("mapped_count ", ps, depth, &q_r->mapped_count)) - return False; - if(!prs_uint32("unknown1 ", ps, depth, &q_r->unknown1)) - return False; - if(!prs_uint32("unknown2 ", ps, depth, &q_r->unknown2)) - return False; - - return True; -} - -/******************************************************************* - Identical to lsa_io_r_lookup_names3. -********************************************************************/ - -bool lsa_io_r_lookup_names4(const char *desc, LSA_R_LOOKUP_NAMES4 *out, prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "lsa_io_r_lookup_names4"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_dom_ref", ps, depth, &out->ptr_dom_ref)) - return False; - - if (out->ptr_dom_ref != 0) - if(!lsa_io_dom_r_ref("", out->dom_ref, ps, depth)) - return False; - - if(!prs_uint32("num_entries", ps, depth, &out->num_entries)) - return False; - if(!prs_uint32("ptr_entries", ps, depth, &out->ptr_entries)) - return False; - - if (out->ptr_entries != 0) { - if(!prs_uint32("num_entries2", ps, depth, &out->num_entries2)) - return False; - - if (out->num_entries2 != out->num_entries) { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps) && out->num_entries2) { - if ((out->trans_sids = PRS_ALLOC_MEM(ps, LSA_TRANSLATED_SID3, out->num_entries2)) - == NULL) { - DEBUG(3, ("lsa_io_r_lookup_names4(): out of memory\n")); - return False; - } - } - - for (i = 0; i < out->num_entries2; i++) { - if(!smb_io_lsa_translated_sids3("", &out->trans_sids[i], ps, depth)) { - return False; - } - } - /* Now process the DOM_SID2 entries. */ - for (i = 0; i < out->num_entries2; i++) { - if (out->trans_sids[i].sid2) { - if( !smb_io_dom_sid2("sid2", out->trans_sids[i].sid2, ps, depth) ) { - return False; - } - } - } - } - - if(!prs_uint32("mapped_count", ps, depth, &out->mapped_count)) - return False; - - if(!prs_ntstatus("status ", ps, depth, &out->status)) - return False; - - return True; -} - -/* - initialise a LSA_Q_ENUM_ACCOUNTS structure -*/ -void init_lsa_q_enum_accounts(LSA_Q_ENUM_ACCOUNTS *trn, POLICY_HND *hnd, uint32 enum_context, uint32 pref_max_length) -{ - memcpy(&trn->pol, hnd, sizeof(trn->pol)); - - trn->enum_context = enum_context; - trn->pref_max_length = pref_max_length; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -bool lsa_io_q_enum_accounts(const char *desc, LSA_Q_ENUM_ACCOUNTS *in, prs_struct *ps, int depth) -{ - if (in == NULL) - return False; - - prs_debug(ps, depth, desc, "lsa_io_q_enum_accounts"); - depth++; - - if (!smb_io_pol_hnd("", &in->pol, ps, depth)) - return False; - - if(!prs_uint32("enum_context ", ps, depth, &in->enum_context)) - return False; - if(!prs_uint32("pref_max_length", ps, depth, &in->pref_max_length)) - return False; - - return True; -} - - -/******************************************************************* - Inits an LSA_R_ENUM_PRIVS structure. -********************************************************************/ - -void init_lsa_r_enum_accounts(LSA_R_ENUM_ACCOUNTS *out, uint32 enum_context) -{ - DEBUG(5, ("init_lsa_r_enum_accounts\n")); - - out->enum_context=enum_context; - if (out->enum_context!=0) { - out->sids.num_entries=enum_context; - out->sids.ptr_sid_enum=1; - out->sids.num_entries2=enum_context; - } else { - out->sids.num_entries=0; - out->sids.ptr_sid_enum=0; - out->sids.num_entries2=0; - } -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -bool lsa_io_r_enum_accounts(const char *desc, LSA_R_ENUM_ACCOUNTS *out, prs_struct *ps, int depth) -{ - if (out == NULL) - return False; - - prs_debug(ps, depth, desc, "lsa_io_r_enum_accounts"); - depth++; - - if (!prs_align(ps)) - return False; - - if(!prs_uint32("enum_context", ps, depth, &out->enum_context)) - return False; - - if (!lsa_io_sid_enum("sids", &out->sids, ps, depth)) - return False; - - if (!prs_align(ps)) - return False; - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} - - -void init_lsa_q_enum_privsaccount(LSA_Q_ENUMPRIVSACCOUNT *trn, POLICY_HND *hnd) -{ - memcpy(&trn->pol, hnd, sizeof(trn->pol)); - -} - -/******************************************************************* - Reads or writes an LSA_Q_ENUMPRIVSACCOUNT structure. -********************************************************************/ - -bool lsa_io_q_enum_privsaccount(const char *desc, LSA_Q_ENUMPRIVSACCOUNT *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_enum_privsaccount"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol", &out->pol, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an LUID structure. -********************************************************************/ - -static bool lsa_io_luid(const char *desc, LUID *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_luid"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("low", ps, depth, &out->low)) - return False; - - if(!prs_uint32("high", ps, depth, &out->high)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an LUID_ATTR structure. -********************************************************************/ - -static bool lsa_io_luid_attr(const char *desc, LUID_ATTR *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_luid_attr"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!lsa_io_luid(desc, &out->luid, ps, depth)) - return False; - - if(!prs_uint32("attr", ps, depth, &out->attr)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an PRIVILEGE_SET structure. -********************************************************************/ - -static bool lsa_io_privilege_set(const char *desc, PRIVILEGE_SET *out, prs_struct *ps, int depth) -{ - uint32 i, dummy; - - prs_debug(ps, depth, desc, "lsa_io_privilege_set"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("count", ps, depth, &dummy)) - return False; - if(!prs_uint32("control", ps, depth, &out->control)) - return False; - - for (i=0; i<out->count; i++) { - if (!lsa_io_luid_attr(desc, &out->set[i], ps, depth)) - return False; - } - - return True; -} - -NTSTATUS init_lsa_r_enum_privsaccount(TALLOC_CTX *mem_ctx, LSA_R_ENUMPRIVSACCOUNT *out, LUID_ATTR *set, uint32 count, uint32 control) -{ - NTSTATUS ret = NT_STATUS_OK; - - out->ptr = 1; - out->count = count; - - if ( !NT_STATUS_IS_OK(ret = privilege_set_init_by_ctx(mem_ctx, &(out->set))) ) - return ret; - - out->set.count = count; - - if (!NT_STATUS_IS_OK(ret = dup_luid_attr(out->set.mem_ctx, &(out->set.set), set, count))) - return ret; - - DEBUG(10,("init_lsa_r_enum_privsaccount: %d privileges\n", out->count)); - - return ret; -} - -/******************************************************************* - Reads or writes an LSA_R_ENUMPRIVSACCOUNT structure. -********************************************************************/ - -bool lsa_io_r_enum_privsaccount(const char *desc, LSA_R_ENUMPRIVSACCOUNT *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_enum_privsaccount"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr", ps, depth, &out->ptr)) - return False; - - if (out->ptr!=0) { - if(!prs_uint32("count", ps, depth, &out->count)) - return False; - - /* malloc memory if unmarshalling here */ - - if (UNMARSHALLING(ps) && out->count != 0) { - if (!NT_STATUS_IS_OK(privilege_set_init_by_ctx(ps->mem_ctx, &(out->set)))) - return False; - - if (!(out->set.set = PRS_ALLOC_MEM(ps,LUID_ATTR,out->count))) - return False; - - } - - if(!lsa_io_privilege_set(desc, &out->set, ps, depth)) - return False; - } - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} - -void init_lsa_string( LSA_STRING *uni, const char *string ) -{ - init_unistr2(&uni->unistring, string, UNI_FLAGS_NONE); - init_uni_hdr(&uni->hdr, &uni->unistring); -} - -void init_lsa_q_lookup_priv_value(LSA_Q_LOOKUP_PRIV_VALUE *q_u, POLICY_HND *hnd, const char *name) -{ - memcpy(&q_u->pol, hnd, sizeof(q_u->pol)); - init_lsa_string( &q_u->privname, name ); -} - -bool smb_io_lsa_string( const char *desc, LSA_STRING *string, prs_struct *ps, int depth ) -{ - prs_debug(ps, depth, desc, "smb_io_lsa_string"); - depth++; - - if(!smb_io_unihdr ("hdr", &string->hdr, ps, depth)) - return False; - if(!smb_io_unistr2("unistring", &string->unistring, string->hdr.buffer, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an LSA_Q_LOOKUP_PRIV_VALUE structure. -********************************************************************/ - -bool lsa_io_q_lookup_priv_value(const char *desc, LSA_Q_LOOKUP_PRIV_VALUE *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_lookup_priv_value"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol", &out->pol, ps, depth)) - return False; - if(!smb_io_lsa_string("privname", &out->privname, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an LSA_R_LOOKUP_PRIV_VALUE structure. -********************************************************************/ - -bool lsa_io_r_lookup_priv_value(const char *desc, LSA_R_LOOKUP_PRIV_VALUE *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_lookup_priv_value"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!lsa_io_luid("luid", &out->luid, ps, depth)) - return False; - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} - - -/******************************************************************* - Reads or writes an LSA_Q_ADDPRIVS structure. -********************************************************************/ - -bool lsa_io_q_addprivs(const char *desc, LSA_Q_ADDPRIVS *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_addprivs"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol", &out->pol, ps, depth)) - return False; - - if(!prs_uint32("count", ps, depth, &out->count)) - return False; - - if (UNMARSHALLING(ps) && out->count!=0) { - if (!NT_STATUS_IS_OK(privilege_set_init_by_ctx(ps->mem_ctx, &(out->set)))) - return False; - - if (!(out->set.set = PRS_ALLOC_MEM(ps, LUID_ATTR, out->count))) - return False; - } - - if(!lsa_io_privilege_set(desc, &out->set, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an LSA_R_ADDPRIVS structure. -********************************************************************/ - -bool lsa_io_r_addprivs(const char *desc, LSA_R_ADDPRIVS *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_addprivs"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an LSA_Q_REMOVEPRIVS structure. -********************************************************************/ - -bool lsa_io_q_removeprivs(const char *desc, LSA_Q_REMOVEPRIVS *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_removeprivs"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("pol", &out->pol, ps, depth)) - return False; - - if(!prs_uint32("allrights", ps, depth, &out->allrights)) - return False; - - if(!prs_uint32("ptr", ps, depth, &out->ptr)) - return False; - - /* - * JFM: I'm not sure at all if the count is inside the ptr - * never seen one with ptr=0 - */ - - if (out->ptr!=0) { - if(!prs_uint32("count", ps, depth, &out->count)) - return False; - - if (UNMARSHALLING(ps) && out->count!=0) { - if (!NT_STATUS_IS_OK(privilege_set_init_by_ctx(ps->mem_ctx, &(out->set)))) - return False; - - if (!(out->set.set = PRS_ALLOC_MEM(ps, LUID_ATTR, out->count))) - return False; - } - - if(!lsa_io_privilege_set(desc, &out->set, ps, depth)) - return False; - } - - return True; -} - -/******************************************************************* - Reads or writes an LSA_R_REMOVEPRIVS structure. -********************************************************************/ - -bool lsa_io_r_removeprivs(const char *desc, LSA_R_REMOVEPRIVS *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_removeprivs"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} - -bool policy_handle_is_valid(const POLICY_HND *hnd) -{ - POLICY_HND zero_pol; - - ZERO_STRUCT(zero_pol); - return ((memcmp(&zero_pol, hnd, sizeof(POLICY_HND)) == 0) ? False : True ); -} - -/******************************************************************* - Inits an LSA_Q_ENUM_ACCT_RIGHTS structure. -********************************************************************/ -void init_q_enum_acct_rights(LSA_Q_ENUM_ACCT_RIGHTS *in, - POLICY_HND *hnd, - uint32 count, - DOM_SID *sid) -{ - DEBUG(5, ("init_q_enum_acct_rights\n")); - - in->pol = *hnd; - init_dom_sid2(&in->sid, sid); -} - -/******************************************************************* -********************************************************************/ -NTSTATUS init_r_enum_acct_rights( LSA_R_ENUM_ACCT_RIGHTS *out, PRIVILEGE_SET *privileges ) -{ - uint32 i; - const char *privname; - const char **privname_array = NULL; - int num_priv = 0; - - for ( i=0; i<privileges->count; i++ ) { - privname = luid_to_privilege_name( &privileges->set[i].luid ); - if ( privname ) { - if ( !add_string_to_array( talloc_tos(), privname, &privname_array, &num_priv ) ) - return NT_STATUS_NO_MEMORY; - } - } - - if ( num_priv ) { - out->rights = TALLOC_P( talloc_tos(), UNISTR4_ARRAY ); - if (!out->rights) { - return NT_STATUS_NO_MEMORY; - } - - if ( !init_unistr4_array( out->rights, num_priv, privname_array ) ) - return NT_STATUS_NO_MEMORY; - - out->count = num_priv; - } - - return NT_STATUS_OK; -} - -/******************************************************************* -reads or writes a LSA_Q_ENUM_ACCT_RIGHTS structure. -********************************************************************/ -bool lsa_io_q_enum_acct_rights(const char *desc, LSA_Q_ENUM_ACCT_RIGHTS *in, prs_struct *ps, int depth) -{ - - if (in == NULL) - return False; - - prs_debug(ps, depth, desc, "lsa_io_q_enum_acct_rights"); - depth++; - - if (!smb_io_pol_hnd("", &in->pol, ps, depth)) - return False; - - if(!smb_io_dom_sid2("sid", &in->sid, ps, depth)) - return False; - - return True; -} - - -/******************************************************************* -reads or writes a LSA_R_ENUM_ACCT_RIGHTS structure. -********************************************************************/ -bool lsa_io_r_enum_acct_rights(const char *desc, LSA_R_ENUM_ACCT_RIGHTS *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_enum_acct_rights"); - depth++; - - if(!prs_uint32("count ", ps, depth, &out->count)) - return False; - - if ( !prs_pointer("rights", ps, depth, (void*)&out->rights, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) ) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} - - -/******************************************************************* - Inits an LSA_Q_ADD_ACCT_RIGHTS structure. -********************************************************************/ -void init_q_add_acct_rights( LSA_Q_ADD_ACCT_RIGHTS *in, POLICY_HND *hnd, - DOM_SID *sid, uint32 count, const char **rights ) -{ - DEBUG(5, ("init_q_add_acct_rights\n")); - - in->pol = *hnd; - init_dom_sid2(&in->sid, sid); - - in->rights = TALLOC_P( talloc_tos(), UNISTR4_ARRAY ); - if (!in->rights) { - smb_panic("init_q_add_acct_rights: talloc fail\n"); - return; - } - init_unistr4_array( in->rights, count, rights ); - - in->count = count; -} - - -/******************************************************************* -reads or writes a LSA_Q_ADD_ACCT_RIGHTS structure. -********************************************************************/ -bool lsa_io_q_add_acct_rights(const char *desc, LSA_Q_ADD_ACCT_RIGHTS *in, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_add_acct_rights"); - depth++; - - if (!smb_io_pol_hnd("", &in->pol, ps, depth)) - return False; - - if(!smb_io_dom_sid2("sid", &in->sid, ps, depth)) - return False; - - if(!prs_uint32("count", ps, depth, &in->count)) - return False; - - if ( !prs_pointer("rights", ps, depth, (void*)&in->rights, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) ) - return False; - - return True; -} - -/******************************************************************* -reads or writes a LSA_R_ENUM_ACCT_RIGHTS structure. -********************************************************************/ -bool lsa_io_r_add_acct_rights(const char *desc, LSA_R_ADD_ACCT_RIGHTS *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_add_acct_rights"); - depth++; - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} - -/******************************************************************* - Inits an LSA_Q_REMOVE_ACCT_RIGHTS structure. -********************************************************************/ - -void init_q_remove_acct_rights(LSA_Q_REMOVE_ACCT_RIGHTS *in, - POLICY_HND *hnd, - DOM_SID *sid, - uint32 removeall, - uint32 count, - const char **rights) -{ - DEBUG(5, ("init_q_remove_acct_rights\n")); - - in->pol = *hnd; - - init_dom_sid2(&in->sid, sid); - - in->removeall = removeall; - in->count = count; - - in->rights = TALLOC_P( talloc_tos(), UNISTR4_ARRAY ); - if (!in->rights) { - smb_panic("init_q_remove_acct_rights: talloc fail\n"); - return; - } - init_unistr4_array( in->rights, count, rights ); -} - -/******************************************************************* -reads or writes a LSA_Q_REMOVE_ACCT_RIGHTS structure. -********************************************************************/ - -bool lsa_io_q_remove_acct_rights(const char *desc, LSA_Q_REMOVE_ACCT_RIGHTS *in, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_q_remove_acct_rights"); - depth++; - - if (!smb_io_pol_hnd("", &in->pol, ps, depth)) - return False; - - if(!smb_io_dom_sid2("sid", &in->sid, ps, depth)) - return False; - - if(!prs_uint32("removeall", ps, depth, &in->removeall)) - return False; - - if(!prs_uint32("count", ps, depth, &in->count)) - return False; - - if ( !prs_pointer("rights", ps, depth, (void*)&in->rights, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) ) - return False; - - return True; -} - -/******************************************************************* -reads or writes a LSA_R_ENUM_ACCT_RIGHTS structure. -********************************************************************/ -bool lsa_io_r_remove_acct_rights(const char *desc, LSA_R_REMOVE_ACCT_RIGHTS *out, prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "lsa_io_r_remove_acct_rights"); - depth++; - - if(!prs_ntstatus("status", ps, depth, &out->status)) - return False; - - return True; -} diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 9e1937ea32..418f857df8 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -1859,4 +1859,14 @@ uint32 str_len_uni(UNISTR *source) return i; } +/******************************************************************* + Verifies policy handle +********************************************************************/ +bool policy_handle_is_valid(const POLICY_HND *hnd) +{ + POLICY_HND zero_pol; + + ZERO_STRUCT(zero_pol); + return ((memcmp(&zero_pol, hnd, sizeof(POLICY_HND)) == 0) ? false : true ); +} diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c deleted file mode 100644 index 257f461d7c..0000000000 --- a/source3/rpc_parse/parse_net.c +++ /dev/null @@ -1,3140 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1997, - * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, - * Copyright (C) Paul Ashton 1997. - * Copyright (C) Jean Francois Micouleau 2002. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_PARSE - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -static bool net_io_neg_flags(const char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth) -{ - if (neg == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_neg_flags"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("neg_flags", ps, depth, &neg->neg_flags)) - return False; - - return True; -} - -/******************************************************************* - Inits a NETLOGON_INFO_3 structure. -********************************************************************/ - -static void init_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts) -{ - info->flags = flags; - info->logon_attempts = logon_attempts; - info->reserved_1 = 0x0; - info->reserved_2 = 0x0; - info->reserved_3 = 0x0; - info->reserved_4 = 0x0; - info->reserved_5 = 0x0; -} - -/******************************************************************* - Reads or writes a NETLOGON_INFO_3 structure. -********************************************************************/ - -static bool net_io_netinfo_3(const char *desc, NETLOGON_INFO_3 *info, prs_struct *ps, int depth) -{ - if (info == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_netinfo_3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("flags ", ps, depth, &info->flags)) - return False; - if(!prs_uint32("logon_attempts", ps, depth, &info->logon_attempts)) - return False; - if(!prs_uint32("reserved_1 ", ps, depth, &info->reserved_1)) - return False; - if(!prs_uint32("reserved_2 ", ps, depth, &info->reserved_2)) - return False; - if(!prs_uint32("reserved_3 ", ps, depth, &info->reserved_3)) - return False; - if(!prs_uint32("reserved_4 ", ps, depth, &info->reserved_4)) - return False; - if(!prs_uint32("reserved_5 ", ps, depth, &info->reserved_5)) - return False; - - return True; -} - - -/******************************************************************* - Inits a NETLOGON_INFO_1 structure. -********************************************************************/ - -static void init_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status) -{ - info->flags = flags; - info->pdc_status = pdc_status; -} - -/******************************************************************* - Reads or writes a NETLOGON_INFO_1 structure. -********************************************************************/ - -static bool net_io_netinfo_1(const char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth) -{ - if (info == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_netinfo_1"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("flags ", ps, depth, &info->flags)) - return False; - if(!prs_uint32("pdc_status", ps, depth, &info->pdc_status)) - return False; - - return True; -} - -/******************************************************************* - Inits a NETLOGON_INFO_2 structure. -********************************************************************/ - -static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status, - uint32 tc_status, const char *trusted_dc_name) -{ - info->flags = flags; - info->pdc_status = pdc_status; - info->ptr_trusted_dc_name = 1; - info->tc_status = tc_status; - - if (trusted_dc_name != NULL) - init_unistr2(&info->uni_trusted_dc_name, trusted_dc_name, UNI_STR_TERMINATE); - else - init_unistr2(&info->uni_trusted_dc_name, "", UNI_STR_TERMINATE); -} - -/******************************************************************* - Reads or writes a NETLOGON_INFO_2 structure. -********************************************************************/ - -static bool net_io_netinfo_2(const char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth) -{ - if (info == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_netinfo_2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("flags ", ps, depth, &info->flags)) - return False; - if(!prs_uint32("pdc_status ", ps, depth, &info->pdc_status)) - return False; - if(!prs_uint32("ptr_trusted_dc_name", ps, depth, &info->ptr_trusted_dc_name)) - return False; - if(!prs_uint32("tc_status ", ps, depth, &info->tc_status)) - return False; - - if (info->ptr_trusted_dc_name != 0) { - if(!smb_io_unistr2("unistr2", &info->uni_trusted_dc_name, info->ptr_trusted_dc_name, ps, depth)) - return False; - } - - if(!prs_align(ps)) - return False; - - return True; -} - -static bool net_io_ctrl_data_info_5(const char *desc, CTRL_DATA_INFO_5 *info, prs_struct *ps, int depth) -{ - if (info == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_ctrl_data_info_5"); - depth++; - - if ( !prs_uint32( "function_code", ps, depth, &info->function_code ) ) - return False; - - if(!prs_uint32("ptr_domain", ps, depth, &info->ptr_domain)) - return False; - - if ( info->ptr_domain ) { - if(!smb_io_unistr2("domain", &info->domain, info->ptr_domain, ps, depth)) - return False; - } - - return True; -} - -static bool net_io_ctrl_data_info_6(const char *desc, CTRL_DATA_INFO_6 *info, prs_struct *ps, int depth) -{ - if (info == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_ctrl_data_info_6"); - depth++; - - if ( !prs_uint32( "function_code", ps, depth, &info->function_code ) ) - return False; - - if(!prs_uint32("ptr_domain", ps, depth, &info->ptr_domain)) - return False; - - if ( info->ptr_domain ) { - if(!smb_io_unistr2("domain", &info->domain, info->ptr_domain, ps, depth)) - return False; - } - - return True; -} - -/******************************************************************* - Reads or writes an NET_Q_LOGON_CTRL2 structure. -********************************************************************/ - -bool net_io_q_logon_ctrl2(const char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth) -{ - if (q_l == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr ", ps, depth, &q_l->ptr)) - return False; - - if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("function_code", ps, depth, &q_l->function_code)) - return False; - if(!prs_uint32("query_level ", ps, depth, &q_l->query_level)) - return False; - switch ( q_l->function_code ) { - case NETLOGON_CONTROL_REDISCOVER: - if ( !net_io_ctrl_data_info_5( "ctrl_data_info5", &q_l->info.info5, ps, depth) ) - return False; - break; - - case NETLOGON_CONTROL_TC_QUERY: - if ( !net_io_ctrl_data_info_6( "ctrl_data_info6", &q_l->info.info6, ps, depth) ) - return False; - break; - - default: - DEBUG(0,("net_io_q_logon_ctrl2: unknown function_code [%d]\n", - q_l->function_code)); - return False; - } - - return True; -} - -/******************************************************************* - Inits an NET_Q_LOGON_CTRL2 structure. -********************************************************************/ - -void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, const char *srv_name, - uint32 query_level) -{ - DEBUG(5,("init_q_logon_ctrl2\n")); - - q_l->function_code = 0x01; - q_l->query_level = query_level; - - init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE); -} - -/******************************************************************* - Inits an NET_R_LOGON_CTRL2 structure. -********************************************************************/ - -void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level, - uint32 flags, uint32 pdc_status, - uint32 logon_attempts, uint32 tc_status, - const char *trusted_domain_name) -{ - r_l->switch_value = query_level; - - switch (query_level) { - case 1: - r_l->ptr = 1; /* undocumented pointer */ - init_netinfo_1(&r_l->logon.info1, flags, pdc_status); - r_l->status = NT_STATUS_OK; - break; - case 2: - r_l->ptr = 1; /* undocumented pointer */ - init_netinfo_2(&r_l->logon.info2, flags, pdc_status, - tc_status, trusted_domain_name); - r_l->status = NT_STATUS_OK; - break; - case 3: - r_l->ptr = 1; /* undocumented pointer */ - init_netinfo_3(&r_l->logon.info3, flags, logon_attempts); - r_l->status = NT_STATUS_OK; - break; - default: - DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n", - r_l->switch_value)); - r_l->ptr = 0; /* undocumented pointer */ - - /* take a guess at an error code... */ - r_l->status = NT_STATUS_INVALID_INFO_CLASS; - break; - } -} - -/******************************************************************* - Reads or writes an NET_R_LOGON_CTRL2 structure. -********************************************************************/ - -bool net_io_r_logon_ctrl2(const char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth) -{ - if (r_l == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2"); - depth++; - - if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value)) - return False; - if(!prs_uint32("ptr ", ps, depth, &r_l->ptr)) - return False; - - if (r_l->ptr != 0) { - switch (r_l->switch_value) { - case 1: - if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth)) - return False; - break; - case 2: - if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth)) - return False; - break; - case 3: - if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth)) - return False; - break; - default: - DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n", - r_l->switch_value)); - break; - } - } - - if(!prs_ntstatus("status ", ps, depth, &r_l->status)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes an NET_Q_LOGON_CTRL structure. -********************************************************************/ - -bool net_io_q_logon_ctrl(const char *desc, NET_Q_LOGON_CTRL *q_l, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "net_io_q_logon_ctrl"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr ", ps, depth, &q_l->ptr)) - return False; - - if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("function_code", ps, depth, &q_l->function_code)) - return False; - if(!prs_uint32("query_level ", ps, depth, &q_l->query_level)) - return False; - - return True; -} - -/******************************************************************* - Inits an NET_Q_LOGON_CTRL structure. -********************************************************************/ - -void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, const char *srv_name, - uint32 query_level) -{ - DEBUG(5,("init_q_logon_ctrl\n")); - - q_l->function_code = 0x01; /* ??? */ - q_l->query_level = query_level; - - init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE); -} - -/******************************************************************* - Inits an NET_R_LOGON_CTRL structure. -********************************************************************/ - -void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level, - uint32 flags, uint32 pdc_status) -{ - DEBUG(5,("init_r_logon_ctrl\n")); - - r_l->switch_value = query_level; /* should only be 0x1 */ - - switch (query_level) { - case 1: - r_l->ptr = 1; /* undocumented pointer */ - init_netinfo_1(&r_l->logon.info1, flags, pdc_status); - r_l->status = NT_STATUS_OK; - break; - default: - DEBUG(2,("init_r_logon_ctrl: unsupported switch value %d\n", - r_l->switch_value)); - r_l->ptr = 0; /* undocumented pointer */ - - /* take a guess at an error code... */ - r_l->status = NT_STATUS_INVALID_INFO_CLASS; - break; - } -} - -/******************************************************************* - Reads or writes an NET_R_LOGON_CTRL structure. -********************************************************************/ - -bool net_io_r_logon_ctrl(const char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "net_io_r_logon_ctrl"); - depth++; - - if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value)) - return False; - if(!prs_uint32("ptr ", ps, depth, &r_l->ptr)) - return False; - - if (r_l->ptr != 0) { - switch (r_l->switch_value) { - case 1: - if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth)) - return False; - break; - default: - DEBUG(2,("net_io_r_logon_ctrl: unsupported switch value %d\n", - r_l->switch_value)); - break; - } - } - - if(!prs_ntstatus("status ", ps, depth, &r_l->status)) - return False; - - return True; -} - -/******************************************************************* - Inits an NET_Q_REQ_CHAL structure. -********************************************************************/ - -void init_q_req_chal(NET_Q_REQ_CHAL *q_c, - const char *logon_srv, const char *logon_clnt, - const DOM_CHAL *clnt_chal) -{ - DEBUG(5,("init_q_req_chal: %d\n", __LINE__)); - - q_c->undoc_buffer = 1; /* don't know what this buffer is */ - - init_unistr2(&q_c->uni_logon_srv, logon_srv , UNI_STR_TERMINATE); - init_unistr2(&q_c->uni_logon_clnt, logon_clnt, UNI_STR_TERMINATE); - - memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); - - DEBUG(5,("init_q_req_chal: %d\n", __LINE__)); -} - -/******************************************************************* - Reads or writes an NET_Q_REQ_CHAL structure. -********************************************************************/ - -bool net_io_q_req_chal(const char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth) -{ - if (q_c == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_q_req_chal"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer)) - return False; - - if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */ - return False; - if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */ - return False; - - if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_r_req_chal(const char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth) -{ - if (r_c == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_r_req_chal"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */ - return False; - - if(!prs_ntstatus("status", ps, depth, &r_c->status)) - return False; - - return True; -} - - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_q_auth(const char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth) -{ - if (q_a == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_q_auth"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */ - return False; - if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_r_auth(const char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth) -{ - if (r_a == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_r_auth"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */ - return False; - - if(!prs_ntstatus("status", ps, depth, &r_a->status)) - return False; - - return True; -} - -/******************************************************************* - Inits a NET_Q_AUTH_2 struct. -********************************************************************/ - -void init_q_auth_2(NET_Q_AUTH_2 *q_a, - const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name, - const DOM_CHAL *clnt_chal, uint32 clnt_flgs) -{ - DEBUG(5,("init_q_auth_2: %d\n", __LINE__)); - - init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name); - memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); - q_a->clnt_flgs.neg_flags = clnt_flgs; - - DEBUG(5,("init_q_auth_2: %d\n", __LINE__)); -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_q_auth_2(const char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth) -{ - if (q_a == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_q_auth_2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */ - return False; - if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) - return False; - if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_r_auth_2(const char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth) -{ - if (r_a == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_r_auth_2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */ - return False; - if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth)) - return False; - - if(!prs_ntstatus("status", ps, depth, &r_a->status)) - return False; - - return True; -} - -/******************************************************************* - Inits a NET_Q_AUTH_3 struct. -********************************************************************/ - -void init_q_auth_3(NET_Q_AUTH_3 *q_a, - const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name, - const DOM_CHAL *clnt_chal, uint32 clnt_flgs) -{ - DEBUG(5,("init_q_auth_3: %d\n", __LINE__)); - - init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name); - memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); - q_a->clnt_flgs.neg_flags = clnt_flgs; - - DEBUG(5,("init_q_auth_3: %d\n", __LINE__)); -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_q_auth_3(const char *desc, NET_Q_AUTH_3 *q_a, prs_struct *ps, int depth) -{ - if (q_a == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_q_auth_3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */ - return False; - if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) - return False; - if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_r_auth_3(const char *desc, NET_R_AUTH_3 *r_a, prs_struct *ps, int depth) -{ - if (r_a == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_r_auth_3"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_chal("srv_chal", &r_a->srv_chal, ps, depth)) /* server challenge */ - return False; - if(!net_io_neg_flags("srv_flgs", &r_a->srv_flgs, ps, depth)) - return False; - if (!prs_uint32("unknown", ps, depth, &r_a->unknown)) - return False; - - if(!prs_ntstatus("status", ps, depth, &r_a->status)) - return False; - - return True; -} - - -/******************************************************************* - Inits a NET_Q_SRV_PWSET. -********************************************************************/ - -void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, - const char *logon_srv, const char *sess_key, const char *acct_name, - uint16 sec_chan, const char *comp_name, - DOM_CRED *cred, const uchar hashed_mach_pwd[16]) -{ - unsigned char nt_cypher[16]; - - DEBUG(5,("init_q_srv_pwset\n")); - - /* Process the new password. */ - cred_hash3( nt_cypher, hashed_mach_pwd, (const unsigned char *)sess_key, 1); - - init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred); - - memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_q_srv_pwset(const char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth) -{ - if (q_s == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_q_srv_pwset"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */ - return False; - if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */ - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_r_srv_pwset(const char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth) -{ - if (r_s == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_r_srv_pwset"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */ - return False; - - if(!prs_ntstatus("status", ps, depth, &r_s->status)) - return False; - - return True; -} - -/************************************************************************* - Init DOM_SID2 array from a string containing multiple sids - *************************************************************************/ - -static int init_dom_sid2s(TALLOC_CTX *ctx, const char *sids_str, DOM_SID2 **ppsids) -{ - const char *ptr; - char *s2; - int count = 0; - - DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:"")); - - *ppsids = NULL; - - if(sids_str) { - int number; - DOM_SID2 *sids; - TALLOC_CTX *frame = talloc_stackframe(); - - /* Count the number of valid SIDs. */ - for (count = 0, ptr = sids_str; - next_token_talloc(frame,&ptr, &s2, NULL); ) { - DOM_SID tmpsid; - if (string_to_sid(&tmpsid, s2)) - count++; - } - - /* Now allocate space for them. */ - if (count) { - *ppsids = TALLOC_ZERO_ARRAY(ctx, DOM_SID2, count); - if (*ppsids == NULL) { - TALLOC_FREE(frame); - return 0; - } - } else { - *ppsids = NULL; - } - - sids = *ppsids; - - for (number = 0, ptr = sids_str; - next_token_talloc(frame, &ptr, &s2, NULL); ) { - DOM_SID tmpsid; - if (string_to_sid(&tmpsid, s2)) { - /* count only valid sids */ - init_dom_sid2(&sids[number], &tmpsid); - number++; - } - } - TALLOC_FREE(frame); - } - - return count; -} - -/******************************************************************* - Inits a NET_ID_INFO_1 structure. -********************************************************************/ - -void init_id_info1(NET_ID_INFO_1 *id, const char *domain_name, - uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high, - const char *user_name, const char *wksta_name, - const char *sess_key, - unsigned char lm_cypher[16], unsigned char nt_cypher[16]) -{ - unsigned char lm_owf[16]; - unsigned char nt_owf[16]; - - DEBUG(5,("init_id_info1: %d\n", __LINE__)); - - id->ptr_id_info1 = 1; - - id->param_ctrl = param_ctrl; - init_logon_id(&id->logon_id, log_id_low, log_id_high); - - - if (lm_cypher && nt_cypher) { - unsigned char key[16]; -#ifdef DEBUG_PASSWORD - DEBUG(100,("lm cypher:")); - dump_data(100, lm_cypher, 16); - - DEBUG(100,("nt cypher:")); - dump_data(100, nt_cypher, 16); -#endif - - memset(key, 0, 16); - memcpy(key, sess_key, 8); - - memcpy(lm_owf, lm_cypher, 16); - SamOEMhash(lm_owf, key, 16); - memcpy(nt_owf, nt_cypher, 16); - SamOEMhash(nt_owf, key, 16); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("encrypt of lm owf password:")); - dump_data(100, lm_owf, 16); - - DEBUG(100,("encrypt of nt owf password:")); - dump_data(100, nt_owf, 16); -#endif - /* set up pointers to cypher blocks */ - lm_cypher = lm_owf; - nt_cypher = nt_owf; - } - - init_owf_info(&id->lm_owf, lm_cypher); - init_owf_info(&id->nt_owf, nt_cypher); - - init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE); - init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name); - init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE); - init_uni_hdr(&id->hdr_user_name, &id->uni_user_name); - init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE); - init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name); -} - -/******************************************************************* - Reads or writes an NET_ID_INFO_1 structure. -********************************************************************/ - -static bool net_io_id_info1(const char *desc, NET_ID_INFO_1 *id, prs_struct *ps, int depth) -{ - if (id == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_id_info1"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1)) - return False; - - if (id->ptr_id_info1 != 0) { - if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth)) - return False; - - if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl)) - return False; - if(!smb_io_logon_id("", &id->logon_id, ps, depth)) - return False; - - if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth)) - return False; - if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth)) - return False; - - if(!smb_io_owf_info("", &id->lm_owf, ps, depth)) - return False; - if(!smb_io_owf_info("", &id->nt_owf, ps, depth)) - return False; - - if(!smb_io_unistr2("unistr2", &id->uni_domain_name, - id->hdr_domain_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("unistr2", &id->uni_user_name, - id->hdr_user_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("unistr2", &id->uni_wksta_name, - id->hdr_wksta_name.buffer, ps, depth)) - return False; - } - - return True; -} - -/******************************************************************* -Inits a NET_ID_INFO_2 structure. - -This is a network logon packet. The log_id parameters -are what an NT server would generate for LUID once the -user is logged on. I don't think we care about them. - -Note that this has no access to the NT and LM hashed passwords, -so it forwards the challenge, and the NT and LM responses (24 -bytes each) over the secure channel to the Domain controller -for it to say yea or nay. This is the preferred method of -checking for a logon as it doesn't export the password -hashes to anyone who has compromised the secure channel. JRA. -********************************************************************/ - -void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name, - uint32 param_ctrl, - uint32 log_id_low, uint32 log_id_high, - const char *user_name, const char *wksta_name, - const uchar lm_challenge[8], - const uchar * lm_chal_resp, size_t lm_chal_resp_len, - const uchar * nt_chal_resp, size_t nt_chal_resp_len) -{ - - DEBUG(5,("init_id_info2: %d\n", __LINE__)); - - id->ptr_id_info2 = 1; - - id->param_ctrl = param_ctrl; - init_logon_id(&id->logon_id, log_id_low, log_id_high); - - memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal)); - init_str_hdr(&id->hdr_nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0); - init_str_hdr(&id->hdr_lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0); - - init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE); - init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name); - init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE); - init_uni_hdr(&id->hdr_user_name, &id->uni_user_name); - init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE); - init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name); - - init_string2(&id->nt_chal_resp, (const char *)nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len); - init_string2(&id->lm_chal_resp, (const char *)lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len); - -} - -/******************************************************************* - Reads or writes an NET_ID_INFO_2 structure. -********************************************************************/ - -static bool net_io_id_info2(const char *desc, NET_ID_INFO_2 *id, prs_struct *ps, int depth) -{ - if (id == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_id_info2"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2)) - return False; - - if (id->ptr_id_info2 != 0) { - if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth)) - return False; - - if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl)) - return False; - if(!smb_io_logon_id("", &id->logon_id, ps, depth)) - return False; - - if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth)) - return False; - if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth)) - return False; - - if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */ - return False; - - if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth)) - return False; - if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth)) - return False; - - if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name, - id->hdr_domain_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_user_name ", &id->uni_user_name, - id->hdr_user_name.buffer, ps, depth)) - return False; - if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name, - id->hdr_wksta_name.buffer, ps, depth)) - return False; - if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp, - id->hdr_nt_chal_resp.buffer, ps, depth)) - return False; - if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp, - id->hdr_lm_chal_resp.buffer, ps, depth)) - return False; - } - - return True; -} - - -/******************************************************************* - Inits a DOM_SAM_INFO structure. -********************************************************************/ - -void init_sam_info(DOM_SAM_INFO *sam, - const char *logon_srv, const char *comp_name, - DOM_CRED *clnt_cred, - DOM_CRED *rtn_cred, uint16 logon_level, - NET_ID_INFO_CTR *ctr) -{ - DEBUG(5,("init_sam_info: %d\n", __LINE__)); - - init_clnt_info2(&sam->client, logon_srv, comp_name, clnt_cred); - - if (rtn_cred != NULL) { - sam->ptr_rtn_cred = 1; - memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred)); - } else { - sam->ptr_rtn_cred = 0; - } - - sam->logon_level = logon_level; - sam->ctr = ctr; -} - -/******************************************************************* - Inits a DOM_SAM_INFO structure. -********************************************************************/ - -void init_sam_info_ex(DOM_SAM_INFO_EX *sam, - const char *logon_srv, const char *comp_name, - uint16 logon_level, NET_ID_INFO_CTR *ctr) -{ - DEBUG(5,("init_sam_info_ex: %d\n", __LINE__)); - - init_clnt_srv(&sam->client, logon_srv, comp_name); - sam->logon_level = logon_level; - sam->ctr = ctr; -} - -/******************************************************************* - Reads or writes a DOM_SAM_INFO structure. -********************************************************************/ - -static bool net_io_id_info_ctr(const char *desc, NET_ID_INFO_CTR **pp_ctr, prs_struct *ps, int depth) -{ - NET_ID_INFO_CTR *ctr = *pp_ctr; - - prs_debug(ps, depth, desc, "smb_io_sam_info_ctr"); - depth++; - - if (UNMARSHALLING(ps)) { - ctr = *pp_ctr = PRS_ALLOC_MEM(ps, NET_ID_INFO_CTR, 1); - if (ctr == NULL) - return False; - } - - if (ctr == NULL) - return False; - - /* don't 4-byte align here! */ - - if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value)) - return False; - - switch (ctr->switch_value) { - case 1: - if(!net_io_id_info1("", &ctr->auth.id1, ps, depth)) - return False; - break; - case 2: - if(!net_io_id_info2("", &ctr->auth.id2, ps, depth)) - return False; - break; - default: - /* PANIC! */ - DEBUG(4,("smb_io_sam_info_ctr: unknown switch_value!\n")); - break; - } - - return True; -} - -/******************************************************************* - Reads or writes a DOM_SAM_INFO structure. - ********************************************************************/ - -static bool smb_io_sam_info(const char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth) -{ - if (sam == NULL) - return False; - - prs_debug(ps, depth, desc, "smb_io_sam_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_clnt_info2("", &sam->client, ps, depth)) - return False; - - if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred)) - return False; - if (sam->ptr_rtn_cred) { - if(!smb_io_cred("", &sam->rtn_cred, ps, depth)) - return False; - } - - if(!prs_uint16("logon_level ", ps, depth, &sam->logon_level)) - return False; - - if (sam->logon_level != 0) { - if(!net_io_id_info_ctr("logon_info", &sam->ctr, ps, depth)) - return False; - } - - return True; -} - -/******************************************************************* - Reads or writes a DOM_SAM_INFO_EX structure. - ********************************************************************/ - -static bool smb_io_sam_info_ex(const char *desc, DOM_SAM_INFO_EX *sam, prs_struct *ps, int depth) -{ - if (sam == NULL) - return False; - - prs_debug(ps, depth, desc, "smb_io_sam_info_ex"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_clnt_srv("", &sam->client, ps, depth)) - return False; - - if(!prs_uint16("logon_level ", ps, depth, &sam->logon_level)) - return False; - - if (sam->logon_level != 0) { - if(!net_io_id_info_ctr("logon_info", &sam->ctr, ps, depth)) - return False; - } - - return True; -} - -/************************************************************************* - Inits a NET_USER_INFO_3 structure. - - This is a network logon reply packet, and contains much information about - the user. This information is passed as a (very long) paramater list - to avoid having to link in the PASSDB code to every program that deals - with this file. - *************************************************************************/ - -void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, - uint32 user_rid, - uint32 group_rid, - - const char* user_name, - const char* full_name, - const char* home_dir, - const char* dir_drive, - const char* logon_script, - const char* profile_path, - - time_t unix_logon_time, - time_t unix_logoff_time, - time_t unix_kickoff_time, - time_t unix_pass_last_set_time, - time_t unix_pass_can_change_time, - time_t unix_pass_must_change_time, - - uint16 logon_count, uint16 bad_pw_count, - uint32 num_groups, const DOM_GID *gids, - uint32 user_flgs, uint32 acct_flags, - uchar user_session_key[16], - uchar lm_session_key[16], - const char *logon_srv, const char *logon_dom, - const DOM_SID *dom_sid) -{ - /* only cope with one "other" sid, right now. */ - /* need to count the number of space-delimited sids */ - unsigned int i; - int num_other_sids = 0; - - NTTIME logon_time, logoff_time, kickoff_time, - pass_last_set_time, pass_can_change_time, - pass_must_change_time; - - ZERO_STRUCTP(usr); - - usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */ - - /* Create NTTIME structs */ - unix_to_nt_time (&logon_time, unix_logon_time); - unix_to_nt_time (&logoff_time, unix_logoff_time); - unix_to_nt_time (&kickoff_time, unix_kickoff_time); - unix_to_nt_time (&pass_last_set_time, unix_pass_last_set_time); - unix_to_nt_time (&pass_can_change_time, unix_pass_can_change_time); - unix_to_nt_time (&pass_must_change_time, unix_pass_must_change_time); - - usr->logon_time = logon_time; - usr->logoff_time = logoff_time; - usr->kickoff_time = kickoff_time; - usr->pass_last_set_time = pass_last_set_time; - usr->pass_can_change_time = pass_can_change_time; - usr->pass_must_change_time = pass_must_change_time; - - usr->logon_count = logon_count; - usr->bad_pw_count = bad_pw_count; - - usr->user_rid = user_rid; - usr->group_rid = group_rid; - usr->num_groups = num_groups; - - usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */ - usr->user_flgs = user_flgs; - usr->acct_flags = acct_flags; - - if (user_session_key != NULL) - memcpy(usr->user_sess_key, user_session_key, sizeof(usr->user_sess_key)); - else - memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key)); - - usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */ - - memset((char *)usr->lm_sess_key, '\0', sizeof(usr->lm_sess_key)); - - for (i=0; i<7; i++) { - memset(&usr->unknown[i], '\0', sizeof(usr->unknown)); - } - - if (lm_session_key != NULL) { - memcpy(usr->lm_sess_key, lm_session_key, sizeof(usr->lm_sess_key)); - } - - num_other_sids = init_dom_sid2s(ctx, NULL, &usr->other_sids); - - usr->num_other_sids = num_other_sids; - usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0; - - init_unistr2(&usr->uni_user_name, user_name, UNI_FLAGS_NONE); - init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name); - init_unistr2(&usr->uni_full_name, full_name, UNI_FLAGS_NONE); - init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name); - init_unistr2(&usr->uni_logon_script, logon_script, UNI_FLAGS_NONE); - init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script); - init_unistr2(&usr->uni_profile_path, profile_path, UNI_FLAGS_NONE); - init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path); - init_unistr2(&usr->uni_home_dir, home_dir, UNI_FLAGS_NONE); - init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir); - init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_FLAGS_NONE); - init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive); - - usr->num_groups2 = num_groups; - - if (num_groups) { - usr->gids = TALLOC_ZERO_ARRAY(ctx,DOM_GID,num_groups); - if (usr->gids == NULL) - return; - } else { - usr->gids = NULL; - } - - for (i = 0; i < num_groups; i++) - usr->gids[i] = gids[i]; - - init_unistr2(&usr->uni_logon_srv, logon_srv, UNI_FLAGS_NONE); - init_uni_hdr(&usr->hdr_logon_srv, &usr->uni_logon_srv); - init_unistr2(&usr->uni_logon_dom, logon_dom, UNI_FLAGS_NONE); - init_uni_hdr(&usr->hdr_logon_dom, &usr->uni_logon_dom); - - init_dom_sid2(&usr->dom_sid, dom_sid); - /* "other" sids are set up above */ -} - -static void dump_acct_flags(uint32 acct_flags) { - - int lvl = 10; - DEBUG(lvl,("dump_acct_flags\n")); - if (acct_flags & ACB_NORMAL) { - DEBUGADD(lvl,("\taccount has ACB_NORMAL\n")); - } - if (acct_flags & ACB_PWNOEXP) { - DEBUGADD(lvl,("\taccount has ACB_PWNOEXP\n")); - } - if (acct_flags & ACB_ENC_TXT_PWD_ALLOWED) { - DEBUGADD(lvl,("\taccount has ACB_ENC_TXT_PWD_ALLOWED\n")); - } - if (acct_flags & ACB_NOT_DELEGATED) { - DEBUGADD(lvl,("\taccount has ACB_NOT_DELEGATED\n")); - } - if (acct_flags & ACB_USE_DES_KEY_ONLY) { - DEBUGADD(lvl,("\taccount has ACB_USE_DES_KEY_ONLY set, sig verify wont work\n")); - } - if (acct_flags & ACB_NO_AUTH_DATA_REQD) { - DEBUGADD(lvl,("\taccount has ACB_NO_AUTH_DATA_REQD set\n")); - } - if (acct_flags & ACB_PW_EXPIRED) { - DEBUGADD(lvl,("\taccount has ACB_PW_EXPIRED set\n")); - } -} - -static void dump_user_flgs(uint32 user_flags) { - - int lvl = 10; - DEBUG(lvl,("dump_user_flgs\n")); - if (user_flags & NETLOGON_EXTRA_SIDS) { - DEBUGADD(lvl,("\taccount has NETLOGON_EXTRA_SIDS\n")); - } - if (user_flags & NETLOGON_RESOURCE_GROUPS) { - DEBUGADD(lvl,("\taccount has NETLOGON_RESOURCE_GROUPS\n")); - } - if (user_flags & NETLOGON_NTLMV2_ENABLED) { - DEBUGADD(lvl,("\taccount has NETLOGON_NTLMV2_ENABLED\n")); - } - if (user_flags & NETLOGON_CACHED_ACCOUNT) { - DEBUGADD(lvl,("\taccount has NETLOGON_CACHED_ACCOUNT\n")); - } - if (user_flags & NETLOGON_PROFILE_PATH_RETURNED) { - DEBUGADD(lvl,("\taccount has NETLOGON_PROFILE_PATH_RETURNED\n")); - } - if (user_flags & NETLOGON_SERVER_TRUST_ACCOUNT) { - DEBUGADD(lvl,("\taccount has NETLOGON_SERVER_TRUST_ACCOUNT\n")); - } - - -} - -/******************************************************************* - This code has been modified to cope with a NET_USER_INFO_2 - which is - exactly the same as a NET_USER_INFO_3, minus the other sids parameters. - We use validation level to determine if we're marshalling a info 2 or - INFO_3 - be we always return an INFO_3. Based on code donated by Marc - Jacobsen at HP. JRA. -********************************************************************/ - -bool net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, - int depth, uint16 validation_level, bool kerb_validation_level) -{ - unsigned int i; - - if (usr == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_user_info3"); - depth++; - - if (UNMARSHALLING(ps)) - ZERO_STRUCTP(usr); - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info)) - return False; - - if (usr->ptr_user_info == 0) - return True; - - if(!smb_io_time("logon time", &usr->logon_time, ps, depth)) /* logon time */ - return False; - if(!smb_io_time("logoff time", &usr->logoff_time, ps, depth)) /* logoff time */ - return False; - if(!smb_io_time("kickoff time", &usr->kickoff_time, ps, depth)) /* kickoff time */ - return False; - if(!smb_io_time("last set time", &usr->pass_last_set_time, ps, depth)) /* password last set time */ - return False; - if(!smb_io_time("can change time", &usr->pass_can_change_time , ps, depth)) /* password can change time */ - return False; - if(!smb_io_time("must change time", &usr->pass_must_change_time, ps, depth)) /* password must change time */ - return False; - - if(!smb_io_unihdr("hdr_user_name", &usr->hdr_user_name, ps, depth)) /* username unicode string header */ - return False; - if(!smb_io_unihdr("hdr_full_name", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */ - return False; - if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */ - return False; - if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */ - return False; - if(!smb_io_unihdr("hdr_home_dir", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */ - return False; - if(!smb_io_unihdr("hdr_dir_drive", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */ - return False; - - if(!prs_uint16("logon_count ", ps, depth, &usr->logon_count)) /* logon count */ - return False; - if(!prs_uint16("bad_pw_count ", ps, depth, &usr->bad_pw_count)) /* bad password count */ - return False; - - if(!prs_uint32("user_rid ", ps, depth, &usr->user_rid)) /* User RID */ - return False; - if(!prs_uint32("group_rid ", ps, depth, &usr->group_rid)) /* Group RID */ - return False; - if(!prs_uint32("num_groups ", ps, depth, &usr->num_groups)) /* num groups */ - return False; - if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */ - return False; - if(!prs_uint32("user_flgs ", ps, depth, &usr->user_flgs)) /* user flags */ - return False; - dump_user_flgs(usr->user_flgs); - if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* user session key */ - return False; - - if(!smb_io_unihdr("hdr_logon_srv", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */ - return False; - if(!smb_io_unihdr("hdr_logon_dom", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */ - return False; - - if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */ - return False; - - if(!prs_uint8s(False, "lm_sess_key", ps, depth, usr->lm_sess_key, 8)) /* lm session key */ - return False; - - if(!prs_uint32("acct_flags ", ps, depth, &usr->acct_flags)) /* Account flags */ - return False; - dump_acct_flags(usr->acct_flags); - for (i = 0; i < 7; i++) - { - if (!prs_uint32("unkown", ps, depth, &usr->unknown[i])) /* unknown */ - return False; - } - - if (validation_level == 3) { - if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */ - return False; - if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */ - return False; - } else { - if (UNMARSHALLING(ps)) { - usr->num_other_sids = 0; - usr->buffer_other_sids = 0; - } - } - - /* get kerb validation info (not really part of user_info_3) - Guenther */ - - if (kerb_validation_level) { - - if(!prs_uint32("ptr_res_group_dom_sid", ps, depth, &usr->ptr_res_group_dom_sid)) - return False; - if(!prs_uint32("res_group_count", ps, depth, &usr->res_group_count)) - return False; - if(!prs_uint32("ptr_res_groups", ps, depth, &usr->ptr_res_groups)) - return False; - } - - if(!smb_io_unistr2("uni_user_name", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */ - return False; - if(!smb_io_unistr2("uni_full_name", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */ - return False; - if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */ - return False; - if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */ - return False; - if(!smb_io_unistr2("uni_home_dir", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */ - return False; - if(!smb_io_unistr2("uni_dir_drive", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */ - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("num_groups2 ", ps, depth, &usr->num_groups2)) /* num groups2 */ - return False; - - if (usr->num_groups != usr->num_groups2) { - DEBUG(3,("net_io_user_info3: num_groups mismatch! (%d != %d)\n", - usr->num_groups, usr->num_groups2)); - return False; - } - - if (UNMARSHALLING(ps)) { - if (usr->num_groups) { - usr->gids = PRS_ALLOC_MEM(ps, DOM_GID, usr->num_groups); - if (usr->gids == NULL) - return False; - } else { - usr->gids = NULL; - } - } - - for (i = 0; i < usr->num_groups; i++) { - if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */ - return False; - } - - if(!smb_io_unistr2("uni_logon_srv", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */ - return False; - if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_dom.buffer, ps, depth)) /* logon domain unicode string */ - return False; - - if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth)) /* domain SID */ - return False; - - if (validation_level == 3 && usr->buffer_other_sids) { - - uint32 num_other_sids = usr->num_other_sids; - - if (!(usr->user_flgs & NETLOGON_EXTRA_SIDS)) { - DEBUG(10,("net_io_user_info3: user_flgs attribute does not have NETLOGON_EXTRA_SIDS\n")); - /* return False; */ - } - - if (!prs_uint32("num_other_sids", ps, depth, - &num_other_sids)) - return False; - - if (num_other_sids != usr->num_other_sids) - return False; - - if (UNMARSHALLING(ps)) { - if (usr->num_other_sids) { - usr->other_sids = PRS_ALLOC_MEM(ps, DOM_SID2, usr->num_other_sids); - usr->other_sids_attrib = - PRS_ALLOC_MEM(ps, uint32, usr->num_other_sids); - } else { - usr->other_sids = NULL; - usr->other_sids_attrib = NULL; - } - - if ((num_other_sids != 0) && - ((usr->other_sids == NULL) || - (usr->other_sids_attrib == NULL))) - return False; - } - - /* First the pointers to the SIDS and attributes */ - - depth++; - - for (i=0; i<usr->num_other_sids; i++) { - uint32 ptr = 1; - - if (!prs_uint32("sid_ptr", ps, depth, &ptr)) - return False; - - if (UNMARSHALLING(ps) && (ptr == 0)) - return False; - - if (!prs_uint32("attribute", ps, depth, - &usr->other_sids_attrib[i])) - return False; - } - - for (i = 0; i < usr->num_other_sids; i++) { - if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */ - return False; - } - - depth--; - } - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_q_sam_logon(const char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth) -{ - if (q_l == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_q_sam_logon"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_sam_info("", &q_l->sam_id, ps, depth)) - return False; - - if(!prs_align_uint16(ps)) - return False; - - if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_r_sam_logon(const char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth) -{ - if (r_l == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_r_sam_logon"); - depth++; - - if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */ - return False; - if (&r_l->buffer_creds) { - if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */ - return False; - } - - if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value)) - return False; - if(!prs_align(ps)) - return False; - -#if 1 /* W2k always needs this - even for bad passwd. JRA */ - if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False)) - return False; -#else - if (r_l->switch_value != 0) { - if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False)) - return False; - } -#endif - - if(!prs_uint32("auth_resp ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */ - return False; - - if(!prs_ntstatus("status ", ps, depth, &r_l->status)) - return False; - - if(!prs_align(ps)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_q_sam_logon_ex(const char *desc, NET_Q_SAM_LOGON_EX *q_l, prs_struct *ps, int depth) -{ - if (q_l == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_q_sam_logon_ex"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_sam_info_ex("", &q_l->sam_id, ps, depth)) - return False; - - if(!prs_align_uint16(ps)) - return False; - - if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level)) - return False; - - if (!prs_align(ps)) - return False; - - if(!prs_uint32("flags ", ps, depth, &q_l->flags)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_r_sam_logon_ex(const char *desc, NET_R_SAM_LOGON_EX *r_l, prs_struct *ps, int depth) -{ - if (r_l == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_r_sam_logon_ex"); - depth++; - - if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value)) - return False; - if(!prs_align(ps)) - return False; - -#if 1 /* W2k always needs this - even for bad passwd. JRA */ - if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False)) - return False; -#else - if (r_l->switch_value != 0) { - if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False)) - return False; - } -#endif - - if(!prs_uint32("auth_resp ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */ - return False; - - if(!prs_uint32("flags ", ps, depth, &r_l->flags)) - return False; - - if(!prs_ntstatus("status ", ps, depth, &r_l->status)) - return False; - - if(!prs_align(ps)) - return False; - - return True; -} - - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_q_sam_logoff(const char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth) -{ - if (q_l == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_q_sam_logoff"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_sam_info("", &q_l->sam_id, ps, depth)) /* domain SID */ - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool net_io_r_sam_logoff(const char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth) -{ - if (r_l == NULL) - return False; - - prs_debug(ps, depth, desc, "net_io_r_sam_logoff"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */ - return False; - if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */ - return False; - - if(!prs_ntstatus("status ", ps, depth, &r_l->status)) - return False; - - return True; -} - -/******************************************************************* -makes a NET_Q_SAM_SYNC structure. -********************************************************************/ -bool init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name, - const char *cli_name, DOM_CRED *cli_creds, - DOM_CRED *ret_creds, uint32 database_id, - uint32 next_rid) -{ - DEBUG(5, ("init_q_sam_sync\n")); - - init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE); - init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE); - - if (cli_creds) - memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds)); - - if (cli_creds) - memcpy(&q_s->ret_creds, ret_creds, sizeof(q_s->ret_creds)); - else - memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds)); - - q_s->database_id = database_id; - q_s->restart_state = 0; - q_s->sync_context = next_rid; - q_s->max_size = 0xffff; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -bool net_io_q_sam_sync(const char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "net_io_q_sam_sync"); - depth++; - - if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth)) - return False; - if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth)) - return False; - - if (!smb_io_cred("", &q_s->cli_creds, ps, depth)) - return False; - if (!smb_io_cred("", &q_s->ret_creds, ps, depth)) - return False; - - if (!prs_uint32("database_id ", ps, depth, &q_s->database_id)) - return False; - if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state)) - return False; - if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context)) - return False; - - if (!prs_uint32("max_size", ps, depth, &q_s->max_size)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_delta_hdr(const char *desc, SAM_DELTA_HDR * delta, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "net_io_sam_delta_hdr"); - depth++; - - if (!prs_uint16("type", ps, depth, &delta->type)) - return False; - if (!prs_uint16("type2", ps, depth, &delta->type2)) - return False; - if (!prs_uint32("target_rid", ps, depth, &delta->target_rid)) - return False; - - if (!prs_uint32("type3", ps, depth, &delta->type3)) - return False; - - /* Not sure why we need this but it seems to be necessary to get - sam deltas working. */ - - if (delta->type != 0x16) { - if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta)) - return False; - } - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_delta_mod_count(const char *desc, SAM_DELTA_MOD_COUNT *info, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "net_io_sam_delta_stamp"); - depth++; - - if (!prs_uint32("seqnum", ps, depth, &info->seqnum)) - return False; - if (!prs_uint32("dom_mod_count_ptr", ps, depth, - &info->dom_mod_count_ptr)) - return False; - - if (info->dom_mod_count_ptr) { - if (!prs_uint64("dom_mod_count", ps, depth, - &info->dom_mod_count)) - return False; - } - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "net_io_sam_domain_info"); - depth++; - - if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth)) - return False; - - if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff)) - return False; - if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len)) - return False; - if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len)) - return False; - if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age)) - return False; - if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age)) - return False; - if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count)) - return False; - if (!smb_io_time("creation_time", &info->creation_time, ps, depth)) - return False; - if (!prs_uint32("security_information", ps, depth, &info->security_information)) - return False; - if (!smb_io_bufhdr4("hdr_sec_desc", &info->hdr_sec_desc, ps, depth)) - return False; - if (!smb_io_lockout_string_hdr("hdr_account_lockout_string", &info->hdr_account_lockout, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_unknown2", &info->hdr_unknown2, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_unknown3", &info->hdr_unknown3, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_unknown4", &info->hdr_unknown4, ps, depth)) - return False; - if (!prs_uint32("logon_chgpass", ps, depth, &info->logon_chgpass)) - return False; - if (!prs_uint32("unknown6", ps, depth, &info->unknown6)) - return False; - if (!prs_uint32("unknown7", ps, depth, &info->unknown7)) - return False; - if (!prs_uint32("unknown8", ps, depth, &info->unknown8)) - return False; - - if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name, - info->hdr_dom_name.buffer, ps, depth)) - return False; - if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info, - info->hdr_oem_info.buffer, ps, depth)) - return False; - - if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth)) - return False; - - if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout, - info->hdr_account_lockout.buffer, ps, depth)) - return False; - - if (!smb_io_unistr2("buf_unknown2", &info->buf_unknown2, - info->hdr_unknown2.buffer, ps, depth)) - return False; - if (!smb_io_unistr2("buf_unknown3", &info->buf_unknown3, - info->hdr_unknown3.buffer, ps, depth)) - return False; - if (!smb_io_unistr2("buf_unknown4", &info->buf_unknown4, - info->hdr_unknown4.buffer, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "net_io_sam_group_info"); - depth++; - - if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth)) - return False; - if (!smb_io_gid("gid", &info->gid, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth)) - return False; - if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth)) - return False; - - if (ps->data_offset + 48 > ps->buffer_size) - return False; - ps->data_offset += 48; - - if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name, - info->hdr_grp_name.buffer, ps, depth)) - return False; - if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc, - info->hdr_grp_desc.buffer, ps, depth)) - return False; - if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_passwd_info(const char *desc, SAM_PWD * pwd, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "net_io_sam_passwd_info"); - depth++; - - if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0)) - return False; - - if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth)) - return False; - if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16)) - return False; - - if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth)) - return False; - if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16)) - return False; - - if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth)) - return False; - if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_account_info(const char *desc, SAM_ACCOUNT_INFO *info, - prs_struct *ps, int depth) -{ - BUFHDR2 hdr_priv_data; - uint32 i; - - prs_debug(ps, depth, desc, "net_io_sam_account_info"); - depth++; - - if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth)) - return False; - - if (!prs_uint32("user_rid ", ps, depth, &info->user_rid)) - return False; - if (!prs_uint32("group_rid", ps, depth, &info->group_rid)) - return False; - - if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps, - depth)) - return False; - - if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps, - depth)) - return False; - - if (!smb_io_time("logon_time", &info->logon_time, ps, depth)) - return False; - if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth)) - return False; - - if (!prs_uint32("logon_divs ", ps, depth, &info->logon_divs)) - return False; - if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs)) - return False; - - if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count)) - return False; - if (!prs_uint16("logon_count", ps, depth, &info->logon_count)) - return False; - if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps, - depth)) - return False; - if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps, - depth)) - return False; - - if (!prs_uint32("acb_info", ps, depth, &info->acb_info)) - return False; - if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16)) - return False; - if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16)) - return False; - if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present)) - return False; - if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present)) - return False; - if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired)) - return False; - - if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps, - depth)) - return False; - if (!prs_uint16("country", ps, depth, &info->country)) - return False; - if (!prs_uint16("codepage", ps, depth, &info->codepage)) - return False; - - if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth)) - return False; - if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth)) - return False; - - for (i = 0; i < 3; i++) - { - if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i], - ps, depth)) - return False; - } - - for (i = 0; i < 4; i++) - { - if (!prs_uint32("dw_reserved", ps, depth, - &info->dw_reserved[i])) - return False; - } - - if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name, - info->hdr_acct_name.buffer, ps, depth)) - return False; - prs_align(ps); - if (!smb_io_unistr2("uni_full_name", &info->uni_full_name, - info->hdr_full_name.buffer, ps, depth)) - return False; - prs_align(ps); - if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir, - info->hdr_home_dir.buffer, ps, depth)) - return False; - prs_align(ps); - if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive, - info->hdr_dir_drive.buffer, ps, depth)) - return False; - prs_align(ps); - if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script, - info->hdr_logon_script.buffer, ps, depth)) - return False; - prs_align(ps); - if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc, - info->hdr_acct_desc.buffer, ps, depth)) - return False; - prs_align(ps); - if (!smb_io_unistr2("uni_workstations", &info->uni_workstations, - info->hdr_workstations.buffer, ps, depth)) - return False; - prs_align(ps); - - if (!prs_uint32("unknown1", ps, depth, &info->unknown1)) - return False; - if (!prs_uint32("unknown2", ps, depth, &info->unknown2)) - return False; - - if (!smb_io_rpc_blob("buf_logon_hrs", &info->buf_logon_hrs, ps, depth)) - return False; - prs_align(ps); - if (!smb_io_unistr2("uni_comment", &info->uni_comment, - info->hdr_comment.buffer, ps, depth)) - return False; - prs_align(ps); - if (!smb_io_unistr2("uni_parameters", &info->uni_parameters, - info->hdr_parameters.buffer, ps, depth)) - return False; - prs_align(ps); - if (hdr_priv_data.buffer != 0) - { - int old_offset = 0; - uint32 len = 0x44; - if (!prs_uint32("pwd_len", ps, depth, &len)) - return False; - old_offset = ps->data_offset; - if (len > 0) - { - if (ps->io) - { - /* reading */ - if (!prs_hash1(ps, ps->data_offset, len)) - return False; - } - if (!net_io_sam_passwd_info("pass", &info->pass, - ps, depth)) - return False; - - if (!ps->io) - { - /* writing */ - if (!prs_hash1(ps, old_offset, len)) - return False; - } - } - if (old_offset + len > ps->buffer_size) - return False; - ps->data_offset = old_offset + len; - } - if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth)) - return False; - prs_align(ps); - if (!smb_io_unistr2("uni_profile", &info->uni_profile, - info->hdr_profile.buffer, ps, depth)) - return False; - - prs_align(ps); - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_group_mem_info(const char *desc, SAM_GROUP_MEM_INFO * info, - prs_struct *ps, int depth) -{ - uint32 i; - fstring tmp; - - prs_debug(ps, depth, desc, "net_io_sam_group_mem_info"); - depth++; - - prs_align(ps); - if (!prs_uint32("ptr_rids ", ps, depth, &info->ptr_rids)) - return False; - if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs)) - return False; - if (!prs_uint32("num_members", ps, depth, &info->num_members)) - return False; - - if (ps->data_offset + 16 > ps->buffer_size) - return False; - ps->data_offset += 16; - - if (info->ptr_rids != 0) - { - if (!prs_uint32("num_members2", ps, depth, - &info->num_members2)) - return False; - - if (info->num_members2 != info->num_members) - { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps)) { - if (info->num_members2) { - info->rids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members2); - - if (info->rids == NULL) { - DEBUG(0, ("out of memory allocating %d rids\n", - info->num_members2)); - return False; - } - } else { - info->rids = NULL; - } - } - - for (i = 0; i < info->num_members2; i++) - { - slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i); - if (!prs_uint32(tmp, ps, depth, &info->rids[i])) - return False; - } - } - - if (info->ptr_attribs != 0) - { - if (!prs_uint32("num_members3", ps, depth, - &info->num_members3)) - return False; - if (info->num_members3 != info->num_members) - { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps)) { - if (info->num_members3) { - info->attribs = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members3); - - if (info->attribs == NULL) { - DEBUG(0, ("out of memory allocating %d attribs\n", - info->num_members3)); - return False; - } - } else { - info->attribs = NULL; - } - } - - for (i = 0; i < info->num_members3; i++) - { - slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i); - if (!prs_uint32(tmp, ps, depth, &info->attribs[i])) - return False; - } - } - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "net_io_sam_alias_info"); - depth++; - - if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth)) - return False; - if (!prs_uint32("als_rid", ps, depth, &info->als_rid)) - return False; - if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth)) - return False; - if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth)) - return False; - - if (ps->data_offset + 40 > ps->buffer_size) - return False; - ps->data_offset += 40; - - if (!smb_io_unistr2("uni_als_name", &info->uni_als_name, - info->hdr_als_name.buffer, ps, depth)) - return False; - if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth)) - return False; - - if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc, - info->hdr_als_desc.buffer, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * info, - prs_struct *ps, int depth) -{ - uint32 i; - fstring tmp; - - prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info"); - depth++; - - prs_align(ps); - if (!prs_uint32("num_members", ps, depth, &info->num_members)) - return False; - if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members)) - return False; - - if (ps->data_offset + 16 > ps->buffer_size) - return False; - ps->data_offset += 16; - - if (info->ptr_members != 0) - { - if (!prs_uint32("num_sids", ps, depth, &info->num_sids)) - return False; - if (info->num_sids != info->num_members) - { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps)) { - if (info->num_sids) { - info->ptr_sids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_sids); - - if (info->ptr_sids == NULL) { - DEBUG(0, ("out of memory allocating %d ptr_sids\n", - info->num_sids)); - return False; - } - } else { - info->ptr_sids = NULL; - } - } - - for (i = 0; i < info->num_sids; i++) - { - slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i); - if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i])) - return False; - } - - if (UNMARSHALLING(ps)) { - if (info->num_sids) { - info->sids = TALLOC_ARRAY(ps->mem_ctx, DOM_SID2, info->num_sids); - - if (info->sids == NULL) { - DEBUG(0, ("error allocating %d sids\n", - info->num_sids)); - return False; - } - } else { - info->sids = NULL; - } - } - - for (i = 0; i < info->num_sids; i++) - { - if (info->ptr_sids[i] != 0) - { - slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]", - i); - if (!smb_io_dom_sid2(tmp, &info->sids[i], - ps, depth)) - return False; - } - } - } - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info, - prs_struct *ps, int depth) -{ - unsigned int i; - prs_debug(ps, depth, desc, "net_io_sam_policy_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_uint32("max_log_size", ps, depth, &info->max_log_size)) - return False; - if (!prs_uint64("audit_retention_period", ps, depth, - &info->audit_retention_period)) - return False; - if (!prs_uint32("auditing_mode", ps, depth, &info->auditing_mode)) - return False; - if (!prs_uint32("num_events", ps, depth, &info->num_events)) - return False; - if (!prs_uint32("ptr_events", ps, depth, &info->ptr_events)) - return False; - - if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth)) - return False; - - if (!prs_uint32("sid_ptr", ps, depth, &info->sid_ptr)) - return False; - - if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit)) - return False; - if (!prs_uint32("non_paged_pool_limit", ps, depth, - &info->non_paged_pool_limit)) - return False; - if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size)) - return False; - if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size)) - return False; - if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit)) - return False; - if (!prs_uint64("time_limit", ps, depth, &info->time_limit)) - return False; - if (!smb_io_time("modify_time", &info->modify_time, ps, depth)) - return False; - if (!smb_io_time("create_time", &info->create_time, ps, depth)) - return False; - if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth)) - return False; - - for (i=0; i<4; i++) { - UNIHDR dummy; - if (!smb_io_unihdr("dummy", &dummy, ps, depth)) - return False; - } - - for (i=0; i<4; i++) { - uint32 reserved; - if (!prs_uint32("reserved", ps, depth, &reserved)) - return False; - } - - if (!prs_uint32("num_event_audit_options", ps, depth, - &info->num_event_audit_options)) - return False; - - for (i=0; i<info->num_event_audit_options; i++) - if (!prs_uint32("event_audit_option", ps, depth, - &info->event_audit_option)) - return False; - - if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth)) - return False; - - if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth)) - return False; - - if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth)) - - return False; - - return True; -} - -#if 0 - -/* This function is pretty broken - see bug #334 */ - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_trustdoms_info(const char *desc, SAM_DELTA_TRUSTDOMS *info, - prs_struct *ps, int depth) -{ - int i; - - prs_debug(ps, depth, desc, "net_io_sam_trustdoms_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("buf_size", ps, depth, &info->buf_size)) - return False; - - if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth)) - return False; - - if(!smb_io_dom_sid2("sid", &info->sid, ps, depth)) - return False; - - if(!smb_io_unihdr("hdr_domain", &info->hdr_domain, ps, depth)) - return False; - - if(!prs_uint32("unknown0", ps, depth, &info->unknown0)) - return False; - if(!prs_uint32("unknown1", ps, depth, &info->unknown1)) - return False; - if(!prs_uint32("unknown2", ps, depth, &info->unknown2)) - return False; - - if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2)) - return False; - if(!prs_uint32("ptr", ps, depth, &info->ptr)) - return False; - - for (i=0; i<12; i++) - if(!prs_uint32("unknown3", ps, depth, &info->unknown3)) - return False; - - if (!smb_io_unistr2("domain", &info->domain, True, ps, depth)) - return False; - - return True; -} - -#endif - -#if 0 - -/* This function doesn't work - see bug #334 */ - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_secret_info(const char *desc, SAM_DELTA_SECRET *info, - prs_struct *ps, int depth) -{ - int i; - - prs_debug(ps, depth, desc, "net_io_sam_secret_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("buf_size", ps, depth, &info->buf_size)) - return False; - - if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth)) - return False; - - if (!smb_io_unistr2("secret", &info->secret, True, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("count1", ps, depth, &info->count1)) - return False; - if(!prs_uint32("count2", ps, depth, &info->count2)) - return False; - if(!prs_uint32("ptr", ps, depth, &info->ptr)) - return False; - - - if(!smb_io_time("time1", &info->time1, ps, depth)) /* logon time */ - return False; - if(!prs_uint32("count3", ps, depth, &info->count3)) - return False; - if(!prs_uint32("count4", ps, depth, &info->count4)) - return False; - if(!prs_uint32("ptr2", ps, depth, &info->ptr2)) - return False; - if(!smb_io_time("time2", &info->time2, ps, depth)) /* logon time */ - return False; - if(!prs_uint32("unknow1", ps, depth, &info->unknow1)) - return False; - - - if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2)) - return False; - if(!prs_uint32("ptr3", ps, depth, &info->ptr3)) - return False; - for(i=0; i<12; i++) - if(!prs_uint32("unknow2", ps, depth, &info->unknow2)) - return False; - - if(!prs_uint32("chal_len", ps, depth, &info->chal_len)) - return False; - if(!prs_uint32("reserved1", ps, depth, &info->reserved1)) - return False; - if(!prs_uint32("chal_len2", ps, depth, &info->chal_len2)) - return False; - - if(!prs_uint8s (False, "chal", ps, depth, info->chal, info->chal_len2)) - return False; - - if(!prs_uint32("key_len", ps, depth, &info->key_len)) - return False; - if(!prs_uint32("reserved2", ps, depth, &info->reserved2)) - return False; - if(!prs_uint32("key_len2", ps, depth, &info->key_len2)) - return False; - - if(!prs_uint8s (False, "key", ps, depth, info->key, info->key_len2)) - return False; - - - if(!prs_uint32("buf_size3", ps, depth, &info->buf_size3)) - return False; - - if(!sec_io_desc("sec_desc2", &info->sec_desc2, ps, depth)) - return False; - - - return True; -} - -#endif - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info, - prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "net_io_sam_privs_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_dom_sid2("sid", &info->sid, ps, depth)) - return False; - - if(!prs_uint32("priv_count", ps, depth, &info->priv_count)) - return False; - if(!prs_uint32("priv_control", ps, depth, &info->priv_control)) - return False; - - if(!prs_uint32("priv_attr_ptr", ps, depth, &info->priv_attr_ptr)) - return False; - if(!prs_uint32("priv_name_ptr", ps, depth, &info->priv_name_ptr)) - return False; - - if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit)) - return False; - if (!prs_uint32("non_paged_pool_limit", ps, depth, - &info->non_paged_pool_limit)) - return False; - if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size)) - return False; - if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size)) - return False; - if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit)) - return False; - if (!prs_uint64("time_limit", ps, depth, &info->time_limit)) - return False; - if (!prs_uint32("system_flags", ps, depth, &info->system_flags)) - return False; - if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth)) - return False; - - for (i=0; i<4; i++) { - UNIHDR dummy; - if (!smb_io_unihdr("dummy", &dummy, ps, depth)) - return False; - } - - for (i=0; i<4; i++) { - uint32 reserved; - if (!prs_uint32("reserved", ps, depth, &reserved)) - return False; - } - - if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count)) - return False; - - if (UNMARSHALLING(ps)) { - if (info->attribute_count) { - info->attributes = TALLOC_ARRAY(ps->mem_ctx, uint32, info->attribute_count); - if (!info->attributes) { - return False; - } - } else { - info->attributes = NULL; - } - } - - for (i=0; i<info->attribute_count; i++) - if(!prs_uint32("attributes", ps, depth, &info->attributes[i])) - return False; - - if(!prs_uint32("privlist_count", ps, depth, &info->privlist_count)) - return False; - - if (UNMARSHALLING(ps)) { - if (info->privlist_count) { - info->hdr_privslist = TALLOC_ARRAY(ps->mem_ctx, UNIHDR, info->privlist_count); - info->uni_privslist = TALLOC_ARRAY(ps->mem_ctx, UNISTR2, info->privlist_count); - if (!info->hdr_privslist) { - return False; - } - if (!info->uni_privslist) { - return False; - } - } else { - info->hdr_privslist = NULL; - info->uni_privslist = NULL; - } - } - - for (i=0; i<info->privlist_count; i++) - if(!smb_io_unihdr("hdr_privslist", &info->hdr_privslist[i], ps, depth)) - return False; - - for (i=0; i<info->privlist_count; i++) - if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth)) - return False; - - if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -static bool net_io_sam_delta_ctr(const char *desc, - SAM_DELTA_CTR * delta, uint16 type, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "net_io_sam_delta_ctr"); - depth++; - - switch (type) { - /* Seen in sam deltas */ - case SAM_DELTA_MODIFIED_COUNT: - if (!net_io_sam_delta_mod_count("", &delta->mod_count, ps, depth)) - return False; - break; - - case SAM_DELTA_DOMAIN_INFO: - if (!net_io_sam_domain_info("", &delta->domain_info, ps, depth)) - return False; - break; - - case SAM_DELTA_GROUP_INFO: - if (!net_io_sam_group_info("", &delta->group_info, ps, depth)) - return False; - break; - - case SAM_DELTA_ACCOUNT_INFO: - if (!net_io_sam_account_info("", &delta->account_info, ps, depth)) - return False; - break; - - case SAM_DELTA_GROUP_MEM: - if (!net_io_sam_group_mem_info("", &delta->grp_mem_info, ps, depth)) - return False; - break; - - case SAM_DELTA_ALIAS_INFO: - if (!net_io_sam_alias_info("", &delta->alias_info, ps, depth)) - return False; - break; - - case SAM_DELTA_POLICY_INFO: - if (!net_io_sam_policy_info("", &delta->policy_info, ps, depth)) - return False; - break; - - case SAM_DELTA_ALIAS_MEM: - if (!net_io_sam_alias_mem_info("", &delta->als_mem_info, ps, depth)) - return False; - break; - - case SAM_DELTA_PRIVS_INFO: - if (!net_io_sam_privs_info("", &delta->privs_info, ps, depth)) - return False; - break; - - /* These guys are implemented but broken */ - - case SAM_DELTA_TRUST_DOMS: - case SAM_DELTA_SECRET_INFO: - break; - - /* These guys are not implemented yet */ - - case SAM_DELTA_RENAME_GROUP: - case SAM_DELTA_RENAME_USER: - case SAM_DELTA_RENAME_ALIAS: - case SAM_DELTA_DELETE_GROUP: - case SAM_DELTA_DELETE_USER: - default: - DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type)); - break; - } - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -bool net_io_r_sam_sync(const char *desc, - NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth) -{ - uint32 i; - - prs_debug(ps, depth, desc, "net_io_r_sam_sync"); - depth++; - - if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth)) - return False; - if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context)) - return False; - - if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas)) - return False; - if (r_s->ptr_deltas != 0) - { - if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas)) - return False; - if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2)) - return False; - if (r_s->ptr_deltas2 != 0) - { - if (!prs_uint32("num_deltas2", ps, depth, - &r_s->num_deltas2)) - return False; - - if (r_s->num_deltas2 != r_s->num_deltas) - { - /* RPC fault */ - return False; - } - - if (UNMARSHALLING(ps)) { - if (r_s->num_deltas2) { - r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas2); - if (r_s->hdr_deltas == NULL) { - DEBUG(0, ("error tallocating memory " - "for %d delta headers\n", - r_s->num_deltas2)); - return False; - } - } else { - r_s->hdr_deltas = NULL; - } - } - - for (i = 0; i < r_s->num_deltas2; i++) - { - if (!net_io_sam_delta_hdr("", - &r_s->hdr_deltas[i], - ps, depth)) - return False; - } - - if (UNMARSHALLING(ps)) { - if (r_s->num_deltas2) { - r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas2); - if (r_s->deltas == NULL) { - DEBUG(0, ("error tallocating memory " - "for %d deltas\n", - r_s->num_deltas2)); - return False; - } - } else { - r_s->deltas = NULL; - } - } - - for (i = 0; i < r_s->num_deltas2; i++) - { - if (!net_io_sam_delta_ctr( - "", &r_s->deltas[i], - r_s->hdr_deltas[i].type3, - ps, depth)) { - DEBUG(0, ("hmm, failed on i=%d\n", i)); - return False; - } - } - } - } - - prs_align(ps); - if (!prs_ntstatus("status", ps, depth, &(r_s->status))) - return False; - - return True; -} - -/******************************************************************* -makes a NET_Q_SAM_DELTAS structure. -********************************************************************/ -bool init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name, - const char *cli_name, DOM_CRED *cli_creds, - uint32 database_id, uint64 dom_mod_count) -{ - DEBUG(5, ("init_net_q_sam_deltas\n")); - - init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE); - init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE); - - memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds)); - memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds)); - - q_s->database_id = database_id; - q_s->dom_mod_count = dom_mod_count; - q_s->max_size = 0xffff; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -bool net_io_q_sam_deltas(const char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps, - int depth) -{ - prs_debug(ps, depth, desc, "net_io_q_sam_deltas"); - depth++; - - if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth)) - return False; - if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth)) - return False; - - if (!smb_io_cred("", &q_s->cli_creds, ps, depth)) - return False; - if (!smb_io_cred("", &q_s->ret_creds, ps, depth)) - return False; - - if (!prs_uint32("database_id ", ps, depth, &q_s->database_id)) - return False; - if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count)) - return False; - if (!prs_uint32("max_size", ps, depth, &q_s->max_size)) - return False; - - return True; -} - -/******************************************************************* -reads or writes a structure. -********************************************************************/ -bool net_io_r_sam_deltas(const char *desc, - NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth) -{ - unsigned int i; - - prs_debug(ps, depth, desc, "net_io_r_sam_deltas"); - depth++; - - if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth)) - return False; - if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count)) - return False; - - if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas)) - return False; - if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas)) - return False; - if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2)) - return False; - - if (r_s->num_deltas2 != 0) - { - if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2)) - return False; - - if (r_s->ptr_deltas != 0) - { - if (UNMARSHALLING(ps)) { - if (r_s->num_deltas) { - r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas); - if (r_s->hdr_deltas == NULL) { - DEBUG(0, ("error tallocating memory " - "for %d delta headers\n", - r_s->num_deltas)); - return False; - } - } else { - r_s->hdr_deltas = NULL; - } - } - - for (i = 0; i < r_s->num_deltas; i++) - { - net_io_sam_delta_hdr("", &r_s->hdr_deltas[i], - ps, depth); - } - - if (UNMARSHALLING(ps)) { - if (r_s->num_deltas) { - r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas); - if (r_s->deltas == NULL) { - DEBUG(0, ("error tallocating memory " - "for %d deltas\n", - r_s->num_deltas)); - return False; - } - } else { - r_s->deltas = NULL; - } - } - - for (i = 0; i < r_s->num_deltas; i++) - { - if (!net_io_sam_delta_ctr( - "", - &r_s->deltas[i], - r_s->hdr_deltas[i].type2, - ps, depth)) - - return False; - } - } - } - - prs_align(ps); - if (!prs_ntstatus("status", ps, depth, &r_s->status)) - return False; - - return True; -} diff --git a/source3/rpc_parse/parse_ntsvcs.c b/source3/rpc_parse/parse_ntsvcs.c index 5758517ca0..2b15a45506 100644 --- a/source3/rpc_parse/parse_ntsvcs.c +++ b/source3/rpc_parse/parse_ntsvcs.c @@ -25,96 +25,6 @@ /******************************************************************* ********************************************************************/ -bool ntsvcs_io_q_get_version(const char *desc, NTSVCS_Q_GET_VERSION *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_q_get_version"); - depth++; - - /* there is nothing to parse in this PDU */ - - return True; - -} - -/******************************************************************* -********************************************************************/ - -bool ntsvcs_io_r_get_version(const char *desc, NTSVCS_R_GET_VERSION *r_u, prs_struct *ps, int depth) -{ - if ( !r_u ) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_r_get_version"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("version", ps, depth, &r_u->version)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool ntsvcs_io_q_get_device_list_size(const char *desc, NTSVCS_Q_GET_DEVICE_LIST_SIZE *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_q_get_device_list_size"); - depth++; - - if(!prs_align(ps)) - return False; - - if ( !prs_pointer("devicename", ps, depth, (void*)&q_u->devicename, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2) ) - return False; - if ( !prs_align(ps) ) - return False; - - if ( !prs_uint32("flags", ps, depth, &q_u->flags) ) - return False; - - return True; - -} - -/******************************************************************* -********************************************************************/ - -bool ntsvcs_io_r_get_device_list_size(const char *desc, NTSVCS_R_GET_DEVICE_LIST_SIZE *r_u, prs_struct *ps, int depth) -{ - if ( !r_u ) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_r_get_device_list_size"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("size", ps, depth, &r_u->size)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - - -/******************************************************************* -********************************************************************/ - bool ntsvcs_io_q_get_device_list(const char *desc, NTSVCS_Q_GET_DEVICE_LIST *q_u, prs_struct *ps, int depth) { if (q_u == NULL) @@ -171,49 +81,6 @@ bool ntsvcs_io_r_get_device_list(const char *desc, NTSVCS_R_GET_DEVICE_LIST *r_u /******************************************************************* ********************************************************************/ -bool ntsvcs_io_q_validate_device_instance(const char *desc, NTSVCS_Q_VALIDATE_DEVICE_INSTANCE *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_q_validate_device_instance"); - depth++; - - if(!prs_align(ps)) - return False; - - if ( !prs_io_unistr2("devicepath", ps, depth, &q_u->devicepath) ) - return False; - if( !prs_align(ps) ) - return False; - - if ( !prs_uint32("flags", ps, depth, &q_u->flags) ) - return False; - - return True; - -} - -/******************************************************************* -********************************************************************/ - -bool ntsvcs_io_r_validate_device_instance(const char *desc, NTSVCS_R_VALIDATE_DEVICE_INSTANCE *r_u, prs_struct *ps, int depth) -{ - if ( !r_u ) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_r_validate_device_instance"); - depth++; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - bool ntsvcs_io_q_get_device_reg_property(const char *desc, NTSVCS_Q_GET_DEVICE_REG_PROPERTY *q_u, prs_struct *ps, int depth) { if (q_u == NULL) @@ -278,149 +145,3 @@ bool ntsvcs_io_r_get_device_reg_property(const char *desc, NTSVCS_R_GET_DEVICE_R return True; } - -/******************************************************************* -********************************************************************/ - -bool ntsvcs_io_q_get_hw_profile_info(const char *desc, NTSVCS_Q_GET_HW_PROFILE_INFO *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_q_get_hw_profile_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if ( !prs_uint32("index", ps, depth, &q_u->index) ) - return False; - - q_u->buffer_size = 0x000000a8; - - if ( UNMARSHALLING(ps) ) { - q_u->buffer = TALLOC_ARRAY(talloc_tos(), uint8, q_u->buffer_size ); - if (!q_u->buffer) { - return False; - } - } - - if ( !prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size) ) - return False; - - if ( !prs_uint32("buffer_size", ps, depth, &q_u->buffer_size) ) - return False; - - if ( !prs_uint32("unknown1", ps, depth, &q_u->unknown1) ) - return False; - - return True; - -} - -/******************************************************************* -********************************************************************/ - -bool ntsvcs_io_r_get_hw_profile_info(const char *desc, NTSVCS_R_GET_HW_PROFILE_INFO *r_u, prs_struct *ps, int depth) -{ - if ( !r_u ) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_r_get_device_reg_property"); - depth++; - - if ( !prs_align(ps) ) - return False; - - if ( UNMARSHALLING(ps) ) { - if (r_u->buffer_size) { - r_u->buffer = TALLOC_ARRAY(talloc_tos(), uint8, r_u->buffer_size ); - if (!r_u->buffer) { - return False; - } - } else { - r_u->buffer = NULL; - } - } - - if ( !prs_uint8s(True, "buffer", ps, depth, r_u->buffer, r_u->buffer_size) ) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool ntsvcs_io_q_hw_profile_flags(const char *desc, NTSVCS_Q_HW_PROFILE_FLAGS *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_q_hw_profile_flags"); - depth++; - - if(!prs_align(ps)) - return False; - - if ( !prs_uint32("unknown1", ps, depth, &q_u->unknown1) ) - return False; - - - if ( !prs_io_unistr2("devicepath", ps, depth, &q_u->devicepath) ) - return False; - if( !prs_align(ps) ) - return False; - - if ( !prs_uint32("unknown2", ps, depth, &q_u->unknown2) ) - return False; - if ( !prs_uint32("unknown3", ps, depth, &q_u->unknown3) ) - return False; - if ( !prs_uint32("unknown4", ps, depth, &q_u->unknown4) ) - return False; - if ( !prs_uint32("unknown5", ps, depth, &q_u->unknown5) ) - return False; - if ( !prs_uint32("unknown6", ps, depth, &q_u->unknown6) ) - return False; - if ( !prs_uint32("unknown7", ps, depth, &q_u->unknown7) ) - return False; - - if ( !prs_uint32("unknown1", ps, depth, &q_u->unknown1) ) - return False; - - return True; - -} - -/******************************************************************* -********************************************************************/ - -bool ntsvcs_io_r_hw_profile_flags(const char *desc, NTSVCS_R_HW_PROFILE_FLAGS *r_u, prs_struct *ps, int depth) -{ - if ( !r_u ) - return False; - - prs_debug(ps, depth, desc, "ntsvcs_io_r_hw_profile_flags"); - depth++; - - if ( !prs_align(ps) ) - return False; - - if ( !prs_uint32("unknown1", ps, depth, &r_u->unknown1) ) - return False; - if ( !prs_uint32("unknown2", ps, depth, &r_u->unknown2) ) - return False; - if ( !prs_uint32("unknown3", ps, depth, &r_u->unknown3) ) - return False; - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - - - - diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c index 6ea128d3a4..c71b31086a 100644 --- a/source3/rpc_parse/parse_sec.c +++ b/source3/rpc_parse/parse_sec.c @@ -27,28 +27,11 @@ #define DBGC_CLASS DBGC_RPC_PARSE /******************************************************************* - Reads or writes a SEC_ACCESS structure. -********************************************************************/ - -bool sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth) -{ - if (t == NULL) - return False; - - prs_debug(ps, depth, desc, "sec_io_access"); - depth++; - - if(!prs_uint32("mask", ps, depth, t)) - return False; - - return True; -} - -/******************************************************************* Reads or writes a SEC_ACE structure. ********************************************************************/ -bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth) +static bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, + int depth) { uint32 old_offset; uint32 offset_ace_size; @@ -130,7 +113,8 @@ bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth) for you as it reads them. ********************************************************************/ -bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth) +static bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, + int depth) { unsigned int i; uint32 old_offset; diff --git a/source3/rpc_parse/parse_srv.c b/source3/rpc_parse/parse_srv.c index 954aa80600..a09e704bed 100644 --- a/source3/rpc_parse/parse_srv.c +++ b/source3/rpc_parse/parse_srv.c @@ -2619,518 +2619,6 @@ bool srv_io_r_net_file_enum(const char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_stru } /******************************************************************* - Inits a SRV_INFO_100 structure. - ********************************************************************/ - -void init_srv_info_100(SRV_INFO_100 *sv100, uint32 platform_id, const char *name) -{ - DEBUG(5,("init_srv_info_100\n")); - - sv100->platform_id = platform_id; - init_buf_unistr2(&sv100->uni_name, &sv100->ptr_name, name); -} - -/******************************************************************* - Reads or writes a SRV_INFO_101 structure. - ********************************************************************/ - -static bool srv_io_info_100(const char *desc, SRV_INFO_100 *sv100, prs_struct *ps, int depth) -{ - if (sv100 == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_info_100"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("platform_id ", ps, depth, &sv100->platform_id)) - return False; - if(!prs_uint32("ptr_name ", ps, depth, &sv100->ptr_name)) - return False; - - if(!smb_io_unistr2("uni_name ", &sv100->uni_name, True, ps, depth)) - return False; - - return True; -} - - -/******************************************************************* - Inits a SRV_INFO_101 structure. - ********************************************************************/ - -void init_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, const char *name, - uint32 ver_major, uint32 ver_minor, - uint32 srv_type, const char *comment) -{ - DEBUG(5,("init_srv_info_101\n")); - - sv101->platform_id = platform_id; - init_buf_unistr2(&sv101->uni_name, &sv101->ptr_name, name); - sv101->ver_major = ver_major; - sv101->ver_minor = ver_minor; - sv101->srv_type = srv_type; - init_buf_unistr2(&sv101->uni_comment, &sv101->ptr_comment, comment); -} - -/******************************************************************* - Reads or writes a SRV_INFO_101 structure. - ********************************************************************/ - -static bool srv_io_info_101(const char *desc, SRV_INFO_101 *sv101, prs_struct *ps, int depth) -{ - if (sv101 == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_info_101"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("platform_id ", ps, depth, &sv101->platform_id)) - return False; - if(!prs_uint32("ptr_name ", ps, depth, &sv101->ptr_name)) - return False; - if(!prs_uint32("ver_major ", ps, depth, &sv101->ver_major)) - return False; - if(!prs_uint32("ver_minor ", ps, depth, &sv101->ver_minor)) - return False; - if(!prs_uint32("srv_type ", ps, depth, &sv101->srv_type)) - return False; - if(!prs_uint32("ptr_comment ", ps, depth, &sv101->ptr_comment)) - return False; - - if(!prs_align(ps)) - return False; - - if(!smb_io_unistr2("uni_name ", &sv101->uni_name, True, ps, depth)) - return False; - if(!smb_io_unistr2("uni_comment ", &sv101->uni_comment, True, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Inits a SRV_INFO_102 structure. - ********************************************************************/ - -void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, const char *name, - const char *comment, uint32 ver_major, uint32 ver_minor, - uint32 srv_type, uint32 users, uint32 disc, uint32 hidden, - uint32 announce, uint32 ann_delta, uint32 licenses, - const char *usr_path) -{ - DEBUG(5,("init_srv_info_102\n")); - - sv102->platform_id = platform_id; - init_buf_unistr2(&sv102->uni_name, &sv102->ptr_name, name); - sv102->ver_major = ver_major; - sv102->ver_minor = ver_minor; - sv102->srv_type = srv_type; - init_buf_unistr2(&sv102->uni_comment, &sv102->ptr_comment, comment); - - /* same as 101 up to here */ - - sv102->users = users; - sv102->disc = disc; - sv102->hidden = hidden; - sv102->announce = announce; - sv102->ann_delta = ann_delta; - sv102->licenses = licenses; - init_buf_unistr2(&sv102->uni_usr_path, &sv102->ptr_usr_path, usr_path); -} - - -/******************************************************************* - Reads or writes a SRV_INFO_102 structure. - ********************************************************************/ - -static bool srv_io_info_102(const char *desc, SRV_INFO_102 *sv102, prs_struct *ps, int depth) -{ - if (sv102 == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_info102"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("platform_id ", ps, depth, &sv102->platform_id)) - return False; - if(!prs_uint32("ptr_name ", ps, depth, &sv102->ptr_name)) - return False; - if(!prs_uint32("ver_major ", ps, depth, &sv102->ver_major)) - return False; - if(!prs_uint32("ver_minor ", ps, depth, &sv102->ver_minor)) - return False; - if(!prs_uint32("srv_type ", ps, depth, &sv102->srv_type)) - return False; - if(!prs_uint32("ptr_comment ", ps, depth, &sv102->ptr_comment)) - return False; - - /* same as 101 up to here */ - - if(!prs_uint32("users ", ps, depth, &sv102->users)) - return False; - if(!prs_uint32("disc ", ps, depth, &sv102->disc)) - return False; - if(!prs_uint32("hidden ", ps, depth, &sv102->hidden)) - return False; - if(!prs_uint32("announce ", ps, depth, &sv102->announce)) - return False; - if(!prs_uint32("ann_delta ", ps, depth, &sv102->ann_delta)) - return False; - if(!prs_uint32("licenses ", ps, depth, &sv102->licenses)) - return False; - if(!prs_uint32("ptr_usr_path", ps, depth, &sv102->ptr_usr_path)) - return False; - - if(!smb_io_unistr2("uni_name ", &sv102->uni_name, True, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("uni_comment ", &sv102->uni_comment, True, ps, depth)) - return False; - if(!prs_align(ps)) - return False; - if(!smb_io_unistr2("uni_usr_path", &sv102->uni_usr_path, True, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a SRV_INFO_102 structure. - ********************************************************************/ - -static bool srv_io_info_ctr(const char *desc, SRV_INFO_CTR *ctr, prs_struct *ps, int depth) -{ - if (ctr == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_info_ctr"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value)) - return False; - if(!prs_uint32("ptr_srv_ctr ", ps, depth, &ctr->ptr_srv_ctr)) - return False; - - if (ctr->ptr_srv_ctr != 0 && ctr->switch_value != 0 && ctr != NULL) { - switch (ctr->switch_value) { - case 100: - if(!srv_io_info_100("sv100", &ctr->srv.sv100, ps, depth)) - return False; - break; - case 101: - if(!srv_io_info_101("sv101", &ctr->srv.sv101, ps, depth)) - return False; - break; - case 102: - if(!srv_io_info_102("sv102", &ctr->srv.sv102, ps, depth)) - return False; - break; - default: - DEBUG(5,("%s no server info at switch_value %d\n", - tab_depth(5,depth), ctr->switch_value)); - break; - } - if(!prs_align(ps)) - return False; - } - - return True; -} - -/******************************************************************* - Inits a SRV_Q_NET_SRV_GET_INFO structure. - ********************************************************************/ - -void init_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv, - const char *server_name, uint32 switch_value) -{ - DEBUG(5,("init_srv_q_net_srv_get_info\n")); - - init_buf_unistr2(&srv->uni_srv_name, &srv->ptr_srv_name, server_name); - - srv->switch_value = switch_value; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool srv_io_q_net_srv_get_info(const char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth) -{ - if (q_n == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_q_net_srv_get_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_srv_name ", ps, depth, &q_n->ptr_srv_name)) - return False; - if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value)) - return False; - - return True; -} - -/******************************************************************* - Inits a SRV_R_NET_SRV_GET_INFO structure. - ********************************************************************/ - -void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv, - uint32 switch_value, SRV_INFO_CTR *ctr, WERROR status) -{ - DEBUG(5,("init_srv_r_net_srv_get_info\n")); - - srv->ctr = ctr; - - if (W_ERROR_IS_OK(status)) { - srv->ctr->switch_value = switch_value; - srv->ctr->ptr_srv_ctr = 1; - } else { - srv->ctr->switch_value = 0; - srv->ctr->ptr_srv_ctr = 0; - } - - srv->status = status; -} - -/******************************************************************* - Inits a SRV_R_NET_SRV_SET_INFO structure. - ********************************************************************/ - -void init_srv_r_net_srv_set_info(SRV_R_NET_SRV_SET_INFO *srv, - uint32 switch_value, WERROR status) -{ - DEBUG(5,("init_srv_r_net_srv_set_info\n")); - - srv->switch_value = switch_value; - srv->status = status; -} - -/******************************************************************* - Reads or writes a structure. -********************************************************************/ - -bool srv_io_q_net_srv_set_info(const char *desc, SRV_Q_NET_SRV_SET_INFO *q_n, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "srv_io_q_net_srv_set_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_srv_name ", ps, depth, &q_n->ptr_srv_name)) - return False; - if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value)) - return False; - - if (UNMARSHALLING(ps)) { - q_n->ctr = PRS_ALLOC_MEM(ps, SRV_INFO_CTR, 1); - - if (!q_n->ctr) - return False; - } - - if(!srv_io_info_ctr("ctr", q_n->ctr, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. - ********************************************************************/ - -bool srv_io_r_net_srv_get_info(const char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth) -{ - if (r_n == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_r_net_srv_get_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!srv_io_info_ctr("ctr", r_n->ctr, ps, depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_n->status)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. - ********************************************************************/ - -bool srv_io_r_net_srv_set_info(const char *desc, SRV_R_NET_SRV_SET_INFO *r_n, - prs_struct *ps, int depth) -{ - prs_debug(ps, depth, desc, "srv_io_r_net_srv_set_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("switch value ", ps, depth, &r_n->switch_value)) - return False; - - if(!prs_werror("status", ps, depth, &r_n->status)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a structure. - ********************************************************************/ - -bool srv_io_q_net_remote_tod(const char *desc, SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth) -{ - if (q_n == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_q_net_remote_tod"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_srv_name ", ps, depth, &q_n->ptr_srv_name)) - return False; - if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a TIME_OF_DAY_INFO structure. - ********************************************************************/ - -static bool srv_io_time_of_day_info(const char *desc, TIME_OF_DAY_INFO *tod, prs_struct *ps, int depth) -{ - if (tod == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_time_of_day_info"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("elapsedt ", ps, depth, &tod->elapsedt)) - return False; - if(!prs_uint32("msecs ", ps, depth, &tod->msecs)) - return False; - if(!prs_uint32("hours ", ps, depth, &tod->hours)) - return False; - if(!prs_uint32("mins ", ps, depth, &tod->mins)) - return False; - if(!prs_uint32("secs ", ps, depth, &tod->secs)) - return False; - if(!prs_uint32("hunds ", ps, depth, &tod->hunds)) - return False; - if(!prs_uint32("timezone ", ps, depth, &tod->zone)) - return False; - if(!prs_uint32("tintervals ", ps, depth, &tod->tintervals)) - return False; - if(!prs_uint32("day ", ps, depth, &tod->day)) - return False; - if(!prs_uint32("month ", ps, depth, &tod->month)) - return False; - if(!prs_uint32("year ", ps, depth, &tod->year)) - return False; - if(!prs_uint32("weekday ", ps, depth, &tod->weekday)) - return False; - - return True; -} - -/******************************************************************* - Inits a TIME_OF_DAY_INFO structure. - ********************************************************************/ - -void init_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs, - uint32 hours, uint32 mins, uint32 secs, uint32 hunds, - uint32 zone, uint32 tintervals, uint32 day, - uint32 month, uint32 year, uint32 weekday) -{ - DEBUG(5,("init_time_of_day_info\n")); - - tod->elapsedt = elapsedt; - tod->msecs = msecs; - tod->hours = hours; - tod->mins = mins; - tod->secs = secs; - tod->hunds = hunds; - tod->zone = zone; - tod->tintervals = tintervals; - tod->day = day; - tod->month = month; - tod->year = year; - tod->weekday = weekday; -} - - -/******************************************************************* - Reads or writes a structure. - ********************************************************************/ - -bool srv_io_r_net_remote_tod(const char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *ps, int depth) -{ - if (r_n == NULL) - return False; - - prs_debug(ps, depth, desc, "srv_io_r_net_remote_tod"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("ptr_srv_tod ", ps, depth, &r_n->ptr_srv_tod)) - return False; - - if(!srv_io_time_of_day_info("tod", r_n->tod, ps, depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_n->status)) - return False; - - return True; -} - -/******************************************************************* initialises a structure. ********************************************************************/ @@ -3491,14 +2979,3 @@ bool srv_io_r_net_file_set_secdesc(const char *desc, SRV_R_NET_FILE_SET_SECDESC return True; } - -/******************************************************************* - Inits a structure -********************************************************************/ - -void init_srv_q_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_u, const char *server) -{ - q_u->ptr_srv_name = 1; - init_unistr2(&q_u->uni_srv_name, server, UNI_STR_TERMINATE); -} - diff --git a/source3/rpc_parse/parse_svcctl.c b/source3/rpc_parse/parse_svcctl.c index 18e12ef0a6..62c1e21927 100644 --- a/source3/rpc_parse/parse_svcctl.c +++ b/source3/rpc_parse/parse_svcctl.c @@ -198,225 +198,6 @@ uint32 svcctl_sizeof_service_config( SERVICE_CONFIG *config ) /******************************************************************* ********************************************************************/ -bool svcctl_io_q_open_scmanager(const char *desc, SVCCTL_Q_OPEN_SCMANAGER *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_open_scmanager"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_pointer("servername", ps, depth, (void*)&q_u->servername, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2)) - return False; - if(!prs_align(ps)) - return False; - - if(!prs_pointer("database", ps, depth, (void*)&q_u->database, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2)) - return False; - if(!prs_align(ps)) - return False; - - if(!prs_uint32("access", ps, depth, &q_u->access)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_open_scmanager(const char *desc, SVCCTL_R_OPEN_SCMANAGER *r_u, prs_struct *ps, int depth) -{ - if (r_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_open_scmanager"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("scm_pol", &r_u->handle, ps, depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_q_get_display_name(const char *desc, SVCCTL_Q_GET_DISPLAY_NAME *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_get_display_name"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth)) - return False; - - if(!smb_io_unistr2("servicename", &q_u->servicename, 1, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("display_name_len", ps, depth, &q_u->display_name_len)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool init_svcctl_r_get_display_name( SVCCTL_R_GET_DISPLAY_NAME *r_u, const char *displayname ) -{ - r_u->display_name_len = strlen(displayname); - init_unistr2( &r_u->displayname, displayname, UNI_STR_TERMINATE ); - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_get_display_name(const char *desc, SVCCTL_R_GET_DISPLAY_NAME *r_u, prs_struct *ps, int depth) -{ - if (r_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_get_display_name"); - depth++; - - if(!prs_align(ps)) - return False; - - - if(!smb_io_unistr2("displayname", &r_u->displayname, 1, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("display_name_len", ps, depth, &r_u->display_name_len)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_q_open_service(const char *desc, SVCCTL_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_open_service"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("scm_pol", &q_u->handle, ps, depth)) - return False; - - if(!smb_io_unistr2("servicename", &q_u->servicename, 1, ps, depth)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("access", ps, depth, &q_u->access)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_open_service(const char *desc, SVCCTL_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth) -{ - if (r_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_open_service"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("service_pol", &r_u->handle, ps, depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_q_query_status(const char *desc, SVCCTL_Q_QUERY_STATUS *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_query_status"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_query_status(const char *desc, SVCCTL_R_QUERY_STATUS *r_u, prs_struct *ps, int depth) -{ - if (r_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_query_status"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!svcctl_io_service_status("service_status", &r_u->svc_status, ps, depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - bool svcctl_io_q_enum_services_status(const char *desc, SVCCTL_Q_ENUM_SERVICES_STATUS *q_u, prs_struct *ps, int depth) { if (q_u == NULL) @@ -481,50 +262,6 @@ bool svcctl_io_r_enum_services_status(const char *desc, SVCCTL_R_ENUM_SERVICES_S /******************************************************************* ********************************************************************/ -bool svcctl_io_q_start_service(const char *desc, SVCCTL_Q_START_SERVICE *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_start_service"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth)) - return False; - - if(!prs_uint32("parmcount", ps, depth, &q_u->parmcount)) - return False; - - if ( !prs_pointer("rights", ps, depth, (void*)&q_u->parameters, sizeof(UNISTR4_ARRAY), (PRS_POINTER_CAST)prs_unistr4_array) ) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_start_service(const char *desc, SVCCTL_R_START_SERVICE *r_u, prs_struct *ps, int depth) -{ - if (r_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_start_service"); - depth++; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - - -/******************************************************************* -********************************************************************/ - bool svcctl_io_q_enum_dependent_services(const char *desc, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, prs_struct *ps, int depth) { if (q_u == NULL) @@ -581,53 +318,6 @@ bool svcctl_io_r_enum_dependent_services(const char *desc, SVCCTL_R_ENUM_DEPENDE /******************************************************************* ********************************************************************/ -bool svcctl_io_q_control_service(const char *desc, SVCCTL_Q_CONTROL_SERVICE *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_control_service"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("service_pol", &q_u->handle, ps, depth)) - return False; - - if(!prs_uint32("control", ps, depth, &q_u->control)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_control_service(const char *desc, SVCCTL_R_CONTROL_SERVICE *r_u, prs_struct *ps, int depth) -{ - if (r_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_control_service"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!svcctl_io_service_status("service_status", &r_u->svc_status, ps, depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - - -/******************************************************************* -********************************************************************/ - bool svcctl_io_q_query_service_config(const char *desc, SVCCTL_Q_QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth) { if (q_u == NULL) @@ -899,195 +589,3 @@ bool svcctl_io_r_query_service_status_ex(const char *desc, SVCCTL_R_QUERY_SERVIC return True; } - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_q_lock_service_db(const char *desc, SVCCTL_Q_LOCK_SERVICE_DB *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_lock_service_db"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("scm_handle", &q_u->handle, ps, depth)) - return False; - - return True; - -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_lock_service_db(const char *desc, SVCCTL_R_LOCK_SERVICE_DB *r_u, prs_struct *ps, int depth) -{ - if ( !r_u ) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_lock_service_db"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("lock_handle", &r_u->h_lock, ps, depth)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_q_unlock_service_db(const char *desc, SVCCTL_Q_UNLOCK_SERVICE_DB *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_unlock_service_db"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("h_lock", &q_u->h_lock, ps, depth)) - return False; - - return True; - -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_unlock_service_db(const char *desc, SVCCTL_R_UNLOCK_SERVICE_DB *r_u, prs_struct *ps, int depth) -{ - if ( !r_u ) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_unlock_service_db"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_q_query_service_sec(const char *desc, SVCCTL_Q_QUERY_SERVICE_SEC *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_query_service_sec"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("handle", &q_u->handle, ps, depth)) - return False; - if(!prs_uint32("security_flags", ps, depth, &q_u->security_flags)) - return False; - if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size)) - return False; - - return True; - -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_query_service_sec(const char *desc, SVCCTL_R_QUERY_SERVICE_SEC *r_u, prs_struct *ps, int depth) -{ - if ( !r_u ) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_query_service_sec"); - depth++; - - if(!prs_align(ps)) - return False; - - if (!prs_rpcbuffer("buffer", ps, depth, &r_u->buffer)) - return False; - - if(!prs_uint32("needed", ps, depth, &r_u->needed)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_q_set_service_sec(const char *desc, SVCCTL_Q_SET_SERVICE_SEC *q_u, prs_struct *ps, int depth) -{ - if (q_u == NULL) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_q_set_service_sec"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!smb_io_pol_hnd("handle", &q_u->handle, ps, depth)) - return False; - if(!prs_uint32("security_flags", ps, depth, &q_u->security_flags)) - return False; - - if (!prs_rpcbuffer("buffer", ps, depth, &q_u->buffer)) - return False; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32("buffer_size", ps, depth, &q_u->buffer_size)) - return False; - - return True; - -} - -/******************************************************************* -********************************************************************/ - -bool svcctl_io_r_set_service_sec(const char *desc, SVCCTL_R_SET_SERVICE_SEC *r_u, prs_struct *ps, int depth) -{ - if ( !r_u ) - return False; - - prs_debug(ps, depth, desc, "svcctl_io_r_set_service_sec"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_werror("status", ps, depth, &r_u->status)) - return False; - - return True; -} - - - - diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c deleted file mode 100644 index f48a397f1d..0000000000 --- a/source3/rpc_server/srv_lsa.c +++ /dev/null @@ -1,789 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1997, - * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, - * Copyright (C) Paul Ashton 1997, - * Copyright (C) Jeremy Allison 2001, - * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002-2003. - * Copyright (C) Gerald (Jerry) Carter 2005 - * - * 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/>. - */ - -/* This is the interface to the lsa server code. */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -static bool proxy_lsa_call(pipes_struct *p, uint8 opnum) -{ - struct api_struct *fns; - int n_fns; - - lsarpc_get_pipe_fns(&fns, &n_fns); - - if (opnum >= n_fns) - return False; - - if (fns[opnum].opnum != opnum) { - smb_panic("LSA function table not sorted"); - } - - return fns[opnum].fn(p); -} - -/*************************************************************************** - api_lsa_open_policy2 - ***************************************************************************/ - -static bool api_lsa_open_policy2(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENPOLICY2); -} - -/*************************************************************************** -api_lsa_open_policy - ***************************************************************************/ - -static bool api_lsa_open_policy(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENPOLICY); -} - -/*************************************************************************** - api_lsa_enum_trust_dom - ***************************************************************************/ - -static bool api_lsa_enum_trust_dom(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_ENUMTRUSTDOM); -} - -/*************************************************************************** - api_lsa_query_info - ***************************************************************************/ - -static bool api_lsa_query_info(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_QUERYINFOPOLICY); -} - -/*************************************************************************** - api_lsa_lookup_sids - ***************************************************************************/ - -static bool api_lsa_lookup_sids(pipes_struct *p) -{ - LSA_Q_LOOKUP_SIDS q_u; - LSA_R_LOOKUP_SIDS r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the info class and policy handle */ - if(!lsa_io_q_lookup_sids("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_sids: failed to unmarshall LSA_Q_LOOKUP_SIDS.\n")); - return False; - } - - r_u.status = _lsa_lookup_sids(p, &q_u, &r_u); - - if(!lsa_io_r_lookup_sids("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_sids: Failed to marshall LSA_R_LOOKUP_SIDS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_names - ***************************************************************************/ - -static bool api_lsa_lookup_names(pipes_struct *p) -{ - LSA_Q_LOOKUP_NAMES q_u; - LSA_R_LOOKUP_NAMES r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the info class and policy handle */ - if(!lsa_io_q_lookup_names("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_names: failed to unmarshall LSA_Q_LOOKUP_NAMES.\n")); - return False; - } - - r_u.status = _lsa_lookup_names(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_names("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_names: Failed to marshall LSA_R_LOOKUP_NAMES.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_close. - ***************************************************************************/ - -static bool api_lsa_close(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_CLOSE); -} - -/*************************************************************************** - api_lsa_open_secret. - ***************************************************************************/ - -static bool api_lsa_open_secret(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENSECRET); -} - -/*************************************************************************** - api_lsa_open_secret. - ***************************************************************************/ - -static bool api_lsa_enum_privs(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_ENUMPRIVS); -} - -/*************************************************************************** - api_lsa_open_secret. - ***************************************************************************/ - -static bool api_lsa_priv_get_dispname(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_LOOKUPPRIVDISPLAYNAME); -} - -/*************************************************************************** - api_lsa_open_secret. - ***************************************************************************/ - -static bool api_lsa_enum_accounts(pipes_struct *p) -{ - LSA_Q_ENUM_ACCOUNTS q_u; - LSA_R_ENUM_ACCOUNTS r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_enum_accounts("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_enum_accounts: failed to unmarshall LSA_Q_ENUM_ACCOUNTS.\n")); - return False; - } - - r_u.status = _lsa_enum_accounts(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_enum_accounts("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_enum_accounts: Failed to marshall LSA_R_ENUM_ACCOUNTS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_UNK_GET_CONNUSER - ***************************************************************************/ - -static bool api_lsa_unk_get_connuser(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_GETUSERNAME); -} - -/*************************************************************************** - api_lsa_create_user - ***************************************************************************/ - -static bool api_lsa_create_account(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_CREATEACCOUNT); -} - -/*************************************************************************** - api_lsa_open_user - ***************************************************************************/ - -static bool api_lsa_open_account(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENACCOUNT); -} - -/*************************************************************************** - api_lsa_get_privs - ***************************************************************************/ - -static bool api_lsa_enum_privsaccount(pipes_struct *p) -{ - LSA_Q_ENUMPRIVSACCOUNT q_u; - LSA_R_ENUMPRIVSACCOUNT r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_enum_privsaccount("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_enum_privsaccount: failed to unmarshall LSA_Q_ENUMPRIVSACCOUNT.\n")); - return False; - } - - r_u.status = _lsa_enum_privsaccount(p, rdata, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_enum_privsaccount("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_enum_privsaccount: Failed to marshall LSA_R_ENUMPRIVSACCOUNT.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_getsystemaccount - ***************************************************************************/ - -static bool api_lsa_getsystemaccount(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_GETSYSTEMACCESSACCOUNT); -} - - -/*************************************************************************** - api_lsa_setsystemaccount - ***************************************************************************/ - -static bool api_lsa_setsystemaccount(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_SETSYSTEMACCESSACCOUNT); -} - -/*************************************************************************** - api_lsa_addprivs - ***************************************************************************/ - -static bool api_lsa_addprivs(pipes_struct *p) -{ - LSA_Q_ADDPRIVS q_u; - LSA_R_ADDPRIVS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_addprivs("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_addprivs: failed to unmarshall LSA_Q_ADDPRIVS.\n")); - return False; - } - - r_u.status = _lsa_addprivs(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_addprivs("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_addprivs: Failed to marshall LSA_R_ADDPRIVS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_removeprivs - ***************************************************************************/ - -static bool api_lsa_removeprivs(pipes_struct *p) -{ - LSA_Q_REMOVEPRIVS q_u; - LSA_R_REMOVEPRIVS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_removeprivs("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_removeprivs: failed to unmarshall LSA_Q_REMOVEPRIVS.\n")); - return False; - } - - r_u.status = _lsa_removeprivs(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_removeprivs("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_removeprivs: Failed to marshall LSA_R_REMOVEPRIVS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_query_secobj - ***************************************************************************/ - -static bool api_lsa_query_secobj(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_QUERYSECURITY); -} - -/*************************************************************************** - api_lsa_add_acct_rights - ***************************************************************************/ - -static bool api_lsa_add_acct_rights(pipes_struct *p) -{ - LSA_Q_ADD_ACCT_RIGHTS q_u; - LSA_R_ADD_ACCT_RIGHTS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_add_acct_rights("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_add_acct_rights: failed to unmarshall LSA_Q_ADD_ACCT_RIGHTS.\n")); - return False; - } - - r_u.status = _lsa_add_acct_rights(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_add_acct_rights("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_add_acct_rights: Failed to marshall LSA_R_ADD_ACCT_RIGHTS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_remove_acct_rights - ***************************************************************************/ - -static bool api_lsa_remove_acct_rights(pipes_struct *p) -{ - LSA_Q_REMOVE_ACCT_RIGHTS q_u; - LSA_R_REMOVE_ACCT_RIGHTS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_remove_acct_rights("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_remove_acct_rights: failed to unmarshall LSA_Q_REMOVE_ACCT_RIGHTS.\n")); - return False; - } - - r_u.status = _lsa_remove_acct_rights(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_remove_acct_rights("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_remove_acct_rights: Failed to marshall LSA_R_REMOVE_ACCT_RIGHTS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_enum_acct_rights - ***************************************************************************/ - -static bool api_lsa_enum_acct_rights(pipes_struct *p) -{ - LSA_Q_ENUM_ACCT_RIGHTS q_u; - LSA_R_ENUM_ACCT_RIGHTS r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_enum_acct_rights("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_enum_acct_rights: failed to unmarshall LSA_Q_ENUM_ACCT_RIGHTS.\n")); - return False; - } - - r_u.status = _lsa_enum_acct_rights(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_enum_acct_rights("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_enum_acct_rights: Failed to marshall LSA_R_ENUM_ACCT_RIGHTS.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_priv_value - ***************************************************************************/ - -static bool api_lsa_lookup_priv_value(pipes_struct *p) -{ - LSA_Q_LOOKUP_PRIV_VALUE q_u; - LSA_R_LOOKUP_PRIV_VALUE r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_lookup_priv_value("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_priv_value: failed to unmarshall LSA_Q_LOOKUP_PRIV_VALUE .\n")); - return False; - } - - r_u.status = _lsa_lookup_priv_value(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_priv_value("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_priv_value: Failed to marshall LSA_R_LOOKUP_PRIV_VALUE.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_open_trust_dom(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_OPENTRUSTEDDOMAIN); -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_create_trust_dom(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_CREATETRUSTEDDOMAIN); -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_create_secret(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_CREATESECRET); -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_set_secret(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_SETSECRET); -} - -/*************************************************************************** - ***************************************************************************/ - -static bool api_lsa_delete_object(pipes_struct *p) -{ - return proxy_lsa_call(p, NDR_LSA_DELETEOBJECT); -} - -/*************************************************************************** - api_lsa_lookup_sids2 - ***************************************************************************/ - -static bool api_lsa_lookup_sids2(pipes_struct *p) -{ - LSA_Q_LOOKUP_SIDS2 q_u; - LSA_R_LOOKUP_SIDS2 r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the info class and policy handle */ - if(!lsa_io_q_lookup_sids2("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_sids2: failed to unmarshall LSA_Q_LOOKUP_SIDS2.\n")); - return False; - } - - r_u.status = _lsa_lookup_sids2(p, &q_u, &r_u); - - if(!lsa_io_r_lookup_sids2("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_sids2: Failed to marshall LSA_R_LOOKUP_SIDS2.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_sids3 - ***************************************************************************/ - -static bool api_lsa_lookup_sids3(pipes_struct *p) -{ - LSA_Q_LOOKUP_SIDS3 q_u; - LSA_R_LOOKUP_SIDS3 r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the info class and policy handle */ - if(!lsa_io_q_lookup_sids3("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_sids3: failed to unmarshall LSA_Q_LOOKUP_SIDS3.\n")); - return False; - } - - r_u.status = _lsa_lookup_sids3(p, &q_u, &r_u); - - if(!lsa_io_r_lookup_sids3("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_sids3: Failed to marshall LSA_R_LOOKUP_SIDS3.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_names2 - ***************************************************************************/ - -static bool api_lsa_lookup_names2(pipes_struct *p) -{ - LSA_Q_LOOKUP_NAMES2 q_u; - LSA_R_LOOKUP_NAMES2 r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the info class and policy handle */ - if(!lsa_io_q_lookup_names2("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_names2: failed to unmarshall LSA_Q_LOOKUP_NAMES2.\n")); - return False; - } - - r_u.status = _lsa_lookup_names2(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_names2("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_names2: Failed to marshall LSA_R_LOOKUP_NAMES2.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_names3 - ***************************************************************************/ - -static bool api_lsa_lookup_names3(pipes_struct *p) -{ - LSA_Q_LOOKUP_NAMES3 q_u; - LSA_R_LOOKUP_NAMES3 r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the info class and policy handle */ - if(!lsa_io_q_lookup_names3("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_names3: failed to unmarshall LSA_Q_LOOKUP_NAMES3.\n")); - return False; - } - - r_u.status = _lsa_lookup_names3(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_names3("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_names3: Failed to marshall LSA_R_LOOKUP_NAMES3.\n")); - return False; - } - - return True; -} - -/*************************************************************************** - api_lsa_lookup_names4 - ***************************************************************************/ - -static bool api_lsa_lookup_names4(pipes_struct *p) -{ - LSA_Q_LOOKUP_NAMES4 q_u; - LSA_R_LOOKUP_NAMES4 r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the info class and policy handle */ - if(!lsa_io_q_lookup_names4("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_lookup_names4: failed to unmarshall LSA_Q_LOOKUP_NAMES4.\n")); - return False; - } - - r_u.status = _lsa_lookup_names4(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!lsa_io_r_lookup_names4("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_lookup_names4: Failed to marshall LSA_R_LOOKUP_NAMES4.\n")); - return False; - } - - return True; -} - -#if 0 /* AD DC work in ongoing in Samba 4 */ - -/*************************************************************************** - api_lsa_query_info2 - ***************************************************************************/ - -static bool api_lsa_query_info2(pipes_struct *p) -{ - LSA_Q_QUERY_INFO2 q_u; - LSA_R_QUERY_INFO2 r_u; - - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!lsa_io_q_query_info2("", &q_u, data, 0)) { - DEBUG(0,("api_lsa_query_info2: failed to unmarshall LSA_Q_QUERY_INFO2.\n")); - return False; - } - - r_u.status = _lsa_query_info2(p, &q_u, &r_u); - - if (!lsa_io_r_query_info2("", &r_u, rdata, 0)) { - DEBUG(0,("api_lsa_query_info2: failed to marshall LSA_R_QUERY_INFO2.\n")); - return False; - } - - return True; -} -#endif /* AD DC work in ongoing in Samba 4 */ - -/*************************************************************************** - \PIPE\ntlsa commands - ***************************************************************************/ - -static struct api_struct api_lsa_cmds[] = -{ - { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 }, - { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy }, - { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info }, - { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom }, - { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close }, - { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret }, - { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids }, - { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names }, - { "LSA_ENUM_PRIVS" , LSA_ENUM_PRIVS , api_lsa_enum_privs }, - { "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname}, - { "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts }, - { "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser }, - { "LSA_CREATEACCOUNT" , LSA_CREATEACCOUNT , api_lsa_create_account }, - { "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account }, - { "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount}, - { "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount }, - { "LSA_SETSYSTEMACCOUNT", LSA_SETSYSTEMACCOUNT, api_lsa_setsystemaccount }, - { "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs }, - { "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs }, - { "LSA_ADDACCTRIGHTS" , LSA_ADDACCTRIGHTS , api_lsa_add_acct_rights }, - { "LSA_REMOVEACCTRIGHTS", LSA_REMOVEACCTRIGHTS, api_lsa_remove_acct_rights }, - { "LSA_ENUMACCTRIGHTS" , LSA_ENUMACCTRIGHTS , api_lsa_enum_acct_rights }, - { "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj }, - { "LSA_LOOKUPPRIVVALUE" , LSA_LOOKUPPRIVVALUE , api_lsa_lookup_priv_value }, - { "LSA_OPENTRUSTDOM" , LSA_OPENTRUSTDOM , api_lsa_open_trust_dom }, - { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret }, - { "LSA_CREATETRUSTDOM" , LSA_CREATETRUSTDOM , api_lsa_create_trust_dom }, - { "LSA_CREATSECRET" , LSA_CREATESECRET , api_lsa_create_secret }, - { "LSA_SETSECRET" , LSA_SETSECRET , api_lsa_set_secret }, - { "LSA_DELETEOBJECT" , LSA_DELETEOBJECT , api_lsa_delete_object }, - { "LSA_LOOKUPSIDS2" , LSA_LOOKUPSIDS2 , api_lsa_lookup_sids2 }, - { "LSA_LOOKUPNAMES2" , LSA_LOOKUPNAMES2 , api_lsa_lookup_names2 }, - { "LSA_LOOKUPNAMES3" , LSA_LOOKUPNAMES3 , api_lsa_lookup_names3 }, - { "LSA_LOOKUPSIDS3" , LSA_LOOKUPSIDS3 , api_lsa_lookup_sids3 }, - { "LSA_LOOKUPNAMES4" , LSA_LOOKUPNAMES4 , api_lsa_lookup_names4 } -#if 0 /* AD DC work in ongoing in Samba 4 */ - /* be careful of the adding of new RPC's. See commentrs below about - ADS DC capabilities */ - { "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 } -#endif /* AD DC work in ongoing in Samba 4 */ -}; - -static int count_fns(void) -{ - int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct); - -#if 0 /* AD DC work is on going in Samba 4 */ - /* - * NOTE: Certain calls can not be enabled if we aren't an ADS DC. Make sure - * these calls are always last and that you decrement by the amount of calls - * to disable. - */ - if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) { - funcs -= 1; - } -#endif /* AD DC work in ongoing in Samba 4 */ - - return funcs; -} - -void lsa_get_pipe_fns( struct api_struct **fns, int *n_fns ) -{ - *fns = api_lsa_cmds; - *n_fns = count_fns(); -} - - -NTSTATUS rpc_lsa_init(void) -{ - int funcs = count_fns(); - - return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds, - funcs); -} diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 3cf83962ee..20c910e46d 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -10,17 +10,18 @@ * Copyright (C) Simo Sorce 2003. * Copyright (C) Gerald (Jerry) Carter 2005. * Copyright (C) Volker Lendecke 2005. + * Copyright (C) Guenther Deschner 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/>. */ @@ -40,12 +41,59 @@ struct lsa_info { }; const struct generic_mapping lsa_generic_mapping = { - POLICY_READ, - POLICY_WRITE, - POLICY_EXECUTE, - POLICY_ALL_ACCESS + LSA_POLICY_READ, + LSA_POLICY_WRITE, + LSA_POLICY_EXECUTE, + LSA_POLICY_ALL_ACCESS }; +/*************************************************************************** + init_lsa_ref_domain_list - adds a domain if it's not already in, returns the index. +***************************************************************************/ + +static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx, + struct lsa_RefDomainList *ref, + const char *dom_name, + DOM_SID *dom_sid) +{ + int num = 0; + + if (dom_name != NULL) { + for (num = 0; num < ref->count; num++) { + if (sid_equal(dom_sid, ref->domains[num].sid)) { + return num; + } + } + } else { + num = ref->count; + } + + if (num >= MAX_REF_DOMAINS) { + /* index not found, already at maximum domain limit */ + return -1; + } + + ref->count = num + 1; + ref->max_size = MAX_REF_DOMAINS; + + ref->domains = TALLOC_REALLOC_ARRAY(mem_ctx, ref->domains, + struct lsa_DomainInfo, ref->count); + if (!ref->domains) { + return -1; + } + + ZERO_STRUCT(ref->domains[num]); + + init_lsa_StringLarge(&ref->domains[num].name, dom_name); + ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid); + if (!ref->domains[num].sid) { + return -1; + } + + return num; +} + + /******************************************************************* Function to free the per handle data. ********************************************************************/ @@ -82,53 +130,16 @@ static void init_dom_query_5(struct lsa_DomainInfo *r, } /*************************************************************************** - init_dom_ref - adds a domain if it's not already in, returns the index. -***************************************************************************/ - -static int init_dom_ref(DOM_R_REF *ref, const char *dom_name, DOM_SID *dom_sid) -{ - int num = 0; - - if (dom_name != NULL) { - for (num = 0; num < ref->num_ref_doms_1; num++) { - if (sid_equal(dom_sid, &ref->ref_dom[num].ref_dom.sid)) - return num; - } - } else { - num = ref->num_ref_doms_1; - } - - if (num >= MAX_REF_DOMAINS) { - /* index not found, already at maximum domain limit */ - return -1; - } - - ref->num_ref_doms_1 = num+1; - ref->ptr_ref_dom = 1; - ref->max_entries = MAX_REF_DOMAINS; - ref->num_ref_doms_2 = num+1; - - ref->hdr_ref_dom[num].ptr_dom_sid = 1; /* dom sid cannot be NULL. */ - - init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, UNI_FLAGS_NONE); - init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, &ref->ref_dom[num].uni_dom_name); - - init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid ); - - return num; -} - -/*************************************************************************** lookup_lsa_rids. Must be called as root for lookup_name to work. ***************************************************************************/ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx, - DOM_R_REF *ref, - DOM_RID *prid, - uint32 num_entries, - const UNISTR2 *name, - int flags, - uint32 *pmapped_count) + struct lsa_RefDomainList *ref, + struct lsa_TranslatedSid *prid, + uint32_t num_entries, + struct lsa_String *name, + int flags, + uint32_t *pmapped_count) { uint32 mapped_count, i; @@ -141,15 +152,14 @@ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx, DOM_SID sid; uint32 rid; int dom_idx; - char *full_name; + const char *full_name; const char *domain; enum lsa_SidType type = SID_NAME_UNKNOWN; /* Split name into domain and user component */ - full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]); + full_name = name[i].string; if (full_name == NULL) { - DEBUG(0, ("pull_ucs2_talloc failed\n")); return NT_STATUS_NO_MEMORY; } @@ -182,11 +192,11 @@ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx, if (type != SID_NAME_UNKNOWN) { sid_split_rid(&sid, &rid); - dom_idx = init_dom_ref(ref, domain, &sid); + dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid); mapped_count++; } - init_dom_rid(&prid[i], rid, type, dom_idx); + init_lsa_translated_sid(&prid[i], type, rid, dom_idx); } *pmapped_count = mapped_count; @@ -198,12 +208,12 @@ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx, ***************************************************************************/ static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx, - DOM_R_REF *ref, - LSA_TRANSLATED_SID3 *trans_sids, - uint32 num_entries, - const UNISTR2 *name, - int flags, - uint32 *pmapped_count) + struct lsa_RefDomainList *ref, + struct lsa_TranslatedSid3 *trans_sids, + uint32_t num_entries, + struct lsa_String *name, + int flags, + uint32 *pmapped_count) { uint32 mapped_count, i; @@ -216,15 +226,16 @@ static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx, DOM_SID sid; uint32 rid; int dom_idx; - char *full_name; + const char *full_name; const char *domain; enum lsa_SidType type = SID_NAME_UNKNOWN; + ZERO_STRUCT(sid); + /* Split name into domain and user component */ - full_name = rpcstr_pull_unistr2_talloc(mem_ctx, &name[i]); + full_name = name[i].string; if (full_name == NULL) { - DEBUG(0, ("pull_ucs2_talloc failed\n")); return NT_STATUS_NO_MEMORY; } @@ -259,164 +270,20 @@ static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx, DOM_SID domain_sid; sid_copy(&domain_sid, &sid); sid_split_rid(&domain_sid, &rid); - dom_idx = init_dom_ref(ref, domain, &domain_sid); + dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid); mapped_count++; } - /* Initialize the LSA_TRANSLATED_SID3 return. */ + /* Initialize the lsa_TranslatedSid3 return. */ trans_sids[i].sid_type = type; - trans_sids[i].sid2 = TALLOC_P(mem_ctx, DOM_SID2); - if (trans_sids[i].sid2 == NULL) { - return NT_STATUS_NO_MEMORY; - } - init_dom_sid2(trans_sids[i].sid2, &sid); - trans_sids[i].sid_idx = dom_idx; + trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid); + trans_sids[i].sid_index = dom_idx; } *pmapped_count = mapped_count; return NT_STATUS_OK; } -/*************************************************************************** - init_reply_lookup_names - ***************************************************************************/ - -static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l, - DOM_R_REF *ref, uint32 num_entries, - DOM_RID *rid, uint32 mapped_count) -{ - r_l->ptr_dom_ref = 1; - r_l->dom_ref = ref; - - r_l->num_entries = num_entries; - r_l->ptr_entries = 1; - r_l->num_entries2 = num_entries; - r_l->dom_rid = rid; - - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - init_reply_lookup_names2 - ***************************************************************************/ - -static void init_reply_lookup_names2(LSA_R_LOOKUP_NAMES2 *r_l, - DOM_R_REF *ref, uint32 num_entries, - DOM_RID2 *rid, uint32 mapped_count) -{ - r_l->ptr_dom_ref = 1; - r_l->dom_ref = ref; - - r_l->num_entries = num_entries; - r_l->ptr_entries = 1; - r_l->num_entries2 = num_entries; - r_l->dom_rid = rid; - - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - init_reply_lookup_names3 - ***************************************************************************/ - -static void init_reply_lookup_names3(LSA_R_LOOKUP_NAMES3 *r_l, - DOM_R_REF *ref, uint32 num_entries, - LSA_TRANSLATED_SID3 *trans_sids, uint32 mapped_count) -{ - r_l->ptr_dom_ref = 1; - r_l->dom_ref = ref; - - r_l->num_entries = num_entries; - r_l->ptr_entries = 1; - r_l->num_entries2 = num_entries; - r_l->trans_sids = trans_sids; - - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - init_reply_lookup_names4 - ***************************************************************************/ - -static void init_reply_lookup_names4(LSA_R_LOOKUP_NAMES4 *r_l, - DOM_R_REF *ref, uint32 num_entries, - LSA_TRANSLATED_SID3 *trans_sids, uint32 mapped_count) -{ - r_l->ptr_dom_ref = 1; - r_l->dom_ref = ref; - - r_l->num_entries = num_entries; - r_l->ptr_entries = 1; - r_l->num_entries2 = num_entries; - r_l->trans_sids = trans_sids; - - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - Init_reply_lookup_sids. - ***************************************************************************/ - -static void init_reply_lookup_sids2(LSA_R_LOOKUP_SIDS2 *r_l, - DOM_R_REF *ref, - uint32 mapped_count) -{ - r_l->ptr_dom_ref = ref ? 1 : 0; - r_l->dom_ref = ref; - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - Init_reply_lookup_sids. - ***************************************************************************/ - -static void init_reply_lookup_sids3(LSA_R_LOOKUP_SIDS3 *r_l, - DOM_R_REF *ref, - uint32 mapped_count) -{ - r_l->ptr_dom_ref = ref ? 1 : 0; - r_l->dom_ref = ref; - r_l->mapped_count = mapped_count; -} - -/*************************************************************************** - Init_reply_lookup_sids. - ***************************************************************************/ - -static NTSTATUS init_reply_lookup_sids(TALLOC_CTX *mem_ctx, - LSA_R_LOOKUP_SIDS *r_l, - DOM_R_REF *ref, - LSA_TRANS_NAME_ENUM2 *names, - uint32 mapped_count) -{ - LSA_TRANS_NAME_ENUM *oldnames = &r_l->names; - - oldnames->num_entries = names->num_entries; - oldnames->ptr_trans_names = names->ptr_trans_names; - oldnames->num_entries2 = names->num_entries2; - oldnames->uni_name = names->uni_name; - - if (names->num_entries) { - int i; - - oldnames->name = TALLOC_ARRAY(mem_ctx, LSA_TRANS_NAME, names->num_entries); - - if (!oldnames->name) { - return NT_STATUS_NO_MEMORY; - } - for (i = 0; i < names->num_entries; i++) { - oldnames->name[i].sid_name_use = names->name[i].sid_name_use; - oldnames->name[i].hdr_name = names->name[i].hdr_name; - oldnames->name[i].domain_idx = names->name[i].domain_idx; - } - } - - r_l->ptr_dom_ref = ref ? 1 : 0; - r_l->dom_ref = ref; - r_l->mapped_count = mapped_count; - return NT_STATUS_OK; -} - static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *sd_size) { DOM_SID local_adm_sid; @@ -427,17 +294,17 @@ static NTSTATUS lsa_get_generic_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *s SEC_ACL *psa = NULL; - init_sec_access(&mask, POLICY_EXECUTE); + init_sec_access(&mask, LSA_POLICY_EXECUTE); init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); sid_copy(&adm_sid, get_global_sam_sid()); sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS); - init_sec_access(&mask, POLICY_ALL_ACCESS); + init_sec_access(&mask, LSA_POLICY_ALL_ACCESS); init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); sid_copy(&local_adm_sid, &global_sid_Builtin); sid_append_rid(&local_adm_sid, BUILTIN_ALIAS_RID_ADMINS); - init_sec_access(&mask, POLICY_ALL_ACCESS); + init_sec_access(&mask, LSA_POLICY_ALL_ACCESS); init_sec_ace(&ace[2], &local_adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 3, ace)) == NULL) @@ -467,7 +334,7 @@ static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name, r_l->hdr_nb_dom_name.uni_max_len += 2; r_l->uni_nb_dom_name.uni_max_len += 1; } - + if (dns_name && *dns_name) { init_unistr2(&r_l->uni_dns_dom_name, dns_name, UNI_FLAGS_NONE); init_uni_hdr(&r_l->hdr_dns_dom_name, &r_l->uni_dns_dom_name); @@ -486,7 +353,7 @@ static void init_dns_dom_info(LSA_DNS_DOM_INFO *r_l, const char *nb_name, if (dom_guid) { memcpy(&r_l->dom_guid, dom_guid, sizeof(struct GUID)); } - + if (dom_sid) { r_l->ptr_dom_sid = 1; init_dom_sid2(&r_l->dom_sid, dom_sid); @@ -528,7 +395,7 @@ NTSTATUS _lsa_OpenPolicy2(pipes_struct *p, /* This is needed for lsa_open_account and rpcclient .... :-) */ if (p->pipe_user.ut.uid == sec_initial_uid()) - acc_granted = POLICY_ALL_ACCESS; + acc_granted = LSA_POLICY_ALL_ACCESS; /* associate the domain SID with the (unique) handle. */ if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) @@ -621,7 +488,7 @@ NTSTATUS _lsa_EnumTrustDom(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights */ - if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains); @@ -667,6 +534,10 @@ NTSTATUS _lsa_EnumTrustDom(pipes_struct *p, return nt_status; } +#define LSA_AUDIT_NUM_CATEGORIES_NT4 7 +#define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9 +#define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4 + /*************************************************************************** _lsa_QueryInfoPolicy ***************************************************************************/ @@ -696,7 +567,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, uint32 policy_def = LSA_AUDIT_POLICY_ALL; /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_AUDIT_INFORMATION)) { + if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) { DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n")); return NT_STATUS_ACCESS_DENIED; } @@ -724,7 +595,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, } case 0x03: /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* Request PolicyPrimaryDomainInformation. */ @@ -732,15 +603,22 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: name = get_global_sam_name(); - sid = get_global_sam_sid(); + sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid()); + if (!sid) { + return NT_STATUS_NO_MEMORY; + } break; case ROLE_DOMAIN_MEMBER: name = lp_workgroup(); /* We need to return the Domain SID here. */ - if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) - sid = &domain_sid; - else + if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + sid = sid_dup_talloc(p->mem_ctx, &domain_sid); + if (!sid) { + return NT_STATUS_NO_MEMORY; + } + } else { return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } break; case ROLE_STANDALONE: name = lp_workgroup(); @@ -753,7 +631,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, break; case 0x05: /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* Request PolicyAccountDomainInformation. */ @@ -764,7 +642,7 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, break; case 0x06: /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; switch (lp_server_role()) { @@ -801,38 +679,40 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p, ***************************************************************************/ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, - uint16 level, /* input */ - int num_sids, /* input */ - const DOM_SID2 *sid, /* input */ - DOM_R_REF **pp_ref, /* output */ - LSA_TRANS_NAME_ENUM2 *names, /* input/output */ - uint32 *pp_mapped_count) + TALLOC_CTX *mem_ctx, + uint16_t level, /* input */ + int num_sids, /* input */ + struct lsa_SidPtr *sid, /* input */ + struct lsa_RefDomainList **pp_ref, /* input/output */ + struct lsa_TranslatedName2 **pp_names,/* input/output */ + uint32_t *pp_mapped_count) /* input/output */ { NTSTATUS status; int i; const DOM_SID **sids = NULL; - DOM_R_REF *ref = NULL; + struct lsa_RefDomainList *ref = NULL; uint32 mapped_count = 0; struct lsa_dom_info *dom_infos = NULL; struct lsa_name_info *name_infos = NULL; + struct lsa_TranslatedName2 *names = NULL; *pp_mapped_count = 0; + *pp_names = NULL; *pp_ref = NULL; - ZERO_STRUCTP(names); if (num_sids == 0) { return NT_STATUS_OK; } sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids); - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); + ref = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList); if (sids == NULL || ref == NULL) { return NT_STATUS_NO_MEMORY; } for (i=0; i<num_sids; i++) { - sids[i] = &sid[i].sid; + sids[i] = sid[i].sid; } status = lookup_sids(p->mem_ctx, num_sids, sids, level, @@ -842,9 +722,8 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, return status; } - names->name = TALLOC_ARRAY(p->mem_ctx, LSA_TRANS_NAME2, num_sids); - names->uni_name = TALLOC_ARRAY(p->mem_ctx, UNISTR2, num_sids); - if ((names->name == NULL) || (names->uni_name == NULL)) { + names = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName2, num_sids); + if (names == NULL) { return NT_STATUS_NO_MEMORY; } @@ -854,8 +733,9 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, break; } - if (init_dom_ref(ref, dom_infos[i].name, - &dom_infos[i].sid) != i) { + if (init_lsa_ref_domain_list(mem_ctx, ref, + dom_infos[i].name, + &dom_infos[i].sid) != i) { DEBUG(0, ("Domain %s mentioned twice??\n", dom_infos[i].name)); return NT_STATUS_INTERNAL_ERROR; @@ -874,7 +754,7 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, * RID as 8 bytes hex, in others it returns the full * SID. We (Jerry/VL) could not figure out which the * hard cases are, so leave it with the SID. */ - name->name = talloc_asprintf(p->mem_ctx, "%s", + name->name = talloc_asprintf(p->mem_ctx, "%s", sid_to_fstring(tmp, sids[i])); if (name->name == NULL) { @@ -883,13 +763,10 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, } else { mapped_count += 1; } - init_lsa_trans_name2(&names->name[i], &names->uni_name[i], - name->type, name->name, name->dom_idx); - } - names->num_entries = num_sids; - names->ptr_trans_names = 1; - names->num_entries2 = num_sids; + init_lsa_translated_name2(&names[i], name->type, + name->name, name->dom_idx, 0); + } status = NT_STATUS_NONE_MAPPED; if (mapped_count > 0) { @@ -901,147 +778,173 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, num_sids, mapped_count, nt_errstr(status))); *pp_mapped_count = mapped_count; + *pp_names = names; *pp_ref = ref; return status; } /*************************************************************************** - _lsa_lookup_sids + _lsa_LookupSids ***************************************************************************/ -NTSTATUS _lsa_lookup_sids(pipes_struct *p, - LSA_Q_LOOKUP_SIDS *q_u, - LSA_R_LOOKUP_SIDS *r_u) +NTSTATUS _lsa_LookupSids(pipes_struct *p, + struct lsa_LookupSids *r) { + NTSTATUS status; struct lsa_info *handle; - int num_sids = q_u->sids.num_entries; + int num_sids = r->in.sids->num_sids; uint32 mapped_count = 0; - DOM_R_REF *ref = NULL; - LSA_TRANS_NAME_ENUM2 names; - NTSTATUS status; + struct lsa_RefDomainList *domains = NULL; + struct lsa_TranslatedName *names_out = NULL; + struct lsa_TranslatedName2 *names = NULL; + int i; - if ((q_u->level < 1) || (q_u->level > 6)) { + if ((r->in.level < 1) || (r->in.level > 6)) { return NT_STATUS_INVALID_PARAMETER; } - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) { return NT_STATUS_INVALID_HANDLE; } /* check if the user has enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { + if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) { return NT_STATUS_ACCESS_DENIED; } if (num_sids > MAX_LOOKUP_SIDS) { - DEBUG(5,("_lsa_lookup_sids: limit of %d exceeded, requested %d\n", + DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n", MAX_LOOKUP_SIDS, num_sids)); return NT_STATUS_NONE_MAPPED; } - r_u->status = _lsa_lookup_sids_internal(p, - q_u->level, - num_sids, - q_u->sids.sid, - &ref, - &names, - &mapped_count); + status = _lsa_lookup_sids_internal(p, + p->mem_ctx, + r->in.level, + num_sids, + r->in.sids->sids, + &domains, + &names, + &mapped_count); - /* Convert from LSA_TRANS_NAME_ENUM2 to LSA_TRANS_NAME_ENUM */ + /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */ + names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName, + num_sids); + if (!names_out) { + return NT_STATUS_NO_MEMORY; + } - status = init_reply_lookup_sids(p->mem_ctx, r_u, ref, &names, mapped_count); - if (!NT_STATUS_IS_OK(status)) { - return status; + for (i=0; i<num_sids; i++) { + names_out[i].sid_type = names[i].sid_type; + names_out[i].name = names[i].name; + names_out[i].sid_index = names[i].sid_index; } - return r_u->status; + + *r->out.domains = domains; + r->out.names->count = num_sids; + r->out.names->names = names_out; + *r->out.count = mapped_count; + + return status; } /*************************************************************************** - _lsa_lookup_sids2 + _lsa_LookupSids2 ***************************************************************************/ -NTSTATUS _lsa_lookup_sids2(pipes_struct *p, - LSA_Q_LOOKUP_SIDS2 *q_u, - LSA_R_LOOKUP_SIDS2 *r_u) +NTSTATUS _lsa_LookupSids2(pipes_struct *p, + struct lsa_LookupSids2 *r) { + NTSTATUS status; struct lsa_info *handle; - int num_sids = q_u->sids.num_entries; + int num_sids = r->in.sids->num_sids; uint32 mapped_count = 0; - DOM_R_REF *ref = NULL; + struct lsa_RefDomainList *domains = NULL; + struct lsa_TranslatedName2 *names = NULL; + bool check_policy = true; - if ((q_u->level < 1) || (q_u->level > 6)) { - return NT_STATUS_INVALID_PARAMETER; + switch (p->hdr_req.opnum) { + case NDR_LSA_LOOKUPSIDS3: + check_policy = false; + break; + case NDR_LSA_LOOKUPSIDS2: + default: + check_policy = true; } - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { - return NT_STATUS_INVALID_HANDLE; + if ((r->in.level < 1) || (r->in.level > 6)) { + return NT_STATUS_INVALID_PARAMETER; } - /* check if the user have enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { - return NT_STATUS_ACCESS_DENIED; + if (check_policy) { + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) { + return NT_STATUS_INVALID_HANDLE; + } + + /* check if the user have enough rights */ + if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) { + return NT_STATUS_ACCESS_DENIED; + } } if (num_sids > MAX_LOOKUP_SIDS) { - DEBUG(5,("_lsa_lookup_sids2: limit of %d exceeded, requested %d\n", + DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n", MAX_LOOKUP_SIDS, num_sids)); return NT_STATUS_NONE_MAPPED; } - r_u->status = _lsa_lookup_sids_internal(p, - q_u->level, - num_sids, - q_u->sids.sid, - &ref, - &r_u->names, - &mapped_count); + status = _lsa_lookup_sids_internal(p, + p->mem_ctx, + r->in.level, + num_sids, + r->in.sids->sids, + &domains, + &names, + &mapped_count); - init_reply_lookup_sids2(r_u, ref, mapped_count); - return r_u->status; + *r->out.domains = domains; + r->out.names->count = num_sids; + r->out.names->names = names; + *r->out.count = mapped_count; + + return status; } /*************************************************************************** - _lsa_lookup_sida3 + _lsa_LookupSids3 ***************************************************************************/ -NTSTATUS _lsa_lookup_sids3(pipes_struct *p, - LSA_Q_LOOKUP_SIDS3 *q_u, - LSA_R_LOOKUP_SIDS3 *r_u) +NTSTATUS _lsa_LookupSids3(pipes_struct *p, + struct lsa_LookupSids3 *r) { - int num_sids = q_u->sids.num_entries; - uint32 mapped_count = 0; - DOM_R_REF *ref = NULL; - - if ((q_u->level < 1) || (q_u->level > 6)) { - return NT_STATUS_INVALID_PARAMETER; - } + struct lsa_LookupSids2 q; /* No policy handle on this call. Restrict to crypto connections. */ if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - DEBUG(0,("_lsa_lookup_sids3: client %s not using schannel for netlogon\n", + DEBUG(0,("_lsa_LookupSids3: client %s not using schannel for netlogon\n", get_remote_machine_name() )); return NT_STATUS_INVALID_PARAMETER; } - if (num_sids > MAX_LOOKUP_SIDS) { - DEBUG(5,("_lsa_lookup_sids3: limit of %d exceeded, requested %d\n", - MAX_LOOKUP_SIDS, num_sids)); - return NT_STATUS_NONE_MAPPED; - } + q.in.handle = NULL; + q.in.sids = r->in.sids; + q.in.level = r->in.level; + q.in.unknown1 = r->in.unknown1; + q.in.unknown2 = r->in.unknown2; + q.in.names = r->in.names; + q.in.count = r->in.count; - r_u->status = _lsa_lookup_sids_internal(p, - q_u->level, - num_sids, - q_u->sids.sid, - &ref, - &r_u->names, - &mapped_count); + q.out.domains = r->out.domains; + q.out.names = r->out.names; + q.out.count = r->out.count; - init_reply_lookup_sids3(r_u, ref, mapped_count); - return r_u->status; + return _lsa_LookupSids2(p, &q); } +/*************************************************************************** + ***************************************************************************/ + static int lsa_lookup_level_to_flags(uint16 level) { int flags; @@ -1068,33 +971,37 @@ static int lsa_lookup_level_to_flags(uint16 level) } /*************************************************************************** -lsa_reply_lookup_names + _lsa_LookupNames ***************************************************************************/ -NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP_NAMES *r_u) +NTSTATUS _lsa_LookupNames(pipes_struct *p, + struct lsa_LookupNames *r) { + NTSTATUS status = NT_STATUS_NONE_MAPPED; struct lsa_info *handle; - UNISTR2 *names = q_u->uni_name; - uint32 num_entries = q_u->num_entries; - DOM_R_REF *ref; - DOM_RID *rids; + struct lsa_String *names = r->in.names; + uint32 num_entries = r->in.num_names; + struct lsa_RefDomainList *domains = NULL; + struct lsa_TranslatedSid *rids = NULL; uint32 mapped_count = 0; int flags = 0; if (num_entries > MAX_LOOKUP_SIDS) { num_entries = MAX_LOOKUP_SIDS; - DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries)); + DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n", + num_entries)); } - - flags = lsa_lookup_level_to_flags(q_u->lookup_level); - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); - if (!ref) { + flags = lsa_lookup_level_to_flags(r->in.level); + + domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList); + if (!domains) { return NT_STATUS_NO_MEMORY; } if (num_entries) { - rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries); + rids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid, + num_entries); if (!rids) { return NT_STATUS_NO_MEMORY; } @@ -1102,146 +1009,136 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP rids = NULL; } - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { - r_u->status = NT_STATUS_INVALID_HANDLE; + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) { + status = NT_STATUS_INVALID_HANDLE; goto done; } /* check if the user have enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { - r_u->status = NT_STATUS_ACCESS_DENIED; + if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) { + status = NT_STATUS_ACCESS_DENIED; goto done; } /* set up the LSA Lookup RIDs response */ become_root(); /* lookup_name can require root privs */ - r_u->status = lookup_lsa_rids(p->mem_ctx, ref, rids, num_entries, - names, flags, &mapped_count); + status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries, + names, flags, &mapped_count); unbecome_root(); done: - if (NT_STATUS_IS_OK(r_u->status) && (num_entries != 0) ) { - if (mapped_count == 0) - r_u->status = NT_STATUS_NONE_MAPPED; - else if (mapped_count != num_entries) - r_u->status = STATUS_SOME_UNMAPPED; + if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) { + if (mapped_count == 0) { + status = NT_STATUS_NONE_MAPPED; + } else if (mapped_count != num_entries) { + status = STATUS_SOME_UNMAPPED; + } } - init_reply_lookup_names(r_u, ref, num_entries, rids, mapped_count); - return r_u->status; + *r->out.count = mapped_count; + *r->out.domains = domains; + r->out.sids->sids = rids; + r->out.sids->count = num_entries; + + return status; } /*************************************************************************** -lsa_reply_lookup_names2 + _lsa_LookupNames2 ***************************************************************************/ -NTSTATUS _lsa_lookup_names2(pipes_struct *p, LSA_Q_LOOKUP_NAMES2 *q_u, LSA_R_LOOKUP_NAMES2 *r_u) +NTSTATUS _lsa_LookupNames2(pipes_struct *p, + struct lsa_LookupNames2 *r) { - struct lsa_info *handle; - UNISTR2 *names = q_u->uni_name; - uint32 num_entries = q_u->num_entries; - DOM_R_REF *ref; - DOM_RID *rids; - DOM_RID2 *rids2; - int i; - uint32 mapped_count = 0; - int flags = 0; - - if (num_entries > MAX_LOOKUP_SIDS) { - num_entries = MAX_LOOKUP_SIDS; - DEBUG(5,("_lsa_lookup_names2: truncating name lookup list to %d\n", num_entries)); - } - - flags = lsa_lookup_level_to_flags(q_u->lookup_level); + NTSTATUS status; + struct lsa_LookupNames q; + struct lsa_TransSidArray2 *sid_array2 = r->in.sids; + struct lsa_TransSidArray *sid_array = NULL; + uint32_t i; - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); - if (ref == NULL) { - r_u->status = NT_STATUS_NO_MEMORY; + sid_array = TALLOC_ZERO_P(p->mem_ctx, struct lsa_TransSidArray); + if (!sid_array) { return NT_STATUS_NO_MEMORY; } - if (num_entries) { - rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID, num_entries); - rids2 = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries); - if ((rids == NULL) || (rids2 == NULL)) { - r_u->status = NT_STATUS_NO_MEMORY; - return NT_STATUS_NO_MEMORY; - } - } else { - rids = NULL; - rids2 = NULL; - } - - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { - r_u->status = NT_STATUS_INVALID_HANDLE; - goto done; - } + q.in.handle = r->in.handle; + q.in.num_names = r->in.num_names; + q.in.names = r->in.names; + q.in.level = r->in.level; + q.in.sids = sid_array; + q.in.count = r->in.count; + /* we do not know what this is for */ + /* = r->in.unknown1; */ + /* = r->in.unknown2; */ - /* check if the user have enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { - r_u->status = NT_STATUS_ACCESS_DENIED; - goto done; - } - - /* set up the LSA Lookup RIDs response */ - become_root(); /* lookup_name can require root privs */ - r_u->status = lookup_lsa_rids(p->mem_ctx, ref, rids, num_entries, - names, flags, &mapped_count); - unbecome_root(); + q.out.domains = r->out.domains; + q.out.sids = sid_array; + q.out.count = r->out.count; -done: + status = _lsa_LookupNames(p, &q); - if (NT_STATUS_IS_OK(r_u->status)) { - if (mapped_count == 0) { - r_u->status = NT_STATUS_NONE_MAPPED; - } else if (mapped_count != num_entries) { - r_u->status = STATUS_SOME_UNMAPPED; - } + sid_array2->sids = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count); + if (!sid_array2->sids) { + return NT_STATUS_NO_MEMORY; } - /* Convert the rids array to rids2. */ - for (i = 0; i < num_entries; i++) { - rids2[i].type = rids[i].type; - rids2[i].rid = rids[i].rid; - rids2[i].rid_idx = rids[i].rid_idx; - rids2[i].unknown = 0; + for (i=0; i<sid_array->count; i++) { + sid_array2->sids[i].sid_type = sid_array->sids[i].sid_type; + sid_array2->sids[i].rid = sid_array->sids[i].rid; + sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index; + sid_array2->sids[i].unknown = 0; } - init_reply_lookup_names2(r_u, ref, num_entries, rids2, mapped_count); - return r_u->status; + r->out.sids = sid_array2; + + return status; } /*************************************************************************** -lsa_reply_lookup_names3. + _lsa_LookupNames3 ***************************************************************************/ -NTSTATUS _lsa_lookup_names3(pipes_struct *p, LSA_Q_LOOKUP_NAMES3 *q_u, LSA_R_LOOKUP_NAMES3 *r_u) +NTSTATUS _lsa_LookupNames3(pipes_struct *p, + struct lsa_LookupNames3 *r) { + NTSTATUS status; struct lsa_info *handle; - UNISTR2 *names = q_u->uni_name; - uint32 num_entries = q_u->num_entries; - DOM_R_REF *ref = NULL; - LSA_TRANSLATED_SID3 *trans_sids = NULL; + struct lsa_String *names = r->in.names; + uint32 num_entries = r->in.num_names; + struct lsa_RefDomainList *domains = NULL; + struct lsa_TranslatedSid3 *trans_sids = NULL; uint32 mapped_count = 0; int flags = 0; + bool check_policy = true; + + switch (p->hdr_req.opnum) { + case NDR_LSA_LOOKUPNAMES4: + check_policy = false; + break; + case NDR_LSA_LOOKUPNAMES3: + default: + check_policy = true; + } if (num_entries > MAX_LOOKUP_SIDS) { num_entries = MAX_LOOKUP_SIDS; - DEBUG(5,("_lsa_lookup_names3: truncating name lookup list to %d\n", num_entries)); + DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries)); } - + /* Probably the lookup_level is some sort of bitmask. */ - if (q_u->lookup_level == 1) { + if (r->in.level == 1) { flags = LOOKUP_NAME_ALL; } - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); - if (ref == NULL) { + domains = TALLOC_ZERO_P(p->mem_ctx, struct lsa_RefDomainList); + if (!domains) { return NT_STATUS_NO_MEMORY; } + if (num_entries) { - trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_TRANSLATED_SID3, num_entries); + trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TranslatedSid3, + num_entries); if (!trans_sids) { return NT_STATUS_NO_MEMORY; } @@ -1249,59 +1146,52 @@ NTSTATUS _lsa_lookup_names3(pipes_struct *p, LSA_Q_LOOKUP_NAMES3 *q_u, LSA_R_LOO trans_sids = NULL; } - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) { - r_u->status = NT_STATUS_INVALID_HANDLE; - goto done; - } + if (check_policy) { - /* check if the user have enough rights */ - if (!(handle->access & POLICY_LOOKUP_NAMES)) { - r_u->status = NT_STATUS_ACCESS_DENIED; - goto done; + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) { + status = NT_STATUS_INVALID_HANDLE; + goto done; + } + + /* check if the user have enough rights */ + if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) { + status = NT_STATUS_ACCESS_DENIED; + goto done; + } } /* set up the LSA Lookup SIDs response */ become_root(); /* lookup_name can require root privs */ - r_u->status = lookup_lsa_sids(p->mem_ctx, ref, trans_sids, num_entries, - names, flags, &mapped_count); + status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries, + names, flags, &mapped_count); unbecome_root(); done: - if (NT_STATUS_IS_OK(r_u->status)) { + if (NT_STATUS_IS_OK(status)) { if (mapped_count == 0) { - r_u->status = NT_STATUS_NONE_MAPPED; + status = NT_STATUS_NONE_MAPPED; } else if (mapped_count != num_entries) { - r_u->status = STATUS_SOME_UNMAPPED; + status = STATUS_SOME_UNMAPPED; } } - init_reply_lookup_names3(r_u, ref, num_entries, trans_sids, mapped_count); - return r_u->status; + *r->out.count = mapped_count; + *r->out.domains = domains; + r->out.sids->sids = trans_sids; + r->out.sids->count = num_entries; + + return status; } /*************************************************************************** -lsa_reply_lookup_names4. + _lsa_LookupNames4 ***************************************************************************/ -NTSTATUS _lsa_lookup_names4(pipes_struct *p, LSA_Q_LOOKUP_NAMES4 *q_u, LSA_R_LOOKUP_NAMES4 *r_u) +NTSTATUS _lsa_LookupNames4(pipes_struct *p, + struct lsa_LookupNames4 *r) { - UNISTR2 *names = q_u->uni_name; - uint32 num_entries = q_u->num_entries; - DOM_R_REF *ref = NULL; - LSA_TRANSLATED_SID3 *trans_sids = NULL; - uint32 mapped_count = 0; - int flags = 0; - - if (num_entries > MAX_LOOKUP_SIDS) { - num_entries = MAX_LOOKUP_SIDS; - DEBUG(5,("_lsa_lookup_names4: truncating name lookup list to %d\n", num_entries)); - } - - /* Probably the lookup_level is some sort of bitmask. */ - if (q_u->lookup_level == 1) { - flags = LOOKUP_NAME_ALL; - } + struct lsa_LookupNames3 q; /* No policy handle on this call. Restrict to crypto connections. */ if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { @@ -1310,36 +1200,20 @@ NTSTATUS _lsa_lookup_names4(pipes_struct *p, LSA_Q_LOOKUP_NAMES4 *q_u, LSA_R_LOO return NT_STATUS_INVALID_PARAMETER; } - ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); - if (!ref) { - return NT_STATUS_NO_MEMORY; - } - - if (num_entries) { - trans_sids = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_TRANSLATED_SID3, num_entries); - if (!trans_sids) { - return NT_STATUS_NO_MEMORY; - } - } else { - trans_sids = NULL; - } - - /* set up the LSA Lookup SIDs response */ - become_root(); /* lookup_name can require root privs */ - r_u->status = lookup_lsa_sids(p->mem_ctx, ref, trans_sids, num_entries, - names, flags, &mapped_count); - unbecome_root(); + q.in.handle = NULL; + q.in.num_names = r->in.num_names; + q.in.names = r->in.names; + q.in.level = r->in.level; + q.in.unknown1 = r->in.unknown1; + q.in.unknown2 = r->in.unknown2; + q.in.sids = r->in.sids; + q.in.count = r->in.count; - if (NT_STATUS_IS_OK(r_u->status)) { - if (mapped_count == 0) { - r_u->status = NT_STATUS_NONE_MAPPED; - } else if (mapped_count != num_entries) { - r_u->status = STATUS_SOME_UNMAPPED; - } - } + q.out.domains = r->out.domains; + q.out.sids = r->out.sids; + q.out.count = r->out.count; - init_reply_lookup_names4(r_u, ref, num_entries, trans_sids, mapped_count); - return r_u->status; + return _lsa_LookupNames3(p, &q); } /*************************************************************************** @@ -1353,6 +1227,7 @@ NTSTATUS _lsa_Close(pipes_struct *p, struct lsa_Close *r) } close_policy_hnd(p, r->in.handle); + ZERO_STRUCTP(r->out.handle); return NT_STATUS_OK; } @@ -1424,17 +1299,17 @@ NTSTATUS _lsa_EnumPrivs(pipes_struct *p, if ( enum_context >= num_privs ) return NT_STATUS_NO_MORE_ENTRIES; - - DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", + + DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n", enum_context, num_privs)); - + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights I don't know if it's the right one. not documented. */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; if (num_privs) { @@ -1492,7 +1367,7 @@ NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p, /* * I don't know if it's the right one. not documented. */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string)); @@ -1519,21 +1394,22 @@ NTSTATUS _lsa_LookupPrivDisplayName(pipes_struct *p, } /*************************************************************************** -_lsa_enum_accounts. + _lsa_EnumAccounts ***************************************************************************/ -NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u) +NTSTATUS _lsa_EnumAccounts(pipes_struct *p, + struct lsa_EnumAccounts *r) { struct lsa_info *handle; DOM_SID *sid_list; int i, j, num_entries; - LSA_SID_ENUM *sids=&r_u->sids; - NTSTATUS ret; + NTSTATUS status; + struct lsa_SidPtr *sids = NULL; - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle)) return NT_STATUS_INVALID_HANDLE; - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; sid_list = NULL; @@ -1542,34 +1418,37 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU /* The only way we can currently find out all the SIDs that have been privileged is to scan all privileges */ - if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) { - return ret; + status = privilege_enumerate_accounts(&sid_list, &num_entries); + if (!NT_STATUS_IS_OK(status)) { + return status; } - if (q_u->enum_context >= num_entries) + if (*r->in.resume_handle >= num_entries) { return NT_STATUS_NO_MORE_ENTRIES; + } - if (num_entries-q_u->enum_context) { - sids->ptr_sid = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_entries-q_u->enum_context); - sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context); - - if (sids->ptr_sid==NULL || sids->sid==NULL) { + if (num_entries - *r->in.resume_handle) { + sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr, + num_entries - *r->in.resume_handle); + if (!sids) { SAFE_FREE(sid_list); return NT_STATUS_NO_MEMORY; } - for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) { - init_dom_sid2(&(*sids).sid[j], &sid_list[i]); - (*sids).ptr_sid[j] = 1; + for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) { + sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]); + if (!sids[j].sid) { + SAFE_FREE(sid_list); + return NT_STATUS_NO_MEMORY; + } } - } else { - sids->ptr_sid = NULL; - sids->sid = NULL; } talloc_free(sid_list); - init_lsa_r_enum_accounts(r_u, num_entries); + *r->out.resume_handle = num_entries; + r->out.sids->num_sids = num_entries; + r->out.sids->sids = sids; return NT_STATUS_OK; } @@ -1643,20 +1522,20 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p, * I don't know if it's the right one. not documented. * but guessed with rpcclient. */ - if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) + if (!(handle->access & LSA_POLICY_GET_PRIVATE_INFORMATION)) return NT_STATUS_ACCESS_DENIED; - /* check to see if the pipe_user is a Domain Admin since + /* check to see if the pipe_user is a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) return NT_STATUS_ACCESS_DENIED; - + if ( is_privileged_sid( r->in.sid ) ) return NT_STATUS_OBJECT_NAME_COLLISION; /* associate the user/group SID with the (unique) handle. */ - + if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL) return NT_STATUS_NO_MEMORY; @@ -1692,7 +1571,7 @@ NTSTATUS _lsa_OpenAccount(pipes_struct *p, * I don't know if it's the right one. not documented. * but guessed with rpcclient. */ - if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION)) + if (!(handle->access & LSA_POLICY_GET_PRIVATE_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* TODO: Fis the parsing routine before reenabling this check! */ @@ -1716,38 +1595,69 @@ NTSTATUS _lsa_OpenAccount(pipes_struct *p, } /*************************************************************************** + _lsa_EnumPrivsAccount For a given SID, enumerate all the privilege this account has. ***************************************************************************/ -NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u) +NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p, + struct lsa_EnumPrivsAccount *r) { + NTSTATUS status = NT_STATUS_OK; struct lsa_info *info=NULL; SE_PRIV mask; PRIVILEGE_SET privileges; + struct lsa_PrivilegeSet *priv_set = NULL; + struct lsa_LUIDAttribute *luid_attrs = NULL; + int i; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) ) + if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) ) return NT_STATUS_OBJECT_NAME_NOT_FOUND; privilege_set_init( &privileges ); if ( se_priv_to_privilege_set( &privileges, &mask ) ) { - DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n", + DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n", sid_string_dbg(&info->sid), privileges.count)); - r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0); + priv_set = TALLOC_ZERO_P(p->mem_ctx, struct lsa_PrivilegeSet); + if (!priv_set) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + luid_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, + struct lsa_LUIDAttribute, + privileges.count); + if (!luid_attrs) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + for (i=0; i<privileges.count; i++) { + luid_attrs[i].luid.low = privileges.set[i].luid.low; + luid_attrs[i].luid.high = privileges.set[i].luid.high; + luid_attrs[i].attribute = privileges.set[i].attr; + } + + priv_set->count = privileges.count; + priv_set->unknown = 0; + priv_set->set = luid_attrs; + + *r->out.privs = priv_set; + } else { + status = NT_STATUS_NO_SUCH_PRIVILEGE; } - else - r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE; + done: privilege_set_free( &privileges ); - return r_u->status; + return status; } /*************************************************************************** @@ -1772,7 +1682,7 @@ NTSTATUS _lsa_GetSystemAccessAccount(pipes_struct *p, 0x02 -> Access this computer from network 0x04 -> Log on as a batch job 0x10 -> Log on as a service - + they can be ORed together */ @@ -1795,9 +1705,9 @@ NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p, if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - /* check to see if the pipe_user is a Domain Admin since + /* check to see if the pipe_user is a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) return NT_STATUS_ACCESS_DENIED; @@ -1808,35 +1718,36 @@ NTSTATUS _lsa_SetSystemAccessAccount(pipes_struct *p, } /*************************************************************************** + _lsa_AddPrivilegesToAccount For a given SID, add some privileges. ***************************************************************************/ -NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u) +NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p, + struct lsa_AddPrivilegesToAccount *r) { struct lsa_info *info = NULL; SE_PRIV mask; - PRIVILEGE_SET *set = NULL; + struct lsa_PrivilegeSet *set = NULL; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - - /* check to see if the pipe_user is root or a Domain Admin since + + /* check to see if the pipe_user is root or a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - - if ( p->pipe_user.ut.uid != sec_initial_uid() + + if ( p->pipe_user.ut.uid != sec_initial_uid() && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) { return NT_STATUS_ACCESS_DENIED; } - set = &q_u->set; - + set = r->in.privs; if ( !privilege_set_to_se_priv( &mask, set ) ) return NT_STATUS_NO_SUCH_PRIVILEGE; if ( !grant_privilege( &info->sid, &mask ) ) { - DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n", + DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege(%s) failed!\n", sid_string_dbg(&info->sid) )); DEBUG(3,("Privilege mask:\n")); dump_se_priv( DBGC_ALL, 3, &mask ); @@ -1847,35 +1758,37 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u } /*************************************************************************** + _lsa_RemovePrivilegesFromAccount For a given SID, remove some privileges. ***************************************************************************/ -NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u) +NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p, + struct lsa_RemovePrivilegesFromAccount *r) { struct lsa_info *info = NULL; SE_PRIV mask; - PRIVILEGE_SET *set = NULL; + struct lsa_PrivilegeSet *set = NULL; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - /* check to see if the pipe_user is root or a Domain Admin since + /* check to see if the pipe_user is root or a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( p->pipe_user.ut.uid != sec_initial_uid() - && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) + && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) { return NT_STATUS_ACCESS_DENIED; } - set = &q_u->set; + set = r->in.privs; if ( !privilege_set_to_se_priv( &mask, set ) ) return NT_STATUS_NO_SUCH_PRIVILEGE; if ( !revoke_privilege( &info->sid, &mask ) ) { - DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n", + DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n", sid_string_dbg(&info->sid) )); DEBUG(3,("Privilege mask:\n")); dump_se_priv( DBGC_ALL, 3, &mask ); @@ -1902,7 +1815,7 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; @@ -1959,7 +1872,7 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, switch (q_u->info_class) { case 0x0c: /* check if the user have enough rights */ - if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION)) + if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) return NT_STATUS_ACCESS_DENIED; /* Request PolicyPrimaryDomainInformation. */ @@ -1985,7 +1898,7 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, default: return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name, + init_dns_dom_info(&r_u->info.dns_dom_info, nb_name, dns_name, forest_name,&guid,sid); break; default: @@ -2004,54 +1917,46 @@ NTSTATUS _lsa_QuerySecurity(pipes_struct *p, #endif /* AD DC work in ongoing in Samba 4 */ /*************************************************************************** + _lsa_AddAccountRights ***************************************************************************/ -NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u) +NTSTATUS _lsa_AddAccountRights(pipes_struct *p, + struct lsa_AddAccountRights *r) { struct lsa_info *info = NULL; int i = 0; DOM_SID sid; - fstring privname; - UNISTR4_ARRAY *uni_privnames = q_u->rights; - /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - - /* check to see if the pipe_user is a Domain Admin since + + /* check to see if the pipe_user is a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( p->pipe_user.ut.uid != sec_initial_uid() - && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) + && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) { return NT_STATUS_ACCESS_DENIED; } /* according to an NT4 PDC, you can add privileges to SIDs even without call_lsa_create_account() first. And you can use any arbitrary SID. */ - - sid_copy( &sid, &q_u->sid.sid ); - - /* just a little sanity check */ - - if ( q_u->count != uni_privnames->count ) { - DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n")); - return NT_STATUS_INVALID_HANDLE; - } - - for ( i=0; i<q_u->count; i++ ) { - UNISTR4 *uni4_str = &uni_privnames->strings[i]; + + sid_copy( &sid, r->in.sid ); + + for ( i=0; i < r->in.rights->count; i++ ) { + + const char *privname = r->in.rights->names[i].string; /* only try to add non-null strings */ - if ( !uni4_str->string ) + if ( !privname ) continue; - rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE ); - if ( !grant_privilege_by_name( &sid, privname ) ) { - DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname )); + DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n", + privname )); return NT_STATUS_NO_SUCH_PRIVILEGE; } } @@ -2060,58 +1965,51 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R } /*************************************************************************** + _lsa_RemoveAccountRights ***************************************************************************/ -NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u) +NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p, + struct lsa_RemoveAccountRights *r) { struct lsa_info *info = NULL; int i = 0; DOM_SID sid; - fstring privname; - UNISTR4_ARRAY *uni_privnames = q_u->rights; - + const char *privname = NULL; /* find the connection policy handle. */ - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - - /* check to see if the pipe_user is a Domain Admin since + + /* check to see if the pipe_user is a Domain Admin since account_pol.tdb was already opened as root, this is all we have */ - + if ( p->pipe_user.ut.uid != sec_initial_uid() && !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) ) { return NT_STATUS_ACCESS_DENIED; } - sid_copy( &sid, &q_u->sid.sid ); + sid_copy( &sid, r->in.sid ); - if ( q_u->removeall ) { - if ( !revoke_all_privileges( &sid ) ) + if ( r->in.remove_all ) { + if ( !revoke_all_privileges( &sid ) ) return NT_STATUS_ACCESS_DENIED; - + return NT_STATUS_OK; } - - /* just a little sanity check */ - - if ( q_u->count != uni_privnames->count ) { - DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n")); - return NT_STATUS_INVALID_HANDLE; - } - - for ( i=0; i<q_u->count; i++ ) { - UNISTR4 *uni4_str = &uni_privnames->strings[i]; + + for ( i=0; i < r->in.rights->count; i++ ) { + + privname = r->in.rights->names[i].string; /* only try to add non-null strings */ - if ( !uni4_str->string ) + if ( !privname ) continue; - rpcstr_pull( privname, uni4_str->string->buffer, sizeof(privname), -1, STR_TERMINATE ); - if ( !revoke_privilege_by_name( &sid, privname ) ) { - DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname )); + DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n", + privname )); return NT_STATUS_NO_SUCH_PRIVILEGE; } } @@ -2119,28 +2017,70 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, return NT_STATUS_OK; } +/******************************************************************* +********************************************************************/ + +static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx, + struct lsa_RightSet *r, + PRIVILEGE_SET *privileges) +{ + uint32 i; + const char *privname; + const char **privname_array = NULL; + int num_priv = 0; + + for (i=0; i<privileges->count; i++) { + + privname = luid_to_privilege_name(&privileges->set[i].luid); + if (privname) { + if (!add_string_to_array(mem_ctx, privname, + &privname_array, &num_priv)) { + return NT_STATUS_NO_MEMORY; + } + } + } + + if (num_priv) { + + r->names = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_StringLarge, + num_priv); + if (!r->names) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<num_priv; i++) { + init_lsa_StringLarge(&r->names[i], privname_array[i]); + } + + r->count = num_priv; + } + + return NT_STATUS_OK; +} /*************************************************************************** + _lsa_EnumAccountRights ***************************************************************************/ -NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u) +NTSTATUS _lsa_EnumAccountRights(pipes_struct *p, + struct lsa_EnumAccountRights *r) { + NTSTATUS status; struct lsa_info *info = NULL; DOM_SID sid; PRIVILEGE_SET privileges; SE_PRIV mask; - /* find the connection policy handle. */ - - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - + /* according to an NT4 PDC, you can add privileges to SIDs even without call_lsa_create_account() first. And you can use any arbitrary SID. */ - - sid_copy( &sid, &q_u->sid.sid ); - + + sid_copy( &sid, r->in.sid ); + if ( !get_privileges_for_sids( &mask, &sid, 1 ) ) return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -2148,37 +2088,38 @@ NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA if ( se_priv_to_privilege_set( &privileges, &mask ) ) { - DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n", + DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n", sid_string_dbg(&sid), privileges.count)); - r_u->status = init_r_enum_acct_rights( r_u, &privileges ); + status = init_lsa_right_set(p->mem_ctx, r->out.rights, &privileges); + } else { + status = NT_STATUS_NO_SUCH_PRIVILEGE; } - else - r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE; privilege_set_free( &privileges ); - return r_u->status; + return status; } - /*************************************************************************** + _lsa_LookupPrivValue ***************************************************************************/ -NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, LSA_R_LOOKUP_PRIV_VALUE *r_u) +NTSTATUS _lsa_LookupPrivValue(pipes_struct *p, + struct lsa_LookupPrivValue *r) { struct lsa_info *info = NULL; - fstring name; + const char *name = NULL; LUID_ATTR priv_luid; SE_PRIV mask; - + /* find the connection policy handle. */ - - if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info)) + + if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - - unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name)); - + + name = r->in.name->string; + DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name)); if ( !se_priv_from_name( name, &mask ) ) @@ -2186,19 +2127,17 @@ NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, L priv_luid = get_privilege_luid( &mask ); - r_u->luid.low = priv_luid.luid.low; - r_u->luid.high = priv_luid.luid.high; - + r->out.luid->low = priv_luid.luid.low; + r->out.luid->high = priv_luid.luid.high; return NT_STATUS_OK; } - /* * From here on the server routines are just dummy ones to make smbd link with * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are * pulling the server stubs across one by one. - */ + */ NTSTATUS _lsa_Delete(pipes_struct *p, struct lsa_Delete *r) { @@ -2230,42 +2169,6 @@ NTSTATUS _lsa_ClearAuditLog(pipes_struct *p, struct lsa_ClearAuditLog *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_EnumAccounts(pipes_struct *p, struct lsa_EnumAccounts *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_LookupNames(pipes_struct *p, struct lsa_LookupNames *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_LookupSids(pipes_struct *p, struct lsa_LookupSids *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_EnumPrivsAccount(pipes_struct *p, struct lsa_EnumPrivsAccount *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_AddPrivilegesToAccount(pipes_struct *p, struct lsa_AddPrivilegesToAccount *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_RemovePrivilegesFromAccount(pipes_struct *p, struct lsa_RemovePrivilegesFromAccount *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_GetQuotasForAccount(pipes_struct *p, struct lsa_GetQuotasForAccount *r) { p->rng_fault_state = True; @@ -2296,12 +2199,6 @@ NTSTATUS _lsa_QuerySecret(pipes_struct *p, struct lsa_QuerySecret *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupPrivValue(pipes_struct *p, struct lsa_LookupPrivValue *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_LookupPrivName(pipes_struct *p, struct lsa_LookupPrivName *r) { p->rng_fault_state = True; @@ -2314,24 +2211,6 @@ NTSTATUS _lsa_EnumAccountsWithUserRight(pipes_struct *p, struct lsa_EnumAccounts return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_EnumAccountRights(pipes_struct *p, struct lsa_EnumAccountRights *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_AddAccountRights(pipes_struct *p, struct lsa_AddAccountRights *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_RemoveAccountRights(pipes_struct *p, struct lsa_RemoveAccountRights *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_QueryTrustedDomainInfoBySid(pipes_struct *p, struct lsa_QueryTrustedDomainInfoBySid *r) { p->rng_fault_state = True; @@ -2428,18 +2307,6 @@ NTSTATUS _lsa_TestCall(pipes_struct *p, struct lsa_TestCall *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupSids2(pipes_struct *p, struct lsa_LookupSids2 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_LookupNames2(pipes_struct *p, struct lsa_LookupNames2 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_CreateTrustedDomainEx2(pipes_struct *p, struct lsa_CreateTrustedDomainEx2 *r) { p->rng_fault_state = True; @@ -2494,12 +2361,6 @@ NTSTATUS _lsa_CREDRPROFILELOADED(pipes_struct *p, struct lsa_CREDRPROFILELOADED return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupNames3(pipes_struct *p, struct lsa_LookupNames3 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTYPES *r) { p->rng_fault_state = True; @@ -2542,18 +2403,6 @@ NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r) return NT_STATUS_NOT_IMPLEMENTED; } -NTSTATUS _lsa_LookupSids3(pipes_struct *p, struct lsa_LookupSids3 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - -NTSTATUS _lsa_LookupNames4(pipes_struct *p, struct lsa_LookupNames4 *r) -{ - p->rng_fault_state = True; - return NT_STATUS_NOT_IMPLEMENTED; -} - NTSTATUS _lsa_LSAROPENPOLICYSCE(pipes_struct *p, struct lsa_LSAROPENPOLICYSCE *r) { p->rng_fault_state = True; diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c deleted file mode 100644 index 4f0a0142e5..0000000000 --- a/source3/rpc_server/srv_netlog.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1997, - * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, - * Copyright (C) Paul Ashton 1997, - * Copyright (C) Jeremy Allison 1998-2001, - * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* This is the interface to the netlogon pipe. */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -/******************************************************************* - ********************************************************************/ - -static bool proxy_netr_call(pipes_struct *p, uint8 opnum) -{ - struct api_struct *fns; - int n_fns; - - netlogon_get_pipe_fns(&fns, &n_fns); - - if (opnum >= n_fns) { - return false; - } - - if (fns[opnum].opnum != opnum) { - smb_panic("NETLOGON function table not sorted"); - } - - return fns[opnum].fn(p); -} - -/************************************************************************* - api_net_req_chal: - *************************************************************************/ - -static bool api_net_req_chal(pipes_struct *p) -{ - NET_Q_REQ_CHAL q_u; - NET_R_REQ_CHAL r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the challenge... */ - if(!net_io_q_req_chal("", &q_u, data, 0)) { - DEBUG(0,("api_net_req_chal: Failed to unmarshall NET_Q_REQ_CHAL.\n")); - return False; - } - - r_u.status = _net_req_chal(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_req_chal("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_req_chal: Failed to marshall NET_R_REQ_CHAL.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_auth: - *************************************************************************/ - -static bool api_net_auth(pipes_struct *p) -{ - NET_Q_AUTH q_u; - NET_R_AUTH r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the challenge... */ - if(!net_io_q_auth("", &q_u, data, 0)) { - DEBUG(0,("api_net_auth: Failed to unmarshall NET_Q_AUTH.\n")); - return False; - } - - r_u.status = _net_auth(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_auth("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_auth: Failed to marshall NET_R_AUTH.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_auth_2: - *************************************************************************/ - -static bool api_net_auth_2(pipes_struct *p) -{ - NET_Q_AUTH_2 q_u; - NET_R_AUTH_2 r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the challenge... */ - if(!net_io_q_auth_2("", &q_u, data, 0)) { - DEBUG(0,("api_net_auth_2: Failed to unmarshall NET_Q_AUTH_2.\n")); - return False; - } - - r_u.status = _net_auth_2(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_auth_2("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_auth_2: Failed to marshall NET_R_AUTH_2.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_srv_pwset: - *************************************************************************/ - -static bool api_net_srv_pwset(pipes_struct *p) -{ - NET_Q_SRV_PWSET q_u; - NET_R_SRV_PWSET r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the challenge and encrypted password ... */ - if(!net_io_q_srv_pwset("", &q_u, data, 0)) { - DEBUG(0,("api_net_srv_pwset: Failed to unmarshall NET_Q_SRV_PWSET.\n")); - return False; - } - - r_u.status = _net_srv_pwset(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_srv_pwset("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_srv_pwset: Failed to marshall NET_R_SRV_PWSET.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_sam_logoff: - *************************************************************************/ - -static bool api_net_sam_logoff(pipes_struct *p) -{ - NET_Q_SAM_LOGOFF q_u; - NET_R_SAM_LOGOFF r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!net_io_q_sam_logoff("", &q_u, data, 0)) { - DEBUG(0,("api_net_sam_logoff: Failed to unmarshall NET_Q_SAM_LOGOFF.\n")); - return False; - } - - r_u.status = _net_sam_logoff(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_sam_logoff("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_sam_logoff: Failed to marshall NET_R_SAM_LOGOFF.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_sam_logon: - *************************************************************************/ - -static bool api_net_sam_logon(pipes_struct *p) -{ - NET_Q_SAM_LOGON q_u; - NET_R_SAM_LOGON r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!net_io_q_sam_logon("", &q_u, data, 0)) { - DEBUG(0, ("api_net_sam_logon: Failed to unmarshall NET_Q_SAM_LOGON.\n")); - return False; - } - - r_u.status = _net_sam_logon(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_sam_logon("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_sam_logon: Failed to marshall NET_R_SAM_LOGON.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_trust_dom_list: - *************************************************************************/ - -static bool api_net_trust_dom_list(pipes_struct *p) -{ - return proxy_netr_call(p, NDR_NETR_NETRENUMERATETRUSTEDDOMAINS); -} - -/************************************************************************* - api_net_logon_ctrl2: - *************************************************************************/ - -static bool api_net_logon_ctrl2(pipes_struct *p) -{ - NET_Q_LOGON_CTRL2 q_u; - NET_R_LOGON_CTRL2 r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - - /* grab the lsa netlogon ctrl2 query... */ - if(!net_io_q_logon_ctrl2("", &q_u, data, 0)) { - DEBUG(0,("api_net_logon_ctrl2: Failed to unmarshall NET_Q_LOGON_CTRL2.\n")); - return False; - } - - r_u.status = _net_logon_ctrl2(p, &q_u, &r_u); - - if(!net_io_r_logon_ctrl2("", &r_u, rdata, 0)) { - DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL2.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_logon_ctrl: - *************************************************************************/ - -static bool api_net_logon_ctrl(pipes_struct *p) -{ - NET_Q_LOGON_CTRL q_u; - NET_R_LOGON_CTRL r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the lsa netlogon ctrl query... */ - if(!net_io_q_logon_ctrl("", &q_u, data, 0)) { - DEBUG(0,("api_net_logon_ctrl: Failed to unmarshall NET_Q_LOGON_CTRL.\n")); - return False; - } - - r_u.status = _net_logon_ctrl(p, &q_u, &r_u); - - if(!net_io_r_logon_ctrl("", &r_u, rdata, 0)) { - DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL.\n")); - return False; - } - - return True; -} - -/************************************************************************* - api_net_sam_logon_ex: - *************************************************************************/ - -static bool api_net_sam_logon_ex(pipes_struct *p) -{ - NET_Q_SAM_LOGON_EX q_u; - NET_R_SAM_LOGON_EX r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!net_io_q_sam_logon_ex("", &q_u, data, 0)) { - DEBUG(0, ("api_net_sam_logon_ex: Failed to unmarshall NET_Q_SAM_LOGON_EX.\n")); - return False; - } - - r_u.status = _net_sam_logon_ex(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!net_io_r_sam_logon_ex("", &r_u, rdata, 0)) { - DEBUG(0,("api_net_sam_logon_ex: Failed to marshall NET_R_SAM_LOGON_EX.\n")); - return False; - } - - return True; -} - -/******************************************************************* - array of \PIPE\NETLOGON operations - ********************************************************************/ -static struct api_struct api_net_cmds [] = - { - { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal }, - { "NET_AUTH" , NET_AUTH , api_net_auth }, - { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 }, - { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset }, - { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon }, - { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff }, - { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 }, - { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list }, - { "NET_LOGON_CTRL" , NET_LOGON_CTRL , api_net_logon_ctrl }, - { "NET_SAMLOGON_EX" , NET_SAMLOGON_EX , api_net_sam_logon_ex }, - }; - -void netlog_get_pipe_fns( struct api_struct **fns, int *n_fns ) -{ - *fns = api_net_cmds; - *n_fns = sizeof(api_net_cmds) / sizeof(struct api_struct); -} - -NTSTATUS rpc_net_init(void) -{ - return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "NETLOGON", "lsass", api_net_cmds, - sizeof(api_net_cmds) / sizeof(struct api_struct)); -} diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 528a33915a..5b26f55845 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -1,4 +1,4 @@ -/* +/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, @@ -6,17 +6,18 @@ * Copyright (C) Paul Ashton 1997. * Copyright (C) Jeremy Allison 1998-2001. * Copyright (C) Andrew Bartlett 2001. + * Copyright (C) Guenther Deschner 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/>. */ @@ -34,30 +35,83 @@ extern userdom_struct current_user_info; init_net_r_req_chal: *************************************************************************/ -static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c, - DOM_CHAL *srv_chal, NTSTATUS status) +static void init_net_r_req_chal(struct netr_Credential *r, + struct netr_Credential *srv_chal) { DEBUG(6,("init_net_r_req_chal: %d\n", __LINE__)); - memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data)); - r_c->status = status; + + memcpy(r->data, srv_chal->data, sizeof(r->data)); +} + +/******************************************************************* + Inits a netr_NETLOGON_INFO_1 structure. +********************************************************************/ + +static void init_netlogon_info1(struct netr_NETLOGON_INFO_1 *r, + uint32_t flags, + uint32_t pdc_connection_status) +{ + r->flags = flags; + r->pdc_connection_status = pdc_connection_status; +} + +/******************************************************************* + Inits a netr_NETLOGON_INFO_2 structure. +********************************************************************/ + +static void init_netlogon_info2(struct netr_NETLOGON_INFO_2 *r, + uint32_t flags, + uint32_t pdc_connection_status, + const char *trusted_dc_name, + uint32_t tc_connection_status) +{ + r->flags = flags; + r->pdc_connection_status = pdc_connection_status; + r->trusted_dc_name = trusted_dc_name; + r->tc_connection_status = tc_connection_status; +} + +/******************************************************************* + Inits a netr_NETLOGON_INFO_3 structure. +********************************************************************/ + +static void init_netlogon_info3(struct netr_NETLOGON_INFO_3 *r, + uint32_t flags, + uint32_t logon_attempts) +{ + r->flags = flags; + r->logon_attempts = logon_attempts; } /************************************************************************* - net_reply_logon_ctrl: + _netr_LogonControl *************************************************************************/ -NTSTATUS _net_logon_ctrl(pipes_struct *p, NET_Q_LOGON_CTRL *q_u, - NET_R_LOGON_CTRL *r_u) +WERROR _netr_LogonControl(pipes_struct *p, + struct netr_LogonControl *r) { - uint32 flags = 0x0; - uint32 pdc_connection_status = 0x00; /* Maybe a win32 error code? */ - + struct netr_NETLOGON_INFO_1 *info1; + uint32_t flags = 0x0; + uint32_t pdc_connection_status = W_ERROR_V(WERR_OK); + /* Setup the Logon Control response */ - init_net_r_logon_ctrl(r_u, q_u->query_level, flags, - pdc_connection_status); + switch (r->in.level) { + case 1: + info1 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_1); + if (!info1) { + return WERR_NOMEM; + } + init_netlogon_info1(info1, + flags, + pdc_connection_status); + r->out.info->info1 = info1; + break; + default: + return WERR_UNKNOWN_LEVEL; + } - return r_u->status; + return WERR_OK; } /**************************************************************************** @@ -72,76 +126,109 @@ static void send_sync_message(void) } /************************************************************************* - net_reply_logon_ctrl2: + _netr_LogonControl2 *************************************************************************/ -NTSTATUS _net_logon_ctrl2(pipes_struct *p, NET_Q_LOGON_CTRL2 *q_u, NET_R_LOGON_CTRL2 *r_u) +WERROR _netr_LogonControl2(pipes_struct *p, + struct netr_LogonControl2 *r) { uint32 flags = 0x0; uint32 pdc_connection_status = 0x0; uint32 logon_attempts = 0x0; uint32 tc_status; - fstring servername, domain, dc_name, dc_name2; + fstring dc_name, dc_name2; struct sockaddr_storage dc_ss; + const char *domain = NULL; + struct netr_NETLOGON_INFO_1 *info1; + struct netr_NETLOGON_INFO_2 *info2; + struct netr_NETLOGON_INFO_3 *info3; - /* this should be \\global_myname() */ - unistr2_to_ascii(servername, &q_u->uni_server_name, sizeof(servername)); - - r_u->status = NT_STATUS_OK; - tc_status = W_ERROR_V(WERR_NO_SUCH_DOMAIN); fstrcpy( dc_name, "" ); - - switch ( q_u->function_code ) { + + switch (r->in.function_code) { case NETLOGON_CONTROL_TC_QUERY: - unistr2_to_ascii(domain, &q_u->info.info6.domain, sizeof(domain)); - + domain = r->in.data->domain; + if ( !is_trusted_domain( domain ) ) break; - + if ( !get_dc_name( domain, NULL, dc_name2, &dc_ss ) ) { tc_status = W_ERROR_V(WERR_NO_LOGON_SERVERS); break; } fstr_sprintf( dc_name, "\\\\%s", dc_name2 ); - + tc_status = W_ERROR_V(WERR_OK); - + break; - + case NETLOGON_CONTROL_REDISCOVER: - unistr2_to_ascii(domain, &q_u->info.info6.domain, sizeof(domain)); - + domain = r->in.data->domain; + if ( !is_trusted_domain( domain ) ) break; - + if ( !get_dc_name( domain, NULL, dc_name2, &dc_ss ) ) { tc_status = W_ERROR_V(WERR_NO_LOGON_SERVERS); break; } fstr_sprintf( dc_name, "\\\\%s", dc_name2 ); - + tc_status = W_ERROR_V(WERR_OK); - + break; - + default: /* no idea what this should be */ - DEBUG(0,("_net_logon_ctrl2: unimplemented function level [%d]\n", - q_u->function_code)); + DEBUG(0,("_netr_LogonControl2: unimplemented function level [%d]\n", + r->in.function_code)); + return WERR_UNKNOWN_LEVEL; } - + /* prepare the response */ - - init_net_r_logon_ctrl2( r_u, q_u->query_level, flags, - pdc_connection_status, logon_attempts, tc_status, dc_name ); - if (lp_server_role() == ROLE_DOMAIN_BDC) + switch (r->in.level) { + case 1: + info1 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_1); + W_ERROR_HAVE_NO_MEMORY(info1); + + init_netlogon_info1(info1, + flags, + pdc_connection_status); + r->out.query->info1 = info1; + break; + case 2: + info2 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_2); + W_ERROR_HAVE_NO_MEMORY(info2); + + init_netlogon_info2(info2, + flags, + pdc_connection_status, + dc_name, + tc_status); + r->out.query->info2 = info2; + break; + case 3: + info3 = TALLOC_ZERO_P(p->mem_ctx, struct netr_NETLOGON_INFO_3); + W_ERROR_HAVE_NO_MEMORY(info3); + + init_netlogon_info3(info3, + flags, + logon_attempts); + r->out.query->info3 = info3; + break; + default: + return WERR_UNKNOWN_LEVEL; + } + + if (lp_server_role() == ROLE_DOMAIN_BDC) { send_sync_message(); + } - return r_u->status; + return WERR_OK; } /************************************************************************* @@ -169,38 +256,23 @@ WERROR _netr_NetrEnumerateTrustedDomains(pipes_struct *p, return WERR_OK; } -/*********************************************************************************** - init_net_r_srv_pwset: - ***********************************************************************************/ - -static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s, - DOM_CRED *srv_cred, NTSTATUS status) -{ - DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__)); - - memcpy(&r_s->srv_cred, srv_cred, sizeof(r_s->srv_cred)); - r_s->status = status; - - DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__)); -} - /****************************************************************** gets a machine password entry. checks access rights of the host. ******************************************************************/ -static NTSTATUS get_md4pw(char *md4pw, char *mach_acct, uint16 sec_chan_type) +static NTSTATUS get_md4pw(char *md4pw, const char *mach_acct, uint16 sec_chan_type) { struct samu *sampass = NULL; const uint8 *pass; bool ret; uint32 acct_ctrl; - + #if 0 char addr[INET6_ADDRSTRLEN]; /* * Currently this code is redundent as we already have a filter - * by hostname list. What this code really needs to do is to + * by hostname list. What this code really needs to do is to * get a hosts allowed/hosts denied list from the SAM database * on a per user basis, and make the access decision there. * I will leave this code here for now as a reminder to implement @@ -223,7 +295,7 @@ static NTSTATUS get_md4pw(char *md4pw, char *mach_acct, uint16 sec_chan_type) become_root(); ret = pdb_getsampwnam(sampass, mach_acct); unbecome_root(); - + if (!ret) { DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct)); TALLOC_FREE(sampass); @@ -239,7 +311,7 @@ static NTSTATUS get_md4pw(char *md4pw, char *mach_acct, uint16 sec_chan_type) if (!(acct_ctrl & ACB_SVRTRUST) && !(acct_ctrl & ACB_WSTRUST) && - !(acct_ctrl & ACB_DOMTRUST)) + !(acct_ctrl & ACB_DOMTRUST)) { DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct)); TALLOC_FREE(sampass); @@ -285,17 +357,18 @@ static NTSTATUS get_md4pw(char *md4pw, char *mach_acct, uint16 sec_chan_type) dump_data(5, (uint8 *)md4pw, 16); TALLOC_FREE(sampass); - + return NT_STATUS_OK; - + } /************************************************************************* - _net_req_chal + _netr_ServerReqChallenge *************************************************************************/ -NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u) +NTSTATUS _netr_ServerReqChallenge(pipes_struct *p, + struct netr_ServerReqChallenge *r) { if (!p->dc) { p->dc = TALLOC_ZERO_P(p->pipe_state_mem_ctx, struct dcinfo); @@ -303,65 +376,53 @@ NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u return NT_STATUS_NO_MEMORY; } } else { - DEBUG(10,("_net_req_chal: new challenge requested. Clearing old state.\n")); + DEBUG(10,("_netr_ServerReqChallenge: new challenge requested. Clearing old state.\n")); ZERO_STRUCTP(p->dc); } - rpcstr_pull(p->dc->remote_machine, - q_u->uni_logon_clnt.buffer, - sizeof(fstring),q_u->uni_logon_clnt.uni_str_len*2,0); + fstrcpy(p->dc->remote_machine, r->in.computer_name); /* Save the client challenge to the server. */ - memcpy(p->dc->clnt_chal.data, q_u->clnt_chal.data, sizeof(q_u->clnt_chal.data)); + memcpy(p->dc->clnt_chal.data, r->in.credentials->data, + sizeof(r->in.credentials->data)); /* Create a server challenge for the client */ /* Set this to a random value. */ generate_random_buffer(p->dc->srv_chal.data, 8); - + /* set up the LSA REQUEST CHALLENGE response */ - init_net_r_req_chal(r_u, &p->dc->srv_chal, NT_STATUS_OK); - + init_net_r_req_chal(r->out.return_credentials, &p->dc->srv_chal); + p->dc->challenge_sent = True; return NT_STATUS_OK; } /************************************************************************* - init_net_r_auth: - *************************************************************************/ - -static void init_net_r_auth(NET_R_AUTH *r_a, DOM_CHAL *resp_cred, NTSTATUS status) -{ - memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); - r_a->status = status; -} - -/************************************************************************* - _net_auth. Create the initial credentials. + _netr_ServerAuthenticate + Create the initial credentials. *************************************************************************/ -NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u) +NTSTATUS _netr_ServerAuthenticate(pipes_struct *p, + struct netr_ServerAuthenticate *r) { NTSTATUS status; - fstring mach_acct; - fstring remote_machine; - DOM_CHAL srv_chal_out; + struct netr_Credential srv_chal_out; if (!p->dc || !p->dc->challenge_sent) { return NT_STATUS_ACCESS_DENIED; } - rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring), - q_u->clnt_id.uni_acct_name.uni_str_len*2,0); - rpcstr_pull(remote_machine, q_u->clnt_id.uni_comp_name.buffer,sizeof(fstring), - q_u->clnt_id.uni_comp_name.uni_str_len*2,0); - - status = get_md4pw((char *)p->dc->mach_pw, mach_acct, q_u->clnt_id.sec_chan); + status = get_md4pw((char *)p->dc->mach_pw, + r->in.account_name, + r->in.secure_channel_type); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("_net_auth: creds_server_check failed. Failed to " + DEBUG(0,("_netr_ServerAuthenticate: get_md4pw failed. Failed to " "get password for machine account %s " "from client %s: %s\n", - mach_acct, remote_machine, nt_errstr(status) )); + r->in.account_name, + r->in.computer_name, + nt_errstr(status) )); /* always return NT_STATUS_ACCESS_DENIED */ return NT_STATUS_ACCESS_DENIED; } @@ -372,110 +433,101 @@ NTSTATUS _net_auth(pipes_struct *p, NET_Q_AUTH *q_u, NET_R_AUTH *r_u) &p->dc->clnt_chal, /* Stored client chal. */ &p->dc->srv_chal, /* Stored server chal. */ p->dc->mach_pw, - &srv_chal_out); + &srv_chal_out); /* Check client credentials are valid. */ - if (!creds_server_check(p->dc, &q_u->clnt_chal)) { - DEBUG(0,("_net_auth: creds_server_check failed. Rejecting auth " + if (!netlogon_creds_server_check(p->dc, r->in.credentials)) { + DEBUG(0,("_netr_ServerAuthenticate: netlogon_creds_server_check failed. Rejecting auth " "request from client %s machine account %s\n", - remote_machine, mach_acct )); + r->in.computer_name, + r->in.account_name)); return NT_STATUS_ACCESS_DENIED; } - fstrcpy(p->dc->mach_acct, mach_acct); - fstrcpy(p->dc->remote_machine, remote_machine); + fstrcpy(p->dc->mach_acct, r->in.account_name); + fstrcpy(p->dc->remote_machine, r->in.computer_name); p->dc->authenticated = True; /* set up the LSA AUTH response */ /* Return the server credentials. */ - init_net_r_auth(r_u, &srv_chal_out, NT_STATUS_OK); - return r_u->status; -} - -/************************************************************************* - init_net_r_auth_2: - *************************************************************************/ + memcpy(r->out.return_credentials->data, &srv_chal_out.data, + sizeof(r->out.return_credentials->data)); -static void init_net_r_auth_2(NET_R_AUTH_2 *r_a, - DOM_CHAL *resp_cred, NEG_FLAGS *flgs, NTSTATUS status) -{ - memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data)); - memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs)); - r_a->status = status; + return NT_STATUS_OK; } /************************************************************************* - _net_auth_2 + _netr_ServerAuthenticate2 *************************************************************************/ -NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u) +NTSTATUS _netr_ServerAuthenticate2(pipes_struct *p, + struct netr_ServerAuthenticate2 *r) { NTSTATUS status; - NEG_FLAGS srv_flgs; - fstring mach_acct; - fstring remote_machine; - DOM_CHAL srv_chal_out; - - rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring), - q_u->clnt_id.uni_acct_name.uni_str_len*2,0); + uint32_t srv_flgs; + struct netr_Credential srv_chal_out; - /* We use this as the key to store the creds. */ - rpcstr_pull(remote_machine, q_u->clnt_id.uni_comp_name.buffer,sizeof(fstring), - q_u->clnt_id.uni_comp_name.uni_str_len*2,0); + /* We use this as the key to store the creds: */ + /* r->in.computer_name */ if (!p->dc || !p->dc->challenge_sent) { - DEBUG(0,("_net_auth2: no challenge sent to client %s\n", - remote_machine )); + DEBUG(0,("_netr_ServerAuthenticate2: no challenge sent to client %s\n", + r->in.computer_name)); return NT_STATUS_ACCESS_DENIED; } - if ( (lp_server_schannel() == True) && - ((q_u->clnt_flgs.neg_flags & NETLOGON_NEG_SCHANNEL) == 0) ) { + if ( (lp_server_schannel() == true) && + ((*r->in.negotiate_flags & NETLOGON_NEG_SCHANNEL) == 0) ) { /* schannel must be used, but client did not offer it. */ - DEBUG(0,("_net_auth2: schannel required but client failed " + DEBUG(0,("_netr_ServerAuthenticate2: schannel required but client failed " "to offer it. Client was %s\n", - mach_acct )); + r->in.account_name)); return NT_STATUS_ACCESS_DENIED; } - status = get_md4pw((char *)p->dc->mach_pw, mach_acct, q_u->clnt_id.sec_chan); + status = get_md4pw((char *)p->dc->mach_pw, + r->in.account_name, + r->in.secure_channel_type); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("_net_auth2: failed to get machine password for " + DEBUG(0,("_netr_ServerAuthenticate2: failed to get machine password for " "account %s: %s\n", - mach_acct, nt_errstr(status) )); + r->in.account_name, nt_errstr(status) )); /* always return NT_STATUS_ACCESS_DENIED */ return NT_STATUS_ACCESS_DENIED; } /* From the client / server challenges and md4 password, generate sess key */ - creds_server_init(q_u->clnt_flgs.neg_flags, + creds_server_init(*r->in.negotiate_flags, p->dc, &p->dc->clnt_chal, /* Stored client chal. */ &p->dc->srv_chal, /* Stored server chal. */ p->dc->mach_pw, - &srv_chal_out); + &srv_chal_out); /* Check client credentials are valid. */ - if (!creds_server_check(p->dc, &q_u->clnt_chal)) { - DEBUG(0,("_net_auth2: creds_server_check failed. Rejecting auth " + if (!netlogon_creds_server_check(p->dc, r->in.credentials)) { + DEBUG(0,("_netr_ServerAuthenticate2: netlogon_creds_server_check failed. Rejecting auth " "request from client %s machine account %s\n", - remote_machine, mach_acct )); + r->in.computer_name, + r->in.account_name)); return NT_STATUS_ACCESS_DENIED; } - srv_flgs.neg_flags = 0x000001ff; + srv_flgs = 0x000001ff; - if (lp_server_schannel() != False) { - srv_flgs.neg_flags |= NETLOGON_NEG_SCHANNEL; + if (lp_server_schannel() != false) { + srv_flgs |= NETLOGON_NEG_SCHANNEL; } /* set up the LSA AUTH 2 response */ - init_net_r_auth_2(r_u, &srv_chal_out, &srv_flgs, NT_STATUS_OK); + memcpy(r->out.return_credentials->data, &srv_chal_out.data, + sizeof(r->out.return_credentials->data)); + *r->out.negotiate_flags = srv_flgs; - fstrcpy(p->dc->mach_acct, mach_acct); - fstrcpy(p->dc->remote_machine, remote_machine); + fstrcpy(p->dc->mach_acct, r->in.account_name); + fstrcpy(p->dc->remote_machine, r->in.computer_name); fstrcpy(p->dc->domain, lp_workgroup() ); p->dc->authenticated = True; @@ -483,39 +535,40 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u) /* Store off the state so we can continue after client disconnect. */ become_root(); secrets_store_schannel_session_info(p->mem_ctx, - remote_machine, - p->dc); + r->in.computer_name, + p->dc); unbecome_root(); - return r_u->status; + return NT_STATUS_OK; } /************************************************************************* - _net_srv_pwset + _netr_ServerPasswordSet *************************************************************************/ -NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *r_u) +NTSTATUS _netr_ServerPasswordSet(pipes_struct *p, + struct netr_ServerPasswordSet *r) { + NTSTATUS status = NT_STATUS_OK; fstring remote_machine; struct samu *sampass=NULL; bool ret = False; unsigned char pwd[16]; int i; uint32 acct_ctrl; - DOM_CRED cred_out; + struct netr_Authenticator cred_out; const uchar *old_pw; - DEBUG(5,("_net_srv_pwset: %d\n", __LINE__)); + DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__)); /* We need the remote machine name for the creds lookup. */ - rpcstr_pull(remote_machine,q_u->clnt_id.login.uni_comp_name.buffer, - sizeof(remote_machine),q_u->clnt_id.login.uni_comp_name.uni_str_len*2,0); + fstrcpy(remote_machine, r->in.computer_name); if ( (lp_server_schannel() == True) && (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) ) { /* 'server schannel = yes' should enforce use of schannel, the client did offer it in auth2, but obviously did not use it. */ - DEBUG(0,("_net_srv_pwset: client %s not using schannel for netlogon\n", + DEBUG(0,("_netr_ServerPasswordSet: client %s not using schannel for netlogon\n", remote_machine )); return NT_STATUS_ACCESS_DENIED; } @@ -536,12 +589,12 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * return NT_STATUS_INVALID_HANDLE; } - DEBUG(3,("_net_srv_pwset: Server Password Set by remote machine:[%s] on account [%s]\n", + DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n", remote_machine, p->dc->mach_acct)); - + /* Step the creds chain forward. */ - if (!creds_server_step(p->dc, &q_u->clnt_id.cred, &cred_out)) { - DEBUG(2,("_net_srv_pwset: creds_server_step failed. Rejecting auth " + if (!netlogon_creds_server_step(p->dc, r->in.credential, &cred_out)) { + DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth " "request from client %s machine account %s\n", remote_machine, p->dc->mach_acct )); return NT_STATUS_INVALID_PARAMETER; @@ -566,7 +619,7 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * } /* Ensure the account exists and is a machine account. */ - + acct_ctrl = pdb_get_acct_ctrl(sampass); if (!(acct_ctrl & ACB_WSTRUST || @@ -575,16 +628,16 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * TALLOC_FREE(sampass); return NT_STATUS_NO_SUCH_USER; } - + if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { TALLOC_FREE(sampass); return NT_STATUS_ACCOUNT_DISABLED; } /* Woah - what does this to to the credential chain ? JRA */ - cred_hash3( pwd, q_u->pwd, p->dc->sess_key, 0); + cred_hash3(pwd, r->in.new_password->hash, p->dc->sess_key, 0); - DEBUG(100,("Server password set : new given value was :\n")); + DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n")); for(i = 0; i < sizeof(pwd); i++) DEBUG(100,("%02X ", pwd[i])); DEBUG(100,("\n")); @@ -592,7 +645,7 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * old_pw = pdb_get_nt_passwd(sampass); if (old_pw && memcmp(pwd, old_pw, 16) == 0) { - /* Avoid backend modificiations and other fun if the + /* Avoid backend modificiations and other fun if the client changed the password to the *same thing* */ ret = True; @@ -603,43 +656,44 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * TALLOC_FREE(sampass); return NT_STATUS_NO_MEMORY; } - + if (!pdb_set_nt_passwd(sampass, pwd, PDB_CHANGED)) { TALLOC_FREE(sampass); return NT_STATUS_NO_MEMORY; } - + if (!pdb_set_pass_last_set_time(sampass, time(NULL), PDB_CHANGED)) { TALLOC_FREE(sampass); /* Not quite sure what this one qualifies as, but this will do */ - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_UNSUCCESSFUL; } - + become_root(); - r_u->status = pdb_update_sam_account(sampass); + status = pdb_update_sam_account(sampass); unbecome_root(); } /* set up the LSA Server Password Set response */ - init_net_r_srv_pwset(r_u, &cred_out, r_u->status); + + memcpy(r->out.return_authenticator, &cred_out, + sizeof(r->out.return_authenticator)); TALLOC_FREE(sampass); - return r_u->status; + return status; } /************************************************************************* - _net_sam_logoff: + _netr_LogonSamLogoff *************************************************************************/ -NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOFF *r_u) +NTSTATUS _netr_LogonSamLogoff(pipes_struct *p, + struct netr_LogonSamLogoff *r) { - fstring remote_machine; - if ( (lp_server_schannel() == True) && (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) ) { /* 'server schannel = yes' should enforce use of schannel, the client did offer it in auth2, but obviously did not use it. */ - DEBUG(0,("_net_sam_logoff: client %s not using schannel for netlogon\n", + DEBUG(0,("_netr_LogonSamLogoff: client %s not using schannel for netlogon\n", get_remote_machine_name() )); return NT_STATUS_ACCESS_DENIED; } @@ -648,9 +702,8 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF if (!get_valid_user_struct(p->vuid)) return NT_STATUS_NO_SUCH_USER; - /* Get the remote machine name for the creds store. */ - rpcstr_pull(remote_machine,q_u->sam_id.client.login.uni_comp_name.buffer, - sizeof(remote_machine),q_u->sam_id.client.login.uni_comp_name.uni_str_len*2,0); + /* Using the remote machine name for the creds store: */ + /* r->in.computer_name */ if (!p->dc) { /* Restore the saved state of the netlogon creds. */ @@ -658,8 +711,8 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF become_root(); ret = secrets_restore_schannel_session_info(p->pipe_state_mem_ctx, - remote_machine, - &p->dc); + r->in.computer_name, + &p->dc); unbecome_root(); if (!ret) { return NT_STATUS_INVALID_HANDLE; @@ -670,25 +723,22 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF return NT_STATUS_INVALID_HANDLE; } - r_u->buffer_creds = 1; /* yes, we have valid server credentials */ - /* checks and updates credentials. creates reply credentials */ - if (!creds_server_step(p->dc, &q_u->sam_id.client.cred, &r_u->srv_creds)) { - DEBUG(2,("_net_sam_logoff: creds_server_step failed. Rejecting auth " + if (!netlogon_creds_server_step(p->dc, r->in.credential, r->out.return_authenticator)) { + DEBUG(2,("_netr_LogonSamLogoff: netlogon_creds_server_step failed. Rejecting auth " "request from client %s machine account %s\n", - remote_machine, p->dc->mach_acct )); + r->in.computer_name, p->dc->mach_acct )); return NT_STATUS_INVALID_PARAMETER; } /* We must store the creds state after an update. */ become_root(); secrets_store_schannel_session_info(p->pipe_state_mem_ctx, - remote_machine, - p->dc); + r->in.computer_name, + p->dc); unbecome_root(); - r_u->status = NT_STATUS_OK; - return r_u->status; + return NT_STATUS_OK; } /******************************************************************* @@ -699,7 +749,7 @@ static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid, size_t num_sids, const DOM_SID *sids, - int *numgroups, DOM_GID **pgids) + int *numgroups, DOM_GID **pgids) { int i; @@ -722,53 +772,54 @@ static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, } /************************************************************************* - _net_sam_logon + _netr_LogonSamLogon *************************************************************************/ -static NTSTATUS _net_sam_logon_internal(pipes_struct *p, - NET_Q_SAM_LOGON *q_u, - NET_R_SAM_LOGON *r_u, - bool process_creds) +NTSTATUS _netr_LogonSamLogon(pipes_struct *p, + struct netr_LogonSamLogon *r) { NTSTATUS status = NT_STATUS_OK; - NET_USER_INFO_3 *usr_info = NULL; - NET_ID_INFO_CTR *ctr = q_u->sam_id.ctr; - UNISTR2 *uni_samlogon_user = NULL; - UNISTR2 *uni_samlogon_domain = NULL; - UNISTR2 *uni_samlogon_workstation = NULL; + struct netr_SamInfo3 *sam3 = NULL; + union netr_LogonLevel *logon = r->in.logon; fstring nt_username, nt_domain, nt_workstation; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; struct samu *sampw; struct auth_context *auth_context = NULL; - + bool process_creds = true; + + switch (p->hdr_req.opnum) { + case NDR_NETR_LOGONSAMLOGON: + process_creds = true; + break; + case NDR_NETR_LOGONSAMLOGONEX: + default: + process_creds = false; + } + if ( (lp_server_schannel() == True) && (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) ) { /* 'server schannel = yes' should enforce use of schannel, the client did offer it in auth2, but obviously did not use it. */ - DEBUG(0,("_net_sam_logon_internal: client %s not using schannel for netlogon\n", + DEBUG(0,("_netr_LogonSamLogon: client %s not using schannel for netlogon\n", get_remote_machine_name() )); return NT_STATUS_ACCESS_DENIED; } - usr_info = TALLOC_P(p->mem_ctx, NET_USER_INFO_3); - if (!usr_info) { + sam3 = TALLOC_ZERO_P(p->mem_ctx, struct netr_SamInfo3); + if (!sam3) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(usr_info); - /* store the user information, if there is any. */ - r_u->user = usr_info; - r_u->auth_resp = 1; /* authoritative response */ - if (q_u->validation_level != 2 && q_u->validation_level != 3) { - DEBUG(0,("_net_sam_logon: bad validation_level value %d.\n", (int)q_u->validation_level )); + r->out.validation->sam3 = sam3; + *r->out.authoritative = true; /* authoritative response */ + if (r->in.validation_level != 2 && r->in.validation_level != 3) { + DEBUG(0,("_netr_LogonSamLogon: bad validation_level value %d.\n", + (int)r->in.validation_level)); return NT_STATUS_ACCESS_DENIED; } - /* We handle the return of USER_INFO_2 instead of 3 in the parse return. Sucks, I know... */ - r_u->switch_value = q_u->validation_level; /* indicates type of validation user info */ - r_u->buffer_creds = 1; /* Ensure we always return server creds. */ - + if (!get_valid_user_struct(p->vuid)) return NT_STATUS_NO_SUCH_USER; @@ -779,8 +830,8 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, /* Note this is the remote machine this request is coming from (member server), not neccessarily the workstation name the user is logging onto. */ - rpcstr_pull(remote_machine,q_u->sam_id.client.login.uni_comp_name.buffer, - sizeof(remote_machine),q_u->sam_id.client.login.uni_comp_name.uni_str_len*2,0); + + fstrcpy(remote_machine, r->in.computer_name); if (!p->dc) { /* Restore the saved state of the netlogon creds. */ @@ -801,8 +852,8 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } /* checks and updates credentials. creates reply credentials */ - if (!creds_server_step(p->dc, &q_u->sam_id.client.cred, &r_u->srv_creds)) { - DEBUG(2,("_net_sam_logon: creds_server_step failed. Rejecting auth " + if (!netlogon_creds_server_step(p->dc, r->in.credential, r->out.return_authenticator)) { + DEBUG(2,("_netr_LogonSamLogon: creds_server_step failed. Rejecting auth " "request from client %s machine account %s\n", remote_machine, p->dc->mach_acct )); return NT_STATUS_INVALID_PARAMETER; @@ -816,20 +867,25 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, unbecome_root(); } - switch (q_u->sam_id.logon_level) { + switch (r->in.logon_level) { case INTERACTIVE_LOGON_TYPE: - uni_samlogon_user = &ctr->auth.id1.uni_user_name; - uni_samlogon_domain = &ctr->auth.id1.uni_domain_name; + fstrcpy(nt_username, + logon->password->identity_info.account_name.string); + fstrcpy(nt_domain, + logon->password->identity_info.domain_name.string); + fstrcpy(nt_workstation, + logon->password->identity_info.workstation.string); - uni_samlogon_workstation = &ctr->auth.id1.uni_wksta_name; - DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", lp_workgroup())); break; case NET_LOGON_TYPE: - uni_samlogon_user = &ctr->auth.id2.uni_user_name; - uni_samlogon_domain = &ctr->auth.id2.uni_domain_name; - uni_samlogon_workstation = &ctr->auth.id2.uni_wksta_name; - + fstrcpy(nt_username, + logon->network->identity_info.account_name.string); + fstrcpy(nt_domain, + logon->network->identity_info.domain_name.string); + fstrcpy(nt_workstation, + logon->network->identity_info.workstation.string); + DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", lp_workgroup())); break; default: @@ -837,24 +893,23 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, return NT_STATUS_INVALID_INFO_CLASS; } /* end switch */ - rpcstr_pull(nt_username,uni_samlogon_user->buffer,sizeof(nt_username),uni_samlogon_user->uni_str_len*2,0); - rpcstr_pull(nt_domain,uni_samlogon_domain->buffer,sizeof(nt_domain),uni_samlogon_domain->uni_str_len*2,0); - rpcstr_pull(nt_workstation,uni_samlogon_workstation->buffer,sizeof(nt_workstation),uni_samlogon_workstation->uni_str_len*2,0); - DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username, nt_workstation, nt_domain)); fstrcpy(current_user_info.smb_name, nt_username); sub_set_smb_name(nt_username); - - DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", q_u->sam_id.ctr->switch_value, nt_username)); + + DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", + r->in.validation_level, nt_username)); status = NT_STATUS_OK; - - switch (ctr->switch_value) { + + switch (r->in.logon_level) { case NET_LOGON_TYPE: { const char *wksname = nt_workstation; - - if (!NT_STATUS_IS_OK(status = make_auth_context_fixed(&auth_context, ctr->auth.id2.lm_chal))) { + + status = make_auth_context_fixed(&auth_context, + logon->network->challenge); + if (!NT_STATUS_IS_OK(status)) { return status; } @@ -865,16 +920,16 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, if (*wksname == '\\') wksname++; /* Standard challenge/response authenticaion */ - if (!make_user_info_netlogon_network(&user_info, - nt_username, nt_domain, + if (!make_user_info_netlogon_network(&user_info, + nt_username, nt_domain, wksname, - ctr->auth.id2.param_ctrl, - ctr->auth.id2.lm_chal_resp.buffer, - ctr->auth.id2.lm_chal_resp.str_str_len, - ctr->auth.id2.nt_chal_resp.buffer, - ctr->auth.id2.nt_chal_resp.str_str_len)) { + logon->network->identity_info.parameter_control, + logon->network->lm.data, + logon->network->lm.length, + logon->network->nt.data, + logon->network->nt.length)) { status = NT_STATUS_NO_MEMORY; - } + } break; } case INTERACTIVE_LOGON_TYPE: @@ -884,20 +939,20 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, on */ { const uint8 *chal; - + if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) { return status; } - + chal = auth_context->get_ntlm_challenge(auth_context); - if (!make_user_info_netlogon_interactive(&user_info, - nt_username, nt_domain, - nt_workstation, - ctr->auth.id1.param_ctrl, + if (!make_user_info_netlogon_interactive(&user_info, + nt_username, nt_domain, + nt_workstation, + logon->password->identity_info.parameter_control, chal, - ctr->auth.id1.lm_owf.data, - ctr->auth.id1.nt_owf.data, + logon->password->lmpassword.hash, + logon->password->ntpassword.hash, p->dc->sess_key)) { status = NT_STATUS_NO_MEMORY; } @@ -907,29 +962,29 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, DEBUG(2,("SAM Logon: unsupported switch value\n")); return NT_STATUS_INVALID_INFO_CLASS; } /* end switch */ - + if ( NT_STATUS_IS_OK(status) ) { - status = auth_context->check_ntlm_password(auth_context, + status = auth_context->check_ntlm_password(auth_context, user_info, &server_info); } - (auth_context->free)(&auth_context); + (auth_context->free)(&auth_context); free_user_info(&user_info); - - DEBUG(5, ("_net_sam_logon: check_password returned status %s\n", + + DEBUG(5,("_netr_LogonSamLogon: check_password returned status %s\n", nt_errstr(status))); /* Check account and password */ - + if (!NT_STATUS_IS_OK(status)) { - /* If we don't know what this domain is, we need to - indicate that we are not authoritative. This - allows the client to decide if it needs to try + /* If we don't know what this domain is, we need to + indicate that we are not authoritative. This + allows the client to decide if it needs to try a local user. Fix by jpjanosi@us.ibm.com, #2976 */ - if ( NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) + if ( NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) && !strequal(nt_domain, get_global_sam_name()) && !is_trusted_domain(nt_domain) ) - r_u->auth_resp = 0; /* We are not authoritative */ + *r->out.authoritative = false; /* We are not authoritative */ TALLOC_FREE(server_info); return status; @@ -937,7 +992,7 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, if (server_info->guest) { /* We don't like guest domain logons... */ - DEBUG(5,("_net_sam_logon: Attempted domain logon as GUEST " + DEBUG(5,("_netr_LogonSamLogon: Attempted domain logon as GUEST " "denied.\n")); TALLOC_FREE(server_info); return NT_STATUS_LOGON_FAILURE; @@ -956,29 +1011,40 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, int num_gids = 0; const char *my_name; - unsigned char user_session_key[16]; - unsigned char lm_session_key[16]; + + struct netr_UserSessionKey user_session_key; + struct netr_LMSessionKey lm_session_key; unsigned char pipe_session_key[16]; - sampw = server_info->sam_account; + NTTIME last_logon, last_logoff, acct_expiry, last_password_change; + NTTIME allow_password_change, force_password_change; + struct samr_RidWithAttributeArray groups; + int i; + struct dom_sid2 *sid = NULL; + + ZERO_STRUCT(user_session_key); + ZERO_STRUCT(lm_session_key); - /* set up pointer indicating user/password failed to be - * found */ - usr_info->ptr_user_info = 0; + sampw = server_info->sam_account; user_sid = pdb_get_user_sid(sampw); group_sid = pdb_get_group_sid(sampw); if ((user_sid == NULL) || (group_sid == NULL)) { - DEBUG(1, ("_net_sam_logon: User without group or user SID\n")); + DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n")); return NT_STATUS_UNSUCCESSFUL; } sid_copy(&domain_sid, user_sid); sid_split_rid(&domain_sid, &user_rid); + sid = sid_dup_talloc(p->mem_ctx, &domain_sid); + if (!sid) { + return NT_STATUS_NO_MEMORY; + } + if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) { - DEBUG(1, ("_net_sam_logon: user %s\\%s has user sid " + DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid " "%s\n but group sid %s.\n" "The conflicting domain portions are not " "supported for NETLOGON calls\n", @@ -1005,9 +1071,9 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } if (server_info->user_session_key.length) { - memcpy(user_session_key, + memcpy(user_session_key.key, server_info->user_session_key.data, - MIN(sizeof(user_session_key), + MIN(sizeof(user_session_key.key), server_info->user_session_key.length)); if (process_creds) { /* Get the pipe session key from the creds. */ @@ -1019,13 +1085,13 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } memcpy(pipe_session_key, p->auth.a_u.schannel_auth->sess_key, 16); } - SamOEMhash(user_session_key, pipe_session_key, 16); + SamOEMhash(user_session_key.key, pipe_session_key, 16); memset(pipe_session_key, '\0', 16); } if (server_info->lm_session_key.length) { - memcpy(lm_session_key, + memcpy(lm_session_key.key, server_info->lm_session_key.data, - MIN(sizeof(lm_session_key), + MIN(sizeof(lm_session_key.key), server_info->lm_session_key.length)); if (process_creds) { /* Get the pipe session key from the creds. */ @@ -1037,36 +1103,56 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } memcpy(pipe_session_key, p->auth.a_u.schannel_auth->sess_key, 16); } - SamOEMhash(lm_session_key, pipe_session_key, 16); + SamOEMhash(lm_session_key.key, pipe_session_key, 16); memset(pipe_session_key, '\0', 16); } - init_net_user_info3(p->mem_ctx, usr_info, - user_rid, - group_rid, - pdb_get_username(sampw), - pdb_get_fullname(sampw), - pdb_get_homedir(sampw), - pdb_get_dir_drive(sampw), - pdb_get_logon_script(sampw), - pdb_get_profile_path(sampw), - pdb_get_logon_time(sampw), - get_time_t_max(), - get_time_t_max(), - pdb_get_pass_last_set_time(sampw), - pdb_get_pass_can_change_time(sampw), - pdb_get_pass_must_change_time(sampw), - 0, /* logon_count */ - 0, /* bad_pw_count */ - num_gids, /* uint32 num_groups */ - gids , /* DOM_GID *gids */ - NETLOGON_EXTRA_SIDS, /* uint32 user_flgs (?) */ - pdb_get_acct_ctrl(sampw), - server_info->user_session_key.length ? user_session_key : NULL, - server_info->lm_session_key.length ? lm_session_key : NULL, - my_name , /* char *logon_srv */ - pdb_get_domain(sampw), - &domain_sid); /* DOM_SID *dom_sid */ + groups.count = num_gids; + groups.rids = TALLOC_ARRAY(p->mem_ctx, struct samr_RidWithAttribute, + groups.count); + if (!groups.rids) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i < groups.count; i++) { + groups.rids[i].rid = gids[i].g_rid; + groups.rids[i].attributes = gids[i].attr; + } + + unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw)); + unix_to_nt_time(&last_logoff, get_time_t_max()); + unix_to_nt_time(&acct_expiry, get_time_t_max()); + unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw)); + unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw)); + unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw)); + + init_netr_SamInfo3(sam3, + last_logon, + last_logoff, + acct_expiry, + last_password_change, + allow_password_change, + force_password_change, + talloc_strdup(p->mem_ctx, pdb_get_username(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_fullname(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_logon_script(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_profile_path(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_homedir(sampw)), + talloc_strdup(p->mem_ctx, pdb_get_dir_drive(sampw)), + 0, /* logon_count */ + 0, /* bad_password_count */ + user_rid, + group_rid, + groups, + NETLOGON_EXTRA_SIDS, + user_session_key, + my_name, + talloc_strdup(p->mem_ctx, pdb_get_domain(sampw)), + sid, + lm_session_key, + pdb_get_acct_ctrl(sampw), + 0, /* sidcount */ + NULL); /* struct netr_SidAttr *sids */ ZERO_STRUCT(user_session_key); ZERO_STRUCT(lm_session_key); } @@ -1075,25 +1161,14 @@ static NTSTATUS _net_sam_logon_internal(pipes_struct *p, } /************************************************************************* - _net_sam_logon + _netr_LogonSamLogonEx + - no credential chaining. Map into net sam logon. *************************************************************************/ -NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u) -{ - return _net_sam_logon_internal(p, q_u, r_u, True); -} - -/************************************************************************* - _net_sam_logon_ex - no credential chaining. Map into net sam logon. - *************************************************************************/ - -NTSTATUS _net_sam_logon_ex(pipes_struct *p, NET_Q_SAM_LOGON_EX *q_u, NET_R_SAM_LOGON_EX *r_u) +NTSTATUS _netr_LogonSamLogonEx(pipes_struct *p, + struct netr_LogonSamLogonEx *r) { - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); + struct netr_LogonSamLogon q; /* Only allow this if the pipe is protected. */ if (p->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { @@ -1102,26 +1177,20 @@ NTSTATUS _net_sam_logon_ex(pipes_struct *p, NET_Q_SAM_LOGON_EX *q_u, NET_R_SAM_L return NT_STATUS_INVALID_PARAMETER; } - /* Map a NET_Q_SAM_LOGON_EX to NET_Q_SAM_LOGON. */ - q.validation_level = q_u->validation_level; - - /* Map a DOM_SAM_INFO_EX into a DOM_SAM_INFO with no creds. */ - q.sam_id.client.login = q_u->sam_id.client; - q.sam_id.logon_level = q_u->sam_id.logon_level; - q.sam_id.ctr = q_u->sam_id.ctr; + q.in.server_name = r->in.server_name; + q.in.computer_name = r->in.computer_name; + q.in.logon_level = r->in.logon_level; + q.in.logon = r->in.logon; + q.in.validation_level = r->in.validation_level; + /* we do not handle the flags */ + /* = r->in.flags; */ - r_u->status = _net_sam_logon_internal(p, &q, &r, False); + q.out.validation = r->out.validation; + q.out.authoritative = r->out.authoritative; + /* we do not handle the flags */ + /* = r->out.flags; */ - if (!NT_STATUS_IS_OK(r_u->status)) { - return r_u->status; - } - - /* Map the NET_R_SAM_LOGON to NET_R_SAM_LOGON_EX. */ - r_u->switch_value = r.switch_value; - r_u->user = r.user; - r_u->auth_resp = r.auth_resp; - r_u->flags = 0; /* FIXME ! */ - return r_u->status; + return _netr_LogonSamLogon(p, &q); } /************************************************************************* @@ -1133,10 +1202,10 @@ NTSTATUS _net_sam_logon_ex(pipes_struct *p, NET_Q_SAM_LOGON_EX *q_u, NET_R_SAM_L { NTSTATUS status = NT_STATUS_OK; - /* TODO: According to MSDN, the can only be executed against a + /* TODO: According to MSDN, the can only be executed against a DC or domain member running Windows 2000 or later. Need - to test against a standalone 2k server and see what it - does. A windows 2000 DC includes its own domain in the + to test against a standalone 2k server and see what it + does. A windows 2000 DC includes its own domain in the list. --jerry */ return status; @@ -1167,56 +1236,6 @@ WERROR _netr_LogonUasLogoff(pipes_struct *p, /**************************************************************** ****************************************************************/ -NTSTATUS _netr_LogonSamLogon(pipes_struct *p, - struct netr_LogonSamLogon *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_LogonSamLogoff(pipes_struct *p, - struct netr_LogonSamLogoff *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_ServerReqChallenge(pipes_struct *p, - struct netr_ServerReqChallenge *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_ServerAuthenticate(pipes_struct *p, - struct netr_ServerAuthenticate *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_ServerPasswordSet(pipes_struct *p, - struct netr_ServerPasswordSet *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - NTSTATUS _netr_DatabaseDeltas(pipes_struct *p, struct netr_DatabaseDeltas *r) { @@ -1257,16 +1276,6 @@ NTSTATUS _netr_AccountSync(pipes_struct *p, /**************************************************************** ****************************************************************/ -WERROR _netr_LogonControl(pipes_struct *p, - struct netr_LogonControl *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** -****************************************************************/ - WERROR _netr_GetDcName(pipes_struct *p, struct netr_GetDcName *r) { @@ -1287,26 +1296,6 @@ WERROR _netr_GetAnyDCName(pipes_struct *p, /**************************************************************** ****************************************************************/ -WERROR _netr_LogonControl2(pipes_struct *p, - struct netr_LogonControl2 *r) -{ - p->rng_fault_state = true; - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS _netr_ServerAuthenticate2(pipes_struct *p, - struct netr_ServerAuthenticate2 *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - NTSTATUS _netr_DatabaseSync2(pipes_struct *p, struct netr_DatabaseSync2 *r) { @@ -1527,16 +1516,6 @@ WERROR _netr_DsrGetDcSiteCoverageW(pipes_struct *p, /**************************************************************** ****************************************************************/ -NTSTATUS _netr_LogonSamLogonEx(pipes_struct *p, - struct netr_LogonSamLogonEx *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - WERROR _netr_DsrEnumerateDomainTrusts(pipes_struct *p, struct netr_DsrEnumerateDomainTrusts *r) { diff --git a/source3/rpc_server/srv_ntsvcs.c b/source3/rpc_server/srv_ntsvcs.c index b3e93ac459..12fffc3e96 100644 --- a/source3/rpc_server/srv_ntsvcs.c +++ b/source3/rpc_server/srv_ntsvcs.c @@ -25,49 +25,38 @@ /******************************************************************* ********************************************************************/ -static bool api_ntsvcs_get_version(pipes_struct *p) +static bool proxy_ntsvcs_call(pipes_struct *p, uint8_t opnum) { - NTSVCS_Q_GET_VERSION q_u; - NTSVCS_R_GET_VERSION r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); + struct api_struct *fns; + int n_fns; - if(!ntsvcs_io_q_get_version("", &q_u, data, 0)) - return False; + ntsvcs_get_pipe_fns(&fns, &n_fns); - r_u.status = _ntsvcs_get_version(p, &q_u, &r_u); + if (opnum >= n_fns) { + return false; + } - if(!ntsvcs_io_r_get_version("", &r_u, rdata, 0)) - return False; + if (fns[opnum].opnum != opnum) { + smb_panic("NTSVCS function table not sorted"); + } - return True; + return fns[opnum].fn(p); } /******************************************************************* ********************************************************************/ -static bool api_ntsvcs_get_device_list_size(pipes_struct *p) +static bool api_ntsvcs_get_version(pipes_struct *p) { - NTSVCS_Q_GET_DEVICE_LIST_SIZE q_u; - NTSVCS_R_GET_DEVICE_LIST_SIZE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!ntsvcs_io_q_get_device_list_size("", &q_u, data, 0)) - return False; - - r_u.status = _ntsvcs_get_device_list_size(p, &q_u, &r_u); + return proxy_ntsvcs_call(p, NDR_PNP_GETVERSION); +} - if(!ntsvcs_io_r_get_device_list_size("", &r_u, rdata, 0)) - return False; +/******************************************************************* + ********************************************************************/ - return True; +static bool api_ntsvcs_get_device_list_size(pipes_struct *p) +{ + return proxy_ntsvcs_call(p, NDR_PNP_GETDEVICELISTSIZE); } /******************************************************************* @@ -99,23 +88,7 @@ static bool api_ntsvcs_get_device_list(pipes_struct *p) static bool api_ntsvcs_validate_device_instance(pipes_struct *p) { - NTSVCS_Q_VALIDATE_DEVICE_INSTANCE q_u; - NTSVCS_R_VALIDATE_DEVICE_INSTANCE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!ntsvcs_io_q_validate_device_instance("", &q_u, data, 0)) - return False; - - r_u.status = _ntsvcs_validate_device_instance(p, &q_u, &r_u); - - if(!ntsvcs_io_r_validate_device_instance("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_ntsvcs_call(p, NDR_PNP_VALIDATEDEVICEINSTANCE); } /******************************************************************* @@ -147,23 +120,7 @@ static bool api_ntsvcs_get_device_reg_property(pipes_struct *p) static bool api_ntsvcs_get_hw_profile_info(pipes_struct *p) { - NTSVCS_Q_GET_HW_PROFILE_INFO q_u; - NTSVCS_R_GET_HW_PROFILE_INFO r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!ntsvcs_io_q_get_hw_profile_info("", &q_u, data, 0)) - return False; - - r_u.status = _ntsvcs_get_hw_profile_info(p, &q_u, &r_u); - - if(!ntsvcs_io_r_get_hw_profile_info("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_ntsvcs_call(p, NDR_PNP_GETHWPROFINFO); } /******************************************************************* @@ -171,23 +128,7 @@ static bool api_ntsvcs_get_hw_profile_info(pipes_struct *p) static bool api_ntsvcs_hw_profile_flags(pipes_struct *p) { - NTSVCS_Q_HW_PROFILE_FLAGS q_u; - NTSVCS_R_HW_PROFILE_FLAGS r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!ntsvcs_io_q_hw_profile_flags("", &q_u, data, 0)) - return False; - - r_u.status = _ntsvcs_hw_profile_flags(p, &q_u, &r_u); - - if(!ntsvcs_io_r_hw_profile_flags("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_ntsvcs_call(p, NDR_PNP_HWPROFFLAGS); } /******************************************************************* @@ -206,13 +147,13 @@ static struct api_struct api_ntsvcs_cmds[] = }; -void ntsvcs_get_pipe_fns( struct api_struct **fns, int *n_fns ) +void ntsvcs2_get_pipe_fns( struct api_struct **fns, int *n_fns ) { *fns = api_ntsvcs_cmds; *n_fns = sizeof(api_ntsvcs_cmds) / sizeof(struct api_struct); } -NTSTATUS rpc_ntsvcs_init(void) +NTSTATUS rpc_ntsvcs2_init(void) { return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "ntsvcs", "ntsvcs", api_ntsvcs_cmds, sizeof(api_ntsvcs_cmds) / sizeof(struct api_struct)); diff --git a/source3/rpc_server/srv_ntsvcs_nt.c b/source3/rpc_server/srv_ntsvcs_nt.c index 16c74c5d6d..11ea5d0cd1 100644 --- a/source3/rpc_server/srv_ntsvcs_nt.c +++ b/source3/rpc_server/srv_ntsvcs_nt.c @@ -34,31 +34,31 @@ static char* get_device_path(TALLOC_CTX *mem_ctx, const char *device ) /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_get_version( pipes_struct *p, NTSVCS_Q_GET_VERSION *q_u, NTSVCS_R_GET_VERSION *r_u ) +WERROR _PNP_GetVersion(pipes_struct *p, + struct PNP_GetVersion *r) { - r_u->version = 0x00000400; /* no idea what this means */ - + *r->out.version = 0x0400; /* no idea what this means */ + return WERR_OK; } /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_get_device_list_size( pipes_struct *p, NTSVCS_Q_GET_DEVICE_LIST_SIZE *q_u, NTSVCS_R_GET_DEVICE_LIST_SIZE *r_u ) +WERROR _PNP_GetDeviceListSize(pipes_struct *p, + struct PNP_GetDeviceListSize *r) { - fstring device; char *devicepath; - if ( !q_u->devicename ) + if (!r->in.devicename) { return WERR_ACCESS_DENIED; + } - rpcstr_pull(device, q_u->devicename->buffer, sizeof(device), q_u->devicename->uni_str_len*2, 0); - - if (!(devicepath = get_device_path(p->mem_ctx, device))) { + if (!(devicepath = get_device_path(p->mem_ctx, r->in.devicename))) { return WERR_NOMEM; } - r_u->size = strlen(devicepath) + 2; + *r->out.size = strlen(devicepath) + 2; TALLOC_FREE(devicepath); @@ -143,7 +143,8 @@ WERROR _ntsvcs_get_device_reg_property( pipes_struct *p, NTSVCS_Q_GET_DEVICE_REG /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_validate_device_instance( pipes_struct *p, NTSVCS_Q_VALIDATE_DEVICE_INSTANCE *q_u, NTSVCS_R_VALIDATE_DEVICE_INSTANCE *r_u ) +WERROR _PNP_ValidateDeviceInstance(pipes_struct *p, + struct PNP_ValidateDeviceInstance *r) { /* whatever dude */ return WERR_OK; @@ -152,12 +153,12 @@ WERROR _ntsvcs_validate_device_instance( pipes_struct *p, NTSVCS_Q_VALIDATE_DEVI /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_get_hw_profile_info( pipes_struct *p, NTSVCS_Q_GET_HW_PROFILE_INFO *q_u, NTSVCS_R_GET_HW_PROFILE_INFO *r_u ) +WERROR _PNP_GetHwProfInfo(pipes_struct *p, + struct PNP_GetHwProfInfo *r) { /* steal the incoming buffer */ - r_u->buffer_size = q_u->buffer_size; - r_u->buffer = q_u->buffer; + r->out.info = r->in.info; /* Take the 5th Ammentment */ @@ -167,10 +168,611 @@ WERROR _ntsvcs_get_hw_profile_info( pipes_struct *p, NTSVCS_Q_GET_HW_PROFILE_INF /******************************************************************** ********************************************************************/ -WERROR _ntsvcs_hw_profile_flags( pipes_struct *p, NTSVCS_Q_HW_PROFILE_FLAGS *q_u, NTSVCS_R_HW_PROFILE_FLAGS *r_u ) -{ +WERROR _PNP_HwProfFlags(pipes_struct *p, + struct PNP_HwProfFlags *r) +{ /* just nod your head */ - + return WERR_OK; } +/**************************************************************** +****************************************************************/ + +WERROR _PNP_Disconnect(pipes_struct *p, + struct PNP_Disconnect *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_Connect(pipes_struct *p, + struct PNP_Connect *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetGlobalState(pipes_struct *p, + struct PNP_GetGlobalState *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_InitDetection(pipes_struct *p, + struct PNP_InitDetection *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_ReportLogOn(pipes_struct *p, + struct PNP_ReportLogOn *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetRootDeviceInstance(pipes_struct *p, + struct PNP_GetRootDeviceInstance *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetRelatedDeviceInstance(pipes_struct *p, + struct PNP_GetRelatedDeviceInstance *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_EnumerateSubKeys(pipes_struct *p, + struct PNP_EnumerateSubKeys *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetDeviceList(pipes_struct *p, + struct PNP_GetDeviceList *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetDepth(pipes_struct *p, + struct PNP_GetDepth *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetDeviceRegProp(pipes_struct *p, + struct PNP_GetDeviceRegProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_SetDeviceRegProp(pipes_struct *p, + struct PNP_SetDeviceRegProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetClassInstance(pipes_struct *p, + struct PNP_GetClassInstance *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_CreateKey(pipes_struct *p, + struct PNP_CreateKey *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DeleteRegistryKey(pipes_struct *p, + struct PNP_DeleteRegistryKey *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetClassCount(pipes_struct *p, + struct PNP_GetClassCount *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetClassName(pipes_struct *p, + struct PNP_GetClassName *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DeleteClassKey(pipes_struct *p, + struct PNP_DeleteClassKey *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetInterfaceDeviceAlias(pipes_struct *p, + struct PNP_GetInterfaceDeviceAlias *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetInterfaceDeviceList(pipes_struct *p, + struct PNP_GetInterfaceDeviceList *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetInterfaceDeviceListSize(pipes_struct *p, + struct PNP_GetInterfaceDeviceListSize *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RegisterDeviceClassAssociation(pipes_struct *p, + struct PNP_RegisterDeviceClassAssociation *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_UnregisterDeviceClassAssociation(pipes_struct *p, + struct PNP_UnregisterDeviceClassAssociation *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetClassRegProp(pipes_struct *p, + struct PNP_GetClassRegProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_SetClassRegProp(pipes_struct *p, + struct PNP_SetClassRegProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_CreateDevInst(pipes_struct *p, + struct PNP_CreateDevInst *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DeviceInstanceAction(pipes_struct *p, + struct PNP_DeviceInstanceAction *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetDeviceStatus(pipes_struct *p, + struct PNP_GetDeviceStatus *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_SetDeviceProblem(pipes_struct *p, + struct PNP_SetDeviceProblem *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DisableDevInst(pipes_struct *p, + struct PNP_DisableDevInst *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_UninstallDevInst(pipes_struct *p, + struct PNP_UninstallDevInst *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_AddID(pipes_struct *p, + struct PNP_AddID *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RegisterDriver(pipes_struct *p, + struct PNP_RegisterDriver *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_QueryRemove(pipes_struct *p, + struct PNP_QueryRemove *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RequestDeviceEject(pipes_struct *p, + struct PNP_RequestDeviceEject *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_IsDockStationPresent(pipes_struct *p, + struct PNP_IsDockStationPresent *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RequestEjectPC(pipes_struct *p, + struct PNP_RequestEjectPC *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_AddEmptyLogConf(pipes_struct *p, + struct PNP_AddEmptyLogConf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_FreeLogConf(pipes_struct *p, + struct PNP_FreeLogConf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetFirstLogConf(pipes_struct *p, + struct PNP_GetFirstLogConf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetNextLogConf(pipes_struct *p, + struct PNP_GetNextLogConf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetLogConfPriority(pipes_struct *p, + struct PNP_GetLogConfPriority *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_AddResDes(pipes_struct *p, + struct PNP_AddResDes *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_FreeResDes(pipes_struct *p, + struct PNP_FreeResDes *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetNextResDes(pipes_struct *p, + struct PNP_GetNextResDes *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetResDesData(pipes_struct *p, + struct PNP_GetResDesData *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetResDesDataSize(pipes_struct *p, + struct PNP_GetResDesDataSize *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_ModifyResDes(pipes_struct *p, + struct PNP_ModifyResDes *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_DetectResourceLimit(pipes_struct *p, + struct PNP_DetectResourceLimit *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_QueryResConfList(pipes_struct *p, + struct PNP_QueryResConfList *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_SetHwProf(pipes_struct *p, + struct PNP_SetHwProf *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_QueryArbitratorFreeData(pipes_struct *p, + struct PNP_QueryArbitratorFreeData *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_QueryArbitratorFreeSize(pipes_struct *p, + struct PNP_QueryArbitratorFreeSize *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RunDetection(pipes_struct *p, + struct PNP_RunDetection *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_RegisterNotification(pipes_struct *p, + struct PNP_RegisterNotification *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_UnregisterNotification(pipes_struct *p, + struct PNP_UnregisterNotification *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetCustomDevProp(pipes_struct *p, + struct PNP_GetCustomDevProp *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetVersionInternal(pipes_struct *p, + struct PNP_GetVersionInternal *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetBlockedDriverInfo(pipes_struct *p, + struct PNP_GetBlockedDriverInfo *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +WERROR _PNP_GetServerSideDeviceInstallFlags(pipes_struct *p, + struct PNP_GetServerSideDeviceInstallFlags *r) +{ + p->rng_fault_state = true; + return WERR_NOT_SUPPORTED; +} + diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 06694a2701..19c8db0533 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -993,7 +993,7 @@ bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ for ( i=0; pipe_names[i].client_pipe; i++ ) { - DEBUG(10,("checking %s\n", pipe_names[i].client_pipe)); + DEBUGADD(10,("checking %s\n", pipe_names[i].client_pipe)); if ( strequal(pipe_names[i].client_pipe, pname) && (abstract->version == pipe_names[i].abstr_syntax.version) && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct GUID)) == 0) @@ -1105,7 +1105,7 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ char *OIDs[ASN1_MAX_OIDS]; int i; NTSTATUS status; - bool got_kerberos_mechanism = False; + bool got_kerberos_mechanism = false; AUTH_NTLMSSP_STATE *a = NULL; RPC_HDR_AUTH auth_info; @@ -1133,7 +1133,7 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ } if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { - got_kerberos_mechanism = True; + got_kerberos_mechanism = true; } for (i=0;OIDs[i];i++) { @@ -1154,27 +1154,38 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ free_pipe_ntlmssp_auth_data(&p->auth); } - /* Initialize the NTLM engine. */ - status = auth_ntlmssp_start(&a); - if (!NT_STATUS_IS_OK(status)) { - goto err; - } + if (!got_kerberos_mechanism) { + /* Initialize the NTLM engine. */ + status = auth_ntlmssp_start(&a); + if (!NT_STATUS_IS_OK(status)) { + goto err; + } - /* - * Pass the first security blob of data to it. - * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED - * which means we need another packet to complete the bind. - */ + /* + * Pass the first security blob of data to it. + * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED + * which means we need another packet to complete the bind. + */ - status = auth_ntlmssp_update(a, secblob, &chal); + status = auth_ntlmssp_update(a, secblob, &chal); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n")); - goto err; - } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n")); + goto err; + } - /* Generate the response blob we need for step 2 of the bind. */ - response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP); + /* Generate the response blob we need for step 2 of the bind. */ + response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP); + } else { + /* + * SPNEGO negotiate down to NTLMSSP. The subsequent + * code to process follow-up packets is not complete + * yet. JRA. + */ + response = spnego_gen_auth_response(NULL, + NT_STATUS_MORE_PROCESSING_REQUIRED, + OID_NTLMSSP); + } /* Copy the blob into the pout_auth parse struct */ init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); @@ -1231,6 +1242,10 @@ static bool pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p ZERO_STRUCT(auth_reply); ZERO_STRUCT(response); + /* + * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently + * fail here as 'a' == NULL. + */ if (p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) { DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n")); goto err; @@ -1259,7 +1274,7 @@ static bool pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p * The following call actually checks the challenge/response data. * for correctness against the given DOMAIN\user name. */ - + if (!pipe_ntlmssp_verify_final(p, &auth_blob)) { goto err; } @@ -2361,7 +2376,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) switch ( idx ) { case PI_LSARPC: - lsa_get_pipe_fns( &cmds, &n_cmds ); + lsarpc_get_pipe_fns( &cmds, &n_cmds ); break; case PI_DSSETUP: dssetup_get_pipe_fns( &cmds, &n_cmds ); @@ -2370,7 +2385,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) samr_get_pipe_fns( &cmds, &n_cmds ); break; case PI_NETLOGON: - netlog_get_pipe_fns( &cmds, &n_cmds ); + netlogon_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SRVSVC: srvsvc2_get_pipe_fns( &cmds, &n_cmds ); @@ -2394,7 +2409,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) eventlog2_get_pipe_fns( &cmds, &n_cmds ); break; case PI_NTSVCS: - ntsvcs_get_pipe_fns( &cmds, &n_cmds ); + ntsvcs2_get_pipe_fns( &cmds, &n_cmds ); break; #ifdef DEVELOPER case PI_RPCECHO: diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 0db74c2a1b..f38a8fcfc0 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -11,6 +11,7 @@ * Copyright (C) Gerald (Jerry) Carter 2003-2004, * Copyright (C) Simo Sorce 2003. * Copyright (C) Volker Lendecke 2005. + * Copyright (C) Guenther Deschner 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 @@ -876,6 +877,8 @@ static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, return NT_STATUS_OK; } +#define MAX_SAM_ENTRIES MAX_SAM_ENTRIES_W2K + /******************************************************************* _samr_EnumDomainUsers ********************************************************************/ @@ -1315,8 +1318,8 @@ static NTSTATUS init_samr_dispinfo_4(TALLOC_CTX *ctx, for (i = 0; i < num_entries ; i++) { - init_lsa_AsciiString(&r->entries[i].account_name, - entries[i].account_name); + init_lsa_AsciiStringLarge(&r->entries[i].account_name, + entries[i].account_name); r->entries[i].idx = start_idx+i+1; } @@ -1351,8 +1354,8 @@ static NTSTATUS init_samr_dispinfo_5(TALLOC_CTX *ctx, for (i = 0; i < num_entries ; i++) { - init_lsa_AsciiString(&r->entries[i].account_name, - entries[i].account_name); + init_lsa_AsciiStringLarge(&r->entries[i].account_name, + entries[i].account_name); r->entries[i].idx = start_idx+i+1; } @@ -2535,10 +2538,10 @@ static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, logon_hours, pdb_get_bad_password_count(pw), pdb_get_logon_count(pw), - 0, //country_code, - 0, //code_page, - 0, //nt_password_set, - 0, //lm_password_set, + 0, /* country_code */ + 0, /* code_page */ + 0, /* nt_password_set */ + 0, /* lm_password_set */ password_expired); TALLOC_FREE(pw); diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index 364adbc0de..688d72064f 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -6,6 +6,7 @@ Copyright (C) Gerald (Jerry) Carter 2000-2001 Copyright (C) Andrew Bartlett 2001-2002 Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Guenther Deschner 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 diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c index 25e652c1fd..41fc39baf7 100644 --- a/source3/rpc_server/srv_srvsvc.c +++ b/source3/rpc_server/srv_srvsvc.c @@ -34,13 +34,13 @@ static bool proxy_srvsvc_call(pipes_struct *p, uint8 opnum) struct api_struct *fns; int n_fns; - lsarpc_get_pipe_fns(&fns, &n_fns); + srvsvc_get_pipe_fns(&fns, &n_fns); if (opnum >= n_fns) return False; if (fns[opnum].opnum != opnum) { - smb_panic("LSA function table not sorted\n"); + smb_panic("SRVSVC function table not sorted\n"); } return fns[opnum].fn(p); @@ -52,25 +52,7 @@ static bool proxy_srvsvc_call(pipes_struct *p, uint8 opnum) static bool api_srv_net_srv_get_info(pipes_struct *p) { - SRV_Q_NET_SRV_GET_INFO q_u; - SRV_R_NET_SRV_GET_INFO r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the net server get info */ - if (!srv_io_q_net_srv_get_info("", &q_u, data, 0)) - return False; - - r_u.status = _srv_net_srv_get_info(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if (!srv_io_r_net_srv_get_info("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_srvsvc_call(p, NDR_SRVSVC_NETSRVGETINFO); } /******************************************************************* @@ -79,25 +61,7 @@ static bool api_srv_net_srv_get_info(pipes_struct *p) static bool api_srv_net_srv_set_info(pipes_struct *p) { - SRV_Q_NET_SRV_SET_INFO q_u; - SRV_R_NET_SRV_SET_INFO r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the net server set info */ - if (!srv_io_q_net_srv_set_info("", &q_u, data, 0)) - return False; - - r_u.status = _srv_net_srv_set_info(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if (!srv_io_r_net_srv_set_info("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_srvsvc_call(p, NDR_SRVSVC_NETSRVSETINFO); } /******************************************************************* @@ -306,28 +270,7 @@ static bool api_srv_net_share_get_info(pipes_struct *p) static bool api_srv_net_share_set_info(pipes_struct *p) { - SRV_Q_NET_SHARE_SET_INFO q_u; - SRV_R_NET_SHARE_SET_INFO r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* Unmarshall the net server set info. */ - if(!srv_io_q_net_share_set_info("", &q_u, data, 0)) { - DEBUG(0,("api_srv_net_share_set_info: Failed to unmarshall SRV_Q_NET_SHARE_SET_INFO.\n")); - return False; - } - - r_u.status = _srv_net_share_set_info(p, &q_u, &r_u); - - if(!srv_io_r_net_share_set_info("", &r_u, rdata, 0)) { - DEBUG(0,("api_srv_net_share_set_info: Failed to marshall SRV_R_NET_SHARE_SET_INFO.\n")); - return False; - } - - return True; + return proxy_srvsvc_call(p, NDR_SRVSVC_NETSHARESETINFO); } /******************************************************************* @@ -426,25 +369,7 @@ static bool api_srv_net_share_del_sticky(pipes_struct *p) static bool api_srv_net_remote_tod(pipes_struct *p) { - SRV_Q_NET_REMOTE_TOD q_u; - SRV_R_NET_REMOTE_TOD r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - /* grab the net server get enum */ - if(!srv_io_q_net_remote_tod("", &q_u, data, 0)) - return False; - - r_u.status = _srv_net_remote_tod(p, &q_u, &r_u); - - /* store the response in the SMB stream */ - if(!srv_io_r_net_remote_tod("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_srvsvc_call(p, NDR_SRVSVC_NETREMOTETOD); } /******************************************************************* diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 1b877ee5b4..4efea33738 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -1,21 +1,21 @@ -/* +/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1997, * Copyright (C) Jeremy Allison 2001. * Copyright (C) Nigel Williams 2001. * Copyright (C) Gerald (Jerry) Carter 2006. - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ @@ -101,11 +101,11 @@ static int pipe_enum_fn( struct db_record *rec, void *p) ********************************************************************/ static WERROR net_enum_pipes( TALLOC_CTX *ctx, const char *username, - FILE_INFO_3 **info, + FILE_INFO_3 **info, uint32 *count, uint32 resume ) { struct file_enum_count fenum; - + fenum.ctx = ctx; fenum.username = username; fenum.count = *count; @@ -202,7 +202,7 @@ static void enum_file_fn( const struct share_mode_entry *e, ********************************************************************/ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, - FILE_INFO_3 **info, + FILE_INFO_3 **info, uint32 *count, uint32 resume ) { struct file_enum_count f_enum_cnt; @@ -211,12 +211,12 @@ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, f_enum_cnt.username = username; f_enum_cnt.count = *count; f_enum_cnt.info = *info; - + share_mode_forall( enum_file_fn, (void *)&f_enum_cnt ); - + *info = f_enum_cnt.info; *count = f_enum_cnt.count; - + return WERR_OK; } @@ -225,9 +225,6 @@ static WERROR net_enum_files( TALLOC_CTX *ctx, const char *username, ********************************************************************/ static uint32 get_share_type(int snum) { - char *net_name = lp_servicename(snum); - int len_net_name = strlen(net_name); - /* work out the share type */ uint32 type = STYPE_DISKTREE; @@ -235,7 +232,7 @@ static uint32 get_share_type(int snum) type = STYPE_PRINTQ; if (strequal(lp_fstype(snum), "IPC")) type = STYPE_IPC; - if (net_name[len_net_name-1] == '$') + if (lp_administrative_share(snum)) type |= STYPE_HIDDEN; return type; @@ -605,7 +602,7 @@ static bool init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, { SRV_SHARE_INFO_501 *info501 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_501, num_entries); int i = 0; - + if (!info501) { return False; } @@ -615,7 +612,7 @@ static bool init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, init_srv_share_info_501(p, &info501[i++], snum); } } - + ctr->share.info501 = info501; break; } @@ -640,7 +637,7 @@ static bool init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, } /* here for completeness but not currently used with enum (1004 - 1501)*/ - + case 1004: { SRV_SHARE_INFO_1004 *info1004 = TALLOC_ARRAY(ctx, SRV_SHARE_INFO_1004, num_entries); @@ -748,7 +745,7 @@ static bool init_srv_share_info_ctr(pipes_struct *p, SRV_SHARE_INFO_CTR *ctr, ********************************************************************/ static void init_srv_r_net_share_enum(pipes_struct *p, SRV_R_NET_SHARE_ENUM *r_n, - uint32 info_level, uint32 resume_hnd, bool all) + uint32 info_level, uint32 resume_hnd, bool all) { DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__)); @@ -855,7 +852,7 @@ static void init_srv_sess_info_0(pipes_struct *p, SRV_SESS_INFO_0 *ss0, uint32 * ss0->num_entries_read = num_entries; ss0->ptr_sess_info = num_entries > 0 ? 1 : 0; ss0->num_entries_read2 = num_entries; - + if ((*snum) >= (*stot)) { (*snum) = 0; } @@ -870,16 +867,16 @@ static void init_srv_sess_info_0(pipes_struct *p, SRV_SESS_INFO_0 *ss0, uint32 * /******************************************************************* ********************************************************************/ -static void sess_file_fn( const struct share_mode_entry *e, +static void sess_file_fn( const struct share_mode_entry *e, const char *sharepath, const char *fname, void *data ) { struct sess_file_count *sess = (struct sess_file_count *)data; - + if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) { sess->count++; } - + return; } @@ -893,9 +890,9 @@ static int net_count_files( uid_t uid, struct server_id pid ) s_file_cnt.count = 0; s_file_cnt.uid = uid; s_file_cnt.pid = pid; - + share_mode_forall( sess_file_fn, &s_file_cnt ); - + return s_file_cnt.count; } @@ -913,42 +910,42 @@ static void init_srv_sess_info_1(pipes_struct *p, SRV_SESS_INFO_1 *ss1, uint32 * ss1->num_entries_read = 0; ss1->ptr_sess_info = 0; ss1->num_entries_read2 = 0; - + (*stot) = 0; return; } - + if (ss1 == NULL) { (*snum) = 0; return; } (*stot) = list_sessions(p->mem_ctx, &session_list); - + for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++) { uint32 num_files; uint32 connect_time; struct passwd *pw = sys_getpwnam(session_list[*snum].username); bool guest; - + if ( !pw ) { DEBUG(10,("init_srv_sess_info_1: failed to find owner: %s\n", session_list[*snum].username)); continue; } - + connect_time = (uint32)(now - session_list[*snum].connect_start); num_files = net_count_files(pw->pw_uid, session_list[*snum].pid); guest = strequal( session_list[*snum].username, lp_guestaccount() ); - - init_srv_sess_info1( &ss1->info_1[num_entries], + + init_srv_sess_info1( &ss1->info_1[num_entries], session_list[*snum].remote_machine, - session_list[*snum].username, + session_list[*snum].username, num_files, connect_time, - 0, + 0, guest); num_entries++; } @@ -956,7 +953,7 @@ static void init_srv_sess_info_1(pipes_struct *p, SRV_SESS_INFO_1 *ss1, uint32 * ss1->num_entries_read = num_entries; ss1->ptr_sess_info = num_entries > 0 ? 1 : 0; ss1->num_entries_read2 = num_entries; - + if ((*snum) >= (*stot)) { (*snum) = 0; } @@ -1001,7 +998,7 @@ static WERROR init_srv_sess_info_ctr(pipes_struct *p, SRV_SESS_INFO_CTR *ctr, ********************************************************************/ static void init_srv_r_net_sess_enum(pipes_struct *p, SRV_R_NET_SESS_ENUM *r_n, - uint32 resume_hnd, int sess_level, int switch_value) + uint32 resume_hnd, int sess_level, int switch_value) { DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__)); @@ -1047,7 +1044,7 @@ static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *sto ss0->num_entries_read = num_entries; ss0->ptr_conn_info = num_entries > 0 ? 1 : 0; ss0->num_entries_read2 = num_entries; - + if ((*snum) >= (*stot)) { (*snum) = 0; } @@ -1104,7 +1101,7 @@ static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto ss1->num_entries_read = num_entries; ss1->ptr_conn_info = num_entries > 0 ? 1 : 0; ss1->num_entries_read2 = num_entries; - + if ((*snum) >= (*stot)) { (*snum) = 0; @@ -1114,7 +1111,7 @@ static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *sto ss1->num_entries_read = 0; ss1->ptr_conn_info = 0; ss1->num_entries_read2 = 0; - + (*stot) = 0; } } @@ -1157,7 +1154,7 @@ static WERROR init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr, ********************************************************************/ static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n, - uint32 resume_hnd, int conn_level, int switch_value) + uint32 resume_hnd, int conn_level, int switch_value) { DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__)); @@ -1183,7 +1180,7 @@ static WERROR net_file_enum_3( const char *username, SRV_R_NET_FILE_ENUM *r, TALLOC_CTX *ctx = talloc_tos(); SRV_FILE_INFO_CTR *ctr = &r->ctr; - /* TODO -- Windows enumerates + /* TODO -- Windows enumerates (b) active pipes (c) open directories and files */ @@ -1191,12 +1188,12 @@ static WERROR net_file_enum_3( const char *username, SRV_R_NET_FILE_ENUM *r, &ctr->num_entries, resume_hnd ); if ( !W_ERROR_IS_OK(r->status)) goto done; - + r->status = net_enum_pipes( ctx, username, &ctr->file.info3, &ctr->num_entries, resume_hnd ); if ( !W_ERROR_IS_OK(r->status)) goto done; - + r->level = ctr->level = 3; r->total_entries = ctr->num_entries; /* ctr->num_entries = r->total_entries - resume_hnd; */ @@ -1206,7 +1203,7 @@ static WERROR net_file_enum_3( const char *username, SRV_R_NET_FILE_ENUM *r, r->status = WERR_OK; done: - if ( ctr->num_entries > 0 ) + if ( ctr->num_entries > 0 ) ctr->ptr_entries = 1; init_enum_hnd(&r->enum_hnd, 0); @@ -1219,105 +1216,133 @@ done: WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_FILE_ENUM *r_u) { + const char *username = NULL; + switch ( q_u->level ) { - case 3: { - char *username; - if (!(username = rpcstr_pull_unistr2_talloc( - p->mem_ctx, q_u->username))) { - return WERR_NOMEM; + case 3: + if (q_u->username) { + username = rpcstr_pull_unistr2_talloc( + p->mem_ctx, q_u->username); + if (!username) { + return WERR_NOMEM; + } } return net_file_enum_3(username, r_u, get_enum_hnd(&q_u->enum_hnd)); - } default: return WERR_UNKNOWN_LEVEL; } - + return WERR_OK; } /******************************************************************* -net server get info + _srvsvc_NetSrvGetInfo ********************************************************************/ -WERROR _srv_net_srv_get_info(pipes_struct *p, SRV_Q_NET_SRV_GET_INFO *q_u, SRV_R_NET_SRV_GET_INFO *r_u) +WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, + struct srvsvc_NetSrvGetInfo *r) { WERROR status = WERR_OK; - SRV_INFO_CTR *ctr = TALLOC_P(p->mem_ctx, SRV_INFO_CTR); - - if (!ctr) - return WERR_NOMEM; - ZERO_STRUCTP(ctr); - - DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__)); if (!pipe_access_check(p)) { - DEBUG(3, ("access denied to srv_net_srv_get_info\n")); + DEBUG(3, ("access denied to _srvsvc_NetSrvGetInfo\n")); return WERR_ACCESS_DENIED; } - switch (q_u->switch_value) { + switch (r->in.level) { /* Technically level 102 should only be available to Administrators but there isn't anything super-secret here, as most of it is made up. */ - case 102: - init_srv_info_102(&ctr->srv.sv102, - 500, global_myname(), - string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), - lp_major_announce_version(), lp_minor_announce_version(), - lp_default_server_announce(), - 0xffffffff, /* users */ - 0xf, /* disc */ - 0, /* hidden */ - 240, /* announce */ - 3000, /* announce delta */ - 100000, /* licenses */ - "c:\\"); /* user path */ + case 102: { + struct srvsvc_NetSrvInfo102 *info102; + + info102 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo102); + if (!info102) { + return WERR_NOMEM; + } + + init_srvsvc_NetSrvInfo102(info102, + PLATFORM_ID_NT, + global_myname(), + lp_major_announce_version(), + lp_minor_announce_version(), + lp_default_server_announce(), + string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), + 0xffffffff, /* users */ + 0xf, /* disc */ + 0, /* hidden */ + 240, /* announce */ + 3000, /* announce delta */ + 100000, /* licenses */ + "c:\\"); /* user path */ + r->out.info->info102 = info102; break; - case 101: - init_srv_info_101(&ctr->srv.sv101, - 500, global_myname(), - lp_major_announce_version(), lp_minor_announce_version(), - lp_default_server_announce(), - string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH)); + } + case 101: { + struct srvsvc_NetSrvInfo101 *info101; + + info101 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo101); + if (!info101) { + return WERR_NOMEM; + } + + init_srvsvc_NetSrvInfo101(info101, + PLATFORM_ID_NT, + global_myname(), + lp_major_announce_version(), + lp_minor_announce_version(), + lp_default_server_announce(), + string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH)); + r->out.info->info101 = info101; break; - case 100: - init_srv_info_100(&ctr->srv.sv100, 500, global_myname()); + } + case 100: { + struct srvsvc_NetSrvInfo100 *info100; + + info100 = TALLOC_P(p->mem_ctx, struct srvsvc_NetSrvInfo100); + if (!info100) { + return WERR_NOMEM; + } + + init_srvsvc_NetSrvInfo100(info100, + PLATFORM_ID_NT, + global_myname()); + r->out.info->info100 = info100; + break; + } default: status = WERR_UNKNOWN_LEVEL; break; } - /* set up the net server get info structure */ - init_srv_r_net_srv_get_info(r_u, q_u->switch_value, ctr, status); - - DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetSrvGetInfo: %d\n", __LINE__)); - return r_u->status; + return status; } /******************************************************************* -net server set info + _srvsvc_NetSrvSetInfo ********************************************************************/ -WERROR _srv_net_srv_set_info(pipes_struct *p, SRV_Q_NET_SRV_SET_INFO *q_u, SRV_R_NET_SRV_SET_INFO *r_u) +WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, + struct srvsvc_NetSrvSetInfo *r) { WERROR status = WERR_OK; - DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__)); /* Set up the net server set info structure. */ - init_srv_r_net_srv_set_info(r_u, 0x0, status); - - DEBUG(5,("srv_net_srv_set_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetSrvSetInfo: %d\n", __LINE__)); - return r_u->status; + return status; } /******************************************************************* @@ -1401,7 +1426,7 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES /* fail out now if you are not root or not a domain admin */ - if ((user.ut.uid != sec_initial_uid()) && + if ((user.ut.uid != sec_initial_uid()) && ( ! nt_token_check_domain_rid(p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS))) { goto done; @@ -1413,7 +1438,7 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES strequal(session_list[snum].remote_machine, machine)) { NTSTATUS ntstat; - + if (user.ut.uid != sec_initial_uid()) { not_root = True; become_root(); @@ -1422,11 +1447,11 @@ WERROR _srv_net_sess_del(pipes_struct *p, SRV_Q_NET_SESS_DEL *q_u, SRV_R_NET_SES ntstat = messaging_send(smbd_messaging_context(), session_list[snum].pid, MSG_SHUTDOWN, &data_blob_null); - + if (NT_STATUS_IS_OK(ntstat)) r_u->status = WERR_OK; - if (not_root) + if (not_root) unbecome_root(); } } @@ -1539,16 +1564,17 @@ char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname) } /******************************************************************* - Net share set info. Modify share details. + _srvsvc_NetShareSetInfo. Modify share details. ********************************************************************/ -WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, SRV_R_NET_SHARE_SET_INFO *r_u) +WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, + struct srvsvc_NetShareSetInfo *r) { struct current_user user; char *command = NULL; char *share_name = NULL; char *comment = NULL; - char *pathname = NULL; + const char *pathname = NULL; int type; int snum; int ret; @@ -1558,15 +1584,16 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S bool is_disk_op = False; int max_connections = 0; TALLOC_CTX *ctx = p->mem_ctx; + union srvsvc_NetShareInfo *info = r->in.info; - DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__)); - share_name = unistr2_to_ascii_talloc(ctx, &q_u->uni_share_name); + share_name = talloc_strdup(p->mem_ctx, r->in.share_name); if (!share_name) { - return WERR_NET_NAME_NOT_FOUND; + return WERR_NOMEM; } - r_u->parm_error = 0; + *r->out.parm_error = 0; if ( strequal(share_name,"IPC$") || ( lp_enable_asu_support() && strequal(share_name,"ADMIN$") ) @@ -1594,44 +1621,39 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S if ( user.ut.uid != sec_initial_uid() && !is_disk_op ) return WERR_ACCESS_DENIED; - switch (q_u->info_level) { + switch (r->in.level) { case 1: pathname = talloc_strdup(ctx, lp_pathname(snum)); - comment = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info2.info_2_str.uni_remark); - type = q_u->info.share.info2.info_2.type; + comment = talloc_strdup(ctx, info->info2->comment); + type = info->info2->type; psd = NULL; break; case 2: - comment = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info2.info_2_str.uni_remark); - pathname = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info2.info_2_str.uni_path); - type = q_u->info.share.info2.info_2.type; - max_connections = (q_u->info.share.info2.info_2.max_uses == 0xffffffff) ? 0 : q_u->info.share.info2.info_2.max_uses; + comment = talloc_strdup(ctx, info->info2->comment); + pathname = info->info2->path; + type = info->info2->type; + max_connections = (info->info2->max_users == 0xffffffff) ? + 0 : info->info2->max_users; psd = NULL; break; #if 0 /* not supported on set but here for completeness */ case 501: - unistr2_to_ascii(comment, &q_u->info.share.info501.info_501_str.uni_remark, sizeof(comment)); - type = q_u->info.share.info501.info_501.type; + comment = talloc_strdup(ctx, info->info501->comment); + type = info->info501->type; psd = NULL; break; #endif case 502: - comment = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info502.info_502_str.uni_remark); - pathname = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info502.info_502_str.uni_path); - type = q_u->info.share.info502.info_502.type; - psd = q_u->info.share.info502.info_502_str.sd; + comment = talloc_strdup(ctx, info->info502->comment); + pathname = info->info502->path; + type = info->info502->type; + psd = info->info502->sd; map_generic_share_sd_bits(psd); break; case 1004: pathname = talloc_strdup(ctx, lp_pathname(snum)); - comment = unistr2_to_ascii_talloc(ctx, - &q_u->info.share.info1004.info_1004_str.uni_remark); + comment = talloc_strdup(ctx, info->info1004->comment); type = STYPE_DISKTREE; break; case 1005: @@ -1639,12 +1661,12 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S user, so we must compare it to see if it's what is set in smb.conf, so that we can contine other ops like setting ACLs on a share */ - if (((q_u->info.share.info1005.share_info_flags & + if (((info->info1005->dfs_flags & SHARE_1005_CSC_POLICY_MASK) >> SHARE_1005_CSC_POLICY_SHIFT) == lp_csc_policy(snum)) return WERR_OK; else { - DEBUG(3, ("_srv_net_share_set_info: client is trying to change csc policy from the network; must be done with smb.conf\n")); + DEBUG(3, ("_srvsvc_NetShareSetInfo: client is trying to change csc policy from the network; must be done with smb.conf\n")); return WERR_ACCESS_DENIED; } case 1006: @@ -1653,12 +1675,13 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S case 1501: pathname = talloc_strdup(ctx, lp_pathname(snum)); comment = talloc_strdup(ctx, lp_comment(snum)); - psd = q_u->info.share.info1501.sdb->sd; + psd = info->info1501->sd; map_generic_share_sd_bits(psd); type = STYPE_DISKTREE; break; default: - DEBUG(5,("_srv_net_share_set_info: unsupported switch value %d\n", q_u->info_level)); + DEBUG(5,("_srvsvc_NetShareSetInfo: unsupported switch value %d\n", + r->in.level)); return WERR_UNKNOWN_LEVEL; } @@ -1677,7 +1700,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S string_replace(comment, '"', ' '); } - DEBUG(10,("_srv_net_share_set_info: change share command = %s\n", + DEBUG(10,("_srvsvc_NetShareSetInfo: change share command = %s\n", lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" )); /* Only call modify function if something changed. */ @@ -1685,7 +1708,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) || (lp_max_connections(snum) != max_connections)) { if (!lp_change_share_cmd() || !*lp_change_share_cmd()) { - DEBUG(10,("_srv_net_share_set_info: No change share command\n")); + DEBUG(10,("_srvsvc_NetShareSetInfo: No change share command\n")); return WERR_ACCESS_DENIED; } @@ -1701,7 +1724,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S return WERR_NOMEM; } - DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command )); + DEBUG(10,("_srvsvc_NetShareSetInfo: Running [%s]\n", command )); /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/ @@ -1720,14 +1743,16 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S /********* END SeDiskOperatorPrivilege BLOCK *********/ - DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret )); + DEBUG(3,("_srvsvc_NetShareSetInfo: Running [%s] returned (%d)\n", + command, ret )); TALLOC_FREE(command); if ( ret != 0 ) return WERR_ACCESS_DENIED; } else { - DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name )); + DEBUG(10,("_srvsvc_NetShareSetInfo: No change to share name (%s)\n", + share_name )); } /* Replace SD if changed. */ @@ -1739,12 +1764,12 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S if (old_sd && !sec_desc_equal(old_sd, psd)) { if (!set_share_security(share_name, psd)) - DEBUG(0,("_srv_net_share_set_info: Failed to change security info in share %s.\n", + DEBUG(0,("_srvsvc_NetShareSetInfo: Failed to change security info in share %s.\n", share_name )); } } - DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetShareSetInfo: %d\n", __LINE__)); return WERR_OK; } @@ -1819,7 +1844,7 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S map_generic_share_sd_bits(psd); break; - /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */ + /* none of the following contain share names. NetShareAdd does not have a separate parameter for the share name */ case 1004: case 1005: @@ -2029,12 +2054,13 @@ WERROR _srv_net_share_del_sticky(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_ } /******************************************************************* -time of day + _srvsvc_NetRemoteTOD ********************************************************************/ -WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET_REMOTE_TOD *r_u) +WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, + struct srvsvc_NetRemoteTOD *r) { - TIME_OF_DAY_INFO *tod; + struct srvsvc_NetRemoteTODInfo *tod; struct tm *t; time_t unixdate = time(NULL); @@ -2043,37 +2069,35 @@ WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET uint32 zone = get_time_zone(unixdate)/60; - DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__)); - if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, TIME_OF_DAY_INFO)) ) + if ( !(tod = TALLOC_ZERO_P(p->mem_ctx, struct srvsvc_NetRemoteTODInfo)) ) return WERR_NOMEM; - r_u->tod = tod; - r_u->ptr_srv_tod = 0x1; - r_u->status = WERR_OK; + *r->out.info = tod; - DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__)); t = gmtime(&unixdate); /* set up the */ - init_time_of_day_info(tod, - unixdate, - 0, - t->tm_hour, - t->tm_min, - t->tm_sec, - 0, - zone, - 10000, - t->tm_mday, - t->tm_mon + 1, - 1900+t->tm_year, - t->tm_wday); - - DEBUG(5,("_srv_net_remote_tod: %d\n", __LINE__)); + init_srvsvc_NetRemoteTODInfo(tod, + unixdate, + 0, + t->tm_hour, + t->tm_min, + t->tm_sec, + 0, + zone, + 10000, + t->tm_mday, + t->tm_mon + 1, + 1900+t->tm_year, + t->tm_wday); + + DEBUG(5,("_srvsvc_NetRemoteTOD: %d\n", __LINE__)); - return r_u->status; + return WERR_OK; } /*********************************************************************************** @@ -2362,7 +2386,7 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D r_u->total_entries = init_server_disk_enum(&resume); - r_u->disk_enum_ctr.unknown = 0; + r_u->disk_enum_ctr.unknown = 0; if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) { return WERR_NOMEM; @@ -2378,7 +2402,7 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D /*copy disk name into a unicode string*/ - init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name); + init_unistr3(&r_u->disk_enum_ctr.disk_info[i].disk_name, disk_name); } /* add a terminating null string. Is this there if there is more data to come? */ @@ -2524,12 +2548,6 @@ WERROR _srvsvc_NetShareGetInfo(pipes_struct *p, struct srvsvc_NetShareGetInfo *r return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NetShareSetInfo(pipes_struct *p, struct srvsvc_NetShareSetInfo *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - WERROR _srvsvc_NetShareDel(pipes_struct *p, struct srvsvc_NetShareDel *r) { p->rng_fault_state = True; @@ -2548,18 +2566,6 @@ WERROR _srvsvc_NetShareCheck(pipes_struct *p, struct srvsvc_NetShareCheck *r) return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NetSrvGetInfo(pipes_struct *p, struct srvsvc_NetSrvGetInfo *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _srvsvc_NetSrvSetInfo(pipes_struct *p, struct srvsvc_NetSrvSetInfo *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - WERROR _srvsvc_NetDiskEnum(pipes_struct *p, struct srvsvc_NetDiskEnum *r) { p->rng_fault_state = True; @@ -2590,12 +2596,6 @@ WERROR _srvsvc_NetTransportDel(pipes_struct *p, struct srvsvc_NetTransportDel *r return WERR_NOT_SUPPORTED; } -WERROR _srvsvc_NetRemoteTOD(pipes_struct *p, struct srvsvc_NetRemoteTOD *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - WERROR _srvsvc_NetSetServiceBits(pipes_struct *p, struct srvsvc_NetSetServiceBits *r) { p->rng_fault_state = True; diff --git a/source3/rpc_server/srv_svcctl.c b/source3/rpc_server/srv_svcctl.c index ce81a24202..5e125145d6 100644 --- a/source3/rpc_server/srv_svcctl.c +++ b/source3/rpc_server/srv_svcctl.c @@ -53,23 +53,7 @@ static bool api_svcctl_close_service(pipes_struct *p) static bool api_svcctl_open_scmanager(pipes_struct *p) { - SVCCTL_Q_OPEN_SCMANAGER q_u; - SVCCTL_R_OPEN_SCMANAGER r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_open_scmanager("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_open_scmanager(p, &q_u, &r_u); - - if(!svcctl_io_r_open_scmanager("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_OPENSCMANAGERW); } /******************************************************************* @@ -77,23 +61,7 @@ static bool api_svcctl_open_scmanager(pipes_struct *p) static bool api_svcctl_open_service(pipes_struct *p) { - SVCCTL_Q_OPEN_SERVICE q_u; - SVCCTL_R_OPEN_SERVICE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_open_service("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_open_service(p, &q_u, &r_u); - - if(!svcctl_io_r_open_service("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_OPENSERVICEW); } /******************************************************************* @@ -101,23 +69,7 @@ static bool api_svcctl_open_service(pipes_struct *p) static bool api_svcctl_get_display_name(pipes_struct *p) { - SVCCTL_Q_GET_DISPLAY_NAME q_u; - SVCCTL_R_GET_DISPLAY_NAME r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_get_display_name("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_get_display_name(p, &q_u, &r_u); - - if(!svcctl_io_r_get_display_name("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_GETSERVICEDISPLAYNAMEW); } /******************************************************************* @@ -125,23 +77,7 @@ static bool api_svcctl_get_display_name(pipes_struct *p) static bool api_svcctl_query_status(pipes_struct *p) { - SVCCTL_Q_QUERY_STATUS q_u; - SVCCTL_R_QUERY_STATUS r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_query_status("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_query_status(p, &q_u, &r_u); - - if(!svcctl_io_r_query_status("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_QUERYSERVICESTATUS); } /******************************************************************* @@ -219,23 +155,7 @@ static bool api_svcctl_enum_dependent_services(pipes_struct *p) static bool api_svcctl_start_service(pipes_struct *p) { - SVCCTL_Q_START_SERVICE q_u; - SVCCTL_R_START_SERVICE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_start_service("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_start_service(p, &q_u, &r_u); - - if(!svcctl_io_r_start_service("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_STARTSERVICEW); } /******************************************************************* @@ -243,23 +163,7 @@ static bool api_svcctl_start_service(pipes_struct *p) static bool api_svcctl_control_service(pipes_struct *p) { - SVCCTL_Q_CONTROL_SERVICE q_u; - SVCCTL_R_CONTROL_SERVICE r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_control_service("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_control_service(p, &q_u, &r_u); - - if(!svcctl_io_r_control_service("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_CONTROLSERVICE); } /******************************************************************* @@ -315,23 +219,7 @@ static bool api_svcctl_query_service_config2(pipes_struct *p) static bool api_svcctl_lock_service_db(pipes_struct *p) { - SVCCTL_Q_LOCK_SERVICE_DB q_u; - SVCCTL_R_LOCK_SERVICE_DB r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_lock_service_db("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_lock_service_db(p, &q_u, &r_u); - - if(!svcctl_io_r_lock_service_db("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_LOCKSERVICEDATABASE); } @@ -340,23 +228,7 @@ static bool api_svcctl_lock_service_db(pipes_struct *p) static bool api_svcctl_unlock_service_db(pipes_struct *p) { - SVCCTL_Q_UNLOCK_SERVICE_DB q_u; - SVCCTL_R_UNLOCK_SERVICE_DB r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_unlock_service_db("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_unlock_service_db(p, &q_u, &r_u); - - if(!svcctl_io_r_unlock_service_db("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_UNLOCKSERVICEDATABASE); } /******************************************************************* @@ -364,23 +236,7 @@ static bool api_svcctl_unlock_service_db(pipes_struct *p) static bool api_svcctl_query_security_sec(pipes_struct *p) { - SVCCTL_Q_QUERY_SERVICE_SEC q_u; - SVCCTL_R_QUERY_SERVICE_SEC r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_query_service_sec("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_query_service_sec(p, &q_u, &r_u); - - if(!svcctl_io_r_query_service_sec("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_QUERYSERVICEOBJECTSECURITY); } /******************************************************************* @@ -388,23 +244,7 @@ static bool api_svcctl_query_security_sec(pipes_struct *p) static bool api_svcctl_set_security_sec(pipes_struct *p) { - SVCCTL_Q_SET_SERVICE_SEC q_u; - SVCCTL_R_SET_SERVICE_SEC r_u; - prs_struct *data = &p->in_data.data; - prs_struct *rdata = &p->out_data.rdata; - - ZERO_STRUCT(q_u); - ZERO_STRUCT(r_u); - - if(!svcctl_io_q_set_service_sec("", &q_u, data, 0)) - return False; - - r_u.status = _svcctl_set_service_sec(p, &q_u, &r_u); - - if(!svcctl_io_r_set_service_sec("", &r_u, rdata, 0)) - return False; - - return True; + return proxy_svcctl_call(p, NDR_SVCCTL_SETSERVICEOBJECTSECURITY); } diff --git a/source3/rpc_server/srv_svcctl_nt.c b/source3/rpc_server/srv_svcctl_nt.c index ac45d8bf75..73d09b1bbb 100644 --- a/source3/rpc_server/srv_svcctl_nt.c +++ b/source3/rpc_server/srv_svcctl_nt.c @@ -1,22 +1,22 @@ -/* +/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * * Copyright (C) Marcin Krzysztof Porwit 2005. - * + * * Largely Rewritten (Again) by: * Copyright (C) Gerald (Jerry) Carter 2005. - * + * * 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/>. */ @@ -63,42 +63,42 @@ bool init_service_op_table( void ) const char **service_list = lp_svcctl_list(); int num_services = SVCCTL_NUM_INTERNAL_SERVICES + str_list_count( service_list ); int i; - + if ( !(svcctl_ops = TALLOC_ARRAY( NULL, struct service_control_op, num_services+1)) ) { DEBUG(0,("init_service_op_table: talloc() failed!\n")); return False; } /* services listed in smb.conf get the rc.init interface */ - + for ( i=0; service_list && service_list[i]; i++ ) { svcctl_ops[i].name = talloc_strdup( svcctl_ops, service_list[i] ); svcctl_ops[i].ops = &rcinit_svc_ops; } - + /* add builtin services */ - + svcctl_ops[i].name = talloc_strdup( svcctl_ops, "Spooler" ); svcctl_ops[i].ops = &spoolss_svc_ops; i++; - + svcctl_ops[i].name = talloc_strdup( svcctl_ops, "NETLOGON" ); svcctl_ops[i].ops = &netlogon_svc_ops; i++; - + svcctl_ops[i].name = talloc_strdup( svcctl_ops, "RemoteRegistry" ); svcctl_ops[i].ops = &winreg_svc_ops; i++; - + svcctl_ops[i].name = talloc_strdup( svcctl_ops, "WINS" ); svcctl_ops[i].ops = &wins_svc_ops; i++; - + /* NULL terminate the array */ - + svcctl_ops[i].name = NULL; svcctl_ops[i].ops = NULL; - + return True; } @@ -119,7 +119,7 @@ static struct service_control_op* find_service_by_name( const char *name ) /******************************************************************** ********************************************************************/ -static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, +static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, uint32 access_desired, uint32 *access_granted ) { NTSTATUS result; @@ -128,7 +128,7 @@ static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, DEBUG(5,("svcctl_access_check: using root's token\n")); token = get_root_nt_token(); } - + se_access_check( sec_desc, token, access_desired, access_granted, &result ); return result; @@ -139,7 +139,7 @@ static NTSTATUS svcctl_access_check( SEC_DESC *sec_desc, NT_USER_TOKEN *token, static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx ) { - SEC_ACE ace[2]; + SEC_ACE ace[2]; SEC_ACCESS mask; size_t i = 0; SEC_DESC *sd; @@ -147,18 +147,18 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx ) size_t sd_size; /* basic access for Everyone */ - + init_sec_access(&mask, SC_MANAGER_READ_ACCESS ); init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - + /* Full Access 'BUILTIN\Administrators' */ - + init_sec_access(&mask,SC_MANAGER_ALL_ACCESS ); init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - + + /* create the security descriptor */ - + if ( !(acl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) ) return NULL; @@ -173,7 +173,7 @@ static SEC_DESC* construct_scm_sd( TALLOC_CTX *ctx ) /****************************************************************** free() function for REGISTRY_KEY *****************************************************************/ - + static void free_service_handle_info(void *ptr) { TALLOC_FREE( ptr ); @@ -197,21 +197,21 @@ static SERVICE_INFO *find_service_info_by_hnd(pipes_struct *p, POLICY_HND *hnd) /****************************************************************** *****************************************************************/ - + static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, uint32 type, const char *service, uint32 access_granted ) { SERVICE_INFO *info = NULL; WERROR result = WERR_OK; struct service_control_op *s_op; - + if ( !(info = TALLOC_ZERO_P( NULL, SERVICE_INFO )) ) return WERR_NOMEM; /* the Service Manager has a NULL name */ - + info->type = SVC_HANDLE_IS_SCM; - + switch ( type ) { case SVC_HANDLE_IS_SCM: info->type = SVC_HANDLE_IS_SCM; @@ -220,17 +220,17 @@ static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, u case SVC_HANDLE_IS_DBLOCK: info->type = SVC_HANDLE_IS_DBLOCK; break; - + case SVC_HANDLE_IS_SERVICE: info->type = SVC_HANDLE_IS_SERVICE; - + /* lookup the SERVICE_CONTROL_OPS */ if ( !(s_op = find_service_by_name( service )) ) { result = WERR_NO_SUCH_SERVICE; goto done; } - + info->ops = s_op->ops; if ( !(info->name = talloc_strdup( info, s_op->name )) ) { @@ -244,15 +244,15 @@ static WERROR create_open_service_handle( pipes_struct *p, POLICY_HND *handle, u goto done; } - info->access_granted = access_granted; - + info->access_granted = access_granted; + /* store the SERVICE_INFO and create an open handle */ - + if ( !create_policy_hnd( p, handle, free_service_handle_info, info ) ) { result = WERR_ACCESS_DENIED; goto done; } - + done: if ( !W_ERROR_IS_OK(result) ) free_service_handle_info( info ); @@ -263,62 +263,61 @@ done: /******************************************************************** ********************************************************************/ -WERROR _svcctl_open_scmanager(pipes_struct *p, SVCCTL_Q_OPEN_SCMANAGER *q_u, SVCCTL_R_OPEN_SCMANAGER *r_u) +WERROR _svcctl_OpenSCManagerW(pipes_struct *p, + struct svcctl_OpenSCManagerW *r) { SEC_DESC *sec_desc; uint32 access_granted = 0; NTSTATUS status; - + /* perform access checks */ - + if ( !(sec_desc = construct_scm_sd( p->mem_ctx )) ) return WERR_NOMEM; - - se_map_generic( &q_u->access, &scm_generic_map ); - status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted ); + + se_map_generic( &r->in.access_mask, &scm_generic_map ); + status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, r->in.access_mask, &access_granted ); if ( !NT_STATUS_IS_OK(status) ) return ntstatus_to_werror( status ); - - return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SCM, NULL, access_granted ); + + return create_open_service_handle( p, r->out.handle, SVC_HANDLE_IS_SCM, NULL, access_granted ); } /******************************************************************** + _svcctl_OpenServiceW ********************************************************************/ -WERROR _svcctl_open_service(pipes_struct *p, SVCCTL_Q_OPEN_SERVICE *q_u, SVCCTL_R_OPEN_SERVICE *r_u) +WERROR _svcctl_OpenServiceW(pipes_struct *p, + struct svcctl_OpenServiceW *r) { SEC_DESC *sec_desc; uint32 access_granted = 0; NTSTATUS status; - char *service = NULL; - size_t ret = rpcstr_pull_talloc(p->mem_ctx, - &service, - q_u->servicename.buffer, - q_u->servicename.uni_str_len*2, - 0); - - if (ret == (size_t)-1 || !service) { + const char *service = NULL; + + service = r->in.ServiceName; + if (!service) { return WERR_NOMEM; } - DEBUG(5, ("_svcctl_open_service: Attempting to open Service [%s], \n", service)); + DEBUG(5, ("_svcctl_OpenServiceW: Attempting to open Service [%s], \n", service)); /* based on my tests you can open a service if you have a valid scm handle */ - if ( !find_service_info_by_hnd( p, &q_u->handle ) ) + if ( !find_service_info_by_hnd( p, r->in.scmanager_handle) ) return WERR_BADFID; - /* perform access checks. Use the root token in order to ensure that we + /* perform access checks. Use the root token in order to ensure that we retrieve the security descriptor */ if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, service, get_root_nt_token() )) ) return WERR_NOMEM; - se_map_generic( &q_u->access, &svc_generic_map ); - status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, q_u->access, &access_granted ); + se_map_generic( &r->in.access_mask, &svc_generic_map ); + status = svcctl_access_check( sec_desc, p->pipe_user.nt_user_token, r->in.access_mask, &access_granted ); if ( !NT_STATUS_IS_OK(status) ) return ntstatus_to_werror( status ); - return create_open_service_handle( p, &r_u->handle, SVC_HANDLE_IS_SERVICE, service, access_granted ); + return create_open_service_handle( p, r->out.handle, SVC_HANDLE_IS_SERVICE, service, access_granted ); } /******************************************************************** @@ -329,49 +328,58 @@ WERROR _svcctl_CloseServiceHandle(pipes_struct *p, struct svcctl_CloseServiceHan if ( !close_policy_hnd( p, r->in.handle ) ) return WERR_BADFID; - return WERR_OK; + return WERR_OK; } /******************************************************************** + _svcctl_GetServiceDisplayNameW ********************************************************************/ -WERROR _svcctl_get_display_name(pipes_struct *p, SVCCTL_Q_GET_DISPLAY_NAME *q_u, SVCCTL_R_GET_DISPLAY_NAME *r_u) +WERROR _svcctl_GetServiceDisplayNameW(pipes_struct *p, + struct svcctl_GetServiceDisplayNameW *r) { - fstring service; + const char *service; const char *display_name; - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* can only use an SCM handle here */ - + if ( !info || (info->type != SVC_HANDLE_IS_SCM) ) return WERR_BADFID; - - rpcstr_pull(service, q_u->servicename.buffer, sizeof(service), q_u->servicename.uni_str_len*2, 0); - + + service = r->in.service_name; + display_name = svcctl_lookup_dispname(p->mem_ctx, service, p->pipe_user.nt_user_token ); - init_svcctl_r_get_display_name( r_u, display_name ? display_name : ""); + if (!display_name) { + display_name = ""; + } + + *r->out.display_name = display_name; + *r->out.display_name_length = strlen(display_name); return WERR_OK; } /******************************************************************** + _svcctl_QueryServiceStatus ********************************************************************/ -WERROR _svcctl_query_status(pipes_struct *p, SVCCTL_Q_QUERY_STATUS *q_u, SVCCTL_R_QUERY_STATUS *r_u) +WERROR _svcctl_QueryServiceStatus(pipes_struct *p, + struct svcctl_QueryServiceStatus *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; - + if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) ) return WERR_ACCESS_DENIED; - + /* try the service specific status call */ - return info->ops->service_status( info->name, &r_u->svc_status ); + return info->ops->service_status( info->name, r->out.service_status ); } /******************************************************************** @@ -383,7 +391,7 @@ static int enumerate_status( TALLOC_CTX *ctx, ENUM_SERVICES_STATUS **status, NT_ int i; ENUM_SERVICES_STATUS *st; const char *display_name; - + /* just count */ while ( svcctl_ops[num_services].name ) num_services++; @@ -392,16 +400,16 @@ static int enumerate_status( TALLOC_CTX *ctx, ENUM_SERVICES_STATUS **status, NT_ DEBUG(0,("enumerate_status: talloc() failed!\n")); return -1; } - + for ( i=0; i<num_services; i++ ) { init_unistr( &st[i].servicename, svcctl_ops[i].name ); - + display_name = svcctl_lookup_dispname(ctx, svcctl_ops[i].name, token ); init_unistr( &st[i].displayname, display_name ? display_name : ""); - + svcctl_ops[i].ops->service_status( svcctl_ops[i].name, &st[i].status ); } - + *status = st; return num_services; @@ -419,12 +427,12 @@ WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STAT WERROR result = WERR_OK; SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); NT_USER_TOKEN *token = p->pipe_user.nt_user_token; - + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SCM) ) return WERR_BADFID; - + if ( !(info->access_granted & SC_RIGHT_MGR_ENUMERATE_SERVICE) ) { return WERR_ACCESS_DENIED; } @@ -464,51 +472,57 @@ WERROR _svcctl_enum_services_status(pipes_struct *p, SVCCTL_Q_ENUM_SERVICES_STAT } /******************************************************************** + _svcctl_StartServiceW ********************************************************************/ -WERROR _svcctl_start_service(pipes_struct *p, SVCCTL_Q_START_SERVICE *q_u, SVCCTL_R_START_SERVICE *r_u) +WERROR _svcctl_StartServiceW(pipes_struct *p, + struct svcctl_StartServiceW *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) return WERR_BADFID; - + if ( !(info->access_granted & SC_RIGHT_SVC_START) ) return WERR_ACCESS_DENIED; - + return info->ops->start_service( info->name ); } /******************************************************************** + _svcctl_ControlService ********************************************************************/ -WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, SVCCTL_R_CONTROL_SERVICE *r_u) +WERROR _svcctl_ControlService(pipes_struct *p, + struct svcctl_ControlService *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* perform access checks */ - + if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) - return WERR_BADFID; - - switch ( q_u->control ) { + return WERR_BADFID; + + switch ( r->in.control ) { case SVCCTL_CONTROL_STOP: if ( !(info->access_granted & SC_RIGHT_SVC_STOP) ) return WERR_ACCESS_DENIED; - - return info->ops->stop_service( info->name, &r_u->svc_status ); - + + return info->ops->stop_service( info->name, + r->out.service_status ); + case SVCCTL_CONTROL_INTERROGATE: if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) ) return WERR_ACCESS_DENIED; - - return info->ops->service_status( info->name, &r_u->svc_status ); + + return info->ops->service_status( info->name, + r->out.service_status ); } - + /* default control action */ - + return WERR_ACCESS_DENIED; } @@ -518,22 +532,22 @@ WERROR _svcctl_control_service(pipes_struct *p, SVCCTL_Q_CONTROL_SERVICE *q_u, S WERROR _svcctl_enum_dependent_services( pipes_struct *p, SVCCTL_Q_ENUM_DEPENDENT_SERVICES *q_u, SVCCTL_R_ENUM_DEPENDENT_SERVICES *r_u ) { SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) - return WERR_BADFID; - + return WERR_BADFID; + if ( !(info->access_granted & SC_RIGHT_SVC_ENUMERATE_DEPENDENTS) ) return WERR_ACCESS_DENIED; - - /* we have to set the outgoing buffer size to the same as the + + /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure */ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); - + r_u->needed = q_u->buffer_size; - + /* no dependent services...basically a stub function */ r_u->returned = 0; @@ -547,21 +561,21 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_ { SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); uint32 buffer_size; - + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) - return WERR_BADFID; - + return WERR_BADFID; + if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_STATUS) ) return WERR_ACCESS_DENIED; - /* we have to set the outgoing buffer size to the same as the + /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure) */ rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); r_u->needed = q_u->buffer_size; - + switch ( q_u->level ) { case SVC_STATUS_PROCESS_INFO: { @@ -576,18 +590,18 @@ WERROR _svcctl_query_service_status_ex( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_ buffer_size = sizeof(SERVICE_STATUS_PROCESS); break; } - + default: - return WERR_UNKNOWN_LEVEL; + return WERR_UNKNOWN_LEVEL; } - + buffer_size += buffer_size % 4; r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size; - if (buffer_size > q_u->buffer_size ) + if (buffer_size > q_u->buffer_size ) return WERR_MORE_DATA; - + return WERR_OK; } @@ -600,12 +614,12 @@ static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG REGISTRY_VALUE *val; /* retrieve the registry values for this service */ - + if ( !(values = svcctl_fetch_regvalues( name, token )) ) return WERR_REG_CORRUPT; - + /* now fill in the individual values */ - + config->displayname = TALLOC_ZERO_P( ctx, UNISTR2 ); if ( (val = regval_ctr_getvalue( values, "DisplayName" )) != NULL ) init_unistr2( config->displayname, regval_sz( val ), UNI_STR_TERMINATE ); @@ -613,23 +627,23 @@ static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG init_unistr2( config->displayname, name, UNI_STR_TERMINATE ); if ( (val = regval_ctr_getvalue( values, "ObjectName" )) != NULL ) { - config->startname = TALLOC_ZERO_P( ctx, UNISTR2 ); + config->startname = TALLOC_ZERO_P( ctx, UNISTR2 ); init_unistr2( config->startname, regval_sz( val ), UNI_STR_TERMINATE ); } - + if ( (val = regval_ctr_getvalue( values, "ImagePath" )) != NULL ) { - config->executablepath = TALLOC_ZERO_P( ctx, UNISTR2 ); + config->executablepath = TALLOC_ZERO_P( ctx, UNISTR2 ); init_unistr2( config->executablepath, regval_sz( val ), UNI_STR_TERMINATE ); } /* a few hard coded values */ /* loadordergroup and dependencies are empty */ - + config->tag_id = 0x00000000; /* unassigned loadorder group */ config->service_type = SVCCTL_WIN32_OWN_PROC; config->error_control = SVCCTL_SVC_ERROR_NORMAL; - /* set the start type. NetLogon and WINS are disabled to prevent + /* set the start type. NetLogon and WINS are disabled to prevent the client from showing the "Start" button (if of course the services are not running */ @@ -639,7 +653,7 @@ static WERROR fill_svc_config( TALLOC_CTX *ctx, const char *name, SERVICE_CONFIG config->start_type = SVCCTL_DISABLED; else config->start_type = SVCCTL_DEMAND_START; - + TALLOC_FREE( values ); @@ -654,24 +668,24 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); uint32 buffer_size; WERROR wresult; - + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SERVICE) ) - return WERR_BADFID; - + return WERR_BADFID; + if ( !(info->access_granted & SC_RIGHT_SVC_QUERY_CONFIG) ) return WERR_ACCESS_DENIED; - /* we have to set the outgoing buffer size to the same as the + /* we have to set the outgoing buffer size to the same as the incoming buffer size (even in the case of failure */ r_u->needed = q_u->buffer_size; - + wresult = fill_svc_config( p->mem_ctx, info->name, &r_u->config, p->pipe_user.nt_user_token ); if ( !W_ERROR_IS_OK(wresult) ) return wresult; - + buffer_size = svcctl_sizeof_service_config( &r_u->config ); r_u->needed = (buffer_size > q_u->buffer_size) ? buffer_size : q_u->buffer_size; @@ -679,7 +693,7 @@ WERROR _svcctl_query_service_config( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CON ZERO_STRUCTP( &r_u->config ); return WERR_INSUFFICIENT_BUFFER; } - + return WERR_OK; } @@ -750,53 +764,61 @@ WERROR _svcctl_query_service_config2( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_CO } /******************************************************************** + _svcctl_LockServiceDatabase ********************************************************************/ -WERROR _svcctl_lock_service_db( pipes_struct *p, SVCCTL_Q_LOCK_SERVICE_DB *q_u, SVCCTL_R_LOCK_SERVICE_DB *r_u ) +WERROR _svcctl_LockServiceDatabase(pipes_struct *p, + struct svcctl_LockServiceDatabase *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); - + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); + /* perform access checks */ if ( !info || (info->type != SVC_HANDLE_IS_SCM) ) - return WERR_BADFID; - + return WERR_BADFID; + if ( !(info->access_granted & SC_RIGHT_MGR_LOCK) ) return WERR_ACCESS_DENIED; /* Just open a handle. Doesn't actually lock anything */ - - return create_open_service_handle( p, &r_u->h_lock, SVC_HANDLE_IS_DBLOCK, NULL, 0 ); -; + + return create_open_service_handle( p, r->out.lock, SVC_HANDLE_IS_DBLOCK, NULL, 0 ); } /******************************************************************** + _svcctl_UnlockServiceDatabase ********************************************************************/ -WERROR _svcctl_unlock_service_db( pipes_struct *p, SVCCTL_Q_UNLOCK_SERVICE_DB *q_u, SVCCTL_R_UNLOCK_SERVICE_DB *r_u ) +WERROR _svcctl_UnlockServiceDatabase(pipes_struct *p, + struct svcctl_UnlockServiceDatabase *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->h_lock ); + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.lock ); if ( !info || (info->type != SVC_HANDLE_IS_DBLOCK) ) - return WERR_BADFID; - - return close_policy_hnd( p, &q_u->h_lock) ? WERR_OK : WERR_BADFID; + return WERR_BADFID; + + return close_policy_hnd( p, r->out.lock) ? WERR_OK : WERR_BADFID; } /******************************************************************** + _svcctl_QueryServiceObjectSecurity ********************************************************************/ -WERROR _svcctl_query_service_sec( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_SEC *q_u, SVCCTL_R_QUERY_SERVICE_SEC *r_u ) +WERROR _svcctl_QueryServiceObjectSecurity(pipes_struct *p, + struct svcctl_QueryServiceObjectSecurity *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); SEC_DESC *sec_desc; + NTSTATUS status; + uint8_t *buffer = NULL; + size_t len = 0; /* only support the SCM and individual services */ if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) ) - return WERR_BADFID; + return WERR_BADFID; /* check access reights (according to MSDN) */ @@ -805,7 +827,7 @@ WERROR _svcctl_query_service_sec( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_SEC *q /* TODO: handle something besides DACL_SECURITY_INFORMATION */ - if ( (q_u->security_flags & DACL_SECURITY_INFORMATION) != DACL_SECURITY_INFORMATION ) + if ( (r->in.security_flags & DACL_SECURITY_INFORMATION) != DACL_SECURITY_INFORMATION ) return WERR_INVALID_PARAM; /* lookup the security descriptor and marshall it up for a reply */ @@ -813,29 +835,35 @@ WERROR _svcctl_query_service_sec( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_SEC *q if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, info->name, get_root_nt_token() )) ) return WERR_NOMEM; - r_u->needed = ndr_size_security_descriptor( sec_desc, 0 ); + *r->out.needed = ndr_size_security_descriptor( sec_desc, 0 ); - if ( r_u->needed > q_u->buffer_size ) { - ZERO_STRUCTP( &r_u->buffer ); + if ( *r->out.needed > r->in.buffer_size ) { + ZERO_STRUCTP( &r->out.buffer ); return WERR_INSUFFICIENT_BUFFER; } - rpcbuf_init( &r_u->buffer, q_u->buffer_size, p->mem_ctx ); + status = marshall_sec_desc(p->mem_ctx, sec_desc, &buffer, &len); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + *r->out.needed = len; + r->out.buffer = buffer; - if ( !sec_io_desc("", &sec_desc, &r_u->buffer.prs, 0 ) ) - return WERR_NOMEM; - return WERR_OK; } /******************************************************************** + _svcctl_SetServiceObjectSecurity ********************************************************************/ -WERROR _svcctl_set_service_sec( pipes_struct *p, SVCCTL_Q_SET_SERVICE_SEC *q_u, SVCCTL_R_SET_SERVICE_SEC *r_u ) +WERROR _svcctl_SetServiceObjectSecurity(pipes_struct *p, + struct svcctl_SetServiceObjectSecurity *r) { - SERVICE_INFO *info = find_service_info_by_hnd( p, &q_u->handle ); + SERVICE_INFO *info = find_service_info_by_hnd( p, r->in.handle ); SEC_DESC *sec_desc = NULL; uint32 required_access; + NTSTATUS status; if ( !info || !(info->type & (SVC_HANDLE_IS_SERVICE|SVC_HANDLE_IS_SCM)) ) return WERR_BADFID; @@ -843,298 +871,242 @@ WERROR _svcctl_set_service_sec( pipes_struct *p, SVCCTL_Q_SET_SERVICE_SEC *q_u, /* can't set the security de4scriptor on the ServiceControlManager */ if ( info->type == SVC_HANDLE_IS_SCM ) - return WERR_ACCESS_DENIED; + return WERR_ACCESS_DENIED; /* check the access on the open handle */ - - switch ( q_u->security_flags ) { + + switch ( r->in.security_flags ) { case DACL_SECURITY_INFORMATION: required_access = STD_RIGHT_WRITE_DAC_ACCESS; break; - + case OWNER_SECURITY_INFORMATION: case GROUP_SECURITY_INFORMATION: required_access = STD_RIGHT_WRITE_OWNER_ACCESS; break; - + case SACL_SECURITY_INFORMATION: return WERR_INVALID_PARAM; default: return WERR_INVALID_PARAM; } - + if ( !(info->access_granted & required_access) ) return WERR_ACCESS_DENIED; - + /* read the security descfriptor */ - - if ( !sec_io_desc("", &sec_desc, &q_u->buffer.prs, 0 ) ) - return WERR_NOMEM; - + + status = unmarshall_sec_desc(p->mem_ctx, + r->in.buffer, r->in.buffer_size, + &sec_desc); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + /* store the new SD */ - if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc, p->pipe_user.nt_user_token ) ) + if ( !svcctl_set_secdesc( p->mem_ctx, info->name, sec_desc, p->pipe_user.nt_user_token ) ) return WERR_ACCESS_DENIED; return WERR_OK; } -WERROR _svcctl_ControlService(pipes_struct *p, struct svcctl_ControlService *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - WERROR _svcctl_DeleteService(pipes_struct *p, struct svcctl_DeleteService *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_LockServiceDatabase(pipes_struct *p, struct svcctl_LockServiceDatabase *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_QueryServiceObjectSecurity(pipes_struct *p, struct svcctl_QueryServiceObjectSecurity *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_SetServiceObjectSecurity(pipes_struct *p, struct svcctl_SetServiceObjectSecurity *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_QueryServiceStatus(pipes_struct *p, struct svcctl_QueryServiceStatus *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_SetServiceStatus(pipes_struct *p, struct svcctl_SetServiceStatus *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_UnlockServiceDatabase(pipes_struct *p, struct svcctl_UnlockServiceDatabase *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_NotifyBootConfigStatus(pipes_struct *p, struct svcctl_NotifyBootConfigStatus *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_SCSetServiceBitsW(pipes_struct *p, struct svcctl_SCSetServiceBitsW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_ChangeServiceConfigW(pipes_struct *p, struct svcctl_ChangeServiceConfigW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_CreateServiceW(pipes_struct *p, struct svcctl_CreateServiceW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumDependentServicesW(pipes_struct *p, struct svcctl_EnumDependentServicesW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumServicesStatusW(pipes_struct *p, struct svcctl_EnumServicesStatusW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_OpenSCManagerW(pipes_struct *p, struct svcctl_OpenSCManagerW *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_OpenServiceW(pipes_struct *p, struct svcctl_OpenServiceW *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceConfigW(pipes_struct *p, struct svcctl_QueryServiceConfigW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceLockStatusW(pipes_struct *p, struct svcctl_QueryServiceLockStatusW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_StartServiceW(pipes_struct *p, struct svcctl_StartServiceW *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; -} - -WERROR _svcctl_GetServiceDisplayNameW(pipes_struct *p, struct svcctl_GetServiceDisplayNameW *r) -{ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_GetServiceKeyNameW(pipes_struct *p, struct svcctl_GetServiceKeyNameW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_SCSetServiceBitsA(pipes_struct *p, struct svcctl_SCSetServiceBitsA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_ChangeServiceConfigA(pipes_struct *p, struct svcctl_ChangeServiceConfigA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_CreateServiceA(pipes_struct *p, struct svcctl_CreateServiceA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumDependentServicesA(pipes_struct *p, struct svcctl_EnumDependentServicesA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumServicesStatusA(pipes_struct *p, struct svcctl_EnumServicesStatusA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_OpenSCManagerA(pipes_struct *p, struct svcctl_OpenSCManagerA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_OpenServiceA(pipes_struct *p, struct svcctl_OpenServiceA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceConfigA(pipes_struct *p, struct svcctl_QueryServiceConfigA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceLockStatusA(pipes_struct *p, struct svcctl_QueryServiceLockStatusA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_StartServiceA(pipes_struct *p, struct svcctl_StartServiceA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_GetServiceDisplayNameA(pipes_struct *p, struct svcctl_GetServiceDisplayNameA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_GetServiceKeyNameA(pipes_struct *p, struct svcctl_GetServiceKeyNameA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_GetCurrentGroupeStateW(pipes_struct *p, struct svcctl_GetCurrentGroupeStateW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_EnumServiceGroupW(pipes_struct *p, struct svcctl_EnumServiceGroupW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_ChangeServiceConfig2A(pipes_struct *p, struct svcctl_ChangeServiceConfig2A *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_ChangeServiceConfig2W(pipes_struct *p, struct svcctl_ChangeServiceConfig2W *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceConfig2A(pipes_struct *p, struct svcctl_QueryServiceConfig2A *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceConfig2W(pipes_struct *p, struct svcctl_QueryServiceConfig2W *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_QueryServiceStatusEx(pipes_struct *p, struct svcctl_QueryServiceStatusEx *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _EnumServicesStatusExA(pipes_struct *p, struct EnumServicesStatusExA *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _EnumServicesStatusExW(pipes_struct *p, struct EnumServicesStatusExW *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } WERROR _svcctl_SCSendTSMessage(pipes_struct *p, struct svcctl_SCSendTSMessage *r) { p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + return WERR_NOT_SUPPORTED; } diff --git a/source3/rpc_server/srv_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c index 92c178042f..c76bc19d9c 100644 --- a/source3/rpc_server/srv_winreg_nt.c +++ b/source3/rpc_server/srv_winreg_nt.c @@ -21,14 +21,10 @@ /* Implementation of registry functions. */ #include "includes.h" -#include "regfio.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV -static const struct generic_mapping reg_generic_map = - { REG_KEY_READ, REG_KEY_WRITE, REG_KEY_EXECUTE, REG_KEY_ALL }; - /****************************************************************** free() function for struct registry_key *****************************************************************/ @@ -40,7 +36,7 @@ static void free_regkey(void *ptr) } /****************************************************************** - Find a registry key handle and return a REGISTRY_KEY + Find a registry key handle and return a struct registry_key * *****************************************************************/ static struct registry_key *find_regkey_by_hnd(pipes_struct *p, @@ -512,8 +508,6 @@ WERROR _winreg_InitiateSystemShutdownEx(pipes_struct *p, struct winreg_InitiateS /* pull the message string and perform necessary sanity checks on it */ - chkmsg[0] = '\0'; - if ( r->in.message && r->in.message->name && r->in.message->name->name ) { if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->name->name )) == NULL ) { return WERR_NOMEM; @@ -655,125 +649,6 @@ static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname ) } /******************************************************************* - Note: topkeypat is the *full* path that this *key will be - loaded into (including the name of the key) - ********************************************************************/ - -static WERROR reg_load_tree( REGF_FILE *regfile, const char *topkeypath, - REGF_NK_REC *key ) -{ - REGF_NK_REC *subkey; - REGISTRY_KEY registry_key; - REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; - int i; - char *path = NULL; - WERROR result = WERR_OK; - - /* initialize the REGISTRY_KEY structure */ - - if ( !(registry_key.hook = reghook_cache_find(topkeypath)) ) { - DEBUG(0,("reg_load_tree: Failed to assigned a REGISTRY_HOOK to [%s]\n", - topkeypath )); - return WERR_BADFILE; - } - - registry_key.name = talloc_strdup( regfile->mem_ctx, topkeypath ); - if ( !registry_key.name ) { - DEBUG(0,("reg_load_tree: Talloc failed for reg_key.name!\n")); - return WERR_NOMEM; - } - - /* now start parsing the values and subkeys */ - - if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) - return WERR_NOMEM; - - if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) - return WERR_NOMEM; - - /* copy values into the REGVAL_CTR */ - - for ( i=0; i<key->num_values; i++ ) { - regval_ctr_addvalue( values, key->values[i].valuename, key->values[i].type, - (char*)key->values[i].data, (key->values[i].data_size & ~VK_DATA_IN_OFFSET) ); - } - - /* copy subkeys into the REGSUBKEY_CTR */ - - key->subkey_index = 0; - while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { - regsubkey_ctr_addkey( subkeys, subkey->keyname ); - } - - /* write this key and values out */ - - if ( !store_reg_values( ®istry_key, values ) - || !store_reg_keys( ®istry_key, subkeys ) ) - { - DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); - result = WERR_REG_IO_FAILURE; - } - - TALLOC_FREE( subkeys ); - - if ( !W_ERROR_IS_OK(result) ) - return result; - - /* now continue to load each subkey registry tree */ - - key->subkey_index = 0; - while ( (subkey = regfio_fetch_subkey( regfile, key )) ) { - path = talloc_asprintf(regfile->mem_ctx, - "%s\\%s", - topkeypath, - subkey->keyname); - if (!path) { - return WERR_NOMEM; - } - result = reg_load_tree( regfile, path, subkey ); - if ( !W_ERROR_IS_OK(result) ) - break; - } - - return result; -} - -/******************************************************************* - ********************************************************************/ - -static WERROR restore_registry_key ( REGISTRY_KEY *krecord, const char *fname ) -{ - REGF_FILE *regfile; - REGF_NK_REC *rootkey; - WERROR result; - - /* open the registry file....fail if the file already exists */ - - if ( !(regfile = regfio_open( fname, (O_RDONLY), 0 )) ) { - DEBUG(0,("restore_registry_key: failed to open \"%s\" (%s)\n", - fname, strerror(errno) )); - return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); - } - - /* get the rootkey from the regf file and then load the tree - via recursive calls */ - - if ( !(rootkey = regfio_rootkey( regfile )) ) { - regfio_close( regfile ); - return WERR_REG_FILE_INVALID; - } - - result = reg_load_tree( regfile, krecord->name, rootkey ); - - /* cleanup */ - - regfio_close( regfile ); - - return result; -} - -/******************************************************************* ********************************************************************/ WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r) @@ -807,175 +682,9 @@ WERROR _winreg_RestoreKey(pipes_struct *p, struct winreg_RestoreKey *r) DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n", regkey->key->name, fname, lp_servicename(snum) )); - return restore_registry_key( regkey->key, fname ); + return reg_restorekey(regkey, fname); } -/******************************************************************** -********************************************************************/ - -static WERROR reg_write_tree( REGF_FILE *regfile, const char *keypath, - REGF_NK_REC *parent, SEC_DESC *sec_desc ) -{ - REGF_NK_REC *key; - REGVAL_CTR *values; - REGSUBKEY_CTR *subkeys; - int i, num_subkeys; - char *key_tmp = NULL; - char *keyname, *parentpath; - char *subkeypath = NULL; - char *subkeyname; - REGISTRY_KEY registry_key; - WERROR result = WERR_OK; - - if (!regfile) - return WERR_GENERAL_FAILURE; - - if (!keypath) - return WERR_OBJECT_PATH_INVALID; - - /* split up the registry key path */ - - key_tmp = talloc_strdup(regfile->mem_ctx, keypath); - if (!key_tmp) { - return WERR_NOMEM; - } - if (!reg_split_key( key_tmp, &parentpath, &keyname ) ) - return WERR_OBJECT_PATH_INVALID; - - if ( !keyname ) - keyname = parentpath; - - /* we need a REGISTRY_KEY object here to enumerate subkeys and values */ - - ZERO_STRUCT( registry_key ); - - if ( (registry_key.name = talloc_strdup(regfile->mem_ctx, keypath)) == NULL ) - return WERR_NOMEM; - - if ( (registry_key.hook = reghook_cache_find( registry_key.name )) == NULL ) - return WERR_BADFILE; - - /* lookup the values and subkeys */ - - if ( !(subkeys = TALLOC_ZERO_P( regfile->mem_ctx, REGSUBKEY_CTR )) ) - return WERR_NOMEM; - - if ( !(values = TALLOC_ZERO_P( subkeys, REGVAL_CTR )) ) - return WERR_NOMEM; - - fetch_reg_keys( ®istry_key, subkeys ); - fetch_reg_values( ®istry_key, values ); - - /* write out this key */ - - if ( !(key = regfio_write_key( regfile, keyname, values, subkeys, sec_desc, parent )) ) { - result = WERR_CAN_NOT_COMPLETE; - goto done; - } - - /* write each one of the subkeys out */ - - num_subkeys = regsubkey_ctr_numkeys( subkeys ); - for ( i=0; i<num_subkeys; i++ ) { - subkeyname = regsubkey_ctr_specific_key( subkeys, i ); - subkeypath = talloc_asprintf(regfile->mem_ctx, - "%s\\%s", keypath, subkeyname); - if (!subkeypath) { - result = WERR_NOMEM; - goto done; - } - result = reg_write_tree( regfile, subkeypath, key, sec_desc ); - if ( !W_ERROR_IS_OK(result) ) - goto done; - } - - DEBUG(6,("reg_write_tree: wrote key [%s]\n", keypath )); - -done: - TALLOC_FREE( subkeys ); - TALLOC_FREE( registry_key.name ); - - return result; -} - -/******************************************************************* - ********************************************************************/ - -static WERROR make_default_reg_sd( TALLOC_CTX *ctx, SEC_DESC **psd ) -{ - DOM_SID adm_sid, owner_sid; - SEC_ACE ace[2]; /* at most 2 entries */ - SEC_ACCESS mask; - SEC_ACL *psa = NULL; - size_t sd_size; - - /* set the owner to BUILTIN\Administrator */ - - sid_copy(&owner_sid, &global_sid_Builtin); - sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN ); - - - /* basic access for Everyone */ - - init_sec_access(&mask, reg_generic_map.generic_execute | reg_generic_map.generic_read ); - init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /* add Full Access 'BUILTIN\Administrators' */ - - init_sec_access(&mask, reg_generic_map.generic_all); - sid_copy(&adm_sid, &global_sid_Builtin); - sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS); - init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); - - /* create the security descriptor */ - - if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 2, ace)) == NULL) - return WERR_NOMEM; - - if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, - SEC_DESC_SELF_RELATIVE, &owner_sid, NULL, - NULL, psa, &sd_size)) == NULL) - return WERR_NOMEM; - - return WERR_OK; -} - -/******************************************************************* - ********************************************************************/ - -static WERROR backup_registry_key ( REGISTRY_KEY *krecord, const char *fname ) -{ - REGF_FILE *regfile; - WERROR result; - SEC_DESC *sd = NULL; - - /* open the registry file....fail if the file already exists */ - - if ( !(regfile = regfio_open( fname, (O_RDWR|O_CREAT|O_EXCL), (S_IREAD|S_IWRITE) )) ) { - DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", - fname, strerror(errno) )); - return ( ntstatus_to_werror(map_nt_error_from_unix( errno )) ); - } - - if ( !W_ERROR_IS_OK(result = make_default_reg_sd( regfile->mem_ctx, &sd )) ) { - regfio_close( regfile ); - return result; - } - - /* write the registry tree to the file */ - - result = reg_write_tree( regfile, krecord->name, NULL, sd ); - - /* cleanup */ - - regfio_close( regfile ); - - return result; -} - -/******************************************************************* - ********************************************************************/ - WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r) { struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle ); @@ -1002,7 +711,7 @@ WERROR _winreg_SaveKey(pipes_struct *p, struct winreg_SaveKey *r) DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n", regkey->key->name, fname, lp_servicename(snum) )); - return backup_registry_key( regkey->key, fname ); + return reg_savekey(regkey, fname); } /******************************************************************* diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c index e0103e6b58..6d03009d00 100644 --- a/source3/rpc_server/srv_wkssvc_nt.c +++ b/source3/rpc_server/srv_wkssvc_nt.c @@ -281,11 +281,12 @@ WERROR _wkssvc_NetrGetJoinableOus(pipes_struct *p, struct wkssvc_NetrGetJoinable } /******************************************************************** + _wkssvc_NetrJoinDomain2 ********************************************************************/ -WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r) +WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, + struct wkssvc_NetrJoinDomain2 *r) { -#if 0 struct libnet_JoinCtx *j = NULL; char *cleartext_pwd = NULL; char *admin_domain = NULL; @@ -293,7 +294,7 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r WERROR werr; NTSTATUS status; struct nt_user_token *token = p->pipe_user.nt_user_token; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; if (!r->in.domain_name) { return WERR_INVALID_PARAM; @@ -302,6 +303,8 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r if (!user_has_privileges(token, &se_machine_account) && !nt_token_check_domain_rid(token, DOMAIN_GROUP_RID_ADMINS) && !nt_token_check_domain_rid(token, BUILTIN_ALIAS_RID_ADMINS)) { + DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have " + "sufficient privileges\n")); return WERR_ACCESS_DENIED; } @@ -335,32 +338,96 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, struct wkssvc_NetrJoinDomain2 *r return werr; } - j->in.dc_name = info->domain_controller_name; + j->in.dc_name = info->dc_unc; j->in.domain_name = r->in.domain_name; j->in.account_ou = r->in.account_ou; j->in.join_flags = r->in.join_flags; j->in.admin_account = admin_account; j->in.admin_password = cleartext_pwd; - j->in.modify_config = true; + j->in.debug = true; become_root(); werr = libnet_Join(p->mem_ctx, j); unbecome_root(); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join gave %s\n", + j->out.error_string ? j->out.error_string : + dos_errstr(werr))); + } + + TALLOC_FREE(j); return werr; -#endif - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; } /******************************************************************** + _wkssvc_NetrUnjoinDomain2 ********************************************************************/ -WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p, struct wkssvc_NetrUnjoinDomain2 *r) +WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p, + struct wkssvc_NetrUnjoinDomain2 *r) { - /* FIXME: Add implementation code here */ - p->rng_fault_state = True; - return WERR_NOT_SUPPORTED; + struct libnet_UnjoinCtx *u = NULL; + char *cleartext_pwd = NULL; + char *admin_domain = NULL; + char *admin_account = NULL; + WERROR werr; + NTSTATUS status; + struct nt_user_token *token = p->pipe_user.nt_user_token; + struct netr_DsRGetDCNameInfo *info = NULL; + + if (!user_has_privileges(token, &se_machine_account) && + !nt_token_check_domain_rid(token, DOMAIN_GROUP_RID_ADMINS) && + !nt_token_check_domain_rid(token, BUILTIN_ALIAS_RID_ADMINS)) { + DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have " + "sufficient privileges\n")); + return WERR_ACCESS_DENIED; + } + + werr = decode_wkssvc_join_password_buffer(p->mem_ctx, + r->in.encrypted_password, + &p->session_key, + &cleartext_pwd); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + split_domain_user(p->mem_ctx, + r->in.account, + &admin_domain, + &admin_account); + + status = dsgetdcname(p->mem_ctx, + lp_realm(), + NULL, + NULL, + DS_DIRECTORY_SERVICE_REQUIRED | + DS_WRITABLE_REQUIRED | + DS_RETURN_DNS_NAME, + &info); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + werr = libnet_init_UnjoinCtx(p->mem_ctx, &u); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + u->in.dc_name = info->dc_unc; + u->in.domain_name = lp_realm(); + u->in.unjoin_flags = r->in.unjoin_flags | + WKSSVC_JOIN_FLAGS_JOIN_TYPE; + u->in.admin_account = admin_account; + u->in.admin_password = cleartext_pwd; + u->in.debug = true; + + become_root(); + werr = libnet_Unjoin(p->mem_ctx, u); + unbecome_root(); + + TALLOC_FREE(u); + return werr; } /******************************************************************** diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index c014dba676..90f8646810 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -4,6 +4,7 @@ Copyright (C) Tim Potter 2000 Copyright (C) Rafal Szczesniak 2002 + Copyright (C) Guenther Deschner 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 @@ -394,7 +395,7 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct rpc_pipe_client *cli, } result = rpccli_lsa_open_policy(cli, mem_ctx, True, - POLICY_VIEW_LOCAL_INFORMATION, + LSA_POLICY_VIEW_LOCAL_INFORMATION, &pol); if (!NT_STATUS_IS_OK(result)) @@ -550,8 +551,7 @@ static NTSTATUS cmd_lsa_enum_sids(struct rpc_pipe_client *cli, uint32 enum_context=0; uint32 pref_max_length=0x1000; - DOM_SID *sids; - uint32 count=0; + struct lsa_SidArray sid_array; int i; if (argc > 3) { @@ -572,19 +572,22 @@ static NTSTATUS cmd_lsa_enum_sids(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_enum_sids(cli, mem_ctx, &pol, &enum_context, pref_max_length, - &count, &sids); + result = rpccli_lsa_EnumAccounts(cli, mem_ctx, + &pol, + &enum_context, + &sid_array, + pref_max_length); if (!NT_STATUS_IS_OK(result)) goto done; /* Print results */ - printf("found %d SIDs\n\n", count); + printf("found %d SIDs\n\n", sid_array.num_sids); - for (i = 0; i < count; i++) { + for (i = 0; i < sid_array.num_sids; i++) { fstring sid_str; - sid_to_fstring(sid_str, &sids[i]); + sid_to_fstring(sid_str, sid_array.sids[i].sid); printf("%s\n", sid_str); } @@ -650,10 +653,8 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct rpc_pipe_client *cli, POLICY_HND user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 access_desired = 0x000f000f; - DOM_SID sid; - uint32 count=0; - LUID_ATTR *set; + struct lsa_PrivilegeSet *privs = NULL; int i; if (argc != 2 ) { @@ -681,17 +682,22 @@ static NTSTATUS cmd_lsa_enum_privsaccounts(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_enum_privsaccount(cli, mem_ctx, &user_pol, &count, &set); + result = rpccli_lsa_EnumPrivsAccount(cli, mem_ctx, + &user_pol, + &privs); if (!NT_STATUS_IS_OK(result)) goto done; /* Print results */ - printf("found %d privileges for SID %s\n\n", count, argv[1]); + printf("found %d privileges for SID %s\n\n", privs->count, argv[1]); printf("high\tlow\tattribute\n"); - for (i = 0; i < count; i++) { - printf("%u\t%u\t%u\n", set[i].luid.high, set[i].luid.low, set[i].attr); + for (i = 0; i < privs->count; i++) { + printf("%u\t%u\t%u\n", + privs->set[i].luid.high, + privs->set[i].luid.low, + privs->set[i].attribute); } rpccli_lsa_Close(cli, mem_ctx, &dom_pol); @@ -708,10 +714,8 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct rpc_pipe_client *cli, { POLICY_HND dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_SID sid; - uint32 count; - char **rights; + struct lsa_RightSet rights; int i; @@ -731,16 +735,19 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_enum_account_rights(cli, mem_ctx, &dom_pol, &sid, &count, &rights); + result = rpccli_lsa_EnumAccountRights(cli, mem_ctx, + &dom_pol, + &sid, + &rights); if (!NT_STATUS_IS_OK(result)) goto done; - printf("found %d privileges for SID %s\n", count, + printf("found %d privileges for SID %s\n", rights.count, sid_string_tos(&sid)); - for (i = 0; i < count; i++) { - printf("\t%s\n", rights[i]); + for (i = 0; i < rights.count; i++) { + printf("\t%s\n", rights.names[i].string); } rpccli_lsa_Close(cli, mem_ctx, &dom_pol); @@ -757,8 +764,9 @@ static NTSTATUS cmd_lsa_add_acct_rights(struct rpc_pipe_client *cli, { POLICY_HND dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - + struct lsa_RightSet rights; DOM_SID sid; + int i; if (argc < 3 ) { printf("Usage: %s SID [rights...]\n", argv[0]); @@ -776,8 +784,21 @@ static NTSTATUS cmd_lsa_add_acct_rights(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid, - argc-2, argv+2); + rights.count = argc-2; + rights.names = TALLOC_ARRAY(mem_ctx, struct lsa_StringLarge, + rights.count); + if (!rights.names) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<argc-1; i++) { + init_lsa_StringLarge(&rights.names[i], argv[i+2]); + } + + result = rpccli_lsa_AddAccountRights(cli, mem_ctx, + &dom_pol, + &sid, + &rights); if (!NT_STATUS_IS_OK(result)) goto done; @@ -796,8 +817,9 @@ static NTSTATUS cmd_lsa_remove_acct_rights(struct rpc_pipe_client *cli, { POLICY_HND dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - + struct lsa_RightSet rights; DOM_SID sid; + int i; if (argc < 3 ) { printf("Usage: %s SID [rights...]\n", argv[0]); @@ -815,8 +837,22 @@ static NTSTATUS cmd_lsa_remove_acct_rights(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid, - False, argc-2, argv+2); + rights.count = argc-2; + rights.names = TALLOC_ARRAY(mem_ctx, struct lsa_StringLarge, + rights.count); + if (!rights.names) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<argc-2; i++) { + init_lsa_StringLarge(&rights.names[i], argv[i+2]); + } + + result = rpccli_lsa_RemoveAccountRights(cli, mem_ctx, + &dom_pol, + &sid, + false, + &rights); if (!NT_STATUS_IS_OK(result)) goto done; @@ -836,7 +872,8 @@ static NTSTATUS cmd_lsa_lookup_priv_value(struct rpc_pipe_client *cli, { POLICY_HND pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - LUID luid; + struct lsa_LUID luid; + struct lsa_String name; if (argc != 2 ) { printf("Usage: %s name\n", argv[0]); @@ -850,7 +887,12 @@ static NTSTATUS cmd_lsa_lookup_priv_value(struct rpc_pipe_client *cli, if (!NT_STATUS_IS_OK(result)) goto done; - result = rpccli_lsa_lookup_priv_value(cli, mem_ctx, &pol, argv[1], &luid); + init_lsa_String(&name, argv[1]); + + result = rpccli_lsa_LookupPrivValue(cli, mem_ctx, + &pol, + &name, + &luid); if (!NT_STATUS_IS_OK(result)) goto done; @@ -1130,6 +1172,176 @@ static NTSTATUS cmd_lsa_get_username(struct rpc_pipe_client *cli, return result; } +static NTSTATUS cmd_lsa_add_priv(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + POLICY_HND dom_pol, user_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + struct lsa_PrivilegeSet privs; + struct lsa_LUIDAttribute *set = NULL; + DOM_SID sid; + int i; + + ZERO_STRUCT(privs); + + if (argc < 3 ) { + printf("Usage: %s SID [rights...]\n", argv[0]); + return NT_STATUS_OK; + } + + result = name_to_sid(cli, mem_ctx, &sid, argv[1]); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_lsa_open_policy2(cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &dom_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_lsa_OpenAccount(cli, mem_ctx, + &dom_pol, + &sid, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &user_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + for (i=2; i<argc; i++) { + + struct lsa_String priv_name; + struct lsa_LUID luid; + + init_lsa_String(&priv_name, argv[i]); + + result = rpccli_lsa_LookupPrivValue(cli, mem_ctx, + &dom_pol, + &priv_name, + &luid); + if (!NT_STATUS_IS_OK(result)) { + continue; + } + + privs.count++; + set = TALLOC_REALLOC_ARRAY(mem_ctx, set, + struct lsa_LUIDAttribute, + privs.count); + if (!set) { + return NT_STATUS_NO_MEMORY; + } + + set[privs.count-1].luid = luid; + set[privs.count-1].attribute = 0; + } + + privs.set = set; + + result = rpccli_lsa_AddPrivilegesToAccount(cli, mem_ctx, + &user_pol, + &privs); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + rpccli_lsa_Close(cli, mem_ctx, &user_pol); + rpccli_lsa_Close(cli, mem_ctx, &dom_pol); + done: + return result; +} + +static NTSTATUS cmd_lsa_del_priv(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + POLICY_HND dom_pol, user_pol; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + struct lsa_PrivilegeSet privs; + struct lsa_LUIDAttribute *set = NULL; + DOM_SID sid; + int i; + + ZERO_STRUCT(privs); + + if (argc < 3 ) { + printf("Usage: %s SID [rights...]\n", argv[0]); + return NT_STATUS_OK; + } + + result = name_to_sid(cli, mem_ctx, &sid, argv[1]); + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_lsa_open_policy2(cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &dom_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + result = rpccli_lsa_OpenAccount(cli, mem_ctx, + &dom_pol, + &sid, + SEC_RIGHTS_MAXIMUM_ALLOWED, + &user_pol); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + for (i=2; i<argc; i++) { + + struct lsa_String priv_name; + struct lsa_LUID luid; + + init_lsa_String(&priv_name, argv[i]); + + result = rpccli_lsa_LookupPrivValue(cli, mem_ctx, + &dom_pol, + &priv_name, + &luid); + if (!NT_STATUS_IS_OK(result)) { + continue; + } + + privs.count++; + set = TALLOC_REALLOC_ARRAY(mem_ctx, set, + struct lsa_LUIDAttribute, + privs.count); + if (!set) { + return NT_STATUS_NO_MEMORY; + } + + set[privs.count-1].luid = luid; + set[privs.count-1].attribute = 0; + } + + privs.set = set; + + + result = rpccli_lsa_RemovePrivilegesFromAccount(cli, mem_ctx, + &user_pol, + false, + &privs); + + if (!NT_STATUS_IS_OK(result)) { + goto done; + } + + rpccli_lsa_Close(cli, mem_ctx, &user_pol); + rpccli_lsa_Close(cli, mem_ctx, &dom_pol); + done: + return result; +} + /* List of commands exported by this module */ @@ -1148,10 +1360,8 @@ struct cmd_set lsarpc_commands[] = { { "lsacreateaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_create_account, NULL, PI_LSARPC, NULL, "Create a new lsa account", "" }, { "lsaenumprivsaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privsaccounts, NULL, PI_LSARPC, NULL, "Enumerate the privileges of an SID", "" }, { "lsaenumacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_rights, NULL, PI_LSARPC, NULL, "Enumerate the rights of an SID", "" }, -#if 0 - { "lsaaddpriv", RPC_RTYPE_NTSTATUS, cmd_lsa_add_priv, NULL, PI_LSARPC, "Assign a privilege to a SID", "" }, - { "lsadelpriv", RPC_RTYPE_NTSTATUS, cmd_lsa_del_priv, NULL, PI_LSARPC, "Revoke a privilege from a SID", "" }, -#endif + { "lsaaddpriv", RPC_RTYPE_NTSTATUS, cmd_lsa_add_priv, NULL, PI_LSARPC, NULL, "Assign a privilege to a SID", "" }, + { "lsadelpriv", RPC_RTYPE_NTSTATUS, cmd_lsa_del_priv, NULL, PI_LSARPC, NULL, "Revoke a privilege from a SID", "" }, { "lsaaddacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_add_acct_rights, NULL, PI_LSARPC, NULL, "Add rights to an account", "" }, { "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, NULL, "Remove rights from an account", "" }, { "lsalookupprivvalue", RPC_RTYPE_NTSTATUS, cmd_lsa_lookup_priv_value, NULL, PI_LSARPC, NULL, "Get a privilege value given its name", "" }, diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index a752003e8d..95d79b5825 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -3,6 +3,7 @@ RPC pipe client Copyright (C) Tim Potter 2000 + Copyright (C) Guenther Deschner 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 @@ -21,27 +22,68 @@ #include "includes.h" #include "rpcclient.h" -static NTSTATUS cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, int argc, - const char **argv) +static WERROR cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) { - uint32 query_level = 1; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + WERROR werr; + const char *logon_server = cli->cli->desthost; + enum netr_LogonControlCode function_code = NETLOGON_CONTROL_REDISCOVER; + uint32_t level = 1; + union netr_CONTROL_DATA_INFORMATION data; + union netr_CONTROL_QUERY_INFORMATION query; + const char *domain = lp_workgroup(); - if (argc > 1) { - fprintf(stderr, "Usage: %s\n", argv[0]); - return NT_STATUS_OK; + if (argc > 5) { + fprintf(stderr, "Usage: %s <logon_server> <function_code> " + "<level> <domain>\n", argv[0]); + return WERR_OK; } - result = rpccli_netlogon_logon_ctrl2(cli, mem_ctx, query_level); + if (argc >= 2) { + logon_server = argv[1]; + } - if (!NT_STATUS_IS_OK(result)) - goto done; + if (argc >= 3) { + function_code = atoi(argv[2]); + } + + if (argc >= 4) { + level = atoi(argv[3]); + } + + if (argc >= 5) { + domain = argv[4]; + } + + switch (function_code) { + case NETLOGON_CONTROL_REDISCOVER: + case NETLOGON_CONTROL_TC_QUERY: + data.domain = domain; + break; + default: + break; + } + + status = rpccli_netr_LogonControl2(cli, mem_ctx, + logon_server, + function_code, + level, + &data, + &query, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + if (!W_ERROR_IS_OK(werr)) { + return werr; + } /* Display results */ - done: - return result; + return werr; } static WERROR cmd_netlogon_getanydcname(struct rpc_pipe_client *cli, @@ -348,169 +390,292 @@ static WERROR cmd_netlogon_dsr_getsitename(struct rpc_pipe_client *cli, return WERR_OK; } -static NTSTATUS cmd_netlogon_logon_ctrl(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, int argc, - const char **argv) +static WERROR cmd_netlogon_logon_ctrl(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) { -#if 0 - uint32 query_level = 1; -#endif - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + WERROR werr; + const char *logon_server = cli->cli->desthost; + enum netr_LogonControlCode function_code = 1; + uint32_t level = 1; + union netr_CONTROL_QUERY_INFORMATION info; + + if (argc > 4) { + fprintf(stderr, "Usage: %s <logon_server> <function_code> " + "<level>\n", argv[0]); + return WERR_OK; + } - if (argc > 1) { - fprintf(stderr, "Usage: %s\n", argv[0]); - return NT_STATUS_OK; + if (argc >= 2) { + logon_server = argv[1]; } -#if 0 - result = cli_netlogon_logon_ctrl(cli, mem_ctx, query_level); - if (!NT_STATUS_IS_OK(result)) { - goto done; + if (argc >= 3) { + function_code = atoi(argv[2]); + } + + if (argc >= 4) { + level = atoi(argv[3]); + } + + status = rpccli_netr_LogonControl(cli, mem_ctx, + logon_server, + function_code, + level, + &info, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + if (!W_ERROR_IS_OK(werr)) { + return werr; } -#endif /* Display results */ - return result; + return werr; } /* Display sam synchronisation information */ -static void display_sam_sync(uint32 num_deltas, SAM_DELTA_HDR *hdr_deltas, - SAM_DELTA_CTR *deltas) +static void display_sam_sync(struct netr_DELTA_ENUM_ARRAY *r) { - fstring name; - uint32 i, j; - - for (i = 0; i < num_deltas; i++) { - switch (hdr_deltas[i].type) { - case SAM_DELTA_DOMAIN_INFO: - unistr2_to_ascii(name, - &deltas[i].domain_info.uni_dom_name, - sizeof(name)); - printf("Domain: %s\n", name); - break; - case SAM_DELTA_GROUP_INFO: - unistr2_to_ascii(name, - &deltas[i].group_info.uni_grp_name, - sizeof(name)); - printf("Group: %s\n", name); - break; - case SAM_DELTA_ACCOUNT_INFO: - unistr2_to_ascii(name, - &deltas[i].account_info.uni_acct_name, - sizeof(name)); - printf("Account: %s\n", name); - break; - case SAM_DELTA_ALIAS_INFO: - unistr2_to_ascii(name, - &deltas[i].alias_info.uni_als_name, - sizeof(name)); - printf("Alias: %s\n", name); - break; - case SAM_DELTA_ALIAS_MEM: { - SAM_ALIAS_MEM_INFO *alias = &deltas[i].als_mem_info; - - for (j = 0; j < alias->num_members; j++) { - fstring sid_str; - - sid_to_fstring(sid_str, &alias->sids[j].sid); - - printf("%s\n", sid_str); - } - break; - } - case SAM_DELTA_GROUP_MEM: { - SAM_GROUP_MEM_INFO *group = &deltas[i].grp_mem_info; - - for (j = 0; j < group->num_members; j++) - printf("rid 0x%x, attrib 0x%08x\n", - group->rids[j], group->attribs[j]); - break; - } - case SAM_DELTA_MODIFIED_COUNT: { - SAM_DELTA_MOD_COUNT *mc = &deltas[i].mod_count; - - printf("sam sequence update: 0x%04x\n", mc->seqnum); - break; - } - default: - printf("unknown delta type 0x%02x\n", - hdr_deltas[i].type); - break; - } - } + uint32_t i, j; + + for (i=0; i < r->num_deltas; i++) { + + union netr_DELTA_UNION u = r->delta_enum[i].delta_union; + union netr_DELTA_ID_UNION id = r->delta_enum[i].delta_id_union; + + switch (r->delta_enum[i].delta_type) { + case NETR_DELTA_DOMAIN: + printf("Domain: %s\n", + u.domain->domain_name.string); + break; + case NETR_DELTA_GROUP: + printf("Group: %s\n", + u.group->group_name.string); + break; + case NETR_DELTA_DELETE_GROUP: + printf("Delete Group: %d\n", + u.delete_account.unknown); + break; + case NETR_DELTA_RENAME_GROUP: + printf("Rename Group: %s -> %s\n", + u.rename_group->OldName.string, + u.rename_group->NewName.string); + break; + case NETR_DELTA_USER: + printf("Account: %s\n", + u.user->account_name.string); + break; + case NETR_DELTA_DELETE_USER: + printf("Delete User: %d\n", + id.rid); + break; + case NETR_DELTA_RENAME_USER: + printf("Rename user: %s -> %s\n", + u.rename_user->OldName.string, + u.rename_user->NewName.string); + break; + case NETR_DELTA_GROUP_MEMBER: + for (j=0; j < u.group_member->num_rids; j++) { + printf("rid 0x%x, attrib 0x%08x\n", + u.group_member->rids[j], + u.group_member->attribs[j]); + } + break; + case NETR_DELTA_ALIAS: + printf("Alias: %s\n", + u.alias->alias_name.string); + break; + case NETR_DELTA_DELETE_ALIAS: + printf("Delete Alias: %d\n", + r->delta_enum[i].delta_id_union.rid); + break; + case NETR_DELTA_RENAME_ALIAS: + printf("Rename alias: %s -> %s\n", + u.rename_alias->OldName.string, + u.rename_alias->NewName.string); + break; + case NETR_DELTA_ALIAS_MEMBER: + for (j=0; j < u.alias_member->sids.num_sids; j++) { + fstring sid_str; + sid_to_fstring(sid_str, + u.alias_member->sids.sids[j].sid); + printf("%s\n", sid_str); + } + break; + case NETR_DELTA_POLICY: + printf("Policy\n"); + break; + case NETR_DELTA_TRUSTED_DOMAIN: + printf("Trusted Domain: %s\n", + u.trusted_domain->domain_name.string); + break; + case NETR_DELTA_DELETE_TRUST: + printf("Delete Trust: %d\n", + u.delete_trust.unknown); + break; + case NETR_DELTA_ACCOUNT: + printf("Account\n"); + break; + case NETR_DELTA_DELETE_ACCOUNT: + printf("Delete Account: %d\n", + u.delete_account.unknown); + break; + case NETR_DELTA_SECRET: + printf("Secret\n"); + break; + case NETR_DELTA_DELETE_SECRET: + printf("Delete Secret: %d\n", + u.delete_secret.unknown); + break; + case NETR_DELTA_DELETE_GROUP2: + printf("Delete Group2: %s\n", + u.delete_group->account_name); + break; + case NETR_DELTA_DELETE_USER2: + printf("Delete User2: %s\n", + u.delete_user->account_name); + break; + case NETR_DELTA_MODIFY_COUNT: + printf("sam sequence update: 0x%016llx\n", + (unsigned long long) *u.modified_count); + break; + default: + printf("unknown delta type 0x%02x\n", + r->delta_enum[i].delta_type); + break; + } + } } /* Perform sam synchronisation */ -static NTSTATUS cmd_netlogon_sam_sync(struct rpc_pipe_client *cli, +static NTSTATUS cmd_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 database_id = 0, num_deltas; - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; + const char *logon_server = cli->cli->desthost; + const char *computername = global_myname(); + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + enum netr_SamDatabaseID database_id = SAM_DATABASE_DOMAIN; + uint16_t restart_state = 0; + uint32_t sync_context = 0; if (argc > 2) { fprintf(stderr, "Usage: %s [database_id]\n", argv[0]); return NT_STATUS_OK; } - if (argc == 2) - database_id = atoi(argv[1]); + if (argc == 2) { + database_id = atoi(argv[1]); + } - /* Synchronise sam database */ + /* Synchronise sam database */ + + do { + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; + + netlogon_creds_client_step(cli->dc, &credential); + + result = rpccli_netr_DatabaseSync2(cli, mem_ctx, + logon_server, + computername, + &credential, + &return_authenticator, + database_id, + restart_state, + &sync_context, + &delta_enum_array, + 0xffff); + + /* Check returned credentials. */ + if (!netlogon_creds_client_check(cli->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } - result = rpccli_netlogon_sam_sync(cli, mem_ctx, database_id, - 0, &num_deltas, &hdr_deltas, &deltas); + if (NT_STATUS_IS_ERR(result)) { + break; + } - if (!NT_STATUS_IS_OK(result)) - goto done; + /* Display results */ - /* Display results */ + display_sam_sync(delta_enum_array); - display_sam_sync(num_deltas, hdr_deltas, deltas); + TALLOC_FREE(delta_enum_array); - done: - return result; + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + + return result; } /* Perform sam delta synchronisation */ -static NTSTATUS cmd_netlogon_sam_deltas(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, int argc, - const char **argv) +static NTSTATUS cmd_netlogon_sam_deltas(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 database_id, num_deltas, tmp; - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; - uint64 seqnum; + uint32_t tmp; + const char *logon_server = cli->cli->desthost; + const char *computername = global_myname(); + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + enum netr_SamDatabaseID database_id = SAM_DATABASE_DOMAIN; + uint64_t sequence_num; + + if (argc != 3) { + fprintf(stderr, "Usage: %s database_id seqnum\n", argv[0]); + return NT_STATUS_OK; + } - if (argc != 3) { - fprintf(stderr, "Usage: %s database_id seqnum\n", argv[0]); - return NT_STATUS_OK; - } + database_id = atoi(argv[1]); + tmp = atoi(argv[2]); - database_id = atoi(argv[1]); - tmp = atoi(argv[2]); + sequence_num = tmp & 0xffff; - seqnum = tmp & 0xffff; + do { + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; - result = rpccli_netlogon_sam_deltas(cli, mem_ctx, database_id, - seqnum, &num_deltas, - &hdr_deltas, &deltas); + netlogon_creds_client_step(cli->dc, &credential); - if (!NT_STATUS_IS_OK(result)) - goto done; + result = rpccli_netr_DatabaseDeltas(cli, mem_ctx, + logon_server, + computername, + &credential, + &return_authenticator, + database_id, + &sequence_num, + &delta_enum_array, + 0xffff); - /* Display results */ + /* Check returned credentials. */ + if (!netlogon_creds_client_check(cli->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + + if (NT_STATUS_IS_ERR(result)) { + break; + } + + /* Display results */ + + display_sam_sync(delta_enum_array); + + TALLOC_FREE(delta_enum_array); + + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); - display_sam_sync(num_deltas, hdr_deltas, deltas); - - done: return result; } @@ -837,14 +1002,13 @@ static WERROR cmd_netlogon_enumtrusteddomainsex(struct rpc_pipe_client *cli, } - /* List of commands exported by this module */ struct cmd_set netlogon_commands[] = { { "NETLOGON" }, - { "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, NULL, "Logon Control 2", "" }, + { "logonctrl2", RPC_RTYPE_WERROR, NULL, cmd_netlogon_logon_ctrl2, PI_NETLOGON, NULL, "Logon Control 2", "" }, { "getanydcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getanydcname, PI_NETLOGON, NULL, "Get trusted DC name", "" }, { "getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcname, PI_NETLOGON, NULL, "Get trusted PDC name", "" }, { "dsr_getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcname, PI_NETLOGON, NULL, "Get trusted DC name", "" }, @@ -852,7 +1016,7 @@ struct cmd_set netlogon_commands[] = { { "dsr_getdcnameex2", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcnameex2, PI_NETLOGON, NULL, "Get trusted DC name", "" }, { "dsr_getsitename", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getsitename, PI_NETLOGON, NULL, "Get sitename", "" }, { "dsr_getforesttrustinfo", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getforesttrustinfo, PI_NETLOGON, NULL, "Get Forest Trust Info", "" }, - { "logonctrl", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl, NULL, PI_NETLOGON, NULL, "Logon Control", "" }, + { "logonctrl", RPC_RTYPE_WERROR, NULL, cmd_netlogon_logon_ctrl, PI_NETLOGON, NULL, "Logon Control", "" }, { "samsync", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync, NULL, PI_NETLOGON, NULL, "Sam Synchronisation", "" }, { "samdeltas", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas, NULL, PI_NETLOGON, NULL, "Query Sam Deltas", "" }, { "samlogon", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_logon, NULL, PI_NETLOGON, NULL, "Sam Logon", "" }, diff --git a/source3/rpcclient/cmd_ntsvcs.c b/source3/rpcclient/cmd_ntsvcs.c new file mode 100644 index 0000000000..b7b37e2fa6 --- /dev/null +++ b/source3/rpcclient/cmd_ntsvcs.c @@ -0,0 +1,189 @@ +/* + Unix SMB/CIFS implementation. + RPC pipe client + + Copyright (C) Günther Deschner 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "rpcclient.h" + +static WERROR cmd_ntsvcs_get_version(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + WERROR werr; + uint16_t version; + + status = rpccli_PNP_GetVersion(cli, mem_ctx, + &version, &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(werr)) { + printf("version: %d\n", version); + } + + return werr; +} + +static WERROR cmd_ntsvcs_validate_dev_inst(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + WERROR werr; + const char *devicepath = NULL; + uint32_t flags = 0; + + if (argc < 2 || argc > 3) { + printf("usage: %s [devicepath] <flags>\n", argv[0]); + return WERR_OK; + } + + devicepath = argv[1]; + + if (argc >= 3) { + flags = atoi(argv[2]); + } + + status = rpccli_PNP_ValidateDeviceInstance(cli, mem_ctx, + devicepath, + flags, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + return werr; +} + +static WERROR cmd_ntsvcs_get_device_list_size(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + WERROR werr; + const char *devicename = NULL; + uint32_t flags = 0; + uint32_t size = 0; + + if (argc < 2 || argc > 4) { + printf("usage: %s [devicename] <flags>\n", argv[0]); + return WERR_OK; + } + + devicename = argv[1]; + + if (argc >= 3) { + flags = atoi(argv[2]); + } + + status = rpccli_PNP_GetDeviceListSize(cli, mem_ctx, + devicename, + &size, + flags, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(werr)) { + printf("size: %d\n", size); + } + + return werr; +} + +static WERROR cmd_ntsvcs_hw_prof_flags(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + WERROR werr; + const char *devicepath = NULL; + uint32_t unk3 = 0; + uint16_t unk4 = 0; + const char *unk5 = NULL; + const char *unk5a = NULL; + + if (argc < 2) { + printf("usage: %s [devicepath]\n", argv[0]); + return WERR_OK; + } + + devicepath = argv[1]; + + status = rpccli_PNP_HwProfFlags(cli, mem_ctx, + 0, + devicepath, + 0, + &unk3, + &unk4, + unk5, + &unk5a, + 0, + 0, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + return werr; +} + +static WERROR cmd_ntsvcs_get_hw_prof_info(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + int argc, + const char **argv) +{ + NTSTATUS status; + WERROR werr; + uint32_t idx = 0; + struct PNP_HwProfInfo info; + uint32_t unknown1 = 0, unknown2 = 0; + + ZERO_STRUCT(info); + + status = rpccli_PNP_GetHwProfInfo(cli, mem_ctx, + idx, + &info, + unknown1, + unknown2, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + + return werr; +} + +struct cmd_set ntsvcs_commands[] = { + + { "NTSVCS" }, + { "ntsvcs_getversion", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_get_version, PI_NTSVCS, NULL, "Query NTSVCS version", "" }, + { "ntsvcs_validatedevinst", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_validate_dev_inst, PI_NTSVCS, NULL, "Query NTSVCS device instance", "" }, + { "ntsvcs_getdevlistsize", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_get_device_list_size, PI_NTSVCS, NULL, "Query NTSVCS get device list", "" }, + { "ntsvcs_hwprofflags", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_hw_prof_flags, PI_NTSVCS, NULL, "Query NTSVCS HW prof flags", "" }, + { "ntsvcs_hwprofinfo", RPC_RTYPE_WERROR, NULL, cmd_ntsvcs_get_hw_prof_info, PI_NTSVCS, NULL, "Query NTSVCS HW prof info", "" }, + { NULL } +}; diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index f8b8ba893c..2d20afeb13 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -6,6 +6,7 @@ Copyright (C) Luke Kenneth Casson Leighton 1996-2000, Copyright (C) Elrond 2000, Copyright (C) Tim Potter 2000 + Copyright (C) Guenther Deschner 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 @@ -1044,8 +1045,8 @@ static NTSTATUS cmd_samr_enum_domains(struct rpc_pipe_client *cli, return NT_STATUS_OK; } - if (argc > 2) { - sscanf(argv[2], "%x", &access_mask); + if (argc > 1) { + sscanf(argv[1], "%x", &access_mask); } /* Get sam policy handle */ @@ -1194,11 +1195,11 @@ static NTSTATUS cmd_samr_query_aliasinfo(struct rpc_pipe_client *cli, sscanf(argv[2], "%i", &alias_rid); - if (argc > 3) { + if (argc > 2) { level = atoi(argv[3]); } - if (argc > 4) { + if (argc > 3) { sscanf(argv[4], "%x", &access_mask); } diff --git a/source3/rpcclient/cmd_srvsvc.c b/source3/rpcclient/cmd_srvsvc.c index 572609981d..2e84f0498f 100644 --- a/source3/rpcclient/cmd_srvsvc.c +++ b/source3/rpcclient/cmd_srvsvc.c @@ -130,51 +130,37 @@ static char *get_server_type_str(uint32 type) return typestr; } -static void display_server(char *sname, uint32 type, const char *comment) +static void display_server(const char *sname, uint32 type, const char *comment) { printf("\t%-15.15s%-20s %s\n", sname, get_server_type_str(type), comment); } -static void display_srv_info_101(SRV_INFO_101 *sv101) +static void display_srv_info_101(struct srvsvc_NetSrvInfo101 *r) { - fstring name; - fstring comment; + display_server(r->server_name, r->server_type, r->comment); - unistr2_to_ascii(name, &sv101->uni_name, sizeof(name)); - unistr2_to_ascii(comment, &sv101->uni_comment, sizeof(comment)); - - display_server(name, sv101->srv_type, comment); - - printf("\tplatform_id :\t%d\n", sv101->platform_id); - printf("\tos version :\t%d.%d\n", sv101->ver_major, - sv101->ver_minor); - - printf("\tserver type :\t0x%x\n", sv101->srv_type); + printf("\tplatform_id :\t%d\n", r->platform_id); + printf("\tos version :\t%d.%d\n", + r->version_major, r->version_minor); + printf("\tserver type :\t0x%x\n", r->server_type); } -static void display_srv_info_102(SRV_INFO_102 *sv102) +static void display_srv_info_102(struct srvsvc_NetSrvInfo102 *r) { - fstring name; - fstring comment; - fstring usr_path; - - unistr2_to_ascii(name, &sv102->uni_name, sizeof(name)); - unistr2_to_ascii(comment, &sv102->uni_comment, sizeof(comment)); - unistr2_to_ascii(usr_path, &sv102->uni_usr_path, sizeof(usr_path)); - - display_server(name, sv102->srv_type, comment); - - printf("\tplatform_id :\t%d\n", sv102->platform_id); - printf("\tos version :\t%d.%d\n", sv102->ver_major, - sv102->ver_minor); - - printf("\tusers :\t%x\n", sv102->users); - printf("\tdisc, hidden :\t%x, %x\n", sv102->disc, sv102->hidden); - printf("\tannounce, delta :\t%d, %d\n", sv102->announce, - sv102->ann_delta); - printf("\tlicenses :\t%d\n", sv102->licenses); - printf("\tuser path :\t%s\n", usr_path); + display_server(r->server_name, r->server_type, r->comment); + + printf("\tplatform_id :\t%d\n", r->platform_id); + printf("\tos version :\t%d.%d\n", + r->version_major, r->version_minor); + printf("\tserver type :\t0x%x\n", r->server_type); + + printf("\tusers :\t%x\n", r->users); + printf("\tdisc, hidden :\t%x, %x\n", r->disc, r->hidden); + printf("\tannounce, delta :\t%d, %d\n", r->announce, + r->anndelta); + printf("\tlicenses :\t%d\n", r->licenses); + printf("\tuser path :\t%s\n", r->userpath); } /* Server query info */ @@ -183,8 +169,10 @@ static WERROR cmd_srvsvc_srv_query_info(struct rpc_pipe_client *cli, int argc, const char **argv) { uint32 info_level = 101; - SRV_INFO_CTR ctr; + union srvsvc_NetSrvInfo info; WERROR result; + NTSTATUS status; + const char *server_name; if (argc > 2) { printf("Usage: %s [infolevel]\n", argv[0]); @@ -194,8 +182,18 @@ static WERROR cmd_srvsvc_srv_query_info(struct rpc_pipe_client *cli, if (argc == 2) info_level = atoi(argv[1]); - result = rpccli_srvsvc_net_srv_get_info(cli, mem_ctx, info_level, - &ctr); + server_name = talloc_asprintf_strupper_m(mem_ctx, "\\\\%s", + cli->cli->desthost); + W_ERROR_HAVE_NO_MEMORY(server_name); + + status = rpccli_srvsvc_NetSrvGetInfo(cli, mem_ctx, + server_name, + info_level, + &info, + &result); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } if (!W_ERROR_IS_OK(result)) { goto done; @@ -205,10 +203,10 @@ static WERROR cmd_srvsvc_srv_query_info(struct rpc_pipe_client *cli, switch (info_level) { case 101: - display_srv_info_101(&ctr.srv.sv101); + display_srv_info_101(info.info101); break; case 102: - display_srv_info_102(&ctr.srv.sv102); + display_srv_info_102(info.info102); break; default: printf("unsupported info level %d\n", info_level); @@ -404,9 +402,10 @@ static WERROR cmd_srvsvc_net_remote_tod(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - TIME_OF_DAY_INFO tod; + struct srvsvc_NetRemoteTODInfo *tod = NULL; fstring srv_name_slash; WERROR result; + NTSTATUS status; if (argc > 1) { printf("Usage: %s\n", argv[0]); @@ -414,8 +413,14 @@ static WERROR cmd_srvsvc_net_remote_tod(struct rpc_pipe_client *cli, } fstr_sprintf(srv_name_slash, "\\\\%s", cli->cli->desthost); - result = rpccli_srvsvc_net_remote_tod( - cli, mem_ctx, srv_name_slash, &tod); + status = rpccli_srvsvc_NetRemoteTOD(cli, mem_ctx, + srv_name_slash, + &tod, + &result); + if (!NT_STATUS_IS_OK(status)) { + result = ntstatus_to_werror(status); + goto done; + } if (!W_ERROR_IS_OK(result)) goto done; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 4a9b4acb7d..5e87058111 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -503,6 +503,7 @@ extern struct cmd_set echo_commands[]; extern struct cmd_set shutdown_commands[]; extern struct cmd_set test_commands[]; extern struct cmd_set wkssvc_commands[]; +extern struct cmd_set ntsvcs_commands[]; static struct cmd_set *rpcclient_command_list[] = { rpcclient_commands, @@ -517,6 +518,7 @@ static struct cmd_set *rpcclient_command_list[] = { shutdown_commands, test_commands, wkssvc_commands, + ntsvcs_commands, NULL }; diff --git a/source3/script/installbin.sh.in b/source3/script/installbin.sh.in index 59a6c31ca8..c607d9e445 100755 --- a/source3/script/installbin.sh.in +++ b/source3/script/installbin.sh.in @@ -19,15 +19,6 @@ for p in $*; do fi cp $p $DESTDIR/$BINDIR/ chmod $INSTALLPERMS $DESTDIR/$BINDIR/$p2 - - # this is a special case, mount needs this in a specific location - if [ $p2 = smbmount ]; then - if [ ! -d $DESTDIR/@rootsbindir@ ]; then - mkdir $DESTDIR/@rootsbindir@ - fi - echo "Creating sym link $DESTDIR/@rootsbindir@/mount.smbfs to $BINDIR/$p2 " - ln -sf $BINDIR/$p2 $DESTDIR/@rootsbindir@/mount.smbfs - fi done diff --git a/source3/script/installman.sh b/source3/script/installman.sh index 7edc707ab0..869ce6ee38 100755 --- a/source3/script/installman.sh +++ b/source3/script/installman.sh @@ -49,7 +49,6 @@ for lang in $langs; do # Check if this man page if required by the configured feature set case "${MP_BASENAME}" in smbsh.1) test -z "${SMBWRAPPER}" && continue ;; - smbmnt.8|smbmount.8|smbumount.8) test -z "${SMBMOUNT_PROGS}" && continue ;; *) ;; esac diff --git a/source3/script/mkproto.sh b/source3/script/mkproto.sh index e46e73e3e9..8561f42dff 100755 --- a/source3/script/mkproto.sh +++ b/source3/script/mkproto.sh @@ -25,7 +25,7 @@ header="$1" shift headertmp="$header.$$.tmp~" -proto_src="`echo $@ | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort | uniq | egrep -v 'tdb/|wrapped|modules/getdate'`" +proto_src="`echo $@ | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort | uniq | egrep -v 'tdb/|wrapped|modules/getdate' | egrep -v '\.a$'`" echo creating $header diff --git a/source3/script/mksyms.awk b/source3/script/mksyms.awk new file mode 100644 index 0000000000..a30bea4d34 --- /dev/null +++ b/source3/script/mksyms.awk @@ -0,0 +1,76 @@ +# +# mksyms.awk +# +# Extract symbols to export from C-header files. +# output in version-script format for linking shared libraries. +# +# Copyright (C) 2008 Micheal Adam <obnox@samba.org> +# +BEGIN { + inheader=0; + current_file=""; + print "#" + print "# This file is automatically generated with \"make symbols\". DO NOT EDIT " + print "#" + print "{" + print "\tglobal:" +} + +END { + print"" + print "\tlocal: *;" + print "};" +} + +{ + if (FILENAME!=current_file) { + print "\t\t# The following definitions come from",FILENAME + current_file=FILENAME + } + if (inheader) { + if (match($0,"[)][ \t]*[;][ \t]*$")) { + inheader = 0; + } + next; + } +} + +/^static/ || /^[ \t]*typedef/ || !/^[a-zA-Z\_]/ { + next; +} + +/^extern[ \t]+[^()]+[;][ \t]*$/ { + gsub(/[^ \t]+[ \t]+/, ""); + sub(/[;][ \t]*$/, ""); + printf "\t\t%s;\n", $0; + next; +} + +# look for function headers: +{ + gotstart = 0; + if ($0 ~ /^[A-Za-z_][A-Za-z0-9_]+/) { + gotstart = 1; + } + if(!gotstart) { + next; + } +} + +/[_A-Za-z0-9]+[ \t]*[(].*[)][ \t]*;[ \t]*$/ { + sub(/[(].*$/, ""); + gsub(/[^ \t]+[ \t]+/, ""); + gsub(/^[*]/, ""); + printf "\t\t%s;\n",$0; + next; +} + +/[_A-Za-z0-9]+[ \t]*[(]/ { + inheader=1; + sub(/[(].*$/, ""); + gsub(/[^ \t]+[ \t]+/, ""); + gsub(/^[*]/, ""); + printf "\t\t%s;\n",$0; + next; +} + diff --git a/source3/script/mksyms.sh b/source3/script/mksyms.sh new file mode 100755 index 0000000000..637ec5027c --- /dev/null +++ b/source3/script/mksyms.sh @@ -0,0 +1,45 @@ +#! /bin/sh + +# +# mksyms.sh +# +# Extract symbols to export from C-header files. +# output in version-script format for linking shared libraries. +# +# This is the shell warpper for the mksyms.awk core script. +# +# Copyright (C) 2008 Micheal Adam <obnox@samba.org> +# + +LANG=C; export LANG +LC_ALL=C; export LC_ALL +LC_COLLATE=C; export LC_COLLATE + +if [ $# -lt 2 ] +then + echo "Usage: $0 awk output_file header_files" + exit 1 +fi + +awk="$1" +shift + +symsfile="$1" +shift +symsfile_tmp="$symsfile.$$.tmp~" + +proto_src="`echo $@ | tr ' ' '\n' | sort | uniq `" + +echo creating $symsfile + +mkdir -p `dirname $symsfile` + +${awk} -f script/mksyms.awk $proto_src > $symsfile_tmp + +if cmp -s $symsfile $symsfile_tmp 2>/dev/null +then + echo "$symsfile unchanged" + rm $symsfile_tmp +else + mv $symsfile_tmp $symsfile +fi diff --git a/source3/script/tests/test_posix_s3.sh b/source3/script/tests/test_posix_s3.sh index 91863b7a6b..7b4c0224ba 100755 --- a/source3/script/tests/test_posix_s3.sh +++ b/source3/script/tests/test_posix_s3.sh @@ -54,6 +54,8 @@ skipped="$skipped RAW-SFILEINFO" echo "WARNING: Skipping tests $skipped" +ADDARGS="$ADDARGS --option=torture:sharedelay=100000" + failed=0 for t in $tests; do if [ ! -z "$start" -a "$start" != $t ]; then diff --git a/source3/script/uninstallbin.sh.in b/source3/script/uninstallbin.sh.in index e1bbf6ecb1..8064db8d95 100755 --- a/source3/script/uninstallbin.sh.in +++ b/source3/script/uninstallbin.sh.in @@ -26,12 +26,6 @@ for p in $*; do echo "Cannot remove $DESTDIR/$BINDIR/$p2 ... does $USER have privileges? " fi fi - - # this is a special case, mount needs this in a specific location - if test "$p2" = smbmount -a -f "$DESTDIR/sbin/mount.smbfs"; then - echo "Removing $DESTDIR/sbin/mount.smbfs " - rm -f "$DESTDIR/@rootsbindir@/sbin/mount.smbfs" - fi done diff --git a/source3/services/services_db.c b/source3/services/services_db.c index d4e144d5ff..ae83e72697 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -469,7 +469,7 @@ void svcctl_init_keys( void ) fetch_reg_keys( key, subkeys ); - /* the builting services exist */ + /* the builtin services exist */ for ( i=0; builtin_svcs[i].servicename; i++ ) add_new_svc_name( key, subkeys, builtin_svcs[i].servicename ); @@ -520,25 +520,21 @@ SEC_DESC *svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); - SAFE_FREE(path); - return NULL; + goto done; } - SAFE_FREE(path); if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("svcctl_get_secdesc: talloc() failed!\n")); - TALLOC_FREE( key ); - return NULL; + goto done; } - fetch_reg_values( key, values ); - - TALLOC_FREE(key); + if (fetch_reg_values( key, values ) == -1) { + DEBUG(0, ("Error getting registry values\n")); + goto done; + } if ( !(val = regval_ctr_getvalue( values, "Security" )) ) { - DEBUG(6,("svcctl_get_secdesc: constructing default secdesc for service [%s]\n", - name)); - return construct_service_sd( ctx ); + goto fallback_to_default_sd; } /* stream the service security descriptor */ @@ -546,10 +542,18 @@ SEC_DESC *svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * status = unmarshall_sec_desc(ctx, regval_data_p(val), regval_size(val), &ret_sd); - if (!NT_STATUS_IS_OK(status)) { - return construct_service_sd( ctx ); + if (NT_STATUS_IS_OK(status)) { + goto done; } +fallback_to_default_sd: + DEBUG(6, ("svcctl_get_secdesc: constructing default secdesc for " + "service [%s]\n", name)); + ret_sd = construct_service_sd(ctx); + +done: + SAFE_FREE(path); + TALLOC_FREE(key); return ret_sd; } diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index 86fdfe31b7..2889e3c13f 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -141,21 +141,27 @@ static struct aio_extra *find_aio_ex(uint16 mid) We can have these many aio buffers in flight. *****************************************************************************/ -#define AIO_PENDING_SIZE 10 +static int aio_pending_size; static sig_atomic_t signals_received; static int outstanding_aio_calls; -static uint16 aio_pending_array[AIO_PENDING_SIZE]; +static uint16 *aio_pending_array; /**************************************************************************** Signal handler when an aio request completes. *****************************************************************************/ -static void signal_handler(int sig, siginfo_t *info, void *unused) +void aio_request_done(uint16_t mid) { - if (signals_received < AIO_PENDING_SIZE) { - aio_pending_array[signals_received] = info->si_value.sival_int; + if (signals_received < aio_pending_size) { + aio_pending_array[signals_received] = mid; signals_received++; - } /* Else signal is lost. */ + } + /* Else signal is lost. */ +} + +static void signal_handler(int sig, siginfo_t *info, void *unused) +{ + aio_request_done(info->si_value.sival_int); sys_select_signal(RT_SIGNAL_AIO); } @@ -176,6 +182,10 @@ void initialize_async_io_handler(void) { struct sigaction act; + aio_pending_size = lp_maxmux(); + aio_pending_array = SMB_MALLOC_ARRAY(uint16, aio_pending_size); + SMB_ASSERT(aio_pending_array != NULL); + ZERO_STRUCT(act); act.sa_sigaction = signal_handler; act.sa_flags = SA_SIGINFO; @@ -202,6 +212,12 @@ bool schedule_aio_read_and_X(connection_struct *conn, size_t bufsize; size_t min_aio_read_size = lp_aio_read_size(SNUM(conn)); + if (fsp->base_fsp != NULL) { + /* No AIO on streams yet */ + DEBUG(10, ("AIO on streams not yet supported\n")); + return false; + } + if ((!min_aio_read_size || (smb_maxcnt < min_aio_read_size)) && !SMB_VFS_AIO_FORCE(fsp)) { /* Too small a read for aio request. */ @@ -219,7 +235,7 @@ bool schedule_aio_read_and_X(connection_struct *conn, return False; } - if (outstanding_aio_calls >= AIO_PENDING_SIZE) { + if (outstanding_aio_calls >= aio_pending_size) { DEBUG(10,("schedule_aio_read_and_X: Already have %d aio " "activities outstanding.\n", outstanding_aio_calls )); @@ -285,6 +301,12 @@ bool schedule_aio_write_and_X(connection_struct *conn, bool write_through = BITSETW(req->inbuf+smb_vwv7,0); size_t min_aio_write_size = lp_aio_write_size(SNUM(conn)); + if (fsp->base_fsp != NULL) { + /* No AIO on streams yet */ + DEBUG(10, ("AIO on streams not yet supported\n")); + return false; + } + if ((!min_aio_write_size || (numtowrite < min_aio_write_size)) && !SMB_VFS_AIO_FORCE(fsp)) { /* Too small a write for aio request. */ @@ -302,7 +324,7 @@ bool schedule_aio_write_and_X(connection_struct *conn, return False; } - if (outstanding_aio_calls >= AIO_PENDING_SIZE) { + if (outstanding_aio_calls >= aio_pending_size) { DEBUG(3,("schedule_aio_write_and_X: Already have %d aio " "activities outstanding.\n", outstanding_aio_calls )); @@ -351,6 +373,8 @@ bool schedule_aio_write_and_X(connection_struct *conn, return False; } + release_level_2_oplocks_on_change(fsp); + if (!write_through && !lp_syncalways(SNUM(fsp->conn)) && fsp->aio_write_behind) { /* Lie to the client and immediately claim we finished the @@ -421,6 +445,9 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) SSVAL(outbuf,smb_vwv7,((nread >> 16) & 1)); SSVAL(smb_buf(outbuf),-2,nread); + aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nread; + aio_ex->fsp->fh->position_information = aio_ex->fsp->fh->pos; + DEBUG( 3, ( "handle_aio_read_complete file %s max=%d " "nread=%d\n", aio_ex->fsp->fsp_name, @@ -522,6 +549,8 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n", fsp->fsp_name, nt_errstr(status) )); } + + aio_ex->fsp->fh->pos = aio_ex->acb.aio_offset + nwritten; } show_msg(outbuf); diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c index 73cee440d4..fa0f0ed51d 100644 --- a/source3/smbd/notify_inotify.c +++ b/source3/smbd/notify_inotify.c @@ -29,10 +29,12 @@ #include <asm/types.h> #endif +#ifndef HAVE_INOTIFY_INIT + #include <linux/inotify.h> #include <asm/unistd.h> -#ifndef HAVE_INOTIFY_INIT + /* glibc doesn't define these functions yet (as of March 2006) */ @@ -50,6 +52,10 @@ static int inotify_rm_watch(int fd, int wd) { return syscall(__NR_inotify_rm_watch, fd, wd); } +#else + +#include <sys/inotify.h> + #endif diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 9381174af0..5293ca5347 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -558,7 +558,7 @@ void reply_ntcreate_and_X(struct smb_request *req) } file_len = sbuf.st_size; - fattr = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fsp->fsp_name,&sbuf); if (fattr == 0) { fattr = FILE_ATTRIBUTE_NORMAL; } @@ -626,7 +626,7 @@ void reply_ntcreate_and_X(struct smb_request *req) uint32 perms = 0; p += 25; if (fsp->is_directory - || can_write_to_file(conn, fname, &sbuf)) { + || can_write_to_file(conn, fsp->fsp_name, &sbuf)) { perms = FILE_GENERIC_ALL; } else { perms = FILE_GENERIC_READ|FILE_EXECUTE; @@ -1007,7 +1007,7 @@ static void call_nt_transact_create(connection_struct *conn, } file_len = sbuf.st_size; - fattr = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fsp->fsp_name,&sbuf); if (fattr == 0) { fattr = FILE_ATTRIBUTE_NORMAL; } @@ -1075,7 +1075,7 @@ static void call_nt_transact_create(connection_struct *conn, uint32 perms = 0; p += 25; if (fsp->is_directory - || can_write_to_file(conn, fname, &sbuf)) { + || can_write_to_file(conn, fsp->fsp_name, &sbuf)) { perms = FILE_GENERIC_ALL; } else { perms = FILE_GENERIC_READ|FILE_EXECUTE; @@ -1083,7 +1083,7 @@ static void call_nt_transact_create(connection_struct *conn, SIVAL(p,0,perms); } - DEBUG(5,("call_nt_transact_create: open name = %s\n", fname)); + DEBUG(5,("call_nt_transact_create: open name = %s\n", fsp->fsp_name)); /* Send the required number of replies */ send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index aa4bc48f3d..cc78503379 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2671,8 +2671,9 @@ NTSTATUS create_file_unixpath(connection_struct *conn, status = split_ntfs_stream_name(talloc_tos(), fname, &base, NULL); if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("split_ntfs_stream_name failed: %s\n", - nt_errstr(status))); + DEBUG(10, ("create_file_unixpath: " + "split_ntfs_stream_name failed: %s\n", + nt_errstr(status))); goto fail; } @@ -2840,7 +2841,7 @@ NTSTATUS create_file_unixpath(connection_struct *conn, } } - DEBUG(10, ("create_file: info=%d\n", info)); + DEBUG(10, ("create_file_unixpath: info=%d\n", info)); /* * Set fsp->base_fsp late enough that we can't "goto fail" anymore. In @@ -2867,7 +2868,7 @@ NTSTATUS create_file_unixpath(connection_struct *conn, return NT_STATUS_OK; fail: - DEBUG(10, ("create_file: %s\n", nt_errstr(status))); + DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status))); if (fsp != NULL) { close_file(fsp, ERROR_CLOSE); diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 687b67950a..80eba562c5 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -121,6 +121,10 @@ void invalidate_vuid(uint16 vuid) data_blob_free(&vuser->session_key); + if (vuser->auth_ntlmssp_state) { + auth_ntlmssp_end(&vuser->auth_ntlmssp_state); + } + DLIST_REMOVE(validated_users, vuser); /* clear the vuid from the 'cache' on each connection, and diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 669dad2e3a..818ff319e4 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1639,11 +1639,11 @@ void reply_open(struct smb_request *req) } size = sbuf.st_size; - fattr = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fsp->fsp_name,&sbuf); mtime = sbuf.st_mtime; if (fattr & aDIR) { - DEBUG(3,("attempt to open a directory %s\n",fname)); + DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name)); close_file(fsp,ERROR_CLOSE); reply_doserror(req, ERRDOS,ERRnoaccess); END_PROFILE(SMBopen); @@ -1802,7 +1802,7 @@ void reply_open_and_X(struct smb_request *req) sbuf.st_size = get_allocation_size(conn,fsp,&sbuf); } - fattr = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fsp->fsp_name,&sbuf); mtime = sbuf.st_mtime; if (fattr & aDIR) { close_file(fsp,ERROR_CLOSE); @@ -1985,7 +1985,7 @@ void reply_mknew(struct smb_request *req) } ts[0] = get_atimespec(&sbuf); /* atime. */ - file_ntimes(conn, fname, ts); + file_ntimes(conn, fsp->fsp_name, ts); reply_outbuf(req, 1, 0); SSVAL(req->outbuf,smb_vwv0,fsp->fnum); @@ -2000,9 +2000,9 @@ void reply_mknew(struct smb_request *req) CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); } - DEBUG( 2, ( "reply_mknew: file %s\n", fname ) ); + DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) ); DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", - fname, fsp->fh->fd, (unsigned int)fattr ) ); + fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) ); END_PROFILE(SMBcreate); return; @@ -2125,9 +2125,9 @@ void reply_ctemp(struct smb_request *req) SSVAL(req->outbuf,smb_vwv0,fsp->fnum); /* the returned filename is relative to the directory */ - s = strrchr_m(fname, '/'); + s = strrchr_m(fsp->fsp_name, '/'); if (!s) { - s = fname; + s = fsp->fsp_name; } else { s++; } @@ -2154,9 +2154,9 @@ void reply_ctemp(struct smb_request *req) CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED); } - DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) ); - DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd, - (unsigned int)sbuf.st_mode ) ); + DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) ); + DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name, + fsp->fh->fd, (unsigned int)sbuf.st_mode ) ); END_PROFILE(SMBctemp); return; diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c index ea017e08d8..d4394e5bca 100644 --- a/source3/smbd/seal.c +++ b/source3/smbd/seal.c @@ -496,12 +496,15 @@ static NTSTATUS srv_enc_spnego_negotiate(connection_struct *conn, srv_free_encryption_context(&partial_srv_trans_enc_ctx); + if (got_kerberos_mechanism) { #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - if (got_kerberos_mechanism && lp_use_kerberos_keytab() ) { status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, secblob); - } else +#else + /* Currently we don't SPNEGO negotiate + * back to NTLMSSP as we do in sessionsetupX. We should... */ + return NT_STATUS_LOGON_FAILURE; #endif - { + } else { status = srv_enc_ntlm_negotiate(ppdata, p_data_size, secblob, true); } @@ -558,7 +561,16 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn, status = auth_ntlmssp_update(ec->auth_ntlmssp_state, auth, &auth_reply); data_blob_free(&auth); - response = spnego_gen_auth_response(&auth_reply, status, OID_NTLMSSP); + /* From RFC4178. + * + * supportedMech + * + * This field SHALL only be present in the first reply from the + * target. + * So set mechOID to NULL here. + */ + + response = spnego_gen_auth_response(&auth_reply, status, NULL); data_blob_free(&auth_reply); if (NT_STATUS_IS_OK(status)) { diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 7116027adf..7bf11abfbd 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -988,7 +988,8 @@ static bool init_structs(void ) init_dptrs(); - secrets_init(); + if (!secrets_init()) + return False; return True; } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 1e4e208951..9baa02977a 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 = NULL; + struct 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; @@ -268,7 +268,7 @@ static void reply_spnego_kerberos(struct smb_request *req, fstring real_username; bool map_domainuser_to_guest = False; bool username_was_mapped; - PAC_LOGON_INFO *logon_info = NULL; + struct PAC_LOGON_INFO *logon_info = NULL; ZERO_STRUCT(ticket); ZERO_STRUCT(ap_rep); @@ -394,10 +394,9 @@ static void reply_spnego_kerberos(struct smb_request *req, domain = p+1; - if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) { - unistr2_to_ascii(netbios_domain_name, - &logon_info->info3.uni_logon_dom, - sizeof(netbios_domain_name)); + if (logon_info && logon_info->info3.base.domain.string) { + fstrcpy(netbios_domain_name, + logon_info->info3.base.domain.string); domain = netbios_domain_name; DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain)); @@ -620,6 +619,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req, uint16 vuid, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status, + const char *OID, bool wrap) { DATA_BLOB response; @@ -680,7 +680,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req, if (wrap) { response = spnego_gen_auth_response(ntlmssp_blob, - nt_status, OID_NTLMSSP); + nt_status, OID); } else { response = *ntlmssp_blob; } @@ -745,6 +745,28 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, } /**************************************************************************** + Fall back from krb5 to NTLMSSP. +****************************************************************************/ + +static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req, + uint16 vuid) +{ + DATA_BLOB response; + + reply_outbuf(req, 4, 0); + SSVAL(req->outbuf,smb_uid,vuid); + + DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO " + "but set to downgrade to NTLMSSP\n")); + + response = spnego_gen_auth_response(NULL, + NT_STATUS_MORE_PROCESSING_REQUIRED, + OID_NTLMSSP); + reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED); + data_blob_free(&response); +} + +/**************************************************************************** Reply to a session setup spnego negotiate packet. ****************************************************************************/ @@ -789,6 +811,15 @@ static void reply_spnego_negotiate(struct smb_request *req, auth_ntlmssp_end(auth_ntlmssp_state); } + if (got_kerberos_mechanism) { + data_blob_free(&secblob); + /* The mechtoken is a krb5 ticket, but + * we need to fall back to NTLM. */ + reply_spnego_downgrade_to_ntlmssp(req, + vuid); + return; + } + status = auth_ntlmssp_start(auth_ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ @@ -803,7 +834,7 @@ static void reply_spnego_negotiate(struct smb_request *req, data_blob_free(&secblob); reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state, - &chal, status, True); + &chal, status, OID_NTLMSSP, true); data_blob_free(&chal); @@ -823,7 +854,7 @@ static void reply_spnego_auth(struct smb_request *req, DATA_BLOB auth = data_blob_null; DATA_BLOB auth_reply = data_blob_null; DATA_BLOB secblob = data_blob_null; - NTSTATUS status = NT_STATUS_INVALID_PARAMETER; + NTSTATUS status = NT_STATUS_LOGON_FAILURE; if (!spnego_parse_auth(blob1, &auth)) { #if 0 @@ -833,7 +864,7 @@ static void reply_spnego_auth(struct smb_request *req, invalidate_vuid(vuid); reply_nterror(req, nt_status_squash( - NT_STATUS_INVALID_PARAMETER)); + NT_STATUS_LOGON_FAILURE)); return; } @@ -843,24 +874,43 @@ static void reply_spnego_auth(struct smb_request *req, bool got_krb5_mechanism = False; status = parse_spnego_mechanisms(auth, &secblob, &got_krb5_mechanism); - if (NT_STATUS_IS_OK(status)) { - DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", - (unsigned long)secblob.length)); + + if (!NT_STATUS_IS_OK(status)) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + reply_nterror(req, nt_status_squash(status)); + return; + } + + DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", + (unsigned long)secblob.length)); #ifdef HAVE_KRB5 - if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || - lp_use_kerberos_keytab()) ) { - bool destroy_vuid = True; - reply_spnego_kerberos(req, &secblob, - vuid, &destroy_vuid); - data_blob_free(&secblob); - data_blob_free(&auth); - if (destroy_vuid) { - /* Kill the intermediate vuid */ - invalidate_vuid(vuid); - } - return; + if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || + lp_use_kerberos_keytab()) ) { + bool destroy_vuid = True; + reply_spnego_kerberos(req, &secblob, + vuid, &destroy_vuid); + data_blob_free(&secblob); + data_blob_free(&auth); + if (destroy_vuid) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); } + return; + } #endif + /* Can't blunder into NTLMSSP auth if we have + * a krb5 ticket. */ + + if (got_krb5_mechanism) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + DEBUG(3,("reply_spnego_auth: network " + "misconfiguration, client sent us a " + "krb5 ticket and kerberos security " + "not enabled")); + reply_nterror(req, nt_status_squash( + NT_STATUS_LOGON_FAILURE)); } } @@ -868,13 +918,13 @@ static void reply_spnego_auth(struct smb_request *req, data_blob_free(&secblob); if (!*auth_ntlmssp_state) { - /* Kill the intermediate vuid */ - invalidate_vuid(vuid); - - /* auth before negotiatiate? */ - reply_nterror(req, nt_status_squash( - NT_STATUS_INVALID_PARAMETER)); - return; + status = auth_ntlmssp_start(auth_ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + reply_nterror(req, nt_status_squash(status)); + return; + } } status = auth_ntlmssp_update(*auth_ntlmssp_state, @@ -882,9 +932,11 @@ static void reply_spnego_auth(struct smb_request *req, data_blob_free(&auth); + /* Don't send the mechid as we've already sent this (RFC4178). */ + reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state, - &auth_reply, status, True); + &auth_reply, status, NULL, true); data_blob_free(&auth_reply); @@ -1251,7 +1303,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req) reply_spnego_ntlmssp(req, vuid, &vuser->auth_ntlmssp_state, - &chal, status, False); + &chal, status, OID_NTLMSSP, false); data_blob_free(&chal); return; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 1f7af82670..dc908846b3 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1017,7 +1017,7 @@ static void call_trans2open(connection_struct *conn, } size = get_file_size(sbuf); - fattr = dos_mode(conn,fname,&sbuf); + fattr = dos_mode(conn,fsp->fsp_name,&sbuf); mtime = sbuf.st_mtime; inode = sbuf.st_ino; if (fattr & aDIR) { @@ -1054,7 +1054,7 @@ static void call_trans2open(connection_struct *conn, SIVAL(params,20,inode); SSVAL(params,24,0); /* Padding. */ if (flags & 8) { - uint32 ea_size = estimate_ea_size(conn, fsp, fname); + uint32 ea_size = estimate_ea_size(conn, fsp, fsp->fsp_name); SIVAL(params, 26, ea_size); } else { SIVAL(params, 26, 0); diff --git a/source3/tests/os2_delete.c b/source3/tests/os2_delete.c deleted file mode 100644 index b3aaf67f41..0000000000 --- a/source3/tests/os2_delete.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - test readdir/unlink pattern that OS/2 uses - tridge@samba.org July 2005 -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <unistd.h> -#include <sys/types.h> -#include <dirent.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> - -#define NUM_FILES 700 -#define READDIR_SIZE 100 -#define DELETE_SIZE 4 - -#define TESTDIR "test.dir" - -#define FAILED(d) (fprintf(stderr, "Failed for %s - %s\n", d, strerror(errno)), exit(1), 1) - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -static void cleanup(void) -{ - /* I'm a lazy bastard */ - system("rm -rf " TESTDIR); - mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir"); -} - -static void create_files() -{ - int i; - for (i=0;i<NUM_FILES;i++) { - char fname[40]; - sprintf(fname, TESTDIR "/test%u.txt", i); - close(open(fname, O_CREAT|O_RDWR, 0600)) == 0 || FAILED("close"); - } -} - -static int os2_delete(DIR *d) -{ - off_t offsets[READDIR_SIZE]; - int i, j; - struct dirent *de; - char names[READDIR_SIZE][30]; - - /* scan, remembering offsets */ - for (i=0, de=readdir(d); - de && i < READDIR_SIZE; - de=readdir(d), i++) { - offsets[i] = telldir(d); - strcpy(names[i], de->d_name); - } - - if (i == 0) { - return 0; - } - - /* delete the first few */ - for (j=0; j<MIN(i, DELETE_SIZE); j++) { - char fname[40]; - sprintf(fname, TESTDIR "/%s", names[j]); - unlink(fname) == 0 || FAILED("unlink"); - } - - /* seek to just after the deletion */ - seekdir(d, offsets[j-1]); - - /* return number deleted */ - return j; -} - -int main(void) -{ - int total_deleted = 0; - DIR *d; - struct dirent *de; - - cleanup(); - create_files(); - - d = opendir(TESTDIR); - - /* skip past . and .. */ - de = readdir(d); - strcmp(de->d_name, ".") == 0 || FAILED("match ."); - de = readdir(d); - strcmp(de->d_name, "..") == 0 || FAILED("match .."); - - while (1) { - int n = os2_delete(d); - if (n == 0) break; - total_deleted += n; - } - closedir(d); - - printf("Deleted %d files of %d\n", total_deleted, NUM_FILES); - - rmdir(TESTDIR) == 0 || FAILED("rmdir"); - - return 0; -} -/* - test readdir/unlink pattern that OS/2 uses - tridge@samba.org July 2005 -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <unistd.h> -#include <sys/types.h> -#include <dirent.h> -#include <errno.h> -#include <string.h> -#include <fcntl.h> - -#define NUM_FILES 700 -#define READDIR_SIZE 100 -#define DELETE_SIZE 4 - -#define TESTDIR "test.dir" - -#define FAILED(d) (fprintf(stderr, "Failed for %s - %s\n", d, strerror(errno)), exit(1), 1) - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -static void cleanup(void) -{ - /* I'm a lazy bastard */ - system("rm -rf " TESTDIR); - mkdir(TESTDIR, 0700) == 0 || FAILED("mkdir"); -} - -static void create_files() -{ - int i; - for (i=0;i<NUM_FILES;i++) { - char fname[40]; - sprintf(fname, TESTDIR "/test%u.txt", i); - close(open(fname, O_CREAT|O_RDWR, 0600)) == 0 || FAILED("close"); - } -} - -static int os2_delete(DIR *d) -{ - off_t offsets[READDIR_SIZE]; - int i, j; - struct dirent *de; - char names[READDIR_SIZE][30]; - - /* scan, remembering offsets */ - for (i=0, de=readdir(d); - de && i < READDIR_SIZE; - de=readdir(d), i++) { - offsets[i] = telldir(d); - strcpy(names[i], de->d_name); - } - - if (i == 0) { - return 0; - } - - /* delete the first few */ - for (j=0; j<MIN(i, DELETE_SIZE); j++) { - char fname[40]; - sprintf(fname, TESTDIR "/%s", names[j]); - unlink(fname) == 0 || FAILED("unlink"); - } - - /* seek to just after the deletion */ - seekdir(d, offsets[j-1]); - - /* return number deleted */ - return j; -} - -int main(void) -{ - int total_deleted = 0; - DIR *d; - struct dirent *de; - - cleanup(); - create_files(); - - d = opendir(TESTDIR); - - /* skip past . and .. */ - de = readdir(d); - strcmp(de->d_name, ".") == 0 || FAILED("match ."); - de = readdir(d); - strcmp(de->d_name, "..") == 0 || FAILED("match .."); - - while (1) { - int n = os2_delete(d); - if (n == 0) break; - total_deleted += n; - } - closedir(d); - - printf("Deleted %d files of %d\n", total_deleted, NUM_FILES); - - rmdir(TESTDIR) == 0 || FAILED("rmdir"); - - return 0; -} diff --git a/source3/tests/shared_mmap.c b/source3/tests/shared_mmap.c deleted file mode 100644 index fcef75d0d6..0000000000 --- a/source3/tests/shared_mmap.c +++ /dev/null @@ -1,68 +0,0 @@ -/* this tests whether we can use a shared writeable mmap on a file - - as needed for the mmap varient of FAST_SHARE_MODES */ - -#if defined(HAVE_UNISTD_H) -#include <unistd.h> -#endif -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#define DATA "conftest.mmap" - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -main() -{ - int *buf; - int i; - int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666); - int count=7; - - if (fd == -1) exit(1); - - for (i=0;i<10000;i++) { - write(fd,&i,sizeof(i)); - } - - close(fd); - - if (fork() == 0) { - fd = open(DATA,O_RDWR); - if (fd == -1) exit(1); - - buf = (int *)mmap(NULL, 10000*sizeof(int), - (PROT_READ | PROT_WRITE), - MAP_FILE | MAP_SHARED, - fd, 0); - - while (count-- && buf[9124] != 55732) sleep(1); - - if (count <= 0) exit(1); - - buf[1763] = 7268; - exit(0); - } - - fd = open(DATA,O_RDWR); - if (fd == -1) exit(1); - - buf = (int *)mmap(NULL, 10000*sizeof(int), - (PROT_READ | PROT_WRITE), - MAP_FILE | MAP_SHARED, - fd, 0); - - if (buf == (int *)-1) exit(1); - - buf[9124] = 55732; - - while (count-- && buf[1763] != 7268) sleep(1); - - unlink(DATA); - - if (count > 0) exit(0); - exit(1); -} diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 82a28bd868..9359b58599 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -842,7 +842,6 @@ static NTSTATUS cmd_ftruncate(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int ar static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv) { - bool ret; int fd; int op; long offset; @@ -914,7 +913,7 @@ static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c printf("lock: debug lock(fd=%d, op=%d, offset=%ld, count=%ld, type=%d))\n", fd, op, offset, count, type); - if ((ret = SMB_VFS_LOCK(vfs->files[fd], op, offset, count, type)) == False) { + if (SMB_VFS_LOCK(vfs->files[fd], op, offset, count, type) == False) { printf("lock: error=%d (%s)\n", errno, strerror(errno)); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/torture/samtest.h b/source3/torture/samtest.h deleted file mode 100644 index 5cde3fadb5..0000000000 --- a/source3/torture/samtest.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SAM module tester - - Copyright (C) Jelmer Vernooij 2002 - - Most of this code was ripped off of rpcclient. - Copyright (C) Tim Potter 2000-2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -struct samtest_state { - SAM_CONTEXT *context; - NT_USER_TOKEN *token; -}; - -struct cmd_set { - char *name; - NTSTATUS (*fn)(struct samtest_state *sam, TALLOC_CTX *mem_ctx, int argc, - char **argv); - char *description; - char *usage; -}; - - diff --git a/source3/torture/smbiconv.c b/source3/torture/smbiconv.c index 05a8c3d815..72fbdc470f 100644 --- a/source3/torture/smbiconv.c +++ b/source3/torture/smbiconv.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#undef realloc static int process_block (smb_iconv_t cd, const char *addr, size_t len, FILE *output) @@ -85,7 +86,7 @@ incomplete character or shift sequence at end of buffer")); static int -process_fd (iconv_t cd, int fd, FILE *output) +process_fd (smb_iconv_t cd, int fd, FILE *output) { /* we have a problem with reading from a descriptor since we must not provide the iconv() function an incomplete character or shift @@ -167,8 +168,8 @@ process_fd (iconv_t cd, int fd, FILE *output) int main(int argc, char *argv[]) { const char *file = NULL; - char *from = ""; - char *to = ""; + const char *from = ""; + const char *to = ""; char *output = NULL; const char *preload_modules[] = {NULL, NULL}; FILE *out = stdout; @@ -213,7 +214,7 @@ int main(int argc, char *argv[]) } cd = smb_iconv_open(to, from); - if((int)cd == -1) { + if (cd == (smb_iconv_t)-1) { DEBUG(0,("unable to find from or to encoding, exiting...\n")); return 1; } diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 732ba8d8b6..46e0a2591b 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -23,6 +23,8 @@ #include "includes.h" #include "utils/net.h" +#include "libnet/libnet.h" + #ifdef HAVE_ADS int net_ads_usage(int argc, const char **argv) @@ -810,76 +812,65 @@ static int net_ads_status(int argc, const char **argv) static int net_ads_leave(int argc, const char **argv) { - ADS_STRUCT *ads = NULL; - ADS_STATUS adsret; - NTSTATUS status; - int ret = -1; - struct cli_state *cli = NULL; TALLOC_CTX *ctx; - DOM_SID *dom_sid = NULL; - const char *short_domain_name = NULL; - - if (!secrets_init()) { - DEBUG(1,("Failed to initialise secrets database\n")); - return -1; - } + struct libnet_UnjoinCtx *r = NULL; + WERROR werr; if (!(ctx = talloc_init("net_ads_leave"))) { d_fprintf(stderr, "Could not initialise talloc context.\n"); return -1; } - /* The finds a DC and takes care of getting the - user creds if necessary */ + use_in_memory_ccache(); - if (!ADS_ERR_OK(ads_startup(True, &ads))) { + werr = libnet_init_UnjoinCtx(ctx, &r); + if (!W_ERROR_IS_OK(werr)) { + d_fprintf(stderr, "Could not initialise unjoin context.\n"); return -1; } - /* make RPC calls here */ + r->in.debug = opt_verbose; + r->in.dc_name = opt_host; + r->in.domain_name = lp_realm(); + r->in.admin_account = opt_user_name; + r->in.admin_password = net_prompt_pass(opt_user_name); + r->in.unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE; - if ( !NT_STATUS_IS_OK(connect_to_ipc_krb5(&cli, &ads->ldap.ss, - ads->config.ldap_server_name)) ) - { + werr = libnet_Unjoin(ctx, r); + if (!W_ERROR_IS_OK(werr)) { + d_printf("Failed to leave domain: %s\n", + r->out.error_string ? r->out.error_string : + get_friendly_werror_msg(werr)); goto done; } - if ( !NT_STATUS_IS_OK(netdom_get_domain_sid( ctx, cli, &short_domain_name, &dom_sid )) ) { + if (W_ERROR_IS_OK(werr)) { + d_printf("Deleted account for '%s' in realm '%s'\n", + r->in.machine_name, r->out.dns_domain_name); goto done; } - saf_delete( short_domain_name ); - - status = netdom_leave_domain(ctx, cli, dom_sid); - - /* Try and delete it via LDAP - the old way we used to. */ - - adsret = ads_leave_realm(ads, global_myname()); - if (ADS_ERR_OK(adsret)) { - d_printf("Deleted account for '%s' in realm '%s'\n", - global_myname(), ads->config.realm); - ret = 0; - } else { - /* We couldn't delete it - see if the disable succeeded. */ - if (NT_STATUS_IS_OK(status)) { - d_printf("Disabled account for '%s' in realm '%s'\n", - global_myname(), ads->config.realm); - ret = 0; - } else { - d_fprintf(stderr, "Failed to disable machine account for '%s' in realm '%s'\n", - global_myname(), ads->config.realm); - } + /* We couldn't delete it - see if the disable succeeded. */ + if (r->out.disabled_machine_account) { + d_printf("Disabled account for '%s' in realm '%s'\n", + r->in.machine_name, r->out.dns_domain_name); + werr = WERR_OK; + goto done; } -done: + d_fprintf(stderr, "Failed to disable machine account for '%s' in realm '%s'\n", + r->in.machine_name, r->out.dns_domain_name); - if ( cli ) - cli_shutdown(cli); + done: + TALLOC_FREE(r); + TALLOC_FREE(ctx); - ads_destroy(&ads); - TALLOC_FREE( ctx ); + if (W_ERROR_IS_OK(werr)) { + return 0; + } - return ret; + return -1; } static NTSTATUS net_ads_join_ok(void) @@ -957,338 +948,6 @@ static NTSTATUS check_ads_config( void ) } /******************************************************************* - Do the domain join - ********************************************************************/ - -static NTSTATUS net_join_domain(TALLOC_CTX *ctx, const char *servername, - struct sockaddr_storage *pss, - const char **domain, - DOM_SID **dom_sid, - const char *password) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct cli_state *cli = NULL; - - ret = connect_to_ipc_krb5(&cli, pss, servername); - if ( !NT_STATUS_IS_OK(ret) ) { - goto done; - } - - ret = netdom_get_domain_sid( ctx, cli, domain, dom_sid ); - if ( !NT_STATUS_IS_OK(ret) ) { - goto done; - } - - /* cli->server_domain is not filled in when using krb5 - session setups */ - - saf_store( *domain, cli->desthost ); - - ret = netdom_join_domain( ctx, cli, *dom_sid, password, ND_TYPE_AD ); - -done: - if ( cli ) - cli_shutdown(cli); - - return ret; -} - -/******************************************************************* - Set a machines dNSHostName and servicePrincipalName attributes - ********************************************************************/ - -static ADS_STATUS net_set_machine_spn(TALLOC_CTX *ctx, ADS_STRUCT *ads_s ) -{ - ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN); - char *new_dn; - ADS_MODLIST mods; - const char *servicePrincipalName[3] = {NULL, NULL, NULL}; - char *psp; - fstring my_fqdn; - LDAPMessage *res = NULL; - char *dn_string = NULL; - const char *machine_name = global_myname(); - int count; - - if ( !machine_name ) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* Find our DN */ - - status = ads_find_machine_acct(ads_s, &res, machine_name); - if (!ADS_ERR_OK(status)) - return status; - - if ( (count = ads_count_replies(ads_s, res)) != 1 ) { - DEBUG(1,("net_set_machine_spn: %d entries returned!\n", count)); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - if ( (dn_string = ads_get_dn(ads_s, res)) == NULL ) { - DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); - goto done; - } - - new_dn = talloc_strdup(ctx, dn_string); - ads_memfree(ads_s, dn_string); - if (!new_dn) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* Windows only creates HOST/shortname & HOST/fqdn. */ - - if ( !(psp = talloc_asprintf(ctx, "HOST/%s", machine_name)) ) - goto done; - strupper_m(psp); - servicePrincipalName[0] = psp; - - name_to_fqdn(my_fqdn, machine_name); - strlower_m(my_fqdn); - if ( !(psp = talloc_asprintf(ctx, "HOST/%s", my_fqdn)) ) - goto done; - servicePrincipalName[1] = psp; - - if (!(mods = ads_init_mods(ctx))) { - goto done; - } - - /* fields of primary importance */ - - ads_mod_str(ctx, &mods, "dNSHostName", my_fqdn); - ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName); - - status = ads_gen_mod(ads_s, new_dn, mods); - -done: - ads_msgfree(ads_s, res); - - return status; -} - -/******************************************************************* - Set a machines dNSHostName and servicePrincipalName attributes - ********************************************************************/ - -static ADS_STATUS net_set_machine_upn(TALLOC_CTX *ctx, ADS_STRUCT *ads_s, const char *upn ) -{ - ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN); - char *new_dn; - ADS_MODLIST mods; - LDAPMessage *res = NULL; - char *dn_string = NULL; - const char *machine_name = global_myname(); - int count; - - if ( !machine_name ) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* Find our DN */ - - status = ads_find_machine_acct(ads_s, &res, machine_name); - if (!ADS_ERR_OK(status)) - return status; - - if ( (count = ads_count_replies(ads_s, res)) != 1 ) { - DEBUG(1,("net_set_machine_spn: %d entries returned!\n", count)); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - if ( (dn_string = ads_get_dn(ads_s, res)) == NULL ) { - DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); - goto done; - } - - new_dn = talloc_strdup(ctx, dn_string); - ads_memfree(ads_s, dn_string); - if (!new_dn) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* now do the mods */ - - if (!(mods = ads_init_mods(ctx))) { - goto done; - } - - /* fields of primary importance */ - - ads_mod_str(ctx, &mods, "userPrincipalName", upn); - - status = ads_gen_mod(ads_s, new_dn, mods); - -done: - ads_msgfree(ads_s, res); - - return status; -} - -/******************************************************************* - Set a machines dNSHostName and servicePrincipalName attributes - ********************************************************************/ - -static ADS_STATUS net_set_os_attributes(TALLOC_CTX *ctx, ADS_STRUCT *ads_s, - const char *os_name, const char *os_version ) -{ - ADS_STATUS status = ADS_ERROR(LDAP_SERVER_DOWN); - char *new_dn; - ADS_MODLIST mods; - LDAPMessage *res = NULL; - char *dn_string = NULL; - const char *machine_name = global_myname(); - int count; - char *os_sp = NULL; - - if ( !os_name || !os_version ) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* Find our DN */ - - status = ads_find_machine_acct(ads_s, &res, machine_name); - if (!ADS_ERR_OK(status)) - return status; - - if ( (count = ads_count_replies(ads_s, res)) != 1 ) { - DEBUG(1,("net_set_machine_spn: %d entries returned!\n", count)); - return ADS_ERROR(LDAP_NO_MEMORY); - } - - if ( (dn_string = ads_get_dn(ads_s, res)) == NULL ) { - DEBUG(1, ("ads_add_machine_acct: ads_get_dn returned NULL (malloc failure?)\n")); - goto done; - } - - new_dn = talloc_strdup(ctx, dn_string); - ads_memfree(ads_s, dn_string); - if (!new_dn) { - return ADS_ERROR(LDAP_NO_MEMORY); - } - - /* now do the mods */ - - if (!(mods = ads_init_mods(ctx))) { - goto done; - } - - os_sp = talloc_asprintf( ctx, "Samba %s", SAMBA_VERSION_STRING ); - - /* fields of primary importance */ - - ads_mod_str(ctx, &mods, "operatingSystem", os_name); - ads_mod_str(ctx, &mods, "operatingSystemVersion", os_version); - if ( os_sp ) - ads_mod_str(ctx, &mods, "operatingSystemServicePack", os_sp); - - status = ads_gen_mod(ads_s, new_dn, mods); - -done: - ads_msgfree(ads_s, res); - TALLOC_FREE( os_sp ); - - return status; -} - -/******************************************************************* - join a domain using ADS (LDAP mods) - ********************************************************************/ - -static ADS_STATUS net_precreate_machine_acct( ADS_STRUCT *ads, const char *ou ) -{ - ADS_STATUS rc = ADS_ERROR(LDAP_SERVER_DOWN); - char *ou_str = NULL; - char *dn = NULL; - LDAPMessage *res = NULL; - bool moved; - - ou_str = ads_ou_string(ads, ou); - if (asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path) == -1) { - rc = ADS_ERROR(LDAP_NO_MEMORY); - goto done; - } - - rc = ads_search_dn(ads, &res, dn, NULL); - if (!ADS_ERR_OK(rc)) { - d_fprintf(stderr, "The specified OU does not exist.\n"); - goto done; - } - - /* Attempt to create the machine account and bail if this fails. - Assume that the admin wants exactly what they requested */ - - rc = ads_create_machine_acct( ads, global_myname(), dn ); - if (ADS_ERR_OK(rc)) { - DEBUG(1, ("machine account created\n")); - goto done; - } - if ( !(rc.error_type == ENUM_ADS_ERROR_LDAP && rc.err.rc == LDAP_ALREADY_EXISTS) ) { - DEBUG(1, ("machine account creation failed\n")); - goto done; - } - - rc = ads_move_machine_acct(ads, global_myname(), dn, &moved); - if (!ADS_ERR_OK(rc)) { - DEBUG(1, ("failure to locate/move pre-existing machine account\n")); - goto done; - } - - if (moved) { - d_printf("The machine account was moved into the specified OU.\n"); - } else { - d_printf("The machine account already exists in the specified OU.\n"); - } - -done: - ads_msgfree(ads, res); - SAFE_FREE( ou_str ); - SAFE_FREE( dn ); - - return rc; -} - -/************************************************************************ - ************************************************************************/ - -static bool net_derive_salting_principal( TALLOC_CTX *ctx, ADS_STRUCT *ads ) -{ - uint32 domain_func; - ADS_STATUS status; - fstring salt; - char *std_salt; - const char *machine_name = global_myname(); - - status = ads_domain_func_level( ads, &domain_func ); - if ( !ADS_ERR_OK(status) ) { - DEBUG(2,("Failed to determine domain functional level!\n")); - return False; - } - - /* go ahead and setup the default salt */ - - if ( (std_salt = kerberos_standard_des_salt()) == NULL ) { - d_fprintf(stderr, "net_derive_salting_principal: failed to obtain stanard DES salt\n"); - return False; - } - - fstrcpy( salt, std_salt ); - SAFE_FREE( std_salt ); - - /* if it's a Windows functional domain, we have to look for the UPN */ - - if ( domain_func == DS_DOMAIN_FUNCTION_2000 ) { - char *upn; - - upn = ads_get_upn(ads, ctx, machine_name); - if ( upn ) { - fstrcpy( salt, upn ); - } - } - - return kerberos_secrets_store_des_salt( salt ); -} - -/******************************************************************* Send a DNS update request *******************************************************************/ @@ -1443,50 +1102,35 @@ static int net_ads_join_usage(int argc, const char **argv) int net_ads_join(int argc, const char **argv) { - ADS_STRUCT *ads = NULL; - ADS_STATUS status; NTSTATUS nt_status; - const char *short_domain_name = NULL; - char *tmp_password, *password; TALLOC_CTX *ctx = NULL; - DOM_SID *domain_sid = NULL; + struct libnet_JoinCtx *r = NULL; + const char *domain = lp_realm(); + WERROR werr = WERR_SETUP_NOT_JOINED; bool createupn = False; const char *machineupn = NULL; const char *create_in_ou = NULL; int i; - fstring dc_name; - struct sockaddr_storage dcss; const char *os_name = NULL; const char *os_version = NULL; nt_status = check_ads_config(); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, "Invalid configuration. Exiting....\n"); + werr = ntstatus_to_werror(nt_status); goto fail; } - /* find a DC to initialize the server affinity cache */ - - get_dc_name( lp_workgroup(), lp_realm(), dc_name, &dcss ); - - status = ads_startup(True, &ads); - if (!ADS_ERR_OK(status)) { - DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status))); - nt_status = ads_ntstatus(status); + if (!(ctx = talloc_init("net_ads_join"))) { + d_fprintf(stderr, "Could not initialise talloc context.\n"); + werr = WERR_NOMEM; goto fail; } - if (strcmp(ads->config.realm, lp_realm()) != 0) { - d_fprintf(stderr, "realm of remote server (%s) and realm in %s " - "(%s) DO NOT match. Aborting join\n", - ads->config.realm, get_dyn_CONFIGFILE(), lp_realm()); - nt_status = NT_STATUS_INVALID_PARAMETER; - goto fail; - } + use_in_memory_ccache(); - if (!(ctx = talloc_init("net_ads_join"))) { - d_fprintf(stderr, "Could not initialise talloc context.\n"); - nt_status = NT_STATUS_NO_MEMORY; + werr = libnet_init_JoinCtx(ctx, &r); + if (!W_ERROR_IS_OK(werr)) { goto fail; } @@ -1500,203 +1144,102 @@ int net_ads_join(int argc, const char **argv) else if ( !StrnCaseCmp(argv[i], "createcomputer", strlen("createcomputer")) ) { if ( (create_in_ou = get_string_param(argv[i])) == NULL ) { d_fprintf(stderr, "Please supply a valid OU path.\n"); - nt_status = NT_STATUS_INVALID_PARAMETER; + werr = WERR_INVALID_PARAM; goto fail; } } else if ( !StrnCaseCmp(argv[i], "osName", strlen("osName")) ) { if ( (os_name = get_string_param(argv[i])) == NULL ) { d_fprintf(stderr, "Please supply a operating system name.\n"); - nt_status = NT_STATUS_INVALID_PARAMETER; + werr = WERR_INVALID_PARAM; goto fail; } } else if ( !StrnCaseCmp(argv[i], "osVer", strlen("osVer")) ) { if ( (os_version = get_string_param(argv[i])) == NULL ) { d_fprintf(stderr, "Please supply a valid operating system version.\n"); - nt_status = NT_STATUS_INVALID_PARAMETER; + werr = WERR_INVALID_PARAM; goto fail; } } else { - d_fprintf(stderr, "Bad option: %s\n", argv[i]); - nt_status = NT_STATUS_INVALID_PARAMETER; - goto fail; - } - } - - /* If we were given an OU, try to create the machine in - the OU account first and then do the normal RPC join */ - - if ( create_in_ou ) { - status = net_precreate_machine_acct( ads, create_in_ou ); - if ( !ADS_ERR_OK(status) ) { - d_fprintf( stderr, "Failed to pre-create the machine object " - "in OU %s.\n", create_in_ou); - DEBUG(1, ("error calling net_precreate_machine_acct: %s\n", - ads_errstr(status))); - nt_status = ads_ntstatus(status); - goto fail; + domain = argv[i]; } } /* Do the domain join here */ - tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); - password = talloc_strdup(ctx, tmp_password); - - nt_status = net_join_domain(ctx, ads->config.ldap_server_name, - &ads->ldap.ss, &short_domain_name, &domain_sid, password); - if ( !NT_STATUS_IS_OK(nt_status) ) { - DEBUG(1, ("call of net_join_domain failed: %s\n", - get_friendly_nt_error_msg(nt_status))); + r->in.domain_name = domain; + r->in.create_upn = createupn; + r->in.upn = machineupn; + r->in.account_ou = create_in_ou; + r->in.os_name = os_name; + r->in.os_version = os_version; + r->in.dc_name = opt_host; + r->in.admin_account = opt_user_name; + r->in.admin_password = net_prompt_pass(opt_user_name); + r->in.debug = opt_verbose; + r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE | + WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; + + werr = libnet_Join(ctx, r); + if (!W_ERROR_IS_OK(werr)) { goto fail; } /* Check the short name of the domain */ - if ( !strequal(lp_workgroup(), short_domain_name) ) { + if (!strequal(lp_workgroup(), r->out.netbios_domain_name)) { d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE()); d_printf("domain name obtained from the server.\n"); - d_printf("Using the name [%s] from the server.\n", short_domain_name); + d_printf("Using the name [%s] from the server.\n", r->out.netbios_domain_name); d_printf("You should set \"workgroup = %s\" in %s.\n", - short_domain_name, get_dyn_CONFIGFILE()); + r->out.netbios_domain_name, get_dyn_CONFIGFILE()); } - d_printf("Using short domain name -- %s\n", short_domain_name); + d_printf("Using short domain name -- %s\n", r->out.netbios_domain_name); - /* HACK ALERT! Store the sid and password under both the lp_workgroup() - value from smb.conf and the string returned from the server. The former is - neede to bootstrap winbindd's first connection to the DC to get the real - short domain name --jerry */ + d_printf("Joined '%s' to realm '%s'\n", r->in.machine_name, + r->out.dns_domain_name); - if ( (netdom_store_machine_account( lp_workgroup(), domain_sid, password ) == -1) - || (netdom_store_machine_account( short_domain_name, domain_sid, password ) == -1) ) +#if defined(WITH_DNS_UPDATES) { - /* issue an internal error here for now. - * everything else would mean changing tdb routines. */ - nt_status = NT_STATUS_INTERNAL_ERROR; - goto fail; - } - - /* Verify that everything is ok */ - - nt_status = net_rpc_join_ok(short_domain_name, - ads->config.ldap_server_name, &ads->ldap.ss); - if (!NT_STATUS_IS_OK(nt_status)) { - d_fprintf(stderr, - "Failed to verify membership in domain: %s!\n", - nt_errstr(nt_status)); - goto fail; - } - - /* create the dNSHostName & servicePrincipalName values */ - - status = net_set_machine_spn( ctx, ads ); - if ( !ADS_ERR_OK(status) ) { - - d_fprintf(stderr, "Failed to set servicePrincipalNames. Please ensure that\n"); - d_fprintf(stderr, "the DNS domain of this server matches the AD domain,\n"); - d_fprintf(stderr, "Or rejoin with using Domain Admin credentials.\n"); - - /* Disable the machine account in AD. Better to fail than to leave - a confused admin. */ - - if ( net_ads_leave( 0, NULL ) != 0 ) { - d_fprintf( stderr, "Failed to disable machine account in AD. Please do so manually.\n"); - } - - /* clear out the machine password */ - - netdom_store_machine_account( lp_workgroup(), domain_sid, "" ); - netdom_store_machine_account( short_domain_name, domain_sid, "" ); - - nt_status = ads_ntstatus(status); - goto fail; - } - - if ( !net_derive_salting_principal( ctx, ads ) ) { - DEBUG(1,("Failed to determine salting principal\n")); - goto fail; - } - - if ( createupn ) { - char *upn; - - /* default to using the short UPN name */ - if (!machineupn ) { - upn = talloc_asprintf(ctx, - "host/%s@%s", global_myname(), - ads->config.realm ); - if (!upn) { - nt_status = NT_STATUS_NO_MEMORY; - goto fail; - } - machineupn = upn; - } - - status = net_set_machine_upn( ctx, ads, machineupn ); - if ( !ADS_ERR_OK(status) ) { - d_fprintf(stderr, "Failed to set userPrincipalName. Are you a Domain Admin?\n"); + /* We enter this block with user creds */ + ADS_STRUCT *ads_dns = NULL; + + if ( (ads_dns = ads_init( lp_realm(), NULL, NULL )) != NULL ) { + /* kinit with the machine password */ + + use_in_memory_ccache(); + asprintf( &ads_dns->auth.user_name, "%s$", global_myname() ); + ads_dns->auth.password = secrets_fetch_machine_password( + lp_workgroup(), NULL, NULL ); + ads_dns->auth.realm = SMB_STRDUP( lp_realm() ); + ads_kinit_password( ads_dns ); } - } - - /* Try to set the operatingSystem attributes if asked */ - if ( os_name && os_version ) { - status = net_set_os_attributes( ctx, ads, os_name, os_version ); - if ( !ADS_ERR_OK(status) ) { - d_fprintf(stderr, "Failed to set operatingSystem attributes. " - "Are you a Domain Admin?\n"); + if ( !ads_dns || !NT_STATUS_IS_OK(net_update_dns( ctx, ads_dns )) ) { + d_fprintf( stderr, "DNS update failed!\n" ); } - } - - /* Now build the keytab, using the same ADS connection */ - if (lp_use_kerberos_keytab() && ads_keytab_create_default(ads)) { - DEBUG(1,("Error creating host keytab!\n")); + /* exit from this block using machine creds */ + ads_destroy(&ads_dns); } - -#if defined(WITH_DNS_UPDATES) - /* We enter this block with user creds */ - ads_kdestroy( NULL ); - ads_destroy(&ads); - ads = NULL; - - if ( (ads = ads_init( lp_realm(), NULL, NULL )) != NULL ) { - /* kinit with the machine password */ - - use_in_memory_ccache(); - asprintf( &ads->auth.user_name, "%s$", global_myname() ); - ads->auth.password = secrets_fetch_machine_password( - lp_workgroup(), NULL, NULL ); - ads->auth.realm = SMB_STRDUP( lp_realm() ); - ads_kinit_password( ads ); - } - - if ( !ads || !NT_STATUS_IS_OK(net_update_dns( ctx, ads )) ) { - d_fprintf( stderr, "DNS update failed!\n" ); - } - - /* exit from this block using machine creds */ #endif - - d_printf("Joined '%s' to realm '%s'\n", global_myname(), ads->server.realm); - + TALLOC_FREE(r); TALLOC_FREE( ctx ); - ads_destroy(&ads); return 0; fail: /* issue an overall failure message at the end. */ - d_printf("Failed to join domain: %s\n", get_friendly_nt_error_msg(nt_status)); - + d_printf("Failed to join domain: %s\n", + r && r->out.error_string ? r->out.error_string : + get_friendly_werror_msg(werr)); TALLOC_FREE( ctx ); - ads_destroy(&ads); return -1; - } /******************************************************************* @@ -2519,8 +2062,8 @@ static int net_ads_kerberos_renew(int argc, const char **argv) static int net_ads_kerberos_pac(int argc, const char **argv) { - PAC_DATA *pac = NULL; - PAC_LOGON_INFO *info = NULL; + struct PAC_DATA *pac = NULL; + struct PAC_LOGON_INFO *info = NULL; TALLOC_CTX *mem_ctx = NULL; NTSTATUS status; int ret = -1; @@ -2551,7 +2094,9 @@ static int net_ads_kerberos_pac(int argc, const char **argv) info = get_logon_info_from_pac(pac); if (info) { - dump_pac_logon_info(0, info); + const char *s; + s = NDR_PRINT_STRUCT_STRING(mem_ctx, PAC_LOGON_INFO, info); + d_printf("The Pac: %s\n", s); } ret = 0; diff --git a/source3/utils/net_dom.c b/source3/utils/net_dom.c index 30993ae2fa..e88bbdb276 100644 --- a/source3/utils/net_dom.c +++ b/source3/utils/net_dom.c @@ -101,7 +101,7 @@ static int net_dom_unjoin(int argc, const char **argv) status = NetUnjoinDomain(server_name, account, password, unjoin_flags); if (status != 0) { printf("Failed to unjoin domain: %s\n", - libnetapi_errstr(status)); + libnetapi_get_error_string(ctx, status)); goto done; } @@ -215,7 +215,7 @@ static int net_dom_join(int argc, const char **argv) Account, password, join_flags); if (status != 0) { printf("Failed to join domain: %s\n", - libnetapi_errstr(status)); + libnetapi_get_error_string(ctx, status)); goto done; } diff --git a/source3/utils/net_domain.c b/source3/utils/net_domain.c deleted file mode 100644 index 90d28b5e6e..0000000000 --- a/source3/utils/net_domain.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - Samba Unix/Linux SMB client library - net ads commands - Copyright (C) 2001 Andrew Tridgell (tridge@samba.org) - Copyright (C) 2001 Remus Koos (remuskoos@yahoo.com) - Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com) - Copyright (C) 2006 Gerald (Jerry) Carter (jerry@samba.org) - - 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" - -/* Macro for checking RPC error codes to make things more readable */ - -#define CHECK_RPC_ERR(rpc, msg) \ - if (!NT_STATUS_IS_OK(result = rpc)) { \ - DEBUG(0, (msg ": %s\n", nt_errstr(result))); \ - goto done; \ - } - -#define CHECK_RPC_ERR_DEBUG(rpc, debug_args) \ - if (!NT_STATUS_IS_OK(result = rpc)) { \ - DEBUG(0, debug_args); \ - goto done; \ - } - -/******************************************************************* - Leave an AD domain. Windows XP disables the machine account. - We'll try the same. The old code would do an LDAP delete. - That only worked using the machine creds because added the machine - with full control to the computer object's ACL. -*******************************************************************/ - -NTSTATUS netdom_leave_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli, - DOM_SID *dom_sid ) -{ - struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND sam_pol, domain_pol, user_pol; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - char *acct_name; - uint32 user_rid; - struct lsa_String lsa_acct_name; - struct samr_Ids user_rids; - struct samr_Ids name_types; - union samr_UserInfo *info = NULL; - - /* Open the domain */ - - if ( (pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &status)) == NULL ) { - DEBUG(0, ("Error connecting to SAM pipe. Error was %s\n", - nt_errstr(status) )); - return status; - } - - status = rpccli_samr_Connect2(pipe_hnd, mem_ctx, - pipe_hnd->cli->desthost, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &sam_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - - status = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, - &sam_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, - dom_sid, - &domain_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - /* Create domain user */ - - acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname()); - strlower_m(acct_name); - - init_lsa_String(&lsa_acct_name, acct_name); - - status = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, - &domain_pol, - 1, - &lsa_acct_name, - &user_rids, - &name_types); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - if ( name_types.ids[0] != SID_NAME_USER) { - DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types.ids[0])); - return NT_STATUS_INVALID_WORKSTATION; - } - - user_rid = user_rids.ids[0]; - - /* Open handle on user */ - - status = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, - &domain_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, - user_rid, - &user_pol); - if ( !NT_STATUS_IS_OK(status) ) { - goto done; - } - - /* Get user info */ - - status = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, - &user_pol, - 16, - &info); - if ( !NT_STATUS_IS_OK(status) ) { - rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol); - goto done; - } - - /* now disable and setuser info */ - - info->info16.acct_flags |= ACB_DISABLED; - - status = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, - &user_pol, - 16, - info); - - rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol); - -done: - rpccli_samr_Close(pipe_hnd, mem_ctx, &domain_pol); - rpccli_samr_Close(pipe_hnd, mem_ctx, &sam_pol); - - cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */ - - return status; -} - -/******************************************************************* - Store the machine password and domain SID - ********************************************************************/ - -int netdom_store_machine_account( const char *domain, DOM_SID *sid, const char *pw ) -{ - if (!secrets_store_domain_sid(domain, sid)) { - DEBUG(1,("Failed to save domain sid\n")); - return -1; - } - - if (!secrets_store_machine_password(pw, domain, SEC_CHAN_WKSTA)) { - DEBUG(1,("Failed to save machine password\n")); - return -1; - } - - return 0; -} - -/******************************************************************* - ********************************************************************/ - -NTSTATUS netdom_get_domain_sid( TALLOC_CTX *mem_ctx, struct cli_state *cli, - const char **domain, DOM_SID **sid ) -{ - struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND lsa_pol; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - union lsa_PolicyInformation *info = NULL; - - if ( (pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &status)) == NULL ) { - DEBUG(0, ("Error connecting to LSA pipe. Error was %s\n", - nt_errstr(status) )); - return status; - } - - status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True, - SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - status = rpccli_lsa_QueryInfoPolicy(pipe_hnd, mem_ctx, - &lsa_pol, - LSA_POLICY_INFO_ACCOUNT_DOMAIN, - &info); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - *domain = info->account_domain.name.string; - *sid = info->account_domain.sid; - - rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol); - cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */ - - /* Bail out if domain didn't get set. */ - if (!domain) { - DEBUG(0, ("Could not get domain name.\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - return NT_STATUS_OK; -} - -/******************************************************************* - Do the domain join - ********************************************************************/ - -NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli, - DOM_SID *dom_sid, const char *clear_pw, - enum netdom_domain_t dom_type ) -{ - struct rpc_pipe_client *pipe_hnd = NULL; - POLICY_HND sam_pol, domain_pol, user_pol; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - char *acct_name; - struct lsa_String lsa_acct_name; - uint32 user_rid; - uint32 acb_info = ACB_WSTRUST; - uint32 acct_flags; - uchar pwbuf[532]; - struct MD5Context md5ctx; - uchar md5buffer[16]; - DATA_BLOB digested_session_key; - uchar md4_trust_password[16]; - uint32_t access_granted = 0; - struct samr_Ids user_rids; - struct samr_Ids name_types; - union samr_UserInfo info; - - /* Open the domain */ - - if ( (pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &status)) == NULL ) { - DEBUG(0, ("Error connecting to SAM pipe. Error was %s\n", - nt_errstr(status) )); - return status; - } - - status = rpccli_samr_Connect2(pipe_hnd, mem_ctx, - pipe_hnd->cli->desthost, - SEC_RIGHTS_MAXIMUM_ALLOWED, - &sam_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - - status = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, - &sam_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, - dom_sid, - &domain_pol); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - /* Create domain user */ - - acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname()); - strlower_m(acct_name); - - init_lsa_String(&lsa_acct_name, acct_name); - - /* Don't try to set any acb_info flags other than ACB_WSTRUST */ - acct_flags = SEC_GENERIC_READ | SEC_GENERIC_WRITE | SEC_GENERIC_EXECUTE | - SEC_STD_WRITE_DAC | SEC_STD_DELETE | - SAMR_USER_ACCESS_SET_PASSWORD | - SAMR_USER_ACCESS_GET_ATTRIBUTES | - SAMR_USER_ACCESS_SET_ATTRIBUTES; - - DEBUG(10, ("Creating account with flags: %d\n",acct_flags)); - - status = rpccli_samr_CreateUser2(pipe_hnd, mem_ctx, - &domain_pol, - &lsa_acct_name, - acb_info, - acct_flags, - &user_pol, - &access_granted, - &user_rid); - - if ( !NT_STATUS_IS_OK(status) - && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) - { - d_fprintf(stderr, "Creation of workstation account failed\n"); - - /* If NT_STATUS_ACCESS_DENIED then we have a valid - username/password combo but the user does not have - administrator access. */ - - if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) - d_fprintf(stderr, "User specified does not have administrator privileges\n"); - - return status; - } - - /* We *must* do this.... don't ask... */ - - if (NT_STATUS_IS_OK(status)) { - rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol); - } - - status = rpccli_samr_LookupNames(pipe_hnd, mem_ctx, - &domain_pol, - 1, - &lsa_acct_name, - &user_rids, - &name_types); - if ( !NT_STATUS_IS_OK(status) ) - return status; - - if ( name_types.ids[0] != SID_NAME_USER) { - DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types.ids[0])); - return NT_STATUS_INVALID_WORKSTATION; - } - - user_rid = user_rids.ids[0]; - - /* Open handle on user */ - - status = rpccli_samr_OpenUser(pipe_hnd, mem_ctx, - &domain_pol, - SEC_RIGHTS_MAXIMUM_ALLOWED, - user_rid, - &user_pol); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* Create a random machine account password and generate the hash */ - - E_md4hash(clear_pw, md4_trust_password); - encode_pw_buffer(pwbuf, clear_pw, STR_UNICODE); - - generate_random_buffer((uint8*)md5buffer, sizeof(md5buffer)); - digested_session_key = data_blob_talloc(mem_ctx, 0, 16); - - MD5Init(&md5ctx); - MD5Update(&md5ctx, md5buffer, sizeof(md5buffer)); - MD5Update(&md5ctx, cli->user_session_key.data, cli->user_session_key.length); - MD5Final(digested_session_key.data, &md5ctx); - - SamOEMhashBlob(pwbuf, sizeof(pwbuf), &digested_session_key); - memcpy(&pwbuf[516], md5buffer, sizeof(md5buffer)); - - /* Fill in the additional account flags now */ - - acb_info |= ACB_PWNOEXP; - if ( dom_type == ND_TYPE_AD ) { -#if !defined(ENCTYPE_ARCFOUR_HMAC) - acb_info |= ACB_USE_DES_KEY_ONLY; -#endif - ;; - } - - /* Set password and account flags on machine account */ - ZERO_STRUCT(info.info25); - info.info25.info.fields_present = ACCT_NT_PWD_SET | - ACCT_LM_PWD_SET | - SAMR_FIELD_ACCT_FLAGS; - info.info25.info.acct_flags = acb_info; - memcpy(&info.info25.password.data, pwbuf, sizeof(pwbuf)); - - - status = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, - &user_pol, - 25, - &info); - - if ( !NT_STATUS_IS_OK(status) ) { - d_fprintf( stderr, "Failed to set password for machine account (%s)\n", - nt_errstr(status)); - return status; - } - - rpccli_samr_Close(pipe_hnd, mem_ctx, &user_pol); - cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */ - - return status; -} - diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c index 8c01b5b4ba..e5d83bc891 100644 --- a/source3/utils/net_lookup.c +++ b/source3/utils/net_lookup.c @@ -366,8 +366,9 @@ static int net_lookup_dsgetdcname(int argc, const char **argv) const char *domain_name = NULL; char *site_name = NULL; uint32_t flags = 0; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; TALLOC_CTX *mem_ctx; + char *s = NULL; if (argc < 1 || argc > 3) { d_printf("usage: net lookup dsgetdcname " @@ -410,7 +411,9 @@ static int net_lookup_dsgetdcname(int argc, const char **argv) return -1; } - display_ds_domain_controller_info(mem_ctx, info); + s = NDR_PRINT_STRUCT_STRING(mem_ctx, netr_DsRGetDCNameInfo, info); + printf("%s\n", s); + TALLOC_FREE(s); SAFE_FREE(site_name); TALLOC_FREE(mem_ctx); diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 3767138601..f7fadb9520 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -3,7 +3,7 @@ Distributed SMB/CIFS Server Management Utility Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org) Copyright (C) 2002 Jim McDonough (jmcd@us.ibm.com) - Copyright (C) 2004 Guenther Deschner (gd@samba.org) + Copyright (C) 2004,2008 Guenther Deschner (gd@samba.org) Copyright (C) 2005 Jeremy Allison (jra@samba.org) Copyright (C) 2006 Jelmer Vernooij (jelmer@samba.org) @@ -1406,9 +1406,8 @@ static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx, TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - const POLICY_HND *user_hnd, + POLICY_HND *user_hnd, int argc, const char **argv)) - { POLICY_HND connect_pol, domain_pol, user_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; @@ -1490,7 +1489,7 @@ static NTSTATUS rpc_sh_handle_user(TALLOC_CTX *mem_ctx, static NTSTATUS rpc_sh_user_show_internals(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - const POLICY_HND *user_hnd, + POLICY_HND *user_hnd, int argc, const char **argv) { NTSTATUS result; @@ -1502,7 +1501,7 @@ static NTSTATUS rpc_sh_user_show_internals(TALLOC_CTX *mem_ctx, } result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, - CONST_DISCARD(struct policy_handle *, user_hnd), + user_hnd, 21, &info); if (!NT_STATUS_IS_OK(result)) { @@ -1539,7 +1538,7 @@ do { if (strequal(ctx->thiscmd, name)) { \ static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - const POLICY_HND *user_hnd, + POLICY_HND *user_hnd, int argc, const char **argv) { NTSTATUS result; @@ -1554,7 +1553,7 @@ static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx, } result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, - CONST_DISCARD(struct policy_handle *, user_hnd), + user_hnd, 21, &info); if (!NT_STATUS_IS_OK(result)) { @@ -1589,7 +1588,7 @@ static NTSTATUS rpc_sh_user_str_edit_internals(TALLOC_CTX *mem_ctx, SETSTR("description", description, DESCRIPTION); result = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, - CONST_DISCARD(struct policy_handle *, user_hnd), + user_hnd, 21, info); @@ -1622,7 +1621,7 @@ static NTSTATUS rpc_sh_user_str_edit(TALLOC_CTX *mem_ctx, static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx, struct rpc_sh_ctx *ctx, struct rpc_pipe_client *pipe_hnd, - const POLICY_HND *user_hnd, + POLICY_HND *user_hnd, int argc, const char **argv) { NTSTATUS result; @@ -1643,7 +1642,7 @@ static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx, newval = strequal(argv[0], "yes"); result = rpccli_samr_QueryUserInfo(pipe_hnd, mem_ctx, - CONST_DISCARD(struct policy_handle *, user_hnd), + user_hnd, 21, &info); if (!NT_STATUS_IS_OK(result)) { @@ -1670,7 +1669,7 @@ static NTSTATUS rpc_sh_user_flag_edit_internals(TALLOC_CTX *mem_ctx, info->info21.fields_present = SAMR_FIELD_ACCT_FLAGS; result = rpccli_samr_SetUserInfo(pipe_hnd, mem_ctx, - CONST_DISCARD(struct policy_handle *, user_hnd), + user_hnd, 21, info); @@ -3601,14 +3600,14 @@ static bool check_share_sanity(struct cli_state *cli, fstring netname, uint32 ty } /** - * Migrate shares from a remote RPC server to the local RPC srever + * Migrate shares from a remote RPC server to the local RPC server * * All parameters are provided by the run_rpc_command function, except for - * argc, argv which are passes through. + * argc, argv which are passed through. * * @param domain_sid The domain sid acquired from the remote server * @param cli A cli_state connected to the server. - * @param mem_ctx Talloc context, destoyed on completion of the function. + * @param mem_ctx Talloc context, destroyed on completion of the function. * @param argc Standard main() style argc * @param argv Standard main() style argv. Initial components are already * stripped diff --git a/source3/utils/net_rpc_audit.c b/source3/utils/net_rpc_audit.c index 7c2a5b33ca..a846395bb8 100644 --- a/source3/utils/net_rpc_audit.c +++ b/source3/utils/net_rpc_audit.c @@ -1,7 +1,7 @@ /* Samba Unix/Linux SMB client library Distributed SMB/CIFS Server Management Utility - Copyright (C) 2006 Guenther Deschner + Copyright (C) 2006,2008 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 diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index f08dc66d3c..8259ec46e6 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -3,6 +3,7 @@ Distributed SMB/CIFS Server Management Utility Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org) Copyright (C) Tim Potter 2001 + Copyright (C) 2008 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 diff --git a/source3/utils/net_rpc_rights.c b/source3/utils/net_rpc_rights.c index de6e14ebad..7857dbcbaf 100644 --- a/source3/utils/net_rpc_rights.c +++ b/source3/utils/net_rpc_rights.c @@ -2,6 +2,7 @@ Samba Unix/Linux SMB client library Distributed SMB/CIFS Server Management Utility Copyright (C) Gerald (Jerry) Carter 2004 + Copyright (C) Guenther Deschner 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 @@ -152,22 +153,24 @@ static NTSTATUS check_privilege_for_user(struct rpc_pipe_client *pipe_hnd, const char *right) { NTSTATUS result; - uint32 count; - char **rights; + struct lsa_RightSet rights; int i; - result = rpccli_lsa_enum_account_rights(pipe_hnd, ctx, pol, sid, &count, &rights); + result = rpccli_lsa_EnumAccountRights(pipe_hnd, ctx, + pol, + sid, + &rights); if (!NT_STATUS_IS_OK(result)) { return result; } - if (count == 0) { + if (rights.count == 0) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - - for (i = 0; i < count; i++) { - if (StrCaseCmp(rights[i], right) == 0) { + + for (i = 0; i < rights.count; i++) { + if (StrCaseCmp(rights.names[i].string, right) == 0) { return NT_STATUS_OK; } } @@ -184,20 +187,23 @@ static NTSTATUS enum_privileges_for_user(struct rpc_pipe_client *pipe_hnd, DOM_SID *sid ) { NTSTATUS result; - uint32 count; - char **rights; + struct lsa_RightSet rights; int i; - result = rpccli_lsa_enum_account_rights(pipe_hnd, ctx, pol, sid, &count, &rights); + result = rpccli_lsa_EnumAccountRights(pipe_hnd, ctx, + pol, + sid, + &rights); if (!NT_STATUS_IS_OK(result)) return result; - if ( count == 0 ) + if (rights.count == 0) { d_printf("No privileges assigned\n"); - - for (i = 0; i < count; i++) { - printf("%s\n", rights[i]); + } + + for (i = 0; i < rights.count; i++) { + printf("%s\n", rights.names[i].string); } return NT_STATUS_OK; @@ -214,24 +220,27 @@ 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 = NULL; - uint32 count=0; + struct lsa_SidArray sid_array; int i; fstring name; - result = rpccli_lsa_enum_sids(pipe_hnd, ctx, pol, &enum_context, - pref_max_length, &count, &sids); + result = rpccli_lsa_EnumAccounts(pipe_hnd, ctx, + pol, + &enum_context, + &sid_array, + pref_max_length); if (!NT_STATUS_IS_OK(result)) return result; d_printf("%s:\n", privilege); - for ( i=0; i<count; i++ ) { - - - result = check_privilege_for_user( pipe_hnd, ctx, pol, &sids[i], privilege); - + for ( i=0; i<sid_array.num_sids; i++ ) { + + result = check_privilege_for_user(pipe_hnd, ctx, pol, + sid_array.sids[i].sid, + privilege); + if ( ! NT_STATUS_IS_OK(result)) { if ( ! NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { return result; @@ -241,9 +250,9 @@ static NTSTATUS enum_accounts_for_privilege(struct rpc_pipe_client *pipe_hnd, /* try to convert the SID to a name. Fall back to printing the raw SID if necessary */ - result = sid_to_name( pipe_hnd, ctx, &sids[i], name ); + result = sid_to_name( pipe_hnd, ctx, sid_array.sids[i].sid, name ); if ( !NT_STATUS_IS_OK (result) ) - sid_to_fstring(name, &sids[i]); + sid_to_fstring(name, sid_array.sids[i].sid); d_printf(" %s\n", name); } @@ -261,30 +270,32 @@ static NTSTATUS enum_privileges_for_accounts(struct rpc_pipe_client *pipe_hnd, NTSTATUS result; uint32 enum_context=0; uint32 pref_max_length=0x1000; - DOM_SID *sids; - uint32 count=0; + struct lsa_SidArray sid_array; int i; fstring name; - result = rpccli_lsa_enum_sids(pipe_hnd, ctx, pol, &enum_context, - pref_max_length, &count, &sids); + result = rpccli_lsa_EnumAccounts(pipe_hnd, ctx, + pol, + &enum_context, + &sid_array, + pref_max_length); if (!NT_STATUS_IS_OK(result)) return result; - - for ( i=0; i<count; i++ ) { - + + for ( i=0; i<sid_array.num_sids; i++ ) { + /* try to convert the SID to a name. Fall back to printing the raw SID if necessary */ - - result = sid_to_name(pipe_hnd, ctx, &sids[i], name ); + + result = sid_to_name(pipe_hnd, ctx, sid_array.sids[i].sid, name); if ( !NT_STATUS_IS_OK (result) ) - sid_to_fstring(name, &sids[i]); - + sid_to_fstring(name, sid_array.sids[i].sid); + d_printf("%s\n", name); - - result = enum_privileges_for_user(pipe_hnd, ctx, pol, &sids[i] ); - + + result = enum_privileges_for_user(pipe_hnd, ctx, pol, + sid_array.sids[i].sid); if ( !NT_STATUS_IS_OK(result) ) return result; @@ -426,6 +437,8 @@ static NTSTATUS rpc_rights_grant_internal(const DOM_SID *domain_sid, { POLICY_HND dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + struct lsa_RightSet rights; + int i; DOM_SID sid; @@ -445,8 +458,21 @@ static NTSTATUS rpc_rights_grant_internal(const DOM_SID *domain_sid, if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_lsa_add_account_rights(pipe_hnd, mem_ctx, &dom_pol, sid, - argc-1, argv+1); + rights.count = argc-1; + rights.names = TALLOC_ARRAY(mem_ctx, struct lsa_StringLarge, + rights.count); + if (!rights.names) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<argc-1; i++) { + init_lsa_StringLarge(&rights.names[i], argv[i+1]); + } + + result = rpccli_lsa_AddAccountRights(pipe_hnd, mem_ctx, + &dom_pol, + &sid, + &rights); if (!NT_STATUS_IS_OK(result)) goto done; @@ -477,8 +503,9 @@ static NTSTATUS rpc_rights_revoke_internal(const DOM_SID *domain_sid, { POLICY_HND dom_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - + struct lsa_RightSet rights; DOM_SID sid; + int i; if (argc < 2 ) { d_printf("Usage: net rpc rights revoke <name|SID> <rights...>\n"); @@ -496,8 +523,22 @@ static NTSTATUS rpc_rights_revoke_internal(const DOM_SID *domain_sid, if (!NT_STATUS_IS_OK(result)) return result; - result = rpccli_lsa_remove_account_rights(pipe_hnd, mem_ctx, &dom_pol, sid, - False, argc-1, argv+1); + rights.count = argc-1; + rights.names = TALLOC_ARRAY(mem_ctx, struct lsa_StringLarge, + rights.count); + if (!rights.names) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i<argc-1; i++) { + init_lsa_StringLarge(&rights.names[i], argv[i+1]); + } + + result = rpccli_lsa_RemoveAccountRights(pipe_hnd, mem_ctx, + &dom_pol, + &sid, + false, + &rights); if (!NT_STATUS_IS_OK(result)) goto done; diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index e1f0cd3751..775270a69b 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. dump the remote SAM using rpc samsync operations @@ -7,17 +7,18 @@ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005 Modified by Volker Lendecke 2002 Copyright (C) Jeremy Allison 2005. + Copyright (C) Guenther Deschner 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/>. */ @@ -31,57 +32,62 @@ static uint32 ldif_uid = 999; /* Keep track of ldap initialization */ static int init_ldap = 1; -static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g) +static void display_group_mem_info(uint32_t rid, + struct netr_DELTA_GROUP_MEMBER *r) { int i; d_printf("Group mem %u: ", rid); - for (i=0;i<g->num_members;i++) { - d_printf("%u ", g->rids[i]); + for (i=0; i< r->num_rids; i++) { + d_printf("%u ", r->rids[i]); } d_printf("\n"); } -static void display_alias_info(uint32 rid, SAM_ALIAS_INFO *a) +static void display_alias_info(uint32_t rid, + struct netr_DELTA_ALIAS *r) { - d_printf("Alias '%s' ", unistr2_static(&a->uni_als_name)); - d_printf("desc='%s' rid=%u\n", unistr2_static(&a->uni_als_desc), a->als_rid); + d_printf("Alias '%s' ", r->alias_name.string); + d_printf("desc='%s' rid=%u\n", r->description.string, r->rid); } -static void display_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *a) +static void display_alias_mem(uint32_t rid, + struct netr_DELTA_ALIAS_MEMBER *r) { int i; d_printf("Alias rid %u: ", rid); - for (i=0;i<a->num_members;i++) { - d_printf("%s ", sid_string_tos(&a->sids[i].sid)); + for (i=0; i< r->sids.num_sids; i++) { + d_printf("%s ", sid_string_tos(r->sids.sids[i].sid)); } d_printf("\n"); } -static void display_account_info(uint32 rid, SAM_ACCOUNT_INFO *a) +static void display_account_info(uint32_t rid, + struct netr_DELTA_USER *r) { fstring hex_nt_passwd, hex_lm_passwd; uchar lm_passwd[16], nt_passwd[16]; static uchar zero_buf[16]; /* Decode hashes from password hash (if they are not NULL) */ - - if (memcmp(a->pass.buf_lm_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(a->user_rid, a->pass.buf_lm_pwd, lm_passwd, 0); - pdb_sethexpwd(hex_lm_passwd, lm_passwd, a->acb_info); + + if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0); + pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags); } else { pdb_sethexpwd(hex_lm_passwd, NULL, 0); } - if (memcmp(a->pass.buf_nt_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(a->user_rid, a->pass.buf_nt_pwd, nt_passwd, 0); - pdb_sethexpwd(hex_nt_passwd, nt_passwd, a->acb_info); + if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0); + pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags); } else { pdb_sethexpwd(hex_nt_passwd, NULL, 0); } - - printf("%s:%d:%s:%s:%s:LCT-0\n", unistr2_static(&a->uni_acct_name), - a->user_rid, hex_lm_passwd, hex_nt_passwd, - pdb_encode_acct_ctrl(a->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN)); + + printf("%s:%d:%s:%s:%s:LCT-0\n", + r->account_name.string, + r->rid, hex_lm_passwd, hex_nt_passwd, + pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN)); } static time_t uint64s_nt_time_to_unix_abs(const uint64 *src) @@ -91,102 +97,201 @@ static time_t uint64s_nt_time_to_unix_abs(const uint64 *src) return nt_time_to_unix_abs(&nttime); } -static void display_domain_info(SAM_DOMAIN_INFO *a) +static void display_domain_info(struct netr_DELTA_DOMAIN *r) { time_t u_logout; - u_logout = uint64s_nt_time_to_unix_abs(&a->force_logoff); + u_logout = uint64s_nt_time_to_unix_abs((const uint64 *)&r->force_logoff_time); - d_printf("Domain name: %s\n", unistr2_static(&a->uni_dom_name)); + d_printf("Domain name: %s\n", r->domain_name.string); - d_printf("Minimal Password Length: %d\n", a->min_pwd_len); - d_printf("Password History Length: %d\n", a->pwd_history_len); + d_printf("Minimal Password Length: %d\n", r->min_password_length); + d_printf("Password History Length: %d\n", r->password_history_length); d_printf("Force Logoff: %d\n", (int)u_logout); - d_printf("Max Password Age: %s\n", display_time(a->max_pwd_age)); - d_printf("Min Password Age: %s\n", display_time(a->min_pwd_age)); + d_printf("Max Password Age: %s\n", display_time(r->max_password_age)); + d_printf("Min Password Age: %s\n", display_time(r->min_password_age)); +#if 0 + /* FIXME - gd */ d_printf("Lockout Time: %s\n", display_time(a->account_lockout.lockout_duration)); d_printf("Lockout Reset Time: %s\n", display_time(a->account_lockout.reset_count)); - d_printf("Bad Attempt Lockout: %d\n", a->account_lockout.bad_attempt_lockout); - d_printf("User must logon to change password: %d\n", a->logon_chgpass); +#endif + d_printf("User must logon to change password: %d\n", r->logon_to_chgpass); } -static void display_group_info(uint32 rid, SAM_GROUP_INFO *a) +static void display_group_info(uint32_t rid, struct netr_DELTA_GROUP *r) { - d_printf("Group '%s' ", unistr2_static(&a->uni_grp_name)); - d_printf("desc='%s', rid=%u\n", unistr2_static(&a->uni_grp_desc), rid); + d_printf("Group '%s' ", r->group_name.string); + d_printf("desc='%s', rid=%u\n", r->description.string, rid); } -static void display_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta) +static void display_sam_entry(struct netr_DELTA_ENUM *r) { - switch (hdr_delta->type) { - case SAM_DELTA_ACCOUNT_INFO: - display_account_info(hdr_delta->target_rid, &delta->account_info); + union netr_DELTA_UNION u = r->delta_union; + union netr_DELTA_ID_UNION id = r->delta_id_union; + + switch (r->delta_type) { + case NETR_DELTA_DOMAIN: + display_domain_info(u.domain); + break; + case NETR_DELTA_GROUP: + display_group_info(id.rid, u.group); + break; +#if 0 + case NETR_DELTA_DELETE_GROUP: + printf("Delete Group: %d\n", + u.delete_account.unknown); + break; + case NETR_DELTA_RENAME_GROUP: + printf("Rename Group: %s -> %s\n", + u.rename_group->OldName.string, + u.rename_group->NewName.string); break; - case SAM_DELTA_GROUP_MEM: - display_group_mem_info(hdr_delta->target_rid, &delta->grp_mem_info); +#endif + case NETR_DELTA_USER: + display_account_info(id.rid, u.user); break; - case SAM_DELTA_ALIAS_INFO: - display_alias_info(hdr_delta->target_rid, &delta->alias_info); +#if 0 + case NETR_DELTA_DELETE_USER: + printf("Delete User: %d\n", + id.rid); break; - case SAM_DELTA_ALIAS_MEM: - display_alias_mem(hdr_delta->target_rid, &delta->als_mem_info); + case NETR_DELTA_RENAME_USER: + printf("Rename user: %s -> %s\n", + u.rename_user->OldName.string, + u.rename_user->NewName.string); break; - case SAM_DELTA_DOMAIN_INFO: - display_domain_info(&delta->domain_info); +#endif + case NETR_DELTA_GROUP_MEMBER: + display_group_mem_info(id.rid, u.group_member); break; - case SAM_DELTA_GROUP_INFO: - display_group_info(hdr_delta->target_rid, &delta->group_info); + case NETR_DELTA_ALIAS: + display_alias_info(id.rid, u.alias); break; - /* The following types are recognised but not handled */ - case SAM_DELTA_RENAME_GROUP: - d_printf("SAM_DELTA_RENAME_GROUP not handled\n"); +#if 0 + case NETR_DELTA_DELETE_ALIAS: + printf("Delete Alias: %d\n", + id.rid); break; - case SAM_DELTA_RENAME_USER: - d_printf("SAM_DELTA_RENAME_USER not handled\n"); + case NETR_DELTA_RENAME_ALIAS: + printf("Rename alias: %s -> %s\n", + u.rename_alias->OldName.string, + u.rename_alias->NewName.string); break; - case SAM_DELTA_RENAME_ALIAS: - d_printf("SAM_DELTA_RENAME_ALIAS not handled\n"); +#endif + case NETR_DELTA_ALIAS_MEMBER: + display_alias_mem(id.rid, u.alias_member); + break; +#if 0 + case NETR_DELTA_POLICY: + printf("Policy\n"); break; - case SAM_DELTA_POLICY_INFO: - d_printf("SAM_DELTA_POLICY_INFO not handled\n"); + case NETR_DELTA_TRUSTED_DOMAIN: + printf("Trusted Domain: %s\n", + u.trusted_domain->domain_name.string); break; - case SAM_DELTA_TRUST_DOMS: - d_printf("SAM_DELTA_TRUST_DOMS not handled\n"); + case NETR_DELTA_DELETE_TRUST: + printf("Delete Trust: %d\n", + u.delete_trust.unknown); break; - case SAM_DELTA_PRIVS_INFO: - d_printf("SAM_DELTA_PRIVS_INFO not handled\n"); + case NETR_DELTA_ACCOUNT: + printf("Account\n"); break; - case SAM_DELTA_SECRET_INFO: - d_printf("SAM_DELTA_SECRET_INFO not handled\n"); + case NETR_DELTA_DELETE_ACCOUNT: + printf("Delete Account: %d\n", + u.delete_account.unknown); break; - case SAM_DELTA_DELETE_GROUP: - d_printf("SAM_DELTA_DELETE_GROUP not handled\n"); + case NETR_DELTA_SECRET: + printf("Secret\n"); break; - case SAM_DELTA_DELETE_USER: - d_printf("SAM_DELTA_DELETE_USER not handled\n"); + case NETR_DELTA_DELETE_SECRET: + printf("Delete Secret: %d\n", + u.delete_secret.unknown); + break; + case NETR_DELTA_DELETE_GROUP2: + printf("Delete Group2: %s\n", + u.delete_group->account_name); + break; + case NETR_DELTA_DELETE_USER2: + printf("Delete User2: %s\n", + u.delete_user->account_name); + break; + case NETR_DELTA_MODIFY_COUNT: + printf("sam sequence update: 0x%016llx\n", + (unsigned long long) *u.modified_count); + break; +#endif + /* The following types are recognised but not handled */ + case NETR_DELTA_RENAME_GROUP: + d_printf("NETR_DELTA_RENAME_GROUP not handled\n"); break; - case SAM_DELTA_MODIFIED_COUNT: - d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n"); + case NETR_DELTA_RENAME_USER: + d_printf("NETR_DELTA_RENAME_USER not handled\n"); + break; + case NETR_DELTA_RENAME_ALIAS: + d_printf("NETR_DELTA_RENAME_ALIAS not handled\n"); + break; + case NETR_DELTA_POLICY: + d_printf("NETR_DELTA_POLICY not handled\n"); + break; + case NETR_DELTA_TRUSTED_DOMAIN: + d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n"); + break; + case NETR_DELTA_ACCOUNT: + d_printf("NETR_DELTA_ACCOUNT not handled\n"); + break; + case NETR_DELTA_SECRET: + d_printf("NETR_DELTA_SECRET not handled\n"); + break; + case NETR_DELTA_DELETE_GROUP: + d_printf("NETR_DELTA_DELETE_GROUP not handled\n"); + break; + case NETR_DELTA_DELETE_USER: + d_printf("NETR_DELTA_DELETE_USER not handled\n"); + break; + case NETR_DELTA_MODIFY_COUNT: + d_printf("NETR_DELTA_MODIFY_COUNT not handled\n"); + break; + case NETR_DELTA_DELETE_ALIAS: + d_printf("NETR_DELTA_DELETE_ALIAS not handled\n"); + break; + case NETR_DELTA_DELETE_TRUST: + d_printf("NETR_DELTA_DELETE_TRUST not handled\n"); + break; + case NETR_DELTA_DELETE_ACCOUNT: + d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n"); + break; + case NETR_DELTA_DELETE_SECRET: + d_printf("NETR_DELTA_DELETE_SECRET not handled\n"); + break; + case NETR_DELTA_DELETE_GROUP2: + d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n"); + break; + case NETR_DELTA_DELETE_USER2: + d_printf("NETR_DELTA_DELETE_USER2 not handled\n"); break; default: - d_printf("Unknown delta record type %d\n", hdr_delta->type); + printf("unknown delta type 0x%02x\n", + r->delta_type); break; } } static void dump_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type) { - uint32 sync_context = 0; NTSTATUS result; int i; TALLOC_CTX *mem_ctx; - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; - uint32 num_deltas; + const char *logon_server = pipe_hnd->cli->desthost; + const char *computername = global_myname(); + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + enum netr_SamDatabaseID database_id = db_type; + uint16_t restart_state = 0; + uint32_t sync_context = 0; if (!(mem_ctx = talloc_init("dump_database"))) { return; @@ -208,29 +313,52 @@ static void dump_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type) } do { - result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, db_type, - sync_context, - &num_deltas, &hdr_deltas, &deltas); - if (!NT_STATUS_IS_OK(result)) + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; + + netlogon_creds_client_step(pipe_hnd->dc, &credential); + + result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx, + logon_server, + computername, + &credential, + &return_authenticator, + database_id, + restart_state, + &sync_context, + &delta_enum_array, + 0xffff); + + /* Check returned credentials. */ + if (!netlogon_creds_client_check(pipe_hnd->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return; + } + + if (NT_STATUS_IS_ERR(result)) { break; + } - for (i = 0; i < num_deltas; i++) { - display_sam_entry(&hdr_deltas[i], &deltas[i]); + /* Display results */ + for (i = 0; i < delta_enum_array->num_deltas; i++) { + display_sam_entry(&delta_enum_array->delta_enum[i]); } - sync_context += 1; + + TALLOC_FREE(delta_enum_array); + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); talloc_destroy(mem_ctx); } /* dump sam database via samsync rpc calls */ -NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, - const char *domain_name, +NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, + 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) + const char **argv) { #if 0 /* net_rpc.c now always tries to create an schannel pipe.. */ @@ -277,7 +405,8 @@ NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, (!(s1) && (s2)) ||\ ((s1) && (s2) && (strcmp((s1), (s2)) != 0)) -static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *delta) +static NTSTATUS sam_account_from_delta(struct samu *account, + struct netr_DELTA_USER *r) { const char *old_string, *new_string; time_t unix_time, stored_time; @@ -287,15 +416,14 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d /* Username, fullname, home dir, dir drive, logon script, acct desc, workstations, profile. */ - if (delta->hdr_acct_name.buffer) { + if (r->account_name.string) { old_string = pdb_get_nt_username(account); - new_string = unistr2_static(&delta->uni_acct_name); + new_string = r->account_name.string; if (STRING_CHANGED) { pdb_set_nt_username(account, new_string, PDB_CHANGED); - } - + /* Unix username is the same - for sanity */ old_string = pdb_get_username( account ); if (STRING_CHANGED) { @@ -303,68 +431,68 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d } } - if (delta->hdr_full_name.buffer) { + if (r->full_name.string) { old_string = pdb_get_fullname(account); - new_string = unistr2_static(&delta->uni_full_name); + new_string = r->full_name.string; if (STRING_CHANGED) pdb_set_fullname(account, new_string, PDB_CHANGED); } - if (delta->hdr_home_dir.buffer) { + if (r->home_directory.string) { old_string = pdb_get_homedir(account); - new_string = unistr2_static(&delta->uni_home_dir); + new_string = r->home_directory.string; if (STRING_CHANGED) pdb_set_homedir(account, new_string, PDB_CHANGED); } - if (delta->hdr_dir_drive.buffer) { + if (r->home_drive.string) { old_string = pdb_get_dir_drive(account); - new_string = unistr2_static(&delta->uni_dir_drive); + new_string = r->home_drive.string; if (STRING_CHANGED) pdb_set_dir_drive(account, new_string, PDB_CHANGED); } - if (delta->hdr_logon_script.buffer) { + if (r->logon_script.string) { old_string = pdb_get_logon_script(account); - new_string = unistr2_static(&delta->uni_logon_script); + new_string = r->logon_script.string; if (STRING_CHANGED) pdb_set_logon_script(account, new_string, PDB_CHANGED); } - if (delta->hdr_acct_desc.buffer) { + if (r->description.string) { old_string = pdb_get_acct_desc(account); - new_string = unistr2_static(&delta->uni_acct_desc); + new_string = r->description.string; if (STRING_CHANGED) pdb_set_acct_desc(account, new_string, PDB_CHANGED); } - if (delta->hdr_workstations.buffer) { + if (r->workstations.string) { old_string = pdb_get_workstations(account); - new_string = unistr2_static(&delta->uni_workstations); + new_string = r->workstations.string; if (STRING_CHANGED) pdb_set_workstations(account, new_string, PDB_CHANGED); } - if (delta->hdr_profile.buffer) { + if (r->profile_path.string) { old_string = pdb_get_profile_path(account); - new_string = unistr2_static(&delta->uni_profile); + new_string = r->profile_path.string; if (STRING_CHANGED) pdb_set_profile_path(account, new_string, PDB_CHANGED); } - if (delta->hdr_parameters.buffer) { + if (r->parameters.string) { DATA_BLOB mung; char *newstr; old_string = pdb_get_munged_dial(account); - mung.length = delta->hdr_parameters.uni_str_len; - mung.data = (uint8 *) delta->uni_parameters.buffer; + mung.length = r->parameters.length; + mung.data = (uint8 *) r->parameters.string; newstr = (mung.length == 0) ? NULL : base64_encode_data_blob(talloc_tos(), mung); @@ -374,57 +502,59 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d } /* User and group sid */ - if (pdb_get_user_rid(account) != delta->user_rid) - pdb_set_user_sid_from_rid(account, delta->user_rid, PDB_CHANGED); - if (pdb_get_group_rid(account) != delta->group_rid) - pdb_set_group_sid_from_rid(account, delta->group_rid, PDB_CHANGED); + if (pdb_get_user_rid(account) != r->rid) + pdb_set_user_sid_from_rid(account, r->rid, PDB_CHANGED); + if (pdb_get_group_rid(account) != r->primary_gid) + pdb_set_group_sid_from_rid(account, r->primary_gid, PDB_CHANGED); /* Logon and password information */ - if (!nt_time_is_zero(&delta->logon_time)) { - unix_time = nt_time_to_unix(delta->logon_time); + if (!nt_time_is_zero(&r->last_logon)) { + unix_time = nt_time_to_unix(r->last_logon); stored_time = pdb_get_logon_time(account); if (stored_time != unix_time) pdb_set_logon_time(account, unix_time, PDB_CHANGED); } - if (!nt_time_is_zero(&delta->logoff_time)) { - unix_time = nt_time_to_unix(delta->logoff_time); + if (!nt_time_is_zero(&r->last_logoff)) { + unix_time = nt_time_to_unix(r->last_logoff); stored_time = pdb_get_logoff_time(account); if (stored_time != unix_time) pdb_set_logoff_time(account, unix_time,PDB_CHANGED); } /* Logon Divs */ - if (pdb_get_logon_divs(account) != delta->logon_divs) - pdb_set_logon_divs(account, delta->logon_divs, PDB_CHANGED); + if (pdb_get_logon_divs(account) != r->logon_hours.units_per_week) + pdb_set_logon_divs(account, r->logon_hours.units_per_week, PDB_CHANGED); +#if 0 + /* no idea what to do with this one - gd */ /* Max Logon Hours */ if (delta->unknown1 != pdb_get_unknown_6(account)) { pdb_set_unknown_6(account, delta->unknown1, PDB_CHANGED); } - +#endif /* Logon Hours Len */ - if (delta->buf_logon_hrs.buf_len != pdb_get_hours_len(account)) { - pdb_set_hours_len(account, delta->buf_logon_hrs.buf_len, PDB_CHANGED); + if (r->logon_hours.units_per_week/8 != pdb_get_hours_len(account)) { + pdb_set_hours_len(account, r->logon_hours.units_per_week/8, PDB_CHANGED); } /* Logon Hours */ - if (delta->buf_logon_hrs.buffer) { + if (r->logon_hours.bits) { char oldstr[44], newstr[44]; pdb_sethexhours(oldstr, pdb_get_hours(account)); - pdb_sethexhours(newstr, delta->buf_logon_hrs.buffer); + pdb_sethexhours(newstr, r->logon_hours.bits); if (!strequal(oldstr, newstr)) - pdb_set_hours(account, (const uint8 *)delta->buf_logon_hrs.buffer, PDB_CHANGED); + pdb_set_hours(account, r->logon_hours.bits, PDB_CHANGED); } - if (pdb_get_bad_password_count(account) != delta->bad_pwd_count) - pdb_set_bad_password_count(account, delta->bad_pwd_count, PDB_CHANGED); + if (pdb_get_bad_password_count(account) != r->bad_password_count) + pdb_set_bad_password_count(account, r->bad_password_count, PDB_CHANGED); - if (pdb_get_logon_count(account) != delta->logon_count) - pdb_set_logon_count(account, delta->logon_count, PDB_CHANGED); + if (pdb_get_logon_count(account) != r->logon_count) + pdb_set_logon_count(account, r->logon_count, PDB_CHANGED); - if (!nt_time_is_zero(&delta->pwd_last_set_time)) { - unix_time = nt_time_to_unix(delta->pwd_last_set_time); + if (!nt_time_is_zero(&r->last_password_change)) { + unix_time = nt_time_to_unix(r->last_password_change); stored_time = pdb_get_pass_last_set_time(account); if (stored_time != unix_time) pdb_set_pass_last_set_time(account, unix_time, PDB_CHANGED); @@ -433,42 +563,41 @@ static NTSTATUS sam_account_from_delta(struct samu *account, SAM_ACCOUNT_INFO *d pdb_set_pass_last_set_time(account, time(NULL), PDB_CHANGED); } -#if 0 -/* No kickoff time in the delta? */ - if (!nt_time_is_zero(&delta->kickoff_time)) { - unix_time = nt_time_to_unix(&delta->kickoff_time); + if (!nt_time_is_zero(&r->acct_expiry)) { + unix_time = nt_time_to_unix(r->acct_expiry); stored_time = pdb_get_kickoff_time(account); if (stored_time != unix_time) pdb_set_kickoff_time(account, unix_time, PDB_CHANGED); } -#endif - /* Decode hashes from password hash - Note that win2000 may send us all zeros for the hashes if it doesn't + /* Decode hashes from password hash + Note that win2000 may send us all zeros for the hashes if it doesn't think this channel is secure enough - don't set the passwords at all in that case */ - if (memcmp(delta->pass.buf_lm_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(delta->user_rid, delta->pass.buf_lm_pwd, lm_passwd, 0); + if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->ntpassword.hash, lm_passwd, 0); pdb_set_lanman_passwd(account, lm_passwd, PDB_CHANGED); } - if (memcmp(delta->pass.buf_nt_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(delta->user_rid, delta->pass.buf_nt_pwd, nt_passwd, 0); + if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->lmpassword.hash, nt_passwd, 0); pdb_set_nt_passwd(account, nt_passwd, PDB_CHANGED); } /* TODO: account expiry time */ - pdb_set_acct_ctrl(account, delta->acb_info, PDB_CHANGED); + pdb_set_acct_ctrl(account, r->acct_flags, PDB_CHANGED); pdb_set_domain(account, lp_workgroup(), PDB_CHANGED); return NT_STATUS_OK; } -static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) +static NTSTATUS fetch_account_info(uint32_t rid, + struct netr_DELTA_USER *r) { + NTSTATUS nt_ret = NT_STATUS_UNSUCCESSFUL; fstring account; char *add_script = NULL; @@ -480,7 +609,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) struct passwd *passwd; fstring sid_string; - fstrcpy(account, unistr2_static(&delta->uni_acct_name)); + fstrcpy(account, r->account_name.string); d_printf("Creating account: %s\n", account); if ( !(sam_account = samu_new( NULL )) ) { @@ -489,17 +618,17 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) if (!(passwd = Get_Pwnam_alloc(sam_account, account))) { /* Create appropriate user */ - if (delta->acb_info & ACB_NORMAL) { + if (r->acct_flags & ACB_NORMAL) { add_script = talloc_strdup(sam_account, lp_adduser_script()); - } else if ( (delta->acb_info & ACB_WSTRUST) || - (delta->acb_info & ACB_SVRTRUST) || - (delta->acb_info & ACB_DOMTRUST) ) { + } else if ( (r->acct_flags & ACB_WSTRUST) || + (r->acct_flags & ACB_SVRTRUST) || + (r->acct_flags & ACB_DOMTRUST) ) { add_script = talloc_strdup(sam_account, lp_addmachine_script()); } else { DEBUG(1, ("Unknown user type: %s\n", - pdb_encode_acct_ctrl(delta->acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN))); + pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN))); nt_ret = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -534,30 +663,30 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) } sid_copy(&user_sid, get_global_sam_sid()); - sid_append_rid(&user_sid, delta->user_rid); + sid_append_rid(&user_sid, r->rid); DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n", sid_to_fstring(sid_string, &user_sid), account)); if (!pdb_getsampwsid(sam_account, &user_sid)) { - sam_account_from_delta(sam_account, delta); - DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n", + sam_account_from_delta(sam_account, r); + DEBUG(3, ("Attempting to add user SID %s for user %s in the passdb\n", sid_to_fstring(sid_string, &user_sid), pdb_get_username(sam_account))); if (!NT_STATUS_IS_OK(pdb_add_sam_account(sam_account))) { DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n", account)); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_ACCESS_DENIED; } } else { - sam_account_from_delta(sam_account, delta); - DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n", + sam_account_from_delta(sam_account, r); + DEBUG(3, ("Attempting to update user SID %s for user %s in the passdb\n", sid_to_fstring(sid_string, &user_sid), pdb_get_username(sam_account))); if (!NT_STATUS_IS_OK(pdb_update_sam_account(sam_account))) { DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n", account)); TALLOC_FREE(sam_account); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_ACCESS_DENIED; } } @@ -573,7 +702,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) } else { if (map.gid != passwd->pw_gid) { if (!(grp = getgrgid(map.gid))) { - DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n", + DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n", (unsigned long)map.gid, pdb_get_username(sam_account), sid_string_tos(&group_sid))); } else { smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account)); @@ -582,7 +711,7 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) } if ( !passwd ) { - DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n", + DEBUG(1, ("No unix user for this account (%s), cannot adjust mappings\n", pdb_get_username(sam_account))); } @@ -591,7 +720,8 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta) return nt_ret; } -static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) +static NTSTATUS fetch_group_info(uint32_t rid, + struct netr_DELTA_GROUP *r) { fstring name; fstring comment; @@ -601,8 +731,8 @@ static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) GROUP_MAP map; bool insert = True; - unistr2_to_ascii(name, &delta->uni_grp_name, sizeof(name)); - unistr2_to_ascii(comment, &delta->uni_grp_desc, sizeof(comment)); + fstrcpy(name, r->group_name.string); + fstrcpy(comment, r->description.string); /* add the group to the mapping table */ sid_copy(&group_sid, get_global_sam_sid()); @@ -620,14 +750,14 @@ static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) /* No group found from mapping, find it from its name. */ if ((grp = getgrnam(name)) == NULL) { - + /* No appropriate group found, create one */ - + d_printf("Creating unix group: '%s'\n", name); - + if (smb_create_group(name, &gid) != 0) return NT_STATUS_ACCESS_DENIED; - + if ((grp = getgrnam(name)) == NULL) return NT_STATUS_ACCESS_DENIED; } @@ -637,7 +767,7 @@ static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) map.sid = group_sid; map.sid_name_use = SID_NAME_DOM_GRP; fstrcpy(map.nt_name, name); - if (delta->hdr_grp_desc.buffer) { + if (r->description.string) { fstrcpy(map.comment, comment); } else { fstrcpy(map.comment, ""); @@ -651,7 +781,8 @@ static NTSTATUS fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta) return NT_STATUS_OK; } -static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) +static NTSTATUS fetch_group_mem_info(uint32_t rid, + struct netr_DELTA_GROUP_MEMBER *r) { int i; TALLOC_CTX *t = NULL; @@ -661,7 +792,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) GROUP_MAP map; struct group *grp; - if (delta->num_members == 0) { + if (r->num_rids == 0) { return NT_STATUS_OK; } @@ -685,8 +816,8 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) return NT_STATUS_NO_MEMORY; } - if (delta->num_members) { - if ((nt_members = TALLOC_ZERO_ARRAY(t, char *, delta->num_members)) == NULL) { + if (r->num_rids) { + if ((nt_members = TALLOC_ZERO_ARRAY(t, char *, r->num_rids)) == NULL) { DEBUG(0, ("talloc failed\n")); talloc_free(t); return NT_STATUS_NO_MEMORY; @@ -695,7 +826,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) nt_members = NULL; } - for (i=0; i<delta->num_members; i++) { + for (i=0; i < r->num_rids; i++) { struct samu *member = NULL; DOM_SID member_sid; @@ -705,11 +836,11 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) } sid_copy(&member_sid, get_global_sam_sid()); - sid_append_rid(&member_sid, delta->rids[i]); + sid_append_rid(&member_sid, r->rids[i]); if (!pdb_getsampwsid(member, &member_sid)) { DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n", - delta->rids[i], sid_string_tos(&member_sid), grp->gr_name)); + r->rids[i], sid_string_tos(&member_sid), grp->gr_name)); TALLOC_FREE(member); continue; } @@ -719,7 +850,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) TALLOC_FREE(member); continue; } - + d_printf("%s,", pdb_get_username(member)); nt_members[i] = talloc_strdup(t, pdb_get_username(member)); TALLOC_FREE(member); @@ -731,7 +862,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) while (*unix_members) { bool is_nt_member = False; - for (i=0; i<delta->num_members; i++) { + for (i=0; i < r->num_rids; i++) { if (nt_members[i] == NULL) { /* This was a primary group */ continue; @@ -751,7 +882,7 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) unix_members += 1; } - for (i=0; i<delta->num_members; i++) { + for (i=0; i < r->num_rids; i++) { bool is_unix_member = False; if (nt_members[i] == NULL) { @@ -776,12 +907,13 @@ static NTSTATUS fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta) smb_add_user_group(grp->gr_name, nt_members[i]); } } - + talloc_destroy(t); return NT_STATUS_OK; } -static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta, +static NTSTATUS fetch_alias_info(uint32_t rid, + struct netr_DELTA_ALIAS *r, DOM_SID dom_sid) { fstring name; @@ -792,8 +924,8 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta, GROUP_MAP map; bool insert = True; - unistr2_to_ascii(name, &delta->uni_als_name, sizeof(name)); - unistr2_to_ascii(comment, &delta->uni_als_desc, sizeof(comment)); + fstrcpy(name, r->alias_name.string); + fstrcpy(comment, r->description.string); /* Find out whether the group is already mapped */ sid_copy(&alias_sid, &dom_sid); @@ -838,24 +970,33 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta, return NT_STATUS_OK; } -static NTSTATUS fetch_alias_mem(uint32 rid, SAM_ALIAS_MEM_INFO *delta, DOM_SID dom_sid) +static NTSTATUS fetch_alias_mem(uint32_t rid, + struct netr_DELTA_ALIAS_MEMBER *r, + DOM_SID dom_sid) { return NT_STATUS_OK; } -static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta) +static NTSTATUS fetch_domain_info(uint32_t rid, + struct netr_DELTA_DOMAIN *r) { - time_t u_max_age, u_min_age, u_logout, u_lockoutreset, u_lockouttime; + time_t u_max_age, u_min_age, u_logout; +#if 0 + /* FIXME: gd */ + time_t u_lockoutreset, u_lockouttime; +#endif NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - char *domname; + const char *domname; - u_max_age = uint64s_nt_time_to_unix_abs(&delta->max_pwd_age); - u_min_age = uint64s_nt_time_to_unix_abs(&delta->min_pwd_age); - u_logout = uint64s_nt_time_to_unix_abs(&delta->force_logoff); + u_max_age = uint64s_nt_time_to_unix_abs((uint64 *)&r->max_password_age); + u_min_age = uint64s_nt_time_to_unix_abs((uint64 *)&r->min_password_age); + u_logout = uint64s_nt_time_to_unix_abs((uint64 *)&r->force_logoff_time); +#if 0 + /* FIXME: gd */ u_lockoutreset = uint64s_nt_time_to_unix_abs(&delta->account_lockout.reset_count); u_lockouttime = uint64s_nt_time_to_unix_abs(&delta->account_lockout.lockout_duration); - - domname = unistr2_to_ascii_talloc(talloc_tos(), &delta->uni_dom_name); +#endif + domname = r->domain_name.string; if (!domname) { return NT_STATUS_NO_MEMORY; } @@ -867,10 +1008,12 @@ static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta) } - if (!pdb_set_account_policy(AP_PASSWORD_HISTORY, delta->pwd_history_len)) + if (!pdb_set_account_policy(AP_PASSWORD_HISTORY, + r->password_history_length)) return nt_status; - if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN, delta->min_pwd_len)) + if (!pdb_set_account_policy(AP_MIN_PASSWORD_LEN, + r->min_password_length)) return nt_status; if (!pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (uint32)u_max_age)) @@ -881,7 +1024,8 @@ static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta) if (!pdb_set_account_policy(AP_TIME_TO_LOGOUT, (uint32)u_logout)) return nt_status; - +#if 0 +/* FIXME: gd */ if (!pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, delta->account_lockout.bad_attempt_lockout)) return nt_status; @@ -893,88 +1037,111 @@ static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta) if (!pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime)) return nt_status; +#endif - if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, delta->logon_chgpass)) + if (!pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, + r->logon_to_chgpass)) return nt_status; return NT_STATUS_OK; } - -static void fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta, - DOM_SID dom_sid) +static void fetch_sam_entry(struct netr_DELTA_ENUM *r, DOM_SID dom_sid) { - switch(hdr_delta->type) { - case SAM_DELTA_ACCOUNT_INFO: - fetch_account_info(hdr_delta->target_rid, - &delta->account_info); + switch(r->delta_type) { + case NETR_DELTA_USER: + fetch_account_info(r->delta_id_union.rid, + r->delta_union.user); break; - case SAM_DELTA_GROUP_INFO: - fetch_group_info(hdr_delta->target_rid, - &delta->group_info); + case NETR_DELTA_GROUP: + fetch_group_info(r->delta_id_union.rid, + r->delta_union.group); break; - case SAM_DELTA_GROUP_MEM: - fetch_group_mem_info(hdr_delta->target_rid, - &delta->grp_mem_info); + case NETR_DELTA_GROUP_MEMBER: + fetch_group_mem_info(r->delta_id_union.rid, + r->delta_union.group_member); break; - case SAM_DELTA_ALIAS_INFO: - fetch_alias_info(hdr_delta->target_rid, - &delta->alias_info, dom_sid); + case NETR_DELTA_ALIAS: + fetch_alias_info(r->delta_id_union.rid, + r->delta_union.alias, + dom_sid); break; - case SAM_DELTA_ALIAS_MEM: - fetch_alias_mem(hdr_delta->target_rid, - &delta->als_mem_info, dom_sid); + case NETR_DELTA_ALIAS_MEMBER: + fetch_alias_mem(r->delta_id_union.rid, + r->delta_union.alias_member, + dom_sid); break; - case SAM_DELTA_DOMAIN_INFO: - fetch_domain_info(hdr_delta->target_rid, - &delta->domain_info); + case NETR_DELTA_DOMAIN: + fetch_domain_info(r->delta_id_union.rid, + r->delta_union.domain); break; /* The following types are recognised but not handled */ - case SAM_DELTA_RENAME_GROUP: - d_printf("SAM_DELTA_RENAME_GROUP not handled\n"); + case NETR_DELTA_RENAME_GROUP: + d_printf("NETR_DELTA_RENAME_GROUP not handled\n"); + break; + case NETR_DELTA_RENAME_USER: + d_printf("NETR_DELTA_RENAME_USER not handled\n"); + break; + case NETR_DELTA_RENAME_ALIAS: + d_printf("NETR_DELTA_RENAME_ALIAS not handled\n"); + break; + case NETR_DELTA_POLICY: + d_printf("NETR_DELTA_POLICY not handled\n"); break; - case SAM_DELTA_RENAME_USER: - d_printf("SAM_DELTA_RENAME_USER not handled\n"); + case NETR_DELTA_TRUSTED_DOMAIN: + d_printf("NETR_DELTA_TRUSTED_DOMAIN not handled\n"); break; - case SAM_DELTA_RENAME_ALIAS: - d_printf("SAM_DELTA_RENAME_ALIAS not handled\n"); + case NETR_DELTA_ACCOUNT: + d_printf("NETR_DELTA_ACCOUNT not handled\n"); break; - case SAM_DELTA_POLICY_INFO: - d_printf("SAM_DELTA_POLICY_INFO not handled\n"); + case NETR_DELTA_SECRET: + d_printf("NETR_DELTA_SECRET not handled\n"); break; - case SAM_DELTA_TRUST_DOMS: - d_printf("SAM_DELTA_TRUST_DOMS not handled\n"); + case NETR_DELTA_DELETE_GROUP: + d_printf("NETR_DELTA_DELETE_GROUP not handled\n"); break; - case SAM_DELTA_PRIVS_INFO: - d_printf("SAM_DELTA_PRIVS_INFO not handled\n"); + case NETR_DELTA_DELETE_USER: + d_printf("NETR_DELTA_DELETE_USER not handled\n"); break; - case SAM_DELTA_SECRET_INFO: - d_printf("SAM_DELTA_SECRET_INFO not handled\n"); + case NETR_DELTA_MODIFY_COUNT: + d_printf("NETR_DELTA_MODIFY_COUNT not handled\n"); break; - case SAM_DELTA_DELETE_GROUP: - d_printf("SAM_DELTA_DELETE_GROUP not handled\n"); + case NETR_DELTA_DELETE_ALIAS: + d_printf("NETR_DELTA_DELETE_ALIAS not handled\n"); break; - case SAM_DELTA_DELETE_USER: - d_printf("SAM_DELTA_DELETE_USER not handled\n"); + case NETR_DELTA_DELETE_TRUST: + d_printf("NETR_DELTA_DELETE_TRUST not handled\n"); break; - case SAM_DELTA_MODIFIED_COUNT: - d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n"); + case NETR_DELTA_DELETE_ACCOUNT: + d_printf("NETR_DELTA_DELETE_ACCOUNT not handled\n"); + break; + case NETR_DELTA_DELETE_SECRET: + d_printf("NETR_DELTA_DELETE_SECRET not handled\n"); + break; + case NETR_DELTA_DELETE_GROUP2: + d_printf("NETR_DELTA_DELETE_GROUP2 not handled\n"); + break; + case NETR_DELTA_DELETE_USER2: + d_printf("NETR_DELTA_DELETE_USER2 not handled\n"); break; default: - d_printf("Unknown delta record type %d\n", hdr_delta->type); + d_printf("Unknown delta record type %d\n", r->delta_type); break; } } static NTSTATUS fetch_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type, DOM_SID dom_sid) { - uint32 sync_context = 0; NTSTATUS result; int i; TALLOC_CTX *mem_ctx; - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; - uint32 num_deltas; + const char *logon_server = pipe_hnd->cli->desthost; + const char *computername = global_myname(); + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + enum netr_SamDatabaseID database_id = db_type; + uint16_t restart_state = 0; + uint32_t sync_context = 0; if (!(mem_ctx = talloc_init("fetch_database"))) return NT_STATUS_NO_MEMORY; @@ -995,20 +1162,36 @@ static NTSTATUS fetch_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type, } do { - result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, - db_type, sync_context, - &num_deltas, - &hdr_deltas, &deltas); - - if (NT_STATUS_IS_OK(result) || - NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { - for (i = 0; i < num_deltas; i++) { - fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid); - } - } else - return result; + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; + + netlogon_creds_client_step(pipe_hnd->dc, &credential); + + result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx, + logon_server, + computername, + &credential, + &return_authenticator, + database_id, + restart_state, + &sync_context, + &delta_enum_array, + 0xffff); + + /* Check returned credentials. */ + if (!netlogon_creds_client_check(pipe_hnd->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + + if (NT_STATUS_IS_ERR(result)) { + break; + } + + for (i = 0; i < delta_enum_array->num_deltas; i++) { + fetch_sam_entry(&delta_enum_array->delta_enum[i], dom_sid); + } - sync_context += 1; } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); talloc_destroy(mem_ctx); @@ -1016,7 +1199,7 @@ static NTSTATUS fetch_database(struct rpc_pipe_client *pipe_hnd, uint32 db_type, return result; } -static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const char +static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const char *builtin_sid, FILE *add_fd) { const char *user_suffix, *group_suffix, *machine_suffix, *idmap_suffix; @@ -1048,7 +1231,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch SAFE_FREE(suffix_attr); return NT_STATUS_NO_MEMORY; } - /* If it exists and is distinct from other containers, + /* If it exists and is distinct from other containers, Write the Users entity */ if (*user_suffix && strcmp(user_suffix, suffix)) { user_attr = sstring_sub(lp_ldap_user_suffix(), '=', ','); @@ -1067,7 +1250,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch SAFE_FREE(user_attr); return NT_STATUS_NO_MEMORY; } - /* If it exists and is distinct from other containers, + /* If it exists and is distinct from other containers, Write the Groups entity */ if (*group_suffix && strcmp(group_suffix, suffix)) { group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); @@ -1079,7 +1262,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fflush(add_fd); } - /* If it exists and is distinct from other containers, + /* If it exists and is distinct from other containers, Write the Computers entity */ machine_suffix = lp_ldap_machine_suffix(); if (machine_suffix == NULL) { @@ -1103,7 +1286,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fflush(add_fd); } - /* If it exists and is distinct from other containers, + /* If it exists and is distinct from other containers, Write the IdMap entity */ idmap_suffix = lp_ldap_idmap_suffix(); if (idmap_suffix == NULL) { @@ -1139,7 +1322,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fprintf(add_fd, "\n"); fflush(add_fd); - /* Write the Domain Admins entity */ + /* Write the Domain Admins entity */ fprintf(add_fd, "# Domain Admins, %s, %s\n", group_attr, suffix); fprintf(add_fd, "dn: cn=Domain Admins,ou=%s,%s\n", group_attr, @@ -1156,7 +1339,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fprintf(add_fd, "\n"); fflush(add_fd); - /* Write the Domain Users entity */ + /* Write the Domain Users entity */ fprintf(add_fd, "# Domain Users, %s, %s\n", group_attr, suffix); fprintf(add_fd, "dn: cn=Domain Users,ou=%s,%s\n", group_attr, @@ -1172,7 +1355,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch fprintf(add_fd, "\n"); fflush(add_fd); - /* Write the Domain Guests entity */ + /* Write the Domain Guests entity */ fprintf(add_fd, "# Domain Guests, %s, %s\n", group_attr, suffix); fprintf(add_fd, "dn: cn=Domain Guests,ou=%s,%s\n", group_attr, @@ -1273,7 +1456,7 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch return NT_STATUS_OK; } -static NTSTATUS map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid, +static NTSTATUS map_populate_groups(GROUPMAP *groupmap, ACCOUNTMAP *accountmap, fstring sid, const char *suffix, const char *builtin_sid) { char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); @@ -1431,7 +1614,7 @@ static int fprintf_attr(FILE *add_fd, const char *attr_name, return res; } -static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupmap, +static NTSTATUS fetch_group_info_to_ldif(struct netr_DELTA_GROUP *r, GROUPMAP *groupmap, FILE *add_fd, fstring sid, char *suffix) { fstring groupname; @@ -1439,9 +1622,7 @@ static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); /* Get the group name */ - unistr2_to_ascii(groupname, - &delta->group_info.uni_grp_name, - sizeof(groupname)); + fstrcpy(groupname, r->group_name.string); /* Set up the group type (always 2 for group info) */ grouptype = 2; @@ -1463,7 +1644,7 @@ static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma } /* Map the group rid, gid, and dn */ - g_rid = delta->group_info.gid.g_rid; + g_rid = r->rid; groupmap->rid = g_rid; groupmap->gidNumber = ldif_gid; snprintf(groupmap->sambaSID, sizeof(groupmap->sambaSID), @@ -1491,7 +1672,7 @@ static NTSTATUS fetch_group_info_to_ldif(SAM_DELTA_CTR *delta, GROUPMAP *groupma return NT_STATUS_OK; } -static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, +static NTSTATUS fetch_account_info_to_ldif(struct netr_DELTA_USER *r, GROUPMAP *groupmap, ACCOUNTMAP *accountmap, FILE *add_fd, @@ -1511,21 +1692,18 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, int i; /* Get the username */ - unistr2_to_ascii(username, - &(delta->account_info.uni_acct_name), - sizeof(username)); + fstrcpy(username, r->account_name.string); /* Get the rid */ - rid = delta->account_info.user_rid; + rid = r->rid; /* Map the rid and username for group member info later */ accountmap->rid = rid; snprintf(accountmap->cn, sizeof(accountmap->cn), "%s", username); /* Get the home directory */ - if (delta->account_info.acb_info & ACB_NORMAL) { - unistr2_to_ascii(homedir, &(delta->account_info.uni_home_dir), - sizeof(homedir)); + if (r->acct_flags & ACB_NORMAL) { + fstrcpy(homedir, r->home_directory.string); if (!*homedir) { snprintf(homedir, sizeof(homedir), "/home/%s", username); } else { @@ -1538,60 +1716,48 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, } /* Get the logon script */ - unistr2_to_ascii(logonscript, &(delta->account_info.uni_logon_script), - sizeof(logonscript)); + fstrcpy(logonscript, r->logon_script.string); /* Get the home drive */ - unistr2_to_ascii(homedrive, &(delta->account_info.uni_dir_drive), - sizeof(homedrive)); + fstrcpy(homedrive, r->home_drive.string); /* Get the home path */ - unistr2_to_ascii(homepath, &(delta->account_info.uni_home_dir), - sizeof(homepath)); + fstrcpy(homepath, r->home_directory.string); /* Get the description */ - unistr2_to_ascii(description, &(delta->account_info.uni_acct_desc), - sizeof(description)); + fstrcpy(description, r->description.string); /* Get the display name */ - unistr2_to_ascii(fullname, &(delta->account_info.uni_full_name), - sizeof(fullname)); + fstrcpy(fullname, r->full_name.string); /* Get the profile path */ - unistr2_to_ascii(profilepath, &(delta->account_info.uni_profile), - sizeof(profilepath)); + fstrcpy(profilepath, r->profile_path.string); /* Get lm and nt password data */ - if (memcmp(delta->account_info.pass.buf_lm_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(delta->account_info.user_rid, - delta->account_info.pass.buf_lm_pwd, - lm_passwd, 0); - pdb_sethexpwd(hex_lm_passwd, lm_passwd, - delta->account_info.acb_info); + if (memcmp(r->lmpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->lmpassword.hash, lm_passwd, 0); + pdb_sethexpwd(hex_lm_passwd, lm_passwd, r->acct_flags); } else { pdb_sethexpwd(hex_lm_passwd, NULL, 0); } - if (memcmp(delta->account_info.pass.buf_nt_pwd, zero_buf, 16) != 0) { - sam_pwd_hash(delta->account_info.user_rid, - delta->account_info.pass.buf_nt_pwd, - nt_passwd, 0); - pdb_sethexpwd(hex_nt_passwd, nt_passwd, - delta->account_info.acb_info); + if (memcmp(r->ntpassword.hash, zero_buf, 16) != 0) { + sam_pwd_hash(r->rid, r->ntpassword.hash, nt_passwd, 0); + pdb_sethexpwd(hex_nt_passwd, nt_passwd, r->acct_flags); } else { pdb_sethexpwd(hex_nt_passwd, NULL, 0); } - unix_time = nt_time_to_unix(delta->account_info.pwd_last_set_time); + unix_time = nt_time_to_unix(r->last_password_change); /* Increment the uid for the new user */ ldif_uid++; /* Set up group id and sambaSID for the user */ - group_rid = delta->account_info.group_rid; + group_rid = r->primary_gid; for (i=0; i<alloced; i++) { if (groupmap[i].rid == group_rid) break; } if (i == alloced){ - DEBUG(1, ("Could not find rid %d in groupmap array\n", + DEBUG(1, ("Could not find rid %d in groupmap array\n", group_rid)); return NT_STATUS_UNSUCCESSFUL; } @@ -1599,7 +1765,7 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, snprintf(sambaSID, sizeof(sambaSID), groupmap[i].sambaSID); /* Set up sambaAcctFlags */ - flags = pdb_encode_acct_ctrl(delta->account_info.acb_info, + flags = pdb_encode_acct_ctrl(r->acct_flags, NEW_PW_FORMAT_SPACE_PADDED_LEN); /* Add the user to the temporary add ldif file */ @@ -1626,8 +1792,8 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, fprintf_attr(add_fd, "sambaHomeDrive", "%s", homedrive); if (*logonscript) fprintf_attr(add_fd, "sambaLogonScript", "%s", logonscript); - fprintf(add_fd, "loginShell: %s\n", - ((delta->account_info.acb_info & ACB_NORMAL) ? + fprintf(add_fd, "loginShell: %s\n", + ((r->acct_flags & ACB_NORMAL) ? "/bin/bash" : "/bin/false")); fprintf(add_fd, "gecos: System User\n"); if (*description) @@ -1651,10 +1817,10 @@ static NTSTATUS fetch_account_info_to_ldif(SAM_DELTA_CTR *delta, return NT_STATUS_OK; } -static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, +static NTSTATUS fetch_alias_info_to_ldif(struct netr_DELTA_ALIAS *r, GROUPMAP *groupmap, FILE *add_fd, fstring sid, - char *suffix, + char *suffix, unsigned db_type) { fstring aliasname, description; @@ -1662,12 +1828,10 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, char *group_attr = sstring_sub(lp_ldap_group_suffix(), '=', ','); /* Get the alias name */ - unistr2_to_ascii(aliasname, &(delta->alias_info.uni_als_name), - sizeof(aliasname)); + fstrcpy(aliasname, r->alias_name.string); /* Get the alias description */ - unistr2_to_ascii(description, &(delta->alias_info.uni_als_desc), - sizeof(description)); + fstrcpy(description, r->description.string); /* Set up the group type */ switch (db_type) { @@ -1684,7 +1848,7 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, /* These groups are entered by populate_ldap_for_ldif - Note that populate creates a group called Relicators, + Note that populate creates a group called Relicators, but NT returns a group called Replicator */ if (strcmp(aliasname, "Domain Admins") == 0 || @@ -1703,7 +1867,7 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, } /* Map the group rid and gid */ - g_rid = delta->group_info.gid.g_rid; + g_rid = r->rid; groupmap->gidNumber = ldif_gid; snprintf(groupmap->sambaSID, sizeof(groupmap->sambaSID), "%s-%d", sid, g_rid); @@ -1730,8 +1894,8 @@ static NTSTATUS fetch_alias_info_to_ldif(SAM_DELTA_CTR *delta, return NT_STATUS_OK; } -static NTSTATUS fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, - SAM_DELTA_HDR *hdr_delta, +static NTSTATUS fetch_groupmem_info_to_ldif(struct netr_DELTA_GROUP_MEMBER *r, + uint32_t id_rid, GROUPMAP *groupmap, ACCOUNTMAP *accountmap, FILE *mod_fd, int alloced) @@ -1741,8 +1905,8 @@ static NTSTATUS fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, int i, j, k; /* Get the dn for the group */ - if (delta->grp_mem_info.num_members > 0) { - group_rid = hdr_delta->target_rid; + if (r->num_rids > 0) { + group_rid = id_rid; for (j=0; j<alloced; j++) { if (groupmap[j].rid == group_rid) break; } @@ -1755,8 +1919,8 @@ static NTSTATUS fetch_groupmem_info_to_ldif(SAM_DELTA_CTR *delta, fprintf(mod_fd, "dn: %s\n", group_dn); /* Get the cn for each member */ - for (i=0; i<delta->grp_mem_info.num_members; i++) { - rid = delta->grp_mem_info.rids[i]; + for (i=0; i < r->num_rids; i++) { + rid = r->rids[i]; for (k=0; k<alloced; k++) { if (accountmap[k].rid == rid) break; } @@ -1786,15 +1950,19 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, const char *add_template = "/tmp/add.ldif.XXXXXX"; const char *mod_template = "/tmp/mod.ldif.XXXXXX"; fstring sid, domainname; - uint32 sync_context = 0; NTSTATUS ret = NT_STATUS_OK, result; int k; TALLOC_CTX *mem_ctx; - SAM_DELTA_HDR *hdr_deltas; - SAM_DELTA_CTR *deltas; uint32 num_deltas; FILE *add_file = NULL, *mod_file = NULL, *ldif_file = NULL; int num_alloced = 0, g_index = 0, a_index = 0; + const char *logon_server = pipe_hnd->cli->desthost; + const char *computername = global_myname(); + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + enum netr_SamDatabaseID database_id = db_type; + uint16_t restart_state = 0; + uint32_t sync_context = 0; /* Set up array for mapping accounts to groups */ /* Array element is the group rid */ @@ -1802,7 +1970,7 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, /* Set up array for mapping account rid's to cn's */ /* Array element is the account rid */ - ACCOUNTMAP *accountmap = NULL; + ACCOUNTMAP *accountmap = NULL; if (!(mem_ctx = talloc_init("fetch_database"))) { return NT_STATUS_NO_MEMORY; @@ -1838,7 +2006,7 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, DEBUG(1, ("Could not open %s\n", mod_name)); ret = NT_STATUS_UNSUCCESSFUL; goto done; - } + } /* Get the sid */ sid_to_fstring(sid, &dom_sid); @@ -1894,23 +2062,41 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, d_fprintf(stderr, "Fetching PRIVS databases\n"); break; default: - d_fprintf(stderr, - "Fetching unknown database type %u\n", + d_fprintf(stderr, + "Fetching unknown database type %u\n", db_type ); break; } do { - result = rpccli_netlogon_sam_sync(pipe_hnd, mem_ctx, - db_type, sync_context, - &num_deltas, &hdr_deltas, - &deltas); - if (!NT_STATUS_IS_OK(result) && - !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { - ret = NT_STATUS_OK; - goto done; /* is this correct? jmcd */ + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; + + netlogon_creds_client_step(pipe_hnd->dc, &credential); + + result = rpccli_netr_DatabaseSync2(pipe_hnd, mem_ctx, + logon_server, + computername, + &credential, + &return_authenticator, + database_id, + restart_state, + &sync_context, + &delta_enum_array, + 0xffff); + + /* Check returned credentials. */ + if (!netlogon_creds_client_check(pipe_hnd->dc, + &return_authenticator.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; } + if (NT_STATUS_IS_ERR(result)) { + break; + } + + num_deltas = delta_enum_array->num_deltas; + /* Re-allocate memory for groupmap and accountmap arrays */ groupmap = SMB_REALLOC_ARRAY(groupmap, GROUPMAP, num_deltas+num_alloced); @@ -1923,7 +2109,7 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, } /* Initialize the new records */ - memset(&groupmap[num_alloced], 0, + memset(&groupmap[num_alloced], 0, sizeof(GROUPMAP)*num_deltas); memset(&accountmap[num_alloced], 0, sizeof(ACCOUNTMAP)*num_deltas); @@ -1933,73 +2119,60 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, /* Loop through the deltas */ for (k=0; k<num_deltas; k++) { - switch(hdr_deltas[k].type) { - case SAM_DELTA_DOMAIN_INFO: + + union netr_DELTA_UNION u = + delta_enum_array->delta_enum[k].delta_union; + union netr_DELTA_ID_UNION id = + delta_enum_array->delta_enum[k].delta_id_union; + + switch(delta_enum_array->delta_enum[k].delta_type) { + case NETR_DELTA_DOMAIN: /* Is this case needed? */ - unistr2_to_ascii( - domainname, - &deltas[k].domain_info.uni_dom_name, - sizeof(domainname)); + fstrcpy(domainname, + u.domain->domain_name.string); break; - case SAM_DELTA_GROUP_INFO: + case NETR_DELTA_GROUP: fetch_group_info_to_ldif( - &deltas[k], &groupmap[g_index], + u.group, + &groupmap[g_index], add_file, sid, suffix); g_index++; break; - case SAM_DELTA_ACCOUNT_INFO: + case NETR_DELTA_USER: fetch_account_info_to_ldif( - &deltas[k], groupmap, + u.user, groupmap, &accountmap[a_index], add_file, sid, suffix, num_alloced); a_index++; break; - case SAM_DELTA_ALIAS_INFO: + case NETR_DELTA_ALIAS: fetch_alias_info_to_ldif( - &deltas[k], &groupmap[g_index], + u.alias, &groupmap[g_index], add_file, sid, suffix, db_type); g_index++; break; - case SAM_DELTA_GROUP_MEM: + case NETR_DELTA_GROUP_MEMBER: fetch_groupmem_info_to_ldif( - &deltas[k], &hdr_deltas[k], - groupmap, accountmap, + u.group_member, id.rid, + groupmap, accountmap, mod_file, num_alloced); break; - case SAM_DELTA_ALIAS_MEM: - break; - case SAM_DELTA_POLICY_INFO: - break; - case SAM_DELTA_PRIVS_INFO: - break; - case SAM_DELTA_TRUST_DOMS: - /* Implemented but broken */ - break; - case SAM_DELTA_SECRET_INFO: - /* Implemented but broken */ - break; - case SAM_DELTA_RENAME_GROUP: - /* Not yet implemented */ - break; - case SAM_DELTA_RENAME_USER: - /* Not yet implemented */ - break; - case SAM_DELTA_RENAME_ALIAS: - /* Not yet implemented */ - break; - case SAM_DELTA_DELETE_GROUP: - /* Not yet implemented */ - break; - case SAM_DELTA_DELETE_USER: - /* Not yet implemented */ - break; - case SAM_DELTA_MODIFIED_COUNT: - break; + case NETR_DELTA_ALIAS_MEMBER: + case NETR_DELTA_POLICY: + case NETR_DELTA_ACCOUNT: + case NETR_DELTA_TRUSTED_DOMAIN: + case NETR_DELTA_SECRET: + case NETR_DELTA_RENAME_GROUP: + case NETR_DELTA_RENAME_USER: + case NETR_DELTA_RENAME_ALIAS: + case NETR_DELTA_DELETE_GROUP: + case NETR_DELTA_DELETE_USER: + case NETR_DELTA_MODIFY_COUNT: default: break; } /* end of switch */ @@ -2065,7 +2238,7 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, DEBUG(1,("unlink(%s) failed, error was (%s)\n", mod_name, strerror(errno))); } - + if (ldif_file && (ldif_file != stdout)) { fclose(ldif_file); } @@ -2079,15 +2252,15 @@ static NTSTATUS fetch_database_to_ldif(struct rpc_pipe_client *pipe_hnd, return ret; } -/** +/** * Basic usage function for 'net rpc vampire' * @param argc Standard main() style argc * @param argc Standard main() style argv. Initial components are already * stripped **/ -int rpc_vampire_usage(int argc, const char **argv) -{ +int rpc_vampire_usage(int argc, const char **argv) +{ d_printf("net rpc vampire [ldif [<ldif-filename>] [options]\n" "\t to pull accounts from a remote PDC where we are a BDC\n" "\t\t no args puts accounts in local passdb from smb.conf\n" @@ -2100,13 +2273,13 @@ int rpc_vampire_usage(int argc, const char **argv) /* dump sam database via samsync rpc calls */ -NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, - const char *domain_name, +NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, + 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) + const char **argv) { NTSTATUS result; fstring my_dom_sid_str; @@ -2120,7 +2293,7 @@ NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, "workgroup=%s\n\n in your smb.conf?\n", domain_name, get_global_sam_name(), - sid_to_fstring(my_dom_sid_str, + sid_to_fstring(my_dom_sid_str, get_global_sam_sid()), domain_name, sid_to_fstring(rem_dom_sid_str, domain_sid), diff --git a/source3/utils/net_rpc_service.c b/source3/utils/net_rpc_service.c index a70ecf3c72..242d653017 100644 --- a/source3/utils/net_rpc_service.c +++ b/source3/utils/net_rpc_service.c @@ -1,30 +1,33 @@ -/* - 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) Gerald (Jerry) Carter 2005 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" +#define CLI_SERVER_NAME_SLASH(_ctx, _p, _cli) \ + _p = talloc_asprintf(_ctx, "\\\\%s", _cli->cli->desthost); + /******************************************************************** ********************************************************************/ static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, POLICY_HND *hSCM, const char *service, uint32 *state ) @@ -32,24 +35,32 @@ static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd, POLICY_HND hService; SERVICE_STATUS service_status; WERROR result = WERR_GENERAL_FAILURE; - + NTSTATUS status; + /* now cycle until the status is actually 'watch_state' */ - - result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService, - service, SC_RIGHT_SVC_QUERY_STATUS ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx, + hSCM, + service, + SC_RIGHT_SVC_QUERY_STATUS, + &hService, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); return result; } - result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status ); - if ( W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx, + &hService, + &service_status, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { *state = service_status.state; } - + rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL); - + return result; } @@ -57,17 +68,17 @@ static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd, ********************************************************************/ static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, POLICY_HND *hSCM, - const char *service, + const char *service, uint32 watch_state, uint32 *final_state ) { uint32 i; uint32 state = 0; WERROR result = WERR_GENERAL_FAILURE; - - + + i = 0; while ( (state != watch_state ) && i<30 ) { /* get the status */ @@ -76,15 +87,15 @@ static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd, if ( !W_ERROR_IS_OK(result) ) { break; } - + d_printf("."); i++; sys_usleep( 100 ); } d_printf("\n"); - + *final_state = state; - + return result; } @@ -92,155 +103,187 @@ static WERROR watch_service_state(struct rpc_pipe_client *pipe_hnd, ********************************************************************/ static WERROR control_service(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, + TALLOC_CTX *mem_ctx, POLICY_HND *hSCM, - const char *service, + const char *service, uint32 control, uint32 watch_state ) { POLICY_HND hService; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; SERVICE_STATUS service_status; uint32 state = 0; - + /* Open the Service */ - - result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, hSCM, &hService, - service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx, + hSCM, + service, + (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE), + &hService, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); goto done; } - + /* get the status */ - result = rpccli_svcctl_control_service(pipe_hnd, mem_ctx, &hService, - control, &service_status ); - - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_ControlService(pipe_hnd, mem_ctx, + &hService, + control, + &service_status, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Control service request failed. [%s]\n", dos_errstr(result)); goto done; } - + /* loop -- checking the state until we are where we want to be */ - + result = watch_service_state(pipe_hnd, mem_ctx, hSCM, service, watch_state, &state ); - + d_printf("%s service is %s.\n", service, svc_status_string(state)); -done: +done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL); - + return result; -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_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 hSCM; ENUM_SERVICES_STATUS *services; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; fstring servicename; fstring displayname; uint32 num_services = 0; + const char *server_name; int i; - + if (argc != 0 ) { d_printf("Usage: net rpc service list\n"); return NT_STATUS_OK; } - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - + result = rpccli_svcctl_enumerate_services(pipe_hnd, mem_ctx, &hSCM, SVCCTL_TYPE_WIN32, SVCCTL_STATE_ALL, &num_services, &services ); - + if ( !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result)); goto done; } - + if ( num_services == 0 ) d_printf("No services returned\n"); - + for ( i=0; i<num_services; i++ ) { rpcstr_pull( servicename, services[i].servicename.buffer, sizeof(servicename), -1, STR_TERMINATE ); rpcstr_pull( displayname, services[i].displayname.buffer, sizeof(displayname), -1, STR_TERMINATE ); - + d_printf("%-20s \"%s\"\n", servicename, displayname); } -done: +done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); - + return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_status_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 hSCM, hService; WERROR result = WERR_GENERAL_FAILURE; - fstring servicename; + NTSTATUS status; SERVICE_STATUS service_status; SERVICE_CONFIG config; fstring ascii_string; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; } - fstrcpy( servicename, argv[0] ); - /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - + /* Open the Service */ - - result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, servicename, - (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG) ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx, + &hSCM, + argv[0], + (SC_RIGHT_SVC_QUERY_STATUS|SC_RIGHT_SVC_QUERY_CONFIG), + &hService, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); goto done; } - + /* get the status */ - result = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, &hService, &service_status ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_QueryServiceStatus(pipe_hnd, mem_ctx, + &hService, + &service_status, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result)); goto done; } - - d_printf("%s service is %s.\n", servicename, svc_status_string(service_status.state)); + + d_printf("%s service is %s.\n", argv[0], svc_status_string(service_status.state)); /* get the config */ @@ -284,28 +327,30 @@ static NTSTATUS rpc_service_status_internal(const DOM_SID *domain_sid, d_printf("\tDisplay Name = %s\n", ascii_string); } -done: +done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL); rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_stop_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 hSCM; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; fstring servicename; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; @@ -314,36 +359,45 @@ static NTSTATUS rpc_service_stop_internal(const DOM_SID *domain_sid, fstrcpy( servicename, argv[0] ); /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - - result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, + + result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_CONTROL_STOP, SVCCTL_STOPPED ); - + rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); - + return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_pause_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 hSCM; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; fstring servicename; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; @@ -352,36 +406,45 @@ static NTSTATUS rpc_service_pause_internal(const DOM_SID *domain_sid, fstrcpy( servicename, argv[0] ); /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - - result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, + + result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED ); - + rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); - + return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_resume_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 hSCM; WERROR result = WERR_GENERAL_FAILURE; + NTSTATUS status; fstring servicename; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; @@ -390,78 +453,100 @@ static NTSTATUS rpc_service_resume_internal(const DOM_SID *domain_sid, fstrcpy( servicename, argv[0] ); /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm(pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - - result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, + + result = control_service(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING ); - + rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); - + return werror_to_ntstatus(result); -} +} /******************************************************************** ********************************************************************/ static NTSTATUS rpc_service_start_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 hSCM, hService; WERROR result = WERR_GENERAL_FAILURE; - fstring servicename; + NTSTATUS status; uint32 state = 0; - + const char *server_name; + if (argc != 1 ) { d_printf("Usage: net rpc service status <service>\n"); return NT_STATUS_OK; } - fstrcpy( servicename, argv[0] ); - /* Open the Service Control Manager */ - - result = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE ); - if ( !W_ERROR_IS_OK(result) ) { + CLI_SERVER_NAME_SLASH(mem_ctx, server_name, pipe_hnd); + NT_STATUS_HAVE_NO_MEMORY(server_name); + + status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, + server_name, + NULL, + SC_RIGHT_MGR_ENUMERATE_SERVICE, + &hSCM, + &result); + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); return werror_to_ntstatus(result); } - + /* Open the Service */ - - result = rpccli_svcctl_open_service(pipe_hnd, mem_ctx, &hSCM, &hService, - servicename, SC_RIGHT_SVC_START ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_OpenServiceW(pipe_hnd, mem_ctx, + &hSCM, + argv[0], + SC_RIGHT_SVC_START, + &hService, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); goto done; } - + /* get the status */ - result = rpccli_svcctl_start_service(pipe_hnd, mem_ctx, &hService, NULL, 0 ); - if ( !W_ERROR_IS_OK(result) ) { + status = rpccli_svcctl_StartServiceW(pipe_hnd, mem_ctx, + &hService, + 0, + NULL, + &result); + + if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result)); goto done; } - - result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state ); - + + result = watch_service_state(pipe_hnd, mem_ctx, &hSCM, argv[0], SVCCTL_RUNNING, &state ); + if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) ) - d_printf("Successfully started service: %s\n", servicename ); + d_printf("Successfully started service: %s\n", argv[0] ); else - d_fprintf(stderr, "Failed to start service: %s [%s]\n", servicename, dos_errstr(result) ); - -done: + d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) ); + +done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL); rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); @@ -473,7 +558,7 @@ done: static int rpc_service_list( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_list_internal, argc, argv ); } @@ -482,7 +567,7 @@ static int rpc_service_list( int argc, const char **argv ) static int rpc_service_start( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_start_internal, argc, argv ); } @@ -491,7 +576,7 @@ static int rpc_service_start( int argc, const char **argv ) static int rpc_service_stop( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_stop_internal, argc, argv ); } @@ -500,7 +585,7 @@ static int rpc_service_stop( int argc, const char **argv ) static int rpc_service_resume( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_resume_internal, argc, argv ); } @@ -509,7 +594,7 @@ static int rpc_service_resume( int argc, const char **argv ) static int rpc_service_pause( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_pause_internal, argc, argv ); } @@ -518,7 +603,7 @@ static int rpc_service_pause( int argc, const char **argv ) static int rpc_service_status( int argc, const char **argv ) { - return run_rpc_command( NULL, PI_SVCCTL, 0, + return run_rpc_command( NULL, PI_SVCCTL, 0, rpc_service_status_internal, argc, argv ); } @@ -533,14 +618,14 @@ static int net_help_service( int argc, const char **argv ) d_printf("net rpc service pause <service> Pause a service\n"); d_printf("net rpc service resume <service> Resume a paused service\n"); d_printf("net rpc service status <service> View the current status of a service\n"); - + return -1; } /******************************************************************** ********************************************************************/ -int net_rpc_service(int argc, const char **argv) +int net_rpc_service(int argc, const char **argv) { struct functable func[] = { {"list", rpc_service_list}, @@ -551,9 +636,9 @@ int net_rpc_service(int argc, const char **argv) {"status", rpc_service_status}, {NULL, NULL} }; - + if ( argc ) return net_run_function( argc, argv, func, net_help_service ); - + return net_help_service( argc, argv ); } diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index a3a403d7bd..df2bf9753b 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -418,7 +418,7 @@ NTSTATUS contact_winbind_auth_crap(const char *username, } if (flags & WBFLAG_PAM_UNIX_NAME) { - *unix_name = SMB_STRDUP((char *)response.extra_data.data); + *unix_name = SMB_STRDUP(response.data.auth.unix_username); if (!*unix_name) { winbindd_free_response(&response); return NT_STATUS_NO_MEMORY; @@ -1215,7 +1215,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, char *principal; DATA_BLOB ap_rep; DATA_BLOB session_key; - PAC_DATA *pac_data = NULL; + struct PAC_DATA *pac_data = NULL; if ( request.negTokenInit.mechToken.data == NULL ) { DEBUG(1, ("Client did not provide Kerberos data\n")); diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 76036bfdde..db2eefe1e2 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -1035,7 +1035,7 @@ static bool do_winbind_dump_domain_list(struct messaging_context *msg_ctx, print_pid_string_cb); buf_len = sizeof(myid)+domain_len; - buf = SMB_MALLOC(buf_len); + buf = SMB_MALLOC_ARRAY(uint8_t, buf_len); if (!buf) { return false; } diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index db7ceca04d..0900d56987 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -421,7 +421,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, char *sidstr; uint32 group_rid; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - NET_USER_INFO_3 *user; + struct netr_SamInfo3 *user = NULL; DEBUG(3,("ads: query_user\n")); @@ -437,11 +437,11 @@ static NTSTATUS query_user(struct winbindd_domain *domain, DEBUG(5,("query_user: Cache lookup succeeded for %s\n", sid_string_dbg(sid))); - sid_compose(&info->user_sid, &domain->sid, user->user_rid); - sid_compose(&info->group_sid, &domain->sid, user->group_rid); + sid_compose(&info->user_sid, &domain->sid, user->base.rid); + sid_compose(&info->group_sid, &domain->sid, user->base.primary_gid); - info->acct_name = unistr2_to_ascii_talloc(mem_ctx, &user->uni_user_name); - info->full_name = unistr2_to_ascii_talloc(mem_ctx, &user->uni_full_name); + info->acct_name = talloc_strdup(mem_ctx, user->base.account_name.string); + info->full_name = talloc_strdup(mem_ctx, user->base.full_name.string); nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL, &info->homedir, &info->shell, &info->full_name, diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index f235e401e8..4d81ee3960 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -2248,7 +2248,7 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, /* Invalidate the getpwnam and getgroups entries for a winbindd domain */ void wcache_invalidate_samlogon(struct winbindd_domain *domain, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 *info3) { struct winbind_cache *cache; diff --git a/source3/winbindd/winbindd_creds.c b/source3/winbindd/winbindd_creds.c index 4dbace5bcc..9c7acd64e6 100644 --- a/source3/winbindd/winbindd_creds.c +++ b/source3/winbindd/winbindd_creds.c @@ -29,11 +29,11 @@ NTSTATUS winbindd_get_creds(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const DOM_SID *sid, - NET_USER_INFO_3 **info3, + struct netr_SamInfo3 **info3, const uint8 *cached_nt_pass[NT_HASH_LEN], const uint8 *cred_salt[NT_HASH_LEN]) { - NET_USER_INFO_3 *info; + struct netr_SamInfo3 *info; NTSTATUS status; status = wcache_get_creds(domain, mem_ctx, sid, cached_nt_pass, cred_salt); @@ -56,7 +56,7 @@ NTSTATUS winbindd_store_creds(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const char *user, const char *pass, - NET_USER_INFO_3 *info3, + struct netr_SamInfo3 *info3, const DOM_SID *user_sid) { NTSTATUS status; @@ -66,10 +66,10 @@ NTSTATUS winbindd_store_creds(struct winbindd_domain *domain, if (info3 != NULL) { DOM_SID sid; - sid_copy(&sid, &(info3->dom_sid.sid)); - sid_append_rid(&sid, info3->user_rid); + sid_copy(&sid, info3->base.domain_sid); + sid_append_rid(&sid, info3->base.rid); sid_copy(&cred_sid, &sid); - info3->user_flgs |= NETLOGON_CACHED_ACCOUNT; + info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT; } else if (user_sid != NULL) { @@ -138,7 +138,7 @@ NTSTATUS winbindd_update_creds_by_info3(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, const char *user, const char *pass, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 *info3) { return winbindd_store_creds(domain, mem_ctx, user, pass, info3, NULL); } diff --git a/source3/winbindd/winbindd_locator.c b/source3/winbindd/winbindd_locator.c index 6b1cff99e0..10a6c5afeb 100644 --- a/source3/winbindd/winbindd_locator.c +++ b/source3/winbindd/winbindd_locator.c @@ -58,7 +58,7 @@ static enum winbindd_result dual_dsgetdcname(struct winbindd_domain *domain, struct winbindd_cli_state *state) { NTSTATUS result; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; const char *dc = NULL; state->request.domain_name @@ -74,15 +74,15 @@ static enum winbindd_result dual_dsgetdcname(struct winbindd_domain *domain, return WINBINDD_ERROR; } - if (info->domain_controller_address) { - dc = info->domain_controller_address; + if (info->dc_address) { + dc = info->dc_address; if ((dc[0] == '\\') && (dc[1] == '\\')) { dc += 2; } } - if ((!dc || !is_ipaddress_v4(dc)) && info->domain_controller_name) { - dc = info->domain_controller_name; + if ((!dc || !is_ipaddress_v4(dc)) && info->dc_unc) { + dc = info->dc_unc; } if (!dc || !*dc) { diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index dd27ad62f3..ef5a312eea 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -29,136 +29,162 @@ static NTSTATUS append_info3_as_txt(TALLOC_CTX *mem_ctx, struct winbindd_cli_state *state, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 *info3) { + char *ex; + size_t size; + uint32_t i; + state->response.data.auth.info3.logon_time = - nt_time_to_unix(info3->logon_time); + nt_time_to_unix(info3->base.last_logon); state->response.data.auth.info3.logoff_time = - nt_time_to_unix(info3->logoff_time); + nt_time_to_unix(info3->base.last_logoff); state->response.data.auth.info3.kickoff_time = - nt_time_to_unix(info3->kickoff_time); + nt_time_to_unix(info3->base.acct_expiry); state->response.data.auth.info3.pass_last_set_time = - nt_time_to_unix(info3->pass_last_set_time); + nt_time_to_unix(info3->base.last_password_change); state->response.data.auth.info3.pass_can_change_time = - nt_time_to_unix(info3->pass_can_change_time); + nt_time_to_unix(info3->base.allow_password_change); state->response.data.auth.info3.pass_must_change_time = - nt_time_to_unix(info3->pass_must_change_time); - - state->response.data.auth.info3.logon_count = info3->logon_count; - state->response.data.auth.info3.bad_pw_count = info3->bad_pw_count; - - state->response.data.auth.info3.user_rid = info3->user_rid; - state->response.data.auth.info3.group_rid = info3->group_rid; - sid_to_fstring(state->response.data.auth.info3.dom_sid, &(info3->dom_sid.sid)); - - state->response.data.auth.info3.num_groups = info3->num_groups; - state->response.data.auth.info3.user_flgs = info3->user_flgs; - - state->response.data.auth.info3.acct_flags = info3->acct_flags; - state->response.data.auth.info3.num_other_sids = info3->num_other_sids; - - unistr2_to_ascii(state->response.data.auth.info3.user_name, - &info3->uni_user_name, - sizeof(state->response.data.auth.info3.user_name)); - unistr2_to_ascii(state->response.data.auth.info3.full_name, - &info3->uni_full_name, - sizeof(state->response.data.auth.info3.full_name)); - unistr2_to_ascii(state->response.data.auth.info3.logon_script, - &info3->uni_logon_script, - sizeof(state->response.data.auth.info3.logon_script)); - unistr2_to_ascii(state->response.data.auth.info3.profile_path, - &info3->uni_profile_path, - sizeof(state->response.data.auth.info3.profile_path)); - unistr2_to_ascii(state->response.data.auth.info3.home_dir, - &info3->uni_home_dir, - sizeof(state->response.data.auth.info3.home_dir)); - unistr2_to_ascii(state->response.data.auth.info3.dir_drive, - &info3->uni_dir_drive, - sizeof(state->response.data.auth.info3.dir_drive)); - - unistr2_to_ascii(state->response.data.auth.info3.logon_srv, - &info3->uni_logon_srv, - sizeof(state->response.data.auth.info3.logon_srv)); - unistr2_to_ascii(state->response.data.auth.info3.logon_dom, - &info3->uni_logon_dom, - sizeof(state->response.data.auth.info3.logon_dom)); + nt_time_to_unix(info3->base.force_password_change); + + state->response.data.auth.info3.logon_count = info3->base.logon_count; + state->response.data.auth.info3.bad_pw_count = info3->base.bad_password_count; + + state->response.data.auth.info3.user_rid = info3->base.rid; + state->response.data.auth.info3.group_rid = info3->base.primary_gid; + sid_to_fstring(state->response.data.auth.info3.dom_sid, info3->base.domain_sid); + + state->response.data.auth.info3.num_groups = info3->base.groups.count; + state->response.data.auth.info3.user_flgs = info3->base.user_flags; + + state->response.data.auth.info3.acct_flags = info3->base.acct_flags; + state->response.data.auth.info3.num_other_sids = info3->sidcount; + + fstrcpy(state->response.data.auth.info3.user_name, + info3->base.account_name.string); + fstrcpy(state->response.data.auth.info3.full_name, + info3->base.full_name.string); + fstrcpy(state->response.data.auth.info3.logon_script, + info3->base.logon_script.string); + fstrcpy(state->response.data.auth.info3.profile_path, + info3->base.profile_path.string); + fstrcpy(state->response.data.auth.info3.home_dir, + info3->base.home_directory.string); + fstrcpy(state->response.data.auth.info3.dir_drive, + info3->base.home_drive.string); + + fstrcpy(state->response.data.auth.info3.logon_srv, + info3->base.logon_server.string); + fstrcpy(state->response.data.auth.info3.logon_dom, + info3->base.domain.string); + + ex = talloc_strdup(mem_ctx, ""); + NT_STATUS_HAVE_NO_MEMORY(ex); + + for (i=0; i < info3->base.groups.count; i++) { + ex = talloc_asprintf_append_buffer(ex, "0x%08X:0x%08X\n", + info3->base.groups.rids[i].rid, + info3->base.groups.rids[i].attributes); + NT_STATUS_HAVE_NO_MEMORY(ex); + } + + for (i=0; i < info3->sidcount; i++) { + char *sid; + + sid = dom_sid_string(mem_ctx, info3->sids[i].sid); + NT_STATUS_HAVE_NO_MEMORY(sid); + + ex = talloc_asprintf_append_buffer(ex, "%s:0x%08X\n", + sid, + info3->sids[i].attributes); + NT_STATUS_HAVE_NO_MEMORY(ex); + + talloc_free(sid); + } + + size = talloc_get_size(ex); + + SAFE_FREE(state->response.extra_data.data); + state->response.extra_data.data = SMB_MALLOC(size); + if (!state->response.extra_data.data) { + return NT_STATUS_NO_MEMORY; + } + memcpy(state->response.extra_data.data, ex, size); + talloc_free(ex); + + state->response.length += size; return NT_STATUS_OK; } static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx, struct winbindd_cli_state *state, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 *info3) { - prs_struct ps; - uint32 size; - if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) { - return NT_STATUS_NO_MEMORY; - } - if (!net_io_user_info3("", info3, &ps, 1, 3, False)) { - prs_mem_free(&ps); - return NT_STATUS_UNSUCCESSFUL; + DATA_BLOB blob; + enum ndr_err_code ndr_err; + + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info3, + (ndr_push_flags_fn_t)ndr_push_netr_SamInfo3); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0,("append_info3_as_ndr: failed to append\n")); + return ndr_map_error2ntstatus(ndr_err); } - size = prs_data_size(&ps); SAFE_FREE(state->response.extra_data.data); - state->response.extra_data.data = SMB_MALLOC(size); + state->response.extra_data.data = SMB_MALLOC(blob.length); if (!state->response.extra_data.data) { - prs_mem_free(&ps); + data_blob_free(&blob); return NT_STATUS_NO_MEMORY; } - memset( state->response.extra_data.data, '\0', size ); - prs_copy_all_data_out((char *)state->response.extra_data.data, &ps); - state->response.length += size; - prs_mem_free(&ps); + + memset(state->response.extra_data.data, '\0', blob.length); + memcpy(state->response.extra_data.data, blob.data, blob.length); + state->response.length += blob.length; + + data_blob_free(&blob); + return NT_STATUS_OK; } static NTSTATUS append_unix_username(TALLOC_CTX *mem_ctx, struct winbindd_cli_state *state, - const NET_USER_INFO_3 *info3, + const struct netr_SamInfo3 *info3, const char *name_domain, const char *name_user) { /* We've been asked to return the unix username, per 'winbind use default domain' settings and the like */ - fstring username_out; const char *nt_username, *nt_domain; - if (!(nt_domain = unistr2_to_ascii_talloc(mem_ctx, - &info3->uni_logon_dom))) { + nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string); + if (!nt_domain) { /* If the server didn't give us one, just use the one * we sent them */ nt_domain = name_domain; } - if (!(nt_username = unistr2_to_ascii_talloc(mem_ctx, - &info3->uni_user_name))) { + nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string); + if (!nt_username) { /* If the server didn't give us one, just use the one * we sent them */ nt_username = name_user; } - fill_domain_username(username_out, nt_domain, nt_username, - True); - - DEBUG(5,("Setting unix username to [%s]\n", username_out)); + fill_domain_username(state->response.data.auth.unix_username, + nt_domain, nt_username, True); - SAFE_FREE(state->response.extra_data.data); - state->response.extra_data.data = SMB_STRDUP(username_out); - if (!state->response.extra_data.data) { - return NT_STATUS_NO_MEMORY; - } - state->response.length += - strlen((const char *)state->response.extra_data.data)+1; + DEBUG(5,("Setting unix username to [%s]\n", + state->response.data.auth.unix_username)); return NT_STATUS_OK; } static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx, struct winbindd_cli_state *state, - const NET_USER_INFO_3 *info3, + const struct netr_SamInfo3 *info3, const char *name_domain, const char *name_user) { @@ -182,8 +208,8 @@ static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx, DOM_SID user_sid; fstring sidstr; - sid_copy(&user_sid, &info3->dom_sid.sid); - sid_append_rid(&user_sid, info3->user_rid); + sid_copy(&user_sid, info3->base.domain_sid); + sid_append_rid(&user_sid, info3->base.rid); sid_to_fstring(sidstr, &user_sid); afsname = talloc_string_sub(mem_ctx, afsname, "%s", sidstr); @@ -220,7 +246,7 @@ static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx, } static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, - NET_USER_INFO_3 *info3, + struct netr_SamInfo3 *info3, const char *group_sid) /** * Check whether a user belongs to a group or list of groups. @@ -534,7 +560,7 @@ static uid_t get_uid_from_state(struct winbindd_cli_state *state) static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, struct winbindd_cli_state *state, - NET_USER_INFO_3 **info3) + struct netr_SamInfo3 **info3) { #ifdef HAVE_KRB5 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; @@ -702,17 +728,17 @@ failed: static bool check_request_flags(uint32_t flags) { uint32_t flags_edata = WBFLAG_PAM_AFS_TOKEN | - WBFLAG_PAM_UNIX_NAME | + WBFLAG_PAM_INFO3_TEXT | WBFLAG_PAM_INFO3_NDR; if ( ( (flags & flags_edata) == WBFLAG_PAM_AFS_TOKEN) || ( (flags & flags_edata) == WBFLAG_PAM_INFO3_NDR) || - ( (flags & flags_edata) == WBFLAG_PAM_UNIX_NAME) || + ( (flags & flags_edata) == WBFLAG_PAM_INFO3_TEXT)|| !(flags & flags_edata) ) { return True; } - DEBUG(1,("check_request_flags: invalid request flags\n")); + DEBUG(1,("check_request_flags: invalid request flags[0x%08X]\n",flags)); return False; } @@ -721,7 +747,7 @@ static bool check_request_flags(uint32_t flags) ****************************************************************/ static NTSTATUS append_data(struct winbindd_cli_state *state, - NET_USER_INFO_3 *info3, + struct netr_SamInfo3 *info3, const char *name_domain, const char *name_user) { @@ -730,14 +756,14 @@ static NTSTATUS append_data(struct winbindd_cli_state *state, if (flags & WBFLAG_PAM_USER_SESSION_KEY) { memcpy(state->response.data.auth.user_session_key, - info3->user_sess_key, + info3->base.key.key, sizeof(state->response.data.auth.user_session_key) /* 16 */); } if (flags & WBFLAG_PAM_LMKEY) { memcpy(state->response.data.auth.first_8_lm_hash, - info3->lm_sess_key, + info3->base.LMSessKey.key, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */); } @@ -838,7 +864,7 @@ void winbindd_pam_auth(struct winbindd_cli_state *state) NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, struct winbindd_cli_state *state, - NET_USER_INFO_3 **info3) + struct netr_SamInfo3 **info3) { NTSTATUS result = NT_STATUS_LOGON_FAILURE; uint16 max_allowed_bad_attempts; @@ -848,7 +874,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, uchar new_nt_pass[NT_HASH_LEN]; const uint8 *cached_nt_pass; const uint8 *cached_salt; - NET_USER_INFO_3 *my_info3; + struct netr_SamInfo3 *my_info3; time_t kickoff_time, must_change_time; bool password_good = False; #ifdef HAVE_KRB5 @@ -920,43 +946,43 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, /* User *DOES* know the password, update logon_time and reset * bad_pw_count */ - my_info3->user_flgs |= NETLOGON_CACHED_ACCOUNT; + my_info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT; - if (my_info3->acct_flags & ACB_AUTOLOCK) { + if (my_info3->base.acct_flags & ACB_AUTOLOCK) { return NT_STATUS_ACCOUNT_LOCKED_OUT; } - if (my_info3->acct_flags & ACB_DISABLED) { + if (my_info3->base.acct_flags & ACB_DISABLED) { return NT_STATUS_ACCOUNT_DISABLED; } - if (my_info3->acct_flags & ACB_WSTRUST) { + if (my_info3->base.acct_flags & ACB_WSTRUST) { return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT; } - if (my_info3->acct_flags & ACB_SVRTRUST) { + if (my_info3->base.acct_flags & ACB_SVRTRUST) { return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT; } - if (my_info3->acct_flags & ACB_DOMTRUST) { + if (my_info3->base.acct_flags & ACB_DOMTRUST) { return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT; } - if (!(my_info3->acct_flags & ACB_NORMAL)) { + if (!(my_info3->base.acct_flags & ACB_NORMAL)) { DEBUG(0,("winbindd_dual_pam_auth_cached: whats wrong with that one?: 0x%08x\n", - my_info3->acct_flags)); + my_info3->base.acct_flags)); return NT_STATUS_LOGON_FAILURE; } - kickoff_time = nt_time_to_unix(my_info3->kickoff_time); + kickoff_time = nt_time_to_unix(my_info3->base.acct_expiry); if (kickoff_time != 0 && time(NULL) > kickoff_time) { return NT_STATUS_ACCOUNT_EXPIRED; } - must_change_time = nt_time_to_unix(my_info3->pass_must_change_time); + must_change_time = nt_time_to_unix(my_info3->base.force_password_change); if (must_change_time != 0 && must_change_time < time(NULL)) { /* we allow grace logons when the password has expired */ - my_info3->user_flgs |= NETLOGON_GRACE_LOGON; + my_info3->base.user_flags |= NETLOGON_GRACE_LOGON; /* return NT_STATUS_PASSWORD_EXPIRED; */ goto success; } @@ -1027,8 +1053,8 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, /* FIXME: we possibly should handle logon hours as well (does xp when * offline?) see auth/auth_sam.c:sam_account_ok for details */ - unix_to_nt_time(&my_info3->logon_time, time(NULL)); - my_info3->bad_pw_count = 0; + unix_to_nt_time(&my_info3->base.last_logon, time(NULL)); + my_info3->base.bad_password_count = 0; result = winbindd_update_creds_by_info3(domain, state->mem_ctx, @@ -1055,14 +1081,14 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, } /* increase counter */ - my_info3->bad_pw_count++; + my_info3->base.bad_password_count++; if (max_allowed_bad_attempts == 0) { goto failed; } /* lockout user */ - if (my_info3->bad_pw_count >= max_allowed_bad_attempts) { + if (my_info3->base.bad_password_count >= max_allowed_bad_attempts) { uint32 password_properties; @@ -1071,9 +1097,9 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, DEBUG(10,("winbindd_dual_pam_auth_cached: failed to get password properties.\n")); } - if ((my_info3->user_rid != DOMAIN_USER_RID_ADMIN) || + if ((my_info3->base.rid != DOMAIN_USER_RID_ADMIN) || (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)) { - my_info3->acct_flags |= ACB_AUTOLOCK; + my_info3->base.acct_flags |= ACB_AUTOLOCK; } } @@ -1094,7 +1120,7 @@ failed: NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, struct winbindd_cli_state *state, - NET_USER_INFO_3 **info3) + struct netr_SamInfo3 **info3) { struct winbindd_domain *contact_domain; fstring name_domain, name_user; @@ -1153,7 +1179,7 @@ done: NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, struct winbindd_cli_state *state, - NET_USER_INFO_3 **info3) + struct netr_SamInfo3 **info3) { struct rpc_pipe_client *netlogon_pipe; @@ -1167,18 +1193,10 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, fstring name_domain, name_user; bool retry; NTSTATUS result; - NET_USER_INFO_3 *my_info3; - - ZERO_STRUCTP(info3); + struct netr_SamInfo3 *my_info3 = NULL; *info3 = NULL; - my_info3 = TALLOC_ZERO_P(state->mem_ctx, NET_USER_INFO_3); - if (my_info3 == NULL) { - return NT_STATUS_NO_MEMORY; - } - - DEBUG(10,("winbindd_dual_pam_auth_samlogon\n")); /* Parse domain and username */ @@ -1286,7 +1304,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, chal, lm_resp, nt_resp, - my_info3); + &my_info3); attempts += 1; /* We have to try a second time as cm_connect_netlogon @@ -1320,7 +1338,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, * caller, we look up the account flags ourselve - gd */ if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) && - (my_info3->acct_flags == 0) && NT_STATUS_IS_OK(result)) { + (my_info3->base.acct_flags == 0) && NT_STATUS_IS_OK(result)) { struct rpc_pipe_client *samr_pipe; POLICY_HND samr_domain_handle, user_pol; @@ -1340,7 +1358,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, status_tmp = rpccli_samr_OpenUser(samr_pipe, state->mem_ctx, &samr_domain_handle, MAXIMUM_ALLOWED_ACCESS, - my_info3->user_rid, + my_info3->base.rid, &user_pol); if (!NT_STATUS_IS_OK(status_tmp)) { @@ -1368,7 +1386,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, goto done; } - my_info3->acct_flags = acct_flags; + my_info3->base.acct_flags = acct_flags; DEBUG(10,("successfully retrieved acct_flags 0x%x\n", acct_flags)); @@ -1386,8 +1404,8 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, NTSTATUS result = NT_STATUS_LOGON_FAILURE; NTSTATUS krb5_result = NT_STATUS_OK; fstring name_domain, name_user; - NET_USER_INFO_3 *info3 = NULL; - + struct netr_SamInfo3 *info3 = NULL; + /* Ensure null termination */ state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0'; @@ -1482,7 +1500,7 @@ sam_logon: DEBUG(10,("winbindd_dual_pam_auth_samlogon succeeded\n")); /* add the Krb5 err if we have one */ if ( NT_STATUS_EQUAL(krb5_result, NT_STATUS_TIME_DIFFERENCE_AT_DC ) ) { - info3->user_flgs |= LOGON_KRB5_FAIL_CLOCK_SKEW; + info3->base.user_flags |= LOGON_KRB5_FAIL_CLOCK_SKEW; } goto process_result; } @@ -1542,8 +1560,8 @@ process_result: the cache entry by storing the seq_num for the wrong domain). */ if ( domain->primary ) { - sid_compose(&user_sid, &info3->dom_sid.sid, - info3->user_rid); + sid_compose(&user_sid, info3->base.domain_sid, + info3->base.rid); cache_name2sid(domain, name_domain, name_user, SID_NAME_USER, &user_sid); } @@ -1708,7 +1726,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, struct winbindd_cli_state *state) { NTSTATUS result; - NET_USER_INFO_3 info3; + struct netr_SamInfo3 *info3 = NULL; struct rpc_pipe_client *netlogon_pipe; const char *name_user = NULL; const char *name_domain = NULL; @@ -1786,7 +1804,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, } do { - ZERO_STRUCT(info3); retry = False; netlogon_pipe = NULL; @@ -1840,12 +1857,12 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, if (NT_STATUS_IS_OK(result)) { - netsamlogon_cache_store(name_user, &info3); - wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3); + netsamlogon_cache_store(name_user, info3); + wcache_invalidate_samlogon(find_domain_from_name(name_domain), info3); /* Check if the user is in the right group */ - if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, &info3, + if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, info3, state->request.data.auth_crap.require_membership_of_sid))) { DEBUG(3, ("User %s is not in the required group (%s), so " "crap authentication is rejected\n", @@ -1854,7 +1871,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, goto done; } - result = append_data(state, &info3, name_domain, name_user); + result = append_data(state, info3, name_domain, name_user); if (!NT_STATUS_IS_OK(result)) { goto done; } diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index 585923410f..2a7704c8a5 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -6,6 +6,7 @@ Copyright (C) Tim Potter 2000-2001,2003 Copyright (C) Andrew Tridgell 2001 Copyright (C) Volker Lendecke 2005 + Copyright (C) Guenther Deschner 2008 (pidl conversion) 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 @@ -429,7 +430,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain, POLICY_HND dom_pol, user_pol; union samr_UserInfo *info = NULL; uint32 user_rid; - NET_USER_INFO_3 *user; + struct netr_SamInfo3 *user; struct rpc_pipe_client *cli; DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid))); @@ -449,14 +450,14 @@ static NTSTATUS query_user(struct winbindd_domain *domain, DEBUG(5,("query_user: Cache lookup succeeded for %s\n", sid_string_dbg(user_sid))); - sid_compose(&user_info->user_sid, &domain->sid, user->user_rid); + sid_compose(&user_info->user_sid, &domain->sid, user->base.rid); sid_compose(&user_info->group_sid, &domain->sid, - user->group_rid); + user->base.primary_gid); - user_info->acct_name = unistr2_to_ascii_talloc(mem_ctx, - &user->uni_user_name); - user_info->full_name = unistr2_to_ascii_talloc(mem_ctx, - &user->uni_full_name); + user_info->acct_name = talloc_strdup(mem_ctx, + user->base.account_name.string); + user_info->full_name = talloc_strdup(mem_ctx, + user->base.full_name.string); TALLOC_FREE(user); diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 7933ecf63e..038bafbe4e 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1272,7 +1272,7 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, const DOM_SID *user_sid, uint32 *p_num_groups, DOM_SID **user_sids) { - NET_USER_INFO_3 *info3 = NULL; + struct netr_SamInfo3 *info3 = NULL; NTSTATUS status = NT_STATUS_NO_MEMORY; int i; size_t num_groups = 0; @@ -1290,13 +1290,13 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - if (info3->num_groups == 0) { + if (info3->base.groups.count == 0) { TALLOC_FREE(info3); return NT_STATUS_UNSUCCESSFUL; } /* always add the primary group to the sid array */ - sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid); + sid_compose(&primary_group, info3->base.domain_sid, info3->base.rid); status = add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups); @@ -1305,9 +1305,9 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, return status; } - for (i=0; i<info3->num_groups; i++) { - sid_copy(&group_sid, &info3->dom_sid.sid); - sid_append_rid(&group_sid, info3->gids[i].g_rid); + for (i=0; i < info3->base.groups.count; i++) { + sid_copy(&group_sid, info3->base.domain_sid); + sid_append_rid(&group_sid, info3->base.groups.rids[i].rid); status = add_sid_to_array(mem_ctx, &group_sid, user_sids, &num_groups); @@ -1319,13 +1319,13 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, /* Add any Universal groups in the other_sids list */ - for (i=0; i<info3->num_other_sids; i++) { + for (i=0; i < info3->sidcount; i++) { /* Skip Domain local groups outside our domain. We'll get these from the getsidaliases() RPC call. */ - if (info3->other_sids_attrib[i] & SE_GROUP_RESOURCE) + if (info3->sids[i].attributes & SE_GROUP_RESOURCE) continue; - status = add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, + status = add_sid_to_array(mem_ctx, info3->sids[i].sid, user_sids, &num_groups); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); |