mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
r10656: BIG merge from trunk. Features not copied over
* \PIPE\unixinfo
* winbindd's {group,alias}membership new functions
* winbindd's lookupsids() functionality
* swat (trunk changes to be reverted as per discussion with Deryck)
(This used to be commit 939c3cb5d7
)
This commit is contained in:
parent
4a2cc231d2
commit
54abd2aa66
@ -389,16 +389,68 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags'
|
||||
EQUALITY caseIgnoreIA5Match
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.56 NAME 'sambaAccountPolicyName'
|
||||
DESC 'Account Policy Name'
|
||||
EQUALITY caseIgnoreMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255} SINGLE-VALUE )
|
||||
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.57 NAME 'sambaAccountPolicyValue'
|
||||
DESC 'Account Policy Value'
|
||||
# "min password length"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.58 NAME 'sambaMinPwdLength'
|
||||
DESC 'Minimal password length (default: 5)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
# "password history"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.59 NAME 'sambaPwdHistoryLength'
|
||||
DESC 'Length of Password History Entries (default: 0 => off)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
# "user must logon to change password"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.60 NAME 'sambaLogonToChgPwd'
|
||||
DESC 'Force Users to logon for password change (default: 0 => off, 2 => on)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
# "maximum password age"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.61 NAME 'sambaMaxPwdAge'
|
||||
DESC 'Maximum password age, in seconds (default: -1 => never expire passwords)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
# "minimum password age"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.62 NAME 'sambaMinPwdAge'
|
||||
DESC 'Minimum password age, in seconds (default: 0 => allow immediate password change)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
# "lockout duration"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.63 NAME 'sambaLockoutDuration'
|
||||
DESC 'Lockout duration in minutes (default: 30, -1 => forever)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
# "reset count minutes"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.64 NAME 'sambaLockoutObservationWindow'
|
||||
DESC 'Reset time after lockout in minutes (default: 30)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
# "bad lockout attempt"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.65 NAME 'sambaLockoutThreshold'
|
||||
DESC 'Lockout users after bad logon attempts (default: 0 => off)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
# "disconnect time"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.66 NAME 'sambaForceLogoff'
|
||||
DESC 'Disconnect Users outside logon hours (default: -1 => off, 0 => on)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
# "refuse machine password change"
|
||||
attributetype ( 1.3.6.1.4.1.7165.2.1.67 NAME 'sambaRefuseMachinePwdChange'
|
||||
DESC 'Allow Machine Password changes (default: 0 => off)'
|
||||
EQUALITY integerMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
|
||||
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
## objectClasses used by Samba 3.0 schema ##
|
||||
@ -448,7 +500,11 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.5 NAME 'sambaDomain' SUP top STRUCTURAL
|
||||
MUST ( sambaDomainName $
|
||||
sambaSID )
|
||||
MAY ( sambaNextRid $ sambaNextGroupRid $ sambaNextUserRid $
|
||||
sambaAlgorithmicRidBase ) )
|
||||
sambaAlgorithmicRidBase $
|
||||
sambaMinPwdLength $ sambaPwdHistoryLength $ sambaLogonToChgPwd $
|
||||
sambaMaxPwdAge $ sambaMinPwdAge $
|
||||
sambaLockoutDuration $ sambaLockoutObservationWindow $ sambaLockoutThreshold $
|
||||
sambaForceLogoff $ sambaRefuseMachinePwdChange ))
|
||||
|
||||
##
|
||||
## used for idmap_ldap module
|
||||
@ -488,9 +544,3 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURA
|
||||
## DESC 'Samba Privilege'
|
||||
## MUST ( sambaSID )
|
||||
## MAY ( sambaPrivilegeList ) )
|
||||
|
||||
objectclass ( 1.3.6.1.4.1.7165.2.2.15 NAME 'sambaAccountPolicy' SUP top STRUCTURAL
|
||||
DESC 'Samba Account Policy'
|
||||
MUST ( sambaAccountPolicyName $ sambaAccountPolicyValue )
|
||||
MAY ( description ) )
|
||||
|
||||
|
@ -63,6 +63,7 @@ RPCLIBDIR = $(LIBDIR)/rpc
|
||||
IDMAPLIBDIR = $(LIBDIR)/idmap
|
||||
CHARSETLIBDIR = $(LIBDIR)/charset
|
||||
AUTHLIBDIR = $(LIBDIR)/auth
|
||||
CONFIGLIBDIR = $(LIBDIR)/config
|
||||
CONFIGDIR = @configdir@
|
||||
VARDIR = @localstatedir@
|
||||
MANDIR = @mandir@
|
||||
@ -101,8 +102,7 @@ LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@
|
||||
LIBSMBSHAREMODES_MAJOR=0
|
||||
LIBSMBSHAREMODES_MINOR=1
|
||||
|
||||
|
||||
FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) -I$(srcdir)/tdb
|
||||
FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/tdb @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir)
|
||||
FLAGS2 =
|
||||
FLAGS3 =
|
||||
FLAGS4 =
|
||||
@ -199,12 +199,12 @@ LIB_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
|
||||
lib/talloc.o lib/substitute.o lib/fsusage.o \
|
||||
lib/ms_fnmatch.o lib/select.o lib/messages.o \
|
||||
lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
|
||||
lib/md5.o lib/hmacmd5.o lib/iconv.o \
|
||||
lib/md5.o lib/hmacmd5.o lib/arc4.o lib/iconv.o \
|
||||
nsswitch/wb_client.o $(WBCOMMON_OBJ) \
|
||||
lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \
|
||||
lib/pam_errors.o intl/lang_tdb.o \
|
||||
lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
|
||||
lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ \
|
||||
lib/privileges.o lib/secdesc.o lib/secace.o lib/secacl.o @SOCKWRAP@
|
||||
lib/secdesc.o lib/secace.o lib/secacl.o @SOCKWRAP@
|
||||
|
||||
LIB_DUMMY_OBJ = lib/dummysmbd.o lib/dummyroot.o
|
||||
LIB_NONSMBD_OBJ = $(LIB_OBJ) $(LIB_DUMMY_OBJ)
|
||||
@ -262,7 +262,7 @@ REGOBJS_OBJ = registry/reg_objects.o
|
||||
|
||||
REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \
|
||||
registry/reg_db.o registry/reg_eventlog.o registry/reg_shares.o \
|
||||
registry/reg_util.o registry/reg_dynamic.o
|
||||
registry/reg_util.o registry/reg_dynamic.o registry/reg_perfcount.o
|
||||
|
||||
RPC_LSA_OBJ = rpc_server/srv_lsa.o rpc_server/srv_lsa_nt.o
|
||||
|
||||
@ -282,7 +282,10 @@ RPC_SVC_OBJ = rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o
|
||||
RPC_WKS_OBJ = rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o
|
||||
|
||||
RPC_SVCCTL_OBJ = rpc_server/srv_svcctl.o rpc_server/srv_svcctl_nt.o \
|
||||
services/svc_spoolss.o services/svc_rcinit.o services/services_db.o
|
||||
services/svc_spoolss.o services/svc_rcinit.o services/services_db.o \
|
||||
services/svc_netlogon.o services/svc_winreg.o
|
||||
|
||||
RPC_NTSVCS_OBJ = rpc_server/srv_ntsvcs.o rpc_server/srv_ntsvcs_nt.o
|
||||
|
||||
RPC_DFS_OBJ = rpc_server/srv_dfs.o rpc_server/srv_dfs_nt.o
|
||||
|
||||
@ -308,7 +311,8 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \
|
||||
rpc_parse/parse_spoolss.o rpc_parse/parse_dfs.o \
|
||||
rpc_parse/parse_echo.o rpc_parse/parse_shutdown.o \
|
||||
rpc_parse/parse_svcctl.o \
|
||||
rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o $(REGOBJS_OBJ)
|
||||
rpc_parse/parse_eventlog.o rpc_parse/parse_buffer.o \
|
||||
rpc_parse/parse_ntsvcs.o $(REGOBJS_OBJ)
|
||||
|
||||
RPC_CLIENT_OBJ = rpc_client/cli_pipe.o
|
||||
|
||||
@ -320,7 +324,7 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
|
||||
passdb/util_sam_sid.o passdb/pdb_compat.o \
|
||||
passdb/lookup_sid.o \
|
||||
passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o \
|
||||
lib/system_smbd.o
|
||||
lib/system_smbd.o lib/account_pol.o lib/privileges.o
|
||||
|
||||
XML_OBJ = passdb/pdb_xml.o
|
||||
MYSQL_OBJ = passdb/pdb_mysql.o
|
||||
@ -414,7 +418,6 @@ PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \
|
||||
printing/print_iprint.o
|
||||
|
||||
PRINTBASE_OBJ = printing/notify.o printing/printing_db.o
|
||||
|
||||
PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o $(PRINTBASE_OBJ)
|
||||
|
||||
SMBD_OBJ = $(SMBD_OBJ_BASE) $(SMBD_OBJ_MAIN)
|
||||
@ -487,7 +490,8 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
|
||||
rpcclient/cmd_netlogon.o rpcclient/cmd_srvsvc.o \
|
||||
rpcclient/cmd_dfs.o rpcclient/cmd_reg.o \
|
||||
rpcclient/display_sec.o rpcclient/cmd_ds.o \
|
||||
rpcclient/cmd_echo.o rpcclient/cmd_shutdown.o
|
||||
rpcclient/cmd_echo.o rpcclient/cmd_shutdown.o \
|
||||
rpcclient/cmd_test.o
|
||||
|
||||
RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
|
||||
$(PARAM_OBJ) $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) \
|
||||
@ -521,11 +525,6 @@ LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
|
||||
|
||||
LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o tdb/tdb.o tdb/spinlock.o
|
||||
|
||||
CAC_OBJ = $(LIBSMBCLIENT_OBJ) \
|
||||
libmsrpc/libmsrpc.o libmsrpc/libmsrpc_internal.o \
|
||||
libmsrpc/cac_lsarpc.o libmsrpc/cac_winreg.o libmsrpc/cac_samr.o \
|
||||
libmsrpc/cac_svcctl.o
|
||||
|
||||
# This shared library is intended for linking with unit test programs
|
||||
# to test Samba internals. It's called libbigballofmud.so to
|
||||
# discourage casual usage.
|
||||
@ -561,7 +560,7 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
|
||||
$(LIBMSRPC_OBJ) $(IDMAP_OBJ) \
|
||||
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
|
||||
$(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(SERVER_MUTEX_OBJ) \
|
||||
$(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(PRINTERDB_OBJ) $(REGFIO_OBJ)
|
||||
$(AFS_OBJ) $(AFS_SETTOKEN_OBJ) $(REGFIO_OBJ)
|
||||
|
||||
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
|
||||
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ)
|
||||
@ -644,7 +643,8 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
|
||||
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) $(RPC_LSA_DS_OBJ) \
|
||||
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
|
||||
$(RPC_ECHO_OBJ) $(RPC_SVCCTL_OBJ) $(RPC_EVENTLOG_OBJ) $(SMBLDAP_OBJ) \
|
||||
$(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ)
|
||||
$(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ) \
|
||||
$(RPC_NTSVCS_OBJ)
|
||||
|
||||
WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) \
|
||||
$(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ)
|
||||
@ -655,8 +655,6 @@ PICOBJS = $(SMBWRAPPER_OBJ:.o=.@PICSUFFIX@)
|
||||
LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@)
|
||||
LIBSMBSHAREMODES_PICOBJS = $(LIBSMBSHAREMODES_OBJ:.o=.@PICSUFFIX@)
|
||||
|
||||
CAC_PICOBJS = $(CAC_OBJ:.o=.@PICSUFFIX@)
|
||||
|
||||
PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
|
||||
pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \
|
||||
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
|
||||
@ -715,7 +713,7 @@ NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \
|
||||
libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \
|
||||
libads/kerberos_verify.o $(SECRETS_OBJ) $(SERVER_MUTEX_OBJ) \
|
||||
libads/authdata.o $(RPC_PARSE_OBJ0) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
|
||||
$(SMBLDAP_OBJ) $(DOSERR_OBJ)
|
||||
$(SMBLDAP_OBJ) $(DOSERR_OBJ) rpc_parse/parse_net.o
|
||||
|
||||
######################################################################
|
||||
# now the rules...
|
||||
@ -760,9 +758,7 @@ wins : SHOWFLAGS @WINBIND_WINS_NSS@
|
||||
|
||||
modules: SHOWFLAGS proto_exists $(MODULES)
|
||||
|
||||
cac: SHOWFLAGS bin/libmsrpc.@SHLIBEXT@ bin/libmsrpc.a
|
||||
|
||||
everything: all libsmbclient debug2html smbfilter talloctort modules torture cac \
|
||||
everything: all libsmbclient debug2html smbfilter talloctort modules torture \
|
||||
$(EVERYTHING_PROGS)
|
||||
|
||||
.SUFFIXES:
|
||||
@ -1045,16 +1041,6 @@ bin/libsmbsharemodes.a: $(LIBSMBSHAREMODES_PICOBJS)
|
||||
@echo Linking libsmbsharemodes non-shared library $@
|
||||
@-$(AR) -rc $@ $(LIBSMBSHAREMODES_PICOBJS)
|
||||
|
||||
bin/libmsrpc.@SHLIBEXT@: $(CAC_PICOBJS)
|
||||
@echo Linking libmsrpc shared library $@
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(CAC_PICOBJS) $(LDFLAGS) $(LIBS) \
|
||||
@SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/libmsrpc.a: $(CAC_PICOBJS)
|
||||
@echo Linking libmsrpc non-shared library $@
|
||||
@-$(AR) -rc $@ $(CAC_PICOBJS)
|
||||
|
||||
|
||||
# This is probably wrong for anything other than the GNU linker.
|
||||
bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS)
|
||||
@echo Linking bigballofmud shared library $@
|
||||
@ -1091,6 +1077,11 @@ bin/librpc_svcctl.@SHLIBEXT@: $(RPC_SVCCTL_OBJ)
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SVCCTL_OBJ) -lc \
|
||||
@SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/librpc_ntsvcs.@SHLIBEXT@: $(RPC_NTSVCS_OBJ)
|
||||
@echo "Linking $@"
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_NTSVCS_OBJ) -lc \
|
||||
@SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/librpc_wkssvc.@SHLIBEXT@: $(RPC_WKS_OBJ)
|
||||
@echo "Linking $@"
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_WKS_OBJ) -lc \
|
||||
@ -1328,6 +1319,9 @@ bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ)
|
||||
@echo "Linking shared library $@"
|
||||
@$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_PICOOBJ) -lpam $(DYNEXP) $(LIBS) -lc $(LDAP_LIBS) $(KRB5LIBS)
|
||||
|
||||
bin/libmsrpc.a: $(LIBMSRPC_PICOBJ)
|
||||
@-$(AR) -rc $@ $(LIBMSRPC_PICOBJ)
|
||||
|
||||
bin/tdbbackup@EXEEXT@: $(TDBBACKUP_OBJ) bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(LIBS) $(TDBBACKUP_OBJ) @SOCKWRAP@
|
||||
@ -1346,6 +1340,9 @@ bin/t_strcmp@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strcmp.o
|
||||
bin/t_strstr@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strstr.o
|
||||
$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(LIBS) torture/t_strstr.o -L ./bin -lbigballofmud
|
||||
|
||||
bin/t_strappend@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_strappend.o
|
||||
$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) $(LIBS) torture/t_strappend.o -L ./bin -lbigballofmud
|
||||
|
||||
bin/t_stringoverflow@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_stringoverflow.o
|
||||
$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(DYNEXP) torture/t_stringoverflow.o -L./bin -lbigballofmud
|
||||
|
||||
@ -1634,7 +1631,7 @@ Makefile: $(srcdir)/Makefile.in config.status
|
||||
# These are called by the test suite and need to be built before
|
||||
# running it. For the time being we don't build all of BIN_PROGS,
|
||||
# because they're not all needed.
|
||||
check-programs: bin/t_strcmp bin/t_strstr bin/t_push_ucs2 bin/smbcontrol bin/t_snprintf
|
||||
# check-programs: bin/t_strcmp bin/t_strstr bin/t_push_ucs2 bin/smbcontrol bin/t_snprintf bin/t_asn1
|
||||
|
||||
#test: all
|
||||
# @if test -z "$(SMB4TORTURE)"; then \
|
||||
|
@ -235,7 +235,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
|
||||
|
||||
#ifdef DEBUG_PASSWORD
|
||||
DEBUG(100, ("user_info has passwords of length %d and %d\n",
|
||||
user_info->lm_resp.length, user_info->nt_resp.length));
|
||||
(int)user_info->lm_resp.length, (int)user_info->nt_resp.length));
|
||||
DEBUG(100, ("lm:\n"));
|
||||
dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length);
|
||||
DEBUG(100, ("nt:\n"));
|
||||
|
@ -41,14 +41,16 @@ extern BOOL global_machine_password_needs_changing;
|
||||
**/
|
||||
|
||||
static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
|
||||
const char *domain, const char *dc_name,
|
||||
const char *domain,
|
||||
const char *dc_name,
|
||||
struct in_addr dc_ip,
|
||||
const char *setup_creds_as,
|
||||
uint16 sec_chan,
|
||||
const unsigned char *trust_passwd,
|
||||
struct rpc_pipe_client **pipe_ret,
|
||||
BOOL *retry)
|
||||
{
|
||||
NTSTATUS result;
|
||||
struct rpc_pipe_client *netlogon_pipe = NULL;
|
||||
|
||||
*pipe_ret = NULL;
|
||||
|
||||
/* TODO: Send a SAMLOGON request to determine whether this is a valid
|
||||
logonserver. We can avoid a 30-second timeout if the DC is down
|
||||
@ -64,8 +66,9 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
|
||||
* ACCESS_DENIED errors if 2 auths are done from the same machine. JRA.
|
||||
*/
|
||||
|
||||
if (!grab_server_mutex(dc_name))
|
||||
if (!grab_server_mutex(dc_name)) {
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
/* Attempt connection */
|
||||
*retry = True;
|
||||
@ -95,36 +98,65 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
|
||||
* into account also. This patch from "Bjart Kvarme" <bjart.kvarme@usit.uio.no>.
|
||||
*/
|
||||
|
||||
if(cli_nt_session_open(*cli, PI_NETLOGON) == False) {
|
||||
DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
|
||||
machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
|
||||
cli_nt_session_close(*cli);
|
||||
cli_ulogoff(*cli);
|
||||
cli_shutdown(*cli);
|
||||
release_server_mutex();
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
/* open the netlogon pipe. */
|
||||
if (lp_client_schannel()) {
|
||||
/* We also setup the creds chain in the open_schannel call. */
|
||||
netlogon_pipe = cli_rpc_pipe_open_schannel(*cli, PI_NETLOGON,
|
||||
PIPE_AUTH_LEVEL_PRIVACY, domain, &result);
|
||||
} else {
|
||||
netlogon_pipe = cli_rpc_pipe_open_noauth(*cli, PI_NETLOGON, &result);
|
||||
}
|
||||
|
||||
fstr_sprintf((*cli)->mach_acct, "%s$", setup_creds_as);
|
||||
|
||||
/* This must be the remote domain (not ours) for schannel */
|
||||
|
||||
fstrcpy( (*cli)->domain, domain );
|
||||
|
||||
result = cli_nt_establish_netlogon(*cli, sec_chan, trust_passwd);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \
|
||||
%s. Error was : %s.\n", dc_name, nt_errstr(result)));
|
||||
cli_nt_session_close(*cli);
|
||||
cli_ulogoff(*cli);
|
||||
if(!netlogon_pipe) {
|
||||
DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
|
||||
machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
|
||||
cli_shutdown(*cli);
|
||||
release_server_mutex();
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!lp_client_schannel()) {
|
||||
/* We need to set up a creds chain on an unauthenticated netlogon pipe. */
|
||||
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
||||
uint32 sec_chan_type = 0;
|
||||
char machine_pwd[16];
|
||||
|
||||
if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
|
||||
DEBUG(0, ("connect_to_domain_password_server: could not fetch "
|
||||
"trust account password for domain '%s'\n",
|
||||
domain));
|
||||
cli_shutdown(*cli);
|
||||
release_server_mutex();
|
||||
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
}
|
||||
|
||||
result = rpccli_netlogon_setup_creds(netlogon_pipe,
|
||||
dc_name,
|
||||
domain,
|
||||
global_myname(),
|
||||
machine_pwd,
|
||||
sec_chan_type,
|
||||
&neg_flags);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
cli_shutdown(*cli);
|
||||
release_server_mutex();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if(!netlogon_pipe) {
|
||||
DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
|
||||
machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
|
||||
cli_shutdown(*cli);
|
||||
release_server_mutex();
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
/* We exit here with the mutex *locked*. JRA */
|
||||
|
||||
*pipe_ret = netlogon_pipe;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -139,14 +171,13 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
||||
const char *domain,
|
||||
uchar chal[8],
|
||||
auth_serversupplied_info **server_info,
|
||||
const char *dc_name, struct in_addr dc_ip,
|
||||
const char *setup_creds_as,
|
||||
uint16 sec_chan,
|
||||
unsigned char trust_passwd[16],
|
||||
time_t last_change_time)
|
||||
const char *dc_name,
|
||||
struct in_addr dc_ip)
|
||||
|
||||
{
|
||||
NET_USER_INFO_3 info3;
|
||||
struct cli_state *cli = NULL;
|
||||
struct rpc_pipe_client *netlogon_pipe = NULL;
|
||||
NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
|
||||
int i;
|
||||
BOOL retry = True;
|
||||
@ -162,8 +193,12 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
||||
/* rety loop for robustness */
|
||||
|
||||
for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) {
|
||||
nt_status = connect_to_domain_password_server(&cli, domain, dc_name,
|
||||
dc_ip, setup_creds_as, sec_chan, trust_passwd, &retry);
|
||||
nt_status = connect_to_domain_password_server(&cli,
|
||||
domain,
|
||||
dc_name,
|
||||
dc_ip,
|
||||
&netlogon_pipe,
|
||||
&retry);
|
||||
}
|
||||
|
||||
if ( !NT_STATUS_IS_OK(nt_status) ) {
|
||||
@ -181,13 +216,19 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
||||
* in the info3 structure.
|
||||
*/
|
||||
|
||||
nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx,
|
||||
NULL, user_info->smb_name.str, user_info->domain.str,
|
||||
user_info->wksta_name.str, chal, user_info->lm_resp,
|
||||
user_info->nt_resp, &info3);
|
||||
nt_status = rpccli_netlogon_sam_network_logon(netlogon_pipe,
|
||||
mem_ctx,
|
||||
dc_name, /* server name */
|
||||
user_info->smb_name.str, /* user name logging on. */
|
||||
user_info->domain.str, /* domain name */
|
||||
user_info->wksta_name.str, /* workstation name */
|
||||
chal, /* 8 byte challenge. */
|
||||
user_info->lm_resp, /* lanman 24 byte response */
|
||||
user_info->nt_resp, /* nt 24 byte response */
|
||||
&info3); /* info3 out */
|
||||
|
||||
/* let go as soon as possible so we avoid any potential deadlocks
|
||||
with winbind lookup up users or groups */
|
||||
/* Let go as soon as possible so we avoid any potential deadlocks
|
||||
with winbind lookup up users or groups. */
|
||||
|
||||
release_server_mutex();
|
||||
|
||||
@ -195,7 +236,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
||||
DEBUG(0,("domain_client_validate: unable to validate password "
|
||||
"for user %s in domain %s to Domain controller %s. "
|
||||
"Error was %s.\n", user_info->smb_name.str,
|
||||
user_info->domain.str, cli->srv_name_slash,
|
||||
user_info->domain.str, dc_name,
|
||||
nt_errstr(nt_status)));
|
||||
|
||||
/* map to something more useful */
|
||||
@ -203,32 +244,18 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
||||
nt_status = NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
} else {
|
||||
nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str,
|
||||
user_info->smb_name.str, domain, server_info, &info3);
|
||||
nt_status = make_server_info_info3(mem_ctx,
|
||||
user_info->internal_username.str,
|
||||
user_info->smb_name.str,
|
||||
domain,
|
||||
server_info,
|
||||
&info3);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* We don't actually need to do this - plus it fails currently with
|
||||
* NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to
|
||||
* send here. JRA.
|
||||
*/
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
if(cli_nt_logoff(&cli, &ctr) == False) {
|
||||
DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
|
||||
%s to Domain controller %s. Error was %s.\n", user, domain, dc_name, cli_errstr(&cli)));
|
||||
nt_status = NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/* Note - once the cli stream is shutdown the mem_ctx used
|
||||
to allocate the other_sids and gids structures has been deleted - so
|
||||
these pointers are no longer valid..... */
|
||||
|
||||
cli_nt_session_close(cli);
|
||||
cli_ulogoff(cli);
|
||||
cli_shutdown(cli);
|
||||
return nt_status;
|
||||
}
|
||||
@ -244,10 +271,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
|
||||
auth_serversupplied_info **server_info)
|
||||
{
|
||||
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
||||
unsigned char trust_passwd[16];
|
||||
time_t last_change_time;
|
||||
const char *domain = lp_workgroup();
|
||||
uint32 sec_channel_type = 0;
|
||||
fstring dc_name;
|
||||
struct in_addr dc_ip;
|
||||
|
||||
@ -273,26 +297,6 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the machine account password for our primary domain
|
||||
* No need to become_root() as secrets_init() is done at startup.
|
||||
*/
|
||||
|
||||
if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time, &sec_channel_type))
|
||||
{
|
||||
DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain));
|
||||
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
}
|
||||
|
||||
/* Test if machine password has expired and needs to be changed */
|
||||
if (lp_machine_password_timeout()) {
|
||||
if (last_change_time > 0 &&
|
||||
time(NULL) > (last_change_time +
|
||||
lp_machine_password_timeout())) {
|
||||
global_machine_password_needs_changing = True;
|
||||
}
|
||||
}
|
||||
|
||||
/* we need our DC to send the net_sam_logon() request to */
|
||||
|
||||
if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
|
||||
@ -301,9 +305,13 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
nt_status = domain_client_validate(mem_ctx, user_info, domain,
|
||||
(uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
|
||||
global_myname(), sec_channel_type,trust_passwd, last_change_time);
|
||||
nt_status = domain_client_validate(mem_ctx,
|
||||
user_info,
|
||||
domain,
|
||||
(uchar *)auth_context->challenge.data,
|
||||
server_info,
|
||||
dc_name,
|
||||
dc_ip);
|
||||
|
||||
return nt_status;
|
||||
}
|
||||
@ -357,7 +365,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
|
||||
/* No point is bothering if this is not a trusted domain.
|
||||
This return makes "map to guest = bad user" work again.
|
||||
The logic is that if we know nothing about the domain, that
|
||||
user is known to us and does not exist */
|
||||
user is not known to us and does not exist */
|
||||
|
||||
if ( !is_trusted_domain( user_info->domain.str ) )
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
@ -367,8 +375,8 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
|
||||
* No need to become_root() as secrets_init() is done at startup.
|
||||
*/
|
||||
|
||||
if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password, &sid, &last_change_time))
|
||||
{
|
||||
if (!secrets_fetch_trusted_domain_password(user_info->domain.str, &trust_password,
|
||||
&sid, &last_change_time)) {
|
||||
DEBUG(0, ("check_trustdomain_security: could not fetch trust account password for domain %s\n", user_info->domain.str));
|
||||
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
}
|
||||
@ -396,9 +404,13 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str,
|
||||
(uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
|
||||
lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time);
|
||||
nt_status = domain_client_validate(mem_ctx,
|
||||
user_info,
|
||||
user_info->domain.str,
|
||||
(uchar *)auth_context->challenge.data,
|
||||
server_info,
|
||||
dc_name,
|
||||
dc_ip);
|
||||
|
||||
return nt_status;
|
||||
}
|
||||
|
@ -114,13 +114,15 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state,
|
||||
return nt_status;
|
||||
}
|
||||
if (auth_ntlmssp_state->server_info->user_session_key.length) {
|
||||
DEBUG(10, ("Got NT session key of length %u\n", auth_ntlmssp_state->server_info->user_session_key.length));
|
||||
DEBUG(10, ("Got NT session key of length %u\n",
|
||||
(unsigned int)auth_ntlmssp_state->server_info->user_session_key.length));
|
||||
*user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
|
||||
auth_ntlmssp_state->server_info->user_session_key.data,
|
||||
auth_ntlmssp_state->server_info->user_session_key.length);
|
||||
}
|
||||
if (auth_ntlmssp_state->server_info->lm_session_key.length) {
|
||||
DEBUG(10, ("Got LM session key of length %u\n", auth_ntlmssp_state->server_info->lm_session_key.length));
|
||||
DEBUG(10, ("Got LM session key of length %u\n",
|
||||
(unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length));
|
||||
*lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,
|
||||
auth_ntlmssp_state->server_info->lm_session_key.data,
|
||||
auth_ntlmssp_state->server_info->lm_session_key.length);
|
||||
|
@ -372,7 +372,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
|
||||
unsigned char local_lm_response[24];
|
||||
|
||||
#ifdef DEBUG_PASSWORD
|
||||
DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
|
||||
DEBUG(10,("Unencrypted password (len %d):\n",(int)plaintext_password.length));
|
||||
dump_data(100, plaintext_password.data, plaintext_password.length);
|
||||
#endif
|
||||
|
||||
@ -640,6 +640,44 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
|
||||
return token;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
Create a token for the root user to be used internally by smbd.
|
||||
This is similar to running under the context of the LOCAL_SYSTEM account
|
||||
in Windows. This is a read-only token. Do not modify it or free() it.
|
||||
Create a copy if your need to change it.
|
||||
******************************************************************************/
|
||||
|
||||
NT_USER_TOKEN *get_root_nt_token( void )
|
||||
{
|
||||
static NT_USER_TOKEN *token = NULL;
|
||||
DOM_SID u_sid, g_sid;
|
||||
DOM_SID g_sids[1];
|
||||
struct passwd *pw;
|
||||
NTSTATUS result;
|
||||
|
||||
if ( token )
|
||||
return token;
|
||||
|
||||
if ( !(pw = getpwnam( "root" )) ) {
|
||||
DEBUG(0,("create_root_nt_token: getpwnam\"root\") failed!\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the user and primary group SIDs; although the
|
||||
BUILTIN\Administrators SId is really the one that matters here */
|
||||
|
||||
if ( !NT_STATUS_IS_OK(uid_to_sid(&u_sid, pw->pw_uid)) )
|
||||
return NULL;
|
||||
if ( !NT_STATUS_IS_OK(gid_to_sid(&g_sid, pw->pw_gid)) )
|
||||
return NULL;
|
||||
|
||||
sid_copy( &g_sids[0], &global_sid_Builtin_Administrators );
|
||||
|
||||
result = create_nt_user_token( &u_sid, &g_sid, 1, g_sids, False, &token);
|
||||
|
||||
return NT_STATUS_IS_OK(result) ? token : NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* this function returns the groups (SIDs) of the local SAM the user is in.
|
||||
* If this samba server is a DC of the domain the user belongs to, it returns
|
||||
@ -831,6 +869,61 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
Make (and fill) a user_info struct from a Kerberos PAC logon_info by conversion
|
||||
to a SAM_ACCOUNT
|
||||
***************************************************************************/
|
||||
|
||||
NTSTATUS make_server_info_pac(auth_serversupplied_info **server_info,
|
||||
char *unix_username,
|
||||
struct passwd *pwd,
|
||||
PAC_LOGON_INFO *logon_info)
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
SAM_ACCOUNT *sampass = NULL;
|
||||
DOM_SID user_sid, group_sid;
|
||||
fstring dom_name;
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
|
||||
return nt_status;
|
||||
}
|
||||
if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
/* only copy user_sid, group_sid and domain name out of the PAC for
|
||||
* now, we will benefit from more later - Guenther */
|
||||
|
||||
sid_copy(&user_sid, &logon_info->info3.dom_sid.sid);
|
||||
sid_append_rid(&user_sid, logon_info->info3.user_rid);
|
||||
pdb_set_user_sid(sampass, &user_sid, PDB_SET);
|
||||
|
||||
sid_copy(&group_sid, &logon_info->info3.dom_sid.sid);
|
||||
sid_append_rid(&group_sid, logon_info->info3.group_rid);
|
||||
pdb_set_group_sid(sampass, &group_sid, PDB_SET);
|
||||
|
||||
unistr2_to_ascii(dom_name, &logon_info->info3.uni_logon_dom, -1);
|
||||
pdb_set_domain(sampass, dom_name, PDB_SET);
|
||||
|
||||
pdb_set_logon_count(sampass, logon_info->info3.logon_count, PDB_SET);
|
||||
|
||||
(*server_info)->sam_account = sampass;
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username,
|
||||
sampass, pwd->pw_uid, pwd->pw_gid)))
|
||||
{
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
(*server_info)->unix_name = smb_xstrdup(unix_username);
|
||||
|
||||
(*server_info)->sam_fill_level = SAM_FILL_ALL;
|
||||
(*server_info)->uid = pwd->pw_uid;
|
||||
(*server_info)->gid = pwd->pw_gid;
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Make (and fill) a user_info struct from a 'struct passwd' by conversion
|
||||
to a SAM_ACCOUNT
|
||||
|
@ -38,7 +38,7 @@ static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response
|
||||
}
|
||||
prs_copy_data_in(&ps, (char *)info3_ndr, len);
|
||||
prs_set_offset(&ps,0);
|
||||
if (!net_io_user_info3("", info3, &ps, 1, 3)) {
|
||||
if (!net_io_user_info3("", info3, &ps, 1, 3, False)) {
|
||||
DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
#define MOUNT_CIFS_VERSION_MAJOR "1"
|
||||
#define MOUNT_CIFS_VERSION_MINOR "9"
|
||||
#define MOUNT_CIFS_VERSION_MINOR "8"
|
||||
|
||||
#ifndef MOUNT_CIFS_VENDOR_SUFFIX
|
||||
#define MOUNT_CIFS_VENDOR_SUFFIX ""
|
||||
@ -127,10 +127,8 @@ static int open_cred_file(char * file_name)
|
||||
if(fs == NULL)
|
||||
return errno;
|
||||
line_buf = malloc(4096);
|
||||
if(line_buf == NULL) {
|
||||
fclose(fs);
|
||||
if(line_buf == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
while(fgets(line_buf,4096,fs)) {
|
||||
/* parse line from credential file */
|
||||
@ -506,8 +504,6 @@ static int parse_options(char * options, int * filesys_flags)
|
||||
*filesys_flags &= ~MS_NOSUID;
|
||||
} else if (strncmp(data, "nodev", 5) == 0) {
|
||||
*filesys_flags |= MS_NODEV;
|
||||
} else if (strncmp(data, "nobrl", 5) == 0) {
|
||||
*filesys_flags &= ~MS_MANDLOCK;
|
||||
} else if (strncmp(data, "dev", 3) == 0) {
|
||||
*filesys_flags &= ~MS_NODEV;
|
||||
} else if (strncmp(data, "noexec", 6) == 0) {
|
||||
@ -574,15 +570,13 @@ static void check_for_comma(char ** ppasswrd)
|
||||
char *pass;
|
||||
int i,j;
|
||||
int number_of_commas = 0;
|
||||
int len;
|
||||
int len = strlen(*ppasswrd);
|
||||
|
||||
if(ppasswrd == NULL)
|
||||
return;
|
||||
else
|
||||
(pass = *ppasswrd);
|
||||
|
||||
len = strlen(pass);
|
||||
|
||||
for(i=0;i<len;i++) {
|
||||
if(pass[i] == ',')
|
||||
number_of_commas++;
|
||||
@ -696,8 +690,9 @@ static char * parse_server(char ** punc_name)
|
||||
int length = strnlen(unc_name,1024);
|
||||
char * share;
|
||||
char * ipaddress_string = NULL;
|
||||
struct hostent * host_entry;
|
||||
struct hostent * host_entry = NULL;
|
||||
struct in_addr server_ipaddr;
|
||||
int rc;
|
||||
|
||||
if(length > 1023) {
|
||||
printf("mount error: UNC name too long");
|
||||
@ -720,13 +715,6 @@ static char * parse_server(char ** punc_name)
|
||||
if(share) {
|
||||
free_share_name = 1;
|
||||
*punc_name = malloc(length+3);
|
||||
if(*punc_name == NULL) {
|
||||
/* put the original string back if
|
||||
no memory left */
|
||||
*punc_name = unc_name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*share = '/';
|
||||
strncpy((*punc_name)+2,unc_name,length);
|
||||
unc_name = *punc_name;
|
||||
@ -756,7 +744,8 @@ continue_unc_parsing:
|
||||
return NULL;
|
||||
}
|
||||
if(host_entry == NULL) {
|
||||
printf("mount error: could not find target server. TCP name %s not found\n", unc_name);
|
||||
printf("mount error: could not find target server. TCP name %s not found ", unc_name);
|
||||
printf(" rc = %d\n",rc);
|
||||
return NULL;
|
||||
} else {
|
||||
/* BB should we pass an alternate version of the share name as Unicode */
|
||||
@ -1029,9 +1018,6 @@ mount_retry:
|
||||
optlen = 0;
|
||||
if(share_name)
|
||||
optlen += strlen(share_name) + 4;
|
||||
else {
|
||||
printf("No server share name specified\n");
|
||||
}
|
||||
if(user_name)
|
||||
optlen += strlen(user_name) + 6;
|
||||
if(ipaddr)
|
||||
@ -1140,6 +1126,8 @@ mount_retry:
|
||||
strcat(mountent.mnt_opts,"rw");
|
||||
if(flags & MS_MANDLOCK)
|
||||
strcat(mountent.mnt_opts,",mand");
|
||||
else
|
||||
strcat(mountent.mnt_opts,",nomand");
|
||||
if(flags & MS_NOEXEC)
|
||||
strcat(mountent.mnt_opts,",noexec");
|
||||
if(flags & MS_NOSUID)
|
||||
|
@ -70,6 +70,9 @@ static int smb_print(struct cli_state *, char *, FILE *);
|
||||
FILE *fp; /* File to print */
|
||||
int status=0; /* Status of LPD job */
|
||||
struct cli_state *cli; /* SMB interface */
|
||||
char null_str[1];
|
||||
|
||||
null_str[0] = '\0';
|
||||
|
||||
/* we expect the URI in argv[0]. Detect the case where it is in argv[1] and cope */
|
||||
if (argc > 2 && strncmp(argv[0],"smb://", 6) && !strncmp(argv[1],"smb://", 6)) {
|
||||
@ -158,12 +161,12 @@ static int smb_print(struct cli_state *, char *, FILE *);
|
||||
if ((password = strchr_m(username, ':')) != NULL)
|
||||
*password++ = '\0';
|
||||
else
|
||||
password = "";
|
||||
password = null_str;
|
||||
}
|
||||
else
|
||||
{
|
||||
username = "";
|
||||
password = "";
|
||||
username = null_str;
|
||||
password = null_str;
|
||||
server = uri + 6;
|
||||
}
|
||||
|
||||
@ -335,10 +338,8 @@ char * get_ticket_cache( uid_t uid )
|
||||
|
||||
if ( ticket_file == NULL )
|
||||
{
|
||||
#ifdef DEVELOPER
|
||||
/* no ticket cache found */
|
||||
fprintf(stderr, "ERROR: No ticket cache found for userid=%d\n", uid);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -235,6 +235,7 @@ AC_SUBST(SMBWRAP_INC)
|
||||
AC_SUBST(EXTRA_BIN_PROGS)
|
||||
AC_SUBST(EXTRA_SBIN_PROGS)
|
||||
AC_SUBST(EXTRA_ALL_TARGETS)
|
||||
AC_SUBST(CONFIG_LIBS)
|
||||
|
||||
# Set defaults
|
||||
PIE_CFLAGS=""
|
||||
@ -457,10 +458,10 @@ DYNEXP=
|
||||
|
||||
dnl Add modules that have to be built by default here
|
||||
dnl These have to be built static:
|
||||
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_svcctl rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_eventlog auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin printerdb_file"
|
||||
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_svcctl rpc_ntsvcs rpc_net rpc_dfs rpc_srv rpc_spoolss rpc_eventlog auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
|
||||
|
||||
dnl These are preferably build shared, and static if dlopen() is not available
|
||||
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437 auth_script"
|
||||
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437 auth_script"
|
||||
|
||||
if test "x$developer" = xyes; then
|
||||
default_static_modules="$default_static_modules rpc_echo"
|
||||
@ -2820,6 +2821,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])
|
||||
default_static_modules="$default_static_modules pdb_ldap idmap_ldap";
|
||||
default_shared_modules="$default_shared_modules";
|
||||
SMBLDAP="lib/smbldap.o"
|
||||
SMBLDAPUTIL="lib/smbldap_util.o"
|
||||
with_ldap_support=yes
|
||||
@ -3048,9 +3050,77 @@ if test x"$with_ads_support" != x"no"; then
|
||||
AC_CHECK_FUNC_EXT(krb5_krbhst_get_addrinfo, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_c_enctype_compare, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_enctypes_compatible_keys, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_crypto_init, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_crypto_destroy, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_decode_ap_req, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(decode_krb5_ap_req, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_free_ap_req, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(free_AP_REQ, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_c_verify_checksum, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_principal_compare_any_realm, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_parse_name_norealm, $KRB5_LIBS)
|
||||
AC_CHECK_FUNC_EXT(krb5_princ_size, $KRB5_LIBS)
|
||||
|
||||
LIBS="$KRB5_LIBS $LIBS"
|
||||
|
||||
AC_CACHE_CHECK(whether krb5_verify_checksum takes 7 arguments, smb_krb5_verify_checksum, [
|
||||
AC_TRY_COMPILE([
|
||||
#include <krb5.h>],
|
||||
[krb5_verify_checksum(0, 0, 0, 0, 0, 0, 0);],
|
||||
[smb_krb5_verify_checksum=7],
|
||||
[smb_krb5_verify_checksum=6],
|
||||
)
|
||||
])
|
||||
AC_DEFINE_UNQUOTED(KRB5_VERIFY_CHECKSUM_ARGS, $smb_krb5_verify_checksum, [Number of arguments to krb5_verify_checksum])
|
||||
|
||||
AC_CACHE_CHECK([for checksum in krb5_checksum],
|
||||
samba_cv_HAVE_CHECKSUM_IN_KRB5_CHECKSUM,[
|
||||
AC_TRY_COMPILE([#include <krb5.h>],
|
||||
[krb5_checksum cksum; cksum.checksum.length = 0;],
|
||||
samba_cv_HAVE_CHECKSUM_IN_KRB5_CHECKSUM=yes,
|
||||
samba_cv_HAVE_CHECKSUM_IN_KRB5_CHECKSUM=no)])
|
||||
|
||||
if test x"$samba_cv_HAVE_CHECKSUM_IN_KRB5_CHECKSUM" = x"yes"; then
|
||||
AC_DEFINE(HAVE_CHECKSUM_IN_KRB5_CHECKSUM,1,
|
||||
[Whether the krb5_checksum struct has a checksum property])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for etype in EncryptedData],
|
||||
samba_cv_HAVE_ETYPE_IN_ENCRYPTEDDATA,[
|
||||
AC_TRY_COMPILE([#include <krb5.h>],
|
||||
[EncryptedData edata; edata.etype = 0;],
|
||||
samba_cv_HAVE_ETYPE_IN_ENCRYPTEDDATA=yes,
|
||||
samba_cv_HAVE_ETYPE_IN_ENCRYPTEDDATA=no)])
|
||||
|
||||
if test x"$samba_cv_HAVE_ETYPE_IN_ENCRYPTEDDATA" = x"yes"; then
|
||||
AC_DEFINE(HAVE_ETYPE_IN_ENCRYPTEDDATA,1,
|
||||
[Whether the EncryptedData struct has a etype property])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for ticket pointer in krb5_ap_req],
|
||||
samba_cv_HAVE_TICKET_POINTER_IN_KRB5_AP_REQ,[
|
||||
AC_TRY_COMPILE([#include <krb5.h>],
|
||||
[krb5_ap_req *ap_req; ap_req->ticket = NULL;],
|
||||
samba_cv_HAVE_TICKET_POINTER_IN_KRB5_AP_REQ=yes,
|
||||
samba_cv_HAVE_TICKET_POINTER_IN_KRB5_AP_REQ=no)])
|
||||
|
||||
if test x"$samba_cv_HAVE_TICKET_POINTER_IN_KRB5_AP_REQ" = x"yes"; then
|
||||
AC_DEFINE(HAVE_TICKET_POINTER_IN_KRB5_AP_REQ,1,
|
||||
[Whether the krb5_ap_req struct has a ticket pointer])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for krb5_crypto type],
|
||||
samba_cv_HAVE_KRB5_CRYPTO,[
|
||||
AC_TRY_COMPILE([#include <krb5.h>],
|
||||
[krb5_crypto crypto;],
|
||||
samba_cv_HAVE_KRB5_CRYPTO=yes,
|
||||
samba_cv_HAVE_KRB5_CRYPTO=no)])
|
||||
|
||||
if test x"$samba_cv_HAVE_KRB5_CRYPTO" = x"yes"; then
|
||||
AC_DEFINE(HAVE_KRB5_CRYPTO,1,
|
||||
[Whether the type krb5_crypto exists])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for krb5_encrypt_block type],
|
||||
samba_cv_HAVE_KRB5_ENCRYPT_BLOCK,[
|
||||
AC_TRY_COMPILE([#include <krb5.h>],
|
||||
@ -3178,6 +3248,30 @@ if test x"$with_ads_support" != x"no"; then
|
||||
[Whether the KV5M_KEYTAB option is available])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for KRB5_KU_OTHER_CKSUM],
|
||||
samba_cv_HAVE_KRB5_KU_OTHER_CKSUM,[
|
||||
AC_TRY_COMPILE([#include <krb5.h>],
|
||||
[krb5_keyusage usage = KRB5_KU_OTHER_CKSUM;],
|
||||
samba_cv_HAVE_KRB5_KU_OTHER_CKSUM=yes,
|
||||
samba_cv_HAVE_KRB5_KU_OTHER_CKSUM=no)])
|
||||
|
||||
if test x"$samba_cv_HAVE_KRB5_KU_OTHER_CKSUM" = x"yes"; then
|
||||
AC_DEFINE(HAVE_KRB5_KU_OTHER_CKSUM,1,
|
||||
[Whether KRB5_KU_OTHER_CKSUM is available])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for KRB5_KEYUSAGE_APP_DATA_CKSUM],
|
||||
samba_cv_HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM,[
|
||||
AC_TRY_COMPILE([#include <krb5.h>],
|
||||
[krb5_keyusage usage = KRB5_KEYUSAGE_APP_DATA_CKSUM;],
|
||||
samba_cv_HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM=yes,
|
||||
samba_cv_HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM=no)])
|
||||
|
||||
if test x"$samba_cv_HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM" = x"yes"; then
|
||||
AC_DEFINE(HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM,1,
|
||||
[Whether KRB5_KEYUSAGE_APP_DATA_CKSUM is available])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for the krb5_princ_component macro],
|
||||
samba_cv_HAVE_KRB5_PRINC_COMPONENT,[
|
||||
AC_TRY_LINK([#include <krb5.h>],
|
||||
@ -3915,7 +4009,6 @@ AC_ARG_WITH(libsmbclient,
|
||||
INSTALLCLIENT=installclientlib
|
||||
)
|
||||
|
||||
|
||||
INSTALLCLIENTCMD_SH=:
|
||||
INSTALLCLIENTCMD_A=:
|
||||
INSTALLCLIENT=
|
||||
@ -3965,7 +4058,6 @@ AC_ARG_WITH(libsmbsharemodes,
|
||||
INSTALLCLIENT=installclientlib
|
||||
)
|
||||
|
||||
|
||||
#################################################
|
||||
# these tests are taken from the GNU fileutils package
|
||||
AC_CHECKING(how to get filesystem space usage)
|
||||
@ -4951,11 +5043,13 @@ SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB)
|
||||
SMB_MODULE(pdb_guest, passdb/pdb_guest.o, "bin/guest.$SHLIBEXT", PDB)
|
||||
SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o)
|
||||
|
||||
|
||||
SMB_MODULE(rpc_lsa, \$(RPC_LSA_OBJ), "bin/librpc_lsarpc.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_reg, \$(RPC_REG_OBJ), "bin/librpc_winreg.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_lsa_ds, \$(RPC_LSA_DS_OBJ), "bin/librpc_lsa_ds.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_wks, \$(RPC_WKS_OBJ), "bin/librpc_wkssvc.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_svcctl, \$(RPC_SVCCTL_OBJ), "bin/librpc_svcctl.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_ntsvcs, \$(RPC_NTSVCS_OBJ), "bin/librpc_ntsvcs.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_net, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_dfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC)
|
||||
SMB_MODULE(rpc_srv, \$(RPC_SVC_OBJ), "bin/librpc_srvsvc.$SHLIBEXT", RPC)
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Unix SMB/CIFS implementation.
|
||||
* RPC Pipe client / server routines
|
||||
* Copyright (C) Andrew Tridgell 1992-2000,
|
||||
* Copyright (C) Jean François Micouleau 1998-2001.
|
||||
* Copyright (C) Jean François Micouleau 1998-2001.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -365,7 +365,7 @@ static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
|
||||
Remove a group mapping entry.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL group_map_remove(DOM_SID sid)
|
||||
static BOOL group_map_remove(const DOM_SID *sid)
|
||||
{
|
||||
TDB_DATA kbuf, dbuf;
|
||||
pstring key;
|
||||
@ -378,7 +378,7 @@ static BOOL group_map_remove(DOM_SID sid)
|
||||
|
||||
/* the key is the SID, retrieving is direct */
|
||||
|
||||
sid_to_string(string_sid, &sid);
|
||||
sid_to_string(string_sid, sid);
|
||||
slprintf(key, sizeof(key), "%s%s", GROUP_PREFIX, string_sid);
|
||||
|
||||
kbuf.dptr = key;
|
||||
@ -954,7 +954,6 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Create a UNIX group on demand.
|
||||
****************************************************************************/
|
||||
@ -1131,7 +1130,7 @@ NTSTATUS pdb_default_update_group_mapping_entry(struct pdb_methods *methods,
|
||||
NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods,
|
||||
DOM_SID sid)
|
||||
{
|
||||
return group_map_remove(sid) ?
|
||||
return group_map_remove(&sid) ?
|
||||
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
@ -1173,18 +1172,12 @@ NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
|
||||
if (lookup_name(get_global_sam_name(), name, &sid, &type))
|
||||
return NT_STATUS_ALIAS_EXISTS;
|
||||
|
||||
if (!winbind_allocate_rid(&new_rid))
|
||||
if (!winbind_allocate_rid_and_gid(&new_rid, &gid))
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
|
||||
sid_copy(&sid, get_global_sam_sid());
|
||||
sid_append_rid(&sid, new_rid);
|
||||
|
||||
/* Here we allocate the gid */
|
||||
if (!winbind_sid_to_gid(&gid, &sid)) {
|
||||
DEBUG(0, ("Could not get gid for new RID\n"));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
map.gid = gid;
|
||||
sid_copy(&map.sid, &sid);
|
||||
map.sid_name_use = SID_NAME_ALIAS;
|
||||
@ -1282,7 +1275,7 @@ NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
|
||||
return result;
|
||||
|
||||
*alias_rids = TALLOC_ARRAY(mem_ctx, uint32, num_alias_sids);
|
||||
if ((alias_sids != 0) && (*alias_rids == NULL))
|
||||
if (*alias_rids == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
*num_alias_rids = 0;
|
||||
@ -1347,3 +1340,38 @@ NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods,
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
These need to be redirected through pdb_interface.c
|
||||
****************************************************************************/
|
||||
BOOL pdb_get_dom_grp_info(const DOM_SID *sid, struct acct_info *info)
|
||||
{
|
||||
GROUP_MAP map;
|
||||
BOOL res;
|
||||
|
||||
become_root();
|
||||
res = get_domain_group_from_sid(*sid, &map);
|
||||
unbecome_root();
|
||||
|
||||
if (!res)
|
||||
return False;
|
||||
|
||||
fstrcpy(info->acct_name, map.nt_name);
|
||||
fstrcpy(info->acct_desc, map.comment);
|
||||
sid_peek_rid(sid, &info->rid);
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL pdb_set_dom_grp_info(const DOM_SID *sid, const struct acct_info *info)
|
||||
{
|
||||
GROUP_MAP map;
|
||||
|
||||
if (!get_domain_group_from_sid(*sid, &map))
|
||||
return False;
|
||||
|
||||
fstrcpy(map.nt_name, info->acct_name);
|
||||
fstrcpy(map.comment, info->acct_desc);
|
||||
|
||||
return pdb_update_group_mapping_entry(&map);
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,7 +130,7 @@ typedef void **ADS_MODLIST;
|
||||
#define UF_UNUSED_5 0x00800000
|
||||
|
||||
#define UF_UNUSED_6 0x01000000
|
||||
#define UF_UNUSED_7 0x02000000
|
||||
#define UF_NO_AUTH_DATA_REQUIRED 0x02000000
|
||||
#define UF_UNUSED_8 0x04000000
|
||||
#define UF_UNUSED_9 0x08000000
|
||||
|
||||
|
@ -27,7 +27,7 @@ struct nesting {
|
||||
struct nesting *next;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
typedef struct asn1_data {
|
||||
uint8 *data;
|
||||
size_t length;
|
||||
off_t ofs;
|
||||
@ -37,13 +37,16 @@ typedef struct {
|
||||
|
||||
|
||||
#define ASN1_APPLICATION(x) ((x)+0x60)
|
||||
#define ASN1_APPLICATION_SIMPLE(x) ((x)+0x40)
|
||||
#define ASN1_SEQUENCE(x) ((x)+0x30)
|
||||
#define ASN1_CONTEXT(x) ((x)+0xa0)
|
||||
#define ASN1_CONTEXT_SIMPLE(x) ((x)+0x80)
|
||||
#define ASN1_GENERAL_STRING 0x1b
|
||||
#define ASN1_OCTET_STRING 0x4
|
||||
#define ASN1_OID 0x6
|
||||
#define ASN1_BOOLEAN 0x1
|
||||
#define ASN1_INTEGER 0x2
|
||||
#define ASN1_BITFIELD 0x3
|
||||
#define ASN1_ENUMERATED 0xa
|
||||
#define ASN1_SET 0x31
|
||||
|
||||
|
@ -23,12 +23,22 @@
|
||||
#define _AUTHDATA_H
|
||||
|
||||
#include "rpc_misc.h"
|
||||
#include "rpc_netlogon.h"
|
||||
|
||||
#define PAC_TYPE_LOGON_INFO 1
|
||||
#define PAC_TYPE_SERVER_CHECKSUM 6
|
||||
#define PAC_TYPE_PRIVSVR_CHECKSUM 7
|
||||
#define PAC_TYPE_LOGON_NAME 10
|
||||
|
||||
#ifndef KRB5_AUTHDATA_WIN2K_PAC
|
||||
#define KRB5_AUTHDATA_WIN2K_PAC 128
|
||||
#endif
|
||||
|
||||
#ifndef KRB5_AUTHDATA_IF_RELEVANT
|
||||
#define KRB5_AUTHDATA_IF_RELEVANT 1
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct pac_logon_name {
|
||||
NTTIME logon_time;
|
||||
uint16 len;
|
||||
@ -37,7 +47,7 @@ typedef struct pac_logon_name {
|
||||
|
||||
typedef struct pac_signature_data {
|
||||
uint32 type;
|
||||
uint8 *signature;
|
||||
RPC_DATA_BLOB signature; /* this not the on-wire-format (!) */
|
||||
} PAC_SIGNATURE_DATA;
|
||||
|
||||
typedef struct group_membership {
|
||||
@ -50,6 +60,8 @@ typedef struct group_membership_array {
|
||||
GROUP_MEMBERSHIP *group_membership;
|
||||
} GROUP_MEMBERSHIP_ARRAY;
|
||||
|
||||
#if 0 /* Unused, replaced by NET_USER_INFO_3 - Guenther */
|
||||
|
||||
typedef struct krb_sid_and_attrs {
|
||||
uint32 sid_ptr;
|
||||
uint32 attrs;
|
||||
@ -82,7 +94,7 @@ typedef struct pac_logon_info {
|
||||
UNIHDR hdr_dir_drive;
|
||||
|
||||
uint16 logon_count; /* number of times user has logged onto domain */
|
||||
uint16 reserved12;
|
||||
uint16 bad_password_count; /* samba4 idl */
|
||||
|
||||
uint32 user_rid;
|
||||
uint32 group_rid;
|
||||
@ -90,15 +102,15 @@ typedef struct pac_logon_info {
|
||||
uint32 group_membership_ptr;
|
||||
uint32 user_flags;
|
||||
|
||||
uint32 reserved13[4];
|
||||
uint8 session_key[16]; /* samba4 idl */
|
||||
UNIHDR hdr_dom_controller;
|
||||
UNIHDR hdr_dom_name;
|
||||
|
||||
uint32 ptr_dom_sid;
|
||||
|
||||
uint32 reserved16[2];
|
||||
uint32 reserved17; /* looks like it may be acb_info */
|
||||
uint32 reserved18[7];
|
||||
uint8 lm_session_key[8]; /* samba4 idl */
|
||||
uint32 acct_flags; /* samba4 idl */
|
||||
uint32 unknown[7];
|
||||
|
||||
uint32 sid_count;
|
||||
uint32 ptr_extra_sids;
|
||||
@ -121,6 +133,14 @@ typedef struct pac_logon_info {
|
||||
DOM_SID2 res_group_dom_sid;
|
||||
GROUP_MEMBERSHIP_ARRAY res_groups;
|
||||
|
||||
} PAC_LOGON_INFO;
|
||||
#endif
|
||||
|
||||
typedef struct pac_logon_info {
|
||||
NET_USER_INFO_3 info3;
|
||||
DOM_SID2 res_group_dom_sid;
|
||||
GROUP_MEMBERSHIP_ARRAY res_groups;
|
||||
|
||||
} PAC_LOGON_INFO;
|
||||
|
||||
typedef struct pac_info_ctr
|
||||
@ -134,18 +154,19 @@ typedef struct pac_info_ctr
|
||||
} pac;
|
||||
} PAC_INFO_CTR;
|
||||
|
||||
typedef struct pac_info_hdr {
|
||||
typedef struct pac_buffer {
|
||||
uint32 type;
|
||||
uint32 size;
|
||||
uint32 offset;
|
||||
uint32 offsethi;
|
||||
PAC_INFO_CTR *ctr;
|
||||
} PAC_INFO_HDR;
|
||||
uint32 pad;
|
||||
} PAC_BUFFER;
|
||||
|
||||
typedef struct pac_data {
|
||||
uint32 num_buffers;
|
||||
uint32 version;
|
||||
PAC_INFO_HDR *pac_info_hdr_ptr;
|
||||
PAC_BUFFER *pac_buffer;
|
||||
} PAC_DATA;
|
||||
|
||||
|
||||
|
@ -57,25 +57,39 @@ struct print_job_info
|
||||
time_t t;
|
||||
};
|
||||
|
||||
struct cli_pipe_auth_data {
|
||||
enum pipe_auth_type auth_type; /* switch for the union below. Defined in ntdomain.h */
|
||||
enum pipe_auth_level auth_level; /* defined in ntdomain.h */
|
||||
union {
|
||||
struct schannel_auth_struct *schannel_auth;
|
||||
NTLMSSP_STATE *ntlmssp_state;
|
||||
struct kerberos_auth_struct *kerberos_auth;
|
||||
} a_u;
|
||||
void (*cli_auth_data_free_func)(struct cli_pipe_auth_data *);
|
||||
};
|
||||
|
||||
struct rpc_pipe_client {
|
||||
struct rpc_pipe_client *prev, *next;
|
||||
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
struct cli_state *cli;
|
||||
|
||||
int pipe_idx;
|
||||
const char *pipe_name;
|
||||
uint16 fnum;
|
||||
|
||||
int pipe_auth_flags;
|
||||
|
||||
NTLMSSP_STATE *ntlmssp_pipe_state;
|
||||
const char *user_name;
|
||||
const char *domain;
|
||||
const char *user_name;
|
||||
struct pwd_info pwd;
|
||||
|
||||
struct netsec_auth_struct auth_info;
|
||||
|
||||
uint16 max_xmit_frag;
|
||||
uint16 max_recv_frag;
|
||||
|
||||
struct cli_pipe_auth_data auth;
|
||||
|
||||
/* The following is only non-null on a netlogon pipe. */
|
||||
struct dcinfo *dc;
|
||||
};
|
||||
|
||||
struct cli_state {
|
||||
@ -92,8 +106,11 @@ struct cli_state {
|
||||
int privileges;
|
||||
|
||||
fstring desthost;
|
||||
fstring user_name;
|
||||
|
||||
/* The credentials used to open the cli_state connection. */
|
||||
fstring domain;
|
||||
fstring user_name;
|
||||
struct pwd_info pwd;
|
||||
|
||||
/*
|
||||
* The following strings are the
|
||||
@ -111,7 +128,6 @@ struct cli_state {
|
||||
fstring full_dest_host_name;
|
||||
struct in_addr dest_ip;
|
||||
|
||||
struct pwd_info pwd;
|
||||
DATA_BLOB secblob; /* cryptkey or negTokenInit */
|
||||
uint32 sesskey;
|
||||
int serverzone;
|
||||
@ -137,27 +153,8 @@ struct cli_state {
|
||||
any per-pipe authenticaion */
|
||||
DATA_BLOB user_session_key;
|
||||
|
||||
/*
|
||||
* Only used in NT domain calls.
|
||||
*/
|
||||
|
||||
int pipe_idx; /* Index (into list of known pipes)
|
||||
of the pipe we're talking to,
|
||||
if any */
|
||||
|
||||
struct rpc_pipe_client pipes[PI_MAX_PIPES];
|
||||
|
||||
/* Secure pipe parameters */
|
||||
int pipe_auth_flags;
|
||||
|
||||
struct rpc_pipe_client netlogon_pipe; /* The "first" pipe to get
|
||||
the session key for the
|
||||
schannel. */
|
||||
unsigned char sess_key[16]; /* Current session key. */
|
||||
DOM_CRED clnt_cred; /* Client credential. */
|
||||
fstring mach_acct; /* MYNAME$. */
|
||||
fstring srv_name_slash; /* \\remote server. */
|
||||
fstring clnt_name_slash; /* \\local client. */
|
||||
/* The list of pipes currently open on this connection. */
|
||||
struct rpc_pipe_client *pipe_list;
|
||||
|
||||
BOOL use_kerberos;
|
||||
BOOL fallback_after_kerberos;
|
||||
@ -175,9 +172,6 @@ struct cli_state {
|
||||
/* was this structure allocated by cli_initialise? If so, then
|
||||
free in cli_shutdown() */
|
||||
BOOL allocated;
|
||||
|
||||
/* Name of the pipe we're talking to, if any */
|
||||
fstring pipe_name;
|
||||
};
|
||||
|
||||
#define CLI_FULL_CONNECTION_DONT_SPNEGO 0x0001
|
||||
|
@ -70,6 +70,20 @@
|
||||
} \
|
||||
}
|
||||
|
||||
/* insert 'p' after the given element 'el' in a list. If el is NULL then
|
||||
this is the same as a DLIST_ADD() */
|
||||
#define DLIST_ADD_AFTER(list, p, el) \
|
||||
do { \
|
||||
if (!(list) || !(el)) { \
|
||||
DLIST_ADD(list, p); \
|
||||
} else { \
|
||||
p->prev = el; \
|
||||
p->next = el->next; \
|
||||
el->next = p; \
|
||||
if (p->next) p->next->prev = p; \
|
||||
}\
|
||||
} while (0)
|
||||
|
||||
/* demote an element to the top of the list, needs a tmp pointer */
|
||||
#define DLIST_DEMOTE(list, p, tmp) \
|
||||
{ \
|
||||
|
@ -5,6 +5,7 @@
|
||||
Copyright (C) John H Terpstra 1996-2000
|
||||
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
|
||||
Copyright (C) Paul Ashton 1998-2000
|
||||
Copyright (C) Gerald (Jerry) Carter 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -174,6 +175,7 @@
|
||||
#define WERR_NOMEM W_ERROR(8)
|
||||
#define WERR_GENERAL_FAILURE W_ERROR(31)
|
||||
#define WERR_NOT_SUPPORTED W_ERROR(50)
|
||||
#define WERR_DEVICE_NOT_EXIST W_ERROR(55)
|
||||
#define WERR_PRINTQ_FULL W_ERROR(61)
|
||||
#define WERR_NO_SPOOL_SPACE W_ERROR(62)
|
||||
#define WERR_NO_SUCH_SHARE W_ERROR(67)
|
||||
@ -227,6 +229,12 @@
|
||||
#define WERR_PRINT_MONITOR_IN_USE W_ERROR(ERRprintmonitorinuse)
|
||||
#define WERR_PRINTER_HAS_JOBS_QUEUED W_ERROR(ERRprinterhasjobsqueued)
|
||||
|
||||
/* Configuration Manager Errors */
|
||||
/* Basically Win32 errors meanings are specific to the \ntsvcs pipe */
|
||||
|
||||
#define WERR_CM_NO_MORE_HW_PROFILES W_ERROR(35)
|
||||
#define WERR_CM_NO_SUCH_VALUE W_ERROR(37)
|
||||
|
||||
|
||||
/* DFS errors */
|
||||
|
||||
|
@ -27,7 +27,8 @@
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define class #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
|
||||
#define private #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
|
||||
/* allow to build with newer heimdal releases */
|
||||
/* #define private #error DONT_USE_CPLUSPLUS_RESERVED_NAMES */
|
||||
#define public #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
|
||||
#define protected #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
|
||||
#define template #error DONT_USE_CPLUSPLUS_RESERVED_NAMES
|
||||
@ -288,6 +289,7 @@
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_SYS_MOUNT_H
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
@ -896,19 +898,17 @@ extern int errno;
|
||||
|
||||
#include "privileges.h"
|
||||
|
||||
#include "rpc_creds.h"
|
||||
#include "rpc_misc.h"
|
||||
|
||||
#include "rpc_dce.h"
|
||||
|
||||
#include "mapping.h"
|
||||
|
||||
#include "passdb.h"
|
||||
|
||||
#include "ntdomain.h"
|
||||
|
||||
#include "rpc_misc.h"
|
||||
|
||||
#include "rpc_secdes.h"
|
||||
|
||||
#include "nt_printing.h"
|
||||
#include "authdata.h"
|
||||
|
||||
#include "msdfs.h"
|
||||
|
||||
@ -923,6 +923,29 @@ extern int errno;
|
||||
|
||||
#include "auth.h"
|
||||
|
||||
#include "ntdomain.h"
|
||||
|
||||
#include "rpc_svcctl.h"
|
||||
#include "rpc_ntsvcs.h"
|
||||
#include "rpc_lsa.h"
|
||||
#include "rpc_netlogon.h"
|
||||
#include "reg_objects.h"
|
||||
#include "rpc_reg.h"
|
||||
#include "rpc_samr.h"
|
||||
#include "rpc_srvsvc.h"
|
||||
#include "rpc_wkssvc.h"
|
||||
#include "rpc_spoolss.h"
|
||||
#include "rpc_eventlog.h"
|
||||
#include "rpc_dfs.h"
|
||||
#include "rpc_ds.h"
|
||||
#include "rpc_echo.h"
|
||||
#include "rpc_shutdown.h"
|
||||
#include "rpc_unixinfo.h"
|
||||
#include "rpc_perfcount.h"
|
||||
#include "rpc_perfcount_defs.h"
|
||||
|
||||
#include "nt_printing.h"
|
||||
|
||||
#include "idmap.h"
|
||||
|
||||
#include "client.h"
|
||||
@ -945,6 +968,8 @@ extern int errno;
|
||||
|
||||
#include "spnego.h"
|
||||
|
||||
#include "rpc_client.h"
|
||||
|
||||
/*
|
||||
* Type for wide character dirent structure.
|
||||
* Only d_name is defined by POSIX.
|
||||
@ -995,6 +1020,8 @@ struct smb_ldap_privates;
|
||||
|
||||
#include "smbldap.h"
|
||||
|
||||
#include "smb_ldap.h"
|
||||
|
||||
/***** automatically generated prototypes *****/
|
||||
#ifndef NO_PROTO_H
|
||||
#include "proto.h"
|
||||
@ -1414,7 +1441,7 @@ void krb5_free_unparsed_name(krb5_context ctx, char *val);
|
||||
void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);
|
||||
int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
|
||||
int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
|
||||
void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt);
|
||||
BOOL get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);
|
||||
krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
|
||||
krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters);
|
||||
krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
|
||||
|
@ -63,6 +63,11 @@
|
||||
#define MSG_SMB_SAM_SYNC 3003
|
||||
#define MSG_SMB_SAM_REPL 3004
|
||||
#define MSG_SMB_UNLOCK 3005
|
||||
#define MSG_SMB_BREAK_REQUEST 3006
|
||||
#define MSG_SMB_BREAK_RESPONSE 3007
|
||||
#define MSG_SMB_ASYNC_LEVEL2_BREAK 3008
|
||||
#define MSG_SMB_OPEN_RETRY 3009
|
||||
#define MSG_SMB_KERNEL_BREAK 3010
|
||||
|
||||
/* winbind messages */
|
||||
#define MSG_WINBIND_FINISHED 4001
|
||||
@ -77,4 +82,8 @@
|
||||
#define FLAG_MSG_PRINT_NOTIFY 0x0008
|
||||
#define FLAG_MSG_PRINT_GENERAL 0x0010
|
||||
|
||||
struct process_id {
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -33,6 +33,4 @@ typedef int smb_event_id_t;
|
||||
|
||||
typedef void (smb_idle_event_fn)(void **data,time_t *interval,time_t now);
|
||||
|
||||
typedef void (smb_exit_event_fn)(void **data);
|
||||
|
||||
#endif /* _MODULE_H */
|
||||
|
@ -24,30 +24,6 @@
|
||||
#ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */
|
||||
#define _NT_DOMAIN_H
|
||||
|
||||
struct uuid {
|
||||
uint32 time_low;
|
||||
uint16 time_mid;
|
||||
uint16 time_hi_and_version;
|
||||
uint8 clock_seq[2];
|
||||
uint8 node[6];
|
||||
};
|
||||
#define UUID_SIZE 16
|
||||
|
||||
#define UUID_FLAT_SIZE 16
|
||||
typedef struct uuid_flat {
|
||||
uint8 info[UUID_FLAT_SIZE];
|
||||
} UUID_FLAT;
|
||||
|
||||
/* dce/rpc support */
|
||||
#include "rpc_dce.h"
|
||||
|
||||
/* miscellaneous structures / defines */
|
||||
#include "rpc_misc.h"
|
||||
|
||||
#include "rpc_creds.h"
|
||||
|
||||
#include "talloc.h"
|
||||
|
||||
/*
|
||||
* A bunch of stuff that was put into smb.h
|
||||
* in the NTDOM branch - it didn't belong there.
|
||||
@ -67,6 +43,7 @@ typedef struct _prs_struct {
|
||||
uint32 grow_size; /* size requested via prs_grow() calls */
|
||||
char *data_p; /* The buffer itself. */
|
||||
TALLOC_CTX *mem_ctx; /* When unmarshalling, use this.... */
|
||||
const char *sess_key; /* If we have to do encrypt/decrypt on the fly. */
|
||||
} prs_struct;
|
||||
|
||||
/*
|
||||
@ -97,7 +74,7 @@ typedef struct _output_data {
|
||||
* The current PDU being returned. This inclues
|
||||
* headers, data and authentication footer.
|
||||
*/
|
||||
unsigned char current_pdu[MAX_PDU_FRAG_LEN];
|
||||
unsigned char current_pdu[RPC_MAX_PDU_FRAG_LEN];
|
||||
|
||||
/* The amount of data in the current_pdu buffer. */
|
||||
uint32 current_pdu_len;
|
||||
@ -111,9 +88,9 @@ typedef struct _input_data {
|
||||
* This is the current incoming pdu. The data here
|
||||
* is collected via multiple writes until a complete
|
||||
* pdu is seen, then the data is copied into the in_data
|
||||
* structure. The maximum size of this is 0x1630 (MAX_PDU_FRAG_LEN).
|
||||
* structure. The maximum size of this is 0x1630 (RPC_MAX_PDU_FRAG_LEN).
|
||||
*/
|
||||
unsigned char current_in_pdu[MAX_PDU_FRAG_LEN];
|
||||
unsigned char current_in_pdu[RPC_MAX_PDU_FRAG_LEN];
|
||||
|
||||
/*
|
||||
* The amount of data needed to complete the in_pdu.
|
||||
@ -158,22 +135,22 @@ struct handle_list {
|
||||
|
||||
/* Domain controller authentication protocol info */
|
||||
struct dcinfo {
|
||||
DOM_CHAL clnt_chal; /* Initial challenge received from client */
|
||||
DOM_CHAL srv_chal; /* Initial server challenge */
|
||||
DOM_CRED clnt_cred; /* Last client credential */
|
||||
DOM_CRED srv_cred; /* Last server credential */
|
||||
uint32 sequence; /* "timestamp" from client. */
|
||||
DOM_CHAL seed_chal;
|
||||
DOM_CHAL clnt_chal; /* Client credential */
|
||||
DOM_CHAL srv_chal; /* Server credential */
|
||||
|
||||
uchar sess_key[8]; /* Session key */
|
||||
uchar md4pw[16]; /* md4(machine password) */
|
||||
uchar mach_pw[16]; /* md4(machine password) */
|
||||
|
||||
fstring mach_acct; /* Machine name we've authenticated. */
|
||||
|
||||
fstring remote_machine; /* Machine name we've authenticated. */
|
||||
fstring domain;
|
||||
|
||||
BOOL challenge_sent;
|
||||
BOOL got_session_key;
|
||||
BOOL authenticated;
|
||||
|
||||
};
|
||||
|
||||
typedef struct pipe_rpc_fns {
|
||||
@ -188,6 +165,46 @@ typedef struct pipe_rpc_fns {
|
||||
|
||||
} PIPE_RPC_FNS;
|
||||
|
||||
/*
|
||||
* Different auth types we support.
|
||||
* Can't keep in sync with wire values as spnego wraps different auth methods.
|
||||
*/
|
||||
|
||||
enum pipe_auth_type { PIPE_AUTH_TYPE_NONE = 0, PIPE_AUTH_TYPE_NTLMSSP, PIPE_AUTH_TYPE_SCHANNEL,
|
||||
PIPE_AUTH_TYPE_SPNEGO_NTLMSSP, PIPE_AUTH_TYPE_KRB5, PIPE_AUTH_TYPE_SPNEGO_KRB5 };
|
||||
|
||||
/* Possible auth levels - keep these in sync with the wire values. */
|
||||
enum pipe_auth_level { PIPE_AUTH_LEVEL_NONE = 0,
|
||||
PIPE_AUTH_LEVEL_CONNECT = 1, /* We treat as NONE. */
|
||||
PIPE_AUTH_LEVEL_INTEGRITY = 5, /* Sign. */
|
||||
PIPE_AUTH_LEVEL_PRIVACY = 6 /* Seal. */
|
||||
};
|
||||
|
||||
/* auth state for krb5. */
|
||||
struct kerberos_auth_struct {
|
||||
const char *service_principal;
|
||||
DATA_BLOB session_key;
|
||||
};
|
||||
|
||||
/* auth state for schannel. */
|
||||
struct schannel_auth_struct {
|
||||
uchar sess_key[16];
|
||||
uint32 seq_num;
|
||||
};
|
||||
|
||||
/* auth state for all bind types. */
|
||||
|
||||
struct pipe_auth_data {
|
||||
enum pipe_auth_type auth_type; /* switch for union below. */
|
||||
enum pipe_auth_level auth_level;
|
||||
union {
|
||||
struct schannel_auth_struct *schannel_auth;
|
||||
AUTH_NTLMSSP_STATE *auth_ntlmssp_state;
|
||||
/* struct kerberos_auth_struct *kerberos_auth; TO BE ADDED... */
|
||||
} a_u;
|
||||
void (*auth_data_free_func)(struct pipe_auth_data *);
|
||||
};
|
||||
|
||||
/*
|
||||
* DCE/RPC-specific samba-internal-specific handling of data on
|
||||
* NamedPipes.
|
||||
@ -210,20 +227,12 @@ typedef struct pipes_struct {
|
||||
RPC_HDR hdr; /* Incoming RPC header. */
|
||||
RPC_HDR_REQ hdr_req; /* Incoming request header. */
|
||||
|
||||
uint32 ntlmssp_chal_flags; /* Client challenge flags. */
|
||||
BOOL ntlmssp_auth_requested; /* If the client wanted authenticated rpc. */
|
||||
BOOL ntlmssp_auth_validated; /* If the client *got* authenticated rpc. */
|
||||
unsigned char challenge[8];
|
||||
unsigned char ntlmssp_hash[258];
|
||||
uint32 ntlmssp_seq_num;
|
||||
struct dcinfo dc; /* Keeps the creds data. */
|
||||
/* This context is used for pipe state storage and is freed when the pipe is closed. */
|
||||
TALLOC_CTX *pipe_state_mem_ctx;
|
||||
|
||||
/* Hmm. In my understanding the authentication happens
|
||||
implicitly later, so there are no two stages for
|
||||
schannel. */
|
||||
struct pipe_auth_data auth;
|
||||
|
||||
BOOL netsec_auth_validated;
|
||||
struct netsec_auth_struct netsec_auth;
|
||||
struct dcinfo *dc; /* Keeps the creds data from netlogon. */
|
||||
|
||||
/*
|
||||
* Windows user info.
|
||||
@ -233,12 +242,11 @@ typedef struct pipes_struct {
|
||||
fstring wks;
|
||||
|
||||
/*
|
||||
* Unix user name and credentials.
|
||||
* Unix user name and credentials used when a pipe is authenticated.
|
||||
*/
|
||||
|
||||
fstring pipe_user_name;
|
||||
struct current_user pipe_user;
|
||||
|
||||
DATA_BLOB session_key;
|
||||
|
||||
/*
|
||||
@ -277,7 +285,8 @@ typedef struct pipes_struct {
|
||||
|
||||
output_data out_data;
|
||||
|
||||
/* talloc context to use when allocating memory on this pipe. */
|
||||
/* This context is used for PUD data and is freed between each pdu.
|
||||
Don't use for pipe state storage. */
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
/* handle database to use on this pipe. */
|
||||
@ -383,27 +392,11 @@ typedef struct {
|
||||
|
||||
/* end higher order functions */
|
||||
|
||||
|
||||
/* security descriptor structures */
|
||||
#include "rpc_secdes.h"
|
||||
|
||||
/* pac */
|
||||
#include "authdata.h"
|
||||
|
||||
/* different dce/rpc pipes */
|
||||
#include "rpc_buffer.h"
|
||||
#include "rpc_lsa.h"
|
||||
#include "rpc_netlogon.h"
|
||||
#include "rpc_reg.h"
|
||||
#include "rpc_samr.h"
|
||||
#include "rpc_srvsvc.h"
|
||||
#include "rpc_wkssvc.h"
|
||||
#include "rpc_svcctl.h"
|
||||
#include "rpc_spoolss.h"
|
||||
#include "rpc_eventlog.h"
|
||||
#include "rpc_dfs.h"
|
||||
#include "rpc_ds.h"
|
||||
#include "rpc_echo.h"
|
||||
#include "rpc_shutdown.h"
|
||||
typedef struct {
|
||||
uint32 size;
|
||||
prs_struct prs;
|
||||
uint32 struct_start;
|
||||
uint32 string_at_end;
|
||||
} RPC_BUFFER;
|
||||
|
||||
#endif /* _NT_DOMAIN_H */
|
||||
|
@ -34,7 +34,8 @@ enum NTLM_MESSAGE_TYPE
|
||||
NTLMSSP_NEGOTIATE = 1,
|
||||
NTLMSSP_CHALLENGE = 2,
|
||||
NTLMSSP_AUTH = 3,
|
||||
NTLMSSP_UNKNOWN = 4
|
||||
NTLMSSP_UNKNOWN = 4,
|
||||
NTLMSSP_DONE = 5 /* samba final state */
|
||||
};
|
||||
|
||||
/* NTLMSSP negotiation flags */
|
||||
@ -61,13 +62,15 @@ enum NTLM_MESSAGE_TYPE
|
||||
#define NTLMSSP_CHAL_TARGET_INFO 0x00800000
|
||||
#define NTLMSSP_NEGOTIATE_128 0x20000000 /* 128-bit encryption */
|
||||
#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
|
||||
#define NTLMSSP_NEGOTIATE_080000000 0x80000000
|
||||
#define NTLMSSP_NEGOTIATE_56 0x80000000
|
||||
|
||||
#define NTLMSSP_NAME_TYPE_SERVER 0x01
|
||||
#define NTLMSSP_NAME_TYPE_DOMAIN 0x02
|
||||
#define NTLMSSP_NAME_TYPE_SERVER_DNS 0x03
|
||||
#define NTLMSSP_NAME_TYPE_DOMAIN_DNS 0x04
|
||||
|
||||
#define NTLMSSP_SIG_SIZE 16
|
||||
|
||||
typedef struct ntlmssp_state
|
||||
{
|
||||
TALLOC_CTX *mem_ctx;
|
||||
@ -142,23 +145,22 @@ typedef struct ntlmssp_state
|
||||
const char *(*get_global_myname)(void);
|
||||
const char *(*get_domain)(void);
|
||||
|
||||
/* SMB Signing */
|
||||
|
||||
uint32 ntlmssp_seq_num;
|
||||
|
||||
/* ntlmv2 */
|
||||
unsigned char send_sign_const[16];
|
||||
unsigned char send_seal_const[16];
|
||||
unsigned char recv_sign_const[16];
|
||||
unsigned char recv_seal_const[16];
|
||||
|
||||
unsigned char send_sign_hash[258];
|
||||
unsigned char send_seal_hash[258];
|
||||
unsigned char recv_sign_hash[258];
|
||||
unsigned char recv_seal_hash[258];
|
||||
unsigned char send_sign_key[16];
|
||||
unsigned char send_seal_key[16];
|
||||
unsigned char recv_sign_key[16];
|
||||
unsigned char recv_seal_key[16];
|
||||
|
||||
unsigned char send_seal_arc4_state[258];
|
||||
unsigned char recv_seal_arc4_state[258];
|
||||
|
||||
uint32 ntlm2_send_seq_num;
|
||||
uint32 ntlm2_recv_seq_num;
|
||||
|
||||
/* ntlmv1 */
|
||||
unsigned char ntlmssp_hash[258];
|
||||
unsigned char ntlmv1_arc4_state[258];
|
||||
uint32 ntlmv1_seq_num;
|
||||
|
||||
/* it turns out that we don't always get the
|
||||
response in at the time we want to process it.
|
||||
@ -166,4 +168,3 @@ typedef struct ntlmssp_state
|
||||
DATA_BLOB stored_response;
|
||||
|
||||
} NTLMSSP_STATE;
|
||||
|
||||
|
@ -233,6 +233,7 @@ struct acct_info
|
||||
};
|
||||
|
||||
struct samr_displayentry {
|
||||
uint32 idx;
|
||||
uint32 rid;
|
||||
uint16 acct_flags;
|
||||
const char *account_name;
|
||||
@ -268,7 +269,7 @@ struct pdb_search {
|
||||
* this SAMBA will load. Increment this if *ANY* changes are made to the interface.
|
||||
*/
|
||||
|
||||
#define PASSDB_INTERFACE_VERSION 8
|
||||
#define PASSDB_INTERFACE_VERSION 9
|
||||
|
||||
typedef struct pdb_context
|
||||
{
|
||||
@ -373,6 +374,14 @@ typedef struct pdb_context
|
||||
const char ***names,
|
||||
uint32 **attrs);
|
||||
|
||||
NTSTATUS (*pdb_get_account_policy)(struct pdb_context *context,
|
||||
int policy_index, uint32 *value);
|
||||
|
||||
NTSTATUS (*pdb_set_account_policy)(struct pdb_context *context,
|
||||
int policy_index, uint32 value);
|
||||
|
||||
NTSTATUS (*pdb_get_seq_num)(struct pdb_context *context, time_t *seq_num);
|
||||
|
||||
BOOL (*pdb_search_users)(struct pdb_context *context,
|
||||
struct pdb_search *search,
|
||||
uint16 acct_flags);
|
||||
@ -478,6 +487,7 @@ typedef struct pdb_methods
|
||||
int num_members,
|
||||
uint32 **alias_rids,
|
||||
int *num_alias_rids);
|
||||
|
||||
NTSTATUS (*lookup_rids)(struct pdb_methods *methods,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const DOM_SID *domain_sid,
|
||||
@ -486,6 +496,14 @@ typedef struct pdb_methods
|
||||
const char ***names,
|
||||
uint32 **attrs);
|
||||
|
||||
NTSTATUS (*get_account_policy)(struct pdb_methods *methods,
|
||||
int policy_index, uint32 *value);
|
||||
|
||||
NTSTATUS (*set_account_policy)(struct pdb_methods *methods,
|
||||
int policy_index, uint32 value);
|
||||
|
||||
NTSTATUS (*get_seq_num)(struct pdb_methods *methods, time_t *seq_num);
|
||||
|
||||
BOOL (*search_users)(struct pdb_methods *methods,
|
||||
struct pdb_search *search,
|
||||
uint16 acct_flags);
|
||||
|
@ -57,7 +57,7 @@ struct printif
|
||||
print_status_struct *status);
|
||||
int (*queue_pause)(int snum);
|
||||
int (*queue_resume)(int snum);
|
||||
int (*job_delete)(int snum, struct printjob *pjob);
|
||||
int (*job_delete)(const char *sharename, const char *lprm_command, struct printjob *pjob);
|
||||
int (*job_pause)(int snum, struct printjob *pjob);
|
||||
int (*job_resume)(int snum, struct printjob *pjob);
|
||||
int (*job_submit)(int snum, struct printjob *pjob);
|
||||
|
@ -23,35 +23,67 @@
|
||||
|
||||
/* macro to expand cookie-cutter code in cli_xxx() using rpc_api_pipe_req() */
|
||||
|
||||
#define CLI_DO_RPC( pcli, ctx, pipe_num, opnum, q_in, r_out, \
|
||||
#define CLI_DO_RPC( pcli, ctx, p_idx, opnum, q_in, r_out, \
|
||||
q_ps, r_ps, q_io_fn, r_io_fn, default_error ) \
|
||||
{ r_out.status = default_error;\
|
||||
prs_init( &q_ps, MAX_PDU_FRAG_LEN, ctx, MARSHALL ); \
|
||||
prs_init( &r_ps, 0, ctx, UNMARSHALL );\
|
||||
{\
|
||||
SMB_ASSERT(pcli->pipe_idx == p_idx); \
|
||||
if (!prs_init( &q_ps, RPC_MAX_PDU_FRAG_LEN, ctx, MARSHALL )) { \
|
||||
return NT_STATUS_NO_MEMORY;\
|
||||
}\
|
||||
if (!prs_init( &r_ps, 0, ctx, UNMARSHALL )) {\
|
||||
prs_mem_free( &q_ps );\
|
||||
return NT_STATUS_NO_MEMORY;\
|
||||
}\
|
||||
if ( q_io_fn("", &q_in, &q_ps, 0) ) {\
|
||||
if ( rpc_api_pipe_req(pcli, pipe_num, opnum, &q_ps, &r_ps) ) {\
|
||||
NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(pcli, opnum, &q_ps, &r_ps); \
|
||||
if (!NT_STATUS_IS_OK(_smb_pipe_stat_)) {\
|
||||
prs_mem_free( &q_ps );\
|
||||
prs_mem_free( &r_ps );\
|
||||
return _smb_pipe_stat_;\
|
||||
}\
|
||||
if (!r_io_fn("", &r_out, &r_ps, 0)) {\
|
||||
r_out.status = default_error;\
|
||||
}\
|
||||
prs_mem_free( &q_ps );\
|
||||
prs_mem_free( &r_ps );\
|
||||
return default_error;\
|
||||
}\
|
||||
} else {\
|
||||
prs_mem_free( &q_ps );\
|
||||
prs_mem_free( &r_ps );\
|
||||
return default_error;\
|
||||
}\
|
||||
prs_mem_free( &q_ps );\
|
||||
prs_mem_free( &r_ps );\
|
||||
}
|
||||
|
||||
/* macro to expand cookie-cutter code in cli_xxx() using rpc_api_pipe_req_int() */
|
||||
/* Arrrgg. Same but with WERRORS. Needed for registry code. */
|
||||
|
||||
#define CLI_DO_RPC_EX( pcli, ctx, pipe_num, opnum, q_in, r_out, \
|
||||
#define CLI_DO_RPC_WERR( pcli, ctx, p_idx, opnum, q_in, r_out, \
|
||||
q_ps, r_ps, q_io_fn, r_io_fn, default_error ) \
|
||||
{ r_out.status = default_error;\
|
||||
prs_init( &q_ps, MAX_PDU_FRAG_LEN, ctx, MARSHALL ); \
|
||||
prs_init( &r_ps, 0, ctx, UNMARSHALL );\
|
||||
{\
|
||||
SMB_ASSERT(pcli->pipe_idx == p_idx); \
|
||||
if (!prs_init( &q_ps, RPC_MAX_PDU_FRAG_LEN, ctx, MARSHALL )) { \
|
||||
return WERR_NOMEM;\
|
||||
}\
|
||||
if (!prs_init( &r_ps, 0, ctx, UNMARSHALL )) {\
|
||||
prs_mem_free( &q_ps );\
|
||||
return WERR_NOMEM;\
|
||||
}\
|
||||
if ( q_io_fn("", &q_in, &q_ps, 0) ) {\
|
||||
if ( rpc_api_pipe_req_int(pcli, opnum, &q_ps, &r_ps) ) {\
|
||||
NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(pcli, opnum, &q_ps, &r_ps); \
|
||||
if (!NT_STATUS_IS_OK(_smb_pipe_stat_)) {\
|
||||
prs_mem_free( &q_ps );\
|
||||
prs_mem_free( &r_ps );\
|
||||
return ntstatus_to_werror(_smb_pipe_stat_);\
|
||||
}\
|
||||
if (!r_io_fn("", &r_out, &r_ps, 0)) {\
|
||||
r_out.status = default_error;\
|
||||
}\
|
||||
prs_mem_free( &q_ps );\
|
||||
prs_mem_free( &r_ps );\
|
||||
return default_error;\
|
||||
}\
|
||||
} else {\
|
||||
prs_mem_free( &q_ps );\
|
||||
prs_mem_free( &r_ps );\
|
||||
return default_error;\
|
||||
}\
|
||||
prs_mem_free( &q_ps );\
|
||||
prs_mem_free( &r_ps );\
|
||||
|
@ -23,9 +23,6 @@
|
||||
#ifndef _DCE_RPC_H /* _DCE_RPC_H */
|
||||
#define _DCE_RPC_H
|
||||
|
||||
#include "rpc_misc.h" /* this only pulls in STRHDR */
|
||||
|
||||
|
||||
/* DCE/RPC packet types */
|
||||
|
||||
enum RPC_PKT_TYPE {
|
||||
@ -37,7 +34,7 @@ enum RPC_PKT_TYPE {
|
||||
RPC_BINDNACK = 0x0D,
|
||||
RPC_ALTCONT = 0x0E,
|
||||
RPC_ALTCONTRESP = 0x0F,
|
||||
RPC_BINDRESP = 0x10 /* not the real name! this is undocumented! */
|
||||
RPC_AUTH3 = 0x10 /* not the real name! this is undocumented! */
|
||||
};
|
||||
|
||||
/* DCE/RPC flags */
|
||||
@ -45,29 +42,41 @@ enum RPC_PKT_TYPE {
|
||||
#define RPC_FLG_LAST 0x02
|
||||
#define RPC_FLG_NOCALL 0x20
|
||||
|
||||
|
||||
#define SMBD_NTLMSSP_NEG_FLAGS 0x000082b1 /* ALWAYS_SIGN|NEG_NTLM|NEG_LM|NEG_SEAL|NEG_SIGN|NEG_UNICODE */
|
||||
|
||||
/* NTLMSSP signature version */
|
||||
#define NTLMSSP_SIGN_VERSION 0x01
|
||||
|
||||
/* NTLMSSP auth type */
|
||||
#define NTLMSSP_AUTH_TYPE 0xa
|
||||
/* DCE RPC auth types - extended by Microsoft. */
|
||||
#define RPC_ANONYMOUS_AUTH_TYPE 0
|
||||
#define RPC_AUTH_TYPE_KRB5_1 1
|
||||
#define RPC_SPNEGO_AUTH_TYPE 9
|
||||
#define RPC_NTLMSSP_AUTH_TYPE 10
|
||||
#define RPC_KRB5_AUTH_TYPE 16 /* Not yet implemented. */
|
||||
#define RPC_SCHANNEL_AUTH_TYPE 68 /* 0x44 */
|
||||
|
||||
/* DCE-RPC standard identifiers to indicate
|
||||
signing or sealing of an RPC pipe */
|
||||
#define RPC_AUTH_LEVEL_NONE 1
|
||||
#define RPC_AUTH_LEVEL_CONNECT 2
|
||||
#define RPC_AUTH_LEVEL_CALL 3
|
||||
#define RPC_AUTH_LEVEL_PACKET 4
|
||||
#define RPC_AUTH_LEVEL_INTEGRITY 5
|
||||
#define RPC_AUTH_LEVEL_PRIVACY 6
|
||||
|
||||
#if 0
|
||||
#define RPC_PIPE_AUTH_SIGN_LEVEL 0x5
|
||||
#define RPC_PIPE_AUTH_SEAL_LEVEL 0x6
|
||||
#endif
|
||||
|
||||
/* Netlogon schannel auth type and level */
|
||||
#define NETSEC_AUTH_TYPE 0x44
|
||||
#define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
|
||||
#define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
|
||||
#define SCHANNEL_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 }
|
||||
#define SCHANNEL_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
|
||||
|
||||
#define RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN 0x20
|
||||
#define RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN 0x18
|
||||
#define RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN 0x20
|
||||
#define RPC_AUTH_SCHANNEL_SIGN_ONLY_CHK_LEN 0x18
|
||||
|
||||
/* SPNEGO auth type. */
|
||||
#define SPNEGO_AUTH_TYPE 0x9
|
||||
|
||||
/* The 7 here seems to be required to get Win2k not to downgrade us
|
||||
to NT4. Actually, anything other than 1ff would seem to do... */
|
||||
@ -76,20 +85,17 @@ enum RPC_PKT_TYPE {
|
||||
#define NETLOGON_NEG_SCHANNEL 0x40000000
|
||||
#define NETLOGON_NEG_DOMAIN_TRUST_ACCOUNT 0x2010b000
|
||||
|
||||
enum netsec_direction {
|
||||
enum schannel_direction {
|
||||
SENDER_IS_INITIATOR,
|
||||
SENDER_IS_ACCEPTOR
|
||||
};
|
||||
|
||||
/* Internal Flags to indicate what type of authentication on the pipe */
|
||||
#define AUTH_PIPE_SIGN 0x0001
|
||||
#define AUTH_PIPE_SEAL 0x0002
|
||||
#define AUTH_PIPE_NTLMSSP 0x0004
|
||||
#define AUTH_PIPE_NETSEC 0x0008
|
||||
/* Maximum size of the signing data in a fragment. */
|
||||
#define RPC_MAX_SIGN_SIZE 0x20 /* 32 */
|
||||
|
||||
/* Maximum PDU fragment size. */
|
||||
/* #define MAX_PDU_FRAG_LEN 0x1630 this is what wnt sets */
|
||||
#define MAX_PDU_FRAG_LEN 0x10b8 /* this is what w2k sets */
|
||||
#define RPC_MAX_PDU_FRAG_LEN 0x10b8 /* this is what w2k sets */
|
||||
|
||||
/* RPC_IFACE */
|
||||
typedef struct rpc_iface_info {
|
||||
@ -163,7 +169,7 @@ typedef struct rpc_addr_info {
|
||||
fstring str; /* the string above in single byte, null terminated form */
|
||||
} RPC_ADDR_STR;
|
||||
|
||||
/* RPC_HDR_BBA */
|
||||
/* RPC_HDR_BBA - bind acknowledge, and alter context response. */
|
||||
typedef struct rpc_hdr_bba_info {
|
||||
uint16 max_tsize; /* maximum transmission fragment size (0x1630) */
|
||||
uint16 max_rsize; /* max receive fragment size (0x1630) */
|
||||
@ -183,39 +189,24 @@ typedef struct rpc_hdr_auth_info {
|
||||
|
||||
#define RPC_HDR_AUTH_LEN 8
|
||||
|
||||
/* RPC_HDR_AUTHA */
|
||||
typedef struct rpc_hdr_autha_info {
|
||||
uint16 max_tsize; /* maximum transmission fragment size (0x1630) */
|
||||
uint16 max_rsize; /* max receive fragment size (0x1630) */
|
||||
RPC_HDR_AUTH auth;
|
||||
} RPC_HDR_AUTHA;
|
||||
|
||||
#define RPC_HDR_AUTHA_LEN (RPC_HDR_AUTH_LEN+4)
|
||||
|
||||
/* this is TEMPORARILY coded up as a specific structure */
|
||||
/* this structure comes after the bind request */
|
||||
/* RPC_AUTH_NETSEC_NEG */
|
||||
typedef struct rpc_auth_netsec_neg_info {
|
||||
/* RPC_AUTH_SCHANNEL_NEG */
|
||||
typedef struct rpc_auth_schannel_neg_info {
|
||||
uint32 type1; /* Always zero ? */
|
||||
uint32 type2; /* Types 0x3 and 0x13 seen. Check AcquireSecurityContext() docs.... */
|
||||
fstring domain; /* calling workstations's domain */
|
||||
fstring myname; /* calling workstation's name */
|
||||
} RPC_AUTH_NETSEC_NEG;
|
||||
} RPC_AUTH_SCHANNEL_NEG;
|
||||
|
||||
/* attached to the end of encrypted rpc requests and responses */
|
||||
/* RPC_AUTH_NETSEC_CHK */
|
||||
typedef struct rpc_auth_netsec_chk_info {
|
||||
/* RPC_AUTH_SCHANNEL_CHK */
|
||||
typedef struct rpc_auth_schannel_chk_info {
|
||||
uint8 sig [8]; /* 77 00 7a 00 ff ff 00 00 */
|
||||
uint8 packet_digest[8]; /* checksum over the packet, MD5'ed with session key */
|
||||
uint8 seq_num[8]; /* verifier, seq num */
|
||||
uint8 confounder[8]; /* random 8-byte nonce */
|
||||
} RPC_AUTH_NETSEC_CHK;
|
||||
|
||||
struct netsec_auth_struct {
|
||||
uchar sess_key[16];
|
||||
uint32 seq_num;
|
||||
int auth_flags;
|
||||
};
|
||||
} RPC_AUTH_SCHANNEL_CHK;
|
||||
|
||||
typedef struct rpc_context {
|
||||
uint16 context_id; /* presentation context identifier. */
|
||||
@ -268,60 +259,4 @@ typedef struct rpc_auth_verif_info {
|
||||
uint32 msg_type; /* NTLMSSP_MESSAGE_TYPE (1,2,3) and 5 for schannel */
|
||||
} RPC_AUTH_VERIFIER;
|
||||
|
||||
/* this is TEMPORARILY coded up as a specific structure */
|
||||
/* this structure comes after the bind request */
|
||||
/* RPC_AUTH_NTLMSSP_NEG */
|
||||
|
||||
typedef struct rpc_auth_ntlmssp_neg_info {
|
||||
uint32 neg_flgs; /* 0x0000 b2b3 */
|
||||
|
||||
STRHDR hdr_myname; /* offset is against START of this structure */
|
||||
STRHDR hdr_domain; /* offset is against START of this structure */
|
||||
|
||||
fstring myname; /* calling workstation's name */
|
||||
fstring domain; /* calling workstations's domain */
|
||||
} RPC_AUTH_NTLMSSP_NEG;
|
||||
|
||||
/* this is TEMPORARILY coded up as a specific structure */
|
||||
/* this structure comes after the bind acknowledgement */
|
||||
/* RPC_AUTH_NTLMSSP_CHAL */
|
||||
typedef struct rpc_auth_ntlmssp_chal_info {
|
||||
uint32 unknown_1; /* 0x0000 0000 */
|
||||
uint32 unknown_2; /* 0x0000 0028 */
|
||||
uint32 neg_flags; /* 0x0000 82b1 */
|
||||
|
||||
uint8 challenge[8]; /* ntlm challenge */
|
||||
uint8 reserved [8]; /* zeros */
|
||||
} RPC_AUTH_NTLMSSP_CHAL;
|
||||
|
||||
|
||||
/* RPC_AUTH_NTLMSSP_RESP */
|
||||
typedef struct rpc_auth_ntlmssp_resp_info {
|
||||
STRHDR hdr_lm_resp; /* 24 byte response */
|
||||
STRHDR hdr_nt_resp; /* 24 byte response */
|
||||
STRHDR hdr_domain;
|
||||
STRHDR hdr_usr;
|
||||
STRHDR hdr_wks;
|
||||
STRHDR hdr_sess_key; /* NULL unless negotiated */
|
||||
uint32 neg_flags; /* 0x0000 82b1 */
|
||||
|
||||
fstring sess_key;
|
||||
fstring wks;
|
||||
fstring user;
|
||||
fstring domain;
|
||||
fstring nt_resp;
|
||||
fstring lm_resp;
|
||||
} RPC_AUTH_NTLMSSP_RESP;
|
||||
|
||||
/* attached to the end of encrypted rpc requests and responses */
|
||||
/* RPC_AUTH_NTLMSSP_CHK */
|
||||
typedef struct rpc_auth_ntlmssp_chk_info {
|
||||
uint32 ver; /* 0x0000 0001 */
|
||||
uint32 reserved;
|
||||
uint32 crc32; /* checksum using 0xEDB8 8320 as a polynomial */
|
||||
uint32 seq_num;
|
||||
} RPC_AUTH_NTLMSSP_CHK;
|
||||
|
||||
#define RPC_AUTH_NTLMSSP_CHK_LEN 16
|
||||
|
||||
#endif /* _DCE_RPC_H */
|
||||
|
@ -34,21 +34,16 @@
|
||||
#define DFSFLAG_ADD_VOLUME 0x00000001
|
||||
#define DFSFLAG_RESTORE_VOLUME 0x00000002
|
||||
|
||||
typedef struct dfs_q_dfs_exist
|
||||
{
|
||||
typedef struct dfs_q_dfs_exist {
|
||||
uint32 dummy;
|
||||
}
|
||||
DFS_Q_DFS_EXIST;
|
||||
} DFS_Q_DFS_EXIST;
|
||||
|
||||
/* status == 1 if dfs exists. */
|
||||
typedef struct dfs_r_dfs_exist
|
||||
{
|
||||
typedef struct dfs_r_dfs_exist {
|
||||
uint32 status; /* Not a WERROR or NTSTATUS code */
|
||||
}
|
||||
DFS_R_DFS_EXIST;
|
||||
} DFS_R_DFS_EXIST;
|
||||
|
||||
typedef struct dfs_q_dfs_add
|
||||
{
|
||||
typedef struct dfs_q_dfs_add {
|
||||
uint32 ptr_DfsEntryPath;
|
||||
UNISTR2 DfsEntryPath;
|
||||
uint32 ptr_ServerName;
|
||||
@ -58,63 +53,49 @@ typedef struct dfs_q_dfs_add
|
||||
uint32 ptr_Comment;
|
||||
UNISTR2 Comment;
|
||||
uint32 Flags;
|
||||
}
|
||||
DFS_Q_DFS_ADD;
|
||||
} DFS_Q_DFS_ADD;
|
||||
|
||||
typedef struct dfs_r_dfs_add
|
||||
{
|
||||
typedef struct dfs_r_dfs_add {
|
||||
WERROR status;
|
||||
}
|
||||
DFS_R_DFS_ADD;
|
||||
} DFS_R_DFS_ADD;
|
||||
|
||||
/********************************************/
|
||||
typedef struct dfs_q_dfs_remove
|
||||
{
|
||||
typedef struct dfs_q_dfs_remove {
|
||||
UNISTR2 DfsEntryPath;
|
||||
uint32 ptr_ServerName;
|
||||
UNISTR2 ServerName;
|
||||
uint32 ptr_ShareName;
|
||||
UNISTR2 ShareName;
|
||||
}
|
||||
DFS_Q_DFS_REMOVE;
|
||||
} DFS_Q_DFS_REMOVE;
|
||||
|
||||
typedef struct dfs_r_dfs_remove
|
||||
{
|
||||
typedef struct dfs_r_dfs_remove {
|
||||
WERROR status;
|
||||
}
|
||||
DFS_R_DFS_REMOVE;
|
||||
} DFS_R_DFS_REMOVE;
|
||||
|
||||
/********************************************/
|
||||
typedef struct dfs_info_1
|
||||
{
|
||||
typedef struct dfs_info_1 {
|
||||
uint32 ptr_entrypath;
|
||||
UNISTR2 entrypath;
|
||||
}
|
||||
DFS_INFO_1;
|
||||
} DFS_INFO_1;
|
||||
|
||||
typedef struct dfs_info_2
|
||||
{
|
||||
typedef struct dfs_info_2 {
|
||||
uint32 ptr_entrypath;
|
||||
UNISTR2 entrypath;
|
||||
uint32 ptr_comment;
|
||||
UNISTR2 comment;
|
||||
uint32 state;
|
||||
uint32 num_storages;
|
||||
}
|
||||
DFS_INFO_2;
|
||||
} DFS_INFO_2;
|
||||
|
||||
typedef struct dfs_storage_info
|
||||
{
|
||||
typedef struct dfs_storage_info {
|
||||
uint32 state;
|
||||
uint32 ptr_servername;
|
||||
UNISTR2 servername;
|
||||
uint32 ptr_sharename;
|
||||
UNISTR2 sharename;
|
||||
}
|
||||
DFS_STORAGE_INFO;
|
||||
} DFS_STORAGE_INFO;
|
||||
|
||||
typedef struct dfs_info_3
|
||||
{
|
||||
typedef struct dfs_info_3 {
|
||||
uint32 ptr_entrypath;
|
||||
UNISTR2 entrypath;
|
||||
uint32 ptr_comment;
|
||||
@ -124,26 +105,20 @@ typedef struct dfs_info_3
|
||||
uint32 ptr_storages;
|
||||
uint32 num_storage_infos;
|
||||
DFS_STORAGE_INFO* storages;
|
||||
}
|
||||
DFS_INFO_3;
|
||||
|
||||
typedef struct dfs_info_ctr
|
||||
{
|
||||
} DFS_INFO_3;
|
||||
|
||||
typedef struct dfs_info_ctr {
|
||||
uint32 switch_value;
|
||||
uint32 num_entries;
|
||||
uint32 ptr_dfs_ctr; /* pointer to dfs info union */
|
||||
union
|
||||
{
|
||||
union {
|
||||
DFS_INFO_1 *info1;
|
||||
DFS_INFO_2 *info2;
|
||||
DFS_INFO_3 *info3;
|
||||
} dfs;
|
||||
}
|
||||
DFS_INFO_CTR;
|
||||
} DFS_INFO_CTR;
|
||||
|
||||
typedef struct dfs_q_dfs_get_info
|
||||
{
|
||||
typedef struct dfs_q_dfs_get_info {
|
||||
UNISTR2 uni_path;
|
||||
|
||||
uint32 ptr_server;
|
||||
@ -153,20 +128,16 @@ typedef struct dfs_q_dfs_get_info
|
||||
UNISTR2 uni_share;
|
||||
|
||||
uint32 level;
|
||||
}
|
||||
DFS_Q_DFS_GET_INFO;
|
||||
} DFS_Q_DFS_GET_INFO;
|
||||
|
||||
typedef struct dfs_r_dfs_get_info
|
||||
{
|
||||
typedef struct dfs_r_dfs_get_info {
|
||||
uint32 level;
|
||||
uint32 ptr_ctr;
|
||||
DFS_INFO_CTR ctr;
|
||||
WERROR status;
|
||||
}
|
||||
DFS_R_DFS_GET_INFO;
|
||||
} DFS_R_DFS_GET_INFO;
|
||||
|
||||
typedef struct dfs_q_dfs_enum
|
||||
{
|
||||
typedef struct dfs_q_dfs_enum {
|
||||
uint32 level;
|
||||
uint32 maxpreflen;
|
||||
uint32 ptr_buffer;
|
||||
@ -176,11 +147,9 @@ typedef struct dfs_q_dfs_enum
|
||||
uint32 ptr_num_entries2;
|
||||
uint32 num_entries2;
|
||||
ENUM_HND reshnd;
|
||||
}
|
||||
DFS_Q_DFS_ENUM;
|
||||
} DFS_Q_DFS_ENUM;
|
||||
|
||||
typedef struct dfs_r_dfs_enum
|
||||
{
|
||||
typedef struct dfs_r_dfs_enum {
|
||||
DFS_INFO_CTR *ctr;
|
||||
uint32 ptr_buffer;
|
||||
uint32 level;
|
||||
@ -191,7 +160,5 @@ typedef struct dfs_r_dfs_enum
|
||||
uint32 num_entries2;
|
||||
ENUM_HND reshnd;
|
||||
WERROR status;
|
||||
}
|
||||
DFS_R_DFS_ENUM;
|
||||
|
||||
} DFS_R_DFS_ENUM;
|
||||
#endif
|
||||
|
@ -21,9 +21,6 @@
|
||||
#ifndef _RPC_DS_H /* _RPC_LSA_H */
|
||||
#define _RPC_DS_H
|
||||
|
||||
#include "rpc_misc.h"
|
||||
|
||||
|
||||
/* Opcodes available on PIPE_LSARPC_DS */
|
||||
|
||||
#define DS_GETPRIMDOMINFO 0x00
|
||||
|
@ -47,77 +47,74 @@
|
||||
#define EVENTLOG_AUDIT_FAILURE 0x0010
|
||||
|
||||
|
||||
typedef struct eventlog_q_open_eventlog
|
||||
{
|
||||
uint32 unknown1;
|
||||
/***********************************/
|
||||
|
||||
typedef struct {
|
||||
uint16 unknown1;
|
||||
uint16 unknown2;
|
||||
uint16 unknown3;
|
||||
uint16 sourcename_length;
|
||||
uint16 sourcename_size;
|
||||
uint32 sourcename_ptr;
|
||||
UNISTR2 sourcename;
|
||||
uint32 servername_ptr;
|
||||
UNISTR2 servername;
|
||||
}
|
||||
EVENTLOG_Q_OPEN_EVENTLOG;
|
||||
} EVENTLOG_OPEN_UNKNOWN0;
|
||||
|
||||
typedef struct eventlog_r_open_eventlog
|
||||
{
|
||||
typedef struct {
|
||||
EVENTLOG_OPEN_UNKNOWN0 *unknown0;
|
||||
UNISTR4 logname;
|
||||
UNISTR4 servername;
|
||||
uint32 unknown1;
|
||||
uint32 unknown2;
|
||||
} EVENTLOG_Q_OPEN_EVENTLOG;
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
WERROR status;
|
||||
}
|
||||
EVENTLOG_R_OPEN_EVENTLOG;
|
||||
} EVENTLOG_R_OPEN_EVENTLOG;
|
||||
|
||||
typedef struct eventlog_q_close_eventlog
|
||||
{
|
||||
|
||||
/***********************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
}
|
||||
EVENTLOG_Q_CLOSE_EVENTLOG;
|
||||
} EVENTLOG_Q_CLOSE_EVENTLOG;
|
||||
|
||||
typedef struct eventlog_r_close_eventlog
|
||||
{
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
WERROR status;
|
||||
}
|
||||
EVENTLOG_R_CLOSE_EVENTLOG;
|
||||
} EVENTLOG_R_CLOSE_EVENTLOG;
|
||||
|
||||
typedef struct eventlog_q_get_num_records
|
||||
{
|
||||
|
||||
/***********************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
}
|
||||
EVENTLOG_Q_GET_NUM_RECORDS;
|
||||
} EVENTLOG_Q_GET_NUM_RECORDS;
|
||||
|
||||
typedef struct eventlog_r_get_num_records
|
||||
{
|
||||
typedef struct {
|
||||
uint32 num_records;
|
||||
WERROR status;
|
||||
}
|
||||
EVENTLOG_R_GET_NUM_RECORDS;
|
||||
} EVENTLOG_R_GET_NUM_RECORDS;
|
||||
|
||||
typedef struct eventlog_q_get_oldest_entry
|
||||
{
|
||||
|
||||
/***********************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
}
|
||||
EVENTLOG_Q_GET_OLDEST_ENTRY;
|
||||
} EVENTLOG_Q_GET_OLDEST_ENTRY;
|
||||
|
||||
typedef struct eventlog_r_get_oldest_entry
|
||||
{
|
||||
typedef struct {
|
||||
uint32 oldest_entry;
|
||||
WERROR status;
|
||||
}
|
||||
EVENTLOG_R_GET_OLDEST_ENTRY;
|
||||
} EVENTLOG_R_GET_OLDEST_ENTRY;
|
||||
|
||||
typedef struct eventlog_q_read_eventlog
|
||||
|
||||
/***********************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
POLICY_HND handle;
|
||||
uint32 flags;
|
||||
uint32 offset;
|
||||
uint32 max_read_size;
|
||||
}
|
||||
EVENTLOG_Q_READ_EVENTLOG;
|
||||
} EVENTLOG_Q_READ_EVENTLOG;
|
||||
|
||||
typedef struct eventlog_record
|
||||
{
|
||||
typedef struct {
|
||||
uint32 length;
|
||||
uint32 reserved1;
|
||||
uint32 record_number;
|
||||
@ -136,8 +133,7 @@ typedef struct eventlog_record
|
||||
uint32 data_offset;
|
||||
} Eventlog_record;
|
||||
|
||||
typedef struct eventlog_data_record
|
||||
{
|
||||
typedef struct {
|
||||
uint32 source_name_len;
|
||||
wpstring source_name;
|
||||
uint32 computer_name_len;
|
||||
@ -151,8 +147,7 @@ typedef struct eventlog_data_record
|
||||
uint32 data_padding;
|
||||
} Eventlog_data_record;
|
||||
|
||||
typedef struct eventlog_entry
|
||||
{
|
||||
typedef struct eventlog_entry {
|
||||
Eventlog_record record;
|
||||
Eventlog_data_record data_record;
|
||||
uint8 *data;
|
||||
@ -160,8 +155,7 @@ typedef struct eventlog_entry
|
||||
struct eventlog_entry *next;
|
||||
} Eventlog_entry;
|
||||
|
||||
typedef struct eventlog_r_read_eventlog
|
||||
{
|
||||
typedef struct {
|
||||
uint32 num_bytes_in_resp;
|
||||
uint32 bytes_in_next_record;
|
||||
uint32 num_records;
|
||||
@ -170,24 +164,18 @@ typedef struct eventlog_r_read_eventlog
|
||||
uint32 sent_size;
|
||||
uint32 real_size;
|
||||
WERROR status;
|
||||
}
|
||||
EVENTLOG_R_READ_EVENTLOG;
|
||||
} EVENTLOG_R_READ_EVENTLOG;
|
||||
|
||||
typedef struct eventlog_q_clear_eventlog
|
||||
{
|
||||
|
||||
/***********************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
uint32 unknown1;
|
||||
uint16 backup_file_length;
|
||||
uint16 backup_file_size;
|
||||
uint32 backup_file_ptr;
|
||||
UNISTR2 backup_file;
|
||||
}
|
||||
EVENTLOG_Q_CLEAR_EVENTLOG;
|
||||
UNISTR4 backupfile;
|
||||
} EVENTLOG_Q_CLEAR_EVENTLOG;
|
||||
|
||||
typedef struct eventlog_r_clear_eventlog
|
||||
{
|
||||
typedef struct {
|
||||
WERROR status;
|
||||
}
|
||||
EVENTLOG_R_CLEAR_EVENTLOG;
|
||||
} EVENTLOG_R_CLEAR_EVENTLOG;
|
||||
|
||||
#endif /* _RPC_EVENTLOG_H */
|
||||
|
@ -24,8 +24,6 @@
|
||||
#ifndef _RPC_LSA_H /* _RPC_LSA_H */
|
||||
#define _RPC_LSA_H
|
||||
|
||||
#include "rpc_misc.h"
|
||||
|
||||
/* Opcodes available on PIPE_LSARPC */
|
||||
|
||||
#if 0 /* UNIMPLEMENTED */
|
||||
|
@ -21,9 +21,6 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "ntdomain.h"
|
||||
#include "rpc_dce.h"
|
||||
|
||||
#ifndef _RPC_MISC_H /* _RPC_MISC_H */
|
||||
#define _RPC_MISC_H
|
||||
|
||||
@ -302,8 +299,7 @@ typedef struct {
|
||||
**********************************************************************/
|
||||
|
||||
/* DOM_CLNT_SRV - client / server names */
|
||||
typedef struct clnt_srv_info
|
||||
{
|
||||
typedef struct clnt_srv_info {
|
||||
uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
|
||||
UNISTR2 uni_logon_srv; /* logon server name */
|
||||
uint32 undoc_buffer2; /* undocumented 32 bit buffer pointer */
|
||||
@ -311,8 +307,7 @@ typedef struct clnt_srv_info
|
||||
} DOM_CLNT_SRV;
|
||||
|
||||
/* DOM_LOG_INFO - login info */
|
||||
typedef struct log_info
|
||||
{
|
||||
typedef struct log_info {
|
||||
uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
|
||||
UNISTR2 uni_logon_srv; /* logon server name */
|
||||
UNISTR2 uni_acct_name; /* account name */
|
||||
@ -321,89 +316,44 @@ typedef struct log_info
|
||||
} DOM_LOG_INFO;
|
||||
|
||||
/* DOM_CHAL - challenge info */
|
||||
typedef struct chal_info
|
||||
{
|
||||
typedef struct chal_info {
|
||||
uchar data[8]; /* credentials */
|
||||
} DOM_CHAL;
|
||||
|
||||
/* DOM_CREDs - timestamped client or server credentials */
|
||||
typedef struct cred_info
|
||||
{
|
||||
typedef struct cred_info {
|
||||
DOM_CHAL challenge; /* credentials */
|
||||
UTIME timestamp; /* credential time-stamp */
|
||||
} DOM_CRED;
|
||||
|
||||
/* DOM_CLNT_INFO - client info */
|
||||
typedef struct clnt_info
|
||||
{
|
||||
typedef struct clnt_info {
|
||||
DOM_LOG_INFO login;
|
||||
DOM_CRED cred;
|
||||
} DOM_CLNT_INFO;
|
||||
|
||||
/* DOM_CLNT_INFO2 - client info */
|
||||
typedef struct clnt_info2
|
||||
{
|
||||
typedef struct clnt_info2 {
|
||||
DOM_CLNT_SRV login;
|
||||
uint32 ptr_cred;
|
||||
DOM_CRED cred;
|
||||
} DOM_CLNT_INFO2;
|
||||
|
||||
/* DOM_LOGON_ID - logon id */
|
||||
typedef struct logon_info
|
||||
{
|
||||
typedef struct logon_info {
|
||||
uint32 low;
|
||||
uint32 high;
|
||||
} DOM_LOGON_ID;
|
||||
|
||||
/* OWF INFO */
|
||||
typedef struct owf_info
|
||||
{
|
||||
typedef struct owf_info {
|
||||
uint8 data[16];
|
||||
} OWF_INFO;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A client connection's state, pipe name,
|
||||
* user credentials, etc...
|
||||
*/
|
||||
typedef struct _cli_auth_fns cli_auth_fns;
|
||||
struct user_creds;
|
||||
struct cli_connection {
|
||||
|
||||
char *srv_name;
|
||||
char *pipe_name;
|
||||
struct user_creds usr_creds;
|
||||
|
||||
struct cli_state *pCli_state;
|
||||
|
||||
cli_auth_fns *auth;
|
||||
|
||||
void *auth_info;
|
||||
void *auth_creds;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Associate a POLICY_HND with a cli_connection
|
||||
*/
|
||||
typedef struct rpc_hnd_node {
|
||||
|
||||
POLICY_HND hnd;
|
||||
struct cli_connection *cli;
|
||||
|
||||
} RPC_HND_NODE;
|
||||
|
||||
typedef struct uint64_s
|
||||
{
|
||||
uint32 low;
|
||||
uint32 high;
|
||||
} UINT64_S;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* _RPC_MISC_H */
|
||||
|
@ -84,11 +84,22 @@
|
||||
#define NL_CTRL_REPL_IN_PROGRESS 0x0002
|
||||
#define NL_CTRL_FULL_SYNC 0x0004
|
||||
|
||||
#define LOGON_EXTRA_SIDS 0x0020
|
||||
#define LOGON_RESOURCE_GROUPS 0x0200
|
||||
|
||||
#define SE_GROUP_MANDATORY 0x00000001
|
||||
#define SE_GROUP_ENABLED_BY_DEFAULT 0x00000002
|
||||
#define SE_GROUP_ENABLED 0x00000004
|
||||
#define SE_GROUP_OWNER 0x00000008
|
||||
#define SE_GROUP_USE_FOR_DENY_ONLY 0x00000010
|
||||
#define SE_GROUP_LOGON_ID 0xC0000000
|
||||
#define SE_GROUP_RESOURCE 0x20000000
|
||||
|
||||
|
||||
#if 0
|
||||
/* I think this is correct - it's what gets parsed on the wire. JRA. */
|
||||
/* NET_USER_INFO_2 */
|
||||
typedef struct net_user_info_2
|
||||
{
|
||||
typedef struct net_user_info_2 {
|
||||
uint32 ptr_user_info;
|
||||
|
||||
NTTIME logon_time; /* logon time */
|
||||
@ -145,8 +156,7 @@ typedef struct net_user_info_2
|
||||
#endif
|
||||
|
||||
/* NET_USER_INFO_3 */
|
||||
typedef struct net_user_info_3
|
||||
{
|
||||
typedef struct net_user_info_3 {
|
||||
uint32 ptr_user_info;
|
||||
|
||||
NTTIME logon_time; /* logon time */
|
||||
@ -186,6 +196,13 @@ typedef struct net_user_info_3
|
||||
uint32 num_other_sids; /* number of foreign/trusted domain sids */
|
||||
uint32 buffer_other_sids;
|
||||
|
||||
/* The next three uint32 are not really part of user_info_3 but here
|
||||
* for parsing convenience. They are only valid in Kerberos PAC
|
||||
* parsing - Guenther */
|
||||
uint32 ptr_res_group_dom_sid;
|
||||
uint32 res_group_count;
|
||||
uint32 ptr_res_groups;
|
||||
|
||||
UNISTR2 uni_user_name; /* username unicode string */
|
||||
UNISTR2 uni_full_name; /* user's full name unicode string */
|
||||
UNISTR2 uni_logon_script; /* logon script unicode string */
|
||||
@ -203,32 +220,26 @@ typedef struct net_user_info_3
|
||||
|
||||
DOM_SID2 *other_sids; /* foreign/trusted domain SIDs */
|
||||
uint32 *other_sids_attrib;
|
||||
|
||||
} NET_USER_INFO_3;
|
||||
|
||||
|
||||
/* NETLOGON_INFO_1 - pdc status info, i presume */
|
||||
typedef struct netlogon_1_info
|
||||
{
|
||||
typedef struct netlogon_1_info {
|
||||
uint32 flags; /* 0x0 - undocumented */
|
||||
uint32 pdc_status; /* 0x0 - undocumented */
|
||||
|
||||
} NETLOGON_INFO_1;
|
||||
|
||||
/* NETLOGON_INFO_2 - pdc status info, plus trusted domain info */
|
||||
typedef struct netlogon_2_info
|
||||
{
|
||||
typedef struct netlogon_2_info {
|
||||
uint32 flags; /* 0x0 - undocumented */
|
||||
uint32 pdc_status; /* 0x0 - undocumented */
|
||||
uint32 ptr_trusted_dc_name; /* pointer to trusted domain controller name */
|
||||
uint32 tc_status;
|
||||
UNISTR2 uni_trusted_dc_name; /* unicode string - trusted dc name */
|
||||
|
||||
} NETLOGON_INFO_2;
|
||||
|
||||
/* NETLOGON_INFO_3 - logon status info, i presume */
|
||||
typedef struct netlogon_3_info
|
||||
{
|
||||
typedef struct netlogon_3_info {
|
||||
uint32 flags; /* 0x0 - undocumented */
|
||||
uint32 logon_attempts; /* number of logon attempts */
|
||||
uint32 reserved_1; /* 0x0 - undocumented */
|
||||
@ -236,7 +247,6 @@ typedef struct netlogon_3_info
|
||||
uint32 reserved_3; /* 0x0 - undocumented */
|
||||
uint32 reserved_4; /* 0x0 - undocumented */
|
||||
uint32 reserved_5; /* 0x0 - undocumented */
|
||||
|
||||
} NETLOGON_INFO_3;
|
||||
|
||||
/********************************************************
|
||||
@ -250,8 +260,7 @@ typedef struct netlogon_3_info
|
||||
|
||||
/* NET_Q_LOGON_CTRL - LSA Netr Logon Control */
|
||||
|
||||
typedef struct net_q_logon_ctrl_info
|
||||
{
|
||||
typedef struct net_q_logon_ctrl_info {
|
||||
uint32 ptr;
|
||||
UNISTR2 uni_server_name;
|
||||
uint32 function_code;
|
||||
@ -260,8 +269,7 @@ typedef struct net_q_logon_ctrl_info
|
||||
|
||||
/* NET_R_LOGON_CTRL - LSA Netr Logon Control */
|
||||
|
||||
typedef struct net_r_logon_ctrl_info
|
||||
{
|
||||
typedef struct net_r_logon_ctrl_info {
|
||||
uint32 switch_value;
|
||||
uint32 ptr;
|
||||
|
||||
@ -273,22 +281,18 @@ typedef struct net_r_logon_ctrl_info
|
||||
} NET_R_LOGON_CTRL;
|
||||
|
||||
|
||||
typedef struct ctrl_data_info_5
|
||||
{
|
||||
typedef struct ctrl_data_info_5 {
|
||||
uint32 function_code;
|
||||
|
||||
uint32 ptr_domain;
|
||||
UNISTR2 domain;
|
||||
|
||||
} CTRL_DATA_INFO_5;
|
||||
|
||||
typedef struct ctrl_data_info_6
|
||||
{
|
||||
typedef struct ctrl_data_info_6 {
|
||||
uint32 function_code;
|
||||
|
||||
uint32 ptr_domain;
|
||||
UNISTR2 domain;
|
||||
|
||||
} CTRL_DATA_INFO_6;
|
||||
|
||||
|
||||
@ -301,8 +305,7 @@ typedef struct ctrl_data_info_6
|
||||
********************************************************/
|
||||
|
||||
/* NET_Q_LOGON_CTRL2 - LSA Netr Logon Control 2 */
|
||||
typedef struct net_q_logon_ctrl2_info
|
||||
{
|
||||
typedef struct net_q_logon_ctrl2_info {
|
||||
uint32 ptr; /* undocumented buffer pointer */
|
||||
UNISTR2 uni_server_name; /* server name, starting with two '\'s */
|
||||
|
||||
@ -312,7 +315,6 @@ typedef struct net_q_logon_ctrl2_info
|
||||
CTRL_DATA_INFO_5 info5;
|
||||
CTRL_DATA_INFO_6 info6;
|
||||
} info;
|
||||
|
||||
} NET_Q_LOGON_CTRL2;
|
||||
|
||||
/*******************************************************
|
||||
@ -322,8 +324,7 @@ typedef struct net_q_logon_ctrl2_info
|
||||
*******************************************************/
|
||||
|
||||
/* NET_R_LOGON_CTRL2 - response to LSA Logon Control2 */
|
||||
typedef struct net_r_logon_ctrl2_info
|
||||
{
|
||||
typedef struct net_r_logon_ctrl2_info {
|
||||
uint32 switch_value; /* 0x1, 0x3 */
|
||||
uint32 ptr;
|
||||
|
||||
@ -336,13 +337,11 @@ typedef struct net_r_logon_ctrl2_info
|
||||
} logon;
|
||||
|
||||
NTSTATUS status; /* return code */
|
||||
|
||||
} NET_R_LOGON_CTRL2;
|
||||
|
||||
/* NET_Q_GETDCNAME - Ask a DC for a trusted DC name */
|
||||
|
||||
typedef struct net_q_getdcname
|
||||
{
|
||||
typedef struct net_q_getdcname {
|
||||
uint32 ptr_logon_server;
|
||||
UNISTR2 uni_logon_server;
|
||||
uint32 ptr_domainname;
|
||||
@ -351,103 +350,86 @@ typedef struct net_q_getdcname
|
||||
|
||||
/* NET_R_GETDCNAME - Ask a DC for a trusted DC name */
|
||||
|
||||
typedef struct net_r_getdcname
|
||||
{
|
||||
typedef struct net_r_getdcname {
|
||||
uint32 ptr_dcname;
|
||||
UNISTR2 uni_dcname;
|
||||
NTSTATUS status;
|
||||
} NET_R_GETDCNAME;
|
||||
|
||||
/* NET_Q_TRUST_DOM_LIST - LSA Query Trusted Domains */
|
||||
typedef struct net_q_trust_dom_info
|
||||
{
|
||||
typedef struct net_q_trust_dom_info {
|
||||
uint32 ptr; /* undocumented buffer pointer */
|
||||
UNISTR2 uni_server_name; /* server name, starting with two '\'s */
|
||||
|
||||
} NET_Q_TRUST_DOM_LIST;
|
||||
|
||||
#define MAX_TRUST_DOMS 1
|
||||
|
||||
/* NET_R_TRUST_DOM_LIST - response to LSA Trusted Domains */
|
||||
typedef struct net_r_trust_dom_info
|
||||
{
|
||||
typedef struct net_r_trust_dom_info {
|
||||
UNISTR2 uni_trust_dom_name[MAX_TRUST_DOMS];
|
||||
|
||||
NTSTATUS status; /* return code */
|
||||
|
||||
} NET_R_TRUST_DOM_LIST;
|
||||
|
||||
|
||||
/* NEG_FLAGS */
|
||||
typedef struct neg_flags_info
|
||||
{
|
||||
typedef struct neg_flags_info {
|
||||
uint32 neg_flags; /* negotiated flags */
|
||||
|
||||
} NEG_FLAGS;
|
||||
|
||||
|
||||
/* NET_Q_REQ_CHAL */
|
||||
typedef struct net_q_req_chal_info
|
||||
{
|
||||
typedef struct net_q_req_chal_info {
|
||||
uint32 undoc_buffer; /* undocumented buffer pointer */
|
||||
UNISTR2 uni_logon_srv; /* logon server unicode string */
|
||||
UNISTR2 uni_logon_clnt; /* logon client unicode string */
|
||||
DOM_CHAL clnt_chal; /* client challenge */
|
||||
|
||||
} NET_Q_REQ_CHAL;
|
||||
|
||||
|
||||
/* NET_R_REQ_CHAL */
|
||||
typedef struct net_r_req_chal_info
|
||||
{
|
||||
typedef struct net_r_req_chal_info {
|
||||
DOM_CHAL srv_chal; /* server challenge */
|
||||
NTSTATUS status; /* return code */
|
||||
} NET_R_REQ_CHAL;
|
||||
|
||||
/* NET_Q_AUTH */
|
||||
typedef struct net_q_auth_info
|
||||
{
|
||||
typedef struct net_q_auth_info {
|
||||
DOM_LOG_INFO clnt_id; /* client identification info */
|
||||
DOM_CHAL clnt_chal; /* client-calculated credentials */
|
||||
} NET_Q_AUTH;
|
||||
|
||||
/* NET_R_AUTH */
|
||||
typedef struct net_r_auth_info
|
||||
{
|
||||
typedef struct net_r_auth_info {
|
||||
DOM_CHAL srv_chal; /* server-calculated credentials */
|
||||
NTSTATUS status; /* return code */
|
||||
} NET_R_AUTH;
|
||||
|
||||
/* NET_Q_AUTH_2 */
|
||||
typedef struct net_q_auth2_info
|
||||
{
|
||||
typedef struct net_q_auth2_info {
|
||||
DOM_LOG_INFO clnt_id; /* client identification info */
|
||||
DOM_CHAL clnt_chal; /* client-calculated credentials */
|
||||
|
||||
NEG_FLAGS clnt_flgs; /* usually 0x0000 01ff */
|
||||
|
||||
} NET_Q_AUTH_2;
|
||||
|
||||
|
||||
/* NET_R_AUTH_2 */
|
||||
typedef struct net_r_auth2_info
|
||||
{
|
||||
typedef struct net_r_auth2_info {
|
||||
DOM_CHAL srv_chal; /* server-calculated credentials */
|
||||
NEG_FLAGS srv_flgs; /* usually 0x0000 01ff */
|
||||
NTSTATUS status; /* return code */
|
||||
} NET_R_AUTH_2;
|
||||
|
||||
/* NET_Q_AUTH_3 */
|
||||
typedef struct net_q_auth3_info
|
||||
{
|
||||
typedef struct net_q_auth3_info {
|
||||
DOM_LOG_INFO clnt_id; /* client identification info */
|
||||
DOM_CHAL clnt_chal; /* client-calculated credentials */
|
||||
NEG_FLAGS clnt_flgs; /* usually 0x6007 ffff */
|
||||
} NET_Q_AUTH_3;
|
||||
|
||||
/* NET_R_AUTH_3 */
|
||||
typedef struct net_r_auth3_info
|
||||
{
|
||||
typedef struct net_r_auth3_info {
|
||||
DOM_CHAL srv_chal; /* server-calculated credentials */
|
||||
NEG_FLAGS srv_flgs; /* usually 0x6007 ffff */
|
||||
uint32 unknown; /* 0x0000045b */
|
||||
@ -456,25 +438,20 @@ typedef struct net_r_auth3_info
|
||||
|
||||
|
||||
/* NET_Q_SRV_PWSET */
|
||||
typedef struct net_q_srv_pwset_info
|
||||
{
|
||||
typedef struct net_q_srv_pwset_info {
|
||||
DOM_CLNT_INFO clnt_id; /* client identification/authentication info */
|
||||
uint8 pwd[16]; /* new password - undocumented. */
|
||||
|
||||
} NET_Q_SRV_PWSET;
|
||||
|
||||
/* NET_R_SRV_PWSET */
|
||||
typedef struct net_r_srv_pwset_info
|
||||
{
|
||||
typedef struct net_r_srv_pwset_info {
|
||||
DOM_CRED srv_cred; /* server-calculated credentials */
|
||||
|
||||
NTSTATUS status; /* return code */
|
||||
|
||||
} NET_R_SRV_PWSET;
|
||||
|
||||
/* NET_ID_INFO_2 */
|
||||
typedef struct net_network_info_2
|
||||
{
|
||||
typedef struct net_network_info_2 {
|
||||
uint32 ptr_id_info2; /* pointer to id_info_2 */
|
||||
UNIHDR hdr_domain_name; /* domain name unicode header */
|
||||
uint32 param_ctrl; /* param control (0x2) */
|
||||
@ -490,12 +467,10 @@ typedef struct net_network_info_2
|
||||
UNISTR2 uni_wksta_name; /* workgroup name unicode string */
|
||||
STRING2 nt_chal_resp; /* nt challenge response */
|
||||
STRING2 lm_chal_resp; /* lm challenge response */
|
||||
|
||||
} NET_ID_INFO_2;
|
||||
|
||||
/* NET_ID_INFO_1 */
|
||||
typedef struct id_info_1
|
||||
{
|
||||
typedef struct id_info_1 {
|
||||
uint32 ptr_id_info1; /* pointer to id_info_1 */
|
||||
UNIHDR hdr_domain_name; /* domain name unicode header */
|
||||
uint32 param_ctrl; /* param control */
|
||||
@ -507,48 +482,38 @@ typedef struct id_info_1
|
||||
UNISTR2 uni_domain_name; /* domain name unicode string */
|
||||
UNISTR2 uni_user_name; /* user name unicode string */
|
||||
UNISTR2 uni_wksta_name; /* workgroup name unicode string */
|
||||
|
||||
} NET_ID_INFO_1;
|
||||
|
||||
#define INTERACTIVE_LOGON_TYPE 1
|
||||
#define NET_LOGON_TYPE 2
|
||||
|
||||
/* NET_ID_INFO_CTR */
|
||||
typedef struct net_id_info_ctr_info
|
||||
{
|
||||
typedef struct net_id_info_ctr_info {
|
||||
uint16 switch_value;
|
||||
|
||||
union
|
||||
{
|
||||
union {
|
||||
NET_ID_INFO_1 id1; /* auth-level 1 - interactive user login */
|
||||
NET_ID_INFO_2 id2; /* auth-level 2 - workstation referred login */
|
||||
|
||||
} auth;
|
||||
|
||||
} NET_ID_INFO_CTR;
|
||||
|
||||
/* SAM_INFO - sam logon/off id structure */
|
||||
typedef struct sam_info
|
||||
{
|
||||
typedef struct sam_info {
|
||||
DOM_CLNT_INFO2 client;
|
||||
uint32 ptr_rtn_cred; /* pointer to return credentials */
|
||||
DOM_CRED rtn_cred; /* return credentials */
|
||||
uint16 logon_level;
|
||||
NET_ID_INFO_CTR *ctr;
|
||||
|
||||
} DOM_SAM_INFO;
|
||||
|
||||
/* NET_Q_SAM_LOGON */
|
||||
typedef struct net_q_sam_logon_info
|
||||
{
|
||||
typedef struct net_q_sam_logon_info {
|
||||
DOM_SAM_INFO sam_id;
|
||||
uint16 validation_level;
|
||||
|
||||
} NET_Q_SAM_LOGON;
|
||||
|
||||
/* NET_R_SAM_LOGON */
|
||||
typedef struct net_r_sam_logon_info
|
||||
{
|
||||
typedef struct net_r_sam_logon_info {
|
||||
uint32 buffer_creds; /* undocumented buffer pointer */
|
||||
DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
|
||||
|
||||
@ -558,30 +523,23 @@ typedef struct net_r_sam_logon_info
|
||||
uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
|
||||
|
||||
NTSTATUS status; /* return code */
|
||||
|
||||
} NET_R_SAM_LOGON;
|
||||
|
||||
|
||||
/* NET_Q_SAM_LOGOFF */
|
||||
typedef struct net_q_sam_logoff_info
|
||||
{
|
||||
typedef struct net_q_sam_logoff_info {
|
||||
DOM_SAM_INFO sam_id;
|
||||
|
||||
} NET_Q_SAM_LOGOFF;
|
||||
|
||||
/* NET_R_SAM_LOGOFF */
|
||||
typedef struct net_r_sam_logoff_info
|
||||
{
|
||||
typedef struct net_r_sam_logoff_info {
|
||||
uint32 buffer_creds; /* undocumented buffer pointer */
|
||||
DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
|
||||
|
||||
NTSTATUS status; /* return code */
|
||||
|
||||
} NET_R_SAM_LOGOFF;
|
||||
|
||||
/* NET_Q_SAM_SYNC */
|
||||
typedef struct net_q_sam_sync_info
|
||||
{
|
||||
typedef struct net_q_sam_sync_info {
|
||||
UNISTR2 uni_srv_name; /* \\PDC */
|
||||
UNISTR2 uni_cli_name; /* BDC */
|
||||
DOM_CRED cli_creds;
|
||||
@ -592,19 +550,16 @@ typedef struct net_q_sam_sync_info
|
||||
uint32 sync_context;
|
||||
|
||||
uint32 max_size; /* preferred maximum length */
|
||||
|
||||
} NET_Q_SAM_SYNC;
|
||||
|
||||
/* SAM_DELTA_HDR */
|
||||
typedef struct sam_delta_hdr_info
|
||||
{
|
||||
typedef struct sam_delta_hdr_info {
|
||||
uint16 type; /* type of structure attached */
|
||||
uint16 type2;
|
||||
uint32 target_rid;
|
||||
|
||||
uint32 type3;
|
||||
uint32 ptr_delta;
|
||||
|
||||
} SAM_DELTA_HDR;
|
||||
|
||||
/* LOCKOUT_STRING */
|
||||
@ -617,7 +572,6 @@ typedef struct account_lockout_string {
|
||||
UINT64_S reset_count;
|
||||
uint32 bad_attempt_lockout;
|
||||
uint32 dummy;
|
||||
|
||||
} LOCKOUT_STRING;
|
||||
|
||||
/* HDR_LOCKOUT_STRING */
|
||||
@ -625,12 +579,10 @@ typedef struct hdr_account_lockout_string {
|
||||
uint16 size;
|
||||
uint16 length;
|
||||
uint32 buffer;
|
||||
|
||||
} HDR_LOCKOUT_STRING;
|
||||
|
||||
/* SAM_DOMAIN_INFO (0x1) */
|
||||
typedef struct sam_domain_info_info
|
||||
{
|
||||
typedef struct sam_domain_info_info {
|
||||
UNIHDR hdr_dom_name;
|
||||
UNIHDR hdr_oem_info;
|
||||
|
||||
@ -666,13 +618,10 @@ typedef struct sam_domain_info_info
|
||||
uint32 unknown6;
|
||||
uint32 unknown7;
|
||||
uint32 unknown8;
|
||||
|
||||
|
||||
} SAM_DOMAIN_INFO;
|
||||
|
||||
/* SAM_GROUP_INFO (0x2) */
|
||||
typedef struct sam_group_info_info
|
||||
{
|
||||
typedef struct sam_group_info_info {
|
||||
UNIHDR hdr_grp_name;
|
||||
DOM_GID gid;
|
||||
UNIHDR hdr_grp_desc;
|
||||
@ -682,12 +631,10 @@ typedef struct sam_group_info_info
|
||||
UNISTR2 uni_grp_name;
|
||||
UNISTR2 uni_grp_desc;
|
||||
RPC_DATA_BLOB buf_sec_desc;
|
||||
|
||||
} SAM_GROUP_INFO;
|
||||
|
||||
/* SAM_PWD */
|
||||
typedef struct sam_passwd_info
|
||||
{
|
||||
typedef struct sam_passwd_info {
|
||||
/* this structure probably contains password history */
|
||||
/* this is probably a count of lm/nt pairs */
|
||||
uint32 unk_0; /* 0x0000 0002 */
|
||||
@ -700,12 +647,10 @@ typedef struct sam_passwd_info
|
||||
|
||||
UNIHDR hdr_empty_lm;
|
||||
UNIHDR hdr_empty_nt;
|
||||
|
||||
} SAM_PWD;
|
||||
|
||||
/* SAM_ACCOUNT_INFO (0x5) */
|
||||
typedef struct sam_account_info_info
|
||||
{
|
||||
typedef struct sam_account_info_info {
|
||||
UNIHDR hdr_acct_name;
|
||||
UNIHDR hdr_full_name;
|
||||
|
||||
@ -765,12 +710,10 @@ typedef struct sam_account_info_info
|
||||
SAM_PWD pass;
|
||||
RPC_DATA_BLOB buf_sec_desc;
|
||||
UNISTR2 uni_profile;
|
||||
|
||||
} SAM_ACCOUNT_INFO;
|
||||
|
||||
/* SAM_GROUP_MEM_INFO (0x8) */
|
||||
typedef struct sam_group_mem_info_info
|
||||
{
|
||||
typedef struct sam_group_mem_info_info {
|
||||
uint32 ptr_rids;
|
||||
uint32 ptr_attribs;
|
||||
uint32 num_members;
|
||||
@ -785,8 +728,7 @@ typedef struct sam_group_mem_info_info
|
||||
} SAM_GROUP_MEM_INFO;
|
||||
|
||||
/* SAM_ALIAS_INFO (0x9) */
|
||||
typedef struct sam_alias_info_info
|
||||
{
|
||||
typedef struct sam_alias_info_info {
|
||||
UNIHDR hdr_als_name;
|
||||
uint32 als_rid;
|
||||
BUFHDR2 hdr_sec_desc; /* security descriptor */
|
||||
@ -796,12 +738,10 @@ typedef struct sam_alias_info_info
|
||||
UNISTR2 uni_als_name;
|
||||
RPC_DATA_BLOB buf_sec_desc;
|
||||
UNISTR2 uni_als_desc;
|
||||
|
||||
} SAM_ALIAS_INFO;
|
||||
|
||||
/* SAM_ALIAS_MEM_INFO (0xC) */
|
||||
typedef struct sam_alias_mem_info_info
|
||||
{
|
||||
typedef struct sam_alias_mem_info_info {
|
||||
uint32 num_members;
|
||||
uint32 ptr_members;
|
||||
uint8 unknown[16];
|
||||
@ -809,13 +749,11 @@ typedef struct sam_alias_mem_info_info
|
||||
uint32 num_sids;
|
||||
uint32 *ptr_sids;
|
||||
DOM_SID2 *sids;
|
||||
|
||||
} SAM_ALIAS_MEM_INFO;
|
||||
|
||||
|
||||
/* SAM_DELTA_POLICY (0x0D) */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint32 max_log_size; /* 0x5000 */
|
||||
UINT64_S audit_retention_period; /* 0 */
|
||||
uint32 auditing_mode; /* 0 */
|
||||
@ -844,8 +782,7 @@ typedef struct
|
||||
} SAM_DELTA_POLICY;
|
||||
|
||||
/* SAM_DELTA_TRUST_DOMS */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint32 buf_size;
|
||||
SEC_DESC *sec_desc;
|
||||
DOM_SID2 sid;
|
||||
@ -860,12 +797,10 @@ typedef struct
|
||||
|
||||
uint32 unknown3;
|
||||
UNISTR2 domain;
|
||||
|
||||
} SAM_DELTA_TRUSTDOMS;
|
||||
|
||||
/* SAM_DELTA_PRIVS (0x10) */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
DOM_SID2 sid;
|
||||
|
||||
uint32 priv_count;
|
||||
@ -896,8 +831,7 @@ typedef struct
|
||||
} SAM_DELTA_PRIVS;
|
||||
|
||||
/* SAM_DELTA_SECRET */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint32 buf_size;
|
||||
SEC_DESC *sec_desc;
|
||||
UNISTR2 secret;
|
||||
@ -928,19 +862,16 @@ typedef struct
|
||||
|
||||
uint32 buf_size3;
|
||||
SEC_DESC *sec_desc2;
|
||||
|
||||
} SAM_DELTA_SECRET;
|
||||
|
||||
/* SAM_DELTA_MOD_COUNT (0x16) */
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
uint32 seqnum;
|
||||
uint32 dom_mod_count_ptr;
|
||||
UINT64_S dom_mod_count; /* domain mod count at last sync */
|
||||
} SAM_DELTA_MOD_COUNT;
|
||||
|
||||
typedef union sam_delta_ctr_info
|
||||
{
|
||||
typedef union sam_delta_ctr_info {
|
||||
SAM_DOMAIN_INFO domain_info ;
|
||||
SAM_GROUP_INFO group_info ;
|
||||
SAM_ACCOUNT_INFO account_info;
|
||||
@ -955,8 +886,7 @@ typedef union sam_delta_ctr_info
|
||||
} SAM_DELTA_CTR;
|
||||
|
||||
/* NET_R_SAM_SYNC */
|
||||
typedef struct net_r_sam_sync_info
|
||||
{
|
||||
typedef struct net_r_sam_sync_info {
|
||||
DOM_CRED srv_creds;
|
||||
|
||||
uint32 sync_context;
|
||||
@ -973,8 +903,7 @@ typedef struct net_r_sam_sync_info
|
||||
} NET_R_SAM_SYNC;
|
||||
|
||||
/* NET_Q_SAM_DELTAS */
|
||||
typedef struct net_q_sam_deltas_info
|
||||
{
|
||||
typedef struct net_q_sam_deltas_info {
|
||||
UNISTR2 uni_srv_name;
|
||||
UNISTR2 uni_cli_name;
|
||||
DOM_CRED cli_creds;
|
||||
@ -984,12 +913,10 @@ typedef struct net_q_sam_deltas_info
|
||||
UINT64_S dom_mod_count; /* domain mod count at last sync */
|
||||
|
||||
uint32 max_size; /* preferred maximum length */
|
||||
|
||||
} NET_Q_SAM_DELTAS;
|
||||
|
||||
/* NET_R_SAM_DELTAS */
|
||||
typedef struct net_r_sam_deltas_info
|
||||
{
|
||||
typedef struct net_r_sam_deltas_info {
|
||||
DOM_CRED srv_creds;
|
||||
|
||||
UINT64_S dom_mod_count; /* new domain mod count */
|
||||
|
147
source3/include/rpc_ntsvcs.h
Normal file
147
source3/include/rpc_ntsvcs.h
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
SMB parameters and setup
|
||||
Copyright (C) Gerald (Jerry) Carter 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 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_NTSVCS_H /* _RPC_NTSVCS_H */
|
||||
#define _RPC_NTSVCS_H
|
||||
|
||||
/* ntsvcs pipe */
|
||||
|
||||
#define NTSVCS_GET_VERSION 0x02
|
||||
#define NTSVCS_VALIDATE_DEVICE_INSTANCE 0x06
|
||||
#define NTSVCS_GET_ROOT_DEVICE_INSTANCE 0x07
|
||||
#define NTSVCS_GET_DEVICE_LIST 0x0a
|
||||
#define NTSVCS_GET_DEVICE_LIST_SIZE 0x0b
|
||||
#define NTSVCS_GET_DEVICE_REG_PROPERTY 0x0d
|
||||
#define NTSVCS_HW_PROFILE_FLAGS 0x28
|
||||
#define NTSVCS_GET_HW_PROFILE_INFO 0x29
|
||||
#define NTSVCS_GET_VERSION_INTERNAL 0x3e
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
/* nothing in the request */
|
||||
uint32 dummy;
|
||||
} NTSVCS_Q_GET_VERSION;
|
||||
|
||||
typedef struct {
|
||||
uint32 version;
|
||||
WERROR status;
|
||||
} NTSVCS_R_GET_VERSION;
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
UNISTR2 *devicename;
|
||||
uint32 flags;
|
||||
} NTSVCS_Q_GET_DEVICE_LIST_SIZE;
|
||||
|
||||
typedef struct {
|
||||
uint32 size;
|
||||
WERROR status;
|
||||
} NTSVCS_R_GET_DEVICE_LIST_SIZE;
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
UNISTR2 *devicename;
|
||||
uint32 buffer_size;
|
||||
uint32 flags;
|
||||
} NTSVCS_Q_GET_DEVICE_LIST;
|
||||
|
||||
typedef struct {
|
||||
UNISTR2 devicepath;
|
||||
uint32 needed;
|
||||
WERROR status;
|
||||
} NTSVCS_R_GET_DEVICE_LIST;
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
UNISTR2 devicepath;
|
||||
uint32 flags;
|
||||
} NTSVCS_Q_VALIDATE_DEVICE_INSTANCE;
|
||||
|
||||
typedef struct {
|
||||
WERROR status;
|
||||
} NTSVCS_R_VALIDATE_DEVICE_INSTANCE;
|
||||
|
||||
/**************************/
|
||||
|
||||
#define DEV_REGPROP_DESC 1
|
||||
|
||||
typedef struct {
|
||||
UNISTR2 devicepath;
|
||||
uint32 property;
|
||||
uint32 unknown2;
|
||||
uint32 buffer_size1;
|
||||
uint32 buffer_size2;
|
||||
uint32 unknown5;
|
||||
} NTSVCS_Q_GET_DEVICE_REG_PROPERTY;
|
||||
|
||||
typedef struct {
|
||||
uint32 unknown1;
|
||||
REGVAL_BUFFER value;
|
||||
uint32 size;
|
||||
uint32 needed;
|
||||
WERROR status;
|
||||
} NTSVCS_R_GET_DEVICE_REG_PROPERTY;
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
uint32 index;
|
||||
uint8 *buffer;
|
||||
uint32 buffer_size;
|
||||
uint32 unknown1;
|
||||
} NTSVCS_Q_GET_HW_PROFILE_INFO;
|
||||
|
||||
typedef struct {
|
||||
uint32 buffer_size; /* the size (not included in the reply)
|
||||
if just matched from the request */
|
||||
uint8 *buffer;
|
||||
WERROR status;
|
||||
} NTSVCS_R_GET_HW_PROFILE_INFO;
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
uint32 unknown1;
|
||||
UNISTR2 devicepath;
|
||||
uint32 unknown2;
|
||||
uint32 unknown3;
|
||||
uint32 unknown4;
|
||||
uint32 unknown5;
|
||||
uint32 unknown6;
|
||||
uint32 unknown7;
|
||||
} NTSVCS_Q_HW_PROFILE_FLAGS;
|
||||
|
||||
typedef struct {
|
||||
uint32 unknown1;
|
||||
uint32 unknown2;
|
||||
uint32 unknown3;
|
||||
WERROR status;
|
||||
} NTSVCS_R_HW_PROFILE_FLAGS;
|
||||
|
||||
#endif /* _RPC_NTSVCS_H */
|
106
source3/include/rpc_perfcount.h
Normal file
106
source3/include/rpc_perfcount.h
Normal file
@ -0,0 +1,106 @@
|
||||
#ifndef _RPC_PERFCOUNT_H
|
||||
#define _RPC_PERFCOUNT_H
|
||||
|
||||
typedef struct perf_counter_definition
|
||||
{
|
||||
/* sizeof(PERF_COUNTER_DEFINITION) */
|
||||
uint32 ByteLength;
|
||||
uint32 CounterNameTitleIndex;
|
||||
uint32 CounterNameTitlePointer;
|
||||
uint32 CounterHelpTitleIndex;
|
||||
uint32 CounterHelpTitlePointer;
|
||||
uint32 DefaultScale;
|
||||
uint32 DetailLevel;
|
||||
uint32 CounterType;
|
||||
uint32 CounterSize;
|
||||
uint32 CounterOffset;
|
||||
}
|
||||
PERF_COUNTER_DEFINITION;
|
||||
|
||||
typedef struct perf_counter_block
|
||||
{
|
||||
/* Total size of the data block, including all data plus this header */
|
||||
uint32 ByteLength;
|
||||
uint8 *data;
|
||||
}
|
||||
PERF_COUNTER_BLOCK;
|
||||
|
||||
typedef struct perf_instance_definition
|
||||
{
|
||||
/* Total size of the instance definition, including the length of the terminated Name string */
|
||||
uint32 ByteLength;
|
||||
uint32 ParentObjectTitleIndex;
|
||||
uint32 ParentObjectTitlePointer;
|
||||
uint32 UniqueID;
|
||||
/* From the start of the PERF_INSTANCE_DEFINITION, the byte offset to the start of the Name string */
|
||||
uint32 NameOffset;
|
||||
uint32 NameLength;
|
||||
/* Unicode string containing the name for the instance */
|
||||
uint8 *data;
|
||||
PERF_COUNTER_BLOCK counter_data;
|
||||
}
|
||||
PERF_INSTANCE_DEFINITION;
|
||||
|
||||
typedef struct perf_object_type
|
||||
{
|
||||
/* Total size of the object block, including all PERF_INSTANCE_DEFINITIONs,
|
||||
PERF_COUNTER_DEFINITIONs and PERF_COUNTER_BLOCKs in bytes */
|
||||
uint32 TotalByteLength;
|
||||
/* Size of this PERF_OBJECT_TYPE plus all PERF_COUNTER_DEFINITIONs in bytes */
|
||||
uint32 DefinitionLength;
|
||||
/* Size of this PERF_OBJECT_TYPE */
|
||||
uint32 HeaderLength;
|
||||
uint32 ObjectNameTitleIndex;
|
||||
uint32 ObjectNameTitlePointer;
|
||||
uint32 ObjectHelpTitleIndex;
|
||||
uint32 ObjectHelpTitlePointer;
|
||||
uint32 DetailLevel;
|
||||
uint32 NumCounters;
|
||||
uint32 DefaultCounter;
|
||||
uint32 NumInstances;
|
||||
uint32 CodePage;
|
||||
UINT64_S PerfTime;
|
||||
UINT64_S PerfFreq;
|
||||
PERF_COUNTER_DEFINITION *counters;
|
||||
PERF_INSTANCE_DEFINITION *instances;
|
||||
PERF_COUNTER_BLOCK counter_data;
|
||||
}
|
||||
PERF_OBJECT_TYPE;
|
||||
|
||||
/* PerfCounter Inner Buffer structs */
|
||||
typedef struct perf_data_block
|
||||
{
|
||||
/* hardcoded to read "P.E.R.F" */
|
||||
uint16 Signature[4];
|
||||
uint32 LittleEndian;
|
||||
/* both currently hardcoded to 1 */
|
||||
uint32 Version;
|
||||
uint32 Revision;
|
||||
/* bytes of PERF_OBJECT_TYPE data, does NOT include the PERF_DATA_BLOCK */
|
||||
uint32 TotalByteLength;
|
||||
/* size of PERF_DATA_BLOCK including the uint8 *data */
|
||||
uint32 HeaderLength;
|
||||
/* number of PERF_OBJECT_TYPE structures encoded */
|
||||
uint32 NumObjectTypes;
|
||||
uint32 DefaultObject;
|
||||
SYSTEMTIME SystemTime;
|
||||
/* This will guarantee that we're on a 64-bit boundary before we encode
|
||||
PerfTime, and having it there will make my offset math much easier. */
|
||||
uint32 Padding;
|
||||
/* Now when I'm marshalling this, I'll need to call prs_align_uint64()
|
||||
before I start encodint the UINT64_S structs */
|
||||
/* clock rate * seconds uptime */
|
||||
UINT64_S PerfTime;
|
||||
/* The clock rate of the CPU */
|
||||
UINT64_S PerfFreq;
|
||||
/* used for high-res timers -- for now PerfTime * 10e7 */
|
||||
UINT64_S PerfTime100nSec;
|
||||
uint32 SystemNameLength;
|
||||
uint32 SystemNameOffset;
|
||||
/* The SystemName, in unicode, terminated */
|
||||
uint8* data;
|
||||
PERF_OBJECT_TYPE *objects;
|
||||
}
|
||||
PERF_DATA_BLOCK;
|
||||
|
||||
#endif /* _RPC_PERFCOUNT_H */
|
73
source3/include/rpc_perfcount_defs.h
Normal file
73
source3/include/rpc_perfcount_defs.h
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef _RPC_PERFCOUNT_DEFS_H
|
||||
#define _RPC_PERFCOUNT_DEFS_H
|
||||
|
||||
/*
|
||||
* The following #defines match what is in winperf.h.
|
||||
* See that include file for more details, or look up
|
||||
* "Performance Data Format" on MSDN
|
||||
*
|
||||
* Rather than including them in rpc_perfcount.h, they
|
||||
* were broken out into a separate .h file so that they
|
||||
* can be included by other programs that need this info
|
||||
* without pulling in everything else samba-related.
|
||||
*/
|
||||
|
||||
#define PERF_NO_INSTANCES -1
|
||||
#define PERF_NO_UNIQUE_ID -1
|
||||
|
||||
/* These determine the data size */
|
||||
#define PERF_SIZE_DWORD 0x00000000
|
||||
#define PERF_SIZE_LARGE 0x00000100
|
||||
#define PERF_SIZE_ZERO 0x00000200
|
||||
#define PERF_SIZE_VARIABLE_LEN 0x00000300
|
||||
|
||||
/* These determine the usage of the counter */
|
||||
#define PERF_TYPE_NUMBER 0x00000000
|
||||
#define PERF_TYPE_COUNTER 0x00000400
|
||||
#define PERF_TYPE_TEXT 0x00000800
|
||||
#define PERF_TYPE_ZERO 0x00000C00
|
||||
|
||||
/* If PERF_TYPE_NUMBER was selected, these provide display information */
|
||||
#define PERF_NUMBER_HEX 0x00000000
|
||||
#define PERF_NUMBER_DECIMAL 0x00010000
|
||||
#define PERF_NUMBER_DEC_1000 0x00020000
|
||||
|
||||
/* If PERF_TYPE_COUNTER was selected, these provide display information */
|
||||
#define PERF_COUNTER_VALUE 0x00000000
|
||||
#define PERF_COUNTER_RATE 0x00010000
|
||||
#define PERF_COUNTER_FRACTION 0x00020000
|
||||
#define PERF_COUNTER_BASE 0x00030000
|
||||
#define PERF_COUNTER_ELAPSED 0x00040000
|
||||
#define PERF_COUNTER_QUEUELEN 0x00050000
|
||||
#define PERF_COUNTER_HISTOGRAM 0x00060000
|
||||
#define PERF_COUNTER_PRECISION 0x00070000
|
||||
|
||||
/* If PERF_TYPE_TEXT was selected, these provide display information */
|
||||
#define PERF_TEXT_UNICODE 0x00000000
|
||||
#define PERF_TEXT_ASCII 0x00010000
|
||||
|
||||
/* These provide information for which tick count to use when computing elapsed interval */
|
||||
#define PERF_TIMER_TICK 0x00000000
|
||||
#define PERF_TIMER_100NS 0x00100000
|
||||
#define PERF_OBJECT_TIMER 0x00200000
|
||||
|
||||
/* These affect how the data is manipulated prior to being displayed */
|
||||
#define PERF_DELTA_COUNTER 0x00400000
|
||||
#define PERF_DELTA_BASE 0x00800000
|
||||
#define PERF_INVERSE_COUNTER 0x01000000
|
||||
#define PERF_MULTI_COUNTER 0x02000000
|
||||
|
||||
/* These determine if any text gets added when the value is displayed */
|
||||
#define PERF_DISPLAY_NO_SUFFIX 0x00000000
|
||||
#define PERF_DISPLAY_PER_SEC 0x10000000
|
||||
#define PERF_DISPLAY_PERCENT 0x20000000
|
||||
#define PERF_DISPLAY_SECONDS 0x30000000
|
||||
#define PERF_DISPLAY_NOSHOW 0x40000000
|
||||
|
||||
/* These determine the DetailLevel of the counter */
|
||||
#define PERF_DETAIL_NOVICE 100
|
||||
#define PERF_DETAIL_ADVANCED 200
|
||||
#define PERF_DETAIL_EXPERT 300
|
||||
#define PERF_DETAIL_WIZARD 400
|
||||
|
||||
#endif /* _RPC_PERFCOUNT_DEFS_H */
|
@ -25,8 +25,6 @@
|
||||
#ifndef _RPC_REG_H /* _RPC_REG_H */
|
||||
#define _RPC_REG_H
|
||||
|
||||
#include "reg_objects.h"
|
||||
|
||||
/* RPC opnum */
|
||||
|
||||
#define REG_OPEN_HKCR 0x00
|
||||
@ -50,6 +48,7 @@
|
||||
#define REG_SET_VALUE 0x16
|
||||
#define REG_SHUTDOWN 0x18
|
||||
#define REG_ABORT_SHUTDOWN 0x19
|
||||
#define REG_OPEN_HKPT 0x20
|
||||
#define REG_GETVERSION 0x1a
|
||||
#define REG_SHUTDOWN_EX 0x1e
|
||||
|
||||
@ -63,6 +62,9 @@
|
||||
#define KEY_HKLM "HKLM"
|
||||
#define KEY_HKU "HKU"
|
||||
#define KEY_HKCR "HKCR"
|
||||
#define KEY_HKPD "HKPD"
|
||||
#define KEY_HKPT "HKPT"
|
||||
#define KEY_SERVICES "HKLM\\SYSTEM\\CurrentControlSet\\Services"
|
||||
#define KEY_PRINTING "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
|
||||
#define KEY_PRINTING_2K "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers"
|
||||
#define KEY_PRINTING_PORTS "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports"
|
||||
@ -85,6 +87,16 @@
|
||||
#define REG_FULL_RESOURCE_DESCRIPTOR 9
|
||||
#define REG_RESOURCE_REQUIREMENTS_LIST 10
|
||||
|
||||
/*
|
||||
* Registry key types
|
||||
* Most keys are going to be GENERIC -- may need a better name?
|
||||
* HKPD and HKPT are used by reg_perfcount.c
|
||||
* they are special keys that congtain performance data
|
||||
*/
|
||||
#define REG_KEY_GENERIC 0
|
||||
#define REG_KEY_HKPD 1
|
||||
#define REG_KEY_HKPT 2
|
||||
|
||||
/*
|
||||
* container for function pointers to enumeration routines
|
||||
* for vitural registry view
|
||||
@ -108,9 +120,8 @@ typedef struct {
|
||||
/* structure to store the registry handles */
|
||||
|
||||
typedef struct _RegistryKey {
|
||||
struct _RegistryKey *prev, *next;
|
||||
|
||||
pstring name; /* full name of registry key */
|
||||
uint32 type;
|
||||
char *name; /* full name of registry key */
|
||||
uint32 access_granted;
|
||||
REGISTRY_HOOK *hook;
|
||||
} REGISTRY_KEY;
|
||||
|
@ -26,8 +26,6 @@
|
||||
#ifndef _RPC_SAMR_H /* _RPC_SAMR_H */
|
||||
#define _RPC_SAMR_H
|
||||
|
||||
#include "rpc_misc.h"
|
||||
|
||||
/*******************************************************************
|
||||
the following information comes from a QuickView on samsrv.dll,
|
||||
and gives an idea of exactly what is needed:
|
||||
|
@ -481,13 +481,16 @@ typedef struct standard_mapping {
|
||||
SC_RIGHT_MGR_ENUMERATE_SERVICE | \
|
||||
SC_RIGHT_MGR_QUERY_LOCK_STATUS )
|
||||
|
||||
#define SC_MANAGER_ALL_ACCESS \
|
||||
#define SC_MANAGER_EXECUTE_ACCESS SC_MANAGER_READ_ACCESS
|
||||
|
||||
#define SC_MANAGER_WRITE_ACCESS \
|
||||
( STANDARD_RIGHTS_REQUIRED_ACCESS | \
|
||||
SC_MANAGER_READ_ACCESS | \
|
||||
SC_RIGHT_MGR_CREATE_SERVICE | \
|
||||
SC_RIGHT_MGR_LOCK | \
|
||||
SC_RIGHT_MGR_MODIFY_BOOT_CONFIG )
|
||||
|
||||
#define SC_MANAGER_ALL_ACCESS SC_MANAGER_WRITE_ACCESS
|
||||
|
||||
/* Service Object Bits */
|
||||
|
||||
@ -515,12 +518,14 @@ typedef struct standard_mapping {
|
||||
SC_RIGHT_SVC_STOP | \
|
||||
SC_RIGHT_SVC_PAUSE_CONTINUE )
|
||||
|
||||
#define SERVICE_ALL_ACCESS \
|
||||
#define SERVICE_WRITE_ACCESS \
|
||||
( STANDARD_RIGHTS_REQUIRED_ACCESS | \
|
||||
SERVICE_READ_ACCESS | \
|
||||
SERVICE_EXECUTE_ACCESS | \
|
||||
SC_RIGHT_SVC_CHANGE_CONFIG )
|
||||
|
||||
#define SERVICE_ALL_ACCESS SERVICE_WRITE_ACCESS
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
@ -22,12 +22,15 @@
|
||||
#ifndef _RPC_SVCCTL_H /* _RPC_SVCCTL_H */
|
||||
#define _RPC_SVCCTL_H
|
||||
|
||||
|
||||
/* svcctl pipe */
|
||||
|
||||
#define SVCCTL_CLOSE_SERVICE 0x00
|
||||
#define SVCCTL_CONTROL_SERVICE 0x01
|
||||
#define SVCCTL_LOCK_SERVICE_DB 0x03
|
||||
#define SVCCTL_QUERY_SERVICE_SEC 0x04 /* not impmenented */
|
||||
#define SVCCTL_SET_SEVICE_SEC 0x05 /* not implemented */
|
||||
#define SVCCTL_QUERY_STATUS 0x06
|
||||
#define SVCCTL_UNLOCK_SERVICE_DB 0x08
|
||||
#define SVCCTL_ENUM_DEPENDENT_SERVICES_W 0x0d
|
||||
#define SVCCTL_ENUM_SERVICES_STATUS_W 0x0e
|
||||
#define SVCCTL_OPEN_SCMANAGER_W 0x0f
|
||||
@ -105,14 +108,17 @@
|
||||
#define SVCCTL_CONTROL_STOP 0x00000001
|
||||
#define SVCCTL_CONTROL_PAUSE 0x00000002
|
||||
#define SVCCTL_CONTROL_CONTINUE 0x00000003
|
||||
#define SVCCTL_CONTROL_SHUTDOWN 0x00000004
|
||||
#define SVCCTL_CONTROL_INTERROGATE 0x00000004
|
||||
#define SVCCTL_CONTROL_SHUTDOWN 0x00000005
|
||||
|
||||
#define SVC_HANDLE_IS_SCM 0x0000001
|
||||
#define SVC_HANDLE_IS_SERVICE 0x0000002
|
||||
#define SVC_HANDLE_IS_DBLOCK 0x0000003
|
||||
|
||||
#define SVC_STATUS_PROCESS_INFO 0x00000001
|
||||
#define SVC_STATUS_PROCESS_INFO 0x00000000
|
||||
|
||||
#define SVCCTL_SCRIPT_DIR "/svcctl/"
|
||||
/* where we assume the location of the service control scripts */
|
||||
#define SVCCTL_SCRIPT_DIR "svcctl"
|
||||
|
||||
/* utility structures for RPCs */
|
||||
|
||||
@ -127,13 +133,7 @@ typedef struct {
|
||||
} SERVICE_STATUS;
|
||||
|
||||
typedef struct {
|
||||
uint32 type;
|
||||
uint32 state;
|
||||
uint32 controls_accepted;
|
||||
uint32 win32_exit_code;
|
||||
uint32 service_exit_code;
|
||||
uint32 check_point;
|
||||
uint32 wait_hint;
|
||||
SERVICE_STATUS status;
|
||||
uint32 process_id;
|
||||
uint32 service_flags;
|
||||
} SERVICE_STATUS_PROCESS;
|
||||
@ -158,7 +158,8 @@ typedef struct {
|
||||
} SERVICE_CONFIG;
|
||||
|
||||
typedef struct {
|
||||
UNISTR2 *description;
|
||||
uint32 unknown;
|
||||
UNISTR description;
|
||||
} SERVICE_DESCRIPTION;
|
||||
|
||||
typedef struct {
|
||||
@ -168,20 +169,12 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
uint32 reset_period;
|
||||
UNISTR2 *rebootmsg;
|
||||
UNISTR2 *rebootmsg; /* i have no idea if these are UNISTR2's. I can't get a good trace */
|
||||
UNISTR2 *command;
|
||||
uint32 nActions;
|
||||
SC_ACTION *saActions;
|
||||
UNISTR2 *description;
|
||||
uint32 num_actions;
|
||||
SC_ACTION *actions;
|
||||
} SERVICE_FAILURE_ACTIONS;
|
||||
|
||||
|
||||
typedef struct SCM_info_struct {
|
||||
uint32 type; /* should be SVC_HANDLE_IS_SCM */
|
||||
pstring target_server_name; /* name of the server on which the operation is taking place */
|
||||
pstring target_db_name; /* name of the database that we're opening */
|
||||
} SCM_info;
|
||||
|
||||
typedef struct Service_info_struct {
|
||||
uint32 type; /* should be SVC_HANDLE_IS_SERVICE */
|
||||
pstring servicename; /* the name of the service */
|
||||
@ -205,9 +198,9 @@ typedef struct Service_info_struct {
|
||||
|
||||
typedef struct {
|
||||
/* functions for enumerating subkeys and values */
|
||||
WERROR (*stop_service)( SERVICE_STATUS *status );
|
||||
WERROR (*start_service) ( void );
|
||||
WERROR (*service_status)( SERVICE_STATUS *status );
|
||||
WERROR (*stop_service)( const char *service, SERVICE_STATUS *status );
|
||||
WERROR (*start_service) ( const char *service );
|
||||
WERROR (*service_status)( const char *service, SERVICE_STATUS *status );
|
||||
} SERVICE_CONTROL_OPS;
|
||||
|
||||
/* structure to store the service handle information */
|
||||
@ -341,6 +334,7 @@ typedef struct {
|
||||
WERROR status;
|
||||
} SVCCTL_R_ENUM_DEPENDENT_SERVICES;
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
@ -354,32 +348,58 @@ typedef struct {
|
||||
WERROR status;
|
||||
} SVCCTL_R_QUERY_SERVICE_CONFIG;
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
uint32 info_level;
|
||||
uint32 level;
|
||||
uint32 buffer_size;
|
||||
} SVCCTL_Q_QUERY_SERVICE_CONFIG2;
|
||||
|
||||
typedef struct {
|
||||
UNISTR2 *description;
|
||||
uint32 returned;
|
||||
RPC_BUFFER buffer;
|
||||
uint32 needed;
|
||||
uint32 offset;
|
||||
WERROR status;
|
||||
} SVCCTL_R_QUERY_SERVICE_CONFIG2;
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
uint32 info_level;
|
||||
uint32 level;
|
||||
uint32 buffer_size;
|
||||
} SVCCTL_Q_QUERY_SERVICE_STATUSEX;
|
||||
|
||||
typedef struct {
|
||||
RPC_BUFFER buffer;
|
||||
uint32 returned;
|
||||
uint32 needed;
|
||||
WERROR status;
|
||||
} SVCCTL_R_QUERY_SERVICE_STATUSEX;
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND handle;
|
||||
} SVCCTL_Q_LOCK_SERVICE_DB;
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND h_lock;
|
||||
WERROR status;
|
||||
} SVCCTL_R_LOCK_SERVICE_DB;
|
||||
|
||||
|
||||
/**************************/
|
||||
|
||||
typedef struct {
|
||||
POLICY_HND h_lock;
|
||||
} SVCCTL_Q_UNLOCK_SERVICE_DB;
|
||||
|
||||
typedef struct {
|
||||
WERROR status;
|
||||
} SVCCTL_R_UNLOCK_SERVICE_DB;
|
||||
|
||||
#endif /* _RPC_SVCCTL_H */
|
||||
|
||||
|
@ -206,11 +206,11 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
|
||||
#define PI_SHUTDOWN 10
|
||||
#define PI_SVCCTL 11
|
||||
#define PI_EVENTLOG 12
|
||||
#define PI_MAX_PIPES 13
|
||||
#define PI_NTSVCS 13
|
||||
#define PI_MAX_PIPES 14
|
||||
|
||||
/* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
|
||||
typedef struct nttime_info
|
||||
{
|
||||
typedef struct nttime_info {
|
||||
uint32 low;
|
||||
uint32 high;
|
||||
} NTTIME;
|
||||
@ -414,6 +414,10 @@ struct fd_handle {
|
||||
*/
|
||||
};
|
||||
|
||||
struct timed_event;
|
||||
struct idle_event;
|
||||
struct share_mode_entry;
|
||||
|
||||
typedef struct files_struct {
|
||||
struct files_struct *next, *prev;
|
||||
int fnum;
|
||||
@ -437,6 +441,11 @@ typedef struct files_struct {
|
||||
time_t last_write_time;
|
||||
int oplock_type;
|
||||
int sent_oplock_break;
|
||||
struct timed_event *oplock_timeout;
|
||||
|
||||
struct share_mode_entry *pending_break_messages;
|
||||
int num_pending_break_messages;
|
||||
|
||||
unsigned long file_id;
|
||||
BOOL can_lock;
|
||||
BOOL can_read;
|
||||
@ -564,6 +573,7 @@ struct current_user
|
||||
#define NO_BREAK_SENT 0
|
||||
#define BREAK_TO_NONE_SENT 1
|
||||
#define LEVEL_II_BREAK_SENT 2
|
||||
#define ASYNC_LEVEL_II_BREAK_SENT 3
|
||||
|
||||
typedef struct {
|
||||
fstring smb_name; /* user name from the client */
|
||||
@ -619,28 +629,19 @@ struct interface
|
||||
struct in_addr nmask;
|
||||
};
|
||||
|
||||
/* struct used by share mode violation error processing */
|
||||
typedef struct {
|
||||
pid_t pid;
|
||||
uint16 mid;
|
||||
struct timeval time;
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T inode;
|
||||
uint16 port;
|
||||
} deferred_open_entry;
|
||||
|
||||
/* Internal message queue for deferred opens. */
|
||||
struct pending_message_list {
|
||||
struct pending_message_list *next, *prev;
|
||||
struct timeval msg_time; /* The timeout time */
|
||||
struct timeval request_time; /* When was this first issued? */
|
||||
struct timeval end_time; /* When does this time out? */
|
||||
DATA_BLOB buf;
|
||||
DATA_BLOB private_data;
|
||||
};
|
||||
|
||||
/* struct returned by get_share_modes */
|
||||
typedef struct {
|
||||
pid_t pid;
|
||||
uint16 op_port;
|
||||
struct share_mode_entry {
|
||||
struct process_id pid;
|
||||
uint16 op_mid;
|
||||
uint16 op_type;
|
||||
uint32 access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */
|
||||
uint32 share_access; /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */
|
||||
@ -652,14 +653,18 @@ typedef struct {
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T inode;
|
||||
unsigned long share_file_id;
|
||||
} share_mode_entry;
|
||||
};
|
||||
|
||||
|
||||
#define SHAREMODE_FN_CAST() \
|
||||
void (*)(share_mode_entry *, char*)
|
||||
|
||||
#define SHAREMODE_FN(fn) \
|
||||
void (*fn)(share_mode_entry *, char*)
|
||||
struct share_mode_lock {
|
||||
const char *filename;
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T ino;
|
||||
int num_share_modes;
|
||||
struct share_mode_entry *share_modes;
|
||||
BOOL delete_on_close;
|
||||
BOOL fresh;
|
||||
BOOL modified;
|
||||
};
|
||||
|
||||
#define NT_HASH_LEN 16
|
||||
#define LM_HASH_LEN 16
|
||||
@ -700,14 +705,14 @@ typedef struct {
|
||||
|
||||
/* key and data in the connections database - used in smbstatus and smbd */
|
||||
struct connections_key {
|
||||
pid_t pid;
|
||||
struct process_id pid;
|
||||
int cnum;
|
||||
fstring name;
|
||||
};
|
||||
|
||||
struct connections_data {
|
||||
int magic;
|
||||
pid_t pid;
|
||||
struct process_id pid;
|
||||
int cnum;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
@ -719,12 +724,6 @@ struct connections_data {
|
||||
};
|
||||
|
||||
|
||||
/* key and data records in the tdb locking database */
|
||||
struct locking_key {
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T inode;
|
||||
};
|
||||
|
||||
/* the following are used by loadparm for option lists */
|
||||
typedef enum {
|
||||
P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
|
||||
@ -744,11 +743,11 @@ struct enum_list {
|
||||
};
|
||||
|
||||
#define BRLOCK_FN_CAST() \
|
||||
void (*)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
|
||||
void (*)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \
|
||||
enum brl_type lock_type, \
|
||||
br_off start, br_off size)
|
||||
#define BRLOCK_FN(fn) \
|
||||
void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
|
||||
void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \
|
||||
enum brl_type lock_type, \
|
||||
br_off start, br_off size)
|
||||
struct parm_struct
|
||||
@ -1462,10 +1461,29 @@ extern int chain_size;
|
||||
#define BATCH_OPLOCK 2
|
||||
#define LEVEL_II_OPLOCK 4
|
||||
#define INTERNAL_OPEN_ONLY 8
|
||||
#define FAKE_LEVEL_II_OPLOCK 16 /* Client requested no_oplock, but we have to
|
||||
* inform potential level2 holders on
|
||||
* write. */
|
||||
#define DEFERRED_OPEN_ENTRY 32
|
||||
#define UNUSED_SHARE_MODE_ENTRY 64
|
||||
|
||||
#define EXCLUSIVE_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)EXCLUSIVE_OPLOCK|(unsigned int)BATCH_OPLOCK))
|
||||
#define BATCH_OPLOCK_TYPE(lck) ((lck) & (unsigned int)BATCH_OPLOCK)
|
||||
#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & (unsigned int)LEVEL_II_OPLOCK)
|
||||
#define LEVEL_II_OPLOCK_TYPE(lck) ((lck) & ((unsigned int)LEVEL_II_OPLOCK|(unsigned int)FAKE_LEVEL_II_OPLOCK))
|
||||
|
||||
struct inform_level2_message {
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T inode;
|
||||
uint16 mid;
|
||||
unsigned long target_file_id;
|
||||
unsigned long source_file_id;
|
||||
};
|
||||
|
||||
struct kernel_oplock_message {
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T inode;
|
||||
unsigned long file_id;
|
||||
};
|
||||
|
||||
/*
|
||||
* On the wire return values for oplock types.
|
||||
@ -1483,95 +1501,23 @@ extern int chain_size;
|
||||
#define OPLOCKLEVEL_NONE 0
|
||||
#define OPLOCKLEVEL_II 1
|
||||
|
||||
/*
|
||||
* Loopback command offsets.
|
||||
*/
|
||||
|
||||
#define OPBRK_CMD_LEN_OFFSET 0
|
||||
#define OPBRK_CMD_PORT_OFFSET 4
|
||||
#define OPBRK_CMD_HEADER_LEN 6
|
||||
|
||||
#define OPBRK_MESSAGE_CMD_OFFSET 0
|
||||
|
||||
/*
|
||||
* Oplock break command code to send over the udp socket.
|
||||
* The same message is sent for both exlusive and level II breaks.
|
||||
*
|
||||
* The form of this is :
|
||||
*
|
||||
* 0 2 2+pid 2+pid+dev 2+pid+dev+ino
|
||||
* +----+--------+-------+--------+---------+
|
||||
* | cmd| pid | dev | inode | fileid |
|
||||
* +----+--------+-------+--------+---------+
|
||||
*/
|
||||
|
||||
#define OPLOCK_BREAK_PID_OFFSET 2
|
||||
#define OPLOCK_BREAK_DEV_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_t))
|
||||
#define OPLOCK_BREAK_INODE_OFFSET (OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
|
||||
#define OPLOCK_BREAK_FILEID_OFFSET (OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
|
||||
#define OPLOCK_BREAK_MSG_LEN (OPLOCK_BREAK_FILEID_OFFSET + sizeof(unsigned long))
|
||||
|
||||
/* Message types */
|
||||
#define OPLOCK_BREAK_CMD 0x1
|
||||
#define KERNEL_OPLOCK_BREAK_CMD 0x2
|
||||
#define LEVEL_II_OPLOCK_BREAK_CMD 0x3
|
||||
#define ASYNC_LEVEL_II_OPLOCK_BREAK_CMD 0x4
|
||||
|
||||
/* Add the "deferred open" message. */
|
||||
#define RETRY_DEFERRED_OPEN_CMD 0x5
|
||||
|
||||
/*
|
||||
* And the message format for it. Keep the same message length.
|
||||
*
|
||||
* 0 2 2+pid 2+pid+dev 2+pid+dev+ino
|
||||
* +----+--------+-------+--------+---------+
|
||||
* | cmd| pid | dev | inode | mid |
|
||||
* +----+--------+-------+--------+---------+
|
||||
*/
|
||||
|
||||
#define DEFERRED_OPEN_CMD_OFFSET 0
|
||||
#define DEFERRED_OPEN_PID_OFFSET 2 /* pid we're *sending* from. */
|
||||
#define DEFERRED_OPEN_DEV_OFFSET (DEFERRED_OPEN_PID_OFFSET + sizeof(pid_t))
|
||||
#define DEFERRED_OPEN_INODE_OFFSET (DEFERRED_OPEN_DEV_OFFSET + sizeof(SMB_DEV_T))
|
||||
#define DEFERRED_OPEN_MID_OFFSET (DEFERRED_OPEN_INODE_OFFSET + sizeof(SMB_INO_T))
|
||||
#define DEFERRED_OPEN_MSG_LEN OPLOCK_BREAK_MSG_LEN
|
||||
|
||||
/*
|
||||
* Capabilities abstracted for different systems.
|
||||
*/
|
||||
|
||||
#define KERNEL_OPLOCK_CAPABILITY 0x1
|
||||
|
||||
/*
|
||||
* Oplock break command code sent via the kernel interface (if it exists).
|
||||
*
|
||||
* Form of this is :
|
||||
*
|
||||
* 0 2 2+devsize 2+devsize+inodesize
|
||||
* +----+--------+--------+----------+
|
||||
* | cmd| dev | inode | fileid |
|
||||
* +----+--------+--------+----------+
|
||||
*/
|
||||
#define KERNEL_OPLOCK_BREAK_DEV_OFFSET 2
|
||||
#define KERNEL_OPLOCK_BREAK_INODE_OFFSET (KERNEL_OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
|
||||
#define KERNEL_OPLOCK_BREAK_FILEID_OFFSET (KERNEL_OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
|
||||
#define KERNEL_OPLOCK_BREAK_MSG_LEN (KERNEL_OPLOCK_BREAK_FILEID_OFFSET + sizeof(unsigned long))
|
||||
|
||||
|
||||
/* if a kernel does support oplocks then a structure of the following
|
||||
typee is used to describe how to interact with the kernel */
|
||||
struct kernel_oplocks {
|
||||
BOOL (*receive_message)(fd_set *fds, char *buffer, int buffer_len);
|
||||
files_struct * (*receive_message)(fd_set *fds);
|
||||
BOOL (*set_oplock)(files_struct *fsp, int oplock_type);
|
||||
void (*release_oplock)(files_struct *fsp);
|
||||
BOOL (*parse_message)(char *msg_start, int msg_len, SMB_INO_T *inode, SMB_DEV_T *dev, unsigned long *file_id);
|
||||
BOOL (*msg_waiting)(fd_set *fds);
|
||||
int notification_fd;
|
||||
};
|
||||
|
||||
|
||||
#define CMD_REPLY 0x8000
|
||||
|
||||
/* this structure defines the functions for doing change notify in
|
||||
various implementations */
|
||||
struct cnotify_fns {
|
||||
@ -1759,4 +1705,18 @@ struct ea_list {
|
||||
/* EA to use for DOS attributes */
|
||||
#define SAMBA_XATTR_DOS_ATTRIB "user.DOSATTRIB"
|
||||
|
||||
struct uuid {
|
||||
uint32 time_low;
|
||||
uint16 time_mid;
|
||||
uint16 time_hi_and_version;
|
||||
uint8 clock_seq[2];
|
||||
uint8 node[6];
|
||||
};
|
||||
#define UUID_SIZE 16
|
||||
|
||||
#define UUID_FLAT_SIZE 16
|
||||
typedef struct uuid_flat {
|
||||
uint8 info[UUID_FLAT_SIZE];
|
||||
} UUID_FLAT;
|
||||
|
||||
#endif /* _SMB_H */
|
||||
|
256
source3/include/smb_ldap.h
Normal file
256
source3/include/smb_ldap.h
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
Unix SMB/CIFS Implementation.
|
||||
LDAP protocol helper functions for SAMBA
|
||||
Copyright (C) Volker Lendecke 2004
|
||||
|
||||
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 _SMB_LDAP_H
|
||||
#define _SMB_LDAP_H
|
||||
|
||||
enum ldap_request_tag {
|
||||
LDAP_TAG_BindRequest = 0,
|
||||
LDAP_TAG_BindResponse = 1,
|
||||
LDAP_TAG_UnbindRequest = 2,
|
||||
LDAP_TAG_SearchRequest = 3,
|
||||
LDAP_TAG_SearchResultEntry = 4,
|
||||
LDAP_TAG_SearchResultDone = 5,
|
||||
LDAP_TAG_ModifyRequest = 6,
|
||||
LDAP_TAG_ModifyResponse = 7,
|
||||
LDAP_TAG_AddRequest = 8,
|
||||
LDAP_TAG_AddResponse = 9,
|
||||
LDAP_TAG_DelRequest = 10,
|
||||
LDAP_TAG_DelResponse = 11,
|
||||
LDAP_TAG_ModifyDNRequest = 12,
|
||||
LDAP_TAG_ModifyDNResponse = 13,
|
||||
LDAP_TAG_CompareRequest = 14,
|
||||
LDAP_TAG_CompareResponse = 15,
|
||||
LDAP_TAG_AbandonRequest = 16,
|
||||
LDAP_TAG_SearchResultReference = 19,
|
||||
LDAP_TAG_ExtendedRequest = 23,
|
||||
LDAP_TAG_ExtendedResponse = 24
|
||||
};
|
||||
|
||||
enum ldap_auth_mechanism {
|
||||
LDAP_AUTH_MECH_SIMPLE = 0,
|
||||
LDAP_AUTH_MECH_SASL = 3
|
||||
};
|
||||
|
||||
#ifndef LDAP_SUCCESS
|
||||
enum ldap_result_code {
|
||||
LDAP_SUCCESS = 0,
|
||||
LDAP_SASL_BIND_IN_PROGRESS = 0x0e,
|
||||
LDAP_INVALID_CREDENTIALS = 0x31,
|
||||
LDAP_OTHER = 0x50
|
||||
};
|
||||
#endif /* LDAP_SUCCESS */
|
||||
|
||||
struct ldap_Result {
|
||||
int resultcode;
|
||||
const char *dn;
|
||||
const char *errormessage;
|
||||
const char *referral;
|
||||
};
|
||||
|
||||
struct ldap_attribute {
|
||||
const char *name;
|
||||
int num_values;
|
||||
DATA_BLOB *values;
|
||||
};
|
||||
|
||||
struct ldap_BindRequest {
|
||||
int version;
|
||||
const char *dn;
|
||||
enum ldap_auth_mechanism mechanism;
|
||||
union {
|
||||
const char *password;
|
||||
struct {
|
||||
const char *mechanism;
|
||||
DATA_BLOB secblob;
|
||||
} SASL;
|
||||
} creds;
|
||||
};
|
||||
|
||||
struct ldap_BindResponse {
|
||||
struct ldap_Result response;
|
||||
union {
|
||||
DATA_BLOB secblob;
|
||||
} SASL;
|
||||
};
|
||||
|
||||
struct ldap_UnbindRequest {
|
||||
uint8 __dummy;
|
||||
};
|
||||
|
||||
enum ldap_scope {
|
||||
LDAP_SEARCH_SCOPE_BASE = 0,
|
||||
LDAP_SEARCH_SCOPE_SINGLE = 1,
|
||||
LDAP_SEARCH_SCOPE_SUB = 2
|
||||
};
|
||||
|
||||
enum ldap_deref {
|
||||
LDAP_DEREFERENCE_NEVER = 0,
|
||||
LDAP_DEREFERENCE_IN_SEARCHING = 1,
|
||||
LDAP_DEREFERENCE_FINDING_BASE = 2,
|
||||
LDAP_DEREFERENCE_ALWAYS
|
||||
};
|
||||
|
||||
struct ldap_SearchRequest {
|
||||
const char *basedn;
|
||||
enum ldap_scope scope;
|
||||
enum ldap_deref deref;
|
||||
uint32 timelimit;
|
||||
uint32 sizelimit;
|
||||
BOOL attributesonly;
|
||||
char *filter;
|
||||
int num_attributes;
|
||||
const char **attributes;
|
||||
};
|
||||
|
||||
struct ldap_SearchResEntry {
|
||||
const char *dn;
|
||||
int num_attributes;
|
||||
struct ldap_attribute *attributes;
|
||||
};
|
||||
|
||||
struct ldap_SearchResRef {
|
||||
int num_referrals;
|
||||
const char **referrals;
|
||||
};
|
||||
|
||||
enum ldap_modify_type {
|
||||
LDAP_MODIFY_NONE = -1,
|
||||
LDAP_MODIFY_ADD = 0,
|
||||
LDAP_MODIFY_DELETE = 1,
|
||||
LDAP_MODIFY_REPLACE = 2
|
||||
};
|
||||
|
||||
struct ldap_mod {
|
||||
enum ldap_modify_type type;
|
||||
struct ldap_attribute attrib;
|
||||
};
|
||||
|
||||
struct ldap_ModifyRequest {
|
||||
const char *dn;
|
||||
int num_mods;
|
||||
struct ldap_mod *mods;
|
||||
};
|
||||
|
||||
struct ldap_AddRequest {
|
||||
const char *dn;
|
||||
int num_attributes;
|
||||
struct ldap_attribute *attributes;
|
||||
};
|
||||
|
||||
struct ldap_DelRequest {
|
||||
const char *dn;
|
||||
};
|
||||
|
||||
struct ldap_ModifyDNRequest {
|
||||
const char *dn;
|
||||
const char *newrdn;
|
||||
BOOL deleteolddn;
|
||||
const char *newsuperior;
|
||||
};
|
||||
|
||||
struct ldap_CompareRequest {
|
||||
const char *dn;
|
||||
const char *attribute;
|
||||
const char *value;
|
||||
};
|
||||
|
||||
struct ldap_AbandonRequest {
|
||||
uint32 messageid;
|
||||
};
|
||||
|
||||
struct ldap_ExtendedRequest {
|
||||
const char *oid;
|
||||
DATA_BLOB value;
|
||||
};
|
||||
|
||||
struct ldap_ExtendedResponse {
|
||||
struct ldap_Result response;
|
||||
const char *name;
|
||||
DATA_BLOB value;
|
||||
};
|
||||
|
||||
union ldap_Request {
|
||||
struct ldap_BindRequest BindRequest;
|
||||
struct ldap_BindResponse BindResponse;
|
||||
struct ldap_UnbindRequest UnbindRequest;
|
||||
struct ldap_SearchRequest SearchRequest;
|
||||
struct ldap_SearchResEntry SearchResultEntry;
|
||||
struct ldap_Result SearchResultDone;
|
||||
struct ldap_SearchResRef SearchResultReference;
|
||||
struct ldap_ModifyRequest ModifyRequest;
|
||||
struct ldap_Result ModifyResponse;
|
||||
struct ldap_AddRequest AddRequest;
|
||||
struct ldap_Result AddResponse;
|
||||
struct ldap_DelRequest DelRequest;
|
||||
struct ldap_Result DelResponse;
|
||||
struct ldap_ModifyDNRequest ModifyDNRequest;
|
||||
struct ldap_Result ModifyDNResponse;
|
||||
struct ldap_CompareRequest CompareRequest;
|
||||
struct ldap_Result CompareResponse;
|
||||
struct ldap_AbandonRequest AbandonRequest;
|
||||
struct ldap_ExtendedRequest ExtendedRequest;
|
||||
struct ldap_ExtendedResponse ExtendedResponse;
|
||||
};
|
||||
|
||||
struct ldap_Control {
|
||||
const char *oid;
|
||||
BOOL critical;
|
||||
DATA_BLOB value;
|
||||
};
|
||||
|
||||
struct ldap_message {
|
||||
TALLOC_CTX *mem_ctx;
|
||||
uint32 messageid;
|
||||
uint8 type;
|
||||
union ldap_Request r;
|
||||
int num_controls;
|
||||
struct ldap_Control *controls;
|
||||
};
|
||||
|
||||
struct ldap_queue_entry {
|
||||
struct ldap_queue_entry *next, *prev;
|
||||
int msgid;
|
||||
struct ldap_message *msg;
|
||||
};
|
||||
|
||||
struct ldap_connection {
|
||||
TALLOC_CTX *mem_ctx;
|
||||
int sock;
|
||||
int next_msgid;
|
||||
char *host;
|
||||
uint16 port;
|
||||
BOOL ldaps;
|
||||
|
||||
const char *auth_dn;
|
||||
const char *simple_pw;
|
||||
|
||||
/* Current outstanding search entry */
|
||||
int searchid;
|
||||
|
||||
/* List for incoming search entries */
|
||||
struct ldap_queue_entry *search_entries;
|
||||
|
||||
/* Outstanding LDAP requests that have not yet been replied to */
|
||||
struct ldap_queue_entry *outstanding;
|
||||
};
|
||||
|
||||
#endif
|
@ -55,7 +55,7 @@ struct smb_share_mode_entry {
|
||||
uint32_t access_mask;
|
||||
struct timeval open_time;
|
||||
uint32_t file_id;
|
||||
pid_t pid;
|
||||
struct process_id pid;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Unix SMB/CIFS mplementation.
|
||||
LDAP protocol helper functions for SAMBA
|
||||
Copyright (C) Gerald Carter 2001-2003
|
||||
|
||||
@ -40,6 +40,7 @@ struct smbldap_state;
|
||||
#define LDAP_OBJ_IDPOOL "sambaUnixIdPool"
|
||||
#define LDAP_OBJ_IDMAP_ENTRY "sambaIdmapEntry"
|
||||
#define LDAP_OBJ_SID_ENTRY "sambaSidEntry"
|
||||
#define LDAP_OBJ_TRUST_PASSWORD "sambaTrustPassword"
|
||||
|
||||
#define LDAP_OBJ_ACCOUNT "account"
|
||||
#define LDAP_OBJ_POSIXACCOUNT "posixAccount"
|
||||
@ -99,6 +100,8 @@ struct smbldap_state;
|
||||
#define LDAP_ATTR_SID_LIST 40
|
||||
#define LDAP_ATTR_MOD_TIMESTAMP 41
|
||||
#define LDAP_ATTR_LOGON_HOURS 42
|
||||
#define LDAP_ATTR_TRUST_PASSWD_FLAGS 43
|
||||
|
||||
|
||||
typedef struct _attrib_map_entry {
|
||||
int attrib;
|
||||
@ -117,6 +120,8 @@ extern ATTRIB_MAP_ENTRY groupmap_attr_list[];
|
||||
extern ATTRIB_MAP_ENTRY groupmap_attr_list_to_delete[];
|
||||
extern ATTRIB_MAP_ENTRY idpool_attr_list[];
|
||||
extern ATTRIB_MAP_ENTRY sidmap_attr_list[];
|
||||
extern ATTRIB_MAP_ENTRY trustpw_attr_list[];
|
||||
|
||||
|
||||
/* Function declarations -- not included in proto.h so we don't
|
||||
have to worry about LDAP structure types */
|
||||
|
@ -43,7 +43,7 @@ typedef enum _spnego_negResult {
|
||||
} negResult_t;
|
||||
|
||||
typedef struct spnego_negTokenInit {
|
||||
char **mechTypes;
|
||||
const char **mechTypes;
|
||||
int reqFlags;
|
||||
DATA_BLOB mechToken;
|
||||
DATA_BLOB mechListMIC;
|
||||
|
@ -18,8 +18,6 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#define srvstr_pull(base_ptr, dest, src, dest_len, src_len, flags) \
|
||||
pull_string(base_ptr, dest, src, dest_len, src_len, flags)
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
* account policy storage
|
||||
* Copyright (C) Jean François Micouleau 1998-2001.
|
||||
* Copyright (C) Andrew Bartlett 2002
|
||||
* Copyright (C) Guenther Deschner 2004-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
|
||||
@ -22,102 +23,65 @@
|
||||
#include "includes.h"
|
||||
static TDB_CONTEXT *tdb;
|
||||
|
||||
#define DATABASE_VERSION 2
|
||||
/* cache all entries for 60 seconds for to save ldap-queries (cache is updated
|
||||
* after this period if admins do not use pdbedit or usermanager but manipulate
|
||||
* ldap directly) - gd */
|
||||
|
||||
/****************************************************************************
|
||||
Set default for a field if it is empty
|
||||
****************************************************************************/
|
||||
#define DATABASE_VERSION 3
|
||||
#define AP_LASTSET "LAST_CACHE_UPDATE"
|
||||
#define AP_TTL 60
|
||||
|
||||
static void set_default_on_empty(int field, uint32 value)
|
||||
{
|
||||
if (account_policy_get(field, NULL))
|
||||
return;
|
||||
account_policy_set(field, value);
|
||||
return;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Open the account policy tdb.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL init_account_policy(void)
|
||||
{
|
||||
const char *vstring = "INFO/version";
|
||||
uint32 version;
|
||||
|
||||
if (tdb)
|
||||
return True;
|
||||
tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
|
||||
if (!tdb) {
|
||||
DEBUG(0,("Failed to open account policy database\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* handle a Samba upgrade */
|
||||
tdb_lock_bystring(tdb, vstring,0);
|
||||
if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
|
||||
tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
|
||||
|
||||
set_default_on_empty(
|
||||
AP_MIN_PASSWORD_LEN,
|
||||
MINPASSWDLENGTH);/* 5 chars minimum */
|
||||
set_default_on_empty(
|
||||
AP_PASSWORD_HISTORY,
|
||||
0); /* don't keep any old password */
|
||||
set_default_on_empty(
|
||||
AP_USER_MUST_LOGON_TO_CHG_PASS,
|
||||
0); /* don't force user to logon */
|
||||
set_default_on_empty(
|
||||
AP_MAX_PASSWORD_AGE,
|
||||
(uint32)-1); /* don't expire */
|
||||
set_default_on_empty(
|
||||
AP_MIN_PASSWORD_AGE,
|
||||
0); /* 0 days */
|
||||
set_default_on_empty(
|
||||
AP_LOCK_ACCOUNT_DURATION,
|
||||
30); /* lockout for 30 minutes */
|
||||
set_default_on_empty(
|
||||
AP_RESET_COUNT_TIME,
|
||||
30); /* reset after 30 minutes */
|
||||
set_default_on_empty(
|
||||
AP_BAD_ATTEMPT_LOCKOUT,
|
||||
0); /* don't lockout */
|
||||
set_default_on_empty(
|
||||
AP_TIME_TO_LOGOUT,
|
||||
-1); /* don't force logout */
|
||||
set_default_on_empty(
|
||||
AP_REFUSE_MACHINE_PW_CHANGE,
|
||||
0); /* allow machine pw changes */
|
||||
}
|
||||
tdb_unlock_bystring(tdb, vstring);
|
||||
|
||||
/* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
|
||||
|
||||
privilege_create_account( &global_sid_World );
|
||||
privilege_create_account( &global_sid_Builtin_Administrators );
|
||||
privilege_create_account( &global_sid_Builtin_Account_Operators );
|
||||
privilege_create_account( &global_sid_Builtin_Server_Operators );
|
||||
privilege_create_account( &global_sid_Builtin_Print_Operators );
|
||||
privilege_create_account( &global_sid_Builtin_Backup_Operators );
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
struct ap_table {
|
||||
int field;
|
||||
const char *string;
|
||||
} account_policy_names[] = {
|
||||
{AP_MIN_PASSWORD_LEN, "min password length"},
|
||||
{AP_PASSWORD_HISTORY, "password history"},
|
||||
{AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password"},
|
||||
{AP_MAX_PASSWORD_AGE, "maximum password age"},
|
||||
{AP_MIN_PASSWORD_AGE,"minimum password age"},
|
||||
{AP_LOCK_ACCOUNT_DURATION, "lockout duration"},
|
||||
{AP_RESET_COUNT_TIME, "reset count minutes"},
|
||||
{AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt"},
|
||||
{AP_TIME_TO_LOGOUT, "disconnect time"},
|
||||
{AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change"},
|
||||
{0, NULL}
|
||||
uint32 default_val;
|
||||
const char *description;
|
||||
const char *ldap_attr;
|
||||
};
|
||||
|
||||
static const struct ap_table account_policy_names[] = {
|
||||
{AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
|
||||
"Minimal password length (default: 5)",
|
||||
"sambaMinPwdLength" },
|
||||
|
||||
{AP_PASSWORD_HISTORY, "password history", 0,
|
||||
"Length of Password History Entries (default: 0 => off)",
|
||||
"sambaPwdHistoryLength" },
|
||||
|
||||
{AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
|
||||
"Force Users to logon for password change (default: 0 => off, 2 => on)",
|
||||
"sambaLogonToChgPwd" },
|
||||
|
||||
{AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
|
||||
"Maximum password age, in seconds (default: -1 => never expire passwords)",
|
||||
"sambaMaxPwdAge" },
|
||||
|
||||
{AP_MIN_PASSWORD_AGE,"minimum password age", 0,
|
||||
"Minimal password age, in seconds (default: 0 => allow immediate password change)",
|
||||
"sambaMinPwdAge" },
|
||||
|
||||
{AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
|
||||
"Lockout duration in minutes (default: 30, -1 => forever)",
|
||||
"sambaLockoutDuration" },
|
||||
|
||||
{AP_RESET_COUNT_TIME, "reset count minutes", 30,
|
||||
"Reset time after lockout in minutes (default: 30)",
|
||||
"sambaLockoutObservationWindow" },
|
||||
|
||||
{AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
|
||||
"Lockout users after bad logon attempts (default: 0 => off)",
|
||||
"sambaLockoutThreshold" },
|
||||
|
||||
{AP_TIME_TO_LOGOUT, "disconnect time", -1,
|
||||
"Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
|
||||
"sambaForceLogoff" },
|
||||
|
||||
{AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
|
||||
"Allow Machine Password changes (default: 0 => off)",
|
||||
"sambaRefuseMachinePwdChange" },
|
||||
|
||||
{0, NULL, 0, "", NULL}
|
||||
};
|
||||
|
||||
char *account_policy_names_list(void)
|
||||
@ -148,7 +112,7 @@ char *account_policy_names_list(void)
|
||||
Get the account policy name as a string from its #define'ed number
|
||||
****************************************************************************/
|
||||
|
||||
static const char *decode_account_policy_name(int field)
|
||||
const char *decode_account_policy_name(int field)
|
||||
{
|
||||
int i;
|
||||
for (i=0; account_policy_names[i].string; i++) {
|
||||
@ -156,7 +120,34 @@ static const char *decode_account_policy_name(int field)
|
||||
return account_policy_names[i].string;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Get the account policy LDAP attribute as a string from its #define'ed number
|
||||
****************************************************************************/
|
||||
|
||||
const char *get_account_policy_attr(int field)
|
||||
{
|
||||
int i;
|
||||
for (i=0; account_policy_names[i].field; i++) {
|
||||
if (field == account_policy_names[i].field)
|
||||
return account_policy_names[i].ldap_attr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Get the account policy description as a string from its #define'ed number
|
||||
****************************************************************************/
|
||||
|
||||
const char *account_policy_get_desc(int field)
|
||||
{
|
||||
int i;
|
||||
for (i=0; account_policy_names[i].string; i++) {
|
||||
if (field == account_policy_names[i].field)
|
||||
return account_policy_names[i].description;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -171,18 +162,146 @@ int account_policy_name_to_fieldnum(const char *name)
|
||||
return account_policy_names[i].field;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
/*****************************************************************************
|
||||
Update LAST-Set counter inside the cache
|
||||
*****************************************************************************/
|
||||
|
||||
static BOOL account_policy_cache_timestamp(uint32 *value, BOOL update,
|
||||
const char *ap_name)
|
||||
{
|
||||
pstring key;
|
||||
uint32 val = 0;
|
||||
time_t now;
|
||||
|
||||
if (ap_name == NULL)
|
||||
return False;
|
||||
|
||||
slprintf(key, sizeof(key)-1, "%s/%s", ap_name, AP_LASTSET);
|
||||
|
||||
if (!init_account_policy())
|
||||
return False;
|
||||
|
||||
if (!tdb_fetch_uint32(tdb, key, &val) && !update) {
|
||||
DEBUG(10,("failed to get last set timestamp of cache\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
*value = val;
|
||||
|
||||
DEBUG(10, ("account policy cache lastset was: %s\n", http_timestring(val)));
|
||||
|
||||
if (update) {
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
if (!tdb_store_uint32(tdb, key, (uint32)now)) {
|
||||
DEBUG(1, ("tdb_store_uint32 failed for %s\n", key));
|
||||
return False;
|
||||
}
|
||||
DEBUG(10, ("account policy cache lastset now: %s\n", http_timestring(now)));
|
||||
*value = now;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Get default value for account policy
|
||||
*****************************************************************************/
|
||||
|
||||
BOOL account_policy_get_default(int account_policy, uint32 *val)
|
||||
{
|
||||
int i;
|
||||
for (i=0; account_policy_names[i].field; i++) {
|
||||
if (account_policy_names[i].field == account_policy) {
|
||||
*val = account_policy_names[i].default_val;
|
||||
return True;
|
||||
}
|
||||
}
|
||||
DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
|
||||
account_policy));
|
||||
return False;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Set default for a field if it is empty
|
||||
*****************************************************************************/
|
||||
|
||||
static BOOL account_policy_set_default_on_empty(int account_policy)
|
||||
{
|
||||
|
||||
uint32 value;
|
||||
|
||||
if (!account_policy_get(account_policy, &value) &&
|
||||
!account_policy_get_default(account_policy, &value)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return account_policy_set(account_policy, value);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Open the account policy tdb.
|
||||
***`*************************************************************************/
|
||||
|
||||
BOOL init_account_policy(void)
|
||||
{
|
||||
|
||||
const char *vstring = "INFO/version";
|
||||
uint32 version;
|
||||
int i;
|
||||
|
||||
if (tdb)
|
||||
return True;
|
||||
|
||||
tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
|
||||
if (!tdb) {
|
||||
DEBUG(0,("Failed to open account policy database\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* handle a Samba upgrade */
|
||||
tdb_lock_bystring(tdb, vstring,0);
|
||||
if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
|
||||
|
||||
tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
|
||||
|
||||
for (i=0; account_policy_names[i].field; i++) {
|
||||
|
||||
if (!account_policy_set_default_on_empty(account_policy_names[i].field)) {
|
||||
DEBUG(0,("failed to set default value in account policy tdb\n"));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tdb_unlock_bystring(tdb, vstring);
|
||||
|
||||
/* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
|
||||
|
||||
privilege_create_account( &global_sid_World );
|
||||
privilege_create_account( &global_sid_Builtin_Administrators );
|
||||
privilege_create_account( &global_sid_Builtin_Account_Operators );
|
||||
privilege_create_account( &global_sid_Builtin_Server_Operators );
|
||||
privilege_create_account( &global_sid_Builtin_Print_Operators );
|
||||
privilege_create_account( &global_sid_Builtin_Backup_Operators );
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Get an account policy (from tdb)
|
||||
*****************************************************************************/
|
||||
|
||||
BOOL account_policy_get(int field, uint32 *value)
|
||||
{
|
||||
fstring name;
|
||||
uint32 regval;
|
||||
|
||||
if(!init_account_policy())return False;
|
||||
if (!init_account_policy())
|
||||
return False;
|
||||
|
||||
if (value)
|
||||
*value = 0;
|
||||
@ -199,18 +318,21 @@ BOOL account_policy_get(int field, uint32 *value)
|
||||
if (value)
|
||||
*value = regval;
|
||||
|
||||
DEBUG(10,("account_policy_get: %s:%d\n", name, regval));
|
||||
DEBUG(10,("account_policy_get: name: %s, val: %d\n", name, regval));
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Set an account policy (in tdb)
|
||||
****************************************************************************/
|
||||
|
||||
BOOL account_policy_set(int field, uint32 value)
|
||||
{
|
||||
fstring name;
|
||||
|
||||
if(!init_account_policy())return False;
|
||||
if (!init_account_policy())
|
||||
return False;
|
||||
|
||||
fstrcpy(name, decode_account_policy_name(field));
|
||||
if (!*name) {
|
||||
@ -219,15 +341,71 @@ BOOL account_policy_set(int field, uint32 value)
|
||||
}
|
||||
|
||||
if (!tdb_store_uint32(tdb, name, value)) {
|
||||
DEBUG(1, ("tdb_store_uint32 failed for field %d (%s) on value %u", field, name, value));
|
||||
DEBUG(1, ("tdb_store_uint32 failed for field %d (%s) on value %u\n", field, name, value));
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(10,("account_policy_set: %s:%d\n", name, value));
|
||||
DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Set an account policy in the cache
|
||||
****************************************************************************/
|
||||
|
||||
BOOL cache_account_policy_set(int field, uint32 value)
|
||||
{
|
||||
uint32 lastset;
|
||||
const char *policy_name = NULL;
|
||||
|
||||
policy_name = decode_account_policy_name(field);
|
||||
if (policy_name == NULL) {
|
||||
DEBUG(0,("cache_account_policy_set: no policy found\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(10,("cache_account_policy_set: updating account pol cache\n"));
|
||||
|
||||
if (!account_policy_set(field, value)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!account_policy_cache_timestamp(&lastset, True, policy_name))
|
||||
{
|
||||
DEBUG(10,("cache_account_policy_set: failed to get lastest cache update timestamp\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(10,("cache_account_policy_set: cache valid until: %s\n", http_timestring(lastset+AP_TTL)));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
Get an account policy from the cache
|
||||
*****************************************************************************/
|
||||
|
||||
BOOL cache_account_policy_get(int field, uint32 *value)
|
||||
{
|
||||
uint32 lastset;
|
||||
|
||||
if (!account_policy_cache_timestamp(&lastset, False,
|
||||
decode_account_policy_name(field)))
|
||||
{
|
||||
DEBUG(10,("cache_account_policy_get: failed to get latest cache update timestamp\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if ((lastset + AP_TTL) < (uint32)time(NULL) ) {
|
||||
DEBUG(10,("cache_account_policy_get: no valid cache entry (cache expired)\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
return account_policy_get(field, value);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
|
80
source3/lib/arc4.c
Normal file
80
source3/lib/arc4.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
An implementation of arc4.
|
||||
|
||||
Copyright (C) Jeremy Allison 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"
|
||||
|
||||
/*****************************************************************
|
||||
Initialize state for an arc4 crypt/decrpyt.
|
||||
arc4 state is 258 bytes - last 2 bytes are the index bytes.
|
||||
*****************************************************************/
|
||||
|
||||
void smb_arc4_init(unsigned char arc4_state_out[258], const unsigned char *key, size_t keylen)
|
||||
{
|
||||
size_t ind;
|
||||
unsigned char j = 0;
|
||||
|
||||
for (ind = 0; ind < 256; ind++) {
|
||||
arc4_state_out[ind] = (unsigned char)ind;
|
||||
}
|
||||
|
||||
for( ind = 0; ind < 256; ind++) {
|
||||
unsigned char tc;
|
||||
|
||||
j += (arc4_state_out[ind] + key[ind%keylen]);
|
||||
|
||||
tc = arc4_state_out[ind];
|
||||
arc4_state_out[ind] = arc4_state_out[j];
|
||||
arc4_state_out[j] = tc;
|
||||
}
|
||||
arc4_state_out[256] = 0;
|
||||
arc4_state_out[257] = 0;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
Do the arc4 crypt/decrpyt.
|
||||
arc4 state is 258 bytes - last 2 bytes are the index bytes.
|
||||
*****************************************************************/
|
||||
|
||||
void smb_arc4_crypt(unsigned char arc4_state_inout[258], unsigned char *data, size_t len)
|
||||
{
|
||||
unsigned char index_i = arc4_state_inout[256];
|
||||
unsigned char index_j = arc4_state_inout[257];
|
||||
size_t ind;
|
||||
|
||||
for( ind = 0; ind < len; ind++) {
|
||||
unsigned char tc;
|
||||
unsigned char t;
|
||||
|
||||
index_i++;
|
||||
index_j += arc4_state_inout[index_i];
|
||||
|
||||
tc = arc4_state_inout[index_i];
|
||||
arc4_state_inout[index_i] = arc4_state_inout[index_j];
|
||||
arc4_state_inout[index_j] = tc;
|
||||
|
||||
t = arc4_state_inout[index_i] + arc4_state_inout[index_j];
|
||||
data[ind] = data[ind] ^ arc4_state_inout[t];
|
||||
}
|
||||
|
||||
arc4_state_inout[256] = index_i;
|
||||
arc4_state_inout[257] = index_j;
|
||||
}
|
@ -22,8 +22,9 @@
|
||||
#include "includes.h"
|
||||
|
||||
/*******************************************************************
|
||||
free() a data blob
|
||||
Free() a data blob.
|
||||
*******************************************************************/
|
||||
|
||||
static void free_data_blob(DATA_BLOB *d)
|
||||
{
|
||||
if ((d) && (d->free)) {
|
||||
@ -32,8 +33,8 @@ static void free_data_blob(DATA_BLOB *d)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
construct a data blob, must be freed with data_blob_free()
|
||||
you can pass NULL for p and get a blank data blob
|
||||
Construct a data blob, must be freed with data_blob_free().
|
||||
You can pass NULL for p and get a blank data blob
|
||||
*******************************************************************/
|
||||
|
||||
DATA_BLOB data_blob(const void *p, size_t length)
|
||||
@ -56,8 +57,9 @@ DATA_BLOB data_blob(const void *p, size_t length)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
construct a data blob, using supplied TALLOC_CTX
|
||||
Construct a data blob, using supplied TALLOC_CTX.
|
||||
*******************************************************************/
|
||||
|
||||
DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
|
||||
{
|
||||
DATA_BLOB ret;
|
||||
@ -83,8 +85,9 @@ DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
free a data blob
|
||||
Free a data blob.
|
||||
*******************************************************************/
|
||||
|
||||
void data_blob_free(DATA_BLOB *d)
|
||||
{
|
||||
if (d) {
|
||||
@ -96,8 +99,9 @@ void data_blob_free(DATA_BLOB *d)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
clear a DATA_BLOB's contents
|
||||
Clear a DATA_BLOB's contents
|
||||
*******************************************************************/
|
||||
|
||||
static void data_blob_clear(DATA_BLOB *d)
|
||||
{
|
||||
if (d->data) {
|
||||
@ -106,11 +110,11 @@ static void data_blob_clear(DATA_BLOB *d)
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
free a data blob and clear its contents
|
||||
Free a data blob and clear its contents
|
||||
*******************************************************************/
|
||||
|
||||
void data_blob_clear_free(DATA_BLOB *d)
|
||||
{
|
||||
data_blob_clear(d);
|
||||
data_blob_free(d);
|
||||
}
|
||||
|
||||
|
@ -448,19 +448,22 @@ BOOL debug_parse_levels(const char *params_str)
|
||||
Receive a "set debug level" message.
|
||||
****************************************************************************/
|
||||
|
||||
static void debug_message(int msg_type, pid_t src, void *buf, size_t len)
|
||||
static void debug_message(int msg_type, struct process_id src,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
const char *params_str = buf;
|
||||
|
||||
/* Check, it's a proper string! */
|
||||
if (params_str[len-1] != '\0') {
|
||||
DEBUG(1, ("Invalid debug message from pid %u to pid %u\n",
|
||||
(unsigned int)src, (unsigned int)getpid()));
|
||||
(unsigned int)procid_to_pid(&src),
|
||||
(unsigned int)getpid()));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(3, ("INFO: Remote set of debug to `%s' (pid %u from pid %u)\n",
|
||||
params_str, (unsigned int)getpid(), (unsigned int)src));
|
||||
params_str, (unsigned int)getpid(),
|
||||
(unsigned int)procid_to_pid(&src)));
|
||||
|
||||
debug_parse_levels(params_str);
|
||||
}
|
||||
@ -473,7 +476,8 @@ void debug_message_send(pid_t pid, const char *params_str)
|
||||
{
|
||||
if (!params_str)
|
||||
return;
|
||||
message_send_pid(pid, MSG_DEBUG, params_str, strlen(params_str) + 1,
|
||||
message_send_pid(pid_to_procid(pid), MSG_DEBUG,
|
||||
params_str, strlen(params_str) + 1,
|
||||
False);
|
||||
}
|
||||
|
||||
@ -481,11 +485,13 @@ void debug_message_send(pid_t pid, const char *params_str)
|
||||
Return current debug level.
|
||||
****************************************************************************/
|
||||
|
||||
static void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
|
||||
static void debuglevel_message(int msg_type, struct process_id src,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
char *message = debug_list_class_names_and_levels();
|
||||
|
||||
DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",(unsigned int)src));
|
||||
DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",
|
||||
(unsigned int)procid_to_pid(&src)));
|
||||
message_send_pid(src, MSG_DEBUGLEVEL, message, strlen(message) + 1, True);
|
||||
|
||||
SAFE_FREE(message);
|
||||
|
@ -35,7 +35,7 @@ static unsigned long our_dm_mark = 0;
|
||||
* Respond to a POOL_USAGE message by sending back string form of memory
|
||||
* usage stats.
|
||||
**/
|
||||
static void msg_req_dmalloc_mark(int UNUSED(msg_type), pid_t UNUSED(src_pid),
|
||||
static void msg_req_dmalloc_mark(int UNUSED(msg_type), struct process_id UNUSED(src_pid),
|
||||
void *UNUSED(buf), size_t UNUSED(len))
|
||||
{
|
||||
#ifdef ENABLE_DMALLOC
|
||||
@ -49,7 +49,7 @@ static void msg_req_dmalloc_mark(int UNUSED(msg_type), pid_t UNUSED(src_pid),
|
||||
|
||||
|
||||
static void msg_req_dmalloc_log_changed(int UNUSED(msg_type),
|
||||
pid_t UNUSED(src_pid),
|
||||
struct process_id UNUSED(src_pid),
|
||||
void *UNUSED(buf), size_t UNUSED(len))
|
||||
{
|
||||
#ifdef ENABLE_DMALLOC
|
||||
|
@ -251,11 +251,17 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout)
|
||||
char* entry_buf = SMB_STRNDUP(databuf.dptr, databuf.dsize);
|
||||
char *v;
|
||||
time_t t;
|
||||
unsigned u;
|
||||
int status;
|
||||
|
||||
v = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN);
|
||||
|
||||
SAFE_FREE(databuf.dptr);
|
||||
sscanf(entry_buf, CACHE_DATA_FMT, (int*)&t, v);
|
||||
status = sscanf(entry_buf, CACHE_DATA_FMT, &u, v);
|
||||
if ( status != 2 ) {
|
||||
DEBUG(0, ("gencache_get: Invalid return %d from sscanf\n", status ));
|
||||
}
|
||||
t = u;
|
||||
SAFE_FREE(entry_buf);
|
||||
|
||||
DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
|
||||
@ -307,6 +313,8 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
|
||||
TDB_DATA databuf;
|
||||
char *keystr = NULL, *valstr = NULL, *entry = NULL;
|
||||
time_t timeout = 0;
|
||||
int status;
|
||||
unsigned u;
|
||||
|
||||
/* fail completely if get null pointers passed */
|
||||
SMB_ASSERT(fn && keystr_pattern);
|
||||
@ -335,7 +343,11 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
|
||||
entry = SMB_STRNDUP(databuf.dptr, databuf.dsize);
|
||||
SAFE_FREE(databuf.dptr);
|
||||
valstr = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN);
|
||||
sscanf(entry, CACHE_DATA_FMT, (int*)(&timeout), valstr);
|
||||
status = sscanf(entry, CACHE_DATA_FMT, &u, valstr);
|
||||
if ( status != 2 ) {
|
||||
DEBUG(0,("gencache_iterate: invalid return from sscanf %d\n",status));
|
||||
}
|
||||
timeout = u;
|
||||
|
||||
DEBUG(10, ("Calling function with arguments (key = %s, value = %s, timeout = %s)\n",
|
||||
keystr, valstr, ctime(&timeout)));
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
static unsigned char hash[258];
|
||||
static unsigned char smb_arc4_state[258];
|
||||
static uint32 counter;
|
||||
|
||||
static BOOL done_reseed = False;
|
||||
@ -52,61 +52,6 @@ static void get_rand_reseed_data(int *reseed_data)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Setup the seed.
|
||||
*****************************************************************/
|
||||
|
||||
static void seed_random_stream(unsigned char *seedval, size_t seedlen)
|
||||
{
|
||||
unsigned char j = 0;
|
||||
size_t ind;
|
||||
|
||||
for (ind = 0; ind < 256; ind++)
|
||||
hash[ind] = (unsigned char)ind;
|
||||
|
||||
for( ind = 0; ind < 256; ind++) {
|
||||
unsigned char tc;
|
||||
|
||||
j += (hash[ind] + seedval[ind%seedlen]);
|
||||
|
||||
tc = hash[ind];
|
||||
hash[ind] = hash[j];
|
||||
hash[j] = tc;
|
||||
}
|
||||
|
||||
hash[256] = 0;
|
||||
hash[257] = 0;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Get datasize bytes worth of random data.
|
||||
*****************************************************************/
|
||||
|
||||
static void get_random_stream(unsigned char *data, size_t datasize)
|
||||
{
|
||||
unsigned char index_i = hash[256];
|
||||
unsigned char index_j = hash[257];
|
||||
size_t ind;
|
||||
|
||||
for( ind = 0; ind < datasize; ind++) {
|
||||
unsigned char tc;
|
||||
unsigned char t;
|
||||
|
||||
index_i++;
|
||||
index_j += hash[index_i];
|
||||
|
||||
tc = hash[index_i];
|
||||
hash[index_i] = hash[index_j];
|
||||
hash[index_j] = tc;
|
||||
|
||||
t = hash[index_i] + hash[index_j];
|
||||
data[ind] = hash[t];
|
||||
}
|
||||
|
||||
hash[256] = index_i;
|
||||
hash[257] = index_j;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Get a 16 byte hash from the contents of a file.
|
||||
Note that the hash is not initialised.
|
||||
@ -202,7 +147,7 @@ static int do_reseed(BOOL use_fd, int fd)
|
||||
seed_inbuf[i] ^= ((char *)(&reseed_data))[i % sizeof(reseed_data)];
|
||||
}
|
||||
|
||||
seed_random_stream(seed_inbuf, sizeof(seed_inbuf));
|
||||
smb_arc4_init(smb_arc4_state, seed_inbuf, sizeof(seed_inbuf));
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -246,7 +191,7 @@ void generate_random_buffer( unsigned char *out, int len)
|
||||
while(len > 0) {
|
||||
int copy_len = len > 16 ? 16 : len;
|
||||
|
||||
get_random_stream(md4_buf, sizeof(md4_buf));
|
||||
smb_arc4_crypt(smb_arc4_state, md4_buf, sizeof(md4_buf));
|
||||
mdfour(tmp_buf, md4_buf, sizeof(md4_buf));
|
||||
memcpy(p, tmp_buf, copy_len);
|
||||
p += copy_len;
|
||||
|
@ -57,8 +57,8 @@ static int received_signal;
|
||||
struct message_rec {
|
||||
int msg_version;
|
||||
int msg_type;
|
||||
pid_t dest;
|
||||
pid_t src;
|
||||
struct process_id dest;
|
||||
struct process_id src;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
@ -66,7 +66,7 @@ struct message_rec {
|
||||
static struct dispatch_fns {
|
||||
struct dispatch_fns *next, *prev;
|
||||
int msg_type;
|
||||
void (*fn)(int msg_type, pid_t pid, void *buf, size_t len);
|
||||
void (*fn)(int msg_type, struct process_id pid, void *buf, size_t len);
|
||||
} *dispatch_fns;
|
||||
|
||||
/****************************************************************************
|
||||
@ -83,10 +83,12 @@ static void sig_usr1(void)
|
||||
A useful function for testing the message system.
|
||||
****************************************************************************/
|
||||
|
||||
static void ping_message(int msg_type, pid_t src, void *buf, size_t len)
|
||||
static void ping_message(int msg_type, struct process_id src,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
const char *msg = buf ? buf : "none";
|
||||
DEBUG(1,("INFO: Received PING message from PID %u [%s]\n",(unsigned int)src, msg));
|
||||
DEBUG(1,("INFO: Received PING message from PID %s [%s]\n",
|
||||
procid_str_static(&src), msg));
|
||||
message_send_pid(src, MSG_PONG, buf, len, True);
|
||||
}
|
||||
|
||||
@ -123,12 +125,12 @@ BOOL message_init(void)
|
||||
Form a static tdb key from a pid.
|
||||
******************************************************************/
|
||||
|
||||
static TDB_DATA message_key_pid(pid_t pid)
|
||||
static TDB_DATA message_key_pid(struct process_id pid)
|
||||
{
|
||||
static char key[20];
|
||||
TDB_DATA kbuf;
|
||||
|
||||
slprintf(key, sizeof(key)-1, "PID/%d", (int)pid);
|
||||
slprintf(key, sizeof(key)-1, "PID/%s", procid_str_static(&pid));
|
||||
|
||||
kbuf.dptr = (char *)key;
|
||||
kbuf.dsize = strlen(key)+1;
|
||||
@ -140,8 +142,9 @@ static TDB_DATA message_key_pid(pid_t pid)
|
||||
then delete its record in the database.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL message_notify(pid_t pid)
|
||||
static BOOL message_notify(struct process_id procid)
|
||||
{
|
||||
pid_t pid = procid.pid;
|
||||
/*
|
||||
* Doing kill with a non-positive pid causes messages to be
|
||||
* sent to places we don't want.
|
||||
@ -152,7 +155,7 @@ static BOOL message_notify(pid_t pid)
|
||||
if (kill(pid, SIGUSR1) == -1) {
|
||||
if (errno == ESRCH) {
|
||||
DEBUG(2,("pid %d doesn't exist - deleting messages record\n", (int)pid));
|
||||
tdb_delete(tdb, message_key_pid(pid));
|
||||
tdb_delete(tdb, message_key_pid(procid));
|
||||
} else {
|
||||
DEBUG(2,("message to process %d failed - %s\n", (int)pid, strerror(errno)));
|
||||
}
|
||||
@ -165,8 +168,10 @@ static BOOL message_notify(pid_t pid)
|
||||
Send a message to a particular pid.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf, size_t len,
|
||||
BOOL duplicates_allowed, unsigned int timeout)
|
||||
static BOOL message_send_pid_internal(struct process_id pid, int msg_type,
|
||||
const void *buf, size_t len,
|
||||
BOOL duplicates_allowed,
|
||||
unsigned int timeout)
|
||||
{
|
||||
TDB_DATA kbuf;
|
||||
TDB_DATA dbuf;
|
||||
@ -180,12 +185,12 @@ static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf,
|
||||
* sent to places we don't want.
|
||||
*/
|
||||
|
||||
SMB_ASSERT(pid > 0);
|
||||
SMB_ASSERT(procid_to_pid(&pid) > 0);
|
||||
|
||||
rec.msg_version = MESSAGE_VERSION;
|
||||
rec.msg_type = msg_type;
|
||||
rec.dest = pid;
|
||||
rec.src = sys_getpid();
|
||||
rec.src = procid_self();
|
||||
rec.len = len;
|
||||
|
||||
kbuf = message_key_pid(pid);
|
||||
@ -288,7 +293,7 @@ static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf,
|
||||
Send a message to a particular pid - no timeout.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed)
|
||||
BOOL message_send_pid(struct process_id pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed)
|
||||
{
|
||||
return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, 0);
|
||||
}
|
||||
@ -297,7 +302,7 @@ BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len, BOOL
|
||||
Send a message to a particular pid, with timeout in seconds.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL message_send_pid_with_timeout(pid_t pid, int msg_type, const void *buf, size_t len,
|
||||
BOOL message_send_pid_with_timeout(struct process_id pid, int msg_type, const void *buf, size_t len,
|
||||
BOOL duplicates_allowed, unsigned int timeout)
|
||||
{
|
||||
return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, timeout);
|
||||
@ -307,7 +312,7 @@ BOOL message_send_pid_with_timeout(pid_t pid, int msg_type, const void *buf, siz
|
||||
Count the messages pending for a particular pid. Expensive....
|
||||
****************************************************************************/
|
||||
|
||||
unsigned int messages_pending_for_pid(pid_t pid)
|
||||
unsigned int messages_pending_for_pid(struct process_id pid)
|
||||
{
|
||||
TDB_DATA kbuf;
|
||||
TDB_DATA dbuf;
|
||||
@ -349,7 +354,7 @@ static BOOL retrieve_all_messages(char **msgs_buf, size_t *total_len)
|
||||
*msgs_buf = NULL;
|
||||
*total_len = 0;
|
||||
|
||||
kbuf = message_key_pid(sys_getpid());
|
||||
kbuf = message_key_pid(pid_to_procid(sys_getpid()));
|
||||
|
||||
if (tdb_chainlock(tdb, kbuf) == -1)
|
||||
return False;
|
||||
@ -377,7 +382,8 @@ static BOOL retrieve_all_messages(char **msgs_buf, size_t *total_len)
|
||||
Parse out the next message for the current process.
|
||||
****************************************************************************/
|
||||
|
||||
static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type, pid_t *src, char **buf, size_t *len)
|
||||
static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type,
|
||||
struct process_id *src, char **buf, size_t *len)
|
||||
{
|
||||
struct message_rec rec;
|
||||
char *ret_buf = *buf;
|
||||
@ -420,7 +426,7 @@ static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type, pid_t
|
||||
void message_dispatch(void)
|
||||
{
|
||||
int msg_type;
|
||||
pid_t src;
|
||||
struct process_id src;
|
||||
char *buf;
|
||||
char *msgs_buf;
|
||||
size_t len, total_len;
|
||||
@ -438,8 +444,9 @@ void message_dispatch(void)
|
||||
return;
|
||||
|
||||
for (buf = msgs_buf; message_recv(msgs_buf, total_len, &msg_type, &src, &buf, &len); buf += len) {
|
||||
DEBUG(10,("message_dispatch: received msg_type=%d src_pid=%u\n",
|
||||
msg_type, (unsigned int) src));
|
||||
DEBUG(10,("message_dispatch: received msg_type=%d "
|
||||
"src_pid=%u\n", msg_type,
|
||||
(unsigned int) procid_to_pid(&src)));
|
||||
n_handled = 0;
|
||||
for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
|
||||
if (dfn->msg_type == msg_type) {
|
||||
@ -464,7 +471,8 @@ void message_dispatch(void)
|
||||
****************************************************************************/
|
||||
|
||||
void message_register(int msg_type,
|
||||
void (*fn)(int msg_type, pid_t pid, void *buf, size_t len))
|
||||
void (*fn)(int msg_type, struct process_id pid,
|
||||
void *buf, size_t len))
|
||||
{
|
||||
struct dispatch_fns *dfn;
|
||||
|
||||
@ -543,8 +551,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void
|
||||
/* If the pid was not found delete the entry from connections.tdb */
|
||||
|
||||
if (errno == ESRCH) {
|
||||
DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n",
|
||||
(unsigned int)crec.pid, crec.cnum, crec.name));
|
||||
DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n",
|
||||
procid_str_static(&crec.pid),
|
||||
crec.cnum, crec.name));
|
||||
tdb_delete(the_tdb, kbuf);
|
||||
}
|
||||
}
|
||||
|
@ -231,77 +231,3 @@ void smb_run_idle_events(time_t now)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* This Function registers a exit event
|
||||
*
|
||||
* the registered functions are run on exit()
|
||||
* and maybe shutdown idle connections (e.g. to an LDAP server)
|
||||
***************************************************************************/
|
||||
|
||||
struct smb_exit_list_ent {
|
||||
struct smb_exit_list_ent *prev,*next;
|
||||
smb_event_id_t id;
|
||||
smb_exit_event_fn *fn;
|
||||
void *data;
|
||||
};
|
||||
|
||||
static struct smb_exit_list_ent *smb_exit_event_list = NULL;
|
||||
|
||||
smb_event_id_t smb_register_exit_event(smb_exit_event_fn *fn, void *data)
|
||||
{
|
||||
struct smb_exit_list_ent *event;
|
||||
static smb_event_id_t smb_exit_event_id = 1;
|
||||
|
||||
if (!fn) {
|
||||
return SMB_EVENT_ID_INVALID;
|
||||
}
|
||||
|
||||
event = SMB_MALLOC_P(struct smb_exit_list_ent);
|
||||
if (!event) {
|
||||
DEBUG(0,("malloc() failed!\n"));
|
||||
return SMB_EVENT_ID_INVALID;
|
||||
}
|
||||
event->fn = fn;
|
||||
event->data = data;
|
||||
event->id = smb_exit_event_id++;
|
||||
|
||||
DLIST_ADD(smb_exit_event_list,event);
|
||||
|
||||
return event->id;
|
||||
}
|
||||
|
||||
BOOL smb_unregister_exit_event(smb_event_id_t id)
|
||||
{
|
||||
struct smb_exit_list_ent *event = smb_exit_event_list;
|
||||
|
||||
while(event) {
|
||||
if (event->id == id) {
|
||||
DLIST_REMOVE(smb_exit_event_list,event);
|
||||
SAFE_FREE(event);
|
||||
return True;
|
||||
}
|
||||
event = event->next;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
void smb_run_exit_events(void)
|
||||
{
|
||||
struct smb_exit_list_ent *event = smb_exit_event_list;
|
||||
struct smb_exit_list_ent *tmp = NULL;
|
||||
|
||||
while (event) {
|
||||
event->fn(&event->data);
|
||||
tmp = event;
|
||||
event = event->next;
|
||||
/* exit event should only run one time :-)*/
|
||||
SAFE_FREE(tmp);
|
||||
}
|
||||
|
||||
/* the list is empty now...*/
|
||||
smb_exit_event_list = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ pid_t pidfile_pid(const char *name)
|
||||
goto noproc;
|
||||
}
|
||||
|
||||
if (!process_exists((pid_t)ret)) {
|
||||
if (!process_exists_by_pid(ret)) {
|
||||
goto noproc;
|
||||
}
|
||||
|
||||
|
@ -397,6 +397,8 @@ static BOOL privilege_set_add(PRIVILEGE_SET *priv_set, LUID_ATTR set)
|
||||
|
||||
/*********************************************************************
|
||||
Generate the LUID_ATTR structure based on a bitmask
|
||||
The assumption here is that the privilege has already been validated
|
||||
so we are guaranteed to find it in the list.
|
||||
*********************************************************************/
|
||||
|
||||
LUID_ATTR get_privilege_luid( SE_PRIV *mask )
|
||||
@ -404,8 +406,7 @@ LUID_ATTR get_privilege_luid( SE_PRIV *mask )
|
||||
LUID_ATTR priv_luid;
|
||||
int i;
|
||||
|
||||
priv_luid.attr = 0;
|
||||
priv_luid.luid.high = 0;
|
||||
ZERO_STRUCT( priv_luid );
|
||||
|
||||
for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
|
||||
|
||||
|
@ -267,7 +267,11 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
|
||||
return;
|
||||
|
||||
while ( list[i] ) {
|
||||
SAFE_FREE( list[i] );
|
||||
/* SAFE_FREE generates a warning here that can't be gotten rid
|
||||
* of with CONST_DISCARD */
|
||||
if (list[i] != NULL) {
|
||||
free(CONST_DISCARD(char *, list[i]));
|
||||
}
|
||||
i+=1;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,65 @@
|
||||
#include "includes.h"
|
||||
#include "smbldap.h"
|
||||
|
||||
/**********************************************************************
|
||||
Add the account-policies below the sambaDomain object to LDAP,
|
||||
*********************************************************************/
|
||||
static NTSTATUS add_new_domain_account_policies(struct smbldap_state *ldap_state,
|
||||
const char *domain_name)
|
||||
{
|
||||
NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
|
||||
int i, rc;
|
||||
uint32 policy_default;
|
||||
const char *policy_attr = NULL;
|
||||
pstring dn;
|
||||
LDAPMod **mods = NULL;
|
||||
|
||||
DEBUG(3,("Adding new account policies for domain\n"));
|
||||
|
||||
pstr_sprintf(dn, "%s=%s,%s",
|
||||
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
|
||||
domain_name, lp_ldap_suffix());
|
||||
|
||||
for (i=1; decode_account_policy_name(i) != NULL; i++) {
|
||||
|
||||
pstring val;
|
||||
|
||||
policy_attr = get_account_policy_attr(i);
|
||||
if (!policy_attr) {
|
||||
DEBUG(0,("add_new_domain_account_policies: ops. no policy!\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!account_policy_get_default(i, &policy_default)) {
|
||||
DEBUG(0,("add_new_domain_account_policies: failed to get default account policy\n"));
|
||||
return ntstatus;
|
||||
}
|
||||
|
||||
DEBUG(10,("add_new_domain_account_policies: adding \"%s\" with value: %d\n", policy_attr, policy_default));
|
||||
|
||||
pstr_sprintf(val, "%d", policy_default);
|
||||
|
||||
smbldap_set_mod( &mods, LDAP_MOD_REPLACE, policy_attr, val);
|
||||
|
||||
rc = smbldap_modify(ldap_state, dn, mods);
|
||||
|
||||
if (rc!=LDAP_SUCCESS) {
|
||||
char *ld_error = NULL;
|
||||
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
|
||||
DEBUG(1,("failed to add account policies to dn= %s with: %s\n\t%s\n",
|
||||
dn, ldap_err2string(rc),
|
||||
ld_error ? ld_error : "unknown"));
|
||||
SAFE_FREE(ld_error);
|
||||
ldap_mods_free(mods, True);
|
||||
return ntstatus;
|
||||
}
|
||||
}
|
||||
|
||||
ldap_mods_free(mods, True);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Add the sambaDomain to LDAP, so we don't have to search for this stuff
|
||||
again. This is a once-add operation for now.
|
||||
@ -200,6 +259,13 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
status = add_new_domain_account_policies(ldap_state, domain_name);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("Adding domain account policies for %s failed with %s\n",
|
||||
domain_name, nt_errstr(status)));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return smbldap_search_domain_info(ldap_state, result, domain_name, False);
|
||||
|
||||
}
|
||||
|
@ -225,10 +225,16 @@ int smbrunsecret(const char *cmd, const char *secret)
|
||||
*/
|
||||
int status = 0;
|
||||
pid_t wpid;
|
||||
size_t towrite;
|
||||
ssize_t wrote;
|
||||
|
||||
close(ifd[0]);
|
||||
/* send the secret */
|
||||
write(ifd[1], secret, strlen(secret));
|
||||
towrite = strlen(secret);
|
||||
wrote = write(ifd[1], secret, towrite);
|
||||
if ( wrote != towrite ) {
|
||||
DEBUG(0,("smbrunsecret: wrote %ld of %lu bytes\n",(long)wrote,(unsigned long)towrite));
|
||||
}
|
||||
fsync(ifd[1]);
|
||||
close(ifd[1]);
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
* Respond to a POOL_USAGE message by sending back string form of memory
|
||||
* usage stats.
|
||||
**/
|
||||
void msg_pool_usage(int msg_type, pid_t src_pid,
|
||||
void msg_pool_usage(int msg_type, struct process_id src_pid,
|
||||
void *UNUSED(buf), size_t UNUSED(len))
|
||||
{
|
||||
off_t reply;
|
||||
@ -41,7 +41,7 @@ void msg_pool_usage(int msg_type, pid_t src_pid,
|
||||
DEBUG(2,("Got POOL_USAGE\n"));
|
||||
|
||||
reply = talloc_total_size(NULL);
|
||||
fstr_sprintf(reply_str, "%lld", reply);
|
||||
fstr_sprintf(reply_str, "%ld", (long)reply);
|
||||
|
||||
message_send_pid(src_pid, MSG_POOL_USAGE,
|
||||
reply_str, strlen(reply_str)+1, True);
|
||||
|
@ -782,6 +782,15 @@ BOOL nt_time_is_zero(NTTIME *nt)
|
||||
return False;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Check if two NTTIMEs are the same.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL nt_time_equals(NTTIME *nt1, NTTIME *nt2)
|
||||
{
|
||||
return (nt1->high == nt2->high && nt1->low == nt2->low);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Return a timeval difference in usec.
|
||||
****************************************************************************/
|
||||
@ -792,6 +801,135 @@ SMB_BIG_INT usec_time_diff(const struct timeval *larget, const struct timeval *s
|
||||
return (sec_diff * 1000000) + (SMB_BIG_INT)(larget->tv_usec - smallt->tv_usec);
|
||||
}
|
||||
|
||||
/*
|
||||
return a timeval struct with the given elements
|
||||
*/
|
||||
struct timeval timeval_set(uint32_t secs, uint32_t usecs)
|
||||
{
|
||||
struct timeval tv;
|
||||
tv.tv_sec = secs;
|
||||
tv.tv_usec = usecs;
|
||||
return tv;
|
||||
}
|
||||
|
||||
/*
|
||||
return a zero timeval
|
||||
*/
|
||||
struct timeval timeval_zero(void)
|
||||
{
|
||||
return timeval_set(0,0);
|
||||
}
|
||||
|
||||
/*
|
||||
return True if a timeval is zero
|
||||
*/
|
||||
BOOL timeval_is_zero(const struct timeval *tv)
|
||||
{
|
||||
return tv->tv_sec == 0 && tv->tv_usec == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
return a timeval for the current time
|
||||
*/
|
||||
struct timeval timeval_current(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
GetTimeOfDay(&tv);
|
||||
return tv;
|
||||
}
|
||||
|
||||
/*
|
||||
return a timeval ofs microseconds after tv
|
||||
*/
|
||||
struct timeval timeval_add(const struct timeval *tv,
|
||||
uint32_t secs, uint32_t usecs)
|
||||
{
|
||||
struct timeval tv2 = *tv;
|
||||
tv2.tv_sec += secs;
|
||||
tv2.tv_usec += usecs;
|
||||
tv2.tv_sec += tv2.tv_usec / 1000000;
|
||||
tv2.tv_usec = tv2.tv_usec % 1000000;
|
||||
return tv2;
|
||||
}
|
||||
|
||||
/*
|
||||
return the sum of two timeval structures
|
||||
*/
|
||||
struct timeval timeval_sum(const struct timeval *tv1,
|
||||
const struct timeval *tv2)
|
||||
{
|
||||
return timeval_add(tv1, tv2->tv_sec, tv2->tv_usec);
|
||||
}
|
||||
|
||||
/*
|
||||
return a timeval secs/usecs into the future
|
||||
*/
|
||||
struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
|
||||
{
|
||||
struct timeval tv = timeval_current();
|
||||
return timeval_add(&tv, secs, usecs);
|
||||
}
|
||||
|
||||
/*
|
||||
compare two timeval structures.
|
||||
Return -1 if tv1 < tv2
|
||||
Return 0 if tv1 == tv2
|
||||
Return 1 if tv1 > tv2
|
||||
*/
|
||||
int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
|
||||
{
|
||||
if (tv1->tv_sec > tv2->tv_sec) return 1;
|
||||
if (tv1->tv_sec < tv2->tv_sec) return -1;
|
||||
if (tv1->tv_usec > tv2->tv_usec) return 1;
|
||||
if (tv1->tv_usec < tv2->tv_usec) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
return the difference between two timevals as a timeval
|
||||
if tv1 comes after tv2, then return a zero timeval
|
||||
(this is *tv2 - *tv1)
|
||||
*/
|
||||
struct timeval timeval_until(const struct timeval *tv1,
|
||||
const struct timeval *tv2)
|
||||
{
|
||||
struct timeval t;
|
||||
if (timeval_compare(tv1, tv2) >= 0) {
|
||||
return timeval_zero();
|
||||
}
|
||||
t.tv_sec = tv2->tv_sec - tv1->tv_sec;
|
||||
if (tv1->tv_usec > tv2->tv_usec) {
|
||||
t.tv_sec--;
|
||||
t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
|
||||
} else {
|
||||
t.tv_usec = tv2->tv_usec - tv1->tv_usec;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
return the lesser of two timevals
|
||||
*/
|
||||
struct timeval timeval_min(const struct timeval *tv1,
|
||||
const struct timeval *tv2)
|
||||
{
|
||||
if (tv1->tv_sec < tv2->tv_sec) return *tv1;
|
||||
if (tv1->tv_sec > tv2->tv_sec) return *tv2;
|
||||
if (tv1->tv_usec < tv2->tv_usec) return *tv1;
|
||||
return *tv2;
|
||||
}
|
||||
|
||||
/*
|
||||
return the greater of two timevals
|
||||
*/
|
||||
struct timeval timeval_max(const struct timeval *tv1,
|
||||
const struct timeval *tv2)
|
||||
{
|
||||
if (tv1->tv_sec > tv2->tv_sec) return *tv1;
|
||||
if (tv1->tv_sec < tv2->tv_sec) return *tv2;
|
||||
if (tv1->tv_usec > tv2->tv_usec) return *tv1;
|
||||
return *tv2;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
convert ASN.1 GeneralizedTime string to unix-time
|
||||
|
@ -1404,12 +1404,22 @@ BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
|
||||
Check if a process exists. Does this work on all unixes?
|
||||
****************************************************************************/
|
||||
|
||||
BOOL process_exists(pid_t pid)
|
||||
BOOL process_exists(const struct process_id pid)
|
||||
{
|
||||
if (!procid_is_local(&pid)) {
|
||||
/* This *SEVERELY* needs fixing. */
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Doing kill with a non-positive pid causes messages to be
|
||||
* sent to places we don't want. */
|
||||
SMB_ASSERT(pid > 0);
|
||||
return(kill(pid,0) == 0 || errno != ESRCH);
|
||||
SMB_ASSERT(pid.pid > 0);
|
||||
return(kill(pid.pid,0) == 0 || errno != ESRCH);
|
||||
}
|
||||
|
||||
BOOL process_exists_by_pid(pid_t pid)
|
||||
{
|
||||
return process_exists(pid_to_procid(pid));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
@ -2756,3 +2766,57 @@ uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
|
||||
|
||||
return (uint32)-1;
|
||||
}
|
||||
|
||||
pid_t procid_to_pid(const struct process_id *proc)
|
||||
{
|
||||
return proc->pid;
|
||||
}
|
||||
|
||||
struct process_id pid_to_procid(pid_t pid)
|
||||
{
|
||||
struct process_id result;
|
||||
result.pid = pid;
|
||||
return result;
|
||||
}
|
||||
|
||||
struct process_id procid_self(void)
|
||||
{
|
||||
return pid_to_procid(sys_getpid());
|
||||
}
|
||||
|
||||
BOOL procid_equal(const struct process_id *p1, const struct process_id *p2)
|
||||
{
|
||||
return (p1->pid == p2->pid);
|
||||
}
|
||||
|
||||
BOOL procid_is_me(const struct process_id *pid)
|
||||
{
|
||||
return (pid->pid == sys_getpid());
|
||||
}
|
||||
|
||||
struct process_id interpret_pid(const char *pid_string)
|
||||
{
|
||||
return pid_to_procid(atoi(pid_string));
|
||||
}
|
||||
|
||||
char *procid_str_static(const struct process_id *pid)
|
||||
{
|
||||
static fstring str;
|
||||
fstr_sprintf(str, "%d", pid->pid);
|
||||
return str;
|
||||
}
|
||||
|
||||
char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid)
|
||||
{
|
||||
return talloc_strdup(mem_ctx, procid_str_static(pid));
|
||||
}
|
||||
|
||||
BOOL procid_valid(const struct process_id *pid)
|
||||
{
|
||||
return (pid->pid != -1);
|
||||
}
|
||||
|
||||
BOOL procid_is_local(const struct process_id *pid)
|
||||
{
|
||||
return True;
|
||||
}
|
||||
|
@ -2,6 +2,11 @@
|
||||
Unix SMB/CIFS implementation.
|
||||
kerberos authorization data (PAC) utility library
|
||||
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
|
||||
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
|
||||
Copyright (C) Andrew Tridgell 2001
|
||||
Copyright (C) Luke Howard 2002-2003
|
||||
Copyright (C) Stefan Metzmacher 2004-2005
|
||||
Copyright (C) Guenther Deschner 2005
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -22,27 +27,6 @@
|
||||
|
||||
#ifdef HAVE_KRB5
|
||||
|
||||
static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data)
|
||||
{
|
||||
DATA_BLOB pac_contents;
|
||||
ASN1_DATA data;
|
||||
int data_type;
|
||||
|
||||
asn1_load(&data, *auth_data);
|
||||
asn1_start_tag(&data, ASN1_SEQUENCE(0));
|
||||
asn1_start_tag(&data, ASN1_SEQUENCE(0));
|
||||
asn1_start_tag(&data, ASN1_CONTEXT(0));
|
||||
asn1_read_Integer(&data, &data_type);
|
||||
asn1_end_tag(&data);
|
||||
asn1_start_tag(&data, ASN1_CONTEXT(1));
|
||||
asn1_read_OctetString(&data, &pac_contents);
|
||||
asn1_end_tag(&data);
|
||||
asn1_end_tag(&data);
|
||||
asn1_end_tag(&data);
|
||||
asn1_free(&data);
|
||||
return pac_contents;
|
||||
}
|
||||
|
||||
static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
@ -75,6 +59,8 @@ static BOOL pac_io_logon_name(const char *desc, PAC_LOGON_NAME *logon_name,
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0 /* Unused (handled now in net_io_user_info3()) - Guenther */
|
||||
static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
@ -159,6 +145,7 @@ static BOOL pac_io_krb_sid_and_attr_array(const char *desc,
|
||||
return True;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static BOOL pac_io_group_membership(const char *desc,
|
||||
GROUP_MEMBERSHIP *membership,
|
||||
@ -216,27 +203,34 @@ static BOOL pac_io_group_membership_array(const char *desc,
|
||||
|
||||
}
|
||||
|
||||
#if 0 /* Unused, replaced using an expanded net_io_user_info3() now - Guenther */
|
||||
static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
uint32 garbage;
|
||||
uint32 garbage, i;
|
||||
|
||||
if (NULL == info)
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "pac_io_pac_logon_info");
|
||||
depth++;
|
||||
|
||||
if (!prs_uint32("unknown", ps, depth, &garbage))
|
||||
if (!prs_align(ps))
|
||||
return False;
|
||||
if (!prs_uint32("unknown", ps, depth, &garbage))
|
||||
if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */
|
||||
return False;
|
||||
if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */
|
||||
return False;
|
||||
if (!prs_uint32("bufferlen", ps, depth, &garbage))
|
||||
return False;
|
||||
if (!prs_uint32("bufferlenhi", ps, depth, &garbage))
|
||||
if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */
|
||||
return False;
|
||||
|
||||
if (!prs_uint32("pointer", ps, depth, &garbage))
|
||||
return False;
|
||||
|
||||
if (!prs_align(ps))
|
||||
return False;
|
||||
if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
|
||||
return False;
|
||||
if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
|
||||
@ -270,7 +264,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
|
||||
|
||||
if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
|
||||
return False;
|
||||
if (!prs_uint16("reserved12", ps, depth, &info->reserved12))
|
||||
if (!prs_uint16("bad_password_count", ps, depth, &info->bad_password_count))
|
||||
return False;
|
||||
if (!prs_uint32("user_rid", ps, depth, &info->user_rid))
|
||||
return False;
|
||||
@ -287,13 +281,7 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
|
||||
if (!prs_uint32("user_flags", ps, depth, &info->user_flags))
|
||||
return False;
|
||||
|
||||
if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3]))
|
||||
if (!prs_uint8s(False, "session_key", ps, depth, info->session_key, 16))
|
||||
return False;
|
||||
|
||||
if (!smb_io_unihdr("hdr_dom_controller",
|
||||
@ -306,30 +294,17 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
|
||||
if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid))
|
||||
return False;
|
||||
|
||||
if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1]))
|
||||
if (!prs_uint8s(False, "lm_session_key", ps, depth, info->lm_session_key, 8))
|
||||
return False;
|
||||
|
||||
/* might be acb_info */
|
||||
if (!prs_uint32("reserved17", ps, depth, &info->reserved17))
|
||||
if (!prs_uint32("acct_flags", ps, depth, &info->acct_flags))
|
||||
return False;
|
||||
|
||||
|
||||
if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5]))
|
||||
return False;
|
||||
if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6]))
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
if (!prs_uint32("unkown", ps, depth, &info->unknown[i])) /* unknown */
|
||||
return False;
|
||||
}
|
||||
|
||||
if (!prs_uint32("sid_count", ps, depth, &info->sid_count))
|
||||
return False;
|
||||
@ -395,15 +370,73 @@ static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
|
||||
&info->res_group_dom_sid, ps, depth))
|
||||
return False;
|
||||
|
||||
if (info->ptr_res_groups)
|
||||
if (info->ptr_res_groups) {
|
||||
|
||||
if (!(info->user_flgs & LOGON_RESOURCE_GROUPS)) {
|
||||
DEBUG(0,("user_flgs attribute does not have LOGON_RESOURCE_GROUPS\n"));
|
||||
/* return False; */
|
||||
}
|
||||
|
||||
if (!pac_io_group_membership_array("res group membership",
|
||||
&info->res_groups,
|
||||
info->res_group_count,
|
||||
ps, depth))
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
#endif
|
||||
|
||||
static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
uint32 garbage;
|
||||
BOOL kerb_validation_info = True;
|
||||
|
||||
if (NULL == info)
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "pac_io_pac_logon_info");
|
||||
depth++;
|
||||
|
||||
if (!prs_align(ps))
|
||||
return False;
|
||||
if (!prs_uint32("unknown", ps, depth, &garbage)) /* 00081001 */
|
||||
return False;
|
||||
if (!prs_uint32("unknown", ps, depth, &garbage)) /* cccccccc */
|
||||
return False;
|
||||
if (!prs_uint32("bufferlen", ps, depth, &garbage))
|
||||
return False;
|
||||
if (!prs_uint32("bufferlenhi", ps, depth, &garbage)) /* 00000000 */
|
||||
return False;
|
||||
|
||||
if(!net_io_user_info3("", &info->info3, ps, depth, 3, kerb_validation_info))
|
||||
return False;
|
||||
|
||||
if (info->info3.ptr_res_group_dom_sid) {
|
||||
if (!smb_io_dom_sid2("res_group_dom_sid",
|
||||
&info->res_group_dom_sid, ps, depth))
|
||||
return False;
|
||||
}
|
||||
|
||||
if (info->info3.ptr_res_groups) {
|
||||
|
||||
if (!(info->info3.user_flgs & LOGON_RESOURCE_GROUPS)) {
|
||||
DEBUG(0,("user_flgs attribute does not have LOGON_RESOURCE_GROUPS\n"));
|
||||
/* return False; */
|
||||
}
|
||||
|
||||
if (!pac_io_group_membership_array("res group membership",
|
||||
&info->res_groups,
|
||||
info->info3.res_group_count,
|
||||
ps, depth))
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static BOOL pac_io_pac_signature_data(const char *desc,
|
||||
@ -411,28 +444,35 @@ static BOOL pac_io_pac_signature_data(const char *desc,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
uint32 siglen = length - sizeof(uint32);
|
||||
if (NULL == data)
|
||||
return False;
|
||||
|
||||
prs_debug(ps, depth, desc, "pac_io_pac_signature_data");
|
||||
depth++;
|
||||
|
||||
if (data == NULL)
|
||||
return False;
|
||||
|
||||
if (!prs_align(ps))
|
||||
return False;
|
||||
if (!prs_uint32("type", ps, depth, &data->type))
|
||||
return False;
|
||||
if (UNMARSHALLING(ps)) {
|
||||
data->signature = PRS_ALLOC_MEM(ps, unsigned char, siglen);
|
||||
if (!data->signature) {
|
||||
|
||||
if (UNMARSHALLING(ps) && length) {
|
||||
data->signature.buffer = PRS_ALLOC_MEM(ps, uint8, siglen);
|
||||
if (!data->signature.buffer) {
|
||||
DEBUG(3, ("No memory available\n"));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen))
|
||||
|
||||
data->signature.buf_len = siglen;
|
||||
|
||||
if (!prs_uint8s(False, "signature", ps, depth, data->signature.buffer, data->signature.buf_len))
|
||||
return False;
|
||||
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr,
|
||||
static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_BUFFER *hdr,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
if (NULL == hdr)
|
||||
@ -445,7 +485,7 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr,
|
||||
return False;
|
||||
|
||||
if (hdr->offset != prs_offset(ps)) {
|
||||
DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n",
|
||||
DEBUG(5,("offset in header(x%x) and data(x%x) do not match, correcting\n",
|
||||
hdr->offset, prs_offset(ps)));
|
||||
prs_set_offset(ps, hdr->offset);
|
||||
}
|
||||
@ -518,10 +558,15 @@ static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr,
|
||||
prs_set_offset(ps, prs_offset(ps) + hdr->size);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* obscure pad */
|
||||
if (!prs_uint32("pad", ps, depth, &hdr->pad))
|
||||
return False;
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr,
|
||||
static BOOL pac_io_pac_info_hdr(const char *desc, PAC_BUFFER *hdr,
|
||||
prs_struct *ps, int depth)
|
||||
{
|
||||
if (NULL == hdr)
|
||||
@ -563,19 +608,19 @@ static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data,
|
||||
return False;
|
||||
|
||||
if (UNMARSHALLING(ps) && data->num_buffers > 0) {
|
||||
if ((data->pac_info_hdr_ptr = PRS_ALLOC_MEM(ps, PAC_INFO_HDR, data->num_buffers)) == NULL) {
|
||||
if ((data->pac_buffer = PRS_ALLOC_MEM(ps, PAC_BUFFER, data->num_buffers)) == NULL) {
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<data->num_buffers; i++) {
|
||||
if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps,
|
||||
if (!pac_io_pac_info_hdr(desc, &data->pac_buffer[i], ps,
|
||||
depth))
|
||||
return False;
|
||||
}
|
||||
|
||||
for (i=0; i<data->num_buffers; i++) {
|
||||
if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i],
|
||||
if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_buffer[i],
|
||||
ps, depth))
|
||||
return False;
|
||||
}
|
||||
@ -583,25 +628,300 @@ static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data,
|
||||
return True;
|
||||
}
|
||||
|
||||
PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx)
|
||||
static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB pac_data,
|
||||
PAC_SIGNATURE_DATA *sig,
|
||||
krb5_context context,
|
||||
krb5_keyblock *keyblock)
|
||||
{
|
||||
DATA_BLOB pac_data_blob = unwrap_pac(auth_data);
|
||||
prs_struct ps;
|
||||
PAC_DATA *pac_data;
|
||||
krb5_error_code ret;
|
||||
krb5_checksum cksum;
|
||||
krb5_keyusage usage = 0;
|
||||
|
||||
smb_krb5_checksum_from_pac_sig(&cksum, sig);
|
||||
|
||||
#ifdef HAVE_KRB5_KU_OTHER_CKSUM /* Heimdal */
|
||||
usage = KRB5_KU_OTHER_CKSUM;
|
||||
#elif defined(HAVE_KRB5_KEYUSAGE_APP_DATA_CKSUM) /* MIT */
|
||||
usage = KRB5_KEYUSAGE_APP_DATA_CKSUM;
|
||||
#else
|
||||
#error UNKNOWN_KRB5_KEYUSAGE
|
||||
#endif
|
||||
|
||||
ret = smb_krb5_verify_checksum(context,
|
||||
keyblock,
|
||||
usage,
|
||||
&cksum,
|
||||
pac_data.data,
|
||||
pac_data.length);
|
||||
|
||||
if (ret) {
|
||||
DEBUG(2,("check_pac_checksum: PAC Verification failed: %s (%d)\n",
|
||||
error_message(ret), ret));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS parse_pac_data(TALLOC_CTX *mem_ctx, DATA_BLOB *pac_data_blob, PAC_DATA *pac_data)
|
||||
{
|
||||
prs_struct ps;
|
||||
PAC_DATA *my_pac;
|
||||
|
||||
if (!prs_init(&ps, pac_data_blob->length, mem_ctx, UNMARSHALL))
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
if (!prs_copy_data_in(&ps, (char *)pac_data_blob->data, pac_data_blob->length))
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
DEBUG(5,("dump_pac_data\n"));
|
||||
prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL);
|
||||
prs_copy_data_in(&ps, (char *)pac_data_blob.data, pac_data_blob.length);
|
||||
prs_set_offset(&ps, 0);
|
||||
|
||||
data_blob_free(&pac_data_blob);
|
||||
|
||||
pac_data = TALLOC_ZERO_P(ctx, PAC_DATA);
|
||||
pac_io_pac_data("pac data", pac_data, &ps, 0);
|
||||
my_pac = TALLOC_ZERO_P(mem_ctx, PAC_DATA);
|
||||
if (!pac_io_pac_data("pac data", my_pac, &ps, 0))
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
|
||||
prs_mem_free(&ps);
|
||||
|
||||
return pac_data;
|
||||
*pac_data = *my_pac;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* just for debugging, will be removed later - Guenther */
|
||||
char *pac_group_attr_string(uint32 attr)
|
||||
{
|
||||
fstring name = "";
|
||||
|
||||
if (!attr)
|
||||
return NULL;
|
||||
|
||||
if (attr & SE_GROUP_MANDATORY) fstrcat(name, "SE_GROUP_MANDATORY ");
|
||||
if (attr & SE_GROUP_ENABLED_BY_DEFAULT) fstrcat(name, "SE_GROUP_ENABLED_BY_DEFAULT ");
|
||||
if (attr & SE_GROUP_ENABLED) fstrcat(name, "SE_GROUP_ENABLED ");
|
||||
if (attr & SE_GROUP_OWNER) fstrcat(name, "SE_GROUP_OWNER ");
|
||||
if (attr & SE_GROUP_USE_FOR_DENY_ONLY) fstrcat(name, "SE_GROUP_USE_FOR_DENY_ONLY ");
|
||||
if (attr & SE_GROUP_LOGON_ID) fstrcat(name, "SE_GROUP_LOGON_ID ");
|
||||
if (attr & SE_GROUP_RESOURCE) fstrcat(name, "SE_GROUP_RESOURCE ");
|
||||
|
||||
return SMB_STRDUP(name);
|
||||
}
|
||||
|
||||
/* just for debugging, will be removed later - Guenther */
|
||||
static void dump_pac_logon_info(PAC_LOGON_INFO *logon_info) {
|
||||
|
||||
DOM_SID dom_sid, res_group_dom_sid;
|
||||
int i;
|
||||
char *attr_string;
|
||||
uint32 user_flgs = logon_info->info3.user_flgs;
|
||||
|
||||
if (logon_info->info3.ptr_res_group_dom_sid) {
|
||||
sid_copy(&res_group_dom_sid, &logon_info->res_group_dom_sid.sid);
|
||||
}
|
||||
sid_copy(&dom_sid, &logon_info->info3.dom_sid.sid);
|
||||
|
||||
DEBUG(10,("The PAC:\n"));
|
||||
|
||||
DEBUGADD(10,("\tUser Flags: 0x%x (%d)\n", user_flgs, user_flgs));
|
||||
if (user_flgs & LOGON_EXTRA_SIDS)
|
||||
DEBUGADD(10,("\tUser Flags: LOGON_EXTRA_SIDS 0x%x (%d)\n", LOGON_EXTRA_SIDS, LOGON_EXTRA_SIDS));
|
||||
if (user_flgs & LOGON_RESOURCE_GROUPS)
|
||||
DEBUGADD(10,("\tUser Flags: LOGON_RESOURCE_GROUPS 0x%x (%d)\n", LOGON_RESOURCE_GROUPS, LOGON_RESOURCE_GROUPS));
|
||||
DEBUGADD(10,("\tUser SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.user_rid));
|
||||
DEBUGADD(10,("\tGroup SID: %s-%d\n", sid_string_static(&dom_sid), logon_info->info3.group_rid));
|
||||
|
||||
DEBUGADD(10,("\tGroup Membership (Global and Universal Groups of own domain):\n"));
|
||||
for (i = 0; i < logon_info->info3.num_groups; i++) {
|
||||
attr_string = pac_group_attr_string(logon_info->info3.gids[i].attr);
|
||||
DEBUGADD(10,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n",
|
||||
i, sid_string_static(&dom_sid),
|
||||
logon_info->info3.gids[i].g_rid,
|
||||
logon_info->info3.gids[i].attr,
|
||||
attr_string));
|
||||
SAFE_FREE(attr_string);
|
||||
}
|
||||
|
||||
DEBUGADD(10,("\tGroup Membership (Domain Local Groups and Groups from Trusted Domains):\n"));
|
||||
for (i = 0; i < logon_info->info3.num_other_sids; i++) {
|
||||
attr_string = pac_group_attr_string(logon_info->info3.other_sids_attrib[i]);
|
||||
DEBUGADD(10,("\t\t%d: sid: %s\n\t\t attr: 0x%x == %s\n",
|
||||
i, sid_string_static(&logon_info->info3.other_sids[i].sid),
|
||||
logon_info->info3.other_sids_attrib[i],
|
||||
attr_string));
|
||||
SAFE_FREE(attr_string);
|
||||
}
|
||||
|
||||
DEBUGADD(10,("\tGroup Membership (Ressource Groups (SID History ?)):\n"));
|
||||
for (i = 0; i < logon_info->info3.res_group_count; i++) {
|
||||
attr_string = pac_group_attr_string(logon_info->res_groups.group_membership[i].attrs);
|
||||
DEBUGADD(10,("\t\t%d: sid: %s-%d\n\t\t attr: 0x%x == %s\n",
|
||||
i, sid_string_static(&res_group_dom_sid),
|
||||
logon_info->res_groups.group_membership[i].rid,
|
||||
logon_info->res_groups.group_membership[i].attrs,
|
||||
attr_string));
|
||||
SAFE_FREE(attr_string);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS decode_pac_data(TALLOC_CTX *mem_ctx,
|
||||
DATA_BLOB *pac_data_blob,
|
||||
krb5_context context,
|
||||
krb5_keyblock *service_keyblock,
|
||||
krb5_const_principal client_principal,
|
||||
time_t tgs_authtime,
|
||||
PAC_DATA **pac_data)
|
||||
|
||||
{
|
||||
DATA_BLOB modified_pac_blob;
|
||||
PAC_DATA *my_pac;
|
||||
NTSTATUS nt_status;
|
||||
krb5_error_code ret;
|
||||
PAC_SIGNATURE_DATA *srv_sig = NULL;
|
||||
PAC_SIGNATURE_DATA *kdc_sig = NULL;
|
||||
PAC_LOGON_NAME *logon_name = NULL;
|
||||
PAC_LOGON_INFO *logon_info = NULL;
|
||||
krb5_principal client_principal_pac;
|
||||
NTTIME tgs_authtime_nttime;
|
||||
int i, srv_sig_pos = 0, kdc_sig_pos = 0;
|
||||
fstring username;
|
||||
|
||||
*pac_data = NULL;
|
||||
|
||||
my_pac = talloc(mem_ctx, PAC_DATA);
|
||||
if (!my_pac) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
nt_status = parse_pac_data(mem_ctx, pac_data_blob, my_pac);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(0,("decode_pac_data: failed to parse PAC\n"));
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
modified_pac_blob = data_blob_talloc(mem_ctx, pac_data_blob->data, pac_data_blob->length);
|
||||
|
||||
if (my_pac->num_buffers < 4) {
|
||||
nt_status = NT_STATUS_INVALID_PARAMETER;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* store signatures */
|
||||
for (i=0; i < my_pac->num_buffers; i++) {
|
||||
|
||||
switch (my_pac->pac_buffer[i].type) {
|
||||
|
||||
case PAC_TYPE_SERVER_CHECKSUM:
|
||||
if (!my_pac->pac_buffer[i].ctr->pac.srv_cksum) {
|
||||
break;
|
||||
}
|
||||
|
||||
srv_sig = my_pac->pac_buffer[i].ctr->pac.srv_cksum;
|
||||
|
||||
/* get position of signature buffer */
|
||||
srv_sig_pos = my_pac->pac_buffer[i].offset;
|
||||
srv_sig_pos += sizeof(uint32);
|
||||
|
||||
break;
|
||||
|
||||
case PAC_TYPE_PRIVSVR_CHECKSUM:
|
||||
if (!my_pac->pac_buffer[i].ctr->pac.privsrv_cksum) {
|
||||
break;
|
||||
}
|
||||
|
||||
kdc_sig = my_pac->pac_buffer[i].ctr->pac.privsrv_cksum;
|
||||
|
||||
/* get position of signature buffer */
|
||||
kdc_sig_pos = my_pac->pac_buffer[i].offset;
|
||||
kdc_sig_pos += sizeof(uint32);
|
||||
|
||||
break;
|
||||
|
||||
case PAC_TYPE_LOGON_NAME:
|
||||
if (!my_pac->pac_buffer[i].ctr->pac.logon_name) {
|
||||
break;
|
||||
}
|
||||
|
||||
logon_name = my_pac->pac_buffer[i].ctr->pac.logon_name;
|
||||
break;
|
||||
|
||||
case PAC_TYPE_LOGON_INFO:
|
||||
if (!my_pac->pac_buffer[i].ctr->pac.logon_info) {
|
||||
break;
|
||||
}
|
||||
|
||||
logon_info = my_pac->pac_buffer[i].ctr->pac.logon_info;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!srv_sig || !kdc_sig || !logon_name || !logon_info) {
|
||||
nt_status = NT_STATUS_INVALID_PARAMETER;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* zero PAC_SIGNATURE_DATA signature buffer */
|
||||
memset(&modified_pac_blob.data[srv_sig_pos], '\0', srv_sig->signature.buf_len);
|
||||
memset(&modified_pac_blob.data[kdc_sig_pos], '\0', kdc_sig->signature.buf_len);
|
||||
|
||||
/* check server signature */
|
||||
nt_status = check_pac_checksum(mem_ctx, modified_pac_blob, srv_sig, context, service_keyblock);
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(0,("decode_pac_data: failed to verify PAC server signature\n"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Convert to NT time, so as not to loose accuracy in comparison */
|
||||
unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime);
|
||||
|
||||
if (!nt_time_equals(&tgs_authtime_nttime, &logon_name->logon_time)) {
|
||||
|
||||
DEBUG(2,("decode_pac_data: Logon time mismatch between ticket and PAC!\n"));
|
||||
DEBUGADD(2, ("decode_pac_data: PAC: %s\n",
|
||||
http_timestring(nt_time_to_unix(&logon_name->logon_time))));
|
||||
DEBUGADD(2, ("decode_pac_data: Ticket: %s\n",
|
||||
http_timestring(nt_time_to_unix(&tgs_authtime_nttime))));
|
||||
|
||||
nt_status = NT_STATUS_ACCESS_DENIED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!logon_name->len) {
|
||||
DEBUG(2,("decode_pac_data: No Logon Name available\n"));
|
||||
nt_status = NT_STATUS_INVALID_PARAMETER;
|
||||
goto out;
|
||||
}
|
||||
rpcstr_pull(username, logon_name->username, sizeof(username), -1, STR_TERMINATE);
|
||||
|
||||
ret = smb_krb5_parse_name_norealm(context, username, &client_principal_pac);
|
||||
if (ret) {
|
||||
DEBUG(2,("decode_pac_data: Could not parse name from incoming PAC: [%s]: %s\n",
|
||||
username, error_message(ret)));
|
||||
nt_status = NT_STATUS_INVALID_PARAMETER;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!smb_krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) {
|
||||
DEBUG(2,("decode_pac_data: Name in PAC [%s] does not match principal name in ticket\n",
|
||||
username));
|
||||
nt_status = NT_STATUS_ACCESS_DENIED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DEBUG(10,("Successfully validated Kerberos PAC\n"));
|
||||
|
||||
dump_pac_logon_info(logon_info);
|
||||
|
||||
*pac_data = my_pac;
|
||||
|
||||
nt_status = NT_STATUS_OK;
|
||||
|
||||
out:
|
||||
if (client_principal_pac) {
|
||||
krb5_free_principal(context, client_principal_pac);
|
||||
}
|
||||
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -4,8 +4,9 @@
|
||||
Copyright (C) Andrew Tridgell 2001
|
||||
Copyright (C) Remus Koos 2001
|
||||
Copyright (C) Luke Howard 2003
|
||||
Copyright (C) Guenther Deschner 2003
|
||||
Copyright (C) Guenther Deschner 2003, 2005
|
||||
Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003
|
||||
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-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
|
||||
@ -37,7 +38,8 @@ const krb5_data *krb5_princ_component(krb5_context, krb5_principal, int );
|
||||
***********************************************************************************/
|
||||
|
||||
static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context auth_context,
|
||||
const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt)
|
||||
const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt,
|
||||
krb5_keyblock **keyblock)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
BOOL auth_ok = False;
|
||||
@ -100,12 +102,18 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut
|
||||
p_packet->length = ticket->length;
|
||||
p_packet->data = (krb5_pointer)ticket->data;
|
||||
*pp_tkt = NULL;
|
||||
ret = krb5_rd_req(context, &auth_context, p_packet, kt_entry.principal, keytab, NULL, pp_tkt);
|
||||
|
||||
ret = krb5_rd_req_return_keyblock_from_keytab(context, &auth_context, p_packet,
|
||||
kt_entry.principal, keytab,
|
||||
NULL, pp_tkt, keyblock);
|
||||
|
||||
if (ret) {
|
||||
DEBUG(10, ("ads_keytab_verify_ticket: krb5_rd_req(%s) failed: %s\n",
|
||||
DEBUG(10,("ads_keytab_verify_ticket: "
|
||||
"krb5_rd_req_return_keyblock_from_keytab(%s) failed: %s\n",
|
||||
entry_princ_s, error_message(ret)));
|
||||
} else {
|
||||
DEBUG(3,("ads_keytab_verify_ticket: krb5_rd_req succeeded for principal %s\n",
|
||||
DEBUG(3,("ads_keytab_verify_ticket: "
|
||||
"krb5_rd_req_return_keyblock_from_keytab succeeded for principal %s\n",
|
||||
entry_princ_s));
|
||||
auth_ok = True;
|
||||
break;
|
||||
@ -173,7 +181,8 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut
|
||||
|
||||
static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context auth_context,
|
||||
krb5_principal host_princ,
|
||||
const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt)
|
||||
const DATA_BLOB *ticket, krb5_data *p_packet, krb5_ticket **pp_tkt,
|
||||
krb5_keyblock **keyblock)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
BOOL auth_ok = False;
|
||||
@ -182,6 +191,8 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au
|
||||
krb5_enctype *enctypes = NULL;
|
||||
int i;
|
||||
|
||||
ZERO_STRUCTP(keyblock);
|
||||
|
||||
if (!secrets_init()) {
|
||||
DEBUG(1,("ads_secrets_verify_ticket: secrets_init failed\n"));
|
||||
return False;
|
||||
@ -222,20 +233,23 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au
|
||||
|
||||
krb5_auth_con_setuseruserkey(context, auth_context, key);
|
||||
|
||||
krb5_free_keyblock(context, key);
|
||||
|
||||
if (!(ret = krb5_rd_req(context, &auth_context, p_packet,
|
||||
NULL,
|
||||
NULL, NULL, pp_tkt))) {
|
||||
DEBUG(10,("ads_secrets_verify_ticket: enc type [%u] decrypted message !\n",
|
||||
(unsigned int)enctypes[i] ));
|
||||
auth_ok = True;
|
||||
krb5_copy_keyblock(context, key, keyblock);
|
||||
krb5_free_keyblock(context, key);
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10,
|
||||
("ads_secrets_verify_ticket: enc type [%u] failed to decrypt with error %s\n",
|
||||
(unsigned int)enctypes[i], error_message(ret)));
|
||||
|
||||
krb5_free_keyblock(context, key);
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
@ -251,27 +265,33 @@ static BOOL ads_secrets_verify_ticket(krb5_context context, krb5_auth_context au
|
||||
authorization_data if available.
|
||||
***********************************************************************************/
|
||||
|
||||
NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
|
||||
char **principal, DATA_BLOB *auth_data,
|
||||
NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
|
||||
const char *realm, const DATA_BLOB *ticket,
|
||||
char **principal, PAC_DATA **pac_data,
|
||||
DATA_BLOB *ap_rep,
|
||||
DATA_BLOB *session_key)
|
||||
{
|
||||
NTSTATUS sret = NT_STATUS_LOGON_FAILURE;
|
||||
DATA_BLOB auth_data;
|
||||
krb5_context context = NULL;
|
||||
krb5_auth_context auth_context = NULL;
|
||||
krb5_data packet;
|
||||
krb5_ticket *tkt = NULL;
|
||||
krb5_rcache rcache = NULL;
|
||||
krb5_keyblock *keyblock = NULL;
|
||||
time_t authtime;
|
||||
int ret;
|
||||
|
||||
krb5_principal host_princ = NULL;
|
||||
krb5_const_principal client_principal = NULL;
|
||||
char *host_princ_s = NULL;
|
||||
BOOL got_replay_mutex = False;
|
||||
|
||||
BOOL auth_ok = False;
|
||||
BOOL got_auth_data = False;
|
||||
|
||||
ZERO_STRUCT(packet);
|
||||
ZERO_STRUCTP(auth_data);
|
||||
ZERO_STRUCT(auth_data);
|
||||
ZERO_STRUCTP(ap_rep);
|
||||
ZERO_STRUCTP(session_key);
|
||||
|
||||
@ -335,20 +355,30 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
|
||||
}
|
||||
|
||||
if (lp_use_kerberos_keytab()) {
|
||||
auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt);
|
||||
auth_ok = ads_keytab_verify_ticket(context, auth_context, ticket, &packet, &tkt, &keyblock);
|
||||
}
|
||||
if (!auth_ok) {
|
||||
auth_ok = ads_secrets_verify_ticket(context, auth_context, host_princ,
|
||||
ticket, &packet, &tkt);
|
||||
ticket, &packet, &tkt, &keyblock);
|
||||
}
|
||||
|
||||
release_server_mutex();
|
||||
got_replay_mutex = False;
|
||||
|
||||
#if 0
|
||||
/* Heimdal leaks here, if we fix the leak, MIT crashes */
|
||||
if (rcache) {
|
||||
krb5_rc_close(context, rcache);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!auth_ok) {
|
||||
DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n",
|
||||
error_message(ret)));
|
||||
goto out;
|
||||
} else {
|
||||
authtime = get_authtime_from_tkt(tkt);
|
||||
client_principal = get_principal_from_tkt(tkt);
|
||||
}
|
||||
|
||||
ret = krb5_mk_rep(context, auth_context, &packet);
|
||||
@ -369,20 +399,40 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
|
||||
file_save("/tmp/ticket.dat", ticket->data, ticket->length);
|
||||
#endif
|
||||
|
||||
get_auth_data_from_tkt(auth_data, tkt);
|
||||
/* continue when no PAC is retrieved
|
||||
(like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set) */
|
||||
|
||||
{
|
||||
TALLOC_CTX *ctx = talloc_init("pac data");
|
||||
decode_pac_data(auth_data, ctx);
|
||||
talloc_destroy(ctx);
|
||||
got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt);
|
||||
if (!got_auth_data) {
|
||||
DEBUG(3,("ads_verify_ticket: did not retrieve auth data. continuing without PAC\n"));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
data_blob_free(&auth_data);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if defined(HAVE_KRB5_TKT_ENC_PART2)
|
||||
/* MIT */
|
||||
if (tkt->enc_part2) {
|
||||
file_save("/tmp/authdata.dat",
|
||||
tkt->enc_part2->authorization_data[0]->contents,
|
||||
tkt->enc_part2->authorization_data[0]->length);
|
||||
}
|
||||
#else
|
||||
/* Heimdal */
|
||||
if (tkt->ticket.authorization_data) {
|
||||
file_save("/tmp/authdata.dat",
|
||||
tkt->ticket.authorization_data->val->ad_data.data,
|
||||
tkt->ticket.authorization_data->val->ad_data.length);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt),
|
||||
@ -402,7 +452,7 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(sret)) {
|
||||
data_blob_free(auth_data);
|
||||
data_blob_free(&auth_data);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(sret)) {
|
||||
@ -413,6 +463,10 @@ NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
|
||||
krb5_free_principal(context, host_princ);
|
||||
}
|
||||
|
||||
if (keyblock) {
|
||||
krb5_free_keyblock(context, keyblock);
|
||||
}
|
||||
|
||||
if (tkt != NULL) {
|
||||
krb5_free_ticket(context, tkt);
|
||||
}
|
||||
|
@ -2104,7 +2104,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads,
|
||||
if ((*num_strings) != range_start) {
|
||||
DEBUG(1, ("ads_pull_strings_range: Range attribute (%s) doesn't start at %u, but at %lu"
|
||||
" - aborting range retreival\n",
|
||||
range_attr, *num_strings + 1, range_start));
|
||||
range_attr, (unsigned int)(*num_strings) + 1, range_start));
|
||||
ldap_memfree(range_attr);
|
||||
*more_strings = False;
|
||||
return NULL;
|
||||
@ -2140,7 +2140,7 @@ char **ads_pull_strings_range(ADS_STRUCT *ads,
|
||||
*next_attribute = talloc_asprintf(mem_ctx,
|
||||
"%s;range=%d-*",
|
||||
field,
|
||||
*num_strings);
|
||||
(int)*num_strings);
|
||||
|
||||
if (!*next_attribute) {
|
||||
DEBUG(1, ("talloc_asprintf for next attribute failed!\n"));
|
||||
|
@ -258,7 +258,7 @@ static void map_regval_to_ads(TALLOC_CTX *ctx, ADS_MODLIST *mods,
|
||||
}
|
||||
|
||||
|
||||
WERROR get_remote_printer_publishing_data(struct cli_state *cli,
|
||||
WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
ADS_MODLIST *mods,
|
||||
const char *printer)
|
||||
@ -269,16 +269,16 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
|
||||
uint32 i;
|
||||
POLICY_HND pol;
|
||||
|
||||
asprintf(&servername, "\\\\%s", cli->desthost);
|
||||
asprintf(&servername, "\\\\%s", cli->cli->desthost);
|
||||
asprintf(&printername, "%s\\%s", servername, printer);
|
||||
if (!servername || !printername) {
|
||||
DEBUG(3, ("Insufficient memory\n"));
|
||||
return WERR_NOMEM;
|
||||
}
|
||||
|
||||
result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername,
|
||||
result = rpccli_spoolss_open_printer_ex(cli, mem_ctx, printername,
|
||||
"", MAXIMUM_ALLOWED_ACCESS,
|
||||
servername, cli->user_name, &pol);
|
||||
servername, cli->cli->user_name, &pol);
|
||||
if (!W_ERROR_IS_OK(result)) {
|
||||
DEBUG(3, ("Unable to open printer %s, error is %s.\n",
|
||||
printername, dos_errstr(result)));
|
||||
@ -288,7 +288,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
|
||||
if ( !(dsdriver_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
|
||||
return WERR_NOMEM;
|
||||
|
||||
result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
|
||||
result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSDRIVER_KEY, dsdriver_ctr);
|
||||
|
||||
if (!W_ERROR_IS_OK(result)) {
|
||||
DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
|
||||
@ -305,7 +305,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
|
||||
if ( !(dsspooler_ctr = TALLOC_ZERO_P( mem_ctx, REGVAL_CTR )) )
|
||||
return WERR_NOMEM;
|
||||
|
||||
result = cli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
|
||||
result = rpccli_spoolss_enumprinterdataex(cli, mem_ctx, &pol, SPOOL_DSSPOOLER_KEY, dsspooler_ctr);
|
||||
|
||||
if (!W_ERROR_IS_OK(result)) {
|
||||
DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n",
|
||||
@ -323,7 +323,7 @@ WERROR get_remote_printer_publishing_data(struct cli_state *cli,
|
||||
TALLOC_FREE( dsdriver_ctr );
|
||||
TALLOC_FREE( dsspooler_ctr );
|
||||
|
||||
cli_spoolss_close_printer(cli, mem_ctx, &pol);
|
||||
rpccli_spoolss_close_printer(cli, mem_ctx, &pol);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip
|
||||
DATA_BLOB session_key = data_blob(NULL, 0);
|
||||
int rc;
|
||||
|
||||
rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key);
|
||||
rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0);
|
||||
|
||||
if (rc) {
|
||||
return ADS_ERROR_KRB5(rc);
|
||||
|
@ -532,7 +532,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *
|
||||
DEBUG(2,("Doing kerberos session setup\n"));
|
||||
|
||||
/* generate the encapsulated kerberos5 ticket */
|
||||
rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5);
|
||||
rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0);
|
||||
|
||||
if (rc) {
|
||||
DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc)));
|
||||
@ -600,7 +600,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
|
||||
nt_status = ntlmssp_update(ntlmssp_state,
|
||||
blob_in, &blob_out);
|
||||
data_blob_free(&blob_in);
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
|
||||
if (turn == 1) {
|
||||
/* and wrap it in a SPNEGO wrapper */
|
||||
msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
|
||||
@ -1337,25 +1337,6 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Initialise client credentials for authenticated pipe access.
|
||||
****************************************************************************/
|
||||
|
||||
void init_creds(struct ntuser_creds *creds, const char* username,
|
||||
const char* domain, const char* password)
|
||||
{
|
||||
ZERO_STRUCTP(creds);
|
||||
|
||||
pwd_set_cleartext(&creds->pwd, password);
|
||||
|
||||
fstrcpy(creds->user_name, username);
|
||||
fstrcpy(creds->domain, domain);
|
||||
|
||||
if (!*username) {
|
||||
creds->pwd.null_pwd = True;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
establishes a connection to after the negprot.
|
||||
@param output_cli A fully initialised cli structure, non-null only on success
|
||||
@ -1474,7 +1455,6 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
|
||||
int signing_state,
|
||||
BOOL *retry)
|
||||
{
|
||||
struct ntuser_creds creds;
|
||||
NTSTATUS nt_status;
|
||||
struct cli_state *cli = NULL;
|
||||
|
||||
@ -1513,8 +1493,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
|
||||
}
|
||||
}
|
||||
|
||||
init_creds(&creds, user, domain, password);
|
||||
cli_init_creds(cli, &creds);
|
||||
cli_init_creds(cli, user, domain, password);
|
||||
|
||||
*output_cli = cli;
|
||||
return NT_STATUS_OK;
|
||||
|
@ -101,7 +101,7 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot,
|
||||
DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name),
|
||||
inet_ntoa(dest_ip)));
|
||||
|
||||
return message_send_pid(nmbd_pid, MSG_SEND_PACKET, &p, sizeof(p),
|
||||
return message_send_pid(pid_to_procid(nmbd_pid), MSG_SEND_PACKET, &p, sizeof(p),
|
||||
False);
|
||||
}
|
||||
|
||||
|
@ -221,15 +221,16 @@ void cli_setup_bcc(struct cli_state *cli, void *p)
|
||||
Initialise credentials of a client structure.
|
||||
****************************************************************************/
|
||||
|
||||
void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr)
|
||||
void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password)
|
||||
{
|
||||
/* copy_nt_creds(&cli->usr, usr); */
|
||||
fstrcpy(cli->domain , usr->domain);
|
||||
fstrcpy(cli->user_name, usr->user_name);
|
||||
memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd));
|
||||
fstrcpy(cli->domain, domain);
|
||||
fstrcpy(cli->user_name, username);
|
||||
pwd_set_cleartext(&cli->pwd, password);
|
||||
if (!*username) {
|
||||
cli->pwd.null_pwd = True;
|
||||
}
|
||||
|
||||
DEBUG(10,("cli_init_creds: user %s domain %s\n",
|
||||
cli->user_name, cli->domain));
|
||||
DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -260,7 +261,6 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state)
|
||||
struct cli_state *cli_initialise(struct cli_state *cli)
|
||||
{
|
||||
BOOL alloced_cli = False;
|
||||
int i;
|
||||
|
||||
/* Check the effective uid - make sure we are not setuid */
|
||||
if (is_setuid_root()) {
|
||||
@ -332,16 +332,9 @@ struct cli_state *cli_initialise(struct cli_state *cli)
|
||||
/* initialise signing */
|
||||
cli_null_set_signing(cli);
|
||||
|
||||
for (i=0; i<PI_MAX_PIPES; i++)
|
||||
cli->pipes[i].fnum = 0;
|
||||
|
||||
cli->netlogon_pipe.fnum = 0;
|
||||
|
||||
cli->initialised = 1;
|
||||
cli->allocated = alloced_cli;
|
||||
|
||||
cli->pipe_idx = -1;
|
||||
|
||||
return cli;
|
||||
|
||||
/* Clean up after malloc() error */
|
||||
@ -358,34 +351,42 @@ struct cli_state *cli_initialise(struct cli_state *cli)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
close the session
|
||||
External interface.
|
||||
Close an open named pipe over SMB. Free any authentication data.
|
||||
****************************************************************************/
|
||||
|
||||
void cli_nt_session_close(struct cli_state *cli)
|
||||
void cli_rpc_pipe_close(struct rpc_pipe_client *cli)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<PI_MAX_PIPES; i++) {
|
||||
if (cli->pipes[i].pipe_auth_flags & AUTH_PIPE_NTLMSSP) {
|
||||
ntlmssp_end(&cli->pipes[i].ntlmssp_pipe_state);
|
||||
if (!cli_close(cli->cli, cli->fnum)) {
|
||||
DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s "
|
||||
"to machine %s. Error was %s\n",
|
||||
cli->pipe_name,
|
||||
cli->cli->desthost,
|
||||
cli_errstr(cli->cli)));
|
||||
}
|
||||
|
||||
if (cli->pipes[i].fnum != 0)
|
||||
cli_close(cli, cli->pipes[i].fnum);
|
||||
cli->pipes[i].fnum = 0;
|
||||
if (cli->auth.cli_auth_data_free_func) {
|
||||
(*cli->auth.cli_auth_data_free_func)(&cli->auth);
|
||||
}
|
||||
cli->pipe_idx = -1;
|
||||
|
||||
DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n",
|
||||
cli->pipe_name, cli->cli->desthost ));
|
||||
|
||||
DLIST_REMOVE(cli->cli->pipe_list, cli);
|
||||
talloc_destroy(cli->mem_ctx);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
close the NETLOGON session holding the session key for NETSEC
|
||||
Close all pipes open on this session.
|
||||
****************************************************************************/
|
||||
|
||||
void cli_nt_netlogon_netsec_session_close(struct cli_state *cli)
|
||||
void cli_nt_pipes_close(struct cli_state *cli)
|
||||
{
|
||||
if (cli->netlogon_pipe.fnum != 0) {
|
||||
cli_close(cli, cli->netlogon_pipe.fnum);
|
||||
cli->netlogon_pipe.fnum = 0;
|
||||
struct rpc_pipe_client *cp, *next;
|
||||
|
||||
for (cp = cli->pipe_list; cp; cp = next) {
|
||||
next = cp->next;
|
||||
cli_rpc_pipe_close(cp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,8 +396,7 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli)
|
||||
|
||||
void cli_close_connection(struct cli_state *cli)
|
||||
{
|
||||
cli_nt_session_close(cli);
|
||||
cli_nt_netlogon_netsec_session_close(cli);
|
||||
cli_nt_pipes_close(cli);
|
||||
|
||||
/*
|
||||
* tell our peer to free his resources. Wihtout this, when an
|
||||
@ -410,8 +410,9 @@ void cli_close_connection(struct cli_state *cli)
|
||||
* the only user for this so far is smbmount which passes opened connection
|
||||
* down to kernel's smbfs module.
|
||||
*/
|
||||
if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) )
|
||||
if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) {
|
||||
cli_tdis(cli);
|
||||
}
|
||||
|
||||
SAFE_FREE(cli->outbuf);
|
||||
SAFE_FREE(cli->inbuf);
|
||||
@ -420,19 +421,16 @@ void cli_close_connection(struct cli_state *cli)
|
||||
data_blob_free(&cli->secblob);
|
||||
data_blob_free(&cli->user_session_key);
|
||||
|
||||
if (cli->pipes[cli->pipe_idx].pipe_auth_flags & AUTH_PIPE_NTLMSSP)
|
||||
ntlmssp_end(&cli->pipes[cli->pipe_idx].ntlmssp_pipe_state);
|
||||
|
||||
if (cli->mem_ctx) {
|
||||
talloc_destroy(cli->mem_ctx);
|
||||
cli->mem_ctx = NULL;
|
||||
}
|
||||
|
||||
if (cli->fd != -1)
|
||||
if (cli->fd != -1) {
|
||||
close(cli->fd);
|
||||
}
|
||||
cli->fd = -1;
|
||||
cli->smb_rw_error = 0;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -444,9 +442,10 @@ void cli_shutdown(struct cli_state *cli)
|
||||
BOOL allocated = cli->allocated;
|
||||
cli_close_connection(cli);
|
||||
ZERO_STRUCTP(cli);
|
||||
if (allocated)
|
||||
if (allocated) {
|
||||
free(cli);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Set socket options on a open connection.
|
||||
|
@ -404,3 +404,20 @@ BOOL cli_is_dos_error(struct cli_state *cli)
|
||||
|
||||
return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES);
|
||||
}
|
||||
|
||||
/* Return the last error always as an NTSTATUS. */
|
||||
|
||||
NTSTATUS cli_get_nt_error(struct cli_state *cli)
|
||||
{
|
||||
if (cli_is_nt_error(cli)) {
|
||||
return cli_nt_error(cli);
|
||||
} else if (cli_is_dos_error(cli)) {
|
||||
uint32 ecode;
|
||||
uint8 eclass;
|
||||
cli_dos_error(cli, &eclass, &ecode);
|
||||
return dos_to_ntstatus(eclass, ecode);
|
||||
} else {
|
||||
/* Something went wrong, we don't know what. */
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
simple kerberos5 routines for active directory
|
||||
Copyright (C) Andrew Tridgell 2001
|
||||
Copyright (C) Luke Howard 2002-2003
|
||||
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
|
||||
Copyright (C) Guenther Deschner 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
|
||||
@ -186,17 +188,107 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt)
|
||||
BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data)
|
||||
{
|
||||
DATA_BLOB pac_contents;
|
||||
ASN1_DATA data;
|
||||
int data_type;
|
||||
|
||||
if (!auth_data->length) {
|
||||
return False;
|
||||
}
|
||||
|
||||
asn1_load(&data, *auth_data);
|
||||
asn1_start_tag(&data, ASN1_SEQUENCE(0));
|
||||
asn1_start_tag(&data, ASN1_SEQUENCE(0));
|
||||
asn1_start_tag(&data, ASN1_CONTEXT(0));
|
||||
asn1_read_Integer(&data, &data_type);
|
||||
|
||||
if (data_type != KRB5_AUTHDATA_WIN2K_PAC ) {
|
||||
DEBUG(10,("authorization data is not a Windows PAC (type: %d)\n", data_type));
|
||||
asn1_free(&data);
|
||||
return False;
|
||||
}
|
||||
|
||||
asn1_end_tag(&data);
|
||||
asn1_start_tag(&data, ASN1_CONTEXT(1));
|
||||
asn1_read_OctetString(&data, &pac_contents);
|
||||
asn1_end_tag(&data);
|
||||
asn1_end_tag(&data);
|
||||
asn1_end_tag(&data);
|
||||
asn1_free(&data);
|
||||
|
||||
*unwrapped_pac_data = data_blob_talloc(mem_ctx, pac_contents.data, pac_contents.length);
|
||||
|
||||
data_blob_free(&pac_contents);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt)
|
||||
{
|
||||
DATA_BLOB auth_data_wrapped;
|
||||
BOOL got_auth_data_pac = False;
|
||||
int i;
|
||||
|
||||
#if defined(HAVE_KRB5_TKT_ENC_PART2)
|
||||
if (tkt->enc_part2 && tkt->enc_part2->authorization_data && tkt->enc_part2->authorization_data[0] && tkt->enc_part2->authorization_data[0]->length)
|
||||
*auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents,
|
||||
tkt->enc_part2->authorization_data[0]->length);
|
||||
if (tkt->enc_part2 && tkt->enc_part2->authorization_data &&
|
||||
tkt->enc_part2->authorization_data[0] &&
|
||||
tkt->enc_part2->authorization_data[0]->length)
|
||||
{
|
||||
for (i = 0; tkt->enc_part2->authorization_data[i] != NULL; i++) {
|
||||
|
||||
if (tkt->enc_part2->authorization_data[i]->ad_type !=
|
||||
KRB5_AUTHDATA_IF_RELEVANT) {
|
||||
DEBUG(10,("get_auth_data_from_tkt: ad_type is %d\n",
|
||||
tkt->enc_part2->authorization_data[i]->ad_type));
|
||||
continue;
|
||||
}
|
||||
|
||||
auth_data_wrapped = data_blob(tkt->enc_part2->authorization_data[i]->contents,
|
||||
tkt->enc_part2->authorization_data[i]->length);
|
||||
|
||||
/* check if it is a PAC */
|
||||
got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data);
|
||||
data_blob_free(&auth_data_wrapped);
|
||||
|
||||
if (!got_auth_data_pac) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return got_auth_data_pac;
|
||||
}
|
||||
|
||||
#else
|
||||
if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len)
|
||||
*auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data,
|
||||
tkt->ticket.authorization_data->val->ad_data.length);
|
||||
if (tkt->ticket.authorization_data &&
|
||||
tkt->ticket.authorization_data->len)
|
||||
{
|
||||
for (i = 0; i < tkt->ticket.authorization_data->len; i++) {
|
||||
|
||||
if (tkt->ticket.authorization_data->val[i].ad_type !=
|
||||
KRB5_AUTHDATA_IF_RELEVANT) {
|
||||
DEBUG(10,("get_auth_data_from_tkt: ad_type is %d\n",
|
||||
tkt->ticket.authorization_data->val[i].ad_type));
|
||||
continue;
|
||||
}
|
||||
|
||||
auth_data_wrapped = data_blob(tkt->ticket.authorization_data->val[i].ad_data.data,
|
||||
tkt->ticket.authorization_data->val[i].ad_data.length);
|
||||
|
||||
/* check if it is a PAC */
|
||||
got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data);
|
||||
data_blob_free(&auth_data_wrapped);
|
||||
|
||||
if (!got_auth_data_pac) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return got_auth_data_pac;
|
||||
}
|
||||
#endif
|
||||
return False;
|
||||
}
|
||||
|
||||
krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt)
|
||||
@ -435,7 +527,7 @@ cleanup_princ:
|
||||
get a kerberos5 ticket for the given service
|
||||
*/
|
||||
int cli_krb5_get_ticket(const char *principal, time_t time_offset,
|
||||
DATA_BLOB *ticket, DATA_BLOB *session_key_krb5)
|
||||
DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts)
|
||||
{
|
||||
krb5_error_code retval;
|
||||
krb5_data packet;
|
||||
@ -475,7 +567,7 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset,
|
||||
|
||||
if ((retval = ads_krb5_mk_req(context,
|
||||
&auth_context,
|
||||
AP_OPTS_USE_SUBKEY,
|
||||
AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts,
|
||||
principal,
|
||||
ccdef, &packet))) {
|
||||
goto failed;
|
||||
@ -550,10 +642,349 @@ failed:
|
||||
#endif
|
||||
}
|
||||
|
||||
void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum,
|
||||
PAC_SIGNATURE_DATA *sig)
|
||||
{
|
||||
#ifdef HAVE_CHECKSUM_IN_KRB5_CHECKSUM
|
||||
cksum->cksumtype = (krb5_cksumtype)sig->type;
|
||||
cksum->checksum.length = sig->signature.buf_len;
|
||||
cksum->checksum.data = sig->signature.buffer;
|
||||
#else
|
||||
cksum->checksum_type = (krb5_cksumtype)sig->type;
|
||||
cksum->length = sig->signature.buf_len;
|
||||
cksum->contents = sig->signature.buffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
krb5_error_code smb_krb5_verify_checksum(krb5_context context,
|
||||
krb5_keyblock *keyblock,
|
||||
krb5_keyusage usage,
|
||||
krb5_checksum *cksum,
|
||||
uint8 *data,
|
||||
size_t length)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
|
||||
/* verify the checksum */
|
||||
|
||||
/* welcome to the wonderful world of samba's kerberos abstraction layer:
|
||||
*
|
||||
* function heimdal 0.6.1rc3 heimdal 0.7 MIT krb 1.4.2
|
||||
* -----------------------------------------------------------------------------
|
||||
* krb5_c_verify_checksum - works works
|
||||
* krb5_verify_checksum works (6 args) works (6 args) broken (7 args)
|
||||
*/
|
||||
|
||||
#if defined(HAVE_KRB5_C_VERIFY_CHECKSUM)
|
||||
{
|
||||
krb5_boolean checksum_valid = False;
|
||||
krb5_data input;
|
||||
|
||||
input.data = (char *)data;
|
||||
input.length = length;
|
||||
|
||||
ret = krb5_c_verify_checksum(context,
|
||||
keyblock,
|
||||
usage,
|
||||
&input,
|
||||
cksum,
|
||||
&checksum_valid);
|
||||
if (!checksum_valid)
|
||||
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
|
||||
}
|
||||
|
||||
#elif KRB5_VERIFY_CHECKSUM_ARGS == 6 && defined(HAVE_KRB5_CRYPTO_INIT) && defined(HAVE_KRB5_CRYPTO) && defined(HAVE_KRB5_CRYPTO_DESTROY)
|
||||
|
||||
/* Warning: MIT's krb5_verify_checksum cannot be used as it will use a key
|
||||
* without enctype and it ignores any key_usage types - Guenther */
|
||||
|
||||
{
|
||||
|
||||
krb5_crypto crypto;
|
||||
ret = krb5_crypto_init(context,
|
||||
keyblock,
|
||||
0,
|
||||
&crypto);
|
||||
if (ret) {
|
||||
DEBUG(0,("smb_krb5_verify_checksum: krb5_crypto_init() failed: %s\n",
|
||||
error_message(ret)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = krb5_verify_checksum(context,
|
||||
crypto,
|
||||
usage,
|
||||
data,
|
||||
length,
|
||||
cksum);
|
||||
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
}
|
||||
|
||||
#else
|
||||
#error UNKNOWN_KRB5_VERIFY_CHECKSUM_FUNCTION
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_t get_authtime_from_tkt(krb5_ticket *tkt)
|
||||
{
|
||||
#if defined(HAVE_KRB5_TKT_ENC_PART2)
|
||||
return tkt->enc_part2->times.authtime;
|
||||
#else
|
||||
return tkt->ticket.authtime;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int get_kvno_from_ap_req(krb5_ap_req *ap_req)
|
||||
{
|
||||
#ifdef HAVE_TICKET_POINTER_IN_KRB5_AP_REQ /* MIT */
|
||||
if (ap_req->ticket->enc_part.kvno)
|
||||
return ap_req->ticket->enc_part.kvno;
|
||||
#else /* Heimdal */
|
||||
if (ap_req->ticket.enc_part.kvno)
|
||||
return *ap_req->ticket.enc_part.kvno;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_enctype get_enctype_from_ap_req(krb5_ap_req *ap_req)
|
||||
{
|
||||
#ifdef HAVE_ETYPE_IN_ENCRYPTEDDATA /* Heimdal */
|
||||
return ap_req->ticket.enc_part.etype;
|
||||
#else /* MIT */
|
||||
return ap_req->ticket->enc_part.enctype;
|
||||
#endif
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
get_key_from_keytab(krb5_context context,
|
||||
krb5_keytab keytab,
|
||||
krb5_const_principal server,
|
||||
krb5_enctype enctype,
|
||||
krb5_kvno kvno,
|
||||
krb5_keyblock **out_key)
|
||||
{
|
||||
krb5_keytab_entry entry;
|
||||
krb5_error_code ret;
|
||||
krb5_keytab real_keytab;
|
||||
char *name = NULL;
|
||||
|
||||
if (keytab == NULL) {
|
||||
krb5_kt_default(context, &real_keytab);
|
||||
} else {
|
||||
real_keytab = keytab;
|
||||
}
|
||||
|
||||
if ( DEBUGLEVEL >= 10 ) {
|
||||
krb5_unparse_name(context, server, &name);
|
||||
DEBUG(10,("get_key_from_keytab: will look for kvno %d, enctype %d and name: %s\n",
|
||||
kvno, enctype, name));
|
||||
krb5_free_unparsed_name(context, name);
|
||||
}
|
||||
|
||||
ret = krb5_kt_get_entry(context,
|
||||
real_keytab,
|
||||
server,
|
||||
kvno,
|
||||
enctype,
|
||||
&entry);
|
||||
|
||||
if (ret) {
|
||||
DEBUG(0,("get_key_from_keytab: failed to retrieve key: %s\n", error_message(ret)));
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */
|
||||
ret = krb5_copy_keyblock(context, &entry.keyblock, out_key);
|
||||
#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) /* MIT */
|
||||
ret = krb5_copy_keyblock(context, &entry.key, out_key);
|
||||
#else
|
||||
#error UNKNOWN_KRB5_KEYTAB_ENTRY_FORMAT
|
||||
#endif
|
||||
|
||||
if (ret) {
|
||||
DEBUG(0,("get_key_from_keytab: failed to copy key: %s\n", error_message(ret)));
|
||||
goto out;
|
||||
}
|
||||
|
||||
smb_krb5_kt_free_entry(context, &entry);
|
||||
|
||||
out:
|
||||
if (keytab == NULL) {
|
||||
krb5_kt_close(context, real_keytab);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void smb_krb5_free_ap_req(krb5_context context,
|
||||
krb5_ap_req *ap_req)
|
||||
{
|
||||
#ifdef HAVE_KRB5_FREE_AP_REQ /* MIT */
|
||||
krb5_free_ap_req(context, ap_req);
|
||||
#elif defined(HAVE_FREE_AP_REQ) /* Heimdal */
|
||||
free_AP_REQ(ap_req);
|
||||
#else
|
||||
#error UNKNOWN_KRB5_AP_REQ_FREE_FUNCTION
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Prototypes */
|
||||
#if defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */
|
||||
krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep);
|
||||
#endif
|
||||
|
||||
krb5_error_code smb_krb5_get_keyinfo_from_ap_req(krb5_context context,
|
||||
const krb5_data *inbuf,
|
||||
krb5_kvno *kvno,
|
||||
krb5_enctype *enctype)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
#ifdef HAVE_KRB5_DECODE_AP_REQ /* Heimdal */
|
||||
{
|
||||
krb5_ap_req ap_req;
|
||||
|
||||
ret = krb5_decode_ap_req(context, inbuf, &ap_req);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*kvno = get_kvno_from_ap_req(&ap_req);
|
||||
*enctype = get_enctype_from_ap_req(&ap_req);
|
||||
|
||||
smb_krb5_free_ap_req(context, &ap_req);
|
||||
}
|
||||
#elif defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */
|
||||
{
|
||||
krb5_ap_req *ap_req = NULL;
|
||||
|
||||
ret = decode_krb5_ap_req(inbuf, &ap_req);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*kvno = get_kvno_from_ap_req(ap_req);
|
||||
*enctype = get_enctype_from_ap_req(ap_req);
|
||||
|
||||
smb_krb5_free_ap_req(context, ap_req);
|
||||
}
|
||||
#else
|
||||
#error UNKOWN_KRB5_AP_REQ_DECODING_FUNCTION
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_error_code krb5_rd_req_return_keyblock_from_keytab(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
const krb5_data *inbuf,
|
||||
krb5_const_principal server,
|
||||
krb5_keytab keytab,
|
||||
krb5_flags *ap_req_options,
|
||||
krb5_ticket **ticket,
|
||||
krb5_keyblock **keyblock)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_ap_req *ap_req = NULL;
|
||||
krb5_kvno kvno;
|
||||
krb5_enctype enctype;
|
||||
krb5_keyblock *local_keyblock;
|
||||
|
||||
ret = krb5_rd_req(context,
|
||||
auth_context,
|
||||
inbuf,
|
||||
server,
|
||||
keytab,
|
||||
ap_req_options,
|
||||
ticket);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = smb_krb5_get_keyinfo_from_ap_req(context, inbuf, &kvno, &enctype);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = get_key_from_keytab(context,
|
||||
keytab,
|
||||
server,
|
||||
enctype,
|
||||
kvno,
|
||||
&local_keyblock);
|
||||
if (ret) {
|
||||
DEBUG(0,("krb5_rd_req_return_keyblock_from_keytab: failed to call get_key_from_keytab\n"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (ap_req) {
|
||||
smb_krb5_free_ap_req(context, ap_req);
|
||||
}
|
||||
|
||||
if (ret && local_keyblock != NULL) {
|
||||
krb5_free_keyblock(context, local_keyblock);
|
||||
} else {
|
||||
*keyblock = local_keyblock;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_error_code smb_krb5_parse_name_norealm(krb5_context context,
|
||||
const char *name,
|
||||
krb5_principal *principal)
|
||||
{
|
||||
#ifdef HAVE_KRB5_PARSE_NAME_NOREALM
|
||||
return krb5_parse_name_norealm(context, name, principal);
|
||||
#endif
|
||||
|
||||
/* we are cheating here because parse_name will in fact set the realm.
|
||||
* We don't care as the only caller of smb_krb5_parse_name_norealm
|
||||
* ignores the realm anyway when calling
|
||||
* smb_krb5_principal_compare_any_realm later - Guenther */
|
||||
|
||||
return krb5_parse_name(context, name, principal);
|
||||
}
|
||||
|
||||
BOOL smb_krb5_principal_compare_any_realm(krb5_context context,
|
||||
krb5_const_principal princ1,
|
||||
krb5_const_principal princ2)
|
||||
{
|
||||
#ifdef HAVE_KRB5_PRINCIPAL_COMPARE_ANY_REALM
|
||||
|
||||
return krb5_principal_compare_any_realm(context, princ1, princ2);
|
||||
|
||||
/* krb5_princ_size is a macro in MIT */
|
||||
#elif defined(HAVE_KRB5_PRINC_SIZE) || defined(krb5_princ_size)
|
||||
|
||||
int i, len1, len2;
|
||||
const krb5_data *p1, *p2;
|
||||
|
||||
len1 = krb5_princ_size(context, princ1);
|
||||
len2 = krb5_princ_size(context, princ2);
|
||||
|
||||
if (len1 != len2)
|
||||
return False;
|
||||
|
||||
for (i = 0; i < len1; i++) {
|
||||
|
||||
p1 = krb5_princ_component(context, CONST_DISCARD(krb5_principal, princ1), i);
|
||||
p2 = krb5_princ_component(context, CONST_DISCARD(krb5_principal, princ2), i);
|
||||
|
||||
if (p1->length != p2->length || memcmp(p1->data, p2->data, p1->length))
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
#else
|
||||
#error NO_SUITABLE_PRINCIPAL_COMPARE_FUNCTION
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* HAVE_KRB5 */
|
||||
/* this saves a few linking headaches */
|
||||
int cli_krb5_get_ticket(const char *principal, time_t time_offset,
|
||||
DATA_BLOB *ticket, DATA_BLOB *session_key_krb5)
|
||||
DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts)
|
||||
{
|
||||
DEBUG(0,("NO KERBEROS SUPPORT\n"));
|
||||
return 1;
|
||||
|
@ -323,13 +323,13 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset,
|
||||
0x0008 start of message mode named pipe protocol
|
||||
****************************************************************************/
|
||||
|
||||
size_t cli_write(struct cli_state *cli,
|
||||
ssize_t cli_write(struct cli_state *cli,
|
||||
int fnum, uint16 write_mode,
|
||||
const char *buf, off_t offset, size_t size)
|
||||
{
|
||||
int bwritten = 0;
|
||||
int issued = 0;
|
||||
int received = 0;
|
||||
ssize_t bwritten = 0;
|
||||
unsigned int issued = 0;
|
||||
unsigned int received = 0;
|
||||
int mpx = 1;
|
||||
int block = cli->max_xmit - (smb_size+32);
|
||||
int blocks = (size + (block-1)) / block;
|
||||
@ -343,8 +343,8 @@ size_t cli_write(struct cli_state *cli,
|
||||
while (received < blocks) {
|
||||
|
||||
while ((issued - received < mpx) && (issued < blocks)) {
|
||||
int bsent = issued * block;
|
||||
int size1 = MIN(block, size - bsent);
|
||||
ssize_t bsent = issued * block;
|
||||
ssize_t size1 = MIN(block, size - bsent);
|
||||
|
||||
if (!cli_issue_write(cli, fnum, offset + bsent,
|
||||
write_mode,
|
||||
|
@ -325,14 +325,15 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
|
||||
*/
|
||||
int spnego_gen_negTokenTarg(const char *principal, int time_offset,
|
||||
DATA_BLOB *targ,
|
||||
DATA_BLOB *session_key_krb5)
|
||||
DATA_BLOB *session_key_krb5, uint32 extra_ap_opts)
|
||||
{
|
||||
int retval;
|
||||
DATA_BLOB tkt, tkt_wrapped;
|
||||
const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL};
|
||||
|
||||
/* get a kerberos ticket for the service and extract the session key */
|
||||
retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5);
|
||||
retval = cli_krb5_get_ticket(principal, time_offset,
|
||||
&tkt, session_key_krb5, extra_ap_opts);
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
@ -464,7 +464,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
receive a SMB nttrans response allocating the necessary memory
|
||||
Receive a SMB nttrans response allocating the necessary memory.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL cli_receive_nt_trans(struct cli_state *cli,
|
||||
@ -503,7 +503,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
|
||||
*/
|
||||
if (cli_is_dos_error(cli)) {
|
||||
cli_dos_error(cli, &eclass, &ecode);
|
||||
if (cli->pipes[cli->pipe_idx].fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
|
||||
if (!(eclass == ERRDOS && ecode == ERRmoredata)) {
|
||||
cli_signing_trans_stop(cli);
|
||||
return(False);
|
||||
}
|
||||
@ -637,11 +637,22 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
|
||||
}
|
||||
if (cli_is_dos_error(cli)) {
|
||||
cli_dos_error(cli, &eclass, &ecode);
|
||||
if(cli->pipes[cli->pipe_idx].fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
|
||||
if(!(eclass == ERRDOS && ecode == ERRmoredata)) {
|
||||
cli_signing_trans_stop(cli);
|
||||
return(False);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Likewise for NT_STATUS_BUFFER_TOO_SMALL
|
||||
*/
|
||||
if (cli_is_nt_error(cli)) {
|
||||
if (!NT_STATUS_EQUAL(cli_nt_error(cli),
|
||||
NT_STATUS_BUFFER_TOO_SMALL)) {
|
||||
cli_signing_trans_stop(cli);
|
||||
return(False);
|
||||
}
|
||||
}
|
||||
|
||||
/* parse out the total lengths again - they can shrink! */
|
||||
if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data)
|
||||
total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount);
|
||||
|
@ -2,6 +2,7 @@
|
||||
Unix SMB/CIFS implementation.
|
||||
code to manipulate domain credentials
|
||||
Copyright (C) Andrew Tridgell 1997-1998
|
||||
Largely rewritten by Jeremy Allison 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
|
||||
@ -21,8 +22,9 @@
|
||||
#include "includes.h"
|
||||
|
||||
/****************************************************************************
|
||||
represent a credential as a string
|
||||
Represent a credential as a string.
|
||||
****************************************************************************/
|
||||
|
||||
char *credstr(const uchar *cred)
|
||||
{
|
||||
static fstring buf;
|
||||
@ -34,182 +36,243 @@ char *credstr(const uchar *cred)
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
setup the session key.
|
||||
Setup the session key.
|
||||
Input: 8 byte challenge block
|
||||
8 byte server challenge block
|
||||
16 byte md4 encrypted password
|
||||
Output:
|
||||
8 byte session key
|
||||
16 byte session key (last 8 bytes zero).
|
||||
****************************************************************************/
|
||||
void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass,
|
||||
uchar session_key[8])
|
||||
|
||||
static void cred_create_session_key(const DOM_CHAL *clnt_chal_in,
|
||||
const DOM_CHAL *srv_chal_in,
|
||||
const uchar *pass_in,
|
||||
uchar session_key_out[16])
|
||||
{
|
||||
uint32 sum[2];
|
||||
unsigned char sum2[8];
|
||||
|
||||
sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0);
|
||||
sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4);
|
||||
sum[0] = IVAL(clnt_chal_in->data, 0) + IVAL(srv_chal_in->data, 0);
|
||||
sum[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4);
|
||||
|
||||
SIVAL(sum2,0,sum[0]);
|
||||
SIVAL(sum2,4,sum[1]);
|
||||
|
||||
cred_hash1(session_key, sum2, pass);
|
||||
cred_hash1(session_key_out, sum2, pass_in);
|
||||
memset(&session_key_out[8], '\0', 8);
|
||||
|
||||
/* debug output */
|
||||
DEBUG(4,("cred_session_key\n"));
|
||||
DEBUG(4,("cred_create_session_key\n"));
|
||||
|
||||
DEBUG(5,(" clnt_chal: %s\n", credstr(clnt_chal->data)));
|
||||
DEBUG(5,(" srv_chal : %s\n", credstr(srv_chal->data)));
|
||||
DEBUG(5,(" clnt_chal_in: %s\n", credstr(clnt_chal_in->data)));
|
||||
DEBUG(5,(" srv_chal_in : %s\n", credstr(srv_chal_in->data)));
|
||||
DEBUG(5,(" clnt+srv : %s\n", credstr(sum2)));
|
||||
DEBUG(5,(" sess_key : %s\n", credstr(session_key)));
|
||||
DEBUG(5,(" sess_key_out : %s\n", credstr(session_key_out)));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Utility function to step credential chain one forward.
|
||||
Deliberately doesn't update the seed. See reseed comment below.
|
||||
****************************************************************************/
|
||||
|
||||
static void creds_step(struct dcinfo *dc)
|
||||
{
|
||||
DOM_CHAL time_chal;
|
||||
|
||||
DEBUG(5,("\tsequence = 0x%x\n", (unsigned int)dc->sequence ));
|
||||
|
||||
DEBUG(5,("\tseed: %s\n", credstr(dc->seed_chal.data) ));
|
||||
|
||||
SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence);
|
||||
SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
|
||||
|
||||
DEBUG(5,("\tseed+seq %s\n", credstr(time_chal.data) ));
|
||||
|
||||
cred_hash2(dc->clnt_chal.data, time_chal.data, dc->sess_key);
|
||||
|
||||
DEBUG(5,("\tCLIENT %s\n", credstr(dc->clnt_chal.data) ));
|
||||
|
||||
SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1);
|
||||
SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
|
||||
|
||||
DEBUG(5,("\tseed+seq+1 %s\n", credstr(time_chal.data) ));
|
||||
|
||||
cred_hash2(dc->srv_chal.data, time_chal.data, dc->sess_key);
|
||||
|
||||
DEBUG(5,("\tSERVER %s\n", credstr(dc->srv_chal.data) ));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
create a credential
|
||||
|
||||
Input:
|
||||
8 byte sesssion key
|
||||
8 byte stored credential
|
||||
4 byte timestamp
|
||||
|
||||
Output:
|
||||
8 byte credential
|
||||
Create a server credential struct.
|
||||
****************************************************************************/
|
||||
void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp,
|
||||
DOM_CHAL *cred)
|
||||
|
||||
void creds_server_init(struct dcinfo *dc,
|
||||
DOM_CHAL *clnt_chal,
|
||||
DOM_CHAL *srv_chal,
|
||||
const char mach_pw[16],
|
||||
DOM_CHAL *init_chal_out)
|
||||
{
|
||||
DOM_CHAL time_cred;
|
||||
DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) ));
|
||||
DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) ));
|
||||
dump_data_pw("creds_server_init: machine pass", mach_pw, 16);
|
||||
|
||||
SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp.time);
|
||||
SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4));
|
||||
/* Just in case this isn't already there */
|
||||
memcpy(dc->mach_pw, mach_pw, 16);
|
||||
|
||||
cred_hash2(cred->data, time_cred.data, session_key);
|
||||
/* Generate the session key. */
|
||||
cred_create_session_key(clnt_chal, /* Stored client challenge. */
|
||||
srv_chal, /* Stored server challenge. */
|
||||
dc->mach_pw, /* input machine password. */
|
||||
dc->sess_key); /* output session key. */
|
||||
|
||||
/* debug output*/
|
||||
DEBUG(4,("cred_create\n"));
|
||||
dump_data_pw("creds_server_init: session key", dc->sess_key, 16);
|
||||
|
||||
DEBUG(5,(" sess_key : %s\n", credstr(session_key)));
|
||||
DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data)));
|
||||
DEBUG(5,(" timestamp: %x\n" , timestamp.time));
|
||||
DEBUG(5,(" timecred : %s\n", credstr(time_cred.data)));
|
||||
DEBUG(5,(" calc_cred: %s\n", credstr(cred->data)));
|
||||
/* Generate the next client and server creds. */
|
||||
cred_hash2(dc->clnt_chal.data, /* output */
|
||||
clnt_chal->data, /* input */
|
||||
dc->sess_key); /* input */
|
||||
|
||||
cred_hash2(dc->srv_chal.data, /* output */
|
||||
srv_chal->data, /* input */
|
||||
dc->sess_key); /* input */
|
||||
|
||||
/* Seed is the client chal. */
|
||||
memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
|
||||
|
||||
DEBUG(10,("creds_server_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
|
||||
DEBUG(10,("creds_server_init: server : %s\n", credstr(dc->srv_chal.data) ));
|
||||
DEBUG(10,("creds_server_init: seed : %s\n", credstr(dc->seed_chal.data) ));
|
||||
|
||||
memcpy(init_chal_out->data, dc->srv_chal.data, 8);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
check a supplied credential
|
||||
|
||||
Input:
|
||||
8 byte received credential
|
||||
8 byte sesssion key
|
||||
8 byte stored credential
|
||||
4 byte timestamp
|
||||
|
||||
Output:
|
||||
returns 1 if computed credential matches received credential
|
||||
returns 0 otherwise
|
||||
Check a credential sent by the client.
|
||||
****************************************************************************/
|
||||
int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
|
||||
UTIME timestamp)
|
||||
|
||||
BOOL creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in)
|
||||
{
|
||||
DOM_CHAL cred2;
|
||||
|
||||
cred_create(session_key, stored_cred, timestamp, &cred2);
|
||||
|
||||
/* debug output*/
|
||||
DEBUG(4,("cred_assert\n"));
|
||||
|
||||
DEBUG(5,(" challenge : %s\n", credstr(cred->data)));
|
||||
DEBUG(5,(" calculated: %s\n", credstr(cred2.data)));
|
||||
|
||||
if (memcmp(cred->data, cred2.data, 8) == 0)
|
||||
{
|
||||
DEBUG(5, ("credentials check ok\n"));
|
||||
return True;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(5, ("credentials check wrong\n"));
|
||||
if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) {
|
||||
DEBUG(5,("creds_server_check: challenge : %s\n", credstr(rcv_cli_chal_in->data)));
|
||||
DEBUG(5,("calculated: %s\n", credstr(dc->clnt_chal.data)));
|
||||
DEBUG(0,("creds_server_check: credentials check failed.\n"));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
checks credentials; generates next step in the credential chain
|
||||
****************************************************************************/
|
||||
BOOL clnt_deal_with_creds(uchar sess_key[8],
|
||||
DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred)
|
||||
{
|
||||
UTIME new_clnt_time;
|
||||
uint32 new_cred;
|
||||
|
||||
DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__));
|
||||
|
||||
/* increment client time by one second */
|
||||
new_clnt_time.time = sto_clnt_cred->timestamp.time + 1;
|
||||
|
||||
/* check that the received server credentials are valid */
|
||||
if (!cred_assert(&rcv_srv_cred->challenge, sess_key,
|
||||
&sto_clnt_cred->challenge, new_clnt_time))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
|
||||
/* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
|
||||
new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
|
||||
new_cred += new_clnt_time.time;
|
||||
|
||||
/* store new seed in client credentials */
|
||||
SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
|
||||
|
||||
DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->challenge.data)));
|
||||
DEBUG(10,("creds_server_check: credentials check OK.\n"));
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Replace current seed chal. Internal function - due to split server step below.
|
||||
****************************************************************************/
|
||||
|
||||
static void creds_reseed(struct dcinfo *dc)
|
||||
{
|
||||
DOM_CHAL time_chal;
|
||||
|
||||
SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1);
|
||||
SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4));
|
||||
|
||||
dc->seed_chal = time_chal;
|
||||
|
||||
DEBUG(5,("cred_reseed: seed %s\n", credstr(dc->seed_chal.data) ));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
checks credentials; generates next step in the credential chain
|
||||
Step the server credential chain one forward.
|
||||
****************************************************************************/
|
||||
BOOL deal_with_creds(uchar sess_key[8],
|
||||
DOM_CRED *sto_clnt_cred,
|
||||
DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred)
|
||||
{
|
||||
UTIME new_clnt_time;
|
||||
uint32 new_cred;
|
||||
|
||||
DEBUG(5,("deal_with_creds: %d\n", __LINE__));
|
||||
|
||||
/* check that the received client credentials are valid */
|
||||
if (!cred_assert(&rcv_clnt_cred->challenge, sess_key,
|
||||
&sto_clnt_cred->challenge, rcv_clnt_cred->timestamp))
|
||||
BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out)
|
||||
{
|
||||
dc->sequence = received_cred->timestamp.time;
|
||||
|
||||
creds_step(dc);
|
||||
|
||||
/* Create the outgoing credentials */
|
||||
cred_out->timestamp.time = dc->sequence + 1;
|
||||
cred_out->challenge = dc->srv_chal;
|
||||
|
||||
creds_reseed(dc);
|
||||
|
||||
return creds_server_check(dc, &received_cred->challenge);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Create a client credential struct.
|
||||
****************************************************************************/
|
||||
|
||||
void creds_client_init(struct dcinfo *dc,
|
||||
DOM_CHAL *clnt_chal,
|
||||
DOM_CHAL *srv_chal,
|
||||
const char mach_pw[16],
|
||||
DOM_CHAL *init_chal_out)
|
||||
{
|
||||
dc->sequence = time(NULL);
|
||||
|
||||
DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) ));
|
||||
DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) ));
|
||||
dump_data_pw("creds_client_init: machine pass", mach_pw, 16);
|
||||
|
||||
/* Just in case this isn't already there */
|
||||
memcpy(dc->mach_pw, mach_pw, 16);
|
||||
|
||||
/* Generate the session key. */
|
||||
cred_create_session_key(clnt_chal, /* Stored client challenge. */
|
||||
srv_chal, /* Stored server challenge. */
|
||||
dc->mach_pw, /* input machine password. */
|
||||
dc->sess_key); /* output session key. */
|
||||
|
||||
dump_data_pw("creds_client_init: session key", dc->sess_key, 16);
|
||||
|
||||
/* Generate the next client and server creds. */
|
||||
cred_hash2(dc->clnt_chal.data, /* output */
|
||||
clnt_chal->data, /* input */
|
||||
dc->sess_key); /* input */
|
||||
|
||||
cred_hash2(dc->srv_chal.data, /* output */
|
||||
srv_chal->data, /* input */
|
||||
dc->sess_key); /* input */
|
||||
|
||||
/* Seed is the client cred. */
|
||||
memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
|
||||
|
||||
DEBUG(10,("creds_client_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
|
||||
DEBUG(10,("creds_client_init: server : %s\n", credstr(dc->srv_chal.data) ));
|
||||
DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) ));
|
||||
|
||||
memcpy(init_chal_out->data, dc->clnt_chal.data, 8);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Check a credential returned by the server.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in)
|
||||
{
|
||||
if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, 8)) {
|
||||
DEBUG(5,("creds_client_check: challenge : %s\n", credstr(rcv_srv_chal_in->data)));
|
||||
DEBUG(5,("calculated: %s\n", credstr(dc->srv_chal.data)));
|
||||
DEBUG(0,("creds_client_check: credentials check failed.\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* increment client time by one second */
|
||||
new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1;
|
||||
|
||||
/* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
|
||||
new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
|
||||
new_cred += new_clnt_time.time;
|
||||
|
||||
DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred));
|
||||
|
||||
/* doesn't matter that server time is 0 */
|
||||
rtn_srv_cred->timestamp.time = 0;
|
||||
|
||||
DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", new_clnt_time.time));
|
||||
|
||||
/* create return credentials for inclusion in the reply */
|
||||
cred_create(sess_key, &sto_clnt_cred->challenge, new_clnt_time,
|
||||
&rtn_srv_cred->challenge);
|
||||
|
||||
DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data)));
|
||||
|
||||
/* store new seed in client credentials */
|
||||
SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
|
||||
|
||||
DEBUG(10,("creds_client_check: credentials check OK.\n"));
|
||||
return True;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Step the client credentials to the next element in the chain, updating the
|
||||
current client and server credentials and the seed
|
||||
produce the next authenticator in the sequence ready to send to
|
||||
the server
|
||||
****************************************************************************/
|
||||
|
||||
void creds_client_step(struct dcinfo *dc, DOM_CRED *next_cred_out)
|
||||
{
|
||||
dc->sequence += 2;
|
||||
creds_step(dc);
|
||||
creds_reseed(dc);
|
||||
|
||||
next_cred_out->challenge = dc->clnt_chal;
|
||||
next_cred_out->timestamp.time = dc->sequence;
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ static const struct {
|
||||
{ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC},
|
||||
{ERRDOS, 87, NT_STATUS_INVALID_CID},
|
||||
{ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED},
|
||||
{ERRDOS, 87, NT_STATUS_INVALID_PARAMETER},
|
||||
{ERRDOS, ERRinvalidparam, NT_STATUS_INVALID_PARAMETER},
|
||||
{ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE},
|
||||
{ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE},
|
||||
{ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST},
|
||||
@ -338,7 +338,7 @@ static const struct {
|
||||
{ERRDOS, 203, NT_STATUS(0xc0000100)},
|
||||
{ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY},
|
||||
{ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR},
|
||||
{ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY},
|
||||
{ERRDOS, ERRbaddirectory, NT_STATUS_NOT_A_DIRECTORY},
|
||||
{ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE},
|
||||
{ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION},
|
||||
{ERRDOS, 206, NT_STATUS_NAME_TOO_LONG},
|
||||
|
@ -420,7 +420,7 @@ int smbc_open_print_job(const char *fname)
|
||||
{
|
||||
SMBCFILE * file = statcont->open_print_job(statcont, fname);
|
||||
if (!file) return -1;
|
||||
return (int) file;
|
||||
return file->cli_fd;
|
||||
}
|
||||
|
||||
int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn)
|
||||
|
@ -80,6 +80,23 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an lsa pipe handle associated with a cli struct.
|
||||
*/
|
||||
|
||||
static struct rpc_pipe_client *find_lsa_pipe_hnd(struct cli_state *ipc_cli)
|
||||
{
|
||||
struct rpc_pipe_client *pipe_hnd;
|
||||
|
||||
for (pipe_hnd = ipc_cli->pipe_list; pipe_hnd; pipe_hnd = pipe_hnd->next) {
|
||||
if (pipe_hnd->pipe_idx == PI_LSARPC) {
|
||||
return pipe_hnd;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file);
|
||||
static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence);
|
||||
|
||||
@ -800,6 +817,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
|
||||
{
|
||||
struct in_addr ip;
|
||||
struct cli_state *ipc_cli;
|
||||
struct rpc_pipe_client *pipe_hnd;
|
||||
NTSTATUS nt_status;
|
||||
SMBCSRV *ipc_srv=NULL;
|
||||
|
||||
@ -835,9 +853,8 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(pol) {
|
||||
|
||||
if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) {
|
||||
pipe_hnd = cli_rpc_pipe_open_noauth(ipc_cli, PI_LSARPC, &nt_status);
|
||||
if (!pipe_hnd) {
|
||||
DEBUG(1, ("cli_nt_session_open fail!\n"));
|
||||
errno = ENOTSUP;
|
||||
cli_shutdown(ipc_cli);
|
||||
@ -847,7 +864,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
|
||||
/* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
|
||||
but NT sends 0x2000000 so we might as well do it too. */
|
||||
|
||||
nt_status = cli_lsa_open_policy(ipc_cli,
|
||||
nt_status = rpccli_lsa_open_policy(pipe_hnd,
|
||||
ipc_cli->mem_ctx,
|
||||
True,
|
||||
GENERIC_EXECUTE_ACCESS,
|
||||
@ -858,7 +875,6 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
|
||||
cli_shutdown(ipc_cli);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ipc_srv = SMB_MALLOC_P(SMBCSRV);
|
||||
if (!ipc_srv) {
|
||||
@ -1782,7 +1798,7 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int
|
||||
if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, &size, NULL, NULL,
|
||||
NULL, NULL, NULL))
|
||||
{
|
||||
SMB_BIG_UINT b_size = size;
|
||||
SMB_OFF_T b_size = size;
|
||||
if (!cli_getattrE(targetcli, file->cli_fd, NULL, &b_size, NULL, NULL,
|
||||
NULL))
|
||||
{
|
||||
@ -3041,7 +3057,7 @@ static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir)
|
||||
/*
|
||||
* We return the pointer here as the offset
|
||||
*/
|
||||
ret_val = (int)dir->dir_next;
|
||||
ret_val = (off_t)(long)dir->dir_next;
|
||||
return ret_val;
|
||||
|
||||
}
|
||||
@ -3347,14 +3363,20 @@ static void convert_sid_to_string(struct cli_state *ipc_cli,
|
||||
char **domains = NULL;
|
||||
char **names = NULL;
|
||||
uint32 *types = NULL;
|
||||
|
||||
struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli);
|
||||
sid_to_string(str, sid);
|
||||
|
||||
if (numeric) return; /* no lookup desired */
|
||||
if (numeric) {
|
||||
return; /* no lookup desired */
|
||||
}
|
||||
|
||||
if (!pipe_hnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ask LSA to convert the sid to a name */
|
||||
|
||||
if (!NT_STATUS_IS_OK(cli_lsa_lookup_sids(ipc_cli, ipc_cli->mem_ctx,
|
||||
if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ipc_cli->mem_ctx,
|
||||
pol, 1, sid, &domains,
|
||||
&names, &types)) ||
|
||||
!domains || !domains[0] || !names || !names[0]) {
|
||||
@ -3378,6 +3400,11 @@ static BOOL convert_string_to_sid(struct cli_state *ipc_cli,
|
||||
uint32 *types = NULL;
|
||||
DOM_SID *sids = NULL;
|
||||
BOOL result = True;
|
||||
struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli);
|
||||
|
||||
if (!pipe_hnd) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if (numeric) {
|
||||
if (strncmp(str, "S-", 2) == 0) {
|
||||
@ -3388,7 +3415,7 @@ static BOOL convert_string_to_sid(struct cli_state *ipc_cli,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(cli_lsa_lookup_names(ipc_cli, ipc_cli->mem_ctx,
|
||||
if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx,
|
||||
pol, 1, &str, &sids,
|
||||
&types))) {
|
||||
result = False;
|
||||
@ -5161,7 +5188,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr
|
||||
|
||||
/* Try to open the file for reading ... */
|
||||
|
||||
if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) {
|
||||
if ((long)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) {
|
||||
|
||||
DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno));
|
||||
return -1; /* smbc_open sets errno */
|
||||
@ -5170,7 +5197,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr
|
||||
|
||||
/* Now, try to open the printer file for writing */
|
||||
|
||||
if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) {
|
||||
if ((long)(fid2 = c_print->open_print_job(c_print, printq)) < 0) {
|
||||
|
||||
saverr = errno; /* Save errno */
|
||||
c_file->close_fn(c_file, fid1);
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
Copyright (C) Andrew Tridgell 2001
|
||||
Copyright (C) Andrew Bartlett 2001-2003
|
||||
Copyright (C) Andrew Bartlett 2005 (Updated from gensec).
|
||||
|
||||
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
|
||||
@ -217,6 +218,12 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
|
||||
uint32 ntlmssp_command;
|
||||
int i;
|
||||
|
||||
if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
|
||||
/* Called update after negotiations finished. */
|
||||
DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*out = data_blob(NULL, 0);
|
||||
|
||||
if (!in.length && ntlmssp_state->stored_response.length) {
|
||||
@ -348,6 +355,13 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
|
||||
|
||||
if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
|
||||
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
|
||||
if (neg_flags & NTLMSSP_NEGOTIATE_56) {
|
||||
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
|
||||
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
|
||||
}
|
||||
|
||||
if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
|
||||
@ -360,6 +374,34 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
Weaken NTLMSSP keys to cope with down-level clients and servers.
|
||||
|
||||
We probably should have some parameters to control this, but as
|
||||
it only occours for LM_KEY connections, and this is controlled
|
||||
by the client lanman auth/lanman auth parameters, it isn't too bad.
|
||||
*/
|
||||
|
||||
void ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state)
|
||||
{
|
||||
/* Key weakening not performed on the master key for NTLM2
|
||||
and does not occour for NTLM1. Therefore we only need
|
||||
to do this for the LM_KEY.
|
||||
*/
|
||||
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
|
||||
;
|
||||
} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
|
||||
ntlmssp_state->session_key.data[7] = 0xa0;
|
||||
} else { /* forty bits */
|
||||
ntlmssp_state->session_key.data[5] = 0xe5;
|
||||
ntlmssp_state->session_key.data[6] = 0x38;
|
||||
ntlmssp_state->session_key.data[7] = 0xb0;
|
||||
}
|
||||
ntlmssp_state->session_key.length = 8;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Next state function for the Negotiate packet
|
||||
@ -398,6 +440,9 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
|
||||
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);
|
||||
|
||||
@ -495,7 +540,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
|
||||
DATA_BLOB lm_session_key = data_blob(NULL, 0);
|
||||
DATA_BLOB session_key = data_blob(NULL, 0);
|
||||
uint32 ntlmssp_command, auth_flags;
|
||||
NTSTATUS nt_status;
|
||||
NTSTATUS nt_status = NT_STATUS_OK;
|
||||
|
||||
/* used by NTLM2 */
|
||||
BOOL doing_ntlm2 = False;
|
||||
@ -639,6 +684,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
|
||||
data_blob_free(&encrypted_session_key);
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
/* LM Key is incompatible. */
|
||||
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -710,11 +758,11 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
|
||||
if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
|
||||
data_blob_free(&encrypted_session_key);
|
||||
DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
|
||||
encrypted_session_key.length));
|
||||
(unsigned int)encrypted_session_key.length));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
} else if (!session_key.data || session_key.length != 16) {
|
||||
DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
|
||||
session_key.length));
|
||||
(unsigned int)session_key.length));
|
||||
ntlmssp_state->session_key = session_key;
|
||||
} else {
|
||||
dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
|
||||
@ -731,6 +779,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
|
||||
ntlmssp_state->session_key = session_key;
|
||||
}
|
||||
|
||||
/* The client might need us to use a partial-strength session key */
|
||||
ntlmssp_weaken_keys(ntlmssp_state);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
ntlmssp_state->session_key = data_blob(NULL, 0);
|
||||
} else if (ntlmssp_state->session_key.length) {
|
||||
@ -739,8 +790,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
|
||||
|
||||
data_blob_free(&encrypted_session_key);
|
||||
|
||||
/* allow arbitarily many authentications */
|
||||
ntlmssp_state->expected_state = NTLMSSP_AUTH;
|
||||
/* Only one authentication allowed per server state. */
|
||||
ntlmssp_state->expected_state = NTLMSSP_DONE;
|
||||
|
||||
return nt_status;
|
||||
}
|
||||
@ -784,7 +835,8 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
|
||||
NTLMSSP_NEGOTIATE_NTLM |
|
||||
NTLMSSP_NEGOTIATE_NTLM2 |
|
||||
NTLMSSP_NEGOTIATE_KEY_EXCH |
|
||||
NTLMSSP_NEGOTIATE_SIGN;
|
||||
NTLMSSP_NEGOTIATE_SIGN |
|
||||
NTLMSSP_NEGOTIATE_SEAL;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -851,7 +903,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
||||
DATA_BLOB nt_response = data_blob(NULL, 0);
|
||||
DATA_BLOB session_key = data_blob(NULL, 0);
|
||||
DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
|
||||
NTSTATUS nt_status;
|
||||
NTSTATUS nt_status = NT_STATUS_OK;
|
||||
|
||||
if (!msrpc_parse(&reply, "CdBd",
|
||||
"NTLMSSP",
|
||||
@ -977,8 +1029,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
||||
hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
|
||||
dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
|
||||
} else {
|
||||
|
||||
|
||||
uchar lm_hash[16];
|
||||
uchar nt_hash[16];
|
||||
E_deshash(ntlmssp_state->password, lm_hash);
|
||||
@ -998,7 +1048,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
||||
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
|
||||
if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
|
||||
&& lp_client_lanman_auth()) {
|
||||
SMBsesskeygen_lmv1(lm_hash, lm_response.data,
|
||||
SMBsesskeygen_lm_sess_key(lm_hash, lm_response.data,
|
||||
session_key.data);
|
||||
dump_data_pw("LM session key\n", session_key.data, session_key.length);
|
||||
} else {
|
||||
@ -1045,19 +1095,22 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
|
||||
|
||||
data_blob_free(&ntlmssp_state->chal);
|
||||
|
||||
ntlmssp_state->session_key = session_key;
|
||||
|
||||
/* The client might be using 56 or 40 bit weakened keys */
|
||||
ntlmssp_weaken_keys(ntlmssp_state);
|
||||
|
||||
ntlmssp_state->chal = challenge_blob;
|
||||
ntlmssp_state->lm_resp = lm_response;
|
||||
ntlmssp_state->nt_resp = nt_response;
|
||||
ntlmssp_state->session_key = session_key;
|
||||
|
||||
ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
|
||||
ntlmssp_state->expected_state = NTLMSSP_DONE;
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
|
||||
DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
return NT_STATUS_MORE_PROCESSING_REQUIRED;
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
|
||||
@ -1103,4 +1156,3 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
|
||||
/* if odd length and unicode */
|
||||
return False;
|
||||
}
|
||||
if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data)
|
||||
if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data)
|
||||
return False;
|
||||
|
||||
if (0 < len1) {
|
||||
@ -244,7 +244,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
|
||||
return False;
|
||||
}
|
||||
|
||||
if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data)
|
||||
if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data)
|
||||
return False;
|
||||
|
||||
if (0 < len1) {
|
||||
@ -272,7 +272,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob,
|
||||
return False;
|
||||
}
|
||||
|
||||
if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data)
|
||||
if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data)
|
||||
return False;
|
||||
|
||||
*b = data_blob(blob->data + ptr, len1);
|
||||
|
@ -2,8 +2,7 @@
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Version 3.0
|
||||
* NTLMSSP Signing routines
|
||||
* Copyright (C) Luke Kenneth Casson Leighton 1996-2001
|
||||
* Copyright (C) Andrew Bartlett 2003
|
||||
* Copyright (C) Andrew Bartlett 2003-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
|
||||
@ -27,74 +26,25 @@
|
||||
#define SRV_SIGN "session key to server-to-client signing key magic constant"
|
||||
#define SRV_SEAL "session key to server-to-client sealing key magic constant"
|
||||
|
||||
static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len)
|
||||
{
|
||||
unsigned char index_i = hash[256];
|
||||
unsigned char index_j = hash[257];
|
||||
int ind;
|
||||
/**
|
||||
* Some notes on then NTLM2 code:
|
||||
*
|
||||
* NTLM2 is a AEAD system. This means that the data encrypted is not
|
||||
* all the data that is signed. In DCE-RPC case, the headers of the
|
||||
* DCE-RPC packets are also signed. This prevents some of the
|
||||
* fun-and-games one might have by changing them.
|
||||
*
|
||||
*/
|
||||
|
||||
for (ind = 0; ind < len; ind++)
|
||||
{
|
||||
unsigned char tc;
|
||||
unsigned char t;
|
||||
|
||||
index_i++;
|
||||
index_j += hash[index_i];
|
||||
|
||||
tc = hash[index_i];
|
||||
hash[index_i] = hash[index_j];
|
||||
hash[index_j] = tc;
|
||||
|
||||
t = hash[index_i] + hash[index_j];
|
||||
data[ind] = data[ind] ^ hash[t];
|
||||
}
|
||||
|
||||
hash[256] = index_i;
|
||||
hash[257] = index_j;
|
||||
}
|
||||
|
||||
static void calc_hash(unsigned char hash[258], unsigned char *k2, int k2l)
|
||||
{
|
||||
unsigned char j = 0;
|
||||
int ind;
|
||||
|
||||
for (ind = 0; ind < 256; ind++)
|
||||
{
|
||||
hash[ind] = (unsigned char)ind;
|
||||
}
|
||||
|
||||
for (ind = 0; ind < 256; ind++)
|
||||
{
|
||||
unsigned char tc;
|
||||
|
||||
j += (hash[ind] + k2[ind%k2l]);
|
||||
|
||||
tc = hash[ind];
|
||||
hash[ind] = hash[j];
|
||||
hash[j] = tc;
|
||||
}
|
||||
|
||||
hash[256] = 0;
|
||||
hash[257] = 0;
|
||||
}
|
||||
|
||||
static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char digest[16],
|
||||
static void calc_ntlmv2_key(unsigned char subkey[16],
|
||||
DATA_BLOB session_key,
|
||||
const char *constant)
|
||||
{
|
||||
struct MD5Context ctx3;
|
||||
|
||||
/* NOTE: This code is currently complate fantasy - it's
|
||||
got more in common with reality than the previous code
|
||||
(the LM session key is not the right thing to use) but
|
||||
it still needs work */
|
||||
|
||||
MD5Init(&ctx3);
|
||||
MD5Update(&ctx3, session_key.data, session_key.length);
|
||||
MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1);
|
||||
MD5Final(digest, &ctx3);
|
||||
|
||||
calc_hash(hash, digest, 16);
|
||||
MD5Update(&ctx3, constant, strlen(constant)+1);
|
||||
MD5Final(subkey, &ctx3);
|
||||
}
|
||||
|
||||
enum ntlmssp_direction {
|
||||
@ -104,63 +54,106 @@ enum ntlmssp_direction {
|
||||
|
||||
static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
|
||||
const uchar *data, size_t length,
|
||||
const uchar *whole_pdu, size_t pdu_length,
|
||||
enum ntlmssp_direction direction,
|
||||
DATA_BLOB *sig)
|
||||
DATA_BLOB *sig,
|
||||
BOOL encrypt_sig)
|
||||
{
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
|
||||
HMACMD5Context ctx;
|
||||
uchar seq_num[4];
|
||||
uchar digest[16];
|
||||
SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
|
||||
|
||||
hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
|
||||
hmac_md5_update(seq_num, 4, &ctx);
|
||||
hmac_md5_update(data, length, &ctx);
|
||||
hmac_md5_final(digest, &ctx);
|
||||
|
||||
if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */
|
||||
, ntlmssp_state->ntlmssp_seq_num)) {
|
||||
*sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
|
||||
if (!sig->data) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
|
||||
switch (direction) {
|
||||
case NTLMSSP_SEND:
|
||||
NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4);
|
||||
DEBUG(100,("ntlmssp_make_packet_signature: SEND seq = %u, len = %u, pdu_len = %u\n",
|
||||
ntlmssp_state->ntlm2_send_seq_num,
|
||||
(unsigned int)length,
|
||||
(unsigned int)pdu_length));
|
||||
|
||||
SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num);
|
||||
ntlmssp_state->ntlm2_send_seq_num++;
|
||||
hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, 16, &ctx);
|
||||
break;
|
||||
case NTLMSSP_RECEIVE:
|
||||
NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4);
|
||||
|
||||
DEBUG(100,("ntlmssp_make_packet_signature: RECV seq = %u, len = %u, pdu_len = %u\n",
|
||||
ntlmssp_state->ntlm2_recv_seq_num,
|
||||
(unsigned int)length,
|
||||
(unsigned int)pdu_length));
|
||||
|
||||
SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num);
|
||||
ntlmssp_state->ntlm2_recv_seq_num++;
|
||||
hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, 16, &ctx);
|
||||
break;
|
||||
}
|
||||
|
||||
dump_data_pw("pdu data ", whole_pdu, pdu_length);
|
||||
|
||||
hmac_md5_update(seq_num, 4, &ctx);
|
||||
hmac_md5_update(whole_pdu, pdu_length, &ctx);
|
||||
hmac_md5_final(digest, &ctx);
|
||||
|
||||
if (encrypt_sig && (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
|
||||
switch (direction) {
|
||||
case NTLMSSP_SEND:
|
||||
smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, digest, 8);
|
||||
break;
|
||||
case NTLMSSP_RECEIVE:
|
||||
smb_arc4_crypt(ntlmssp_state->recv_seal_arc4_state, digest, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION);
|
||||
memcpy(sig->data + 4, digest, 8);
|
||||
memcpy(sig->data + 12, seq_num, 4);
|
||||
|
||||
dump_data_pw("ntlmssp v2 sig ", sig->data, sig->length);
|
||||
|
||||
} else {
|
||||
uint32 crc;
|
||||
crc = crc32_calc_buffer((const char *)data, length);
|
||||
if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
|
||||
if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmv1_seq_num)) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
|
||||
sizeof(ntlmssp_state->ntlmssp_hash));
|
||||
NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
|
||||
ntlmssp_state->ntlmv1_seq_num++;
|
||||
|
||||
dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmv1_arc4_state,
|
||||
sizeof(ntlmssp_state->ntlmv1_arc4_state));
|
||||
smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4);
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
const uchar *data, size_t length,
|
||||
const uchar *whole_pdu, size_t pdu_length,
|
||||
DATA_BLOB *sig)
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
|
||||
if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
|
||||
DEBUG(3, ("NTLMSSP Signing not negotiated - cannot sign packet!\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!ntlmssp_state->session_key.length) {
|
||||
DEBUG(3, ("NO session key, cannot check sign packet\n"));
|
||||
return NT_STATUS_NO_USER_SESSION_KEY;
|
||||
}
|
||||
|
||||
nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig);
|
||||
nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
|
||||
data, length,
|
||||
whole_pdu, pdu_length,
|
||||
NTLMSSP_SEND, sig, True);
|
||||
|
||||
/* increment counter on send */
|
||||
ntlmssp_state->ntlmssp_seq_num++;
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
@ -172,6 +165,7 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
|
||||
NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
const uchar *data, size_t length,
|
||||
const uchar *whole_pdu, size_t pdu_length,
|
||||
const DATA_BLOB *sig)
|
||||
{
|
||||
DATA_BLOB local_sig;
|
||||
@ -187,32 +181,51 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
(unsigned long)sig->length));
|
||||
}
|
||||
|
||||
nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data,
|
||||
length, NTLMSSP_RECEIVE, &local_sig);
|
||||
nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
|
||||
data, length,
|
||||
whole_pdu, pdu_length,
|
||||
NTLMSSP_RECEIVE, &local_sig, True);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status)));
|
||||
data_blob_free(&local_sig);
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
if (memcmp(sig->data+sig->length - 8, local_sig.data+local_sig.length - 8, 8) != 0) {
|
||||
DEBUG(5, ("BAD SIG: wanted signature of\n"));
|
||||
dump_data(5, (const char *)local_sig.data, local_sig.length);
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
|
||||
if (local_sig.length != sig->length ||
|
||||
memcmp(local_sig.data, sig->data, sig->length) != 0) {
|
||||
DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n"));
|
||||
dump_data(5, local_sig.data, local_sig.length);
|
||||
|
||||
DEBUG(5, ("BAD SIG: got signature of\n"));
|
||||
dump_data(5, (const char *)(sig->data), sig->length);
|
||||
dump_data(5, sig->data, sig->length);
|
||||
|
||||
DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n"));
|
||||
DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n"));
|
||||
data_blob_free(&local_sig);
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
} else {
|
||||
if (local_sig.length != sig->length ||
|
||||
memcmp(local_sig.data + 8, sig->data + 8, sig->length - 8) != 0) {
|
||||
DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n"));
|
||||
dump_data(5, local_sig.data, local_sig.length);
|
||||
|
||||
/* increment counter on recieive */
|
||||
ntlmssp_state->ntlmssp_seq_num++;
|
||||
DEBUG(5, ("BAD SIG: got signature of\n"));
|
||||
dump_data(5, sig->data, sig->length);
|
||||
|
||||
DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n"));
|
||||
data_blob_free(&local_sig);
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length);
|
||||
DEBUG(10,("ntlmssp_check_packet: NTLMSSP signature OK !\n"));
|
||||
|
||||
data_blob_free(&local_sig);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Seal data with the NTLMSSP algorithm
|
||||
*
|
||||
@ -220,8 +233,16 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
|
||||
NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
uchar *data, size_t length,
|
||||
uchar *whole_pdu, size_t pdu_length,
|
||||
DATA_BLOB *sig)
|
||||
{
|
||||
NTSTATUS nt_status;
|
||||
|
||||
if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
|
||||
DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n"));
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!ntlmssp_state->session_key.length) {
|
||||
DEBUG(3, ("NO session key, cannot seal packet\n"));
|
||||
return NT_STATUS_NO_USER_SESSION_KEY;
|
||||
@ -230,53 +251,44 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
DEBUG(10,("ntlmssp_seal_data: seal\n"));
|
||||
dump_data_pw("ntlmssp clear data\n", data, length);
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
|
||||
HMACMD5Context ctx;
|
||||
char seq_num[4];
|
||||
uchar digest[16];
|
||||
SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
|
||||
|
||||
hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
|
||||
hmac_md5_update((const unsigned char *)seq_num, 4, &ctx);
|
||||
hmac_md5_update(data, length, &ctx);
|
||||
hmac_md5_final(digest, &ctx);
|
||||
|
||||
if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */
|
||||
, ntlmssp_state->ntlmssp_seq_num)) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
/* The order of these two operations matters - we must first seal the packet,
|
||||
then seal the sequence number - this is becouse the send_seal_hash is not
|
||||
constant, but is is rather updated with each iteration */
|
||||
nt_status = ntlmssp_make_packet_signature(ntlmssp_state,
|
||||
data, length,
|
||||
whole_pdu, pdu_length,
|
||||
NTLMSSP_SEND, sig, False);
|
||||
smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, data, length);
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
|
||||
smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, sig->data+4, 8);
|
||||
}
|
||||
|
||||
dump_data_pw("ntlmssp client sealing hash:\n",
|
||||
ntlmssp_state->send_seal_hash,
|
||||
sizeof(ntlmssp_state->send_seal_hash));
|
||||
NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length);
|
||||
dump_data_pw("ntlmssp client signing hash:\n",
|
||||
ntlmssp_state->send_sign_hash,
|
||||
sizeof(ntlmssp_state->send_sign_hash));
|
||||
NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4);
|
||||
} else {
|
||||
uint32 crc;
|
||||
crc = crc32_calc_buffer((const char *)data, length);
|
||||
if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
|
||||
if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmv1_seq_num)) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* The order of these two operations matters - we must first seal the packet,
|
||||
then seal the sequence number - this is becouse the ntlmssp_hash is not
|
||||
then seal the sequence number - this is becouse the ntlmv1_arc4_state is not
|
||||
constant, but is is rather updated with each iteration */
|
||||
|
||||
dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
|
||||
sizeof(ntlmssp_state->ntlmssp_hash));
|
||||
NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);
|
||||
dump_data_pw("ntlmv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state,
|
||||
sizeof(ntlmssp_state->ntlmv1_arc4_state));
|
||||
smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, data, length);
|
||||
|
||||
dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
|
||||
sizeof(ntlmssp_state->ntlmssp_hash));
|
||||
NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4);
|
||||
dump_data_pw("ntlmv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state,
|
||||
sizeof(ntlmssp_state->ntlmv1_arc4_state));
|
||||
|
||||
smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4);
|
||||
|
||||
ntlmssp_state->ntlmv1_seq_num++;
|
||||
|
||||
nt_status = NT_STATUS_OK;
|
||||
}
|
||||
dump_data_pw("ntlmssp signature\n", sig->data, sig->length);
|
||||
dump_data_pw("ntlmssp sealed data\n", data, length);
|
||||
|
||||
/* increment counter on send */
|
||||
ntlmssp_state->ntlmssp_seq_num++;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -287,6 +299,7 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
|
||||
NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
uchar *data, size_t length,
|
||||
uchar *whole_pdu, size_t pdu_length,
|
||||
DATA_BLOB *sig)
|
||||
{
|
||||
if (!ntlmssp_state->session_key.length) {
|
||||
@ -294,18 +307,18 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state,
|
||||
return NT_STATUS_NO_USER_SESSION_KEY;
|
||||
}
|
||||
|
||||
DEBUG(10,("ntlmssp__unseal_data: seal\n"));
|
||||
DEBUG(10,("ntlmssp_unseal_data: seal\n"));
|
||||
dump_data_pw("ntlmssp sealed data\n", data, length);
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
|
||||
NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length);
|
||||
} else {
|
||||
dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
|
||||
sizeof(ntlmssp_state->ntlmssp_hash));
|
||||
NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length);
|
||||
}
|
||||
dump_data_pw("ntlmssp clear data\n", data, length);
|
||||
|
||||
return ntlmssp_check_packet(ntlmssp_state, data, length, sig);
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
|
||||
/* First unseal the data. */
|
||||
smb_arc4_crypt(ntlmssp_state->recv_seal_arc4_state, data, length);
|
||||
dump_data_pw("ntlmv2 clear data\n", data, length);
|
||||
} else {
|
||||
smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, data, length);
|
||||
dump_data_pw("ntlmv1 clear data\n", data, length);
|
||||
}
|
||||
return ntlmssp_check_packet(ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -326,6 +339,7 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state)
|
||||
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
|
||||
{
|
||||
DATA_BLOB weak_session_key = ntlmssp_state->session_key;
|
||||
const char *send_sign_const;
|
||||
const char *send_seal_const;
|
||||
const char *recv_sign_const;
|
||||
@ -352,62 +366,96 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state)
|
||||
break;
|
||||
}
|
||||
|
||||
calc_ntlmv2_hash(ntlmssp_state->send_sign_hash,
|
||||
ntlmssp_state->send_sign_const,
|
||||
/**
|
||||
Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions.
|
||||
We probably should have some parameters to control this, once we get NTLM2 working.
|
||||
*/
|
||||
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
|
||||
;
|
||||
} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
|
||||
weak_session_key.length = 6;
|
||||
} else { /* forty bits */
|
||||
weak_session_key.length = 5;
|
||||
}
|
||||
|
||||
dump_data_pw("NTLMSSP weakend master key:\n",
|
||||
weak_session_key.data,
|
||||
weak_session_key.length);
|
||||
|
||||
/* SEND */
|
||||
calc_ntlmv2_key(ntlmssp_state->send_sign_key,
|
||||
ntlmssp_state->session_key, send_sign_const);
|
||||
dump_data_pw("NTLMSSP send sign hash:\n",
|
||||
ntlmssp_state->send_sign_hash,
|
||||
sizeof(ntlmssp_state->send_sign_hash));
|
||||
dump_data_pw("NTLMSSP send sign key:\n",
|
||||
ntlmssp_state->send_sign_key, 16);
|
||||
|
||||
calc_ntlmv2_hash(ntlmssp_state->send_seal_hash,
|
||||
ntlmssp_state->send_seal_const,
|
||||
ntlmssp_state->session_key, send_seal_const);
|
||||
dump_data_pw("NTLMSSP send sesl hash:\n",
|
||||
ntlmssp_state->send_seal_hash,
|
||||
sizeof(ntlmssp_state->send_seal_hash));
|
||||
calc_ntlmv2_key(ntlmssp_state->send_seal_key,
|
||||
weak_session_key, send_seal_const);
|
||||
dump_data_pw("NTLMSSP send seal key:\n",
|
||||
ntlmssp_state->send_seal_key, 16);
|
||||
|
||||
calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash,
|
||||
ntlmssp_state->recv_sign_const,
|
||||
smb_arc4_init(ntlmssp_state->send_seal_arc4_state,
|
||||
ntlmssp_state->send_seal_key, 16);
|
||||
|
||||
dump_data_pw("NTLMSSP send seal arc4 state:\n",
|
||||
ntlmssp_state->send_seal_arc4_state,
|
||||
sizeof(ntlmssp_state->send_seal_arc4_state));
|
||||
|
||||
/* RECV */
|
||||
calc_ntlmv2_key(ntlmssp_state->recv_sign_key,
|
||||
ntlmssp_state->session_key, recv_sign_const);
|
||||
dump_data_pw("NTLMSSP receive sign hash:\n",
|
||||
ntlmssp_state->recv_sign_hash,
|
||||
sizeof(ntlmssp_state->recv_sign_hash));
|
||||
dump_data_pw("NTLMSSP recv send sign key:\n",
|
||||
ntlmssp_state->recv_sign_key, 16);
|
||||
|
||||
calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash,
|
||||
ntlmssp_state->recv_seal_const,
|
||||
ntlmssp_state->session_key, recv_seal_const);
|
||||
dump_data_pw("NTLMSSP receive seal hash:\n",
|
||||
ntlmssp_state->recv_sign_hash,
|
||||
sizeof(ntlmssp_state->recv_sign_hash));
|
||||
calc_ntlmv2_key(ntlmssp_state->recv_seal_key,
|
||||
weak_session_key, recv_seal_const);
|
||||
|
||||
}
|
||||
else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
|
||||
if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) {
|
||||
/* can't sign or check signatures yet */
|
||||
DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
dump_data_pw("NTLMSSP recv seal key:\n",
|
||||
ntlmssp_state->recv_seal_key, 16);
|
||||
|
||||
smb_arc4_init(ntlmssp_state->recv_seal_arc4_state,
|
||||
ntlmssp_state->recv_seal_key, 16);
|
||||
|
||||
dump_data_pw("NTLMSSP recv seal arc4 state:\n",
|
||||
ntlmssp_state->recv_seal_arc4_state,
|
||||
sizeof(ntlmssp_state->recv_seal_arc4_state));
|
||||
|
||||
ntlmssp_state->ntlm2_send_seq_num = 0;
|
||||
ntlmssp_state->ntlm2_recv_seq_num = 0;
|
||||
|
||||
DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n"));
|
||||
|
||||
calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 8);
|
||||
dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
|
||||
sizeof(ntlmssp_state->ntlmssp_hash));
|
||||
} else {
|
||||
if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) {
|
||||
/* can't sign or check signatures yet */
|
||||
DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
#if 0
|
||||
/* Hmmm. Shouldn't we also weaken keys for ntlmv1 ? JRA. */
|
||||
|
||||
DATA_BLOB weak_session_key = ntlmssp_state->session_key;
|
||||
/**
|
||||
Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions.
|
||||
We probably should have some parameters to control this, once we get NTLM2 working.
|
||||
*/
|
||||
|
||||
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
|
||||
;
|
||||
} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
|
||||
weak_session_key.length = 6;
|
||||
} else { /* forty bits */
|
||||
weak_session_key.length = 5;
|
||||
}
|
||||
dump_data_pw("NTLMSSP weakend master key:\n",
|
||||
weak_session_key.data,
|
||||
weak_session_key.length);
|
||||
#endif
|
||||
|
||||
DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n"));
|
||||
DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
|
||||
|
||||
calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 16);
|
||||
dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
|
||||
sizeof(ntlmssp_state->ntlmssp_hash));
|
||||
smb_arc4_init(ntlmssp_state->ntlmv1_arc4_state,
|
||||
ntlmssp_state->session_key.data, ntlmssp_state->session_key.length);
|
||||
|
||||
dump_data_pw("NTLMv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state,
|
||||
sizeof(ntlmssp_state->ntlmv1_arc4_state));
|
||||
|
||||
ntlmssp_state->ntlmv1_seq_num = 0;
|
||||
}
|
||||
|
||||
ntlmssp_state->ntlmssp_seq_num = 0;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
@ -21,16 +21,17 @@
|
||||
#include "includes.h"
|
||||
|
||||
/*************************************************************
|
||||
change a password on a remote machine using IPC calls
|
||||
Change a password on a remote machine using IPC calls.
|
||||
*************************************************************/
|
||||
|
||||
BOOL remote_password_change(const char *remote_machine, const char *user_name,
|
||||
const char *old_passwd, const char *new_passwd,
|
||||
char *err_str, size_t err_str_len)
|
||||
{
|
||||
struct nmb_name calling, called;
|
||||
struct cli_state cli;
|
||||
struct rpc_pipe_client *pipe_hnd;
|
||||
struct in_addr ip;
|
||||
struct ntuser_creds creds;
|
||||
|
||||
NTSTATUS result;
|
||||
|
||||
@ -85,11 +86,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
|
||||
return False;
|
||||
}
|
||||
|
||||
init_creds(&creds, "", "", NULL);
|
||||
cli_init_creds(&cli, &creds);
|
||||
cli_init_creds(&cli, "", "", NULL);
|
||||
} else {
|
||||
init_creds(&creds, user_name, "", old_passwd);
|
||||
cli_init_creds(&cli, &creds);
|
||||
cli_init_creds(&cli, user_name, "", old_passwd);
|
||||
}
|
||||
|
||||
if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
|
||||
@ -99,14 +98,19 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Try not to give the password away to easily */
|
||||
/* Try not to give the password away too easily */
|
||||
|
||||
cli.pipe_auth_flags = AUTH_PIPE_NTLMSSP;
|
||||
cli.pipe_auth_flags |= AUTH_PIPE_SIGN;
|
||||
cli.pipe_auth_flags |= AUTH_PIPE_SEAL;
|
||||
pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli,
|
||||
PI_SAMR,
|
||||
PIPE_AUTH_LEVEL_PRIVACY,
|
||||
"", /* what domain... ? */
|
||||
user_name,
|
||||
old_passwd,
|
||||
&result);
|
||||
|
||||
if ( !cli_nt_session_open( &cli, PI_SAMR ) ) {
|
||||
if (!pipe_hnd) {
|
||||
if (lp_client_lanman_auth()) {
|
||||
/* Use the old RAP method. */
|
||||
if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
|
||||
slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n",
|
||||
remote_machine, cli_errstr(&cli) );
|
||||
@ -114,14 +118,16 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
|
||||
return False;
|
||||
}
|
||||
} else {
|
||||
slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n",
|
||||
remote_machine);
|
||||
slprintf(err_str, err_str_len-1,
|
||||
"SAMR connection to machine %s failed. Error was %s, "
|
||||
"but LANMAN password changed are disabled\n",
|
||||
nt_errstr(result), remote_machine);
|
||||
cli_shutdown(&cli);
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name,
|
||||
if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli.mem_ctx, user_name,
|
||||
new_passwd, old_passwd))) {
|
||||
/* Great - it all worked! */
|
||||
cli_shutdown(&cli);
|
||||
@ -138,25 +144,25 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
|
||||
}
|
||||
|
||||
/* OK, that failed, so try again... */
|
||||
cli_nt_session_close(&cli);
|
||||
cli_rpc_pipe_close(pipe_hnd);
|
||||
|
||||
/* Try anonymous NTLMSSP... */
|
||||
init_creds(&creds, "", "", NULL);
|
||||
cli_init_creds(&cli, &creds);
|
||||
|
||||
cli.pipe_auth_flags = 0;
|
||||
cli_init_creds(&cli, "", "", NULL);
|
||||
|
||||
result = NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* OK, this is ugly, but... */
|
||||
if ( cli_nt_session_open( &cli, PI_SAMR )
|
||||
&& NT_STATUS_IS_OK(result
|
||||
= cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name,
|
||||
new_passwd, old_passwd))) {
|
||||
/* OK, this is ugly, but... try an anonymous pipe. */
|
||||
pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result);
|
||||
|
||||
if ( pipe_hnd &&
|
||||
(NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd,
|
||||
cli.mem_ctx,
|
||||
user_name,
|
||||
new_passwd,
|
||||
old_passwd)))) {
|
||||
/* Great - it all worked! */
|
||||
cli_shutdown(&cli);
|
||||
return True;
|
||||
|
||||
} else {
|
||||
if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)
|
||||
|| NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) {
|
||||
@ -173,6 +179,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
|
||||
just might not support SAMR password changes, so fall back */
|
||||
|
||||
if (lp_client_lanman_auth()) {
|
||||
/* Use the old RAP method. */
|
||||
if (cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
|
||||
/* SAMR failed, but the old LanMan protocol worked! */
|
||||
|
||||
@ -186,8 +193,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
|
||||
return False;
|
||||
} else {
|
||||
slprintf(err_str, err_str_len-1,
|
||||
"machine %s does not support SAMR connections, but LANMAN password changed are disabled\n",
|
||||
remote_machine);
|
||||
"SAMR connection to machine %s failed. Error was %s, "
|
||||
"but LANMAN password changed are disabled\n",
|
||||
nt_errstr(result), remote_machine);
|
||||
cli_shutdown(&cli);
|
||||
return False;
|
||||
}
|
||||
|
@ -60,4 +60,3 @@ void pwd_get_cleartext(struct pwd_info *pwd, fstring clr)
|
||||
clr[0] = 0;
|
||||
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,12 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path)
|
||||
return smb_db;
|
||||
}
|
||||
|
||||
/* key and data records in the tdb locking database */
|
||||
struct locking_key {
|
||||
SMB_DEV_T dev;
|
||||
SMB_INO_T inode;
|
||||
};
|
||||
|
||||
int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
|
||||
{
|
||||
int ret = tdb_close(db_ctx->smb_tdb);
|
||||
@ -102,10 +108,10 @@ struct locking_data {
|
||||
int num_share_mode_entries;
|
||||
BOOL delete_on_close;
|
||||
} s;
|
||||
share_mode_entry dummy; /* Needed for alignment. */
|
||||
struct share_mode_entry dummy; /* Needed for alignment. */
|
||||
} u;
|
||||
/* the following two entries are implicit
|
||||
share_mode_entry modes[num_share_mode_entries];
|
||||
struct share_mode_entry modes[num_share_mode_entries];
|
||||
char file_name[];
|
||||
*/
|
||||
};
|
||||
@ -114,9 +120,9 @@ struct locking_data {
|
||||
* Check if an external smb_share_mode_entry and an internal share_mode entry match.
|
||||
*/
|
||||
|
||||
static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, const share_mode_entry *entry)
|
||||
static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, const struct share_mode_entry *entry)
|
||||
{
|
||||
return (e_entry->pid == entry->pid &&
|
||||
return (procid_equal(&e_entry->pid, &entry->pid) &&
|
||||
e_entry->file_id == (uint32_t)entry->share_file_id &&
|
||||
e_entry->open_time.tv_sec == entry->time.tv_sec &&
|
||||
e_entry->open_time.tv_usec == entry->time.tv_usec &&
|
||||
@ -130,9 +136,9 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, co
|
||||
* Create an internal Samba share_mode entry from an external smb_share_mode_entry.
|
||||
*/
|
||||
|
||||
static void create_share_mode_entry(share_mode_entry *out, const struct smb_share_mode_entry *in)
|
||||
static void create_share_mode_entry(struct share_mode_entry *out, const struct smb_share_mode_entry *in)
|
||||
{
|
||||
memset(out, '\0', sizeof(share_mode_entry));
|
||||
memset(out, '\0', sizeof(struct share_mode_entry));
|
||||
|
||||
out->pid = in->pid;
|
||||
out->share_file_id = (unsigned long)in->file_id;
|
||||
@ -159,7 +165,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
|
||||
struct smb_share_mode_entry *list = NULL;
|
||||
int num_share_modes = 0;
|
||||
struct locking_data *ld = NULL; /* internal samba db state. */
|
||||
share_mode_entry *shares = NULL;
|
||||
struct share_mode_entry *shares = NULL;
|
||||
size_t i;
|
||||
int list_num;
|
||||
|
||||
@ -187,19 +193,24 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
|
||||
|
||||
memset(list, '\0', num_share_modes * sizeof(struct smb_share_mode_entry));
|
||||
|
||||
shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry));
|
||||
shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
|
||||
|
||||
list_num = 0;
|
||||
for (i = 0; i < num_share_modes; i++) {
|
||||
share_mode_entry *share = &shares[i];
|
||||
struct share_mode_entry *share = &shares[i];
|
||||
struct smb_share_mode_entry *sme = &list[list_num];
|
||||
pid_t pid = share->pid;
|
||||
struct process_id pid = share->pid;
|
||||
|
||||
/* Check this process really exists. */
|
||||
if (kill(pid, 0) == -1 && (errno == ESRCH)) {
|
||||
if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) {
|
||||
continue; /* No longer exists. */
|
||||
}
|
||||
|
||||
/* Ignore deferred open entries. */
|
||||
if (share->op_type == DEFERRED_OPEN_ENTRY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Copy into the external list. */
|
||||
sme->dev = (uint64_t)share->dev;
|
||||
sme->ino = (uint64_t)share->inode;
|
||||
@ -238,27 +249,27 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
TDB_DATA locking_key = get_locking_key(dev, ino);
|
||||
int orig_num_share_modes = 0;
|
||||
struct locking_data *ld = NULL; /* internal samba db state. */
|
||||
share_mode_entry *shares = NULL;
|
||||
struct share_mode_entry *shares = NULL;
|
||||
char *new_data_p = NULL;
|
||||
size_t new_data_size = 0;
|
||||
|
||||
db_data = tdb_fetch(db_ctx->smb_tdb, locking_key);
|
||||
if (!db_data.dptr) {
|
||||
/* We must create the entry. */
|
||||
db_data.dptr = malloc((2*sizeof(share_mode_entry)) + strlen(filename) + 1);
|
||||
db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) + strlen(filename) + 1);
|
||||
if (!db_data.dptr) {
|
||||
return -1;
|
||||
}
|
||||
ld = (struct locking_data *)db_data.dptr;
|
||||
ld->u.s.num_share_mode_entries = 1;
|
||||
ld->u.s.delete_on_close = 0;
|
||||
shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry));
|
||||
shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
|
||||
create_share_mode_entry(shares, new_entry);
|
||||
memcpy(db_data.dptr + 2*sizeof(share_mode_entry),
|
||||
memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry),
|
||||
filename,
|
||||
strlen(filename) + 1);
|
||||
|
||||
db_data.dsize = 2*sizeof(share_mode_entry) + strlen(filename) + 1;
|
||||
db_data.dsize = 2*sizeof(struct share_mode_entry) + strlen(filename) + 1;
|
||||
if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) {
|
||||
free(db_data.dptr);
|
||||
return -1;
|
||||
@ -268,7 +279,7 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
}
|
||||
|
||||
/* Entry exists, we must add a new entry. */
|
||||
new_data_p = malloc(db_data.dsize + sizeof(share_mode_entry));
|
||||
new_data_p = malloc(db_data.dsize + sizeof(struct share_mode_entry));
|
||||
if (!new_data_p) {
|
||||
free(db_data.dptr);
|
||||
return -1;
|
||||
@ -278,11 +289,11 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
orig_num_share_modes = ld->u.s.num_share_mode_entries;
|
||||
|
||||
/* Copy the original data. */
|
||||
memcpy(new_data_p, db_data.dptr, (orig_num_share_modes+1)*sizeof(share_mode_entry));
|
||||
memcpy(new_data_p, db_data.dptr, (orig_num_share_modes+1)*sizeof(struct share_mode_entry));
|
||||
|
||||
/* Add in the new share mode */
|
||||
shares = (share_mode_entry *)(new_data_p +
|
||||
((orig_num_share_modes+1)*sizeof(share_mode_entry)));
|
||||
shares = (struct share_mode_entry *)(new_data_p +
|
||||
((orig_num_share_modes+1)*sizeof(struct share_mode_entry)));
|
||||
|
||||
create_share_mode_entry(shares, new_entry);
|
||||
|
||||
@ -290,11 +301,11 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
ld->u.s.num_share_mode_entries++;
|
||||
|
||||
/* Append the original filename */
|
||||
memcpy(new_data_p + ((ld->u.s.num_share_mode_entries+1)*sizeof(share_mode_entry)),
|
||||
db_data.dptr + ((orig_num_share_modes+1)*sizeof(share_mode_entry)),
|
||||
db_data.dsize - ((orig_num_share_modes+1) * sizeof(share_mode_entry)));
|
||||
memcpy(new_data_p + ((ld->u.s.num_share_mode_entries+1)*sizeof(struct share_mode_entry)),
|
||||
db_data.dptr + ((orig_num_share_modes+1)*sizeof(struct share_mode_entry)),
|
||||
db_data.dsize - ((orig_num_share_modes+1) * sizeof(struct share_mode_entry)));
|
||||
|
||||
new_data_size = db_data.dsize + sizeof(share_mode_entry);
|
||||
new_data_size = db_data.dsize + sizeof(struct share_mode_entry);
|
||||
|
||||
free(db_data.dptr);
|
||||
|
||||
@ -318,7 +329,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
TDB_DATA locking_key = get_locking_key(dev, ino);
|
||||
int orig_num_share_modes = 0;
|
||||
struct locking_data *ld = NULL; /* internal samba db state. */
|
||||
share_mode_entry *shares = NULL;
|
||||
struct share_mode_entry *shares = NULL;
|
||||
char *new_data_p = NULL;
|
||||
size_t filename_size = 0;
|
||||
size_t i, num_share_modes;
|
||||
@ -331,7 +342,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
|
||||
ld = (struct locking_data *)db_data.dptr;
|
||||
orig_num_share_modes = ld->u.s.num_share_mode_entries;
|
||||
shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry));
|
||||
shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
|
||||
|
||||
if (orig_num_share_modes == 1) {
|
||||
/* Only one entry - better be ours... */
|
||||
@ -346,22 +357,22 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
}
|
||||
|
||||
/* More than one - allocate a new record minus the one we'll delete. */
|
||||
new_data_p = malloc(db_data.dsize - sizeof(share_mode_entry));
|
||||
new_data_p = malloc(db_data.dsize - sizeof(struct share_mode_entry));
|
||||
if (!new_data_p) {
|
||||
free(db_data.dptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy the header. */
|
||||
memcpy(new_data_p, db_data.dptr, sizeof(share_mode_entry));
|
||||
memcpy(new_data_p, db_data.dptr, sizeof(struct share_mode_entry));
|
||||
|
||||
num_share_modes = 0;
|
||||
for (i = 0; i < orig_num_share_modes; i++) {
|
||||
share_mode_entry *share = &shares[i];
|
||||
pid_t pid = share->pid;
|
||||
struct share_mode_entry *share = &shares[i];
|
||||
struct process_id pid = share->pid;
|
||||
|
||||
/* Check this process really exists. */
|
||||
if (kill(pid, 0) == -1 && (errno == ESRCH)) {
|
||||
if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) {
|
||||
continue; /* No longer exists. */
|
||||
}
|
||||
|
||||
@ -369,8 +380,8 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
continue; /* This is our delete taget. */
|
||||
}
|
||||
|
||||
memcpy(new_data_p + ((num_share_modes+1)*sizeof(share_mode_entry)),
|
||||
share, sizeof(share_mode_entry) );
|
||||
memcpy(new_data_p + ((num_share_modes+1)*sizeof(struct share_mode_entry)),
|
||||
share, sizeof(struct share_mode_entry) );
|
||||
|
||||
num_share_modes++;
|
||||
}
|
||||
@ -383,10 +394,10 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
}
|
||||
|
||||
/* Copy the terminating filename. */
|
||||
fname_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(share_mode_entry));
|
||||
fname_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(struct share_mode_entry));
|
||||
filename_size = db_data.dsize - (fname_ptr - db_data.dptr);
|
||||
|
||||
memcpy(new_data_p + ((num_share_modes+1)*sizeof(share_mode_entry)),
|
||||
memcpy(new_data_p + ((num_share_modes+1)*sizeof(struct share_mode_entry)),
|
||||
fname_ptr,
|
||||
filename_size);
|
||||
|
||||
@ -398,7 +409,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
ld = (struct locking_data *)db_data.dptr;
|
||||
ld->u.s.num_share_mode_entries = num_share_modes;
|
||||
|
||||
db_data.dsize = ((num_share_modes+1)*sizeof(share_mode_entry)) + filename_size;
|
||||
db_data.dsize = ((num_share_modes+1)*sizeof(struct share_mode_entry)) + filename_size;
|
||||
|
||||
if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) {
|
||||
free(db_data.dptr);
|
||||
@ -418,7 +429,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
TDB_DATA locking_key = get_locking_key(dev, ino);
|
||||
int num_share_modes = 0;
|
||||
struct locking_data *ld = NULL; /* internal samba db state. */
|
||||
share_mode_entry *shares = NULL;
|
||||
struct share_mode_entry *shares = NULL;
|
||||
size_t i;
|
||||
int found_entry = 0;
|
||||
|
||||
@ -429,14 +440,14 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
|
||||
|
||||
ld = (struct locking_data *)db_data.dptr;
|
||||
num_share_modes = ld->u.s.num_share_mode_entries;
|
||||
shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry));
|
||||
shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
|
||||
|
||||
for (i = 0; i < num_share_modes; i++) {
|
||||
share_mode_entry *share = &shares[i];
|
||||
pid_t pid = share->pid;
|
||||
struct share_mode_entry *share = &shares[i];
|
||||
struct process_id pid = share->pid;
|
||||
|
||||
/* Check this process really exists. */
|
||||
if (kill(pid, 0) == -1 && (errno == ESRCH)) {
|
||||
if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) {
|
||||
continue; /* No longer exists. */
|
||||
}
|
||||
|
||||
|
@ -357,78 +357,24 @@ void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key,
|
||||
des_crypt56(out + 8, in + 8, key2, forw);
|
||||
}
|
||||
|
||||
void SamOEMhash( unsigned char *data, const unsigned char *key, int val)
|
||||
/*****************************************************************
|
||||
arc4 crypt/decrypt with a 16 byte key.
|
||||
*****************************************************************/
|
||||
|
||||
void SamOEMhash( unsigned char *data, const unsigned char key[16], size_t len)
|
||||
{
|
||||
unsigned char s_box[256];
|
||||
unsigned char index_i = 0;
|
||||
unsigned char index_j = 0;
|
||||
unsigned char j = 0;
|
||||
int ind;
|
||||
unsigned char arc4_state[258];
|
||||
|
||||
for (ind = 0; ind < 256; ind++) {
|
||||
s_box[ind] = (unsigned char)ind;
|
||||
smb_arc4_init(arc4_state, key, 16);
|
||||
smb_arc4_crypt(arc4_state, data, len);
|
||||
}
|
||||
|
||||
for( ind = 0; ind < 256; ind++) {
|
||||
unsigned char tc;
|
||||
|
||||
j += (s_box[ind] + key[ind%16]);
|
||||
|
||||
tc = s_box[ind];
|
||||
s_box[ind] = s_box[j];
|
||||
s_box[j] = tc;
|
||||
}
|
||||
for( ind = 0; ind < val; ind++) {
|
||||
unsigned char tc;
|
||||
unsigned char t;
|
||||
|
||||
index_i++;
|
||||
index_j += s_box[index_i];
|
||||
|
||||
tc = s_box[index_i];
|
||||
s_box[index_i] = s_box[index_j];
|
||||
s_box[index_j] = tc;
|
||||
|
||||
t = s_box[index_i] + s_box[index_j];
|
||||
data[ind] = data[ind] ^ s_box[t];
|
||||
}
|
||||
}
|
||||
|
||||
void SamOEMhashBlob( unsigned char *data, int len, DATA_BLOB *key)
|
||||
void SamOEMhashBlob( unsigned char *data, size_t len, DATA_BLOB *key)
|
||||
{
|
||||
unsigned char s_box[256];
|
||||
unsigned char index_i = 0;
|
||||
unsigned char index_j = 0;
|
||||
unsigned char j = 0;
|
||||
int ind;
|
||||
unsigned char arc4_state[258];
|
||||
|
||||
for (ind = 0; ind < 256; ind++) {
|
||||
s_box[ind] = (unsigned char)ind;
|
||||
}
|
||||
|
||||
for( ind = 0; ind < 256; ind++) {
|
||||
unsigned char tc;
|
||||
|
||||
j += (s_box[ind] + key->data[ind%key->length]);
|
||||
|
||||
tc = s_box[ind];
|
||||
s_box[ind] = s_box[j];
|
||||
s_box[j] = tc;
|
||||
}
|
||||
for( ind = 0; ind < len; ind++) {
|
||||
unsigned char tc;
|
||||
unsigned char t;
|
||||
|
||||
index_i++;
|
||||
index_j += s_box[index_i];
|
||||
|
||||
tc = s_box[index_i];
|
||||
s_box[index_i] = s_box[index_j];
|
||||
s_box[index_j] = tc;
|
||||
|
||||
t = s_box[index_i] + s_box[index_j];
|
||||
data[ind] = data[ind] ^ s_box[t];
|
||||
}
|
||||
smb_arc4_init(arc4_state, key->data, key->length);
|
||||
smb_arc4_crypt(arc4_state, data, len);
|
||||
}
|
||||
|
||||
/* Decode a sam password hash into a password. The password hash is the
|
||||
|
@ -308,32 +308,6 @@ void SMBsesskeygen_ntv1(const uchar kr[16],
|
||||
#endif
|
||||
}
|
||||
|
||||
void SMBsesskeygen_lmv1(const uchar lm_hash[16],
|
||||
const uchar lm_resp[24], /* only uses 8 */
|
||||
uint8 sess_key[16])
|
||||
{
|
||||
/* Calculate the LM session key (effective length 40 bits,
|
||||
but changes with each session) */
|
||||
|
||||
uchar p24[24];
|
||||
uchar partial_lm_hash[16];
|
||||
|
||||
memcpy(partial_lm_hash, lm_hash, 8);
|
||||
memset(partial_lm_hash + 8, 0xbd, 8);
|
||||
|
||||
SMBOWFencrypt(lm_hash, lm_resp, p24);
|
||||
|
||||
memcpy(sess_key, p24, 16);
|
||||
sess_key[5] = 0xe5;
|
||||
sess_key[6] = 0x38;
|
||||
sess_key[7] = 0xb0;
|
||||
|
||||
#ifdef DEBUG_PASSWORD
|
||||
DEBUG(100, ("SMBsesskeygen_lmv1:\n"));
|
||||
dump_data(100, sess_key, 16);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16],
|
||||
const uchar lm_resp[24], /* only uses 8 */
|
||||
uint8 sess_key[16])
|
||||
@ -485,7 +459,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password
|
||||
encode a password buffer with a unicode password. The buffer
|
||||
is filled with random data to make it harder to attack.
|
||||
************************************************************/
|
||||
BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags)
|
||||
BOOL encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags)
|
||||
{
|
||||
uchar new_pw[512];
|
||||
size_t new_pw_len;
|
||||
@ -496,7 +470,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags)
|
||||
|
||||
memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len);
|
||||
|
||||
generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len);
|
||||
generate_random_buffer(buffer, 512 - new_pw_len);
|
||||
|
||||
/*
|
||||
* The length of the new password is in the last 4 bytes of
|
||||
|
@ -75,6 +75,7 @@ err_code_struct dos_msgs[] = {
|
||||
{"ERRlogonfailure",ERRlogonfailure,"Logon failure"},
|
||||
{"ERRdiskfull",ERRdiskfull,"Disk full"},
|
||||
{"ERRgeneral",ERRgeneral, "General failure"},
|
||||
{"ERRbaddirectory", ERRbaddirectory, "Bad directory name"},
|
||||
{"ERRunknownlevel",ERRunknownlevel, "Unknown info level"},
|
||||
{NULL,-1,NULL}};
|
||||
|
||||
|
@ -42,11 +42,11 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
|
||||
asn1_start_tag(asn1, ASN1_CONTEXT(0));
|
||||
asn1_start_tag(asn1, ASN1_SEQUENCE(0));
|
||||
|
||||
token->mechTypes = SMB_MALLOC_P(char *);
|
||||
token->mechTypes = SMB_MALLOC_P(const char *);
|
||||
for (i = 0; !asn1->has_error &&
|
||||
0 < asn1_tag_remaining(asn1); i++) {
|
||||
token->mechTypes =
|
||||
SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2);
|
||||
SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2);
|
||||
asn1_read_OID(asn1, &token->mechTypes[i]);
|
||||
}
|
||||
token->mechTypes[i] = NULL;
|
||||
|
@ -29,22 +29,36 @@
|
||||
Caller must have the cli connected to the netlogon pipe
|
||||
already.
|
||||
**********************************************************/
|
||||
static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
|
||||
static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
|
||||
unsigned char orig_trust_passwd_hash[16],
|
||||
unsigned char new_trust_passwd_hash[16],
|
||||
uint32 sec_channel_type)
|
||||
{
|
||||
NTSTATUS result;
|
||||
|
||||
/* ensure that schannel uses the right domain */
|
||||
fstrcpy(cli->domain, lp_workgroup());
|
||||
if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, sec_channel_type, orig_trust_passwd_hash))) {
|
||||
/* Check if the netlogon pipe is open using schannel. If so we
|
||||
already have valid creds. If not we must set them up. */
|
||||
|
||||
if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
|
||||
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
|
||||
|
||||
result = rpccli_netlogon_setup_creds(cli,
|
||||
cli->cli->desthost,
|
||||
lp_workgroup(),
|
||||
global_myname(),
|
||||
orig_trust_passwd_hash,
|
||||
sec_channel_type,
|
||||
&neg_flags);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
|
||||
nt_errstr(result)));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
|
||||
result = rpccli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
|
||||
@ -59,7 +73,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_
|
||||
Caller must have already setup the connection to the NETLOGON pipe
|
||||
**********************************************************/
|
||||
|
||||
NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
|
||||
const char *domain,
|
||||
unsigned char orig_trust_passwd_hash[16],
|
||||
uint32 sec_channel_type)
|
||||
@ -99,7 +113,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx
|
||||
already setup the connection to the NETLOGON pipe
|
||||
**********************************************************/
|
||||
|
||||
NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli,
|
||||
NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *domain)
|
||||
{
|
||||
@ -116,7 +130,6 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli,
|
||||
return trust_pw_change_and_store_it(cli, mem_ctx, domain,
|
||||
old_trust_passwd_hash,
|
||||
sec_channel_type);
|
||||
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
@ -133,6 +146,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
|
||||
struct in_addr dc_ip;
|
||||
uint32 enum_ctx = 0;
|
||||
struct cli_state *cli = NULL;
|
||||
struct rpc_pipe_client *lsa_pipe;
|
||||
BOOL retry;
|
||||
|
||||
*domain_names = NULL;
|
||||
@ -156,21 +170,21 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
|
||||
|
||||
/* open the LSARPC_PIPE */
|
||||
|
||||
if ( !cli_nt_session_open( cli, PI_LSARPC ) ) {
|
||||
result = NT_STATUS_UNSUCCESSFUL;
|
||||
lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result );
|
||||
if ( !lsa_pipe) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* get a handle */
|
||||
|
||||
result = cli_lsa_open_policy(cli, mem_ctx, True,
|
||||
result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True,
|
||||
POLICY_VIEW_LOCAL_INFORMATION, &pol);
|
||||
if ( !NT_STATUS_IS_OK(result) )
|
||||
goto done;
|
||||
|
||||
/* Lookup list of trusted domains */
|
||||
|
||||
result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
|
||||
result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx,
|
||||
num_domains, domain_names, sids);
|
||||
if ( !NT_STATUS_IS_OK(result) )
|
||||
goto done;
|
||||
@ -184,4 +198,3 @@ done:
|
||||
|
||||
return NT_STATUS_IS_OK(result);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
struct lock_context {
|
||||
uint16 smbpid;
|
||||
uint16 tid;
|
||||
pid_t pid;
|
||||
struct process_id pid;
|
||||
};
|
||||
|
||||
/* The data in brlock records is an unsorted linear array of these
|
||||
@ -89,9 +89,9 @@ static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
|
||||
static BOOL brl_same_context(struct lock_context *ctx1,
|
||||
struct lock_context *ctx2)
|
||||
{
|
||||
return (ctx1->pid == ctx2->pid) &&
|
||||
return (procid_equal(&ctx1->pid, &ctx2->pid) &&
|
||||
(ctx1->smbpid == ctx2->smbpid) &&
|
||||
(ctx1->tid == ctx2->tid);
|
||||
(ctx1->tid == ctx2->tid));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -252,7 +252,7 @@ static int delete_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *stat
|
||||
DEBUG(0,("brlock : delete_fn. LOGIC ERROR ! Shutting down and a record for my pid (%u) exists !\n",
|
||||
(unsigned int)lock->context.pid ));
|
||||
|
||||
} else if (process_exists(lock->context.pid)) {
|
||||
} else if (process_exists(&lock->context.pid)) {
|
||||
|
||||
DEBUG(10,("brlock : delete_fn. pid %u exists.\n", (unsigned int)lock->context.pid ));
|
||||
continue;
|
||||
@ -347,7 +347,7 @@ static int lock_compare(struct lock_struct *lck1,
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
|
||||
uint16 smbpid, pid_t pid, uint16 tid,
|
||||
uint16 smbpid, struct process_id pid, uint16 tid,
|
||||
br_off start, br_off size,
|
||||
enum brl_type lock_type, BOOL *my_lock_ctx)
|
||||
{
|
||||
@ -450,7 +450,7 @@ static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pe
|
||||
****************************************************************************/
|
||||
|
||||
BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
|
||||
uint16 smbpid, pid_t pid, uint16 tid,
|
||||
uint16 smbpid, struct process_id pid, uint16 tid,
|
||||
br_off start, br_off size,
|
||||
BOOL remove_pending_locks_only,
|
||||
void (*pre_unlock_fn)(void *),
|
||||
@ -542,8 +542,8 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
|
||||
|
||||
/* We could send specific lock info here... */
|
||||
if (brl_pending_overlap(lock, pend_lock)) {
|
||||
DEBUG(10,("brl_unlock: sending unlock message to pid %u\n",
|
||||
(unsigned int)pend_lock->context.pid ));
|
||||
DEBUG(10,("brl_unlock: sending unlock message to pid %s\n",
|
||||
procid_str_static(&pend_lock->context.pid )));
|
||||
|
||||
message_send_pid(pend_lock->context.pid,
|
||||
MSG_SMB_UNLOCK,
|
||||
@ -584,7 +584,7 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
|
||||
****************************************************************************/
|
||||
|
||||
BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
|
||||
uint16 smbpid, pid_t pid, uint16 tid,
|
||||
uint16 smbpid, struct process_id pid, uint16 tid,
|
||||
br_off start, br_off size,
|
||||
enum brl_type lock_type)
|
||||
{
|
||||
@ -632,7 +632,7 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
|
||||
Remove any locks associated with a open file.
|
||||
****************************************************************************/
|
||||
|
||||
void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
|
||||
void brl_close(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, int tid, int fnum)
|
||||
{
|
||||
TDB_DATA kbuf, dbuf;
|
||||
int count, i, j, dcount=0;
|
||||
@ -655,7 +655,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
|
||||
struct lock_struct *lock = &locks[i];
|
||||
|
||||
if (lock->context.tid == tid &&
|
||||
lock->context.pid == pid &&
|
||||
procid_equal(&lock->context.pid, &pid) &&
|
||||
lock->fnum == fnum) {
|
||||
|
||||
/* Send unlock messages to any pending waiters that overlap. */
|
||||
@ -667,7 +667,7 @@ void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum)
|
||||
continue;
|
||||
|
||||
if (pend_lock->context.tid == tid &&
|
||||
pend_lock->context.pid == pid &&
|
||||
procid_equal(&pend_lock->context.pid, &pid) &&
|
||||
pend_lock->fnum == fnum)
|
||||
continue;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@
|
||||
|
||||
static struct {
|
||||
char from;
|
||||
char *to;
|
||||
const char *to;
|
||||
int len;
|
||||
} weird_table[] = {
|
||||
{'q', "^q^", 3},
|
||||
|
@ -201,7 +201,7 @@ void run_dns_queue(void)
|
||||
/* Allow SIGTERM to kill us. */
|
||||
BlockSignals(False, SIGTERM);
|
||||
|
||||
if (!process_exists(child_pid)) {
|
||||
if (!process_exists_by_pid(child_pid)) {
|
||||
close(fd_in);
|
||||
start_async_dns();
|
||||
}
|
||||
|
@ -76,7 +76,8 @@ static void terminate(void)
|
||||
Handle a SHUTDOWN message from smbcontrol.
|
||||
**************************************************************************** */
|
||||
|
||||
static void nmbd_terminate(int msg_type, pid_t src, void *buf, size_t len)
|
||||
static void nmbd_terminate(int msg_type, struct process_id src,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
terminate();
|
||||
}
|
||||
@ -307,7 +308,8 @@ static BOOL reload_nmbd_services(BOOL test)
|
||||
* detects that there are no subnets.
|
||||
**************************************************************************** */
|
||||
|
||||
static void msg_reload_nmbd_services(int msg_type, pid_t src, void *buf, size_t len)
|
||||
static void msg_reload_nmbd_services(int msg_type, struct process_id src,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
write_browse_list( 0, True );
|
||||
dump_all_namelists();
|
||||
@ -323,31 +325,33 @@ static void msg_reload_nmbd_services(int msg_type, pid_t src, void *buf, size_t
|
||||
}
|
||||
}
|
||||
|
||||
static void msg_nmbd_send_packet(int msg_type, pid_t src,
|
||||
static void msg_nmbd_send_packet(int msg_type, struct process_id src,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
struct packet_struct *p = (struct packet_struct *)buf;
|
||||
struct subnet_record *subrec;
|
||||
struct in_addr *local_ip;
|
||||
|
||||
DEBUG(10, ("Received send_packet from %d\n", src));
|
||||
DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));
|
||||
|
||||
if (len != sizeof(struct packet_struct)) {
|
||||
DEBUG(2, ("Discarding invalid packet length from %d\n", src));
|
||||
DEBUG(2, ("Discarding invalid packet length from %d\n",
|
||||
procid_to_pid(&src)));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((p->packet_type != NMB_PACKET) &&
|
||||
(p->packet_type != DGRAM_PACKET)) {
|
||||
DEBUG(2, ("Discarding invalid packet type from %d: %d\n",
|
||||
src, p->packet_type));
|
||||
procid_to_pid(&src), p->packet_type));
|
||||
return;
|
||||
}
|
||||
|
||||
local_ip = iface_ip(p->ip);
|
||||
|
||||
if (local_ip == NULL) {
|
||||
DEBUG(2, ("Could not find ip for packet from %d\n", src));
|
||||
DEBUG(2, ("Could not find ip for packet from %d\n",
|
||||
procid_to_pid(&src)));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -590,7 +594,8 @@ static void process(void)
|
||||
|
||||
if(reload_after_sighup) {
|
||||
DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
|
||||
msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED, (pid_t) 0, (void*) &no_subnets, 0);
|
||||
msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED,
|
||||
pid_to_procid(0), (void*) &no_subnets, 0);
|
||||
if(no_subnets)
|
||||
return;
|
||||
reload_after_sighup = 0;
|
||||
|
@ -374,7 +374,8 @@ yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
|
||||
Process a internal Samba message forcing an election.
|
||||
***************************************************************************/
|
||||
|
||||
void nmbd_message_election(int msg_type, pid_t src, void *buf, size_t len)
|
||||
void nmbd_message_election(int msg_type, struct process_id src,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
struct subnet_record *subrec;
|
||||
|
||||
|
@ -1246,7 +1246,7 @@ packet sent to name %s from IP %s\n",
|
||||
packet sent to name %s from IP %s\n",
|
||||
dgram->datasize,
|
||||
len,
|
||||
PTR_DIFF(buf2, dgram->data),
|
||||
(int)PTR_DIFF(buf2, dgram->data),
|
||||
nmb_namestr(&dgram->dest_name),
|
||||
inet_ntoa(p->ip) ));
|
||||
return;
|
||||
@ -1257,7 +1257,7 @@ packet sent to name %s from IP %s\n",
|
||||
packet sent to name %s from IP %s\n",
|
||||
dgram->datasize,
|
||||
len,
|
||||
PTR_DIFF(buf2, dgram->data),
|
||||
(int)PTR_DIFF(buf2, dgram->data),
|
||||
nmb_namestr(&dgram->dest_name),
|
||||
inet_ntoa(p->ip) ));
|
||||
return;
|
||||
|
@ -294,7 +294,7 @@ void sync_check_completion(void)
|
||||
|
||||
for (s=syncs;s;s=next) {
|
||||
next = s->next;
|
||||
if (!process_exists(s->pid)) {
|
||||
if (!process_exists_by_pid(s->pid)) {
|
||||
/* it has completed - grab the info */
|
||||
complete_sync(s);
|
||||
DLIST_REMOVE(syncs, s);
|
||||
|
@ -1874,7 +1874,8 @@ void wins_write_database(BOOL background)
|
||||
Process a internal Samba message receiving a wins record.
|
||||
***************************************************************************/
|
||||
|
||||
void nmbd_wins_new_entry(int msg_type, pid_t src, void *buf, size_t len)
|
||||
void nmbd_wins_new_entry(int msg_type, struct process_id src,
|
||||
void *buf, size_t len)
|
||||
{
|
||||
WINS_RECORD *record;
|
||||
struct name_record *namerec = NULL;
|
||||
|
@ -544,6 +544,11 @@ NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
if ((request->extra_len != 0) &&
|
||||
(write_sock(request->extra_data, request->extra_len, request->flags & WBFLAG_RECURSE) == -1)) {
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user