diff options
50 files changed, 3271 insertions, 1146 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 003752d18c..3928e6d181 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -340,6 +340,7 @@ o Andreas Schneider <anschneider@suse.de> * Don't restart winbind if a corrupted tdb is found during initialization. * Fix Windows 2008 (Longhorn) join. + * Fix crashbug in winbindd. * Add share parameter "administrative share". diff --git a/source3/Makefile.in b/source3/Makefile.in index 3df7958b1a..acd39d79b9 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -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@ @@ -231,8 +232,10 @@ 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 @@ -301,7 +304,8 @@ RPC_PARSE_OBJ1 = $(RPC_PARSE_OBJ0) rpc_parse/parse_sec.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_lsa.o \ + rpc_client/init_srvsvc.o LIBREPLACE_OBJ = @LIBREPLACE_OBJS@ @@ -378,8 +382,12 @@ 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 \ @@ -1096,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@ @@ -1143,7 +1153,7 @@ modules: SHOWFLAGS $(MODULES) 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 krb5pac.idl ntsvcs.idl libnet_join.idl + dssetup.idl krb5pac.idl ntsvcs.idl idl: @IDL_FILES="$(IDL_FILES)" CPP="$(CPP)" PERL="$(PERL)" \ @@ -1925,6 +1935,10 @@ 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 @@ -2035,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@ @@ -2157,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) diff --git a/source3/VERSION b/source3/VERSION index 814d171fd9..c97db4b04e 100644 --- a/source3/VERSION +++ b/source3/VERSION @@ -68,7 +68,7 @@ SAMBA_VERSION_RC_RELEASE= # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # # -> "3.0.0-SVN-build-199" # ######################################################## -SAMBA_VERSION_IS_GIT_SNAPSHOT= +SAMBA_VERSION_IS_GIT_SNAPSHOT=yes ######################################################## # This can be set by vendors if they want... # @@ -95,5 +95,5 @@ SAMBA_VERSION_IS_GIT_SNAPSHOT= # e.g. SAMBA_VERSION_VENDOR_SUFFIX=vendor_version() # # -> "CVS 3.0.0rc2-VendorVersion" # ######################################################## -SAMBA_VERSION_VENDOR_SUFFIX= +SAMBA_VERSION_VENDOR_SUFFIX="test" SAMBA_VERSION_VENDOR_PATCH= diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index ed66d0db0a..b6c26a1fc8 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -127,7 +127,8 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, nt_status = create_local_token(auth_ntlmssp_state->server_info); if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(10, ("create_local_token failed\n")); + DEBUG(10, ("create_local_token failed: %s\n", + nt_errstr(nt_status))); return nt_status; } diff --git a/source3/configure.in b/source3/configure.in index f481a30b3b..056c0f8049 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -109,6 +109,7 @@ 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) @@ -6078,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]) ################################################# 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 a2c3a0c466..c54afd8933 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -1287,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/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_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/lib/netapi/serverinfo.c b/source3/lib/netapi/serverinfo.c index 09f275bac9..d30e7d97f7 100644 --- a/source3/lib/netapi/serverinfo.c +++ b/source3/lib/netapi/serverinfo.c @@ -271,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/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_sock.c b/source3/lib/util_sock.c index a7c35c4887..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; diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index 72bbf60d45..7c8bd418e5 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -118,6 +118,7 @@ static DNS_ERROR dns_udp_open( const char *nameserver, the receiver (in this example case "123.456.789.1") and the specified port number. */ + ZERO_STRUCT(RecvAddr); RecvAddr.sin_family = AF_INET; RecvAddr.sin_port = htons( DNS_UDP_PORT ); RecvAddr.sin_addr.s_addr = ulAddress; 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_join.c b/source3/libnet/libnet_join.c index 866d1c06e1..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) \ @@ -630,7 +630,7 @@ static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx, 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; @@ -1412,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; 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/libnet_join.h b/source3/librpc/gen_ndr/libnet_join.h index 8dbadcf0a2..0415f030b4 100644 --- a/source3/librpc/gen_ndr/libnet_join.h +++ b/source3/librpc/gen_ndr/libnet_join.h @@ -7,6 +7,8 @@ #ifndef _HEADER_libnetjoin #define _HEADER_libnetjoin +enum netr_SchannelType; + struct libnet_JoinCtx { struct { @@ -25,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 { diff --git a/source3/librpc/gen_ndr/ndr_libnet_join.c b/source3/librpc/gen_ndr/ndr_libnet_join.c index 6e65d03977..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) { diff --git a/source3/librpc/gen_ndr/ndr_srvsvc.c b/source3/librpc/gen_ndr/ndr_srvsvc.c index 9b08ade4af..22a04f86f8 100644 --- a/source3/librpc/gen_ndr/ndr_srvsvc.c +++ b/source3/librpc/gen_ndr/ndr_srvsvc.c @@ -15656,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)); @@ -15678,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); @@ -15708,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); @@ -15759,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) { @@ -16179,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)); @@ -16201,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); @@ -16224,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); @@ -16274,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) { @@ -17001,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)); } @@ -17016,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); @@ -17037,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; @@ -17079,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/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/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/idl/libnet_join.idl b/source3/librpc/idl/libnet_join.idl index 65d17c9203..3975d83a80 100644 --- a/source3/librpc/idl/libnet_join.idl +++ b/source3/librpc/idl/libnet_join.idl @@ -12,6 +12,7 @@ import "wkssvc.idl", "security.idl"; interface libnetjoin { typedef bitmap wkssvc_joinflags wkssvc_joinflags; + typedef enum netr_SchannelType netr_SchannelType; [nopush,nopull,noopnum] WERROR libnet_JoinCtx( [in] string dc_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, 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/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 16582f8049..971cde1252 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -1054,7 +1054,7 @@ static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, split_dfs_path(ctx, refs[0].dfspath, pp_newserver, pp_newshare, &newextrapath ); - if (!pp_newserver || !pp_newshare) { + if ((*pp_newserver == NULL) || (*pp_newshare == NULL)) { 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/nsswitch/wins.c b/source3/nsswitch/wins.c index 35649dfda2..e74cfaf69f 100644 --- a/source3/nsswitch/wins.c +++ b/source3/nsswitch/wins.c @@ -110,6 +110,7 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) } if (address[0].ss.ss_family != AF_INET) { free(address); + free(ret); return NULL; } *ret = ((struct sockaddr_in *)&address[0].ss)->sin_addr; diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 87a648a5b4..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); 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/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_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_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 8a25b6cfd5..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; } @@ -602,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; } @@ -612,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; } @@ -637,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); @@ -745,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__)); @@ -852,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; } @@ -867,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; } @@ -890,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; } @@ -910,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++; } @@ -953,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; } @@ -998,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__)); @@ -1044,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; } @@ -1101,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; @@ -1111,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; } } @@ -1154,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__)); @@ -1180,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 */ @@ -1188,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; */ @@ -1203,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); @@ -1233,91 +1233,116 @@ WERROR _srv_net_file_enum(pipes_struct *p, SRV_Q_NET_FILE_ENUM *q_u, SRV_R_NET_F 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_winreg_nt.c b/source3/rpc_server/srv_winreg_nt.c index 7ff93e0b07..c76bc19d9c 100644 --- a/source3/rpc_server/srv_winreg_nt.c +++ b/source3/rpc_server/srv_winreg_nt.c @@ -508,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; 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/script/build_idl.sh b/source3/script/build_idl.sh index 39a63573b9..7aaddc70c7 100755 --- a/source3/script/build_idl.sh +++ b/source3/script/build_idl.sh @@ -23,7 +23,7 @@ for f in ${IDL_FILES}; do basename=`basename $f .idl` ndr="librpc/gen_ndr/ndr_$basename.c" - if [ -f $ndr ] ; then + if [ -f $ndr ] && false; then if [ "x`find librpc/idl/$f -newer $ndr -print`" = "xlibrpc/idl/$f" ]; then list="$list librpc/idl/$f" fi diff --git a/source3/script/tests/selftest.sh b/source3/script/tests/selftest.sh index c6232cf301..2f2cb7b086 100755 --- a/source3/script/tests/selftest.sh +++ b/source3/script/tests/selftest.sh @@ -220,11 +220,16 @@ nogroup:x:65534:nobody $USERNAME-group:x:$GROUPID: EOF +MAKE_TEST_BINARY="bin/smbpasswd" +export MAKE_TEST_BINARY + (echo $PASSWORD; echo $PASSWORD) | \ - smbpasswd -c $CONFFILE -L -s -a $USERNAME >/dev/null || exit 1 + bin/smbpasswd -c $CONFFILE -L -s -a $USERNAME >/dev/null || exit 1 echo "DONE"; +MAKE_TEST_BINARY="" + SERVER_TEST_FIFO="$PREFIX/server_test.fifo" export SERVER_TEST_FIFO NMBD_TEST_LOG="$PREFIX/nmbd_test.log" @@ -234,9 +239,6 @@ export WINBINDD_TEST_LOG SMBD_TEST_LOG="$PREFIX/smbd_test.log" export SMBD_TEST_LOG -MAKE_TEST_BINARY="" -export MAKE_TEST_BINARY - # start off with 0 failures failed=0 export failed @@ -272,6 +274,7 @@ START=`date` echo "delaying for nbt name registration" sleep 10 # This will return quickly when things are up, but be slow if we need to wait for (eg) SSL init + MAKE_TEST_BINARY="bin/nmblookup" bin/nmblookup $CONFIGURATION -U $SERVER_IP __SAMBA__ bin/nmblookup $CONFIGURATION __SAMBA__ bin/nmblookup $CONFIGURATION -U 127.255.255.255 __SAMBA__ @@ -279,8 +282,10 @@ START=`date` bin/nmblookup $CONFIGURATION $SERVER # make sure smbd is also up set echo "wait for smbd" + MAKE_TEST_BINARY="bin/smbclient" bin/smbclient $CONFIGURATION -L $SERVER_IP -U% -p 139 | head -2 bin/smbclient $CONFIGURATION -L $SERVER_IP -U% -p 139 | head -2 + MAKE_TEST_BINARY="" failed=0 diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9baa02977a..5578dafd85 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -539,6 +539,8 @@ static void reply_spnego_kerberos(struct smb_request *req, if ( !server_info->ptok ) { ret = create_local_token( server_info ); if ( !NT_STATUS_IS_OK(ret) ) { + DEBUG(10,("failed to create local token: %s\n", + nt_errstr(ret))); SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 9358a4f184..46e0a2591b 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1121,6 +1121,12 @@ int net_ads_join(int argc, const char **argv) goto fail; } + if (!(ctx = talloc_init("net_ads_join"))) { + d_fprintf(stderr, "Could not initialise talloc context.\n"); + werr = WERR_NOMEM; + goto fail; + } + use_in_memory_ccache(); werr = libnet_init_JoinCtx(ctx, &r); @@ -1128,12 +1134,6 @@ int net_ads_join(int argc, const char **argv) goto fail; } - if (!(ctx = talloc_init("net_ads_join"))) { - d_fprintf(stderr, "Could not initialise talloc context.\n"); - werr = WERR_NOMEM; - goto fail; - } - /* process additional command line args */ for ( i=0; i<argc; i++ ) { diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c index 63b7f48626..e5185d09f0 100644 --- a/source3/utils/smbget.c +++ b/source3/utils/smbget.c @@ -29,7 +29,7 @@ int columns = 0; -static int _resume, _recursive, debuglevel; +static int _resume, _recursive, debuglevel, update; static char *outputfile; @@ -303,8 +303,26 @@ static int smb_download_file(const char *base, const char *name, int recursive, if(newpath[0] == '/')newpath++; - /* Open local file and, if necessary, resume */ - if(!send_stdout) { + /* Open local file according to the mode */ + if(update) { + /* if it is up-to-date, skip */ + if(stat(newpath, &localstat) == 0 && + localstat.st_mtime >= remotestat.st_mtime) { + if(verbose) + printf("%s is up-to-date, skipping\n", newpath); + smbc_close(remotehandle); + return 0; + } + /* else open it for writing and truncate if it exists */ + localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | O_TRUNC, 0775); + if(localhandle < 0) { + fprintf(stderr, "Can't open %s : %s\n", newpath, + strerror(errno)); + smbc_close(remotehandle); + return 1; + } + /* no offset */ + } else if(!send_stdout) { localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | (!resume?O_EXCL:0), 0755); if(localhandle < 0) { fprintf(stderr, "Can't open %s: %s\n", newpath, strerror(errno)); @@ -527,6 +545,7 @@ int main(int argc, const char **argv) {"guest", 'a', POPT_ARG_NONE, NULL, 'a', "Work as user guest" }, {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" }, {"resume", 'r', POPT_ARG_NONE, &_resume, 0, "Automatically resume aborted files" }, + {"update", 'U', POPT_ARG_NONE, &update, 0, "Download only when remote file is newer than local file or local file is missing"}, {"recursive", 'R', POPT_ARG_NONE, &_recursive, 0, "Recursively download files" }, {"username", 'u', POPT_ARG_STRING, &username, 'u', "Username to use" }, {"password", 'p', POPT_ARG_STRING, &password, 'p', "Password to use" }, @@ -576,6 +595,10 @@ int main(int argc, const char **argv) } } + if((send_stdout || _resume || outputfile) && update) { + fprintf(stderr, "The -o, -R or -O and -U options can not be used together.\n"); + return 1; + } if((send_stdout || outputfile) && _recursive) { fprintf(stderr, "The -o or -O and -R options can not be used together.\n"); return 1; |