diff options
65 files changed, 1872 insertions, 961 deletions
diff --git a/packaging/Fedora/samba.spec.tmpl b/packaging/Fedora/samba.spec.tmpl index ba9b2768e64..bd403fc9dc5 100644 --- a/packaging/Fedora/samba.spec.tmpl +++ b/packaging/Fedora/samba.spec.tmpl @@ -125,7 +125,11 @@ CFLAGS="$RPM_OPT_FLAGS" ./configure \ --enable-cups=yes make showlayout make proto -make %{?_smp_mflags} all modules nsswitch/libnss_wins.so debug2html +make %{?_smp_mflags} all modules nsswitch/libnss_wins.so + +## build the cifs fs mount helper +gcc -o mount.cifs $RPM_OPT_FLAGS -Wall -D_GNU_SOURCE -D_LARGEFILE64_SOURCE client/mount.cifs.c +gcc -o umount.cifs $RPM_OPT_FLAGS -Wall -D_GNU_SOURCE -D_LARGEFILE64_SOURCE client/umount.cifs.c %install @@ -153,6 +157,8 @@ install -m755 %{SOURCE8} $RPM_BUILD_ROOT%{_bindir} install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/pam.d/samba install -m644 %{SOURCE1} $RPM_BUILD_ROOT/etc/logrotate.d/samba install -m755 source/script/mksmbpasswd.sh $RPM_BUILD_ROOT%{_bindir} +install -m755 source/mount.cifs $RPM_BUILD_ROOT/sbin/mount.cifs +install -m755 source/umount.cifs $RPM_BUILD_ROOT/sbin/umount.cifs install -m755 %{SOURCE5} $RPM_BUILD_ROOT%{initdir}/smb install -m755 %{SOURCE6} $RPM_BUILD_ROOT%{initdir}/winbind @@ -204,8 +210,6 @@ rm -f $RPM_BUILD_ROOT%{_mandir}/man1/log2pcap.1* rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbsh.1* rm -f $RPM_BUILD_ROOT%{_mandir}/man1/smbget.1* rm -f $RPM_BUILD_ROOT%{_mandir}/man5/smbgetrc.5* -rm -f $RPM_BUILD_ROOT/%{_mandir}/man8/mount.cifs.8* -rm -f $RPM_BUILD_ROOT/%{_mandir}/man8/umount.cifs.8* rm -f $RPM_BUILD_ROOT/%{_mandir}/man1/testprns.1* %clean @@ -311,6 +315,8 @@ fi %defattr(-,root,root) /sbin/mount.smb /sbin/mount.smbfs +/sbin/mount.cifs +/sbin/umount.cifs %{_libdir}/samba/lowcase.dat %{_libdir}/samba/upcase.dat %{_libdir}/samba/valid.dat @@ -325,6 +331,8 @@ fi %{_mandir}/man8/smbmnt.8* %{_mandir}/man8/smbmount.8* %{_mandir}/man8/smbumount.8* +%{_mandir}/man8/mount.cifs.8.* +%{_mandir}/man8/umount.cifs.8.* %{_mandir}/man8/smbspool.8* %{_bindir}/nmblookup %{_bindir}/smbclient @@ -362,6 +370,7 @@ fi # %{_bindir}/editreg %{_bindir}/ntlm_auth %{_bindir}/pdbedit +%{_bindir}/eventlogadm %{_bindir}/profiles %{_bindir}/smbcquotas #%{_bindir}/vfstest diff --git a/packaging/RedHat/samba.spec.tmpl b/packaging/RedHat/samba.spec.tmpl index 4f253910d5a..0794d57b248 100644 --- a/packaging/RedHat/samba.spec.tmpl +++ b/packaging/RedHat/samba.spec.tmpl @@ -127,7 +127,7 @@ mkdir -p $RPM_BUILD_ROOT%{prefix}/{lib,include} # Install standard binary files for i in nmblookup smbclient smbpasswd smbstatus testparm \ rpcclient smbspool smbcacls smbcontrol wbinfo smbmnt net \ - smbcacls pdbedit tdbbackup smbtree ntlm_auth smbcquotas + smbcacls pdbedit eventlogadm tdbbackup smbtree ntlm_auth smbcquotas do install -m755 source/bin/$i $RPM_BUILD_ROOT%{prefix}/bin done @@ -426,6 +426,7 @@ fi %{prefix}/bin/smbcquotas %{prefix}/bin/smbcacls %{prefix}/bin/pdbedit +%{prefix}/bin/eventlogadm %{prefix}/bin/tdbbackup %{prefix}/bin/smbtree %attr(755,root,root) /lib/libnss_wins.s* diff --git a/packaging/Solaris/makepkg.sh b/packaging/Solaris/makepkg.sh index 10ffa1a3072..e60669703c6 100644 --- a/packaging/Solaris/makepkg.sh +++ b/packaging/Solaris/makepkg.sh @@ -9,7 +9,7 @@ INSTALL_BASE=/opt/samba SBINPROGS="smbd nmbd winbindd swat" -BINPROGS="findsmb nmblookup pdbedit rpcclient smbclient smbcquotas smbspool smbtar tdbbackup testparm wbinfo net ntlm_auth profiles smbcacls smbcontrol smbpasswd smbstatus smbtree tdbdump" +BINPROGS="findsmb nmblookup eventlogadm pdbedit rpcclient smbclient smbcquotas smbspool smbtar tdbbackup testparm wbinfo net ntlm_auth profiles smbcacls smbcontrol smbpasswd smbstatus smbtree tdbdump" MSGFILES="de.msg en.msg fr.msg it.msg ja.msg nl.msg pl.msg tr.msg" VFSLIBS="audit.so default_quota.so extd_audit.so full_audit.so readonly.so shadow_copy.so cap.so expand_msdfs.so fake_perms.so netatalk.so recycle.so" DATFILES="lowcase.dat upcase.dat valid.dat" diff --git a/source/Makefile.in b/source/Makefile.in index 4310f51bd54..c10f7c38565 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -130,7 +130,7 @@ BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \ bin/tdbtool@EXEEXT@ BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \ bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ \ - bin/smbcquotas@EXEEXT@ + bin/smbcquotas@EXEEXT@ bin/eventlogadm@EXEEXT@ TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \ bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \ @@ -614,6 +614,9 @@ SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ $(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \ $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) +WR_EVENTLOG_OBJ = utils/eventlogadm.o rpc_server/srv_eventlog_lib.o \ + $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) + TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) libsmb/nterr.o RPCTORTURE_OBJ = torture/rpctorture.o \ @@ -750,6 +753,8 @@ debug2html : SHOWFLAGS bin/debug2html@EXEEXT@ smbfilter : SHOWFLAGS bin/smbfilter@EXEEXT@ +eventlogadm: SHOWFLAGS bin/eventlogadm@EXEEXT@ + talloctort : SHOWFLAGS bin/talloctort@EXEEXT@ nsswitch : SHOWFLAGS bin/winbindd@EXEEXT@ bin/wbinfo@EXEEXT@ @WINBIND_NSS@ \ @@ -759,7 +764,7 @@ wins : SHOWFLAGS @WINBIND_WINS_NSS@ modules: SHOWFLAGS proto_exists $(MODULES) -everything: all libsmbclient debug2html smbfilter talloctort modules torture \ +everything: all libsmbclient debug2html smbfilter talloctort modules torture eventlogadm \ $(EVERYTHING_PROGS) .SUFFIXES: @@ -811,24 +816,24 @@ test: all torture dynconfig.o: dynconfig.c Makefile @echo Compiling $*.c - @$(CC) $(FLAGS) $(PATH_FLAGS) @PIE_CFLAGS@ -c dynconfig.c -o $@ + @$(CC) $(FLAGS) $(PATH_FLAGS) @PIE_CFLAGS@ -c $(srcdir)/dynconfig.c -o $@ dynconfig.@PICSUFFIX@: dynconfig.c Makefile @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi @echo Compiling $*.c with @PICFLAGS@ - @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c dynconfig.c -o $@ + @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c $(srcdir)/dynconfig.c -o $@ @BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@ lib/version.o: lib/version.c include/version.h @echo Compiling $*.c - @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PIE_CFLAGS@ -c lib/version.c -o $@ + @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PIE_CFLAGS@ -c $(srcdir)/lib/version.c -o $@ lib/version.@PICSUFFIX@: lib/version.c include/version.h @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \ dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi @echo Compiling $*.c with @PICFLAGS@ - @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c lib/version.c -o $@ + @$(CC) -I. -I$(srcdir) $(FLAGS) $(PATH_FLAGS) @PICFLAGS@ -c $(srcdir)/lib/version.c -o $@ @BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.@PICSUFFIX@$$%.o%'` $@ smbd/build_options.o: smbd/build_options.c Makefile include/config.h include/build_env.h include/proto.h @@ -972,6 +977,10 @@ bin/smbcquotas@EXEEXT@: $(SMBCQUOTAS_OBJ) @BUILD_POPT@ bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) +bin/eventlogadm@EXEEXT@: $(WR_EVENTLOG_OBJ) @BUILD_POPT@ bin/.dummy + @echo Linking $@ + @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(WR_EVENTLOG_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ + bin/locktest@EXEEXT@: $(LOCKTEST_OBJ) bin/.dummy @echo Linking $@ @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) diff --git a/source/client/client.c b/source/client/client.c index 61c4c8e4beb..e2b34869907 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -514,6 +514,14 @@ static int do_list_queue_empty(void) static void do_list_helper(const char *mntpoint, file_info *f, const char *mask, void *state) { + char *dir_end; + + /* save the directory */ + pstrcpy( f->dir, mask ); + if ( (dir_end = strrchr( f->dir, '\\' )) != NULL ) { + *dir_end = '\0'; + } + if (f->mode & aDIR) { if (do_list_dirs && do_this_one(f)) { do_list_fn(f); @@ -1613,8 +1621,7 @@ static void do_del(file_info *finfo) { pstring mask; - pstrcpy(mask,cur_dir); - pstrcat(mask,finfo->name); + pstr_sprintf( mask, "%s\\%s", finfo->dir, finfo->name ); if (finfo->mode & aDIR) return; diff --git a/source/configure.in b/source/configure.in index deeab5886fe..1aaf65e13ff 100644 --- a/source/configure.in +++ b/source/configure.in @@ -2820,6 +2820,7 @@ if test x"$with_ldap_support" != x"no"; then if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available]) + CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED" default_static_modules="$default_static_modules pdb_ldap idmap_ldap"; default_shared_modules="$default_shared_modules"; SMBLDAP="lib/smbldap.o" @@ -3717,6 +3718,10 @@ case "$host_os" in AC_MSG_CHECKING(whether to use the lib/sysquotas_xfs.c builtin support) AC_MSG_RESULT(yes) ;; + *solaris*) + # need to set this define when using static linking (BUG 1473) + CPPFLAGS="$CPPFLAGS -DSUNOS5" + ;; *) ;; esac @@ -3896,7 +3901,7 @@ fi AC_CACHE_CHECK([whether the old quota support works],samba_cv_QUOTA_WORKS,[ SAVE_CPPFLAGS="$CPPFLAGS" -CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/nsswitch" +CPPFLAGS="$CPPFLAGS -I${srcdir-.}/ -I. -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/popt -I${srcdir-.}/nsswitch -I${srcdir-.}/smbwrapper" AC_TRY_COMPILE([ #include "confdefs.h" #define NO_PROTO_H 1 diff --git a/source/include/client.h b/source/include/client.h index df52e227f0c..30e0fae8744 100644 --- a/source/include/client.h +++ b/source/include/client.h @@ -44,6 +44,7 @@ typedef struct file_info time_t atime; time_t ctime; pstring name; + pstring dir; char short_name[13*3]; /* the *3 is to cope with multi-byte */ } file_info; diff --git a/source/include/doserr.h b/source/include/doserr.h index 593d5d99eef..60c450c819d 100644 --- a/source/include/doserr.h +++ b/source/include/doserr.h @@ -196,7 +196,9 @@ #define WERR_REG_FILE_INVALID W_ERROR(1017) #define WERR_NO_SUCH_SERVICE W_ERROR(1060) #define WERR_INVALID_SERVICE_CONTROL W_ERROR(1052) +#define WERR_MACHINE_LOCKED W_ERROR(1271) #define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338) +#define WERR_EVENTLOG_FILE_CORRUPT W_ERROR(1500) #define WERR_SERVER_UNAVAILABLE W_ERROR(1722) #define WERR_INVALID_FORM_NAME W_ERROR(1902) #define WERR_INVALID_FORM_SIZE W_ERROR(1903) diff --git a/source/include/passdb.h b/source/include/passdb.h index e985ab582dc..4964ff37591 100644 --- a/source/include/passdb.h +++ b/source/include/passdb.h @@ -269,7 +269,7 @@ struct pdb_search { * this SAMBA will load. Increment this if *ANY* changes are made to the interface. */ -#define PASSDB_INTERFACE_VERSION 9 +#define PASSDB_INTERFACE_VERSION 10 typedef struct pdb_context { @@ -294,6 +294,8 @@ typedef struct pdb_context NTSTATUS (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass); NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username); + + NTSTATUS (*pdb_rename_sam_account)(struct pdb_context *, SAM_ACCOUNT *oldname, const char *newname); NTSTATUS (*pdb_update_login_attempts)(struct pdb_context *context, SAM_ACCOUNT *sam_acct, BOOL success); @@ -422,6 +424,8 @@ typedef struct pdb_methods NTSTATUS (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username); + NTSTATUS (*rename_sam_account)(struct pdb_methods *, SAM_ACCOUNT *oldname, const char *newname); + NTSTATUS (*update_login_attempts)(struct pdb_methods *methods, SAM_ACCOUNT *sam_acct, BOOL success); NTSTATUS (*getgrsid)(struct pdb_methods *methods, GROUP_MAP *map, DOM_SID sid); diff --git a/source/include/rpc_buffer.h b/source/include/rpc_buffer.h deleted file mode 100644 index da2be8a4df6..00000000000 --- a/source/include/rpc_buffer.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - Unix SMB/Netbios implementation. - - Copyright (C) Andrew Tridgell 1992-2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean Francois Micouleau 1998-2000. - Copyright (C) Gerald Carter 2001-2005. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _RPC_BUFFER_H /* _RPC_SPOOLSS_H */ -#define _RPC_BUFFER_H - -typedef struct { - uint32 size; - prs_struct prs; - uint32 struct_start; - uint32 string_at_end; -} RPC_BUFFER; - - -#endif /* _RPC_BUFFER_H */ diff --git a/source/include/rpc_creds.h b/source/include/rpc_creds.h deleted file mode 100644 index 3022b172899..00000000000 --- a/source/include/rpc_creds.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1999 - Copyright (C) Luke Kenneth Casson Leighton 1996-1999 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -#ifndef _RPC_CREDS_H /* _RPC_CREDS_H */ -#define _RPC_CREDS_H - -typedef struct ntuser_creds -{ - fstring user_name; - fstring domain; - struct pwd_info pwd; - - uint32 ntlmssp_flags; - -} CREDS_NT; - -typedef struct unixuser_creds -{ - fstring user_name; - fstring requested_name; - fstring real_name; - BOOL guest; - -} CREDS_UNIX; - -typedef struct unixsec_creds -{ - uint32 uid; - uint32 gid; - int num_grps; - uint32 *grps; - -} CREDS_UNIX_SEC; - -typedef struct ntsec_creds -{ - DOM_SID sid; - uint32 num_grps; - uint32 *grp_rids; - -} CREDS_NT_SEC; - -typedef struct user_creds -{ - BOOL reuse; - - uint32 ptr_ntc; - uint32 ptr_uxc; - uint32 ptr_nts; - uint32 ptr_uxs; - uint32 ptr_ssk; - - CREDS_NT ntc; - CREDS_UNIX uxc; - - CREDS_NT_SEC nts; - CREDS_UNIX_SEC uxs; - - uchar usr_sess_key[16]; - -} CREDS_HYBRID; - -typedef struct cred_command -{ - uint16 version; - uint16 command; - uint32 pid; /* unique process id */ - - fstring name; - - uint32 ptr_creds; - CREDS_HYBRID *cred; - -} CREDS_CMD; - -#endif /* _RPC_CREDS_H */ - diff --git a/source/include/rpc_eventlog.h b/source/include/rpc_eventlog.h index 9f968fb54e1..c94b2fa8796 100644 --- a/source/include/rpc_eventlog.h +++ b/source/include/rpc_eventlog.h @@ -47,11 +47,15 @@ #define EVENTLOG_AUDIT_FAILURE 0x0010 /* Defines for TDB keys */ -#define VN_oldest_entry "INFO/oldest_entry" -#define VN_next_record "INFO/next_record" -#define VN_version "INFO/version" -#define VN_maxsize "INFO/maxsize" -#define VN_retention "INFO/retention" +#define EVT_OLDEST_ENTRY "INFO/oldest_entry" +#define EVT_NEXT_RECORD "INFO/next_record" +#define EVT_VERSION "INFO/version" +#define EVT_MAXSIZE "INFO/maxsize" +#define EVT_RETENTION "INFO/retention" + +#define ELOG_APPL "Application" +#define ELOG_SYS "System" +#define ELOG_SEC "Security" #define EVENTLOG_DATABASE_VERSION_V1 1 diff --git a/source/include/rpc_parse.h b/source/include/rpc_parse.h deleted file mode 100644 index 73fbcb2b1be..00000000000 --- a/source/include/rpc_parse.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Elrond 2000 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _RPC_PARSE_H -#define _RPC_PARSE_H - -/* different dce/rpc pipes */ -#include "rpc_reg.h" -#include "rpc_brs.h" - -#endif /* _RPC_PARSE_H */ diff --git a/source/include/secrets.h b/source/include/secrets.h index 4b8d5db66b6..f2d1afd96b3 100644 --- a/source/include/secrets.h +++ b/source/include/secrets.h @@ -98,4 +98,6 @@ struct afs_keyfile { #define SECRETS_AFS_KEYFILE "SECRETS/AFS_KEYFILE" +#define SECRETS_SCHANNEL_STATE "SECRETS/SCHANNEL" + #endif /* _SECRETS_H */ diff --git a/source/include/smb.h b/source/include/smb.h index 61d2237b2dd..e3d151f9ed4 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -27,6 +27,10 @@ #ifndef _SMB_H #define _SMB_H +/* logged when starting the various Samba daemons */ +#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2005" + + #if defined(LARGE_SMB_OFF_T) #define BUFFER_SIZE (128*1024) #else /* no large readwrite possible */ @@ -1719,4 +1723,7 @@ typedef struct uuid_flat { uint8 info[UUID_FLAT_SIZE]; } UUID_FLAT; +/* map readonly options */ +enum mapreadonly_options {MAP_READONLY_NO, MAP_READONLY_YES, MAP_READONLY_PERMISSIONS}; + #endif /* _SMB_H */ diff --git a/source/lib/afs.c b/source/lib/afs.c index b8173f7cc1e..8a304adcf0c 100644 --- a/source/lib/afs.c +++ b/source/lib/afs.c @@ -22,6 +22,8 @@ #ifdef WITH_FAKE_KASERVER +#define NO_ASN1_TYPEDEFS 1 + #include <afs/stds.h> #include <afs/afs.h> #include <afs/auth.h> diff --git a/source/lib/afs_settoken.c b/source/lib/afs_settoken.c index 2e74328d5d6..46802e78cba 100644 --- a/source/lib/afs_settoken.c +++ b/source/lib/afs_settoken.c @@ -22,6 +22,8 @@ #ifdef WITH_FAKE_KASERVER +#define NO_ASN1_TYPEDEFS 1 + #include <afs/stds.h> #include <afs/afs.h> #include <afs/auth.h> diff --git a/source/lib/sysquotas_linux.c b/source/lib/sysquotas_linux.c index 28a86196e2b..761562b402e 100644 --- a/source/lib/sysquotas_linux.c +++ b/source/lib/sysquotas_linux.c @@ -394,6 +394,7 @@ static int sys_set_linux_gen_quota(const char *path, const char *bdev, enum SMB_ D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize; D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize; } + D.dqb_valid = QIF_LIMITS; qflags = dp->qflags; diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c index 6a5c6b6a491..f21577d0802 100644 --- a/source/libads/kerberos_verify.c +++ b/source/libads/kerberos_verify.c @@ -272,6 +272,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, DATA_BLOB *session_key) { NTSTATUS sret = NT_STATUS_LOGON_FAILURE; + NTSTATUS pac_ret; DATA_BLOB auth_data; krb5_context context = NULL; krb5_auth_context auth_context = NULL; @@ -400,7 +401,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, #endif /* continue when no PAC is retrieved - (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set) */ + (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, + or Kerberos tickets encryped using a DES key) - Guenther */ got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt); if (!got_auth_data) { @@ -409,10 +411,10 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, if (got_auth_data && pac_data != NULL) { - sret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data); - if (!NT_STATUS_IS_OK(sret)) { - DEBUG(0,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(sret))); - goto out; + pac_ret = decode_pac_data(mem_ctx, &auth_data, context, keyblock, client_principal, authtime, pac_data); + if (!NT_STATUS_IS_OK(pac_ret)) { + DEBUG(3,("ads_verify_ticket: failed to decode PAC_DATA: %s\n", nt_errstr(pac_ret))); + *pac_data = NULL; } data_blob_free(&auth_data); } diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index df5ad867da8..e87ec32197c 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -689,6 +689,12 @@ failed: &input, cksum, &checksum_valid); + if (ret) { + DEBUG(3,("smb_krb5_verify_checksum: krb5_c_verify_checksum() failed: %s\n", + error_message(ret))); + return ret; + } + if (!checksum_valid) ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; } diff --git a/source/libsmb/doserr.c b/source/libsmb/doserr.c index ef71a883f7f..dd0358f69a5 100644 --- a/source/libsmb/doserr.c +++ b/source/libsmb/doserr.c @@ -66,6 +66,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, + { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c index 1e729abb221..9c7376da449 100644 --- a/source/libsmb/libsmbclient.c +++ b/source/libsmb/libsmbclient.c @@ -5539,6 +5539,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) if (!smbc_initialized) { /* Do some library wide intialisations the first time we get called */ + BOOL conf_loaded = False; /* Set this to what the user wants */ DEBUGLEVEL = context->debug; @@ -5547,16 +5548,22 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) /* Here we would open the smb.conf file if needed ... */ - home = getenv("HOME"); - - slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - load_interfaces(); /* Load the list of interfaces ... */ in_client = True; /* FIXME, make a param */ - if (!lp_load(conf, True, False, False)) { - + home = getenv("HOME"); + if (home) { + slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); + if (lp_load(conf, True, False, False)) { + conf_loaded = True; + } else { + DEBUG(5, ("Could not load config file: %s\n", + conf)); + } + } + + if (!conf_loaded) { /* * Well, if that failed, try the dyn_CONFIGFILE * Which points to the standard locn, and if that @@ -5565,10 +5572,9 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) */ if (!lp_load(dyn_CONFIGFILE, True, False, False)) { - DEBUG(5, ("Could not load either config file: " - "%s or %s\n", - conf, dyn_CONFIGFILE)); - } else { + DEBUG(5, ("Could not load config file: %s\n", + dyn_CONFIGFILE)); + } else if (home) { /* * We loaded the global config file. Now lets * load user-specific modifications to the diff --git a/source/libsmb/ntlmssp.c b/source/libsmb/ntlmssp.c index 6b551e8774c..0becc7fdee3 100644 --- a/source/libsmb/ntlmssp.c +++ b/source/libsmb/ntlmssp.c @@ -419,7 +419,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, fstring dnsname, dnsdomname; uint32 neg_flags = 0; uint32 ntlmssp_command, chal_flags; - char *cliname=NULL, *domname=NULL; const uint8 *cryptkey; const char *target_name; @@ -429,23 +428,15 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, #endif if (request.length) { - if (!msrpc_parse(&request, "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname)) { - DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate:\n")); + if ((request.length < 16) || !msrpc_parse(&request, "Cdd", + "NTLMSSP", + &ntlmssp_command, + &neg_flags)) { + DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n", + (unsigned int)request.length)); dump_data(2, (const char *)request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } - - DEBUG(10, ("ntlmssp_server_negotiate: client = %s, domain = %s\n", - cliname ? cliname : "", domname ? domname : "")); - - SAFE_FREE(cliname); - SAFE_FREE(domname); - debug_ntlmssp_flags(neg_flags); } diff --git a/source/modules/developer.c b/source/modules/developer.c new file mode 100644 index 00000000000..7ffc3ff50d2 --- /dev/null +++ b/source/modules/developer.c @@ -0,0 +1,132 @@ +/* + Unix SMB/CIFS implementation. + Samba module with developer tools + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jelmer Vernooij 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +static struct { + char from; + char *to; + int len; +} weird_table[] = { + {'q', "^q^", 3}, + {'Q', "^Q^", 3}, + {0, NULL} +}; + +static size_t weird_pull(void *cd, char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + while (*inbytesleft >= 1 && *outbytesleft >= 2) { + int i; + int done = 0; + for (i=0;weird_table[i].from;i++) { + if (strncmp((*inbuf), + weird_table[i].to, + weird_table[i].len) == 0) { + if (*inbytesleft < weird_table[i].len) { + DEBUG(0,("ERROR: truncated weird string\n")); + /* smb_panic("weird_pull"); */ + + } else { + (*outbuf)[0] = weird_table[i].from; + (*outbuf)[1] = 0; + (*inbytesleft) -= weird_table[i].len; + (*outbytesleft) -= 2; + (*inbuf) += weird_table[i].len; + (*outbuf) += 2; + done = 1; + break; + } + } + } + if (done) continue; + (*outbuf)[0] = (*inbuf)[0]; + (*outbuf)[1] = 0; + (*inbytesleft) -= 1; + (*outbytesleft) -= 2; + (*inbuf) += 1; + (*outbuf) += 2; + } + + if (*inbytesleft > 0) { + errno = E2BIG; + return -1; + } + + return 0; +} + +static size_t weird_push(void *cd, char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + int ir_count=0; + + while (*inbytesleft >= 2 && *outbytesleft >= 1) { + int i; + int done=0; + for (i=0;weird_table[i].from;i++) { + if ((*inbuf)[0] == weird_table[i].from && + (*inbuf)[1] == 0) { + if (*outbytesleft < weird_table[i].len) { + DEBUG(0,("No room for weird character\n")); + /* smb_panic("weird_push"); */ + } else { + memcpy(*outbuf, weird_table[i].to, + weird_table[i].len); + (*inbytesleft) -= 2; + (*outbytesleft) -= weird_table[i].len; + (*inbuf) += 2; + (*outbuf) += weird_table[i].len; + done = 1; + break; + } + } + } + if (done) continue; + + (*outbuf)[0] = (*inbuf)[0]; + if ((*inbuf)[1]) ir_count++; + (*inbytesleft) -= 2; + (*outbytesleft) -= 1; + (*inbuf) += 2; + (*outbuf) += 1; + } + + if (*inbytesleft == 1) { + errno = EINVAL; + return -1; + } + + if (*inbytesleft > 1) { + errno = E2BIG; + return -1; + } + + return ir_count; +} + +struct charset_functions weird_functions = {"WEIRD", weird_pull, weird_push}; + +int charset_weird_init(void) +{ + smb_register_charset(&weird_functions); + return True; +} diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c index fcaba03b3db..086878e221a 100644 --- a/source/nmbd/nmbd.c +++ b/source/nmbd/nmbd.c @@ -720,7 +720,7 @@ static BOOL open_sockets(BOOL isdaemon, int port) reopen_logs(); DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) ); - DEBUGADD( 0, ( "Copyright Andrew Tridgell and the Samba Team 1994-2004\n" ) ); + DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) ); if ( !reload_nmbd_services(False) ) return(-1); diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 126d70939c0..383b1d70478 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -151,6 +151,7 @@ typedef struct char *szNameResolveOrder; char *szPanicAction; char *szAddUserScript; + char *szRenameUserScript; char *szDelUserScript; char *szAddGroupScript; char *szDelGroupScript; @@ -438,6 +439,7 @@ typedef struct int iallocation_roundup_size; int iAioReadSize; int iAioWriteSize; + int iMap_readonly; param_opt_struct *param_opt; char dummy[3]; /* for alignment */ @@ -571,6 +573,7 @@ static service sDefault = { SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */ 0, /* iAioReadSize */ 0, /* iAioWriteSize */ + MAP_READONLY_YES, /* iMap_readonly */ NULL, /* Parametric options */ @@ -691,6 +694,18 @@ static const struct enum_list enum_announce_as[] = { {-1, NULL} }; +static const struct enum_list enum_map_readonly[] = { + {MAP_READONLY_NO, "no"}, + {MAP_READONLY_NO, "false"}, + {MAP_READONLY_NO, "0"}, + {MAP_READONLY_YES, "yes"}, + {MAP_READONLY_YES, "true"}, + {MAP_READONLY_YES, "1"}, + {MAP_READONLY_PERMISSIONS, "permissions"}, + {MAP_READONLY_PERMISSIONS, "perms"}, + {-1, NULL} +}; + static const struct enum_list enum_case[] = { {CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, @@ -1045,9 +1060,11 @@ static struct parm_struct parm_table[] = { {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, - {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, - {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, + {"map read only", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED }, {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED}, @@ -1061,6 +1078,7 @@ static struct parm_struct parm_table[] = { {N_("Logon Options"), P_SEP, P_SEPARATOR}, {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED}, + {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED}, {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED}, {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED}, {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED}, @@ -1734,6 +1752,7 @@ FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend) FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules) FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction) FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript) +FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript) FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript) FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount) @@ -1992,6 +2011,7 @@ FN_LOCAL_INTEGER(lp_block_size, iBlock_size) FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size) FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize) FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize) +FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly) FN_LOCAL_CHAR(lp_magicchar, magic_char) FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time) FN_GLOBAL_INTEGER(lp_winbind_max_idle_children, &Globals.winbind_max_idle_children) diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c index a9e41984c3d..485f4055682 100644 --- a/source/passdb/pdb_interface.c +++ b/source/passdb/pdb_interface.c @@ -325,6 +325,41 @@ static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCO return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct); } +static NTSTATUS context_rename_sam_account(struct pdb_context *context, SAM_ACCOUNT *oldname, const char *newname) +{ + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + + struct pdb_methods *pdb_selected; + if (!context) { + DEBUG(0, ("invalid pdb_context specified!\n")); + return ret; + } + + if (!oldname->methods){ + pdb_selected = context->pdb_methods; + /* There's no passdb backend specified for this account. + * Try to delete it in every passdb available + * Needed to delete accounts in smbpasswd that are not + * in /etc/passwd. + */ + while (pdb_selected){ + if (NT_STATUS_IS_OK(ret = pdb_selected->rename_sam_account(pdb_selected, oldname, newname))) { + return ret; + } + pdb_selected = pdb_selected->next; + } + return ret; + } + + if (!oldname->methods->rename_sam_account){ + DEBUG(0,("invalid oldname->methods->rename_sam_account\n")); + return ret; + } + + return oldname->methods->rename_sam_account(oldname->methods, oldname, newname); +} + + static NTSTATUS context_update_login_attempts(struct pdb_context *context, SAM_ACCOUNT *sam_acct, BOOL success) { @@ -850,6 +885,7 @@ static NTSTATUS make_pdb_context(struct pdb_context **context) (*context)->pdb_add_sam_account = context_add_sam_account; (*context)->pdb_update_sam_account = context_update_sam_account; (*context)->pdb_delete_sam_account = context_delete_sam_account; + (*context)->pdb_rename_sam_account = context_rename_sam_account; (*context)->pdb_update_login_attempts = context_update_login_attempts; (*context)->pdb_getgrsid = context_getgrsid; (*context)->pdb_getgrgid = context_getgrgid; @@ -1103,6 +1139,22 @@ BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct) return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct)); } +NTSTATUS pdb_rename_sam_account(SAM_ACCOUNT *oldname, const char *newname) +{ + struct pdb_context *pdb_context = pdb_get_static_context(False); + + if (!pdb_context) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + if (sam_account_cache != NULL) { + pdb_free_sam(&sam_account_cache); + sam_account_cache = NULL; + } + + return pdb_context->pdb_rename_sam_account(pdb_context, oldname, newname); +} + NTSTATUS pdb_update_login_attempts(SAM_ACCOUNT *sam_acct, BOOL success) { struct pdb_context *pdb_context = pdb_get_static_context(False); @@ -1440,6 +1492,11 @@ static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM return NT_STATUS_NOT_IMPLEMENTED; } +static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd, const char *newname) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, SAM_ACCOUNT *newpwd, BOOL success) { return NT_STATUS_OK; @@ -1983,6 +2040,7 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) (*methods)->add_sam_account = pdb_default_add_sam_account; (*methods)->update_sam_account = pdb_default_update_sam_account; (*methods)->delete_sam_account = pdb_default_delete_sam_account; + (*methods)->rename_sam_account = pdb_default_rename_sam_account; (*methods)->update_login_attempts = pdb_default_update_login_attempts; (*methods)->getgrsid = pdb_default_getgrsid; diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c index 755e33940b8..f04c82a5b15 100644 --- a/source/passdb/pdb_tdb.c +++ b/source/passdb/pdb_tdb.c @@ -6,6 +6,7 @@ * Copyright (C) Gerald Carter 2000 * Copyright (C) Jeremy Allison 2001 * Copyright (C) Andrew Bartlett 2002 + * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005 * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free @@ -515,6 +516,32 @@ static NTSTATUS tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * return tdbsam_getsampwrid(my_methods, user, rid); } +static BOOL tdb_delete_samacct_only(TDB_CONTEXT *pwd_tdb, + struct pdb_methods *my_methods, + SAM_ACCOUNT *sam_pass) +{ + TDB_DATA key; + fstring keystr; + fstring name; + + fstrcpy(name, pdb_get_username(sam_pass)); + strlower_m(name); + + /* set the search key */ + slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name); + key.dptr = keystr; + key.dsize = strlen (keystr) + 1; + + /* it's outaa here! 8^) */ + if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) { + DEBUG(5, ("Error deleting entry from tdb passwd database!\n")); + DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb))); + tdb_close(pwd_tdb); + return False; + } + return True; +} + /*************************************************************************** Delete a SAM_ACCOUNT ****************************************************************************/ @@ -573,50 +600,19 @@ static NTSTATUS tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_AC return NT_STATUS_OK; } + /*************************************************************************** - Update the TDB SAM + Update the TDB SAM account record only ****************************************************************************/ - -static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag) +static BOOL tdb_update_samacct_only(TDB_CONTEXT *pwd_tdb, + struct pdb_methods *my_methods, + SAM_ACCOUNT* newpwd, int flag) { - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - TDB_CONTEXT *pwd_tdb = NULL; TDB_DATA key, data; uint8 *buf = NULL; fstring keystr; fstring name; BOOL ret = True; - uint32 user_rid; - - /* invalidate the existing TDB iterator if it is open */ - - if (tdb_state->passwd_tdb) { - tdb_close(tdb_state->passwd_tdb); - tdb_state->passwd_tdb = NULL; - } - - /* open the account TDB passwd*/ - - pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT); - - if (!pwd_tdb) { - DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", - tdb_state->tdbsam_location)); - return False; - } - - if (!pdb_get_group_rid(newpwd)) { - DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n", - pdb_get_username(newpwd))); - ret = False; - goto done; - } - - if ( !(user_rid = pdb_get_user_rid(newpwd)) ) { - DEBUG(0,("tdb_update_sam: SAM_ACCOUNT (%s) with no RID!\n", pdb_get_username(newpwd))); - ret = False; - goto done; - } /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */ if ((data.dsize=init_buffer_from_sam (&buf, newpwd, False)) == -1) { @@ -629,7 +625,9 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, fstrcpy(name, pdb_get_username(newpwd)); strlower_m(name); - DEBUG(5, ("Storing %saccount %s with RID %d\n", flag == TDB_INSERT ? "(new) " : "", name, user_rid)); + DEBUG(5, ("Storing %saccount %s with RID %d\n", + flag == TDB_INSERT ? "(new) " : "", name, + pdb_get_user_rid(newpwd))); /* setup the USER index key */ slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name); @@ -640,17 +638,40 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) { DEBUG(0, ("Unable to modify passwd TDB!")); DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb))); - DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr)); + DEBUGADD(0, (" occured while storing the main record (%s)\n", + keystr)); ret = False; goto done; } + +done: + /* cleanup */ + SAFE_FREE(buf); + return (ret); +} + +/*************************************************************************** + Update the TDB SAM RID record only +****************************************************************************/ +static BOOL tdb_update_ridrec_only(TDB_CONTEXT *pwd_tdb, + struct pdb_methods *my_methods, + SAM_ACCOUNT* newpwd, int flag) +{ + TDB_DATA key, data; + fstring keystr; + fstring name; + + fstrcpy(name, pdb_get_username(newpwd)); + strlower_m(name); + /* setup RID data */ data.dsize = strlen(name) + 1; data.dptr = name; /* setup the RID index key */ - slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, user_rid); + slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, + pdb_get_user_rid(newpwd)); key.dptr = keystr; key.dsize = strlen (keystr) + 1; @@ -659,6 +680,56 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, DEBUG(0, ("Unable to modify TDB passwd !")); DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb))); DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr)); + return False; + } + + return True; + +} + +/*************************************************************************** + Update the TDB SAM +****************************************************************************/ + +static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag) +{ + struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; + TDB_CONTEXT *pwd_tdb = NULL; + BOOL ret = True; + uint32 user_rid; + + /* invalidate the existing TDB iterator if it is open */ + + if (tdb_state->passwd_tdb) { + tdb_close(tdb_state->passwd_tdb); + tdb_state->passwd_tdb = NULL; + } + + /* open the account TDB passwd*/ + + pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT); + + if (!pwd_tdb) { + DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", + tdb_state->tdbsam_location)); + return False; + } + + if (!pdb_get_group_rid(newpwd)) { + DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n", + pdb_get_username(newpwd))); + ret = False; + goto done; + } + + if ( !(user_rid = pdb_get_user_rid(newpwd)) ) { + DEBUG(0,("tdb_update_sam: SAM_ACCOUNT (%s) with no RID!\n", pdb_get_username(newpwd))); + ret = False; + goto done; + } + + if (!tdb_update_samacct_only(pwd_tdb, my_methods, newpwd, flag) || + !tdb_update_ridrec_only(pwd_tdb, my_methods, newpwd, flag)) { ret = False; goto done; } @@ -666,7 +737,6 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, done: /* cleanup */ tdb_close (pwd_tdb); - SAFE_FREE(buf); return (ret); } @@ -695,6 +765,103 @@ static NTSTATUS tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCO return NT_STATUS_UNSUCCESSFUL; } +/*************************************************************************** + Renames a SAM_ACCOUNT + - check for the posix user/rename user script + - Add and lock the new user record + - rename the posix user + - rewrite the rid->username record + - delete the old user + - unlock the new user record +***************************************************************************/ +static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods, + SAM_ACCOUNT *oldname, const char *newname) +{ + struct tdbsam_privates *tdb_state = + (struct tdbsam_privates *)my_methods->private_data; + SAM_ACCOUNT *new_acct = NULL; + pstring rename_script; + TDB_CONTEXT *pwd_tdb = NULL; + NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; + BOOL interim_account = False; + + if (!*(lp_renameuser_script())) + goto done; + + if (!pdb_copy_sam_account(oldname, &new_acct) || + !pdb_set_username(new_acct, newname, PDB_CHANGED)) + goto done; + + /* invalidate the existing TDB iterator if it is open */ + + if (tdb_state->passwd_tdb) { + tdb_close(tdb_state->passwd_tdb); + tdb_state->passwd_tdb = NULL; + } + + /* open the account TDB passwd */ + + pwd_tdb = tdbsam_tdbopen(tdb_state->tdbsam_location, O_RDWR | O_CREAT); + + if (!pwd_tdb) { + DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", + tdb_state->tdbsam_location)); + goto done; + } + + /* add the new account and lock it */ + if (!tdb_update_samacct_only(pwd_tdb, my_methods, new_acct, + TDB_INSERT)) + goto done; + interim_account = True; + + if (tdb_lock_bystring(pwd_tdb, newname, 30) == -1) { + goto done; + } + + /* rename the posix user */ + pstrcpy(rename_script, lp_renameuser_script()); + + if (*rename_script) { + int rename_ret; + + pstring_sub(rename_script, "%unew", newname); + pstring_sub(rename_script, "%uold", pdb_get_username(oldname)); + rename_ret = smbrun(rename_script, NULL); + + DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret)); + + if (rename_ret) + goto done; + } else { + goto done; + } + + /* rewrite the rid->username record */ + if (!tdb_update_ridrec_only(pwd_tdb, my_methods, new_acct, TDB_MODIFY)) + goto done; + interim_account = False; + tdb_unlock_bystring(pwd_tdb, newname); + + tdb_delete_samacct_only(pwd_tdb, my_methods, oldname); + + ret = NT_STATUS_OK; + + +done: + /* cleanup */ + if (interim_account) { + tdb_unlock_bystring(pwd_tdb, newname); + tdb_delete_samacct_only(pwd_tdb, my_methods, new_acct); + } + if (pwd_tdb) + tdb_close (pwd_tdb); + if (new_acct) + pdb_free_sam(&new_acct); + + return (ret); +} + static void free_private_data(void **vp) { struct tdbsam_privates **tdb_state = (struct tdbsam_privates **)vp; @@ -736,6 +903,7 @@ static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_meth (*pdb_method)->add_sam_account = tdbsam_add_sam_account; (*pdb_method)->update_sam_account = tdbsam_update_sam_account; (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account; + (*pdb_method)->rename_sam_account = tdbsam_rename_sam_account; tdb_state = TALLOC_ZERO_P(pdb_context->mem_ctx, struct tdbsam_privates); diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c index 743bdd19423..35ccb2c725b 100644 --- a/source/passdb/secrets.c +++ b/source/passdb/secrets.c @@ -942,3 +942,212 @@ void secrets_fetch_ipc_userpass(char **username, char **domain, char **password) } } +/****************************************************************************** + Open or create the schannel session store tdb. +*******************************************************************************/ + +static TDB_CONTEXT *open_schannel_session_store(TALLOC_CTX *mem_ctx) +{ + TDB_DATA vers; + uint32 ver; + TDB_CONTEXT *tdb_sc = NULL; + char *fname = talloc_asprintf(mem_ctx, "%s/schannel_store.tdb", lp_private_dir()); + + if (!fname) { + return NULL; + } + + tdb_sc = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + + if (!tdb_sc) { + DEBUG(0,("open_schannel_session_store: Failed to open %s\n", fname)); + talloc_free(fname); + return NULL; + } + + vers = tdb_fetch_bystring(tdb_sc, "SCHANNEL_STORE_VERSION"); + if (vers.dptr == NULL) { + /* First opener, no version. */ + SIVAL(&ver,0,1); + vers.dptr = (char *)&ver; + vers.dsize = 4; + tdb_store_bystring(tdb_sc, "SCHANNEL_STORE_VERSION", vers, TDB_REPLACE); + vers.dptr = NULL; + } else if (vers.dsize == 4) { + ver = IVAL(vers.dptr,0); + if (ver != 1) { + tdb_close(tdb_sc); + tdb_sc = NULL; + DEBUG(0,("open_schannel_session_store: wrong version number %d in %s\n", + (int)ver, fname )); + } + } else { + tdb_close(tdb_sc); + tdb_sc = NULL; + DEBUG(0,("open_schannel_session_store: wrong version number size %d in %s\n", + (int)vers.dsize, fname )); + } + + SAFE_FREE(vers.dptr); + talloc_free(fname); + + return tdb_sc; +} + +/****************************************************************************** + Store the schannel state after an AUTH2 call. + Note we must be root here. +*******************************************************************************/ + +BOOL secrets_store_schannel_session_info(TALLOC_CTX *mem_ctx, const struct dcinfo *pdc) +{ + TDB_CONTEXT *tdb_sc = NULL; + TDB_DATA value; + BOOL ret; + char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE, + pdc->remote_machine); + if (!keystr) { + return False; + } + + strupper_m(keystr); + + /* Work out how large the record is. */ + value.dsize = tdb_pack(NULL, 0, "dBBBBBfff", + pdc->sequence, + 8, pdc->seed_chal.data, + 8, pdc->clnt_chal.data, + 8, pdc->srv_chal.data, + 8, pdc->sess_key, + 16, pdc->mach_pw, + pdc->mach_acct, + pdc->remote_machine, + pdc->domain); + + value.dptr = TALLOC(mem_ctx, value.dsize); + if (!value.dptr) { + talloc_free(keystr); + return False; + } + + value.dsize = tdb_pack(value.dptr, value.dsize, "dBBBBBfff", + pdc->sequence, + 8, pdc->seed_chal.data, + 8, pdc->clnt_chal.data, + 8, pdc->srv_chal.data, + 8, pdc->sess_key, + 16, pdc->mach_pw, + pdc->mach_acct, + pdc->remote_machine, + pdc->domain); + + tdb_sc = open_schannel_session_store(mem_ctx); + if (!tdb_sc) { + talloc_free(keystr); + talloc_free(value.dptr); + return False; + } + + ret = (tdb_store_bystring(tdb_sc, keystr, value, TDB_REPLACE) == 0 ? True : False); + + DEBUG(3,("secrets_store_schannel_session_info: stored schannel info with key %s\n", + keystr )); + + tdb_close(tdb_sc); + talloc_free(keystr); + talloc_free(value.dptr); + return ret; +} + +/****************************************************************************** + Restore the schannel state on a client reconnect. + Note we must be root here. +*******************************************************************************/ + +BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx, + const char *remote_machine, + struct dcinfo *pdc) +{ + TDB_CONTEXT *tdb_sc = NULL; + TDB_DATA value; + unsigned char *pseed_chal = NULL; + unsigned char *pclnt_chal = NULL; + unsigned char *psrv_chal = NULL; + unsigned char *psess_key = NULL; + unsigned char *pmach_pw = NULL; + uint32 l1, l2, l3, l4, l5; + int ret; + char *keystr = talloc_asprintf(mem_ctx, "%s/%s", SECRETS_SCHANNEL_STATE, + remote_machine); + + ZERO_STRUCTP(pdc); + + if (!keystr) { + return False; + } + + strupper_m(keystr); + + tdb_sc = open_schannel_session_store(mem_ctx); + if (!tdb_sc) { + talloc_free(keystr); + return False; + } + + value = tdb_fetch_bystring(tdb_sc, keystr); + if (!value.dptr) { + DEBUG(0,("secrets_restore_schannel_session_info: Failed to find entry with key %s\n", + keystr )); + tdb_close(tdb_sc); + return False; + } + + tdb_close(tdb_sc); + + /* Retrieve the record. */ + ret = tdb_unpack(value.dptr, value.dsize, "dBBBBBfff", + &pdc->sequence, + &l1, &pseed_chal, + &l2, &pclnt_chal, + &l3, &psrv_chal, + &l4, &psess_key, + &l5, &pmach_pw, + &pdc->mach_acct, + &pdc->remote_machine, + &pdc->domain); + + if (ret == -1 || l1 != 8 || l2 != 8 || l3 != 8 || l4 != 8 || l5 != 16) { + talloc_free(keystr); + SAFE_FREE(pseed_chal); + SAFE_FREE(pclnt_chal); + SAFE_FREE(psrv_chal); + SAFE_FREE(psess_key); + SAFE_FREE(pmach_pw); + SAFE_FREE(value.dptr); + ZERO_STRUCTP(pdc); + return False; + } + + memcpy(pdc->seed_chal.data, pseed_chal, 8); + memcpy(pdc->clnt_chal.data, pclnt_chal, 8); + memcpy(pdc->srv_chal.data, psrv_chal, 8); + memcpy(pdc->sess_key, psess_key, 8); + memcpy(pdc->mach_pw, pmach_pw, 16); + + /* We know these are true so didn't bother to store them. */ + pdc->challenge_sent = True; + pdc->authenticated = True; + + DEBUG(3,("secrets_store_schannel_session_info: restored schannel info key %s\n", + keystr )); + + SAFE_FREE(pseed_chal); + SAFE_FREE(pclnt_chal); + SAFE_FREE(psrv_chal); + SAFE_FREE(psess_key); + SAFE_FREE(pmach_pw); + + talloc_free(keystr); + SAFE_FREE(value.dptr); + return True; +} diff --git a/source/python/py_common.h b/source/python/py_common.h index 2bbd148ff4b..5d1e7b246a4 100644 --- a/source/python/py_common.h +++ b/source/python/py_common.h @@ -32,13 +32,6 @@ #include "Python.h" -/* Return a cli_state struct opened on the specified pipe. If credentials - are passed use them. */ - -typedef struct cli_state *(cli_pipe_fn)( - struct cli_state *cli, char *system_name, - struct ntuser_creds *creds); - /* The following definitions come from python/py_common.c */ PyObject *py_werror_tuple(WERROR werror); diff --git a/source/python/py_lsa.c b/source/python/py_lsa.c index bf9d4661851..4f809520bc3 100644 --- a/source/python/py_lsa.c +++ b/source/python/py_lsa.c @@ -89,8 +89,8 @@ static PyObject *lsa_open_policy(PyObject *self, PyObject *args, goto done; } - ntstatus = cli_lsa_open_policy(cli, mem_ctx, True, - desired_access, &hnd); + ntstatus = rpccli_lsa_open_policy( + cli, mem_ctx, True, desired_access, &hnd); if (!NT_STATUS_IS_OK(ntstatus)) { PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus)); @@ -125,7 +125,7 @@ static PyObject *lsa_close(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - result = cli_lsa_close(hnd->cli, hnd->mem_ctx, &hnd->pol); + result = rpccli_lsa_close(hnd->cli, hnd->mem_ctx, &hnd->pol); /* Cleanup samba stuff */ @@ -185,8 +185,9 @@ static PyObject *lsa_lookup_names(PyObject *self, PyObject *args) names[0] = PyString_AsString(py_names); } - ntstatus = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, - num_names, names, &sids, &name_types); + ntstatus = rpccli_lsa_lookup_names( + hnd->cli, mem_ctx, &hnd->pol, num_names, names, &sids, + &name_types); if (!NT_STATUS_IS_OK(ntstatus) && NT_STATUS_V(ntstatus) != 0x107) { PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus)); @@ -267,9 +268,9 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args, } } - ntstatus = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol, - num_sids, sids, &domains, &names, - &types); + ntstatus = rpccli_lsa_lookup_sids( + hnd->cli, mem_ctx, &hnd->pol, num_sids, sids, &domains, + &names, &types); if (!NT_STATUS_IS_OK(ntstatus)) { PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus)); @@ -306,7 +307,7 @@ static PyObject *lsa_enum_trust_dom(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "")) return NULL; - ntstatus = cli_lsa_enum_trust_dom( + ntstatus = rpccli_lsa_enum_trust_dom( hnd->cli, hnd->mem_ctx, &hnd->pol, &enum_ctx, &num_domains, &domain_names, &domain_sids); diff --git a/source/python/py_samr.c b/source/python/py_samr.c index 77431e24475..fc9f2a83ebe 100644 --- a/source/python/py_samr.c +++ b/source/python/py_samr.c @@ -197,7 +197,7 @@ static PyObject *samr_set_user_info2(PyObject *self, PyObject *args, goto done; } - ntstatus = cli_samr_set_userinfo2( + ntstatus = rpccli_samr_set_userinfo2( user_hnd->cli, mem_ctx, &user_hnd->user_pol, level, sess_key, &ctr); @@ -233,7 +233,7 @@ static PyObject *samr_delete_dom_user(PyObject *self, PyObject *args, return NULL; } - ntstatus = cli_samr_delete_dom_user( + ntstatus = rpccli_samr_delete_dom_user( user_hnd->cli, mem_ctx, &user_hnd->user_pol); if (!NT_STATUS_IS_OK(ntstatus)) { @@ -344,7 +344,7 @@ static PyObject *samr_open_domain(PyObject *self, PyObject *args, PyObject *kw) return NULL; } - ntstatus = cli_samr_open_domain( + ntstatus = rpccli_samr_open_domain( connect_hnd->cli, mem_ctx, &connect_hnd->connect_pol, desired_access, &sid, &domain_pol); @@ -441,7 +441,7 @@ static PyObject *samr_enum_dom_groups(PyObject *self, PyObject *args, size = 0xffff; do { - result = cli_samr_enum_dom_groups( + result = rpccli_samr_enum_dom_groups( domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol, &start_idx, size, &dom_groups, &num_dom_groups); @@ -479,7 +479,7 @@ static PyObject *samr_create_dom_user(PyObject *self, PyObject *args, return NULL; } - ntstatus = cli_samr_create_dom_user( + ntstatus = rpccli_samr_create_dom_user( domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol, account_name, acb_info, unknown, &user_pol, &user_rid); @@ -569,7 +569,7 @@ static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw) goto done; } - ntstatus = cli_samr_connect(cli, mem_ctx, desired_access, &hnd); + ntstatus = rpccli_samr_connect(cli, mem_ctx, desired_access, &hnd); if (!NT_STATUS_IS_OK(ntstatus)) { cli_shutdown(cli); diff --git a/source/python/py_spoolss.h b/source/python/py_spoolss.h index ec94de8fe4f..0bb4aeab596 100644 --- a/source/python/py_spoolss.h +++ b/source/python/py_spoolss.h @@ -27,7 +27,7 @@ typedef struct { PyObject_HEAD - struct cli_state *cli; + struct rpc_pipe_client *cli; TALLOC_CTX *mem_ctx; POLICY_HND pol; } spoolss_policy_hnd_object; diff --git a/source/python/py_spoolss_drivers.c b/source/python/py_spoolss_drivers.c index abc9a4ba9cb..3d7ca3a8fc7 100644 --- a/source/python/py_spoolss_drivers.c +++ b/source/python/py_spoolss_drivers.c @@ -69,7 +69,7 @@ PyObject *spoolss_enumprinterdrivers(PyObject *self, PyObject *args, goto done; } - werror = cli_spoolss_enumprinterdrivers( + werror = rpccli_spoolss_enumprinterdrivers( cli, mem_ctx, level, arch, &num_drivers, &ctr); @@ -182,8 +182,8 @@ PyObject *spoolss_hnd_getprinterdriver(PyObject *self, PyObject *args, /* Call rpc function */ - werror = cli_spoolss_getprinterdriver(hnd->cli, hnd->mem_ctx, &hnd->pol, level, - arch, version, &ctr); + werror = rpccli_spoolss_getprinterdriver( + hnd->cli, hnd->mem_ctx, &hnd->pol, level, arch, version, &ctr); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); @@ -262,7 +262,8 @@ PyObject *spoolss_getprinterdriverdir(PyObject *self, PyObject *args, goto done; } - werror = cli_spoolss_getprinterdriverdir(cli, mem_ctx, level, arch, &ctr); + werror = rpccli_spoolss_getprinterdriverdir( + cli, mem_ctx, level, arch, &ctr); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); @@ -360,7 +361,7 @@ PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args, goto done; } - werror = cli_spoolss_addprinterdriver(cli, mem_ctx, level, &ctr); + werror = rpccli_spoolss_addprinterdriver(cli, mem_ctx, level, &ctr); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); diff --git a/source/python/py_spoolss_forms.c b/source/python/py_spoolss_forms.c index 00c5b18e18d..ce8492c7213 100644 --- a/source/python/py_spoolss_forms.c +++ b/source/python/py_spoolss_forms.c @@ -67,8 +67,8 @@ PyObject *spoolss_hnd_addform(PyObject *self, PyObject *args, PyObject *kw) return NULL; } - werror = cli_spoolss_addform(hnd->cli, hnd->mem_ctx, &hnd->pol, - level, &form); + werror = rpccli_spoolss_addform(hnd->cli, hnd->mem_ctx, &hnd->pol, + level, &form); if (!W_ERROR_IS_OK(werror)) { @@ -90,7 +90,6 @@ PyObject *spoolss_hnd_getform(PyObject *self, PyObject *args, PyObject *kw) char *form_name; int level = 1; static char *kwlist[] = {"form_name", "level", NULL}; - uint32 needed; FORM_1 form; /* Parse parameters */ @@ -101,8 +100,8 @@ PyObject *spoolss_hnd_getform(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_getform(hnd->cli, hnd->mem_ctx, - &hnd->pol, form_name, level, &form); + werror = rpccli_spoolss_getform( + hnd->cli, hnd->mem_ctx, &hnd->pol, form_name, level, &form); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); @@ -157,7 +156,7 @@ PyObject *spoolss_hnd_setform(PyObject *self, PyObject *args, PyObject *kw) form_name = PyDict_GetItemString(info, "name"); - werror = cli_spoolss_setform( + werror = rpccli_spoolss_setform( hnd->cli, hnd->mem_ctx, &hnd->pol, level, PyString_AsString(form_name), &form); @@ -187,7 +186,7 @@ PyObject *spoolss_hnd_deleteform(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_deleteform( + werror = rpccli_spoolss_deleteform( hnd->cli, hnd->mem_ctx, &hnd->pol, form_name); if (!W_ERROR_IS_OK(werror)) { @@ -218,9 +217,8 @@ PyObject *spoolss_hnd_enumforms(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_enumforms( - hnd->cli, hnd->mem_ctx, &hnd->pol, level, - &num_forms, &forms); + werror = rpccli_spoolss_enumforms( + hnd->cli, hnd->mem_ctx, &hnd->pol, level, &num_forms, &forms); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); diff --git a/source/python/py_spoolss_jobs.c b/source/python/py_spoolss_jobs.c index 8ea0ebc073a..8a76d247c67 100644 --- a/source/python/py_spoolss_jobs.c +++ b/source/python/py_spoolss_jobs.c @@ -39,9 +39,9 @@ PyObject *spoolss_hnd_enumjobs(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_enumjobs( - hnd->cli, hnd->mem_ctx, &hnd->pol, level, 0, - 1000, &num_jobs, &ctr); + werror = rpccli_spoolss_enumjobs( + hnd->cli, hnd->mem_ctx, &hnd->pol, level, 0, 1000, + &num_jobs, &ctr); /* Return value */ @@ -99,8 +99,8 @@ PyObject *spoolss_hnd_setjob(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_setjob(hnd->cli, hnd->mem_ctx, &hnd->pol, - jobid, level, command); + werror = rpccli_spoolss_setjob( + hnd->cli, hnd->mem_ctx, &hnd->pol, jobid, level, command); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); @@ -130,8 +130,8 @@ PyObject *spoolss_hnd_getjob(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_getjob(hnd->cli, hnd->mem_ctx, - &hnd->pol, jobid, level, &ctr); + werror = rpccli_spoolss_getjob( + hnd->cli, hnd->mem_ctx, &hnd->pol, jobid, level, &ctr); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); @@ -166,7 +166,7 @@ PyObject *spoolss_hnd_startpageprinter(PyObject *self, PyObject *args, PyObject /* Call rpc function */ - werror = cli_spoolss_startpageprinter( + werror = rpccli_spoolss_startpageprinter( hnd->cli, hnd->mem_ctx, &hnd->pol); if (!W_ERROR_IS_OK(werror)) { @@ -194,7 +194,7 @@ PyObject *spoolss_hnd_endpageprinter(PyObject *self, PyObject *args, PyObject *k /* Call rpc function */ - werror = cli_spoolss_endpageprinter( + werror = rpccli_spoolss_endpageprinter( hnd->cli, hnd->mem_ctx, &hnd->pol); if (!W_ERROR_IS_OK(werror)) { @@ -286,7 +286,7 @@ PyObject *spoolss_hnd_startdocprinter(PyObject *self, PyObject *args, PyObject * /* Call rpc function */ - werror = cli_spoolss_startdocprinter( + werror = rpccli_spoolss_startdocprinter( hnd->cli, hnd->mem_ctx, &hnd->pol, document_name, output_file, data_type, &jobid); @@ -318,7 +318,8 @@ PyObject *spoolss_hnd_enddocprinter(PyObject *self, PyObject *args, PyObject *kw /* Call rpc function */ - werror = cli_spoolss_enddocprinter(hnd->cli, hnd->mem_ctx, &hnd->pol); + werror = rpccli_spoolss_enddocprinter( + hnd->cli, hnd->mem_ctx, &hnd->pol); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); @@ -347,7 +348,7 @@ PyObject *spoolss_hnd_writeprinter(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_writeprinter( + werror = rpccli_spoolss_writeprinter( hnd->cli, hnd->mem_ctx, &hnd->pol, PyString_Size(data), PyString_AsString(data), &num_written); diff --git a/source/python/py_spoolss_ports.c b/source/python/py_spoolss_ports.c index 11a4615bbdb..721ac956eb4 100644 --- a/source/python/py_spoolss_ports.c +++ b/source/python/py_spoolss_ports.c @@ -67,7 +67,8 @@ PyObject *spoolss_enumports(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_enum_ports( cli, mem_ctx, level, &num_ports, &ctr); + werror = rpccli_spoolss_enum_ports( + cli, mem_ctx, level, &num_ports, &ctr); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); diff --git a/source/python/py_spoolss_printerdata.c b/source/python/py_spoolss_printerdata.c index 6fc4227ad21..195f01f62d8 100644 --- a/source/python/py_spoolss_printerdata.c +++ b/source/python/py_spoolss_printerdata.c @@ -122,7 +122,7 @@ PyObject *spoolss_hnd_getprinterdata(PyObject *self, PyObject *args, PyObject *k /* Call rpc function */ - werror = cli_spoolss_getprinterdata( + werror = rpccli_spoolss_getprinterdata( hnd->cli, hnd->mem_ctx, &hnd->pol, valuename, &value); @@ -160,7 +160,7 @@ PyObject *spoolss_hnd_setprinterdata(PyObject *self, PyObject *args, PyObject *k /* Call rpc function */ - werror = cli_spoolss_setprinterdata( + werror = rpccli_spoolss_setprinterdata( hnd->cli, hnd->mem_ctx, &hnd->pol, &value); if (!W_ERROR_IS_OK(werror)) { @@ -186,7 +186,7 @@ PyObject *spoolss_hnd_enumprinterdata(PyObject *self, PyObject *args, PyObject * /* Get max buffer sizes for value and data */ - werror = cli_spoolss_enumprinterdata( + werror = rpccli_spoolss_enumprinterdata( hnd->cli, hnd->mem_ctx, &hnd->pol, ndx, 0, 0, &value_needed, &data_needed, NULL); @@ -202,7 +202,7 @@ PyObject *spoolss_hnd_enumprinterdata(PyObject *self, PyObject *args, PyObject * while (W_ERROR_IS_OK(werror)) { PyObject *obj; - werror = cli_spoolss_enumprinterdata( + werror = rpccli_spoolss_enumprinterdata( hnd->cli, hnd->mem_ctx, &hnd->pol, ndx, value_needed, data_needed, NULL, NULL, &value); @@ -231,7 +231,7 @@ PyObject *spoolss_hnd_deleteprinterdata(PyObject *self, PyObject *args, PyObject /* Call rpc function */ - werror = cli_spoolss_deleteprinterdata( + werror = rpccli_spoolss_deleteprinterdata( hnd->cli, hnd->mem_ctx, &hnd->pol, value); if (!W_ERROR_IS_OK(werror)) { @@ -259,7 +259,7 @@ PyObject *spoolss_hnd_getprinterdataex(PyObject *self, PyObject *args, PyObject /* Call rpc function */ - werror = cli_spoolss_getprinterdataex( + werror = rpccli_spoolss_getprinterdataex( hnd->cli, hnd->mem_ctx, &hnd->pol, key, valuename, &value); @@ -295,7 +295,7 @@ PyObject *spoolss_hnd_setprinterdataex(PyObject *self, PyObject *args, PyObject /* Call rpc function */ - werror = cli_spoolss_setprinterdataex( + werror = rpccli_spoolss_setprinterdataex( hnd->cli, hnd->mem_ctx, &hnd->pol, keyname, &value); if (!W_ERROR_IS_OK(werror)) { @@ -322,7 +322,8 @@ PyObject *spoolss_hnd_enumprinterdataex(PyObject *self, PyObject *args, PyObject /* Get max buffer sizes for value and data */ - werror = cli_spoolss_enumprinterdataex(hnd->cli, hnd->mem_ctx, &hnd->pol, key, &ctr); + werror = rpccli_spoolss_enumprinterdataex( + hnd->cli, hnd->mem_ctx, &hnd->pol, key, &ctr); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); @@ -363,7 +364,7 @@ PyObject *spoolss_hnd_deleteprinterdataex(PyObject *self, PyObject *args, PyObje /* Call rpc function */ - werror = cli_spoolss_deleteprinterdataex( + werror = rpccli_spoolss_deleteprinterdataex( hnd->cli, hnd->mem_ctx, &hnd->pol, key, value); if (!W_ERROR_IS_OK(werror)) { @@ -393,9 +394,9 @@ PyObject *spoolss_hnd_enumprinterkey(PyObject *self, PyObject *args, /* Call rpc function */ - werror = cli_spoolss_enumprinterkey( - hnd->cli, hnd->mem_ctx, &hnd->pol, - keyname, &keylist, &keylist_len); + werror = rpccli_spoolss_enumprinterkey( + hnd->cli, hnd->mem_ctx, &hnd->pol, keyname, &keylist, + &keylist_len); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); diff --git a/source/python/py_spoolss_printers.c b/source/python/py_spoolss_printers.c index aab2d634a34..50c19fcf045 100644 --- a/source/python/py_spoolss_printers.c +++ b/source/python/py_spoolss_printers.c @@ -68,7 +68,7 @@ PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw) goto done; } - werror = cli_spoolss_open_printer_ex( + werror = rpccli_spoolss_open_printer_ex( cli, mem_ctx, unc_name, "", desired_access, server, "", &hnd); @@ -110,7 +110,8 @@ PyObject *spoolss_closeprinter(PyObject *self, PyObject *args) /* Call rpc function */ - result = cli_spoolss_close_printer(hnd->cli, hnd->mem_ctx, &hnd->pol); + result = rpccli_spoolss_close_printer( + hnd->cli, hnd->mem_ctx, &hnd->pol); /* Return value */ @@ -138,7 +139,7 @@ PyObject *spoolss_hnd_getprinter(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_getprinter( + werror = rpccli_spoolss_getprinter( hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr); /* Return value */ @@ -249,8 +250,8 @@ PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_setprinter(hnd->cli, hnd->mem_ctx, &hnd->pol, - level, &ctr, 0); + werror = rpccli_spoolss_setprinter( + hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr, 0); /* Return value */ @@ -325,8 +326,8 @@ PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw) /* Call rpc function */ - werror = cli_spoolss_enum_printers(cli, mem_ctx, name, flags, level, - &num_printers, &ctr); + werror = rpccli_spoolss_enum_printers( + cli, mem_ctx, name, flags, level, &num_printers, &ctr); if (!W_ERROR_IS_OK(werror)) { PyErr_SetObject(spoolss_werror, py_werror_tuple(werror)); @@ -447,7 +448,7 @@ PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw) ctr.printers_2 = &info2; - werror = cli_spoolss_addprinterex(cli, mem_ctx, 2, &ctr); + werror = rpccli_spoolss_addprinterex(cli, mem_ctx, 2, &ctr); Py_INCREF(Py_None); result = Py_None; diff --git a/source/python/py_srvsvc.c b/source/python/py_srvsvc.c index 823dbb334ac..567572a9e5c 100644 --- a/source/python/py_srvsvc.c +++ b/source/python/py_srvsvc.c @@ -120,7 +120,7 @@ PyObject *srvsvc_netservergetinfo(PyObject *self, PyObject *args, ZERO_STRUCT(ctr); - status = cli_srvsvc_net_srv_get_info(cli, mem_ctx, level, &ctr); + status = rpccli_srvsvc_net_srv_get_info(cli, mem_ctx, level, &ctr); if (!NT_STATUS_IS_OK(status)) { PyErr_SetObject(srvsvc_error, py_werror_tuple(status)); diff --git a/source/python/setup.py b/source/python/setup.py index a8b2c2c26d6..18f1f2648ab 100755 --- a/source/python/setup.py +++ b/source/python/setup.py @@ -52,21 +52,28 @@ obj_list = string.split(samba_objs) libraries = [] library_dirs = [] +next_is_path = 0 +next_is_flag = 0 + for lib in string.split(samba_libs): - if lib[0:2] == "-l": - libraries.append(lib[2:]) - continue - if lib[0:8] == "-pthread": + if next_is_path != 0: + library_dirs.append(lib); + next_is_path = 0; + elif next_is_flag != 0: + next_is_flag = 0; + elif lib == "-Wl,-rpath": + next_is_path = 1; + elif lib[0:2] in ("-l","-pthread"): libraries.append(lib[2:]) - continue - if lib[0:2] == "-L": + elif lib[0:2] == "-L": library_dirs.append(lib[2:]) - continue - if lib[0:2] == "-W": - # Skip linker flags - continue - print "Unknown entry '%s' in $LIBS variable passed to setup.py" % lib - sys.exit(1) + elif lib[0:2] in ("-W","-s"): + pass # Skip linker flags + elif lib[0:2] == "-z": + next_is_flag = 1 # Skip linker flags + else: + print "Unknown entry '%s' in $LIBS variable passed to setup.py" % lib + sys.exit(1) flags_list = string.split(samba_cflags) diff --git a/source/registry/reg_db.c b/source/registry/reg_db.c index ab8fc14d909..ddc08cf2ce4 100644 --- a/source/registry/reg_db.c +++ b/source/registry/reg_db.c @@ -26,6 +26,7 @@ #define DBGC_CLASS DBGC_RPC_SRV static TDB_CONTEXT *tdb_reg; +static int tdb_refcount; #define VALUE_PREFIX "SAMBA_REGVAL" @@ -196,7 +197,7 @@ static BOOL init_registry_data( void ) Open the registry database ***********************************************************************/ -BOOL init_registry_db( void ) +BOOL regdb_init( void ) { const char *vstring = "INFO/version"; uint32 vers_id; @@ -208,13 +209,15 @@ BOOL init_registry_db( void ) { tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); if ( !tdb_reg ) { - DEBUG(0,("init_registry: Failed to open registry %s (%s)\n", + DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n", lock_path("registry.tdb"), strerror(errno) )); return False; } - DEBUG(10,("init_registry: Successfully created registry tdb\n")); + DEBUG(10,("regdb_init: Successfully created registry tdb\n")); } + + tdb_refcount = 1; vers_id = tdb_fetch_int32(tdb_reg, vstring); @@ -234,6 +237,59 @@ BOOL init_registry_db( void ) } /*********************************************************************** + Open the registry. Must already have been initialized by regdb_init() + ***********************************************************************/ + +WERROR regdb_open( void ) +{ + WERROR result = WERR_OK; + + if ( tdb_reg ) { + DEBUG(10,("regdb_open: incrementing refcount (%d)\n", tdb_refcount)); + tdb_refcount++; + return WERR_OK; + } + + become_root(); + + tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600); + if ( !tdb_reg ) { + result = ntstatus_to_werror( map_nt_error_from_unix( errno ) ); + DEBUG(0,("regdb_open: Failed to open %s! (%s)\n", + lock_path("registry.tdb"), strerror(errno) )); + } + + unbecome_root(); + + tdb_refcount = 1; + DEBUG(10,("regdb_open: refcount reset (%d)\n", tdb_refcount)); + + return result; +} + +/*********************************************************************** + ***********************************************************************/ + +int regdb_close( void ) +{ + int ret; + + tdb_refcount--; + + DEBUG(10,("regdb_close: decrementing refcount (%d)\n", tdb_refcount)); + + if ( tdb_refcount > 0 ) + return 0; + + SMB_ASSERT( tdb_refcount >= 0 ); + + ret = tdb_close( tdb_reg ); + tdb_reg = NULL; + + return ret; +} + +/*********************************************************************** Add subkey strings to the registry tdb under a defined key fmt is the same format as tdb_pack except this function only supports fstrings diff --git a/source/registry/reg_frontend.c b/source/registry/reg_frontend.c index f5284e9e88f..b0e713a8826 100644 --- a/source/registry/reg_frontend.c +++ b/source/registry/reg_frontend.c @@ -110,7 +110,7 @@ BOOL init_registry( void ) int i; - if ( !init_registry_db() ) { + if ( !regdb_init() ) { DEBUG(0,("init_registry: failed to initialize the registry tdb!\n")); return False; } @@ -132,6 +132,10 @@ BOOL init_registry( void ) svcctl_init_keys(); eventlog_init_keys(); + /* close and let each smbd open up as necessary */ + + regdb_close(); + return True; } @@ -348,10 +352,15 @@ WERROR regkey_open_internal( REGISTRY_KEY **regkey, const char *path, REGSUBKEY_CTR *subkeys = NULL; uint32 access_granted; + if ( !(W_ERROR_IS_OK(result = regdb_open()) ) ) + return result; + DEBUG(7,("regkey_open_internal: name = [%s]\n", path)); - if ( !(*regkey = TALLOC_ZERO_P(NULL, REGISTRY_KEY)) ) + if ( !(*regkey = TALLOC_ZERO_P(NULL, REGISTRY_KEY)) ) { + regdb_close(); return WERR_NOMEM; + } keyinfo = *regkey; @@ -399,8 +408,19 @@ WERROR regkey_open_internal( REGISTRY_KEY **regkey, const char *path, done: if ( !W_ERROR_IS_OK(result) ) { - TALLOC_FREE( *regkey ); + regkey_close_internal( *regkey ); } return result; } + +/******************************************************************* +*******************************************************************/ + +WERROR regkey_close_internal( REGISTRY_KEY *key ) +{ + TALLOC_FREE( key ); + regdb_close(); + + return WERR_OK; +} diff --git a/source/registry/reg_util.c b/source/registry/reg_util.c index 9f19db2646a..511e9b43354 100644 --- a/source/registry/reg_util.c +++ b/source/registry/reg_util.c @@ -125,3 +125,113 @@ char* reg_remaining_path( const char *key ) return p; } +/********************************************************************** +*********************************************************************/ + +int regval_convert_multi_sz( uint16 *multi_string, size_t multi_len, char ***values ) +{ + char **sz; + int i; + int num_strings = 0; + fstring buffer; + uint16 *wp; + + *values = NULL; + + if ( !multi_string || !*values ) + return 0; + + /* just count the NULLs */ + + for ( i=0; (i<multi_len-1) && !(multi_string[i]==0x0 && multi_string[i+1]==0x0); i++ ) { + if ( multi_string[i] == 0x0 ) + num_strings++; + } + + if ( num_strings == 0 ) + return 0; + + if ( !(sz = TALLOC_ARRAY( NULL, char*, num_strings+1 )) ) { + DEBUG(0,("reg_convert_multi_sz: talloc() failed!\n")); + return -1; + } + + wp = multi_string; + + for ( i=0; i<num_strings; i++ ) { + rpcstr_pull( buffer, wp, sizeof(buffer), -1, STR_TERMINATE ); + sz[i] = talloc_strdup( sz, buffer ); + + /* skip to the next string NULL and then one more */ + while ( *wp ) + wp++; + wp++; + } + + /* tag the array off with an empty string */ + sz[i] = '\0'; + + *values = sz; + + return num_strings; +} + +/********************************************************************** + Returns number of bytes, not number of unicode characters +*********************************************************************/ + +size_t regval_build_multi_sz( char **values, uint16 **buffer ) +{ + int i; + size_t buf_size = 0; + uint16 *buf, *b; + UNISTR2 sz; + + if ( !values || !*buffer ) + return 0; + + /* go ahead and alloc some space */ + + if ( !(buf = TALLOC_ARRAY( NULL, uint16, 2 )) ) { + DEBUG(0,("regval_build_multi_sz: talloc() failed!\n")); + return 0; + } + + for ( i=0; values[i]; i++ ) { + ZERO_STRUCT( sz ); + + init_unistr2( &sz, values[i], UNI_STR_TERMINATE ); + + /* Alloc some more memory. Always add one one to account for the + double NULL termination */ + + b = TALLOC_REALLOC_ARRAY( NULL, buf, uint16, buf_size+sz.uni_str_len+1 ); + if ( !b ) { + DEBUG(0,("regval_build_multi_sz: talloc() reallocation error!\n")); + TALLOC_FREE( buffer ); + return 0; + } + buf = b; + + /* copy the unistring2 buffer and increment the size */ + + memcpy( buf+buf_size, sz.buffer, sz.uni_str_len ); + buf_size += sz.uni_str_len; + + /* cleanup rather than leaving memory hanging around */ + TALLOC_FREE( sz.buffer ); + } + + buf[buf_size++] = 0x0; + + *buffer = buf; + + /* return number of bytes */ + return buf_size*2; +} + + + + + + diff --git a/source/rpc_client/cli_ds.c b/source/rpc_client/cli_ds.c index 8d1945f7698..9c7ad840629 100644 --- a/source/rpc_client/cli_ds.c +++ b/source/rpc_client/cli_ds.c @@ -85,7 +85,7 @@ NTSTATUS rpccli_ds_enum_domain_trusts(struct rpc_pipe_client *cli, init_q_ds_enum_domain_trusts( &q, server, flags ); - CLI_DO_RPC( cli, mem_ctx, PI_LSARPC_DS, DS_ENUM_DOM_TRUSTS, + CLI_DO_RPC( cli, mem_ctx, PI_NETLOGON, DS_ENUM_DOM_TRUSTS, q, r, qbuf, rbuf, ds_io_q_enum_domain_trusts, diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c index 2e6f42b0e69..3b411272c3a 100644 --- a/source/rpc_client/cli_pipe.c +++ b/source/rpc_client/cli_pipe.c @@ -2636,6 +2636,8 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli, return result; } +#ifdef HAVE_KRB5 + /**************************************************************************** Free function for the kerberos spcific data. ****************************************************************************/ @@ -2645,6 +2647,8 @@ static void kerberos_auth_struct_free(struct cli_pipe_auth_data *a) data_blob_free(&a->a_u.kerberos_auth->session_key); } +#endif + /**************************************************************************** Open a named pipe to an SMB server and bind using krb5 (bind type 16). The idea is this can be called with service_princ, username and password all diff --git a/source/rpc_server/srv_eventlog_lib.c b/source/rpc_server/srv_eventlog_lib.c index a8c1ad51d21..495ad8e58cb 100644 --- a/source/rpc_server/srv_eventlog_lib.c +++ b/source/rpc_server/srv_eventlog_lib.c @@ -1,8 +1,8 @@ - /* * Unix SMB/CIFS implementation. * Eventlog utility routines * Copyright (C) Marcin Krzysztof Porwit 2005, + * Copyright (C) Brian Moran 2005. * Copyright (C) Gerald (Jerry) Carter 2005. * * This program is free software; you can redistribute it and/or modify @@ -22,116 +22,132 @@ #include "includes.h" +/* maintain a list of open eventlog tdbs with reference counts */ -/**************************************************************** -Init an Eventlog TDB, and return it. If null, something bad happened. -****************************************************************/ -TDB_CONTEXT *init_eventlog_tdb( char *tdbfilename ) -{ - TDB_CONTEXT *the_tdb; - - unlink( tdbfilename ); +struct elog_open_tdb { + struct elog_open_tdb *prev, *next; + char *name; + TDB_CONTEXT *tdb; + int ref_count; +}; - the_tdb = - tdb_open_log( tdbfilename, 0, TDB_DEFAULT, O_RDWR | O_CREAT, - 0664 ); - if ( the_tdb == NULL ) { - DEBUG( 1, ( "Can't open tdb for [%s]\n", tdbfilename ) ); - return NULL; - } - tdb_store_int32( the_tdb, VN_oldest_entry, 1 ); - tdb_store_int32( the_tdb, VN_next_record, 1 ); +static struct elog_open_tdb *open_elog_list; - /* initialize with defaults, copy real values in here from registry */ - - tdb_store_int32( the_tdb, VN_maxsize, 0x80000 ); - tdb_store_int32( the_tdb, VN_retention, 0x93A80 ); - - tdb_store_int32( the_tdb, VN_version, EVENTLOG_DATABASE_VERSION_V1 ); - return the_tdb; -} +/******************************************************************** + Init an Eventlog TDB, and return it. If null, something bad + happened. +********************************************************************/ -/* make the tdb file name for an event log, given destination buffer and size */ -char *mk_tdbfilename( char *dest_buffer, char *eventlog_name, int size_dest ) +TDB_CONTEXT *elog_init_tdb( char *tdbfilename ) { - if ( !dest_buffer ) - return NULL; - pstring ondisk_name; + TDB_CONTEXT *tdb; - pstrcpy( ondisk_name, "EV" ); - pstrcat( ondisk_name, eventlog_name ); - pstrcat( ondisk_name, ".tdb" ); + DEBUG(10,("elog_init_tdb: Initializing eventlog tdb (%s)\n", + tdbfilename)); - memset( dest_buffer, 0, size_dest ); + tdb = tdb_open_log( tdbfilename, 0, TDB_DEFAULT, + O_RDWR|O_CREAT|O_TRUNC, 0600 ); - /* BAD things could happen if the dest_buffer is not large enough... */ - if ( strlen( ondisk_name ) > size_dest ) { - DEBUG( 3, ( "Buffer not big enough for filename\n" ) ); + if ( !tdb ) { + DEBUG( 0, ( "Can't open tdb for [%s]\n", tdbfilename ) ); return NULL; } - strncpy( dest_buffer, ondisk_name, size_dest ); + /* initialize with defaults, copy real values in here from registry */ + + tdb_store_int32( tdb, EVT_OLDEST_ENTRY, 1 ); + tdb_store_int32( tdb, EVT_NEXT_RECORD, 1 ); + tdb_store_int32( tdb, EVT_MAXSIZE, 0x80000 ); + tdb_store_int32( tdb, EVT_RETENTION, 0x93A80 ); - return dest_buffer; + tdb_store_int32( tdb, EVT_VERSION, EVENTLOG_DATABASE_VERSION_V1 ); + + return tdb; } +/******************************************************************** + make the tdb file name for an event log, given destination buffer + and size. Caller must free memory. +********************************************************************/ + +char *elog_tdbname( const char *name ) +{ + fstring path; + char *tdb_fullpath; + char *eventlogdir = lock_path( "eventlog" ); + + pstr_sprintf( path, "%s/%s.tdb", eventlogdir, name ); + strlower_m( path ); + tdb_fullpath = SMB_STRDUP( path ); + + return tdb_fullpath; +} -/* count the number of bytes in the TDB */ -/* Arg! Static Globals! */ +/******************************************************************** + this function is used to count up the number of bytes in a + particular TDB +********************************************************************/ -static int eventlog_tdbcount; -static int eventlog_tdbsize; +struct trav_size_struct { + int size; + int rec_count; +}; -/* this function is used to count up the number of bytes in a particular TDB */ -int eventlog_tdb_size_fn( TDB_CONTEXT * tdb, TDB_DATA key, TDB_DATA data, +static int eventlog_tdb_size_fn( TDB_CONTEXT * tdb, TDB_DATA key, TDB_DATA data, void *state ) { - eventlog_tdbsize += data.dsize; - eventlog_tdbcount++; + struct trav_size_struct *tsize = state; + + tsize->size += data.dsize; + tsize->rec_count++; + return 0; } -/* returns the size of the eventlog, and if MaxSize is a non-null ptr, puts - the MaxSize there. This is purely a way not to have yet another function that solely - reads the maxsize of the eventlog. Yeah, that's it. */ +/******************************************************************** + returns the size of the eventlog, and if MaxSize is a non-null + ptr, puts the MaxSize there. This is purely a way not to have yet + another function that solely reads the maxsize of the eventlog. + Yeah, that's it. +********************************************************************/ -int eventlog_tdb_size( TDB_CONTEXT * tdb, int *MaxSize, int *Retention ) +int elog_tdb_size( TDB_CONTEXT * tdb, int *MaxSize, int *Retention ) { + struct trav_size_struct tsize; + if ( !tdb ) return 0; - eventlog_tdbcount = 0; - eventlog_tdbsize = 0; + + ZERO_STRUCT( tsize ); - tdb_traverse( tdb, eventlog_tdb_size_fn, NULL ); + tdb_traverse( tdb, eventlog_tdb_size_fn, &tsize ); if ( MaxSize != NULL ) { - *MaxSize = tdb_fetch_int32( tdb, VN_maxsize ); + *MaxSize = tdb_fetch_int32( tdb, EVT_MAXSIZE ); } if ( Retention != NULL ) { - *Retention = tdb_fetch_int32( tdb, VN_retention ); + *Retention = tdb_fetch_int32( tdb, EVT_RETENTION ); } DEBUG( 1, - ( "eventlog size: [%d] for [%d] records\n", eventlog_tdbsize, - eventlog_tdbcount ) ); - return eventlog_tdbsize; + ( "eventlog size: [%d] for [%d] records\n", tsize.size, + tsize.rec_count ) ); + return tsize.size; } - -/* - Discard early event logs until we have enough for 'needed' bytes... - NO checking done beforehand to see that we actually need to do this, and - it's going to pluck records one-by-one. So, it's best to determine that this - needs to be done before doing it. - - Setting whack_by_date to True indicates that eventlogs falling outside of the - retention range need to go... - -*/ - -/* return True if we made enough room to accommodate needed bytes */ +/******************************************************************** + Discard early event logs until we have enough for 'needed' bytes... + NO checking done beforehand to see that we actually need to do + this, and it's going to pluck records one-by-one. So, it's best + to determine that this needs to be done before doing it. + + Setting whack_by_date to True indicates that eventlogs falling + outside of the retention range need to go... + + return True if we made enough room to accommodate needed bytes +********************************************************************/ BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed, BOOL whack_by_date ) @@ -139,12 +155,9 @@ BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed, int start_record, i, new_start; int end_record; int nbytes, reclen, len, Retention, MaxSize; - int tresv1, trecnum, timegen, timewr; - TDB_DATA key, ret; TALLOC_CTX *mem_ctx = NULL; - time_t current_time, exp_time; /* discard some eventlogs */ @@ -157,12 +170,12 @@ BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed, if ( mem_ctx == NULL ) return False; /* can't allocate memory indicates bigger problems */ /* lock */ - tdb_lock_bystring( the_tdb, VN_next_record, 1 ); + tdb_lock_bystring( the_tdb, EVT_NEXT_RECORD, 1 ); /* read */ - end_record = tdb_fetch_int32( the_tdb, VN_next_record ); - start_record = tdb_fetch_int32( the_tdb, VN_oldest_entry ); - Retention = tdb_fetch_int32( the_tdb, VN_retention ); - MaxSize = tdb_fetch_int32( the_tdb, VN_maxsize ); + end_record = tdb_fetch_int32( the_tdb, EVT_NEXT_RECORD ); + start_record = tdb_fetch_int32( the_tdb, EVT_OLDEST_ENTRY ); + Retention = tdb_fetch_int32( the_tdb, EVT_RETENTION ); + MaxSize = tdb_fetch_int32( the_tdb, EVT_MAXSIZE ); time( ¤t_time ); @@ -188,7 +201,7 @@ BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed, DEBUG( 8, ( "Can't find a record for the key, record [%d]\n", i ) ); - tdb_unlock_bystring( the_tdb, VN_next_record ); + tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD ); return False; } nbytes += ret.dsize; /* note this includes overhead */ @@ -225,16 +238,16 @@ BOOL make_way_for_eventlogs( TDB_CONTEXT * the_tdb, int32 needed, tdb_delete( the_tdb, key ); } - tdb_store_int32( the_tdb, VN_oldest_entry, new_start ); + tdb_store_int32( the_tdb, EVT_OLDEST_ENTRY, new_start ); } - tdb_unlock_bystring( the_tdb, VN_next_record ); + tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD ); return True; } -/* +/******************************************************************** some hygiene for an eventlog - see how big it is, and then calculate how many bytes we need to remove -*/ +********************************************************************/ BOOL prune_eventlog( TDB_CONTEXT * tdb ) { @@ -245,7 +258,7 @@ BOOL prune_eventlog( TDB_CONTEXT * tdb ) return False; } - CalcdSize = eventlog_tdb_size( tdb, &MaxSize, &Retention ); + CalcdSize = elog_tdb_size( tdb, &MaxSize, &Retention ); DEBUG( 3, ( "Calculated size [%d] MaxSize [%d]\n", CalcdSize, MaxSize ) ); @@ -258,6 +271,9 @@ BOOL prune_eventlog( TDB_CONTEXT * tdb ) return make_way_for_eventlogs( tdb, 0, True ); } +/******************************************************************** +********************************************************************/ + BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed ) { int calcd_size; @@ -273,7 +289,7 @@ BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed ) MaxSize = 0; Retention = 0; - calcd_size = eventlog_tdb_size( tdb, &MaxSize, &Retention ); + calcd_size = elog_tdb_size( tdb, &MaxSize, &Retention ); if ( calcd_size <= MaxSize ) return True; /* you betcha */ @@ -298,29 +314,128 @@ BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed ) return make_way_for_eventlogs( tdb, calcd_size - MaxSize, False ); } -TDB_CONTEXT *open_eventlog_tdb( char *tdbfilename ) +/******************************************************************* +*******************************************************************/ + +TDB_CONTEXT *elog_open_tdb( char *logname ) { - TDB_CONTEXT *the_tdb; + TDB_CONTEXT *tdb; + uint32 vers_id; + struct elog_open_tdb *ptr; + char *tdbfilename; + pstring tdbpath; + struct elog_open_tdb *tdb_node; + char *eventlogdir; + + /* first see if we have an open context */ + + for ( ptr=open_elog_list; ptr; ptr=ptr->next ) { + if ( strequal( ptr->name, logname ) ) { + ptr->ref_count++; + return ptr->tdb; + } + } + + /* make sure that the eventlog dir exists */ + + eventlogdir = lock_path( "eventlog" ); + if ( !directory_exist( eventlogdir, NULL ) ) + mkdir( eventlogdir, 0755 ); + + /* get the path on disk */ + + tdbfilename = elog_tdbname( logname ); + pstrcpy( tdbpath, tdbfilename ); + SAFE_FREE( tdbfilename ); + + DEBUG(7,("elog_open_tdb: Opening %s...\n", tdbpath )); + + tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 ); + if ( tdb ) { + vers_id = tdb_fetch_int32( tdb, EVT_VERSION ); + + if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) { + DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n", + vers_id, tdbpath)); + tdb_close( tdb ); + tdb = elog_init_tdb( tdbpath ); + } + } + else { + tdb = elog_init_tdb( tdbpath ); + } + + /* if we got a valid context, then add it to the list */ + + if ( tdb ) { + if ( !(tdb_node = TALLOC_ZERO_P( NULL, struct elog_open_tdb )) ) { + DEBUG(0,("elog_open_tdb: talloc() failure!\n")); + tdb_close( tdb ); + return NULL; + } + + tdb_node->name = talloc_strdup( tdb_node, logname ); + tdb_node->tdb = tdb; + tdb_node->ref_count = 1; + + DLIST_ADD( open_elog_list, tdb_node ); + } + + return tdb; +} + +/******************************************************************* + Wrapper to handle reference counts to the tdb +*******************************************************************/ - the_tdb = - tdb_open_log( tdbfilename, 0, TDB_DEFAULT, O_RDWR | O_CREAT, - 0664 ); - if ( the_tdb == NULL ) { - return init_eventlog_tdb( tdbfilename ); +int elog_close_tdb( TDB_CONTEXT *tdb ) +{ + struct elog_open_tdb *ptr; + + if ( !tdb ) + return 0; + + /* See if we can just decrement the ref_count. + Just compare pointer values (not names ) */ + + for ( ptr=open_elog_list; ptr; ptr=ptr->next ) { + if ( tdb == ptr->tdb ) { + ptr->ref_count--; + break; + } } - if ( EVENTLOG_DATABASE_VERSION_V1 != - tdb_fetch_int32( the_tdb, VN_version ) ) { - tdb_close( the_tdb ); - return init_eventlog_tdb( tdbfilename ); + + /* if we have a NULL pointer; it means we are trying to + close a tdb not in the list of open eventlogs */ + + SMB_ASSERT( ptr != NULL ); + if ( !ptr ) + return tdb_close( tdb ); + + SMB_ASSERT( ptr->ref_count >= 0 ); + + if ( ptr->ref_count == 0 ) { + DLIST_REMOVE( open_elog_list, ptr ); + TALLOC_FREE( ptr ); + return tdb_close( tdb ); } - return the_tdb; + + return 0; } -/* write an eventlog entry. Note that we have to lock, read next eventlog, increment, write, write the record, unlock */ -/* coming into this, ee has the eventlog record, and the auxilliary date (computer name, etc.) - filled into the other structure. Before packing into a record, this routine will calc the - appropriate padding, etc., and then blast out the record in a form that can be read back in */ +/******************************************************************* + write an eventlog entry. Note that we have to lock, read next + eventlog, increment, write, write the record, unlock + + coming into this, ee has the eventlog record, and the auxilliary date + (computer name, etc.) filled into the other structure. Before packing + into a record, this routine will calc the appropriate padding, etc., + and then blast out the record in a form that can be read back in +*******************************************************************/ + +#define MARGIN 512 + int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee ) { int32 next_record; @@ -343,8 +458,6 @@ int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee ) if ( ee->record.time_generated == 0 ) return 0; -#define MARGIN 512 - /* todo - check for sanity in next_record */ fixup_eventlog_entry( ee ); @@ -365,9 +478,9 @@ int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee ) /* need to read the record number and insert it into the entry here */ /* lock */ - tdb_lock_bystring( the_tdb, VN_next_record, 1 ); + tdb_lock_bystring( the_tdb, EVT_NEXT_RECORD, 1 ); /* read */ - next_record = tdb_fetch_int32( the_tdb, VN_next_record ); + next_record = tdb_fetch_int32( the_tdb, EVT_NEXT_RECORD ); n_packed = tdb_pack( packed_ee, ee->record.length + MARGIN, @@ -406,18 +519,20 @@ int write_eventlog_tdb( TDB_CONTEXT * the_tdb, Eventlog_entry * ee ) if ( tdb_store( the_tdb, kbuf, ebuf, 0 ) ) { /* DEBUG(1,("write_eventlog_tdb: Can't write record %d to eventlog\n",next_record)); */ - tdb_unlock_bystring( the_tdb, VN_next_record ); + tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD ); talloc_destroy( mem_ctx ); return 0; } next_record++; - tdb_store_int32( the_tdb, VN_next_record, next_record ); - tdb_unlock_bystring( the_tdb, VN_next_record ); + tdb_store_int32( the_tdb, EVT_NEXT_RECORD, next_record ); + tdb_unlock_bystring( the_tdb, EVT_NEXT_RECORD ); talloc_destroy( mem_ctx ); return ( next_record - 1 ); } -/* calculate the correct fields etc for an eventlog entry */ +/******************************************************************* + calculate the correct fields etc for an eventlog entry +*******************************************************************/ void fixup_eventlog_entry( Eventlog_entry * ee ) { @@ -453,10 +568,11 @@ void fixup_eventlog_entry( Eventlog_entry * ee ) } /******************************************************************** -Note that it's a pretty good idea to initialize the Eventlog_entry structure to zero's before -calling parse_logentry on an batch of lines that may resolve to a record. -ALSO, it's a good idea to remove any linefeeds (that's EOL to you and me) on the lines going in. - + Note that it's a pretty good idea to initialize the Eventlog_entry + structure to zero's before calling parse_logentry on an batch of + lines that may resolve to a record. ALSO, it's a good idea to + remove any linefeeds (that's EOL to you and me) on the lines + going in. ********************************************************************/ BOOL parse_logentry( char *line, Eventlog_entry * entry, BOOL * eor ) diff --git a/source/rpc_server/srv_eventlog_nt.c b/source/rpc_server/srv_eventlog_nt.c index 6067c94fe89..577ec48482a 100644 --- a/source/rpc_server/srv_eventlog_nt.c +++ b/source/rpc_server/srv_eventlog_nt.c @@ -25,192 +25,201 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV - -typedef struct { - pstring logname; /* rather than alloc on the fly what we need... (memory is cheap now) */ - pstring tdbfname; - TDB_CONTEXT *log_tdb; /* the pointer to the TDB_CONTEXT */ -} EventlogTDBInfo; - -static int nlogs; -static EventlogTDBInfo *ttdb = NULL; -static TALLOC_CTX *mem_ctx = NULL; - typedef struct { char *logname; - char *servername; + TDB_CONTEXT *tdb; uint32 num_records; uint32 oldest_entry; uint32 flags; -} EventlogInfo; + uint32 access_granted; +} EVENTLOG_INFO; +/******************************************************************** + ********************************************************************/ +static void free_eventlog_info( void *ptr ) +{ + EVENTLOG_INFO *elog = (EVENTLOG_INFO *)ptr; + + if ( elog->tdb ) + elog_close_tdb( elog->tdb ); + + TALLOC_FREE( elog ); +} -#if 0 /* UNUSED */ /******************************************************************** ********************************************************************/ - -void test_eventlog_tdb( TDB_CONTEXT * the_tdb ) + +static EVENTLOG_INFO *find_eventlog_info_by_hnd( pipes_struct * p, + POLICY_HND * handle ) { - Eventlog_entry ee; - - int i = 0; - - memset( &ee, 0, sizeof( Eventlog_entry ) ); - - if ( !the_tdb ) - return; - - for ( i = 0; i < 100; i++ ) { - ee.record.length = sizeof( ee.record ); - memset( &ee.data_record, 0, sizeof( ee.data_record ) ); - ee.record.reserved1 = 0xBEEFDEAD; - ee.record.record_number = 1000 - i; /* should get substituted */ - ee.record.time_generated = 0; - ee.record.time_written = 0; - ee.record.event_id = 500; - ee.record.event_type = 300; - ee.record.num_strings = 0; - ee.record.event_category = 0; - ee.record.reserved2 = ( i << 8 ) | i; - ee.record.closing_record_number = -1; - ee.record.string_offset = 0; - ee.record.user_sid_length = 0; - ee.record.user_sid_offset = 0; - ee.record.data_length = 0; - ee.record.data_offset = 0; - - rpcstr_push( ( void * ) ( ee.data_record.source_name ), - "SystemLog", - sizeof( ee.data_record.source_name ), - STR_TERMINATE ); - ee.data_record.source_name_len = - ( strlen_w( ee.data_record.source_name ) * 2 ) + 2; - - rpcstr_push( ( void * ) ( ee.data_record.computer_name ), - "DMLINUX", - sizeof( ee.data_record.computer_name ), - STR_TERMINATE ); - - ee.data_record.computer_name_len = - ( strlen_w( ee.data_record.computer_name ) * 2 ) + 2; - - write_eventlog_tdb( the_tdb, &ee ); + EVENTLOG_INFO *info; + + if ( !find_policy_by_hnd( p, handle, ( void ** ) &info ) ) { + DEBUG( 2, + ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) ); + return NULL; } + + return info; } -#endif /* UNUSED */ /******************************************************************** - ********************************************************************/ +********************************************************************/ -static void refresh_eventlog_tdb_table( void ) +static BOOL elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token ) { - const char **elogs = lp_eventlog_list( ); - int i, j; + char *tdbname = elog_tdbname( info->logname ); + SEC_DESC *sec_desc; + BOOL ret; + NTSTATUS ntstatus; + + if ( !tdbname ) + return False; + + /* get the security descriptor for the file */ + + sec_desc = get_nt_acl_no_snum( info, tdbname ); + SAFE_FREE( tdbname ); + + if ( !sec_desc ) { + DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n", + tdbname)); + return False; + } + + /* run the check, try for the max allowed */ + + ret = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS, + &info->access_granted, &ntstatus ); + + if ( sec_desc ) + TALLOC_FREE( sec_desc ); + + if ( !ret ) { + DEBUG(8,("elog_check_access: se_access_check() return %s\n", + nt_errstr( ntstatus))); + return False; + } + + /* we have to have READ permission for a successful open */ + + return ( info->access_granted & SA_RIGHT_FILE_READ_DATA ); +} - if ( !elogs ) - return; +/******************************************************************** + ********************************************************************/ - if ( !mem_ctx ) { - mem_ctx = talloc_init( "refresh_eventlog_tdb_table" ); +static BOOL elog_validate_logname( const char *name ) +{ + int i; + const char **elogs = lp_eventlog_list(); + + for ( i=0; elogs[i]; i++ ) { + if ( strequal( name, elogs[i] ) ) + return True; } + + return False; +} - if ( !mem_ctx ) { - DEBUG( 1, ( "Can't allocate memory\n" ) ); - return; - } +/******************************************************************** + ********************************************************************/ - /* count them */ - for ( i = 0; elogs[i]; i++ ) { - } - /* number of logs in i */ - DEBUG( 10, ( "Number of eventlogs %d\n", i ) ); - /* check to see if we need to adjust our tables */ - - if ( ( ttdb != NULL ) ) { - if ( i != nlogs ) { - /* refresh the table, by closing and reconstructing */ - DEBUG( 10, ( "Closing existing table \n" ) ); - for ( j = 0; j < nlogs; j++ ) { - tdb_close( ttdb[j].log_tdb ); - } - TALLOC_FREE( ttdb ); - ttdb = NULL; - } else { /* i == nlogs */ - - for ( j = 0; j < nlogs; j++ ) { - if ( StrCaseCmp( ttdb[j].logname, elogs[i] ) ) { - /* something changed, have to discard */ - DEBUG( 10, - ( "Closing existing table \n" ) ); - for ( j = 0; j < nlogs; j++ ) { - tdb_close( ttdb[j].log_tdb ); - } - TALLOC_FREE( ttdb ); - ttdb = NULL; - break; - } +static WERROR elog_open( pipes_struct * p, const char *logname, POLICY_HND *hnd ) +{ + EVENTLOG_INFO *elog; + + /* first thing is to validate the eventlog name */ + + if ( !elog_validate_logname( logname ) ) + return WERR_OBJECT_PATH_INVALID; + + if ( !(elog = TALLOC_ZERO_P( NULL, EVENTLOG_INFO )) ) + return WERR_NOMEM; + + elog->logname = talloc_strdup( elog, logname ); + + /* Open the tdb first (so that we can create any new tdbs if necessary). + We have to do this as root and then use an internal access check + on the file permissions since you can only have a tdb open once + in a single process */ + + become_root(); + elog->tdb = elog_open_tdb( elog->logname ); + unbecome_root(); + + if ( !elog->tdb ) { + /* according to MSDN, if the logfile cannot be found, we should + default to the "Application" log */ + + if ( !strequal( logname, ELOG_APPL ) ) { + + TALLOC_FREE( elog->logname ); + + elog->logname = talloc_strdup( elog, ELOG_APPL ); + + /* do the access check */ + if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) { + TALLOC_FREE( elog ); + return WERR_ACCESS_DENIED; } + + become_root(); + elog->tdb = elog_open_tdb( elog->logname ); + unbecome_root(); + } + + if ( !elog->tdb ) { + TALLOC_FREE( elog ); + return WERR_ACCESS_DENIED; /* ??? */ } } + + /* now do the access check. Close the tdb if we fail here */ - /* note that this might happen because of above */ - if ( ( i > 0 ) && ( ttdb == NULL ) ) { - /* alloc the room */ - DEBUG( 10, ( "Creating the table\n" ) ); - ttdb = TALLOC( mem_ctx, sizeof( EventlogTDBInfo ) * i ); - if ( !ttdb ) { - DEBUG( 10, - ( "Can't allocate table for tdb handles \n" ) ); - return; - } - for ( j = 0; j < i; j++ ) { - pstrcpy( ttdb[j].tdbfname, - lock_path( mk_tdbfilename - ( ttdb[j].tdbfname, - ( char * ) elogs[j], - sizeof( pstring ) ) ) ); - pstrcpy( ttdb[j].logname, elogs[j] ); - DEBUG( 10, ( "Opening tdb for %s\n", elogs[j] ) ); - ttdb[j].log_tdb = - open_eventlog_tdb( ttdb[j].tdbfname ); - } + if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) { + elog_close_tdb( elog->tdb ); + TALLOC_FREE( elog ); + return WERR_ACCESS_DENIED; + } + + /* create the policy handle */ + + if ( !create_policy_hnd + ( p, hnd, free_eventlog_info, ( void * ) elog ) ) { + free_eventlog_info( elog ); + return WERR_NOMEM; } - nlogs = i; + + return WERR_OK; } /******************************************************************** ********************************************************************/ -TDB_CONTEXT *tdb_of( char *eventlog_name ) +static WERROR elog_close( pipes_struct *p, POLICY_HND *hnd ) { - int i; - - if ( !eventlog_name ) - return NULL; + if ( !( close_policy_hnd( p, hnd ) ) ) { + return WERR_BADFID; + } - if ( !ttdb ) { - DEBUG( 10, ( "Refreshing list of eventlogs\n" ) ); - refresh_eventlog_tdb_table( ); - - if ( !ttdb ) { - DEBUG( 10, - ( "eventlog tdb table is NULL after a refresh!\n" ) ); - return NULL; - } - } + return WERR_OK; +} - DEBUG( 10, ( "Number of eventlogs %d\n", nlogs ) ); +/******************************************************************* + *******************************************************************/ - for ( i = 0; i < nlogs; i++ ) { - if ( strequal( eventlog_name, ttdb[i].logname ) ) - return ttdb[i].log_tdb; +static int elog_size( EVENTLOG_INFO *info ) +{ + if ( !info || !info->tdb ) { + DEBUG(0,("elog_size: Invalid info* structure!\n")); + return 0; } - return NULL; + return elog_tdb_size( info->tdb, NULL, NULL ); } - /******************************************************************** For the given tdb, get the next eventlog record into the passed Eventlog_entry. returns NULL if it can't get the record for some reason. @@ -315,36 +324,11 @@ Eventlog_entry *get_eventlog_record( prs_struct * ps, TDB_CONTEXT * tdb, } /******************************************************************** - ********************************************************************/ - -static void free_eventlog_info( void *ptr ) -{ - TALLOC_FREE( ptr ); -} - -/******************************************************************** - ********************************************************************/ - -static EventlogInfo *find_eventlog_info_by_hnd( pipes_struct * p, - POLICY_HND * handle ) -{ - EventlogInfo *info; - - if ( !find_policy_by_hnd( p, handle, ( void ** ) &info ) ) { - DEBUG( 2, - ( "find_eventlog_info_by_hnd: eventlog not found.\n" ) ); - return NULL; - } - - return info; -} - -/******************************************************************** note that this can only be called AFTER the table is constructed, since it uses the table to find the tdb handle ********************************************************************/ -static BOOL sync_eventlog_params( const char *elogname ) +static BOOL sync_eventlog_params( EVENTLOG_INFO *info ) { pstring path; uint32 uiMaxSize; @@ -353,14 +337,12 @@ static BOOL sync_eventlog_params( const char *elogname ) REGISTRY_VALUE *val; REGVAL_CTR *values; WERROR wresult; - TDB_CONTEXT *the_tdb; - - the_tdb = tdb_of( ( char * ) elogname ); + char *elogname = info->logname; DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) ); - if ( !the_tdb ) { - DEBUG( 4, ( "Can't open tdb for %s\n", elogname ) ); + if ( !info->tdb ) { + DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) ); return False; } /* set resonable defaults. 512Kb on size and 1 week on time */ @@ -400,114 +382,54 @@ static BOOL sync_eventlog_params( const char *elogname ) if ( ( val = regval_ctr_getvalue( values, "MaxSize" ) ) != NULL ) uiMaxSize = IVAL( regval_data_p( val ), 0 ); - TALLOC_FREE( keyinfo ); - - tdb_store_int32( the_tdb, VN_maxsize, uiMaxSize ); - tdb_store_int32( the_tdb, VN_retention, uiRetention ); - - return True; -} + regkey_close_internal( keyinfo ); -/******************************************************************** - ********************************************************************/ + tdb_store_int32( info->tdb, EVT_MAXSIZE, uiMaxSize ); + tdb_store_int32( info->tdb, EVT_RETENTION, uiRetention ); -static BOOL open_eventlog_hook( EventlogInfo * info ) -{ return True; } /******************************************************************** ********************************************************************/ -/** - * Callout to get the number of records in the specified event log - * - * smbrun calling convention -- - * INPUT: <get_num_records_cmd> <log name> <policy handle> - * OUTPUT: A single line with a single integer containing the number of - * entries in the log. If there are no entries in the log, return 0. - */ - - -static BOOL get_num_records_hook( EventlogInfo * info ) +static BOOL get_num_records_hook( EVENTLOG_INFO * info ) { - - TDB_CONTEXT *the_tdb = NULL; int next_record; int oldest_record; - - the_tdb = tdb_of( info->logname ); - - if ( !the_tdb ) { - DEBUG( 10, ( "Can't find tdb for %s\n", info->logname ) ); - info->num_records = 0; + if ( !info->tdb ) { + DEBUG( 10, ( "No open tdb for %s\n", info->logname ) ); return False; } - /* lock */ - tdb_lock_bystring( the_tdb, VN_next_record, 1 ); - - - /* read */ - next_record = tdb_fetch_int32( the_tdb, VN_next_record ); - oldest_record = tdb_fetch_int32( the_tdb, VN_oldest_entry ); - + /* lock the tdb since we have to get 2 records */ + tdb_lock_bystring( info->tdb, EVT_NEXT_RECORD, 1 ); + next_record = tdb_fetch_int32( info->tdb, EVT_NEXT_RECORD); + oldest_record = tdb_fetch_int32( info->tdb, EVT_OLDEST_ENTRY); + tdb_unlock_bystring( info->tdb, EVT_NEXT_RECORD); DEBUG( 8, - ( "Oldest Record %d Next Record %d\n", oldest_record, + ( "Oldest Record %d; Next Record %d\n", oldest_record, next_record ) ); info->num_records = ( next_record - oldest_record ); info->oldest_entry = oldest_record; - tdb_unlock_bystring( the_tdb, VN_next_record ); - return True; - - } /******************************************************************** ********************************************************************/ -/** - * Callout to find the oldest record in the log - * - * smbrun calling convention -- - * INPUT: <oldest_entry_cmd> <log name> <policy handle> - * OUTPUT: If there are entries in the event log, the index of the - * oldest entry. Must be 1 or greater. - * If there are no entries in the log, returns a 0 - */ - -static BOOL get_oldest_entry_hook( EventlogInfo * info ) +static BOOL get_oldest_entry_hook( EVENTLOG_INFO * info ) { /* it's the same thing */ return get_num_records_hook( info ); } - -/******************************************************************** - ********************************************************************/ - -/** - * Callout to close the specified event log - * - * smbrun calling convention -- - * INPUT: <close_cmd> <log name> <policy handle> - * OUTPUT: the string "SUCCESS" if the command succeeded - * no such string if there was a failure. - */ - -static BOOL close_eventlog_hook( EventlogInfo * info ) -{ - - return True; -} - /******************************************************************** ********************************************************************/ @@ -631,150 +553,85 @@ static BOOL add_record_to_resp( EVENTLOG_R_READ_EVENTLOG * r_u, /******************************************************************** ********************************************************************/ -/** - * Callout to clear (and optionally backup) a specified event log - * - * smbrun calling convention -- - * INPUT: <clear_eventlog_cmd> <log name> <policy handle> - * OUTPUT: A single line with the string "SUCCESS" if the command succeeded. - * Otherwise it is assumed to have failed - * - * INPUT: <clear_eventlog_cmd> <log name> <backup file> <policy handle> - * OUTPUT: A single line with the string "SUCCESS" if the command succeeded. - * Otherwise it is assumed to have failed - * The given log is copied to that location on the server. See comments for - * eventlog_io_q_clear_eventlog for info about odd file name behavior - */ -static BOOL clear_eventlog_hook( EventlogInfo * info, - pstring backup_file_name ) -{ - - int i; - - - if ( !info ) - return False; - DEBUG( 3, ( "There are %d event logs\n", nlogs ) ); - for ( i = 0; i < nlogs; i++ ) { - DEBUG( 3, - ( "Comparing Eventlog %s, %s\n", info->logname, - ttdb[i].logname ) ); - if ( !StrCaseCmp( info->logname, ttdb[i].logname ) ) { - /* close the current one, reinit */ - tdb_close( ttdb[i].log_tdb ); - DEBUG( 3, - ( "Closing Eventlog %s, file-on-disk %s\n", - info->logname, ttdb[i].tdbfname ) ); - ttdb[i].log_tdb = - init_eventlog_tdb( ttdb[i].tdbfname ); - return True; - } - } - - return False; /* not found */ - /* TODO- do something with the backup file name */ - -} - -/******************************************************************* - *******************************************************************/ - -static int eventlog_size( char *eventlog_name ) -{ - TDB_CONTEXT *tdb; - - if ( !eventlog_name ) - return 0; - tdb = tdb_of( eventlog_name ); - if ( !tdb ) - return 0; - return eventlog_tdb_size( tdb, NULL, NULL ); -} - -/******************************************************************** - ********************************************************************/ - WERROR _eventlog_open_eventlog( pipes_struct * p, EVENTLOG_Q_OPEN_EVENTLOG * q_u, EVENTLOG_R_OPEN_EVENTLOG * r_u ) { - EventlogInfo *info = NULL; - fstring str; - - if ( !( info = TALLOC_ZERO_P( NULL, EventlogInfo ) ) ) - return WERR_NOMEM; + fstring servername, logname; + EVENTLOG_INFO *info; + WERROR wresult; - fstrcpy( str, global_myname( ) ); + fstrcpy( servername, "" ); if ( q_u->servername.string ) { - rpcstr_pull( str, q_u->servername.string->buffer, - sizeof( str ), + rpcstr_pull( servername, q_u->servername.string->buffer, + sizeof( servername ), q_u->servername.string->uni_str_len * 2, 0 ); } - info->servername = talloc_strdup( info, str ); - - fstrcpy( str, "Application" ); + fstrcpy( logname, "" ); if ( q_u->logname.string ) { - rpcstr_pull( str, q_u->logname.string->buffer, - sizeof( str ), + rpcstr_pull( logname, q_u->logname.string->buffer, + sizeof( logname ), q_u->logname.string->uni_str_len * 2, 0 ); } - - info->logname = talloc_strdup( info, str ); - - DEBUG( 1, - ( "Size of %s is %d\n", info->logname, - eventlog_size( info->logname ) ) ); - - - - DEBUG( 10, - ( "_eventlog_open_eventlog: Using [%s] as the server name.\n", - info->servername ) ); - DEBUG( 10, - ( "_eventlog_open_eventlog: Using [%s] as the source log file.\n", - info->logname ) ); - - - if ( !create_policy_hnd - ( p, &r_u->handle, free_eventlog_info, ( void * ) info ) ) { - free_eventlog_info( info ); - return WERR_NOMEM; + + DEBUG( 10,("_eventlog_open_eventlog: Server [%s], Log [%s]\n", + servername, logname )); + + /* according to MSDN, if the logfile cannot be found, we should + default to the "Application" log */ + + if ( !W_ERROR_IS_OK( wresult = elog_open( p, logname, &r_u->handle )) ) + return wresult; + + if ( !(info = find_eventlog_info_by_hnd( p, &r_u->handle )) ) { + DEBUG(0,("_eventlog_open_eventlog: eventlog (%s) opened but unable to find handle!\n", + logname )); + elog_close( p, &r_u->handle ); + return WERR_BADFID; } - if ( !open_eventlog_hook( info ) ) { - close_policy_hnd( p, &r_u->handle ); - return WERR_BADFILE; - } + DEBUG(10,("_eventlog_open_eventlog: Size [%d]\n", elog_size( info ))); - sync_eventlog_params( info->logname ); - prune_eventlog( tdb_of( info->logname ) ); + sync_eventlog_params( info ); + prune_eventlog( info->tdb ); return WERR_OK; } /******************************************************************** + This call still needs some work ********************************************************************/ WERROR _eventlog_clear_eventlog( pipes_struct * p, EVENTLOG_Q_CLEAR_EVENTLOG * q_u, EVENTLOG_R_CLEAR_EVENTLOG * r_u ) { - EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle ); + EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); pstring backup_file_name; - pstrcpy( backup_file_name, "" ); + if ( !info ) + return WERR_BADFID; - if ( q_u->backupfile.string ) - unistr2_to_ascii( backup_file_name, q_u->backupfile.string, - sizeof( backup_file_name ) ); + pstrcpy( backup_file_name, "" ); + if ( q_u->backupfile.string ) { + rpcstr_pull( backup_file_name, q_u->backupfile.string->buffer, + sizeof( backup_file_name ), + q_u->backupfile.string->uni_str_len * 2, 0 ); + } - DEBUG( 10, + DEBUG( 8, ( "_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].", backup_file_name, info->logname ) ); - if ( !( clear_eventlog_hook( info, backup_file_name ) ) ) - return WERR_BADFILE; +#if 0 + /* close the current one, reinit */ + + tdb_close( info->tdb ); + + if ( !(info->tdb = elog_init_tdb( ttdb[i].tdbfname )) ) + return WERR_ACCESS_DENIED; +#endif return WERR_OK; } @@ -786,16 +643,7 @@ WERROR _eventlog_close_eventlog( pipes_struct * p, EVENTLOG_Q_CLOSE_EVENTLOG * q_u, EVENTLOG_R_CLOSE_EVENTLOG * r_u ) { - EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle ); - - if ( !( close_eventlog_hook( info ) ) ) - return WERR_BADFILE; - - if ( !( close_policy_hnd( p, &q_u->handle ) ) ) { - return WERR_BADFID; - } - - return WERR_OK; + return elog_close( p, &q_u->handle ); } /******************************************************************** @@ -805,56 +653,55 @@ WERROR _eventlog_read_eventlog( pipes_struct * p, EVENTLOG_Q_READ_EVENTLOG * q_u, EVENTLOG_R_READ_EVENTLOG * r_u ) { - EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle ); + EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); Eventlog_entry entry, *ee_new; uint32 num_records_read = 0; prs_struct *ps; int bytes_left, record_number; - TDB_CONTEXT *the_tdb; - + TDB_CONTEXT *tdb; info->flags = q_u->flags; ps = &p->out_data.rdata; - bytes_left = q_u->max_read_size; - the_tdb = tdb_of( info->logname ); - if ( !the_tdb ) { - /* todo handle the error */ - + tdb = info->tdb; + if ( !tdb ) { + return WERR_EVENTLOG_FILE_CORRUPT; } - /* DEBUG(8,("Bytes left is %d\n",bytes_left)); */ + /* DEBUG(8,("Bytes left is %d\n",bytes_left)); */ record_number = q_u->offset; while ( bytes_left > 0 ) { if ( get_eventlog_record - ( ps, the_tdb, record_number, &entry ) ) { + ( ps, tdb, record_number, &entry ) ) { DEBUG( 8, ( "Retrieved record %d\n", record_number ) ); + /* Now see if there is enough room to add */ - if ( ( ee_new = - read_package_entry( ps, q_u, r_u, - &entry ) ) == NULL ) { + ee_new = read_package_entry( ps, q_u, r_u,&entry ); + if ( !ee_new ) return WERR_NOMEM; - } - if ( r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size ) { r_u->bytes_in_next_record = ee_new->record.length; + /* response would be too big to fit in client-size buffer */ + bytes_left = 0; break; } + add_record_to_resp( r_u, ee_new ); bytes_left -= ee_new->record.length; ZERO_STRUCT( entry ); num_records_read = r_u->num_records - num_records_read; + DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total of [%d] records using [%d] bytes out of a max of [%d].\n", num_records_read, r_u->num_records, @@ -866,13 +713,12 @@ WERROR _eventlog_read_eventlog( pipes_struct * p, } - if ( info->flags & EVENTLOG_FORWARDS_READ ) { + if ( info->flags & EVENTLOG_FORWARDS_READ ) record_number++; - } else { + else record_number--; - } - } + return WERR_OK; } @@ -883,7 +729,7 @@ WERROR _eventlog_get_oldest_entry( pipes_struct * p, EVENTLOG_Q_GET_OLDEST_ENTRY * q_u, EVENTLOG_R_GET_OLDEST_ENTRY * r_u ) { - EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle ); + EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); if ( !( get_oldest_entry_hook( info ) ) ) return WERR_BADFILE; @@ -900,7 +746,7 @@ WERROR _eventlog_get_num_records( pipes_struct * p, EVENTLOG_Q_GET_NUM_RECORDS * q_u, EVENTLOG_R_GET_NUM_RECORDS * r_u ) { - EventlogInfo *info = find_eventlog_info_by_hnd( p, &q_u->handle ); + EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); if ( !( get_num_records_hook( info ) ) ) return WERR_BADFILE; diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c index 1ad058b5199..2dd8b821d81 100644 --- a/source/rpc_server/srv_netlog_nt.c +++ b/source/rpc_server/srv_netlog_nt.c @@ -26,8 +26,6 @@ #include "includes.h" -extern struct dcinfo last_dcinfo; -extern BOOL server_auth2_negotiated; extern userdom_struct current_user_info; #undef DBGC_CLASS @@ -438,10 +436,14 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u) fstrcpy(p->dc->mach_acct, mach_acct); fstrcpy(p->dc->remote_machine, remote_machine); + fstrcpy(p->dc->domain, lp_workgroup() ); - server_auth2_negotiated = True; p->dc->authenticated = True; - last_dcinfo = *p->dc; + + /* Store off the state so we can continue after client disconnect. */ + become_root(); + secrets_store_schannel_session_info(p->mem_ctx, p->dc); + unbecome_root(); return r_u->status; } diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c index ba6d9704e80..1ca52108428 100644 --- a/source/rpc_server/srv_pipe.c +++ b/source/rpc_server/srv_pipe.c @@ -36,15 +36,6 @@ extern struct current_user current_user; #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV -/************************************************************* - HACK Alert! - We need to transfer the session key from one rpc bind to the - next. This is the way the netlogon schannel works. -**************************************************************/ - -struct dcinfo last_dcinfo; -BOOL server_auth2_negotiated = False; - static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth) { AUTH_NTLMSSP_STATE *a = auth->a_u.auth_ntlmssp_state; @@ -1218,15 +1209,23 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH auth_info; RPC_AUTH_SCHANNEL_NEG neg; RPC_AUTH_VERIFIER auth_verifier; + BOOL ret; + struct dcinfo stored_dcinfo; uint32 flags; - if (!server_auth2_negotiated) { - DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n")); + if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) { + DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n")); return False; } - if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) { - DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n")); + ZERO_STRUCT(stored_dcinfo); + + become_root(); + ret = secrets_restore_schannel_session_info(p->mem_ctx, neg.myname, &stored_dcinfo); + unbecome_root(); + + if (!ret) { + DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n")); return False; } @@ -1236,7 +1235,7 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, } memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key)); - memcpy(p->auth.a_u.schannel_auth->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key)); + memcpy(p->auth.a_u.schannel_auth->sess_key, stored_dcinfo.sess_key, sizeof(stored_dcinfo.sess_key)); p->auth.a_u.schannel_auth->seq_num = 0; @@ -1253,7 +1252,7 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, if (!p->dc) { return False; } - *p->dc = last_dcinfo; + *p->dc = stored_dcinfo; init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { diff --git a/source/rpc_server/srv_reg_nt.c b/source/rpc_server/srv_reg_nt.c index 0ba3e04b99f..35a060c38e3 100644 --- a/source/rpc_server/srv_reg_nt.c +++ b/source/rpc_server/srv_reg_nt.c @@ -43,7 +43,7 @@ static struct generic_mapping reg_generic_map = static void free_regkey_info(void *ptr) { - TALLOC_FREE( ptr ); + regkey_close_internal( (REGISTRY_KEY*)ptr ); } /****************************************************************** @@ -99,10 +99,9 @@ static WERROR open_registry_key( pipes_struct *p, POLICY_HND *hnd, if ( !create_policy_hnd( p, hnd, free_regkey_info, *keyinfo ) ) { result = WERR_BADFILE; - TALLOC_FREE( *keyinfo ); + regkey_close_internal( *keyinfo ); } - return result; } @@ -332,7 +331,7 @@ WERROR _reg_query_value(pipes_struct *p, REG_Q_QUERY_VALUE *q_u, REG_R_QUERY_VAL DEBUG(5,("_reg_info: looking up value: [%s]\n", name)); - if ( !(regvals = TALLOC_P( p->mem_ctx, REGVAL_CTR )) ) + if ( !(regvals = TALLOC_ZERO_P( p->mem_ctx, REGVAL_CTR )) ) return WERR_NOMEM; /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */ @@ -537,6 +536,22 @@ WERROR _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE status = WERR_NO_MORE_ITEMS; goto done; } + +#if 0 /* JERRY TEST CODE */ + if ( val->type == REG_MULTI_SZ ) { + char **str; + int num_strings = regval_convert_multi_sz( (uint16*)regval_data_p(val), regval_size(val), &str ); + uint16 *buffer; + size_t buf_size; + + + if ( num_strings ) + buf_size = regval_build_multi_sz( str, &buffer ); + + TALLOC_FREE( str ); + TALLOC_FREE( buffer ); + } +#endif DEBUG(10,("_reg_enum_value: retrieved value named [%s]\n", val->valuename)); diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c index b69f03a3a28..26a691e9b40 100644 --- a/source/rpc_server/srv_samr_nt.c +++ b/source/rpc_server/srv_samr_nt.c @@ -2424,6 +2424,32 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A } /******************************************************************* + set_user_info_7 + ********************************************************************/ +static NTSTATUS set_user_info_7(const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd) +{ + fstring new_name; + NTSTATUS rc; + + if (id7 == NULL) { + DEBUG(5, ("set_user_info_7: NULL id7\n")); + pdb_free_sam(&pwd); + return NT_STATUS_ACCESS_DENIED; + } + + if(!rpcstr_pull(new_name, id7->uni_name.buffer, sizeof(new_name), id7->uni_name.uni_str_len*2, 0)) { + DEBUG(5, ("set_user_info_7: failed to get new username\n")); + pdb_free_sam(&pwd); + return NT_STATUS_ACCESS_DENIED; + } + + rc = pdb_rename_sam_account(pwd, new_name); + + pdb_free_sam(&pwd); + return rc; +} + +/******************************************************************* set_user_info_16 ********************************************************************/ @@ -2924,6 +2950,9 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_ /* ok! user info levels (lots: see MSDEV help), off we go... */ switch (switch_value) { + case 7: + r_u->status = set_user_info_7(ctr->info.id7, pwd); + break; case 16: if (!set_user_info_16(ctr->info.id16, pwd)) r_u->status = NT_STATUS_ACCESS_DENIED; diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c index 9643b2a7249..1022cb960d3 100644 --- a/source/rpc_server/srv_srvsvc_nt.c +++ b/source/rpc_server/srv_srvsvc_nt.c @@ -2275,31 +2275,18 @@ WERROR _srv_net_disk_enum(pipes_struct *p, SRV_Q_NET_DISK_ENUM *q_u, SRV_R_NET_D WERROR _srv_net_name_validate(pipes_struct *p, SRV_Q_NET_NAME_VALIDATE *q_u, SRV_R_NET_NAME_VALIDATE *r_u) { - int snum; fstring share_name; - r_u->status=WERR_OK; - - switch(q_u->type) { - + switch ( q_u->type ) { case 0x9: - - /*check if share name is ok*/ - /*also check if we already have a share with this name*/ + /* check if share name is ok. + TODO: check for invalid characters in name? */ unistr2_to_ascii(share_name, &q_u->uni_name, sizeof(share_name)); - snum = find_service(share_name); - - /* Share already exists. */ - if (snum >= 0) - r_u->status = WERR_ALREADY_EXISTS; break; - default: - /*unsupported type*/ - r_u->status = WERR_UNKNOWN_LEVEL; - break; + return WERR_UNKNOWN_LEVEL; } - return r_u->status; + return WERR_OK; } diff --git a/source/script/installman.sh b/source/script/installman.sh index 9cd91008392..6278012635f 100755 --- a/source/script/installman.sh +++ b/source/script/installman.sh @@ -13,7 +13,7 @@ if [ $# -ge 4 ] ; then GROFF=$4 # sh cmd line, including options fi -if test ! -d ../docs/manpages; then +if test ! -d $SRCDIR../docs/manpages; then echo "No manpages present. SVN development version maybe?" exit 0 fi diff --git a/source/services/services_db.c b/source/services/services_db.c index 7c75d413528..9cd9ba8d83f 100644 --- a/source/services/services_db.c +++ b/source/services/services_db.c @@ -175,7 +175,7 @@ static BOOL read_init_file( const char *servicename, struct rcinit_file_informat struct rcinit_file_information *info; pstring filepath, str; XFILE *f; - char *p, *s; + char *p; if ( !(info = TALLOC_ZERO_P( NULL, struct rcinit_file_information ) ) ) return False; @@ -189,7 +189,7 @@ static BOOL read_init_file( const char *servicename, struct rcinit_file_informat return False; } - while ( (s = x_fgets( str, sizeof(str)-1, f )) != NULL ) { + while ( (x_fgets( str, sizeof(str)-1, f )) != NULL ) { /* ignore everything that is not a full line comment starting with a '#' */ @@ -325,6 +325,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, if ( !(svc_subkeys = TALLOC_ZERO_P( key_service, REGSUBKEY_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); + regkey_close_internal( key_service ); return; } @@ -336,6 +337,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, if ( !(values = TALLOC_ZERO_P( key_service, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); + regkey_close_internal( key_service ); return; } @@ -344,7 +346,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* cleanup the service key*/ - TALLOC_FREE( key_service ); + regkey_close_internal( key_service ); /* now add the security descriptor */ @@ -354,17 +356,19 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", path, dos_errstr(wresult))); + regkey_close_internal( key_secdesc ); return; } if ( !(values = TALLOC_ZERO_P( key_secdesc, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); + regkey_close_internal( key_secdesc ); return; } if ( !(sd = construct_service_sd(key_secdesc)) ) { DEBUG(0,("add_new_svc_name: Failed to create default sec_desc!\n")); - TALLOC_FREE( key_secdesc ); + regkey_close_internal( key_secdesc ); return; } @@ -381,7 +385,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, /* finally cleanup the Security key */ prs_mem_free( &ps ); - TALLOC_FREE( key_secdesc ); + regkey_close_internal( key_secdesc ); return; } @@ -396,7 +400,6 @@ void svcctl_init_keys( void ) REGSUBKEY_CTR *subkeys; REGISTRY_KEY *key = NULL; WERROR wresult; - BOOL new_services = False; /* bad mojo here if the lookup failed. Should not happen */ @@ -413,6 +416,7 @@ void svcctl_init_keys( void ) if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) { DEBUG(0,("init_services_keys: talloc() failed!\n")); + regkey_close_internal( key ); return; } @@ -432,11 +436,9 @@ void svcctl_init_keys( void ) /* Add the new service key and initialize the appropriate values */ add_new_svc_name( key, subkeys, service_list[i] ); - - new_services = True; } - TALLOC_FREE( key ); + regkey_close_internal( key ); /* initialize the control hooks */ @@ -474,7 +476,7 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("add_new_svc_name: talloc() failed!\n")); - TALLOC_FREE( key ); + regkey_close_internal( key ); return NULL; } @@ -483,7 +485,7 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * if ( !(val = regval_ctr_getvalue( values, "Security" )) ) { DEBUG(6,("svcctl_get_secdesc: constructing default secdesc for service [%s]\n", name)); - TALLOC_FREE( key ); + regkey_close_internal( key ); return construct_service_sd( ctx ); } @@ -494,7 +496,7 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * prs_give_memory( &ps, regval_data_p(val), regval_size(val), False ); if ( !sec_io_desc("sec_desc", &sd, &ps, 0 ) ) { - TALLOC_FREE( key ); + regkey_close_internal( key ); return construct_service_sd( ctx ); } @@ -503,7 +505,7 @@ SEC_DESC* svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * /* finally cleanup the Security key */ prs_mem_free( &ps ); - TALLOC_FREE( key ); + regkey_close_internal( key ); return ret_sd; } @@ -532,7 +534,7 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token ) if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n")); - TALLOC_FREE( key ); + regkey_close_internal( key ); goto fail; } @@ -543,12 +545,13 @@ char* svcctl_lookup_dispname( const char *name, NT_USER_TOKEN *token ) rpcstr_pull( display_name, regval_data_p(val), sizeof(display_name), regval_size(val), 0 ); - TALLOC_FREE( key ); + regkey_close_internal( key ); return display_name; fail: /* default to returning the service name */ + regkey_close_internal( key ); fstrcpy( display_name, name ); return display_name; } @@ -577,7 +580,7 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) if ( !(values = TALLOC_ZERO_P( key, REGVAL_CTR )) ) { DEBUG(0,("svcctl_lookup_dispname: talloc() failed!\n")); - TALLOC_FREE( key ); + regkey_close_internal( key ); return NULL; } @@ -588,7 +591,7 @@ char* svcctl_lookup_description( const char *name, NT_USER_TOKEN *token ) else rpcstr_pull( description, regval_data_p(val), sizeof(description), regval_size(val), 0 ); - TALLOC_FREE( key ); + regkey_close_internal( key ); return description; } @@ -616,13 +619,13 @@ REGVAL_CTR* svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token ) if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) { DEBUG(0,("svcctl_fetch_regvalues: talloc() failed!\n")); - TALLOC_FREE( key ); + regkey_close_internal( key ); return NULL; } fetch_reg_values( key, values ); - TALLOC_FREE( key ); + regkey_close_internal( key ); return values; } diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c index efbd5f04cb9..fec148b8e63 100644 --- a/source/smbd/dosmode.c +++ b/source/smbd/dosmode.c @@ -129,14 +129,19 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL c uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) { int result = 0; + enum mapreadonly_options ro_opts = (enum mapreadonly_options)lp_map_readonly(SNUM(conn)); - if (lp_acl_check_permissions(SNUM(conn))) { + if (ro_opts == MAP_READONLY_YES) { + /* Original Samba method - map inverse of user "w" bit. */ + if ((sbuf->st_mode & S_IWUSR) == 0) { + result |= aRONLY; + } + } else if (ro_opts == MAP_READONLY_PERMISSIONS) { + /* Check actual permissions for read-only. */ if (!can_write_to_file(conn, path, sbuf)) { result |= aRONLY; } - } else if ((sbuf->st_mode & S_IWUSR) == 0) { - result |= aRONLY; - } + } /* Else never set the readonly bit. */ if (MAP_ARCHIVE(conn) && ((sbuf->st_mode & S_IXUSR) != 0)) result |= aARCH; diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c index d4f0167a5f6..91942bf028f 100644 --- a/source/smbd/negprot.c +++ b/source/smbd/negprot.c @@ -167,7 +167,7 @@ static int reply_lanman2(char *inbuf, char *outbuf) Generate the spnego negprot reply blob. Return the number of bytes used. ****************************************************************************/ -static int negprot_spnego(char *p) +static int negprot_spnego(char *p, uint8 *pkeylen) { DATA_BLOB blob; nstring dos_name; @@ -177,7 +177,6 @@ static int negprot_spnego(char *p) OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; - const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; int len; global_spnego_negotiated = True; @@ -198,20 +197,23 @@ static int negprot_spnego(char *p) } #endif -#if 0 /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all - we can't do this until we teach our sesssion setup parser to know - about raw NTLMSSP (clients send no ASN.1 wrapping if we do this) + OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know + about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)" + + Our sessionsetup code now handles raw NTLMSSP connects, so we can go + back to doing what W2K3 does here. This is needed to make PocketPC 2003 + CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133 + for details. JRA. + */ - if (lp_security() != SEC_ADS) { + + if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { memcpy(p, guid, 16); + *pkeylen = 0; return 16; - } -#endif - if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { - blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE"); } else { fstring myname; char *host_princ_s = NULL; @@ -223,6 +225,11 @@ static int negprot_spnego(char *p) } memcpy(p, blob.data, blob.length); len = blob.length; + if (len > 256) { + DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len)); + len = 255; + } + *pkeylen = len; data_blob_free(&blob); return len; } @@ -323,16 +330,17 @@ static int reply_nt1(char *inbuf, char *outbuf) /* note that we do not send a challenge at all if we are using plaintext */ get_challenge(p); - SSVALS(outbuf,smb_vwv16+1,8); + SCVAL(outbuf,smb_vwv16+1,8); p += 8; } p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_UNICODE|STR_TERMINATE|STR_NOALIGN); DEBUG(3,("not using SPNEGO\n")); } else { - int len = negprot_spnego(p); + uint8 keylen; + int len = negprot_spnego(p, &keylen); - SSVALS(outbuf,smb_vwv16+1,len); + SCVAL(outbuf,smb_vwv16+1,keylen); p += len; DEBUG(3,("using SPNEGO\n")); } diff --git a/source/smbd/open.c b/source/smbd/open.c index a8fb8ed38f7..70687ff5805 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -628,7 +628,7 @@ static BOOL is_delete_request(files_struct *fsp) { static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp) { - int i, num_level2; + int i; struct share_mode_entry *exclusive = NULL; BOOL delay_it = False; BOOL have_level2 = False; @@ -638,8 +638,6 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp) return False; } - num_level2 = 0; - if (lck->num_share_modes == 0) { /* No files open at all: Directly grant whatever the client * wants. */ @@ -1715,7 +1713,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, if (ret == -1 && errno == ENOSYS) { errno = saved_errno; /* Ignore ENOSYS */ } else { - DEBUG(5, ("open_file_shared: failed to reset " + DEBUG(5, ("open_file_shared: reset " "attributes of file %s to 0%o\n", fname, (unsigned int)new_unx_mode)); ret = 0; /* Don't do the fchmod below. */ diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index f1c9426676a..ffb16983944 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -4149,16 +4149,13 @@ BOOL can_delete_file_in_directory(connection_struct *conn, const char *fname) /**************************************************************************** Actually emulate the in-kernel access checking for write access. We need this to successfully check for ability to write for dos filetimes. + Note this doesn't take into account share write permissions. ****************************************************************************/ BOOL can_write_to_file(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf) { int ret; - if (!CAN_WRITE(conn)) { - return False; - } - if (current_user.uid == 0 || conn->admin_user) { /* I'm sorry sir, I didn't know you were root... */ return True; @@ -4185,3 +4182,58 @@ BOOL can_write_to_file(connection_struct *conn, const char *fname, SMB_STRUCT_ST /* Finally check other write access. */ return (psbuf->st_mode & S_IWOTH) ? True : False; } + +/******************************************************************** + Pull the NT ACL from a file on disk or the OpenEventlog() access + check. Caller is responsible for freeing the returned security + descriptor via TALLOC_FREE(). This is designed for dealing with + user space access checks in smbd outside of the VFS. For example, + checking access rights in OpenEventlog(). + + Assume we are dealing with files (for now) +********************************************************************/ + +SEC_DESC* get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname) +{ + SEC_DESC *psd, *ret_sd; + size_t sd_size; + connection_struct conn; + files_struct finfo; + struct fd_handle fh; + fstring path; + pstring filename; + + ZERO_STRUCT( conn ); + conn.service = -1; + + if ( !(conn.mem_ctx = talloc_init( "novfs_get_nt_acl" )) ) { + DEBUG(0,("novfs_get_nt_acl: talloc() failed!\n")); + return NULL; + } + + fstrcpy( path, "/" ); + string_set(&conn.connectpath, path); + + if (!smbd_vfs_init(&conn)) { + DEBUG(0,("novfs_get_nt_acl: Unable to create a fake connection struct!\n")); + return NULL; + } + + ZERO_STRUCT( finfo ); + ZERO_STRUCT( fh ); + + finfo.fnum = -1; + finfo.conn = &conn; + finfo.fh = &fh; + finfo.fh->fd = -1; + pstrcpy( filename, fname ); + finfo.fsp_name = filename; + + sd_size = get_nt_acl( &finfo, DACL_SECURITY_INFORMATION, &psd ); + + ret_sd = dup_sec_desc( ctx, psd ); + + conn_free_internal( &conn ); + + return ret_sd; +} diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c index 008f212c2cb..8cb94bca3d8 100644 --- a/source/smbd/quotas.c +++ b/source/smbd/quotas.c @@ -414,7 +414,7 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB static int quotastat; -static int xdr_getquota_args(XDR *xdrsp, struct getquota_args *args) +static int my_xdr_getquota_args(XDR *xdrsp, struct getquota_args *args) { if (!xdr_string(xdrsp, &args->gqa_pathp, RQ_PATHLEN )) return(0); @@ -423,7 +423,7 @@ static int xdr_getquota_args(XDR *xdrsp, struct getquota_args *args) return (1); } -static int xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr) +static int my_xdr_getquota_rslt(XDR *xdrsp, struct getquota_rslt *gqr) { if (!xdr_int(xdrsp, "astat)) { DEBUG(6,("nfs_quotas: Status bad or zero\n")); @@ -493,7 +493,7 @@ static BOOL nfs_quotas(char *nfspath, uid_t euser_id, SMB_BIG_UINT *bsize, SMB_B clnt->cl_auth = authunix_create_default(); DEBUG(9,("nfs_quotas: auth_success\n")); - clnt_stat=clnt_call(clnt, RQUOTAPROC_GETQUOTA, xdr_getquota_args, (caddr_t)&args, xdr_getquota_rslt, (caddr_t)&gqr, timeout); + clnt_stat=clnt_call(clnt, RQUOTAPROC_GETQUOTA, my_xdr_getquota_args, (caddr_t)&args, my_xdr_getquota_rslt, (caddr_t)&gqr, timeout); if (clnt_stat != RPC_SUCCESS) { DEBUG(9,("nfs_quotas: clnt_call fail\n")); diff --git a/source/smbd/server.c b/source/smbd/server.c index 8310b408d07..1bf9dbc374a 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -803,7 +803,7 @@ void build_options(BOOL screen); reopen_logs(); DEBUG(0,( "smbd version %s started.\n", SAMBA_VERSION_STRING)); - DEBUGADD(0,( "Copyright Andrew Tridgell and the Samba Team 1992-2004\n")); + DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) ); DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index f0b7812a1e0..cfb630a5727 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -2346,7 +2346,6 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned fsp.conn = conn; fsp.fnum = -1; - fsp.fh->fd = -1; /* access check */ if (current_user.uid != 0) { diff --git a/source/utils/eventlogadm.c b/source/utils/eventlogadm.c new file mode 100644 index 00000000000..bb3c1bc9bbc --- /dev/null +++ b/source/utils/eventlogadm.c @@ -0,0 +1,166 @@ +/* + * Samba Unix/Linux SMB client utility + * Write Eventlog records to a tdb + * + * Copyright (C) Brian Moran 2005. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_UTIL_EVENTLOG + +Eventlog_entry ee; + +extern int optind; +extern char *optarg; + +int opt_debug = 0; + +static void usage( char *s ) +{ + printf( "\nUsage: %s [-d] [-h] <Eventlog Name>\n", s ); + printf( "\t-d\tturn debug on\n" ); + printf( "\t-h\tdisplay help\n\n" ); +} + +static void display_eventlog_names( void ) +{ + const char **elogs; + int i; + + elogs = lp_eventlog_list( ); + printf( "Active eventlog names (from smb.conf):\n" ); + printf( "--------------------------------------\n" ); + for ( i = 0; elogs[i]; i++ ) { + printf( "\t%s\n", elogs[i] ); + } +} + +int main( int argc, char *argv[] ) +{ + FILE *f1; + + /* fixed constants are bad bad bad */ + pstring linein; + BOOL is_eor; + int pret, opt; + int rcnum; + char *argfname, *exename; + char *tdbname; + + + TDB_CONTEXT *elog_tdb; + + opt_debug = 0; /* todo set this from getopts */ + + + lp_load( dyn_CONFIGFILE, True, False, False ); + + exename = argv[0]; + + while ( ( opt = getopt( argc, argv, "dh" ) ) != -1 ) { + switch ( opt ) { + case 'h': + usage( argv[0] ); + display_eventlog_names( ); + exit( 0 ); + break; + + case 'd': + opt_debug = 1; + break; + } + } + + argc -= optind; + argv += optind; + + if ( argc < 1 ) { + usage( exename ); + exit( 1 ); + } + + + + f1 = stdin; + + if ( !f1 ) { + printf( "Can't open STDIN\n" ); + return -1; + } + + + if ( opt_debug ) { + printf( "Starting %s for eventlog [%s]\n", exename, argv[0] ); + display_eventlog_names( ); + } + + argfname = argv[0]; + + if ( !(elog_tdb = elog_open_tdb( argfname ) ) ) { + printf( "can't open the eventlog TDB (%s)\n", tdbname ); + return -1; + } + + ZERO_STRUCT( ee ); /* MUST initialize between records */ + + while ( !feof( f1 ) ) { + fgets( linein, sizeof( linein ) - 1, f1 ); + linein[strlen( linein ) - 1] = 0; /* whack the line delimiter */ + + if ( opt_debug ) + printf( "Read line [%s]\n", linein ); + + is_eor = False; + + pret = parse_logentry( ( char * ) &linein, &ee, &is_eor ); + + if ( is_eor ) { + fixup_eventlog_entry( &ee ); + + if ( opt_debug ) + printf( "record number [%d], tg [%d] , tw [%d]\n", + ee.record.record_number, + ee.record.time_generated, + ee.record.time_written ); + + if ( ee.record.time_generated != 0 ) { + + /* printf("Writing to the event log\n"); */ + + rcnum = write_eventlog_tdb( elog_tdb, &ee ); + if ( !rcnum ) { + printf( "Can't write to the event log\n" ); + } else { + if ( opt_debug ) + printf( "Wrote record %d\n", + rcnum ); + } + } else { + if ( opt_debug ) + printf( "<null record>\n" ); + } + ZERO_STRUCT( ee ); /* MUST initialize between records */ + } + } + + tdb_close( elog_tdb ); + + return 0; +} diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c index f1522ef1582..54af5c4df19 100644 --- a/source/utils/net_rpc.c +++ b/source/utils/net_rpc.c @@ -4610,9 +4610,9 @@ static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid, if (NT_STATUS_IS_OK(result)) { d_printf("\nShutdown of remote machine succeeded\n"); DEBUG(5,("Shutdown of remote machine succeeded\n")); - } else - DEBUG(0,("Shutdown of remote machine failed!\n")); - + } else { + DEBUG(1,("Shutdown of remote machine failed!\n")); + } return result; } @@ -4640,7 +4640,7 @@ static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid, int argc, const char **argv) { - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + WERROR result; const char *msg = "This machine will be shutdown shortly"; uint32 timeout = 20; #if 0 @@ -4676,16 +4676,19 @@ static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid, } /* create an entry */ - result = werror_to_ntstatus(rpccli_reg_shutdown(pipe_hnd, mem_ctx, msg, timeout, opt_reboot, opt_force)); + result = rpccli_reg_shutdown(pipe_hnd, mem_ctx, msg, timeout, opt_reboot, opt_force); - if (NT_STATUS_IS_OK(result)) { + if (W_ERROR_IS_OK(result)) { d_printf("\nShutdown of remote machine succeeded\n"); - DEBUG(5,("Shutdown of remote machine succeeded\n")); + } else { + d_printf("\nShutdown of remote machine failed\n"); + if (W_ERROR_EQUAL(result,WERR_MACHINE_LOCKED)) + d_printf("\nMachine locked, use -f switch to force\n"); + else + d_printf("\nresult was: %s\n", dos_errstr(result)); } - else - DEBUG(0,("Shutdown of remote machine failed!\n")); - return result; + return werror_to_ntstatus(result); } /** @@ -4703,13 +4706,14 @@ static int rpc_shutdown(int argc, const char **argv) int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0, rpc_init_shutdown_internals, argc, argv); - if (rc == 0) - return rc; - DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n")); + if (rc) { + DEBUG(1, ("initshutdown pipe failed, trying winreg pipe\n")); + rc = run_rpc_command(NULL, PI_WINREG, 0, + rpc_reg_shutdown_internals, argc, argv); + } - return run_rpc_command(NULL, PI_WINREG, 0, rpc_reg_shutdown_internals, - argc, argv); + return rc; } /*************************************************************************** diff --git a/source/wrepld/server.c b/source/wrepld/server.c index 59708dc8bac..5ac78a24745 100644 --- a/source/wrepld/server.c +++ b/source/wrepld/server.c @@ -590,8 +590,8 @@ static void process(void) reopen_logs(); - DEBUG(1,( "wrepld version %s started.\n", SAMBA_VERSION_STRING)); - DEBUGADD(1,( "Copyright Andrew Tridgell and the Samba Team 1992-2004\n")); + DEBUG(0,( "wrepld version %s started.\n", SAMBA_VERSION_STRING)); + DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) ); DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); |