1
0
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:
Gerald Carter 2005-09-30 17:13:37 +00:00 committed by Gerald (Jerry) Carter
parent 4a2cc231d2
commit 54abd2aa66
261 changed files with 20729 additions and 15930 deletions

View File

@ -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 ) )

View File

@ -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)
@ -256,13 +256,13 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
rpc_client/cli_reg.o $(RPC_CLIENT_OBJ) \
rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \
rpc_client/cli_ds.o rpc_client/cli_echo.o \
rpc_client/cli_shutdown.o rpc_client/cli_svcctl.o
rpc_client/cli_shutdown.o rpc_client/cli_svcctl.o
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,8 +418,7 @@ 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)
PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o $(PRINTBASE_OBJ)
SMBD_OBJ = $(SMBD_OBJ_BASE) $(SMBD_OBJ_MAIN)
NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
@ -432,7 +435,7 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
WREPL_OBJ1 = wrepld/server.o wrepld/process.o wrepld/parser.o wrepld/socket.o \
wrepld/partners.o
@ -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 \

View File

@ -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"));

View File

@ -40,15 +40,17 @@ 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,
struct in_addr dc_ip,
const char *setup_creds_as,
uint16 sec_chan,
const unsigned char *trust_passwd,
BOOL *retry)
static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
const char *domain,
const char *dc_name,
struct in_addr dc_ip,
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;
}
@ -135,18 +167,17 @@ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
************************************************************************/
static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
const auth_usersupplied_info *user_info,
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 auth_usersupplied_info *user_info,
const char *domain,
uchar chal[8],
auth_serversupplied_info **server_info,
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);
/* let go as soon as possible so we avoid any potential deadlocks
with winbind lookup up users or groups */
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. */
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;
}

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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=""
@ -359,9 +360,9 @@ if test "$ac_cv_prog_gnu_ld" = "yes"; then
changequote([,])dnl
AC_MSG_RESULT(${ac_cv_gnu_ld_date})
if test -n "$ac_cv_gnu_ld_date"; then
if test "$ac_cv_gnu_ld_date" -lt 20030217; then
ac_cv_gnu_ld_no_default_allow_shlib_undefined=yes
fi
if test "$ac_cv_gnu_ld_date" -lt 20030217; then
ac_cv_gnu_ld_no_default_allow_shlib_undefined=yes
fi
else
AC_MSG_CHECKING(GNU ld release version)
changequote(,)dnl
@ -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"
@ -1990,14 +1991,14 @@ dnl For IA64 HPUX systems, the libs are located in lib/hpux32 instead of lib.
for l in "lib32" "lib" "lib/hpux32"; do
if test -d "$i/$l" ; then
LDFLAGS="$save_LDFLAGS -L$i/$l"
LIBS=
export LDFLAGS LIBS CPPFLAGS
LIBS=
export LDFLAGS LIBS CPPFLAGS
dnl Try to find iconv(3)
jm_ICONV($i/$l)
if test x"$ICONV_FOUND" = "xyes" ; then
libext="$l"
break;
fi
libext="$l"
break;
fi
fi
done
@ -2005,7 +2006,7 @@ dnl Try to find iconv(3)
LDFLAGS=$save_LDFLAGS
LIB_ADD_DIR(LDFLAGS, "$i/$libext")
CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
LIBS="$save_LIBS"
LIBS="$save_LIBS"
ICONV_LOCATION=$i
export LDFLAGS LIBS CPPFLAGS
dnl Now, check for a working iconv ... we want to do it here because
@ -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=
@ -3925,19 +4018,19 @@ AC_MSG_CHECKING(whether to build the libsmbsharemodes shared library)
AC_ARG_WITH(libsmbsharemodes,
[ --with-libsmbsharemodes Build the libsmbsharemodes shared library (default=yes if shared libs supported)],
[ case "$withval" in
no)
no)
AC_MSG_RESULT(no)
;;
*)
if test $BLDSHARED = true; then
INSTALLCLIENTCMD_SH="\$(INSTALLCMD)"
## build the static version of libsmbsharemodes as well
INSTALLCLIENTCMD_A="\$(INSTALLCMD)"
## build the static version of libsmbsharemodes as well
INSTALLCLIENTCMD_A="\$(INSTALLCMD)"
LIBSMBSHAREMODES_SHARED=bin/libsmbsharemodes.$SHLIBEXT
LIBSMBSHAREMODES=libsmbsharemodes
AC_MSG_RESULT(yes)
else
enable_static=yes
enable_static=yes
AC_MSG_RESULT(no shared library support -- will supply static library)
fi
if test $enable_static = yes; then
@ -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)

View File

@ -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.
****************************************************************************/
@ -988,8 +987,8 @@ int smb_create_group(char *unix_group, gid_t *new_gid)
close(fd);
}
}
}
if (*new_gid == 0) {
struct group *grp = getgrnam(unix_group);
@ -1018,7 +1017,7 @@ int smb_delete_group(char *unix_group)
DEBUG(ret ? 0 : 3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
return ret;
}
return -1;
}
@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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) \
{ \

View File

@ -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 */

View File

@ -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);

View File

@ -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

View File

@ -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 */

View File

@ -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,14 +242,13 @@ 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;
/*
* Set to true when an RPC bind has been done on this pipe.
*/
@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -22,36 +22,68 @@
#define _RPC_CLIENT_H
/* 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) ) {\
if (!r_io_fn("", &r_out, &r_ps, 0)) {\
r_out.status = default_error;\
}\
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)) {\
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) ) {\
if (!r_io_fn("", &r_out, &r_ps, 0)) {\
r_out.status = default_error;\
}\
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)) {\
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 );\

View File

@ -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 */

View File

@ -34,164 +34,131 @@
#define DFSFLAG_ADD_VOLUME 0x00000001
#define DFSFLAG_RESTORE_VOLUME 0x00000002
typedef struct dfs_q_dfs_exist
{
uint32 dummy;
}
DFS_Q_DFS_EXIST;
typedef struct dfs_q_dfs_exist {
uint32 dummy;
} 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
{
uint32 ptr_DfsEntryPath;
UNISTR2 DfsEntryPath;
uint32 ptr_ServerName;
UNISTR2 ServerName;
uint32 ptr_ShareName;
UNISTR2 ShareName;
uint32 ptr_Comment;
UNISTR2 Comment;
uint32 Flags;
}
DFS_Q_DFS_ADD;
typedef struct dfs_q_dfs_add {
uint32 ptr_DfsEntryPath;
UNISTR2 DfsEntryPath;
uint32 ptr_ServerName;
UNISTR2 ServerName;
uint32 ptr_ShareName;
UNISTR2 ShareName;
uint32 ptr_Comment;
UNISTR2 Comment;
uint32 Flags;
} DFS_Q_DFS_ADD;
typedef struct dfs_r_dfs_add
{
WERROR status;
}
DFS_R_DFS_ADD;
typedef struct dfs_r_dfs_add {
WERROR status;
} DFS_R_DFS_ADD;
/********************************************/
typedef struct dfs_q_dfs_remove
{
UNISTR2 DfsEntryPath;
uint32 ptr_ServerName;
UNISTR2 ServerName;
uint32 ptr_ShareName;
UNISTR2 ShareName;
}
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;
typedef struct dfs_r_dfs_remove
{
WERROR status;
}
DFS_R_DFS_REMOVE;
typedef struct dfs_r_dfs_remove {
WERROR status;
} DFS_R_DFS_REMOVE;
/********************************************/
typedef struct dfs_info_1
{
uint32 ptr_entrypath;
UNISTR2 entrypath;
}
DFS_INFO_1;
typedef struct dfs_info_1 {
uint32 ptr_entrypath;
UNISTR2 entrypath;
} DFS_INFO_1;
typedef struct dfs_info_2
{
uint32 ptr_entrypath;
UNISTR2 entrypath;
uint32 ptr_comment;
UNISTR2 comment;
uint32 state;
uint32 num_storages;
}
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;
typedef struct dfs_storage_info
{
uint32 state;
uint32 ptr_servername;
UNISTR2 servername;
uint32 ptr_sharename;
UNISTR2 sharename;
}
DFS_STORAGE_INFO;
typedef struct dfs_storage_info {
uint32 state;
uint32 ptr_servername;
UNISTR2 servername;
uint32 ptr_sharename;
UNISTR2 sharename;
} DFS_STORAGE_INFO;
typedef struct dfs_info_3
{
uint32 ptr_entrypath;
UNISTR2 entrypath;
uint32 ptr_comment;
UNISTR2 comment;
uint32 state;
uint32 num_storages;
uint32 ptr_storages;
uint32 num_storage_infos;
DFS_STORAGE_INFO* storages;
}
DFS_INFO_3;
typedef struct dfs_info_3 {
uint32 ptr_entrypath;
UNISTR2 entrypath;
uint32 ptr_comment;
UNISTR2 comment;
uint32 state;
uint32 num_storages;
uint32 ptr_storages;
uint32 num_storage_infos;
DFS_STORAGE_INFO* storages;
} DFS_INFO_3;
typedef struct dfs_info_ctr
{
typedef struct dfs_info_ctr {
uint32 switch_value;
uint32 num_entries;
uint32 ptr_dfs_ctr; /* pointer to dfs info union */
union {
DFS_INFO_1 *info1;
DFS_INFO_2 *info2;
DFS_INFO_3 *info3;
} dfs;
} DFS_INFO_CTR;
typedef struct dfs_q_dfs_get_info {
UNISTR2 uni_path;
uint32 switch_value;
uint32 num_entries;
uint32 ptr_dfs_ctr; /* pointer to dfs info union */
union
{
DFS_INFO_1 *info1;
DFS_INFO_2 *info2;
DFS_INFO_3 *info3;
} dfs;
}
DFS_INFO_CTR;
uint32 ptr_server;
UNISTR2 uni_server;
typedef struct dfs_q_dfs_get_info
{
UNISTR2 uni_path;
uint32 ptr_share;
UNISTR2 uni_share;
uint32 ptr_server;
UNISTR2 uni_server;
uint32 level;
} DFS_Q_DFS_GET_INFO;
uint32 ptr_share;
UNISTR2 uni_share;
uint32 level;
}
DFS_Q_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;
typedef struct dfs_r_dfs_get_info
{
uint32 level;
uint32 ptr_ctr;
DFS_INFO_CTR ctr;
WERROR status;
}
DFS_R_DFS_GET_INFO;
typedef struct dfs_q_dfs_enum
{
uint32 level;
uint32 maxpreflen;
uint32 ptr_buffer;
uint32 level2;
uint32 ptr_num_entries;
uint32 num_entries;
uint32 ptr_num_entries2;
uint32 num_entries2;
ENUM_HND reshnd;
}
DFS_Q_DFS_ENUM;
typedef struct dfs_r_dfs_enum
{
DFS_INFO_CTR *ctr;
uint32 ptr_buffer;
uint32 level;
uint32 level2;
uint32 ptr_num_entries;
uint32 num_entries;
uint32 ptr_num_entries2;
uint32 num_entries2;
ENUM_HND reshnd;
WERROR status;
}
DFS_R_DFS_ENUM;
typedef struct dfs_q_dfs_enum {
uint32 level;
uint32 maxpreflen;
uint32 ptr_buffer;
uint32 level2;
uint32 ptr_num_entries;
uint32 num_entries;
uint32 ptr_num_entries2;
uint32 num_entries2;
ENUM_HND reshnd;
} DFS_Q_DFS_ENUM;
typedef struct dfs_r_dfs_enum {
DFS_INFO_CTR *ctr;
uint32 ptr_buffer;
uint32 level;
uint32 level2;
uint32 ptr_num_entries;
uint32 num_entries;
uint32 ptr_num_entries2;
uint32 num_entries2;
ENUM_HND reshnd;
WERROR status;
} DFS_R_DFS_ENUM;
#endif

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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
{
uint32 neg_flags; /* negotiated flags */
typedef struct neg_flags_info {
uint32 neg_flags; /* negotiated flags */
} NEG_FLAGS;
/* NET_Q_REQ_CHAL */
typedef struct net_q_req_chal_info
{
uint32 undoc_buffer; /* undocumented buffer pointer */
UNISTR2 uni_logon_srv; /* logon server unicode string */
UNISTR2 uni_logon_clnt; /* logon client unicode string */
DOM_CHAL clnt_chal; /* client challenge */
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
{
DOM_LOG_INFO clnt_id; /* client identification info */
DOM_CHAL clnt_chal; /* client-calculated credentials */
NEG_FLAGS clnt_flgs; /* usually 0x0000 01ff */
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
{
DOM_LOG_INFO clnt_id; /* client identification info */
DOM_CHAL clnt_chal; /* client-calculated credentials */
NEG_FLAGS clnt_flgs; /* usually 0x6007 ffff */
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
{
DOM_CLNT_INFO clnt_id; /* client identification/authentication info */
uint8 pwd[16]; /* new password - undocumented. */
typedef struct net_q_srv_pwset_info {
DOM_CLNT_INFO clnt_id; /* client identification/authentication info */
uint8 pwd[16]; /* new password - undocumented. */
} NET_Q_SRV_PWSET;
/* NET_R_SRV_PWSET */
typedef struct net_r_srv_pwset_info
{
DOM_CRED srv_cred; /* server-calculated credentials */
NTSTATUS status; /* return code */
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,81 +482,64 @@ 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
{
uint16 switch_value;
union
{
NET_ID_INFO_1 id1; /* auth-level 1 - interactive user login */
NET_ID_INFO_2 id2; /* auth-level 2 - workstation referred login */
} auth;
typedef struct net_id_info_ctr_info {
uint16 switch_value;
union {
NET_ID_INFO_1 id1; /* auth-level 1 - interactive user login */
NET_ID_INFO_2 id2; /* auth-level 2 - workstation referred login */
} auth;
} NET_ID_INFO_CTR;
/* SAM_INFO - sam logon/off id structure */
typedef struct sam_info
{
DOM_CLNT_INFO2 client;
uint32 ptr_rtn_cred; /* pointer to return credentials */
DOM_CRED rtn_cred; /* return credentials */
uint16 logon_level;
NET_ID_INFO_CTR *ctr;
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
{
DOM_SAM_INFO sam_id;
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
{
uint32 buffer_creds; /* undocumented buffer pointer */
DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
typedef struct net_r_sam_logon_info {
uint32 buffer_creds; /* undocumented buffer pointer */
DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
uint16 switch_value; /* 3 - indicates type of USER INFO */
NET_USER_INFO_3 *user;
NET_USER_INFO_3 *user;
uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
NTSTATUS status; /* return code */
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
{
DOM_SAM_INFO sam_id;
typedef struct net_q_sam_logoff_info {
DOM_SAM_INFO sam_id;
} NET_Q_SAM_LOGOFF;
/* NET_R_SAM_LOGOFF */
typedef struct net_r_sam_logoff_info
{
uint32 buffer_creds; /* undocumented buffer pointer */
DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
NTSTATUS status; /* return code */
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 */

View 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 */

View 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 */

View 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 */

View File

@ -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;

View File

@ -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:

View File

@ -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
/*

View File

@ -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 */

View File

@ -206,13 +206,13 @@ 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
{
uint32 low;
uint32 high;
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
View 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

View File

@ -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;
};
/*

View File

@ -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"
@ -95,10 +96,12 @@ struct smbldap_state;
#define LDAP_ATTR_LOGON_COUNT 36
#define LDAP_ATTR_MUNGED_DIAL 37
#define LDAP_ATTR_BAD_PASSWORD_TIME 38
#define LDAP_ATTR_PWD_HISTORY 39
#define LDAP_ATTR_PWD_HISTORY 39
#define LDAP_ATTR_SID_LIST 40
#define LDAP_ATTR_MOD_TIMESTAMP 41
#define LDAP_ATTR_LOGON_HOURS 42
#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 */

View File

@ -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;

View File

@ -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)

View File

@ -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
View 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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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)));

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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++ ) {

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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]);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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]))
return False;
for (i = 0; i < 7; i++)
{
if (!prs_uint32("unkown", ps, depth, &info->unknown[i])) /* unknown */
return False;
}
if (!prs_uint32("sid_count", ps, depth, &info->sid_count))
return False;
@ -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,8 +485,8 @@ 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",
hdr->offset, prs_offset(ps)));
DEBUG(5,("offset in header(x%x) and data(x%x) do not match, correcting\n",
hdr->offset, prs_offset(ps)));
prs_set_offset(ps, hdr->offset);
}
@ -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

View File

@ -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;
@ -172,8 +180,9 @@ 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)
krb5_principal host_princ,
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);
}

View File

@ -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"));

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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->pipes[i].fnum != 0)
cli_close(cli, cli->pipes[i].fnum);
cli->pipes[i].fnum = 0;
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)));
}
cli->pipe_idx = -1;
if (cli->auth.cli_auth_data_free_func) {
(*cli->auth.cli_auth_data_free_func)(&cli->auth);
}
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,8 +442,9 @@ void cli_shutdown(struct cli_state *cli)
BOOL allocated = cli->allocated;
cli_close_connection(cli);
ZERO_STRUCTP(cli);
if (allocated)
if (allocated) {
free(cli);
}
}
/****************************************************************************

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -464,8 +464,8 @@ 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,
char **param, unsigned int *param_len,
@ -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);

View File

@ -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.
Input: 8 byte challenge block
Setup the session key.
Input: 8 byte challenge block
8 byte server challenge block
16 byte md4 encrypted password
Output:
8 byte session key
Output:
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)
BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out)
{
UTIME new_clnt_time;
uint32 new_cred;
dc->sequence = received_cred->timestamp.time;
DEBUG(5,("deal_with_creds: %d\n", __LINE__));
creds_step(dc);
/* 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))
{
/* 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;
}

View File

@ -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},

View File

@ -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)

View File

@ -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,29 +853,27 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context,
return NULL;
}
if(pol) {
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);
return NULL;
}
if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) {
DEBUG(1, ("cli_nt_session_open fail!\n"));
errno = ENOTSUP;
cli_shutdown(ipc_cli);
return NULL;
}
/* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
but NT sends 0x2000000 so we might as well do it too. */
nt_status = cli_lsa_open_policy(ipc_cli,
ipc_cli->mem_ctx,
True,
GENERIC_EXECUTE_ACCESS,
pol);
if (!NT_STATUS_IS_OK(nt_status)) {
errno = smbc_errno(context, ipc_cli);
cli_shutdown(ipc_cli);
return NULL;
}
/* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED,
but NT sends 0x2000000 so we might as well do it too. */
nt_status = rpccli_lsa_open_policy(pipe_hnd,
ipc_cli->mem_ctx,
True,
GENERIC_EXECUTE_ACCESS,
pol);
if (!NT_STATUS_IS_OK(nt_status)) {
errno = smbc_errno(context, ipc_cli);
cli_shutdown(ipc_cli);
return NULL;
}
ipc_srv = SMB_MALLOC_P(SMBCSRV);
@ -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);

View File

@ -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,8 +1048,8 @@ 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,
session_key.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 {
SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
@ -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;
}

View File

@ -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);

View File

@ -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],
DATA_BLOB session_key,
const char *constant)
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 {
@ -103,64 +53,107 @@ enum ntlmssp_direction {
};
static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
const uchar *data, size_t length,
enum ntlmssp_direction direction,
DATA_BLOB *sig)
const uchar *data, size_t length,
const uchar *whole_pdu, size_t pdu_length,
enum ntlmssp_direction direction,
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) {
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;
}
@ -171,8 +164,9 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
*/
NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
const uchar *data, size_t length,
const DATA_BLOB *sig)
const uchar *data, size_t length,
const uchar *whole_pdu, size_t pdu_length,
const DATA_BLOB *sig)
{
DATA_BLOB local_sig;
NTSTATUS nt_status;
@ -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);
DEBUG(5, ("BAD SIG: got signature of\n"));
dump_data(5, (const char *)(sig->data), 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(0, ("NTLMSSP packet check failed due to invalid signature!\n"));
return NT_STATUS_ACCESS_DENIED;
DEBUG(5, ("BAD SIG: got signature of\n"));
dump_data(5, sig->data, sig->length);
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);
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"));
/* increment counter on recieive */
ntlmssp_state->ntlmssp_seq_num++;
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;
}
@ -286,26 +298,27 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
*/
NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state,
uchar *data, size_t length,
DATA_BLOB *sig)
uchar *data, size_t length,
uchar *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
{
if (!ntlmssp_state->session_key.length) {
DEBUG(3, ("NO session key, cannot unseal packet\n"));
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,
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));
/**
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.
*/
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_hash(ntlmssp_state->recv_sign_hash,
ntlmssp_state->recv_sign_const,
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));
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));
}
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;
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;
}
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));
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 key:\n",
ntlmssp_state->send_sign_key, 16);
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);
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 recv send sign key:\n",
ntlmssp_state->recv_sign_key, 16);
calc_ntlmv2_key(ntlmssp_state->recv_seal_key,
weak_session_key, recv_seal_const);
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;
} 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;
}
DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n"));
dump_data_pw("NTLMSSP weakend master key:\n",
weak_session_key.data,
weak_session_key.length);
#endif
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));
DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
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;
}

View File

@ -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;
if ( !cli_nt_session_open( &cli, PI_SAMR ) ) {
pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli,
PI_SAMR,
PIPE_AUTH_LEVEL_PRIVACY,
"", /* what domain... ? */
user_name,
old_passwd,
&result);
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_init_creds(&cli, "", "", NULL);
cli.pipe_auth_flags = 0;
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! */
@ -185,9 +192,10 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
cli_shutdown(&cli);
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;
}

View File

@ -60,4 +60,3 @@ void pwd_get_cleartext(struct pwd_info *pwd, fstring clr)
clr[0] = 0;
}

View File

@ -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. */
}

View File

@ -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;
}
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];
}
smb_arc4_init(arc4_state, key, 16);
smb_arc4_crypt(arc4_state, data, len);
}
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

View File

@ -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

View File

@ -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}};

View File

@ -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;

View File

@ -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))) {
DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n",
nt_errstr(result)));
return result;
/* 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);
}

View File

@ -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

View File

@ -23,7 +23,7 @@
static struct {
char from;
char *to;
const char *to;
int len;
} weird_table[] = {
{'q', "^q^", 3},

View File

@ -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();
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -543,6 +543,11 @@ NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
if (write_sock(request, sizeof(*request), request->flags & WBFLAG_RECURSE) == -1) {
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