1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-12 09:18:10 +03:00

Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into v3-2-test

(This used to be commit 5a30f6377d)
This commit is contained in:
Jelmer Vernooij 2008-01-05 23:09:38 +01:00
commit aaa2770666
140 changed files with 5434 additions and 2343 deletions

1
.gitignore vendored
View File

@ -34,3 +34,4 @@ source/proto_exists
source/winbindd/winbindd_proto.h
source/cscope.out
source/torture.tdb
source/pkgconfig/*.pc

View File

@ -375,7 +375,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
libsmb/clistr.o libsmb/cliquota.o libsmb/clifsinfo.o libsmb/clidfs.o \
libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
libsmb/clioplock.o $(ERRORMAP_OBJ) libsmb/clirap2.o \
$(DOSERR_OBJ) \
libsmb/smb_seal.o $(DOSERR_OBJ) \
$(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ)
RPC_CLIENT_OBJ1 = rpc_client/cli_netlogon.o rpc_client/cli_srvsvc.o
@ -552,7 +552,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/reply.o smbd/sesssetup.o smbd/trans2.o smbd/uid.o \
smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \
smbd/blocking.o smbd/sec_ctx.o smbd/srvstr.o \
smbd/vfs.o smbd/statcache.o \
smbd/vfs.o smbd/statcache.o smbd/seal.o \
smbd/posix_acls.o lib/sysacls.o $(SERVER_MUTEX_OBJ) \
smbd/process.o smbd/service.o smbd/error.o \
printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \
@ -677,7 +677,7 @@ LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
$(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(RPC_PARSE_OBJ) \
$(SECRETS_OBJ) $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) $(LDB_OBJ)
LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o $(TDB_BASE_OBJ)
LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o $(TDBBASE_OBJ)
# This shared library is intended for linking with unit test programs
# to test Samba internals. It's called libbigballofmud.so to
@ -1415,7 +1415,7 @@ bin/libaddns.a: $(BINARY_PREREQS) $(LIBADDNS_OBJ)
bin/libnetapi.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBNETAPI_OBJ)
@echo Linking shared library $@
@$(SHLD_DSO) $(LIBNETAPI_OBJ) $(LIBS) \
@$(SHLD_DSO) $(LIBNETAPI_OBJ) @LIBWBCLIENT_SHARED@ $(LIBS) \
$(LDAP_LIBS) $(KRB5LIBS) $(NSCD_LIBS) \
@SONAMEFLAG@`basename $@`.$(SONAME_VER)
@ -1425,7 +1425,7 @@ bin/libnetapi.a: $(BINARY_PREREQS) $(LIBNETAPI_OBJ)
bin/libsmbclient.@SHLIBEXT@: $(BINARY_PREREQS) $(LIBSMBCLIENT_OBJ)
@echo Linking shared library $@
@$(SHLD_DSO) $(LIBSMBCLIENT_OBJ) $(LIBS) \
@$(SHLD_DSO) $(LIBSMBCLIENT_OBJ) @LIBWBCLIENT_SHARED@ $(LIBS) \
$(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \
@SONAMEFLAG@`basename $@`.$(SONAME_VER)
@ -1532,7 +1532,7 @@ bin/winbindd@EXEEXT@: $(BINARY_PREREQS) $(WINBINDD_OBJ) @BUILD_POPT@ @LIBWBCLIEN
@POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) \
@WINBIND_LIBS@
bin/vlp@EXEEXT@: $(BINARY_PREREQS) $(VLP_OBJ)
bin/vlp@EXEEXT@: $(BINARY_PREREQS) $(VLP_OBJ) @LIBWBCLIENT_SHARED@
@echo "Linking $@"
@$(CC) $(FLAGS) -o $@ $(VLP_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \
$(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) @LIBWBCLIENT_SHARED@
@ -1997,6 +1997,7 @@ clean: delheaders
$(TOPFILES) $(BIN_PROGS) $(SBIN_PROGS) $(ROOT_SBIN_PROGS) \
$(MODULES) $(TORTURE_PROGS) $(LIBSMBCLIENT) $(LIBADDNS) \
$(LIBSMBSHAREMODES) $(EVERYTHING_PROGS) $(LIBNETAPI) \
bin/libwbclient.so.0 bin/timelimit \
.headers.stamp */src/*.o proto_exists
-rm -rf t_dir
@ -2129,6 +2130,14 @@ Makefile: $(srcdir)/Makefile.in config.status
######################################################################
# Samba Testing Framework
# Check shared libs for unresolved symbols
test_shlibs: $(SHLIBS)
@echo "Testing $(SHLIBS) "
@for module in $(SHLIBS); do \
./script/tests/dlopen.sh bin/$${module}.@SHLIBEXT@ \
|| exit 1; \
done
# Check for NSS module problems.
test_nss_modules: nss_modules
@echo "Testing $(NSS_MODULES) "

View File

@ -270,7 +270,9 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
&info3);
if (NT_STATUS_IS_OK(nt_status)) {
(*server_info)->was_mapped |= user_info->was_mapped;
if (user_info->was_mapped) {
(*server_info)->was_mapped = user_info->was_mapped;
}
if ( ! (*server_info)->guest) {
/* if a real user check pam account restrictions */

View File

@ -1103,7 +1103,7 @@ static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_inf
struct samu *sampass = NULL;
DOM_SID guest_sid;
bool ret;
static const char zeros[16] = { 0, };
char zeros[16];
if ( !(sampass = samu_new( NULL )) ) {
return NT_STATUS_NO_MEMORY;
@ -1138,6 +1138,7 @@ static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_inf
/* annoying, but the Guest really does have a session key, and it is
all zeros! */
ZERO_STRUCT(zeros);
(*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
(*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
@ -1420,7 +1421,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
auth_serversupplied_info **server_info,
NET_USER_INFO_3 *info3)
{
static const char zeros[16] = { 0, };
char zeros[16];
NTSTATUS nt_status = NT_STATUS_OK;
char *found_username = NULL;
@ -1624,7 +1625,9 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
&(info3->uni_logon_srv));
/* ensure we are never given NULL session keys */
ZERO_STRUCT(zeros);
if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
result->user_session_key = data_blob_null;
} else {

View File

@ -134,7 +134,9 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
}
if (NT_STATUS_IS_OK(nt_status)) {
(*server_info)->was_mapped |= user_info->was_mapped;
if (user_info->was_mapped) {
(*server_info)->was_mapped = user_info->was_mapped;
}
}
}
} else if (NT_STATUS_IS_OK(nt_status)) {

View File

@ -77,12 +77,19 @@ bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
NT_USER_TOKEN *get_root_nt_token( void )
{
static NT_USER_TOKEN *token = NULL;
struct nt_user_token *token = NULL;
DOM_SID u_sid, g_sid;
struct passwd *pw;
void *cache_data;
if ( token )
return token;
cache_data = memcache_lookup_talloc(
NULL, SINGLETON_CACHE_TALLOC,
data_blob_string_const("root_nt_token"));
if (cache_data != NULL) {
return talloc_get_type_abort(
cache_data, struct nt_user_token);
}
if ( !(pw = sys_getpwnam( "root" )) ) {
DEBUG(0,("get_root_nt_token: getpwnam(\"root\") failed!\n"));
@ -97,6 +104,11 @@ NT_USER_TOKEN *get_root_nt_token( void )
token = create_local_nt_token(NULL, &u_sid, False,
1, &global_sid_Builtin_Administrators);
memcache_add_talloc(
NULL, SINGLETON_CACHE_TALLOC,
data_blob_string_const("root_nt_token"), token);
return token;
}
@ -284,7 +296,7 @@ struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
DEBUG(10, ("Create local NT token for %s\n",
sid_string_dbg(user_sid)));
if (!(result = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) {
if (!(result = TALLOC_ZERO_P(mem_ctx, struct nt_user_token))) {
DEBUG(0, ("talloc failed\n"));
return NULL;
}

View File

@ -93,6 +93,9 @@ static unsigned int put_total_time_ms = 0;
/* totals globals */
static double dir_total;
/* encrypted state. */
static bool smb_encrypt;
/* root cli_state connection */
struct cli_state *cli;
@ -2178,6 +2181,49 @@ static int cmd_open(void)
return 0;
}
static int cmd_posix_encrypt(void)
{
TALLOC_CTX *ctx = talloc_tos();
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
if (cli->use_kerberos) {
status = cli_gss_smb_encryption_start(cli);
} else {
char *domain = NULL;
char *user = NULL;
char *password = NULL;
if (!next_token_talloc(ctx, &cmd_ptr,&domain,NULL)) {
d_printf("posix_encrypt domain user password\n");
return 1;
}
if (!next_token_talloc(ctx, &cmd_ptr,&user,NULL)) {
d_printf("posix_encrypt domain user password\n");
return 1;
}
if (!next_token_talloc(ctx, &cmd_ptr,&password,NULL)) {
d_printf("posix_encrypt domain user password\n");
return 1;
}
status = cli_raw_ntlm_smb_encryption_start(cli,
user,
password,
domain);
}
if (!NT_STATUS_IS_OK(status)) {
d_printf("posix_encrypt failed with error %s\n", nt_errstr(status));
} else {
d_printf("encryption on\n");
smb_encrypt = true;
}
return 0;
}
/****************************************************************************
****************************************************************************/
@ -2424,17 +2470,30 @@ static int cmd_posix(void)
return 1;
}
}
if (caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP) {
caps = talloc_asprintf_append(caps, "posix_encrypt ");
if (!caps) {
return 1;
}
}
if (caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP) {
caps = talloc_asprintf_append(caps, "mandatory_posix_encrypt ");
if (!caps) {
return 1;
}
}
if (*caps && caps[strlen(caps)-1] == ' ') {
caps[strlen(caps)-1] = '\0';
}
d_printf("Server supports CIFS capabilities %s\n", caps);
if (!cli_set_unix_extensions_capabilities(cli, major, minor, caplow, caphigh)) {
d_printf("Can't set UNIX CIFS extensions capabilities. %s.\n", cli_errstr(cli));
return 1;
}
d_printf("Selecting server supported CIFS capabilities %s\n", caps);
if (caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
CLI_DIRSEP_CHAR = '/';
*CLI_DIRSEP_STR = '/';
@ -3731,16 +3790,28 @@ int cmd_iosize(void)
int iosize;
if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
d_printf("iosize <n> or iosize 0x<n>. "
"Minimum is 16384 (0x4000), "
"max is 16776960 (0xFFFF00)\n");
if (!smb_encrypt) {
d_printf("iosize <n> or iosize 0x<n>. "
"Minimum is 16384 (0x4000), "
"max is 16776960 (0xFFFF00)\n");
} else {
d_printf("iosize <n> or iosize 0x<n>. "
"(Encrypted connection) ,"
"Minimum is 16384 (0x4000), "
"max is 130048 (0x1FC00)\n");
}
return 1;
}
iosize = strtol(buf,NULL,0);
if (iosize < 0 || iosize > 0xFFFF00) {
if (smb_encrypt && (iosize < 0x4000 || iosize > 0xFC00)) {
d_printf("iosize out of range for encrypted "
"connection (min = 16384 (0x4000), "
"max = 130048 (0x1FC00)");
return 1;
} else if (!smb_encrypt && (iosize < 0x4000 || iosize > 0xFFFF00)) {
d_printf("iosize out of range (min = 16384 (0x4000), "
"max = 16776960 (0x0xFFFF00)");
"max = 16776960 (0xFFFF00)");
return 1;
}
@ -3803,6 +3874,7 @@ static struct {
{"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
{"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}},
{"posix", cmd_posix, "turn on all POSIX capabilities", {COMPL_REMOTE,COMPL_NONE}},
{"posix_encrypt",cmd_posix_encrypt,"<domain> <user> <password> start up transport encryption",{COMPL_REMOTE,COMPL_NONE}},
{"posix_open",cmd_posix_open,"<name> 0<mode> open_flags mode open a file using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},
{"posix_mkdir",cmd_posix_mkdir,"<name> 0<mode> creates a directory using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},
{"posix_rmdir",cmd_posix_rmdir,"<name> removes a directory using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},
@ -3915,7 +3987,8 @@ static int process_command_string(const char *cmd_in)
/* establish the connection if not already */
if (!cli) {
cli = cli_cm_open(talloc_tos(), NULL, desthost, service, true);
cli = cli_cm_open(talloc_tos(), NULL, desthost,
service, true, smb_encrypt);
if (!cli) {
return 1;
}
@ -4255,16 +4328,22 @@ static void readline_callback(void)
timeout.tv_usec = 0;
sys_select_intr(cli->fd+1,&fds,NULL,NULL,&timeout);
/* We deliberately use receive_smb instead of
/* We deliberately use receive_smb_raw instead of
client_receive_smb as we want to receive
session keepalives and then drop them here.
*/
if (FD_ISSET(cli->fd,&fds)) {
if (!receive_smb(cli->fd,cli->inbuf,0,&cli->smb_rw_error)) {
if (receive_smb_raw(cli->fd,cli->inbuf,0,0,&cli->smb_rw_error) == -1) {
DEBUG(0, ("Read from server failed, maybe it closed the "
"connection\n"));
return;
}
if(CVAL(cli->inbuf,0) != SMBkeepalive) {
DEBUG(0, ("Read from server "
"returned unexpected packet!\n"));
return;
}
goto again;
}
@ -4340,7 +4419,8 @@ static int process(const char *base_directory)
{
int rc = 0;
cli = cli_cm_open(talloc_tos(), NULL, desthost, service, true);
cli = cli_cm_open(talloc_tos(), NULL,
desthost, service, true, smb_encrypt);
if (!cli) {
return 1;
}
@ -4369,7 +4449,8 @@ static int process(const char *base_directory)
static int do_host_query(const char *query_host)
{
cli = cli_cm_open(talloc_tos(), NULL, query_host, "IPC$", true);
cli = cli_cm_open(talloc_tos(), NULL,
query_host, "IPC$", true, smb_encrypt);
if (!cli)
return 1;
@ -4382,7 +4463,8 @@ static int do_host_query(const char *query_host)
cli_cm_shutdown();
cli_cm_set_port( 139 );
cli = cli_cm_open(talloc_tos(), NULL, query_host, "IPC$", true);
cli = cli_cm_open(talloc_tos(), NULL,
query_host, "IPC$", true, smb_encrypt);
}
if (cli == NULL) {
@ -4407,7 +4489,8 @@ static int do_tar_op(const char *base_directory)
/* do we already have a connection? */
if (!cli) {
cli = cli_cm_open(talloc_tos(), NULL, desthost, service, true);
cli = cli_cm_open(talloc_tos(), NULL,
desthost, service, true, smb_encrypt);
if (!cli)
return 1;
}
@ -4657,6 +4740,9 @@ static int do_message_op(void)
case 'g':
grepable=true;
break;
case 'e':
smb_encrypt=true;
break;
case 'B':
return(do_smb_browse());
@ -4747,6 +4833,7 @@ static int do_message_op(void)
calling_name = talloc_strdup(frame, global_myname() );
}
smb_encrypt = get_cmdline_auth_info_smb_encrypt();
init_names();
if(new_name_resolve_order)

View File

@ -47,7 +47,9 @@ static struct cli_state *smb_complete_connection(const char *, const char *,int
static struct cli_state *smb_connect(const char *, const char *, int, const char *, const char *, const char *, const char *);
static int smb_print(struct cli_state *, char *, FILE *);
static char * uri_unescape_alloc(const char *);
#if 0
static bool smb_encrypt;
#endif
/*
* 'main()' - Main entry for SMB backend.
@ -468,6 +470,23 @@ static struct cli_state
return NULL;
}
#if 0
/* Need to work out how to specify this on the URL. */
if (smb_encrypt)
{
if (!cli_cm_force_encryption(cli,
username,
password,
workgroup,
share))
{
fprintf(stderr, "ERROR: encryption setup failed\n");
cli_shutdown(cli);
return NULL;
}
}
#endif
return cli;
}

View File

@ -455,7 +455,7 @@ AC_ARG_ENABLE(krb5developer, [ --enable-krb5developer Turn on developer warnin
# DEVELOPER_CFLAGS, so that you can turn them on and off with a simple
# Makefile edit, avoiding the need to re-run configure.
if test x"$ac_cv_prog_gcc" = x"yes" ; then
DEVELOPER_CFLAGS="-gstabs -Wall -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
DEVELOPER_CFLAGS="-g -Wall -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
# Add -Wdeclaration-after-statement if compiler supports it
AC_CACHE_CHECK(
[that the C compiler understands -Wdeclaration-after-statement],
@ -3014,6 +3014,7 @@ AC_TRY_RUN([
#define NO_CONFIG_H 1
#define HAVE_IFACE_IFCONF 1
#define AUTOCONF_TEST 1
#define SOCKET_WRAPPER_NOT_REPLACE
#include "${srcdir-.}/lib/replace/replace.c"
#include "${srcdir-.}/lib/interfaces.c"],
samba_cv_HAVE_IFACE_IFCONF=yes,samba_cv_HAVE_IFACE_IFCONF=no,samba_cv_HAVE_IFACE_IFCONF=cross)])
@ -3031,7 +3032,10 @@ AC_TRY_RUN([
#define NO_CONFIG_H 1
#define HAVE_IFACE_IFREQ 1
#define AUTOCONF_TEST 1
#define SOCKET_WRAPPER_NOT_REPLACE
#include "${srcdir-.}/lib/replace/replace.c"
#include "${srcdir-.}/lib/replace/getaddrinfo.c"
#include "${srcdir-.}/lib/replace/snprintf.c"
#include "${srcdir-.}/lib/interfaces.c"],
samba_cv_HAVE_IFACE_IFREQ=yes,samba_cv_HAVE_IFACE_IFREQ=no,samba_cv_HAVE_IFACE_IFREQ=cross)])
CPPFLAGS="$SAVE_CPPFLAGS"
@ -3040,6 +3044,15 @@ if test x"$samba_cv_HAVE_IFACE_IFREQ" = x"yes"; then
fi
fi
dnl AIX 5.3.0.0
AC_TRY_COMPILE([#include <sys/socket.h>],[
struct sockaddr_storage s; s.__ss_family = 0],
samba_cv_have_aix_sockaddr_storage=yes,samba_cv_have_aix_sockaddr_storage=no)
if test x"$samba_cv_have_aix_sockaddr_storage" = x"yes"; then
AC_DEFINE(HAVE_AIX_SOCKADDR_STORAGE, 1, [Whether struct sockaddr_storage has __sa_family])
fi
if test $iface = no; then
AC_CACHE_CHECK([for iface AIX],samba_cv_HAVE_IFACE_AIX,[
SAVE_CPPFLAGS="$CPPFLAGS"
@ -3049,7 +3062,9 @@ AC_TRY_RUN([
#define HAVE_IFACE_AIX 1
#define AUTOCONF_TEST 1
#undef _XOPEN_SOURCE_EXTENDED
#define SOCKET_WRAPPER_NOT_REPLACE
#include "${srcdir-.}/lib/replace/replace.c"
#include "${srcdir-.}/lib/replace/snprintf.c"
#include "${srcdir-.}/lib/interfaces.c"],
samba_cv_HAVE_IFACE_AIX=yes,samba_cv_HAVE_IFACE_AIX=no,samba_cv_HAVE_IFACE_AIX=cross)])
CPPFLAGS="$SAVE_CPPFLAGS"
@ -5089,7 +5104,7 @@ LIBNETAPI_SHARED=
LIBNETAPI=
AC_MSG_CHECKING(whether to build the libnetapi shared library)
AC_ARG_WITH(libnetapi,
[ --with-libnetapi Build the libnetapi shared library (default=no undefined API)],
[ --with-libnetapi Build the libnetapi shared library (default=yes if shared libs supported)],
[ case "$withval" in
*)
AC_MSG_RESULT(no)

View File

@ -114,3 +114,7 @@ ADS_STATUS ads_get_tokensids(ADS_STRUCT *ads,
DOM_SID *primary_group_sid,
DOM_SID **sids,
size_t *num_sids);
ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads,
TALLOC_CTX *mem_ctx,
char ***ous,
size_t *num_ous);

View File

@ -27,7 +27,9 @@
will be a multiple of the page size on almost any system */
#define CLI_BUFFER_SIZE (0xFFFF)
#define CLI_SAMBA_MAX_LARGE_READX_SIZE (127*1024) /* Works for Samba servers */
#define CLI_SAMBA_MAX_LARGE_WRITEX_SIZE (127*1024) /* Works for Samba servers */
#define CLI_WINDOWS_MAX_LARGE_READX_SIZE ((64*1024)-2) /* Windows servers are broken.... */
#define CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE ((64*1024)-2) /* Windows servers are broken.... */
#define CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE (0xFFFF00) /* 24-bit len. */
#define CLI_SAMBA_MAX_POSIX_LARGE_WRITEX_SIZE (0xFFFF00) /* 24-bit len. */
@ -79,6 +81,28 @@ struct rpc_pipe_client {
struct dcinfo *dc;
};
/* Transport encryption state. */
enum smb_trans_enc_type { SMB_TRANS_ENC_NTLM, SMB_TRANS_ENC_GSS };
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
struct smb_tran_enc_state_gss {
gss_ctx_id_t gss_ctx;
gss_cred_id_t creds;
};
#endif
struct smb_trans_enc_state {
enum smb_trans_enc_type smb_enc_type;
uint16 enc_ctx_num;
bool enc_on;
union {
NTLMSSP_STATE *ntlmssp_state;
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
struct smb_tran_enc_state_gss *gss_state;
#endif
} s;
};
struct cli_state {
int port;
int fd;
@ -142,6 +166,8 @@ struct cli_state {
smb_sign_info sign_info;
struct smb_trans_enc_state *trans_enc_state; /* Setup if we're encrypting SMB's. */
/* the session key for this CLI, outside
any per-pipe authenticaion */
DATA_BLOB user_session_key;

View File

@ -161,9 +161,24 @@ extern bool *DEBUGLEVEL_CLASS_ISSET;
* will remove the extra conditional test.
*/
/*
* From talloc.c:
*/
/* these macros gain us a few percent of speed on gcc */
#if (__GNUC__ >= 3)
/* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
as its first argument */
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else
#define likely(x) (x)
#define unlikely(x) (x)
#endif
#define DEBUGLVL( level ) \
( ((level) <= MAX_DEBUG_LEVEL) && \
((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
unlikely((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
(!DEBUGLEVEL_CLASS_ISSET[ DBGC_CLASS ] && \
DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& dbghdr( level, DBGC_CLASS, __FILE__, FUNCTION_MACRO, (__LINE__) ) )
@ -171,7 +186,7 @@ extern bool *DEBUGLEVEL_CLASS_ISSET;
#define DEBUGLVLC( dbgc_class, level ) \
( ((level) <= MAX_DEBUG_LEVEL) && \
((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
unlikely((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
(!DEBUGLEVEL_CLASS_ISSET[ dbgc_class ] && \
DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& dbghdr( level, DBGC_CLASS, __FILE__, FUNCTION_MACRO, (__LINE__) ) )
@ -179,7 +194,7 @@ extern bool *DEBUGLEVEL_CLASS_ISSET;
#define DEBUG( level, body ) \
(void)( ((level) <= MAX_DEBUG_LEVEL) && \
((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
unlikely((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
(!DEBUGLEVEL_CLASS_ISSET[ DBGC_CLASS ] && \
DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& (dbghdr( level, DBGC_CLASS, __FILE__, FUNCTION_MACRO, (__LINE__) )) \
@ -187,7 +202,7 @@ extern bool *DEBUGLEVEL_CLASS_ISSET;
#define DEBUGC( dbgc_class, level, body ) \
(void)( ((level) <= MAX_DEBUG_LEVEL) && \
((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
unlikely((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
(!DEBUGLEVEL_CLASS_ISSET[ dbgc_class ] && \
DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& (dbghdr( level, DBGC_CLASS, __FILE__, FUNCTION_MACRO, (__LINE__) )) \
@ -195,14 +210,14 @@ extern bool *DEBUGLEVEL_CLASS_ISSET;
#define DEBUGADD( level, body ) \
(void)( ((level) <= MAX_DEBUG_LEVEL) && \
((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
unlikely((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
(!DEBUGLEVEL_CLASS_ISSET[ DBGC_CLASS ] && \
DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& (dbgtext body) )
#define DEBUGADDC( dbgc_class, level, body ) \
(void)( ((level) <= MAX_DEBUG_LEVEL) && \
((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
unlikely((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
(!DEBUGLEVEL_CLASS_ISSET[ dbgc_class ] && \
DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& (dbgtext body) )

View File

@ -216,12 +216,14 @@
#define WERR_BUF_TOO_SMALL W_ERROR(2123)
#define WERR_JOB_NOT_FOUND W_ERROR(2151)
#define WERR_DEST_NOT_FOUND W_ERROR(2152)
#define WERR_USER_EXISTS W_ERROR(2224)
#define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320)
#define WERR_DOMAIN_CONTROLLER_NOT_FOUND W_ERROR(2453)
#define WERR_SETUP_ALREADY_JOINED W_ERROR(2691)
#define WERR_SETUP_NOT_JOINED W_ERROR(2692)
#define WERR_SETUP_DOMAIN_CONTROLLER W_ERROR(2693)
#define WERR_DEFAULT_JOIN_REQUIRED W_ERROR(2694)
#define WERR_DEVICE_NOT_AVAILABLE W_ERROR(4319)
#define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105)

View File

@ -106,6 +106,13 @@ struct smbc_internal_data {
* and retrieved with smbc_option_set() and smbc_option_get().
*/
void * _user_data;
/*
* Should we attempt UNIX smb encryption ?
* Set to 0 if we should never attempt, set to 1 if
* encryption requested, set to 2 if encryption required.
*/
int _smb_encryption_level;
};

View File

@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
In-memory cache
Copyright (C) Volker Lendecke 2005-2007
Copyright (C) Volker Lendecke 2007-2008
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -24,6 +24,15 @@
struct memcache;
/*
* A memcache can store different subkeys with overlapping keys, the
* memcache_number becomes part of the key. Feel free to add caches of your
* own here.
*
* If you add talloc type caches, also note this in the switch statement in
* memcache_is_talloc().
*/
enum memcache_number {
STAT_CACHE,
UID_SID_CACHE,
@ -33,28 +42,74 @@ enum memcache_number {
GETWD_CACHE,
GETPWNAM_CACHE, /* talloc */
MANGLE_HASH2_CACHE,
PDB_GETPWSID_CACHE, /* talloc */
SINGLETON_CACHE_TALLOC, /* talloc */
SINGLETON_CACHE
};
/*
* Create a memcache structure. max_size is in bytes, if you set it 0 it will
* not forget anything.
*/
struct memcache *memcache_init(TALLOC_CTX *mem_ctx, size_t max_size);
/*
* If you set this global memcache, use it as the default cache when NULL is
* passed to the memcache functions below. This is a workaround for many
* situations where passing the cache everywhere would be a big hassle.
*/
void memcache_set_global(struct memcache *cache);
/*
* Add a data blob to the cache
*/
void memcache_add(struct memcache *cache, enum memcache_number n,
DATA_BLOB key, DATA_BLOB value);
/*
* Add a talloc object to the cache. The difference to memcache_add() is that
* when the objects is to be discared, talloc_free is called for it. Also
* talloc_move() ownership of the object to the cache.
*
* Please note that the current implementation has a fixed relationship
* between what cache subtypes store talloc objects and which ones store plain
* blobs. We can fix this, but for now we don't have a mixed use of blobs vs
* talloc objects in the cache types.
*/
void memcache_add_talloc(struct memcache *cache, enum memcache_number n,
DATA_BLOB key, void *ptr);
/*
* Delete an object from the cache
*/
void memcache_delete(struct memcache *cache, enum memcache_number n,
DATA_BLOB key);
/*
* Look up an object from the cache. Memory still belongs to the cache, so
* make a copy of it if needed.
*/
bool memcache_lookup(struct memcache *cache, enum memcache_number n,
DATA_BLOB key, DATA_BLOB *value);
/*
* Look up an object from the cache. Memory still belongs to the cache, so
* make a copy of it if needed.
*/
void *memcache_lookup_talloc(struct memcache *cache, enum memcache_number n,
DATA_BLOB key);
/*
* Flush a complete cache subset.
*/
void memcache_flush(struct memcache *cache, enum memcache_number n);
#endif

View File

@ -242,20 +242,15 @@ struct pdb_search {
* changed to version 14 to move lookup_rids and lookup_names to return
* enum lsa_SidType rather than uint32.
* Changed to 16 for access to the trusted domain passwords (obnox).
* Changed to 17, the sampwent interface is gone.
*/
#define PASSDB_INTERFACE_VERSION 16
#define PASSDB_INTERFACE_VERSION 17
struct pdb_methods
{
const char *name; /* What name got this module */
NTSTATUS (*setsampwent)(struct pdb_methods *, bool update, uint32 acb_mask);
void (*endsampwent)(struct pdb_methods *);
NTSTATUS (*getsampwent)(struct pdb_methods *, struct samu *user);
NTSTATUS (*getsampwnam)(struct pdb_methods *, struct samu *sam_acct, const char *username);
NTSTATUS (*getsampwsid)(struct pdb_methods *, struct samu *sam_acct, const DOM_SID *sid);

View File

@ -49,6 +49,7 @@ struct user_auth_info {
bool got_pass;
bool use_kerberos;
int signing_state;
bool smb_encrypt;
};
#endif /* _POPT_COMMON_H */

View File

@ -27,7 +27,7 @@
#define _SMB_H
/* logged when starting the various Samba daemons */
#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2007"
#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2008"
#if defined(LARGE_SMB_OFF_T)
@ -80,7 +80,8 @@ enum smb_read_errors {
SMB_WRITE_ERROR, /* This error code can go into the client smb_rw_error. */
SMB_READ_BAD_SIG,
SMB_NO_MEMORY,
SMB_DO_NOT_DO_TDIS /* cli_close_connection() check for this when smbfs wants to keep tree connected */
SMB_DO_NOT_DO_TDIS, /* cli_close_connection() check for this when smbfs wants to keep tree connected */
SMB_READ_BAD_DECRYPT
};
#define DIR_STRUCT_SIZE 43
@ -657,6 +658,8 @@ typedef struct connection_struct {
bool used;
int num_files_open;
unsigned int num_smb_operations; /* Count of smb operations on this tree. */
int encrypt_level;
bool encrypted_tid;
/* Semantics requested by the client or forced by the server config. */
bool case_sensitive;
@ -692,6 +695,8 @@ struct smb_request {
const uint8 *inbuf;
uint8 *outbuf;
size_t unread_bytes;
bool encrypted;
connection_struct *conn;
};
/* Defines for the sent_oplock_break field above. */
@ -755,6 +760,7 @@ struct pending_message_list {
struct pending_message_list *next, *prev;
struct timeval request_time; /* When was this first issued? */
struct timeval end_time; /* When does this time out? */
bool encrypted;
DATA_BLOB buf;
DATA_BLOB private_data;
};

View File

@ -160,7 +160,6 @@
#define ERROR_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__)
#define ERROR_NT(status) error_packet(outbuf,0,0,status,__LINE__,__FILE__)
#define ERROR_OPEN(status) error_open(outbuf,status,__LINE__,__FILE__)
#define ERROR_FORCE_NT(status) error_packet(outbuf,-1,-1,status,__LINE__,__FILE__)
#define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__)
@ -170,9 +169,6 @@
#define reply_botherror(req,status,eclass,ecode) reply_both_error(req,eclass,ecode,status,__LINE__,__FILE__)
#define reply_unixerror(req,defclass,deferror) reply_unix_error(req,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
/* this is how errors are generated */
#define UNIXERROR(defclass,deferror) unix_error_packet(outbuf,defclass,deferror,NT_STATUS_OK,__LINE__,__FILE__)
/* these are the datagram types */
#define DGRAM_DIRECT_UNIQUE 0x10
@ -189,13 +185,16 @@
#define smb_offset(p,buf) (PTR_DIFF(p,buf+4) + chain_size)
#define smb_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|((PVAL(buf,1)&1)<<16))
#define _smb_setlen(buf,len) do { buf[0] = 0; buf[1] = (len&0x10000)>>16; \
buf[2] = (len&0xFF00)>>8; buf[3] = len&0xFF; } while (0)
#define _smb_setlen(buf,len) do { buf[0] = 0; buf[1] = ((len)&0x10000)>>16; \
buf[2] = ((len)&0xFF00)>>8; buf[3] = (len)&0xFF; } while (0)
#define smb_len_large(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|(PVAL(buf,1)<<16))
#define _smb_setlen_large(buf,len) do { buf[0] = 0; buf[1] = ((len)&0xFF0000)>>16; \
buf[2] = ((len)&0xFF00)>>8; buf[3] = (len)&0xFF; } while (0)
#define ENCRYPTION_REQUIRED(conn) ((conn) ? ((conn)->encrypt_level == Required) : false)
#define IS_CONN_ENCRYPTED(conn) ((conn) ? (conn)->encrypted_tid : false)
/*******************************************************************
find the difference in milliseconds between two struct timeval
values

View File

@ -530,7 +530,8 @@ findfirst/findnext is SMB_FIND_FILE_UNIX_INFO2.
#define CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP 0x20 /* We can cope with POSIX open/mkdir/unlink etc. */
#define CIFS_UNIX_LARGE_READ_CAP 0x40 /* We can cope with 24 bit reads in readX. */
#define CIFS_UNIX_LARGE_WRITE_CAP 0x80 /* We can cope with 24 bit writes in writeX. */
#define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x100 /* We can do SPNEGO negotiations for encryption. */
#define CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP 0x200 /* We *must* SPNEGO negotiations for encryption. */
#define SMB_QUERY_POSIX_FS_INFO 0x201
@ -566,7 +567,6 @@ findfirst/findnext is SMB_FIND_FILE_UNIX_INFO2.
__u8 * psid_list may be empty
*/
/* ... more as we think of them :-). */
/* SMB POSIX ACL definitions. */
@ -653,6 +653,29 @@ enum smb_whoami_flags {
DOM_SID[] - list of SIDs (may be empty)
*/
/*
* The following trans2 is done between client and server
* as a FSINFO call to set up the encryption state for transport
* encryption.
* This is a subcommand of the TRANS2_QFSINFO.
*
* The request looks like :
*
* [data block] -> SPNEGO framed GSSAPI request.
*
* The reply looks like :
*
* [data block] -> SPNEGO framed GSSAPI reply - if error
* is NT_STATUS_OK then we're done, if it's
* NT_STATUS_MORE_PROCESSING_REQUIRED then the
* client needs to keep going. If it's an
* error it can be any NT_STATUS error.
*
*/
#define SMB_REQUEST_TRANSPORT_ENCRYPTION 0x203 /* QFSINFO */
/* The query/set info levels for POSIX ACLs. */
#define SMB_QUERY_POSIX_ACL 0x204
#define SMB_SET_POSIX_ACL 0x204

View File

@ -785,13 +785,13 @@ void check_log_size( void )
(void)x_vfprintf( dbf, format_str, ap );
va_end( ap );
errno = old_errno;
return( 0 );
goto done;
}
/* prevent recursion by checking if reopen_logs() has temporaily
set the debugf string to NULL */
if( debugf == NULL)
return( 0 );
goto done;
#ifdef WITH_SYSLOG
if( !lp_syslog_only() )
@ -806,7 +806,7 @@ void check_log_size( void )
x_setbuf( dbf, NULL );
} else {
errno = old_errno;
return(0);
goto done;
}
}
}
@ -855,10 +855,11 @@ void check_log_size( void )
(void)x_fflush( dbf );
}
errno = old_errno;
done:
TALLOC_FREE(tmp_debug_ctx);
errno = old_errno;
return( 0 );
}

View File

@ -51,4 +51,3 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
{
return NT_STATUS_OK;
}

View File

@ -32,7 +32,6 @@
#define BLOB_TYPE_LEN 9
static TDB_CONTEXT *cache;
static bool cache_readonly;
/**
* @file gencache.c
@ -67,7 +66,6 @@ bool gencache_init(void)
if (!cache && (errno == EACCES)) {
cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDONLY, 0644);
if (cache) {
cache_readonly = True;
DEBUG(5, ("gencache_init: Opening cache file %s read-only.\n", cache_fname));
}
}
@ -95,7 +93,6 @@ bool gencache_shutdown(void)
DEBUG(5, ("Closing cache file\n"));
ret = tdb_close(cache);
cache = NULL;
cache_readonly = False;
return ret != -1;
}
@ -123,10 +120,6 @@ bool gencache_set(const char *keystr, const char *value, time_t timeout)
if (!gencache_init()) return False;
if (cache_readonly) {
return False;
}
asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value);
if (!valstr)
return False;
@ -161,10 +154,6 @@ bool gencache_del(const char *keystr)
if (!gencache_init()) return False;
if (cache_readonly) {
return False;
}
DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr));
ret = tdb_delete_bystring(cache, keystr);
@ -351,10 +340,6 @@ bool gencache_set_data_blob(const char *keystr, DATA_BLOB *blob, time_t timeout)
return False;
}
if (cache_readonly) {
return False;
}
asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE);
if (!valstr) {
return False;

View File

@ -84,6 +84,7 @@
#include <net/if.h>
#endif
#define SOCKET_WRAPPER_NOT_REPLACE
#include "interfaces.h"
#include "lib/replace/replace.h"

View File

@ -46,6 +46,8 @@ static bool memcache_is_talloc(enum memcache_number n)
switch (n) {
case GETPWNAM_CACHE:
case PDB_GETPWSID_CACHE:
case SINGLETON_CACHE_TALLOC:
result = true;
break;
default:

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* Join Support (gtk + netapi)
* Copyright (C) Guenther Deschner 2007
* Copyright (C) Guenther Deschner 2007-2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -35,6 +35,7 @@
#define SAMBA_ICON_PATH "/usr/share/pixmaps/samba/samba.ico"
#define SAMBA_IMAGE_PATH "/usr/share/pixmaps/samba/logo.png"
#define SAMBA_IMAGE_PATH_SMALL "/usr/share/pixmaps/samba/logo-small.png"
#define WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ( 0x00000020 )
#define WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ( 0x00000004 )
@ -124,7 +125,6 @@ static void free_join_state(struct join_state *s)
SAFE_FREE(s->my_fqdn);
SAFE_FREE(s->my_dnsdomain);
SAFE_FREE(s->my_hostname);
}
static void do_cleanup(struct join_state *state)
@ -225,7 +225,8 @@ static void callback_do_reboot(GtkWidget *widget,
gtk_widget_destroy(dialog);
#endif
gtk_label_set_text(GTK_LABEL(state->label_reboot), "Changes will take effect after you restart this computer");
gtk_label_set_text(GTK_LABEL(state->label_reboot),
"Changes will take effect after you restart this computer");
debug("destroying do_change window\n");
gtk_widget_destroy(GTK_WIDGET(state->window_do_change));
@ -248,11 +249,14 @@ static void callback_do_reboot(GtkWidget *widget,
SAFE_FREE(buffer);
state->name_type_new = type;
#endif
gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer), state->name_buffer_new);
if (state->name_type_new == 3) {
gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Domain:");
gtk_label_set_text(GTK_LABEL(state->label_current_name_buffer),
state->name_buffer_new);
if (state->name_type_new == NetSetupDomainName) {
gtk_label_set_text(GTK_LABEL(state->label_current_name_type),
"Domain:");
} else {
gtk_label_set_text(GTK_LABEL(state->label_current_name_type), "Workgroup:");
gtk_label_set_text(GTK_LABEL(state->label_current_name_type),
"Workgroup:");
}
}
}
@ -365,7 +369,8 @@ static void callback_do_join(GtkWidget *widget,
uint32_t unjoin_flags = 0;
gboolean domain_join = FALSE;
gboolean try_unjoin = FALSE;
const char *domain_or_workgroup = NULL;
const char *new_workgroup_type = NULL;
const char *initial_workgroup_type = NULL;
struct join_state *state = (struct join_state *)data;
@ -376,14 +381,33 @@ static void callback_do_join(GtkWidget *widget,
gtk_widget_destroy(GTK_WIDGET(state->window_creds_prompt));
}
switch (state->name_type_initial) {
case NetSetupWorkgroupName:
initial_workgroup_type = "workgroup";
break;
case NetSetupDomainName:
initial_workgroup_type = "domain";
break;
default:
break;
}
switch (state->name_type_new) {
case NetSetupWorkgroupName:
new_workgroup_type = "workgroup";
break;
case NetSetupDomainName:
new_workgroup_type = "domain";
break;
default:
break;
}
if (state->name_type_new == NetSetupDomainName) {
domain_join = TRUE;
join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED; /* for testing */
domain_or_workgroup = "domain";
} else {
domain_or_workgroup = "workgroup";
}
if ((state->name_type_initial == NetSetupDomainName) &&
@ -394,7 +418,7 @@ static void callback_do_join(GtkWidget *widget,
}
debug("callback_do_join: Joining a %s named %s using join_flags 0x%08x ",
domain_or_workgroup,
new_workgroup_type,
state->name_buffer_new,
join_flags);
if (domain_join) {
@ -422,8 +446,8 @@ static void callback_do_join(GtkWidget *widget,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"The following error occured attempting to unjoin the %s: \"%s\": %s",
domain_or_workgroup,
state->name_buffer_new,
initial_workgroup_type,
state->name_buffer_initial,
err_str);
g_signal_connect_swapped(dialog, "response",
@ -451,7 +475,7 @@ static void callback_do_join(GtkWidget *widget,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"The following error occured attempting to join the %s: \"%s\": %s",
domain_or_workgroup,
new_workgroup_type,
state->name_buffer_new,
err_str);
@ -465,7 +489,7 @@ static void callback_do_join(GtkWidget *widget,
}
debug("callback_do_join: Successfully joined %s\n",
domain_or_workgroup);
new_workgroup_type);
dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_parent),
GTK_DIALOG_DESTROY_WITH_PARENT,
@ -473,7 +497,7 @@ static void callback_do_join(GtkWidget *widget,
GTK_BUTTONS_OK,
"Welcome to the %s %s.",
state->name_buffer_new,
domain_or_workgroup);
new_workgroup_type);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
@ -760,6 +784,8 @@ static void callback_do_change(GtkWidget *widget,
debug("callback_do_change called\n");
#if 0
/* FIXME: add proper warnings for Samba as a DC */
if (state->server_role == 3) {
GtkWidget *dialog;
dialog = gtk_message_dialog_new(GTK_WINDOW(state->window_main),
@ -774,13 +800,14 @@ static void callback_do_change(GtkWidget *widget,
gtk_widget_show(dialog);
return;
}
#endif
state->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Computer Name Changes");
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500); /* breite * höhe */
gtk_widget_set_size_request(GTK_WIDGET(window), 480, 500);
gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
g_signal_connect(G_OBJECT(window), "delete_event",
@ -830,14 +857,17 @@ static void callback_do_change(GtkWidget *widget,
char *str = NULL;
entry_text = gtk_entry_get_text(GTK_ENTRY(entry));
if (state->name_type_initial == NetSetupDomainName) {
asprintf(&str, "%s.%s", entry_text, state->my_dnsdomain);
asprintf(&str, "%s.%s", entry_text,
state->my_dnsdomain);
} else {
asprintf(&str, "%s.", entry_text);
}
gtk_label_set_text(GTK_LABEL(state->label_full_computer_name), str);
gtk_label_set_text(GTK_LABEL(state->label_full_computer_name),
str);
free(str);
gtk_misc_set_alignment(GTK_MISC(state->label_full_computer_name), 0, 0);
gtk_box_pack_start(GTK_BOX(box1), state->label_full_computer_name, TRUE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(box1),
state->label_full_computer_name, TRUE, TRUE, 0);
gtk_widget_show(state->label_full_computer_name);
}
@ -872,7 +902,8 @@ static void callback_do_change(GtkWidget *widget,
G_CALLBACK(callback_continue),
(gpointer)state);
if (state->name_type_initial == NetSetupDomainName) {
gtk_entry_set_text(GTK_ENTRY(state->entry_domain), state->name_buffer_initial);
gtk_entry_set_text(GTK_ENTRY(state->entry_domain),
state->name_buffer_initial);
gtk_widget_set_sensitive(state->entry_workgroup, FALSE);
gtk_widget_set_sensitive(state->entry_domain, TRUE);
}
@ -893,7 +924,8 @@ static void callback_do_change(GtkWidget *widget,
G_CALLBACK(callback_do_join_workgroup),
(gpointer)state);
{
gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup), MAX_NETBIOS_NAME_LEN);
gtk_entry_set_max_length(GTK_ENTRY(state->entry_workgroup),
MAX_NETBIOS_NAME_LEN);
g_signal_connect(G_OBJECT(state->entry_workgroup), "changed",
G_CALLBACK(callback_enter_workgroup_and_unlock),
(gpointer)state);
@ -902,7 +934,8 @@ static void callback_do_change(GtkWidget *widget,
(gpointer)state);
if (state->name_type_initial == NetSetupWorkgroupName) {
gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup), state->name_buffer_initial);
gtk_entry_set_text(GTK_ENTRY(state->entry_workgroup),
state->name_buffer_initial);
gtk_widget_set_sensitive(GTK_WIDGET(state->entry_domain), FALSE);
gtk_widget_set_sensitive(GTK_WIDGET(state->entry_workgroup), TRUE);
}
@ -979,21 +1012,25 @@ static int draw_main_window(struct join_state *state)
icon = gdk_pixbuf_new_from_file(SAMBA_ICON_PATH,
&error);
if (icon == NULL) {
g_print("failed to load logo from %s : %s\n",
g_print("failed to load icon from %s : %s\n",
SAMBA_ICON_PATH, error->message);
}
#if 1
image = gtk_image_new_from_file(SAMBA_IMAGE_PATH);
image = gtk_image_new_from_file(SAMBA_IMAGE_PATH_SMALL);
#else
image = gtk_image_new_from_file("/usr/share/pixmaps/redhat-system_settings.png");
#endif
if (image == NULL) {
g_print("failed to load logo from %s : %s\n",
SAMBA_IMAGE_PATH_SMALL, error->message);
}
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
state->window_main = window;
gtk_window_set_title(GTK_WINDOW(window), "Samba - Join Domain dialogue");
gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600); /* breite * höhe */
gtk_widget_set_size_request(GTK_WIDGET(window), 600, 600);
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
gtk_window_set_icon_from_file(GTK_WINDOW(window), SAMBA_ICON_PATH, NULL);
@ -1015,14 +1052,15 @@ static int draw_main_window(struct join_state *state)
{
/* gtk_box_pack_start(GTK_BOX(main_vbox), image, TRUE, TRUE, 10); */
gtk_misc_set_alignment(GTK_MISC(image), 0, 0);
/* gtk_misc_set_alignment(GTK_MISC(image), 0, 0); */
gtk_widget_set_size_request(GTK_WIDGET(image), 150, 40);
gtk_box_pack_start(GTK_BOX(hbox), image, FALSE, FALSE, 10);
gtk_widget_show(image);
/* Label */
label = gtk_label_new("Samba uses the following information to identify your computer on the network.");
gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
gtk_widget_set_size_request(GTK_WIDGET(label), 500, 40);
/* gtk_misc_set_alignment(GTK_MISC(label), 0, 0); */
gtk_widget_set_size_request(GTK_WIDGET(label), 400, 40);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
gtk_widget_show(label);

View File

@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* Join Support (cmdline + netapi)
* Copyright (C) Guenther Deschner 2007
* Copyright (C) Guenther Deschner 2007-2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -56,7 +56,10 @@ int main(int argc, char **argv)
if (argc < 2) {
printf("usage: netdomjoin\n");
printf("\t[hostname=HOSTNAME] [domain=DOMAIN] <ou=OU> <usero=USERO> <passwordo=PASSWORDO> <userd=USERD> <passwordd=PASSWORDD>\n");
printf("\t[hostname] [domain=DOMAIN] <ou=OU> "
"<usero=USERO> <passwordo=PASSWORDO> "
"<userd=USERD> <passwordd=PASSWORDD> "
"<debug=DEBUGLEVEL>\n");
return 0;
}
@ -87,6 +90,11 @@ int main(int argc, char **argv)
str = get_string_param(argv[i]);
libnetapi_set_password(ctx, str);
}
if (strncasecmp(argv[i], "debug", strlen("debug"))== 0) {
const char *str = NULL;
str = get_string_param(argv[i]);
libnetapi_set_debuglevel(ctx, str);
}
}
status = NetJoinDomain(server_name,

View File

@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* NetApi Join Support
* Copyright (C) Guenther Deschner 2007
* Copyright (C) Guenther Deschner 2007-2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -54,8 +54,9 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx,
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
r->in.server_name = talloc_strdup(mem_ctx, info->domain_controller_name);
W_ERROR_HAVE_NO_MEMORY(r->in.server_name);
r->in.dc_name = talloc_strdup(mem_ctx,
info->domain_controller_name);
W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
}
if (account_ou) {
@ -69,8 +70,8 @@ static WERROR NetJoinDomainLocal(struct libnetapi_ctx *mem_ctx,
}
if (password) {
r->in.password = talloc_strdup(mem_ctx, password);
W_ERROR_HAVE_NO_MEMORY(r->in.password);
r->in.admin_password = talloc_strdup(mem_ctx, password);
W_ERROR_HAVE_NO_MEMORY(r->in.admin_password);
}
r->in.join_flags = join_flags;
@ -89,13 +90,11 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx,
{
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_cli = NULL;
struct wkssvc_PasswordBuffer encrypted_password;
struct wkssvc_PasswordBuffer *encrypted_password = NULL;
NTSTATUS status;
WERROR werr;
unsigned int old_timeout = 0;
ZERO_STRUCT(encrypted_password);
status = cli_full_connection(&cli, NULL, server_name,
NULL, 0,
"IPC$", "IPC",
@ -114,7 +113,7 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx,
if (!pipe_cli) {
werr = ntstatus_to_werror(status);
goto done;
};
}
if (password) {
encode_wkssvc_join_password_buffer(ctx,
@ -128,7 +127,7 @@ static WERROR NetJoinDomainRemote(struct libnetapi_ctx *ctx,
status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx,
server_name, domain_name,
account_ou, Account,
&encrypted_password,
encrypted_password,
join_flags, &werr);
if (!NT_STATUS_IS_OK(status)) {
werr = ntstatus_to_werror(status);
@ -224,8 +223,8 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx,
W_ERROR_NOT_OK_RETURN(werr);
if (server_name) {
r->in.server_name = talloc_strdup(mem_ctx, server_name);
W_ERROR_HAVE_NO_MEMORY(r->in.server_name);
r->in.dc_name = talloc_strdup(mem_ctx, server_name);
W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
} else {
NTSTATUS status;
@ -233,7 +232,6 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx,
struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
DS_WRITABLE_REQUIRED |
DS_IS_FLAT_NAME |
DS_RETURN_DNS_NAME;
if (lp_realm()) {
domain = lp_realm();
@ -245,8 +243,9 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx,
if (!NT_STATUS_IS_OK(status)) {
return ntstatus_to_werror(status);
}
r->in.server_name = talloc_strdup(mem_ctx, info->domain_controller_name);
W_ERROR_HAVE_NO_MEMORY(r->in.server_name);
r->in.dc_name = talloc_strdup(mem_ctx,
info->domain_controller_name);
W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
}
if (account) {
@ -255,8 +254,8 @@ static WERROR NetUnjoinDomainLocal(struct libnetapi_ctx *mem_ctx,
}
if (password) {
r->in.password = talloc_strdup(mem_ctx, password);
W_ERROR_HAVE_NO_MEMORY(r->in.password);
r->in.admin_password = talloc_strdup(mem_ctx, password);
W_ERROR_HAVE_NO_MEMORY(r->in.admin_password);
}
r->in.unjoin_flags = unjoin_flags;
@ -276,13 +275,11 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx,
{
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_cli = NULL;
struct wkssvc_PasswordBuffer encrypted_password;
struct wkssvc_PasswordBuffer *encrypted_password = NULL;
NTSTATUS status;
WERROR werr;
unsigned int old_timeout = 0;
ZERO_STRUCT(encrypted_password);
status = cli_full_connection(&cli, NULL, server_name,
NULL, 0,
"IPC$", "IPC",
@ -301,7 +298,7 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx,
if (!pipe_cli) {
werr = ntstatus_to_werror(status);
goto done;
};
}
if (password) {
encode_wkssvc_join_password_buffer(ctx,
@ -315,7 +312,7 @@ static WERROR NetUnjoinDomainRemote(struct libnetapi_ctx *ctx,
status = rpccli_wkssvc_NetrUnjoinDomain2(pipe_cli, ctx,
server_name,
account,
&encrypted_password,
encrypted_password,
unjoin_flags,
&werr);
if (!NT_STATUS_IS_OK(status)) {
@ -408,7 +405,7 @@ static WERROR NetGetJoinInformationRemote(struct libnetapi_ctx *ctx,
if (!pipe_cli) {
werr = ntstatus_to_werror(status);
goto done;
};
}
status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, ctx,
server_name,

View File

@ -167,9 +167,8 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx,
return WERR_NOT_SUPPORTED;
}
return libnet_smbconf_set_global_param(ctx,
"server string",
info1005->comment);
return libnet_conf_set_global_parameter("server string",
info1005->comment);
}
static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx,

View File

@ -414,6 +414,7 @@ static void get_credentials_file(const char *file)
* -N,--no-pass
* -S,--signing
* -P --machine-pass
* -e --encrypt
*/
@ -532,6 +533,10 @@ static void popt_common_credentials_callback(poptContext con,
case 'N':
set_cmdline_auth_info_password("");
break;
case 'e':
set_cmdline_auth_info_smb_encrypt();
break;
}
}
@ -543,5 +548,6 @@ struct poptOption popt_common_credentials[] = {
{ "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
{ "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" },
{"machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" },
{"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
POPT_TABLEEND
};

View File

@ -233,6 +233,10 @@ typedef unsigned short int sa_family_t;
#endif
#endif
#ifdef HAVE_AIX_SOCKADDR_STORAGE
#define ss_family __ss_family
#endif
#ifndef HAVE_STRUCT_ADDRINFO
#define HAVE_STRUCT_ADDRINFO
struct addrinfo {

View File

@ -59,7 +59,7 @@ void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, enum security_ace_type type,
{
t->type = type;
t->flags = flag;
t->size = sid_size(sid) + 8;
t->size = ndr_size_dom_sid(sid, 0) + 8;
t->access_mask = mask;
ZERO_STRUCTP(&t->trustee);
@ -86,7 +86,7 @@ NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsign
(*pp_new)[i].type = SEC_ACE_TYPE_ACCESS_ALLOWED;
(*pp_new)[i].flags = 0;
(*pp_new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid);
(*pp_new)[i].size = SEC_ACE_HEADER_SIZE + ndr_size_dom_sid(sid, 0);
(*pp_new)[i].access_mask = mask;
sid_copy(&(*pp_new)[i].trustee, sid);
return NT_STATUS_OK;

View File

@ -31,35 +31,6 @@ const struct generic_mapping file_generic_mapping = {
FILE_GENERIC_ALL
};
/*******************************************************************
Works out the linearization size of a SEC_DESC.
********************************************************************/
size_t sec_desc_size(SEC_DESC *psd)
{
size_t offset;
if (!psd) return 0;
offset = SEC_DESC_HEADER_SIZE;
/* don't align */
if (psd->owner_sid != NULL)
offset += sid_size(psd->owner_sid);
if (psd->group_sid != NULL)
offset += sid_size(psd->group_sid);
if (psd->sacl != NULL)
offset += psd->sacl->size;
if (psd->dacl != NULL)
offset += psd->dacl->size;
return offset;
}
/*******************************************************************
Compares two SEC_DESC structures
********************************************************************/
@ -235,11 +206,11 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx,
}
if (dst->owner_sid != NULL) {
offset += sid_size(dst->owner_sid);
offset += ndr_size_dom_sid(dst->owner_sid, 0);
}
if (dst->group_sid != NULL) {
offset += sid_size(dst->group_sid);
offset += ndr_size_dom_sid(dst->group_sid, 0);
}
*sd_size = (size_t)offset;
@ -274,25 +245,21 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
struct security_descriptor *secdesc,
uint8 **data, size_t *len)
{
prs_struct ps;
if (!prs_init(&ps, sec_desc_size(secdesc), mem_ctx, MARSHALL)) {
return NT_STATUS_NO_MEMORY;
DATA_BLOB blob;
enum ndr_err_code ndr_err;
ndr_err = ndr_push_struct_blob(
&blob, mem_ctx, secdesc,
(ndr_push_flags_fn_t)ndr_push_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(0, ("ndr_push_security_descriptor failed: %s\n",
ndr_errstr(ndr_err)));
return ndr_map_error2ntstatus(ndr_err);;
}
if (!sec_io_desc("security_descriptor", &secdesc, &ps, 1)) {
prs_mem_free(&ps);
return NT_STATUS_INVALID_PARAMETER;
}
if (!(*data = (uint8 *)talloc_memdup(mem_ctx, ps.data_p,
prs_offset(&ps)))) {
prs_mem_free(&ps);
return NT_STATUS_NO_MEMORY;
}
*len = prs_offset(&ps);
prs_mem_free(&ps);
*data = blob.data;
*len = blob.length;
return NT_STATUS_OK;
}
@ -302,25 +269,33 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
struct security_descriptor **psecdesc)
{
prs_struct ps;
struct security_descriptor *secdesc = NULL;
DATA_BLOB blob;
enum ndr_err_code ndr_err;
struct security_descriptor *result;
if (!(secdesc = TALLOC_ZERO_P(mem_ctx, struct security_descriptor))) {
return NT_STATUS_NO_MEMORY;
}
if (!prs_init(&ps, 0, secdesc, UNMARSHALL)) {
return NT_STATUS_NO_MEMORY;
}
prs_give_memory(&ps, (char *)data, len, False);
if (!sec_io_desc("security_descriptor", &secdesc, &ps, 1)) {
if ((data == NULL) || (len == 0)) {
return NT_STATUS_INVALID_PARAMETER;
}
prs_mem_free(&ps);
*psecdesc = secdesc;
result = TALLOC_ZERO_P(mem_ctx, struct security_descriptor);
if (result == NULL) {
return NT_STATUS_NO_MEMORY;
}
blob = data_blob_const(data, len);
ndr_err = ndr_pull_struct_blob(
&blob, result, result,
(ndr_pull_flags_fn_t)ndr_pull_security_descriptor);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(0, ("ndr_pull_security_descriptor failed: %s\n",
ndr_errstr(ndr_err)));
TALLOC_FREE(result);
return ndr_map_error2ntstatus(ndr_err);;
}
*psecdesc = result;
return NT_STATUS_OK;
}

View File

@ -144,7 +144,7 @@ SEC_DESC *get_share_security( TALLOC_CTX *ctx, const char *servicename,
}
if (psd)
*psize = sec_desc_size(psd);
*psize = ndr_size_security_descriptor(psd, 0);
return psd;
}

View File

@ -289,7 +289,8 @@ static struct user_auth_info cmdline_auth_info = {
NULL, /* password */
false, /* got_pass */
false, /* use_kerberos */
Undefined /* signing state */
Undefined, /* signing state */
false /* smb_encrypt */
};
const char *get_cmdline_auth_info_username(void)
@ -362,11 +363,22 @@ void set_cmdline_auth_info_use_krb5_ticket(void)
cmdline_auth_info.got_pass = true;
}
/* This should only be used by lib/popt_common.c JRA */
void set_cmdline_auth_info_smb_encrypt(void)
{
cmdline_auth_info.smb_encrypt = true;
}
bool get_cmdline_auth_info_got_pass(void)
{
return cmdline_auth_info.got_pass;
}
bool get_cmdline_auth_info_smb_encrypt(void)
{
return cmdline_auth_info.smb_encrypt;
}
bool get_cmdline_auth_info_copy(struct user_auth_info *info)
{
*info = cmdline_auth_info;
@ -604,6 +616,19 @@ void show_msg(char *buf)
dump_data(10, (uint8 *)smb_buf(buf), bcc);
}
/*******************************************************************
Set the length and marker of an encrypted smb packet.
********************************************************************/
void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
{
_smb_setlen(buf,len);
SCVAL(buf,4,0xFF);
SCVAL(buf,5,'E');
SSVAL(buf,6,enc_ctx_num);
}
/*******************************************************************
Set the length and marker of an smb packet.
********************************************************************/
@ -618,21 +643,6 @@ void smb_setlen(char *buf,int len)
SCVAL(buf,7,'B');
}
/*******************************************************************
Setup the word count and byte count for a smb message.
********************************************************************/
int set_message(char *buf,int num_words,int num_bytes,bool zero)
{
if (zero && (num_words || num_bytes)) {
memset(buf + smb_size,'\0',num_words*2 + num_bytes);
}
SCVAL(buf,smb_wct,num_words);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
return (smb_size + num_words*2 + num_bytes);
}
/*******************************************************************
Setup only the byte count for a smb message.
********************************************************************/
@ -641,20 +651,10 @@ int set_message_bcc(char *buf,int num_bytes)
{
int num_words = CVAL(buf,smb_wct);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
_smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
return (smb_size + num_words*2 + num_bytes);
}
/*******************************************************************
Setup only the byte count for a smb message, using the end of the
message as a marker.
********************************************************************/
int set_message_end(void *outbuf,void *end_ptr)
{
return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
}
/*******************************************************************
Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
Return the bytes added

View File

@ -57,7 +57,7 @@ done:
*/
bool registry_init_regdb(void)
{
bool ret = False;
bool ret = false;
int saved_errno = 0;
static REGISTRY_HOOK smbconf_reg_hook = {KEY_SMBCONF, &smbconf_reg_ops};
@ -78,7 +78,7 @@ bool registry_init_regdb(void)
goto done;
}
ret = True;
ret = true;
done:
return ret;

View File

@ -382,7 +382,7 @@ bool sid_linearize(char *outbuf, size_t len, const DOM_SID *sid)
{
size_t i;
if (len < sid_size(sid))
if (len < ndr_size_dom_sid(sid, 0))
return False;
SCVAL(outbuf,0,sid->sid_rev_num);
@ -494,18 +494,6 @@ bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
return sid_compare(sid1, sid2) == 0;
}
/*****************************************************************
Calculates size of a sid.
*****************************************************************/
size_t sid_size(const DOM_SID *sid)
{
if (sid == NULL)
return 0;
return sid->num_auths * sizeof(uint32) + 8;
}
/*****************************************************************
Returns true if SID is internal (and non-mappable).
*****************************************************************/
@ -535,7 +523,7 @@ bool non_mappable_sid(DOM_SID *sid)
char *sid_binstring(const DOM_SID *sid)
{
char *buf, *s;
int len = sid_size(sid);
int len = ndr_size_dom_sid(sid, 0);
buf = (char *)SMB_MALLOC(len);
if (!buf)
return NULL;
@ -553,7 +541,7 @@ char *sid_binstring(const DOM_SID *sid)
char *sid_binstring_hex(const DOM_SID *sid)
{
char *buf, *s;
int len = sid_size(sid);
int len = ndr_size_dom_sid(sid, 0);
buf = (char *)SMB_MALLOC(len);
if (!buf)
return NULL;

View File

@ -1276,56 +1276,6 @@ ssize_t receive_smb_raw(int fd,
return len;
}
/****************************************************************************
Wrapper for receive_smb_raw().
Checks the MAC on signed packets.
****************************************************************************/
bool receive_smb(int fd, char *buffer, unsigned int timeout, enum smb_read_errors *pre)
{
if (receive_smb_raw(fd, buffer, timeout, 0, pre) < 0) {
return false;
}
/* Check the incoming SMB signature. */
if (!srv_check_sign_mac(buffer, true)) {
DEBUG(0, ("receive_smb: SMB Signature verification "
"failed on incoming packet!\n"));
cond_set_smb_read_error(pre,SMB_READ_BAD_SIG);
return false;
}
return true;
}
/****************************************************************************
Send an smb to a fd.
****************************************************************************/
bool send_smb(int fd, char *buffer)
{
size_t len;
size_t nwritten=0;
ssize_t ret;
/* Sign the outgoing packet if required. */
srv_calculate_sign_mac(buffer);
len = smb_len(buffer) + 4;
while (nwritten < len) {
ret = write_data(fd,buffer+nwritten,len - nwritten);
if (ret <= 0) {
DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
(int)len,(int)ret, strerror(errno) ));
return false;
}
nwritten += ret;
}
return true;
}
/****************************************************************************
Open a socket of the specified type, port, and address for incoming data.
****************************************************************************/
@ -1800,18 +1750,66 @@ static bool matchname(const char *remotehost,
return false;
}
static struct {
struct sockaddr_storage ss;
char *name;
} nc;
/*******************************************************************
Deal with the singleton cache.
******************************************************************/
struct name_addr_pair {
struct sockaddr_storage ss;
const char *name;
};
/*******************************************************************
Lookup a name/addr pair. Returns memory allocated from memcache.
******************************************************************/
static bool lookup_nc(struct name_addr_pair *nc)
{
DATA_BLOB tmp;
ZERO_STRUCTP(nc);
if (!memcache_lookup(
NULL, SINGLETON_CACHE,
data_blob_string_const("get_peer_name"),
&tmp)) {
return false;
}
memcpy(&nc->ss, tmp.data, sizeof(nc->ss));
nc->name = (const char *)tmp.data + sizeof(nc->ss);
return true;
}
/*******************************************************************
Save a name/addr pair.
******************************************************************/
static void store_nc(const struct name_addr_pair *nc)
{
DATA_BLOB tmp;
size_t namelen = strlen(nc->name);
tmp = data_blob(NULL, sizeof(nc->ss) + namelen + 1);
if (!tmp.data) {
return;
}
memcpy(tmp.data, &nc->ss, sizeof(nc->ss));
memcpy(tmp.data+sizeof(nc->ss), nc->name, namelen+1);
memcache_add(NULL, SINGLETON_CACHE,
data_blob_string_const("get_peer_name"),
tmp);
data_blob_free(&tmp);
}
/*******************************************************************
Return the DNS name of the remote end of a socket.
******************************************************************/
const char *get_peer_name(int fd,
bool force_lookup)
const char *get_peer_name(int fd, bool force_lookup)
{
struct name_addr_pair nc;
char addr_buf[INET6_ADDRSTRLEN];
struct sockaddr_storage ss;
socklen_t length = sizeof(ss);
@ -1826,13 +1824,15 @@ const char *get_peer_name(int fd,
possible */
if (!lp_hostname_lookups() && (force_lookup == false)) {
length = sizeof(nc.ss);
p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
nc.name = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
&nc.ss, &length);
SAFE_FREE(nc.name);
nc.name = SMB_STRDUP(p);
store_nc(&nc);
lookup_nc(&nc);
return nc.name ? nc.name : "UNKNOWN";
}
lookup_nc(&nc);
memset(&ss, '\0', sizeof(ss));
p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), &ss, &length);
@ -1841,9 +1841,7 @@ const char *get_peer_name(int fd,
return nc.name ? nc.name : "UNKNOWN";
}
/* Not the same. Reset the cache. */
zero_addr(&nc.ss);
SAFE_FREE(nc.name);
/* Not the same. We need to lookup. */
if (fd == -1) {
return "UNKNOWN";
}
@ -1880,7 +1878,11 @@ const char *get_peer_name(int fd,
strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
}
nc.name = SMB_STRDUP(name_buf);
nc.name = name_buf;
nc.ss = ss;
store_nc(&nc);
lookup_nc(&nc);
return nc.name ? nc.name : "UNKNOWN";
}
@ -2002,50 +2004,68 @@ out_umask:
const char *get_mydnsfullname(void)
{
static char *dnshostname_cache;
struct addrinfo *res = NULL;
char my_hostname[HOST_NAME_MAX];
bool ret;
DATA_BLOB tmp;
if (dnshostname_cache == NULL || !*dnshostname_cache) {
struct addrinfo *res = NULL;
char my_hostname[HOST_NAME_MAX];
bool ret;
/* get my host name */
if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
return NULL;
}
/* Ensure null termination. */
my_hostname[sizeof(my_hostname)-1] = '\0';
ret = interpret_string_addr_internal(&res,
my_hostname,
AI_ADDRCONFIG|AI_CANONNAME);
if (!ret || res == NULL) {
DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
"name %s [%s]\n",
my_hostname,
gai_strerror(ret) ));
return NULL;
}
/*
* Make sure that getaddrinfo() returns the "correct" host name.
*/
if (res->ai_canonname == NULL) {
DEBUG(3,("get_mydnsfullname: failed to get "
"canonical name for %s\n",
my_hostname));
freeaddrinfo(res);
return NULL;
}
dnshostname_cache = SMB_STRDUP(res->ai_canonname);
freeaddrinfo(res);
if (memcache_lookup(NULL, SINGLETON_CACHE,
data_blob_string_const("get_mydnsfullname"),
&tmp)) {
SMB_ASSERT(tmp.length > 0);
return (const char *)tmp.data;
}
return dnshostname_cache;
/* get my host name */
if (gethostname(my_hostname, sizeof(my_hostname)) == -1) {
DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
return NULL;
}
/* Ensure null termination. */
my_hostname[sizeof(my_hostname)-1] = '\0';
ret = interpret_string_addr_internal(&res,
my_hostname,
AI_ADDRCONFIG|AI_CANONNAME);
if (!ret || res == NULL) {
DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
"name %s [%s]\n",
my_hostname,
gai_strerror(ret) ));
return NULL;
}
/*
* Make sure that getaddrinfo() returns the "correct" host name.
*/
if (res->ai_canonname == NULL) {
DEBUG(3,("get_mydnsfullname: failed to get "
"canonical name for %s\n",
my_hostname));
freeaddrinfo(res);
return NULL;
}
/* This copies the data, so we must do a lookup
* afterwards to find the value to return.
*/
memcache_add(NULL, SINGLETON_CACHE,
data_blob_string_const("get_mydnsfullname"),
data_blob_string_const(res->ai_canonname));
freeaddrinfo(res);
if (!memcache_lookup(NULL, SINGLETON_CACHE,
data_blob_string_const("get_mydnsfullname"),
&tmp)) {
return NULL;
}
return (const char *)tmp.data;
}
/************************************************************

View File

@ -35,12 +35,12 @@ bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
result = wbcLookupName(dom_name, name, &dom_sid, &type);
if (result != WBC_ERR_SUCCESS)
return False;
return false;
memcpy(sid, &dom_sid, sizeof(DOM_SID));
*name_type = (enum lsa_SidType)type;
return True;
return true;
}
/* Call winbindd to convert sid to name */
@ -59,7 +59,7 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
result = wbcLookupSid(&dom_sid, &domain_name, &account_name, &type);
if (result != WBC_ERR_SUCCESS)
return False;
return false;
/* Copy out result */
@ -74,16 +74,16 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
sid_string_dbg(sid), domain_name, account_name));
SAFE_FREE(domain_name);
SAFE_FREE(account_name);
wbcFreeMemory(domain_name);
wbcFreeMemory(account_name);
if ((domain && !*domain) || (name && !*name)) {
DEBUG(0,("winbind_lookup_sid: talloc() failed!\n"));
return False;
return false;
}
return True;
return true;
}
/* Ping winbindd to see it is alive */
@ -192,8 +192,9 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
ret = wbcLookupRids(&dom_sid, num_rids, rids,
&dom_name, &namelist, &name_types);
if (ret != WBC_ERR_SUCCESS)
return False;
if (ret != WBC_ERR_SUCCESS) {
return false;
}
*domain_name = talloc_strdup(mem_ctx, dom_name);
*names = TALLOC_ARRAY(mem_ctx, const char*, num_rids);
@ -202,13 +203,13 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
for(i=0; i<num_rids; i++) {
(*names)[i] = talloc_strdup(names, namelist[i]);
(*types)[i] = (enum lsa_SidType)name_types[i];
free(CONST_DISCARD(char*, namelist[i]));
}
free(namelist);
free(name_types);
wbcFreeMemory(CONST_DISCARD(char*, dom_name));
wbcFreeMemory(namelist);
wbcFreeMemory(name_types);
return True;
return true;
}
/* Ask Winbind to allocate a new uid for us */
@ -238,7 +239,7 @@ bool winbind_allocate_gid(gid_t *gid)
bool winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
enum lsa_SidType *name_type)
{
return False;
return false;
}
/* Call winbindd to convert sid to name */
@ -247,42 +248,42 @@ bool winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
const char **domain, const char **name,
enum lsa_SidType *name_type)
{
return False;
return false;
}
/* Ping winbindd to see it is alive */
bool winbind_ping(void)
{
return False;
return false;
}
/* Call winbindd to convert SID to uid */
bool winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
{
return False;
return false;
}
/* Call winbindd to convert uid to sid */
bool winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
{
return False;
return false;
}
/* Call winbindd to convert SID to gid */
bool winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
{
return False;
return false;
}
/* Call winbindd to convert gid to sid */
bool winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
{
return False;
return false;
}
/* Check for a trusted domain */
@ -300,21 +301,21 @@ bool winbind_lookup_rids(TALLOC_CTX *mem_ctx,
const char **domain_name,
const char ***names, enum lsa_SidType **types)
{
return False;
return false;
}
/* Ask Winbind to allocate a new uid for us */
bool winbind_allocate_uid(uid_t *uid)
{
return False;
return false;
}
/* Ask Winbind to allocate a new gid for us */
bool winbind_allocate_gid(gid_t *gid)
{
return False;
return false;
}
#endif /* WITH_WINBIND */

View File

@ -141,3 +141,12 @@ const char *ads_errstr(ADS_STATUS status)
}
}
#ifdef HAVE_GSSAPI
NTSTATUS gss_err_to_ntstatus(uint32 maj, uint32 min)
{
ADS_STATUS adss = ADS_ERROR_GSS(maj, min);
DEBUG(10,("gss_err_to_ntstatus: Error %s\n",
ads_errstr(adss) ));
return ads_ntstatus(adss);
}
#endif

View File

@ -56,6 +56,10 @@ static void gotalarm_sig(void)
{
LDAP *ldp = NULL;
DEBUG(10, ("Opening connection to LDAP server '%s:%d', timeout "
"%u seconds\n", server, port, to));
/* Setup timeout */
gotalarm = 0;
CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
@ -65,8 +69,10 @@ static void gotalarm_sig(void)
ldp = ldap_open(server, port);
if (ldp == NULL) {
DEBUG(2,("Could not open LDAP connection to %s:%d: %s\n",
DEBUG(2,("Could not open connection to LDAP server %s:%d: %s\n",
server, port, strerror(errno)));
} else {
DEBUG(10, ("Connected to LDAP server '%s:%d'\n", server, port));
}
/* Teardown timeout. */
@ -400,7 +406,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
got_connection:
print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
DEBUG(3,("Connected to LDAP server %s\n", addr));
DEBUG(3,("Successfully contacted LDAP server %s\n", addr));
if (!ads->auth.user_name) {
/* Must use the userPrincipalName value here or sAMAccountName
@ -442,11 +448,12 @@ got_connection:
/* Otherwise setup the TCP LDAP session */
if ( (ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name,
LDAP_PORT, lp_ldap_timeout())) == NULL )
{
ads->ldap.ld = ldap_open_with_timeout(ads->config.ldap_server_name,
LDAP_PORT, lp_ldap_timeout());
if (ads->ldap.ld == NULL) {
return ADS_ERROR(LDAP_OPERATIONS_ERROR);
}
DEBUG(3,("Connected to LDAP server %s\n", ads->config.ldap_server_name));
/* cache the successful connection for workgroup and realm */
if (ads_closest_dc(ads)) {
@ -2384,20 +2391,22 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
LDAPMessage *msg, const char *field, SEC_DESC **sd)
{
struct berval **values;
bool ret = False;
bool ret = true;
values = ldap_get_values_len(ads->ldap.ld, msg, field);
if (!values) return False;
if (!values) return false;
if (values[0]) {
prs_struct ps;
prs_init(&ps, values[0]->bv_len, mem_ctx, UNMARSHALL);
prs_copy_data_in(&ps, values[0]->bv_val, values[0]->bv_len);
prs_set_offset(&ps,0);
ret = sec_io_desc("sd", sd, &ps, 1);
prs_mem_free(&ps);
NTSTATUS status;
status = unmarshall_sec_desc(mem_ctx,
(uint8 *)values[0]->bv_val,
values[0]->bv_len, sd);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("unmarshall_sec_desc failed: %s\n",
nt_errstr(status)));
ret = false;
}
}
ldap_value_free_len(values);
@ -2788,6 +2797,66 @@ ADS_STATUS ads_upn_suffixes(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char ***suffix
return status;
}
/**
* get the joinable ous for a domain
* @param ads connection to ads server
* @param mem_ctx Pointer to talloc context
* @param ous Pointer to an array of ous
* @param num_ous Pointer to the number of ous
* @return status of search
**/
ADS_STATUS ads_get_joinable_ous(ADS_STRUCT *ads,
TALLOC_CTX *mem_ctx,
char ***ous,
size_t *num_ous)
{
ADS_STATUS status;
LDAPMessage *res = NULL;
LDAPMessage *msg = NULL;
const char *attrs[] = { "dn", NULL };
int count = 0;
status = ads_search(ads, &res,
"(|(objectClass=domain)(objectclass=organizationalUnit))",
attrs);
if (!ADS_ERR_OK(status)) {
return status;
}
count = ads_count_replies(ads, res);
if (count < 1) {
ads_msgfree(ads, res);
return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
}
for (msg = ads_first_entry(ads, res); msg;
msg = ads_next_entry(ads, msg)) {
char *dn = NULL;
dn = ads_get_dn(ads, msg);
if (!dn) {
ads_msgfree(ads, res);
return ADS_ERROR(LDAP_NO_MEMORY);
}
if (!add_string_to_array(mem_ctx, dn,
(const char ***)ous,
(int *)num_ous)) {
ads_memfree(ads, dn);
ads_msgfree(ads, res);
return ADS_ERROR(LDAP_NO_MEMORY);
}
ads_memfree(ads, dn);
}
ads_msgfree(ads, res);
return status;
}
/**
* pull a DOM_SID from an extended dn string
* @param mem_ctx TALLOC_CTX

View File

@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* libnet smbconf registry Support
* Copyright (C) Michael Adam 2007
* Copyright (C) Michael Adam 2007-2008
* Copyright (C) Guenther Deschner 2007
*
* This program is free software; you can redistribute it and/or modify
@ -19,6 +19,12 @@
*/
#include "includes.h"
#include "libnet/libnet.h"
/*
* yuck - static variable to keep track of the registry initialization.
*/
static bool registry_initialized = false;
/**********************************************************************
*
@ -27,116 +33,164 @@
**********************************************************************/
/*
* Open a subkey of KEY_SMBCONF (i.e a service)
* - variant without error output (q = quiet)-
/**
* add a string to a talloced array of strings.
*/
static WERROR libnet_smbconf_open_path_q(TALLOC_CTX *ctx,
const char *subkeyname,
uint32 desired_access,
struct registry_key **key)
static WERROR libnet_conf_add_string_to_array(TALLOC_CTX *mem_ctx,
char ***array,
uint32_t count,
const char *string)
{
char **new_array = NULL;
if ((array == NULL) || (string == NULL)) {
return WERR_INVALID_PARAM;
}
new_array = TALLOC_REALLOC_ARRAY(mem_ctx, *array, char *, count + 1);
if (new_array == NULL) {
return WERR_NOMEM;
}
new_array[count] = talloc_strdup(new_array, string);
*array = new_array;
return WERR_OK;
}
static WERROR libnet_conf_reg_initialize(void)
{
WERROR werr = WERR_OK;
char *path = NULL;
NT_USER_TOKEN *token;
if (!(token = registry_create_admin_token(ctx))) {
DEBUG(1, ("Error creating admin token\n"));
if (registry_initialized) {
goto done;
}
if (subkeyname == NULL) {
path = talloc_strdup(ctx, KEY_SMBCONF);
} else {
path = talloc_asprintf(ctx, "%s\\%s", KEY_SMBCONF, subkeyname);
if (!registry_init_regdb()) {
werr = WERR_REG_IO_FAILURE;
goto done;
}
werr = reg_open_path(ctx, path, desired_access,
token, key);
registry_initialized = true;
done:
return werr;
}
/**
* Open a registry key specified by "path"
*/
static WERROR libnet_conf_reg_open_path(TALLOC_CTX *mem_ctx,
const char *path,
uint32 desired_access,
struct registry_key **key)
{
WERROR werr = WERR_OK;
NT_USER_TOKEN *token;
TALLOC_CTX *tmp_ctx = NULL;
if (path == NULL) {
DEBUG(1, ("Error: NULL path string given\n"));
werr = WERR_INVALID_PARAM;
goto done;
}
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
werr = WERR_NOMEM;
goto done;
}
werr = libnet_conf_reg_initialize();
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("Error initializing registry: %s\n",
dos_errstr(werr)));
goto done;
}
token = registry_create_admin_token(tmp_ctx);
if (token == NULL) {
DEBUG(1, ("Error creating admin token\n"));
/* what is the appropriate error code here? */
werr = WERR_CAN_NOT_COMPLETE;
goto done;
}
werr = reg_open_path(mem_ctx, path, desired_access, token, key);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("Error opening registry path '%s': %s\n",
path, dos_errstr(werr)));
}
done:
TALLOC_FREE(tmp_ctx);
return werr;
}
/**
* Open a subkey of KEY_SMBCONF (i.e a service)
*/
static WERROR libnet_conf_reg_open_service_key(TALLOC_CTX *ctx,
const char *servicename,
uint32 desired_access,
struct registry_key **key)
{
WERROR werr = WERR_OK;
char *path = NULL;
if (servicename == NULL) {
DEBUG(3, ("Error: NULL servicename given.\n"));
werr = WERR_INVALID_PARAM;
goto done;
}
path = talloc_asprintf(ctx, "%s\\%s", KEY_SMBCONF, servicename);
werr = libnet_conf_reg_open_path(ctx, path, desired_access, key);
done:
TALLOC_FREE(path);
return werr;
}
/*
* check if a subkey of KEY_SMBCONF of a given name exists
/**
* open the base key KEY_SMBCONF
*/
bool libnet_smbconf_key_exists(TALLOC_CTX *ctx, const char *subkeyname)
static WERROR libnet_conf_reg_open_base_key(TALLOC_CTX *ctx,
uint32 desired_access,
struct registry_key **key)
{
bool ret = False;
WERROR werr = WERR_OK;
TALLOC_CTX *mem_ctx;
struct registry_key *key;
if (!(mem_ctx = talloc_new(ctx))) {
d_fprintf(stderr, "ERROR: Out of memory...!\n");
goto done;
}
werr = libnet_smbconf_open_path_q(mem_ctx, subkeyname, REG_KEY_READ, &key);
if (W_ERROR_IS_OK(werr)) {
ret = True;
}
done:
TALLOC_FREE(mem_ctx);
return ret;
return libnet_conf_reg_open_path(ctx, KEY_SMBCONF, desired_access, key);
}
static bool libnet_smbconf_value_exists(TALLOC_CTX *ctx,
struct registry_key *key,
const char *param)
/**
* check if a value exists in a given registry key
*/
static bool libnet_conf_value_exists(struct registry_key *key,
const char *param)
{
bool ret = False;
bool ret = false;
WERROR werr = WERR_OK;
TALLOC_CTX *ctx = talloc_stackframe();
struct registry_value *value = NULL;
werr = reg_queryvalue(ctx, key, param, &value);
if (W_ERROR_IS_OK(werr)) {
ret = True;
ret = true;
}
TALLOC_FREE(value);
TALLOC_FREE(ctx);
return ret;
}
/*
* Open a subkey of KEY_SMBCONF (i.e a service)
* - variant with error output -
*/
WERROR libnet_smbconf_open_path(TALLOC_CTX *ctx, const char *subkeyname,
uint32 desired_access,
struct registry_key **key)
{
WERROR werr = WERR_OK;
werr = libnet_smbconf_open_path_q(ctx, subkeyname, desired_access, key);
if (!W_ERROR_IS_OK(werr)) {
d_fprintf(stderr, "Error opening registry path '%s\\%s': %s\n",
KEY_SMBCONF,
(subkeyname == NULL) ? "" : subkeyname,
dos_errstr(werr));
}
return werr;
}
/*
* open the base key KEY_SMBCONF
*/
WERROR libnet_smbconf_open_basepath(TALLOC_CTX *ctx, uint32 desired_access,
struct registry_key **key)
{
return libnet_smbconf_open_path(ctx, NULL, desired_access, key);
}
/*
/**
* create a subkey of KEY_SMBCONF
*/
WERROR libnet_smbconf_reg_createkey_internal(TALLOC_CTX *ctx,
const char * subkeyname,
struct registry_key **newkey)
static WERROR libnet_conf_reg_create_service_key(TALLOC_CTX *ctx,
const char * subkeyname,
struct registry_key **newkey)
{
WERROR werr = WERR_OK;
struct registry_key *create_parent = NULL;
@ -151,7 +205,8 @@ WERROR libnet_smbconf_reg_createkey_internal(TALLOC_CTX *ctx,
goto done;
}
werr = libnet_smbconf_open_basepath(create_ctx, REG_KEY_WRITE, &create_parent);
werr = libnet_conf_reg_open_base_key(create_ctx, REG_KEY_WRITE,
&create_parent);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
@ -159,12 +214,12 @@ WERROR libnet_smbconf_reg_createkey_internal(TALLOC_CTX *ctx,
werr = reg_createkey(ctx, create_parent, subkeyname,
REG_KEY_WRITE, newkey, &action);
if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
d_fprintf(stderr, "Key '%s' already exists.\n", subkeyname);
DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
werr = WERR_ALREADY_EXISTS;
}
if (!W_ERROR_IS_OK(werr)) {
d_fprintf(stderr, "Error creating key %s: %s\n",
subkeyname, dos_errstr(werr));
DEBUG(5, ("Error creating key %s: %s\n",
subkeyname, dos_errstr(werr)));
}
done:
@ -172,12 +227,12 @@ done:
return werr;
}
/*
/**
* add a value to a key.
*/
WERROR libnet_smbconf_reg_setvalue_internal(struct registry_key *key,
const char *valname,
const char *valstr)
static WERROR libnet_conf_reg_set_value(struct registry_key *key,
const char *valname,
const char *valstr)
{
struct registry_value val;
WERROR werr = WERR_OK;
@ -190,11 +245,11 @@ WERROR libnet_smbconf_reg_setvalue_internal(struct registry_key *key,
&canon_valstr))
{
if (canon_valname == NULL) {
d_fprintf(stderr, "invalid parameter '%s' given\n",
valname);
DEBUG(5, ("invalid parameter '%s' given\n",
valname));
} else {
d_fprintf(stderr, "invalid value '%s' given for "
"parameter '%s'\n", valstr, valname);
DEBUG(5, ("invalid value '%s' given for "
"parameter '%s'\n", valstr, valname));
}
werr = WERR_INVALID_PARAM;
goto done;
@ -207,16 +262,16 @@ WERROR libnet_smbconf_reg_setvalue_internal(struct registry_key *key,
val.v.sz.len = strlen(canon_valstr) + 1;
if (registry_smbconf_valname_forbidden(canon_valname)) {
d_fprintf(stderr, "Parameter '%s' not allowed in registry.\n",
canon_valname);
DEBUG(5, ("Parameter '%s' not allowed in registry.\n",
canon_valname));
werr = WERR_INVALID_PARAM;
goto done;
}
subkeyname = strrchr_m(key->key->name, '\\');
if ((subkeyname == NULL) || (*(subkeyname +1) == '\0')) {
d_fprintf(stderr, "Invalid registry key '%s' given as "
"smbconf section.\n", key->key->name);
DEBUG(5, ("Invalid registry key '%s' given as "
"smbconf section.\n", key->key->name));
werr = WERR_INVALID_PARAM;
goto done;
}
@ -224,88 +279,555 @@ WERROR libnet_smbconf_reg_setvalue_internal(struct registry_key *key,
if (!strequal(subkeyname, GLOBAL_NAME) &&
lp_parameter_is_global(valname))
{
d_fprintf(stderr, "Global paramter '%s' not allowed in "
DEBUG(5, ("Global paramter '%s' not allowed in "
"service definition ('%s').\n", canon_valname,
subkeyname);
subkeyname));
werr = WERR_INVALID_PARAM;
goto done;
}
werr = reg_setvalue(key, canon_valname, &val);
if (!W_ERROR_IS_OK(werr)) {
d_fprintf(stderr,
"Error adding value '%s' to "
DEBUG(5, ("Error adding value '%s' to "
"key '%s': %s\n",
canon_valname, key->key->name, dos_errstr(werr));
canon_valname, key->key->name, dos_errstr(werr)));
}
done:
return werr;
}
/**
* format a registry_value into a string.
*
* This is intended to be used for smbconf registry values,
* which are ar stored as REG_SZ values, so the incomplete
* handling should be ok.
*/
static char *libnet_conf_format_registry_value(TALLOC_CTX *mem_ctx,
struct registry_value *value)
{
char *result = NULL;
/* alternatively, create a new talloc context? */
if (mem_ctx == NULL) {
return result;
}
switch (value->type) {
case REG_DWORD:
result = talloc_asprintf(mem_ctx, "%d", value->v.dword);
break;
case REG_SZ:
case REG_EXPAND_SZ:
result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str);
break;
case REG_MULTI_SZ: {
uint32 j;
for (j = 0; j < value->v.multi_sz.num_strings; j++) {
result = talloc_asprintf(mem_ctx, "\"%s\" ",
value->v.multi_sz.strings[j]);
}
break;
}
case REG_BINARY:
result = talloc_asprintf(mem_ctx, "binary (%d bytes)",
(int)value->v.binary.length);
break;
default:
result = talloc_asprintf(mem_ctx, "<unprintable>");
break;
}
return result;
}
/**
* Get the values of a key as a list of value names
* and a list of value strings (ordered)
*/
static WERROR libnet_conf_reg_get_values(TALLOC_CTX *mem_ctx,
struct registry_key *key,
uint32_t *num_values,
char ***value_names,
char ***value_strings)
{
TALLOC_CTX *tmp_ctx = NULL;
WERROR werr = WERR_OK;
uint32_t count;
struct registry_value *valvalue = NULL;
char *valname = NULL;
char **tmp_valnames = NULL;
char **tmp_valstrings = NULL;
if ((num_values == NULL) || (value_names == NULL) ||
(value_strings == NULL))
{
werr = WERR_INVALID_PARAM;
goto done;
}
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
werr = WERR_NOMEM;
goto done;
}
for (count = 0;
W_ERROR_IS_OK(werr = reg_enumvalue(tmp_ctx, key, count, &valname,
&valvalue));
count++)
{
char *valstring;
werr = libnet_conf_add_string_to_array(tmp_ctx,
&tmp_valnames,
count, valname);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
valstring = libnet_conf_format_registry_value(tmp_ctx,
valvalue);
werr = libnet_conf_add_string_to_array(tmp_ctx,
&tmp_valstrings,
count,
valstring);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
}
if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
goto done;
}
werr = WERR_OK;
*num_values = count;
if (count > 0) {
*value_names = talloc_move(mem_ctx, &tmp_valnames);
*value_strings = talloc_move(mem_ctx, &tmp_valstrings);
} else {
*value_names = NULL;
*value_strings = NULL;
}
done:
TALLOC_FREE(tmp_ctx);
return werr;
}
/**********************************************************************
*
* The actual net conf api functions, that are exported.
*
**********************************************************************/
WERROR libnet_smbconf_setparm(TALLOC_CTX *mem_ctx,
const char *service,
const char *param,
const char *valstr)
/**
* Drop the whole configuration (restarting empty).
*/
WERROR libnet_conf_drop(void)
{
WERROR werr;
struct registry_key *key = NULL;
char *path, *p;
WERROR werr = WERR_OK;
struct registry_key *parent_key = NULL;
struct registry_key *new_key = NULL;
TALLOC_CTX* mem_ctx = talloc_stackframe();
enum winreg_CreateAction action;
if (!libnet_smbconf_key_exists(mem_ctx, service)) {
werr = libnet_smbconf_reg_createkey_internal(mem_ctx, service,
&key);
} else {
werr = libnet_smbconf_open_path(mem_ctx, service, REG_KEY_WRITE,
&key);
path = talloc_strdup(mem_ctx, KEY_SMBCONF);
if (path == NULL) {
werr = WERR_NOMEM;
goto done;
}
W_ERROR_NOT_OK_RETURN(werr);
p = strrchr(path, '\\');
*p = '\0';
werr = libnet_conf_reg_open_path(mem_ctx, path, REG_KEY_WRITE,
&parent_key);
werr = libnet_smbconf_reg_setvalue_internal(key, param, valstr);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
werr = reg_deletekey_recursive(mem_ctx, parent_key, p+1);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
werr = reg_createkey(mem_ctx, parent_key, p+1, REG_KEY_WRITE,
&new_key, &action);
done:
TALLOC_FREE(mem_ctx);
return werr;
}
WERROR libnet_smbconf_delparm(TALLOC_CTX *mem_ctx,
const char *service,
const char *param)
/**
* Get the whole configuration as lists of strings with counts:
*
* num_shares : number of shares
* share_names : list of length num_shares of share names
* num_params : list of length num_shares of parameter counts for each share
* param_names : list of lists of parameter names for each share
* param_values : list of lists of parameter values for each share
*/
WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
char ***share_names, uint32_t **num_params,
char ****param_names, char ****param_values)
{
WERROR werr = WERR_OK;
TALLOC_CTX *tmp_ctx = NULL;
uint32_t tmp_num_shares;
char **tmp_share_names;
uint32_t *tmp_num_params;
char ***tmp_param_names;
char ***tmp_param_values;
uint32_t count;
if ((num_shares == NULL) || (share_names == NULL) ||
(num_params == NULL) || (param_names == NULL) ||
(param_values == NULL))
{
werr = WERR_INVALID_PARAM;
goto done;
}
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
werr = WERR_NOMEM;
goto done;
}
werr = libnet_conf_get_share_names(tmp_ctx, &tmp_num_shares,
&tmp_share_names);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
tmp_num_params = TALLOC_ARRAY(tmp_ctx, uint32_t, tmp_num_shares);
tmp_param_names = TALLOC_ARRAY(tmp_ctx, char **, tmp_num_shares);
tmp_param_values = TALLOC_ARRAY(tmp_ctx, char **, tmp_num_shares);
if ((tmp_num_params == NULL) || (tmp_param_names == NULL) ||
(tmp_param_values == NULL))
{
werr = WERR_NOMEM;
goto done;
}
for (count = 0; count < tmp_num_shares; count++) {
werr = libnet_conf_get_share(mem_ctx, tmp_share_names[count],
&tmp_num_params[count],
&tmp_param_names[count],
&tmp_param_values[count]);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
}
werr = WERR_OK;
*num_shares = tmp_num_shares;
if (tmp_num_shares > 0) {
*share_names = talloc_move(mem_ctx, &tmp_share_names);
*num_params = talloc_move(mem_ctx, &tmp_num_params);
*param_names = talloc_move(mem_ctx, &tmp_param_names);
*param_values = talloc_move(mem_ctx, &tmp_param_values);
} else {
*share_names = NULL;
*num_params = NULL;
*param_names = NULL;
*param_values = NULL;
}
done:
TALLOC_FREE(tmp_ctx);
return werr;
}
/**
* get the list of share names defined in the configuration.
*/
WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
char ***share_names)
{
uint32_t count;
uint32_t added_count = 0;
TALLOC_CTX *tmp_ctx = NULL;
WERROR werr = WERR_OK;
struct registry_key *key = NULL;
char *subkey_name = NULL;
char **tmp_share_names = NULL;
if ((num_shares == NULL) || (share_names == NULL)) {
werr = WERR_INVALID_PARAM;
goto done;
}
tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
werr = WERR_NOMEM;
goto done;
}
/* make sure "global" is always listed first */
if (libnet_conf_share_exists(GLOBAL_NAME)) {
werr = libnet_conf_add_string_to_array(tmp_ctx,
&tmp_share_names,
0, GLOBAL_NAME);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
added_count++;
}
werr = libnet_conf_reg_open_base_key(tmp_ctx, SEC_RIGHTS_ENUM_SUBKEYS,
&key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
for (count = 0;
W_ERROR_IS_OK(werr = reg_enumkey(tmp_ctx, key, count,
&subkey_name, NULL));
count++)
{
if (strequal(subkey_name, GLOBAL_NAME)) {
continue;
}
werr = libnet_conf_add_string_to_array(tmp_ctx,
&tmp_share_names,
added_count,
subkey_name);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
added_count++;
}
if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
goto done;
}
werr = WERR_OK;
*num_shares = added_count;
if (added_count > 0) {
*share_names = talloc_move(mem_ctx, &tmp_share_names);
} else {
*share_names = NULL;
}
done:
TALLOC_FREE(tmp_ctx);
return werr;
}
/**
* check if a share/service of a given name exists
*/
bool libnet_conf_share_exists(const char *servicename)
{
bool ret = false;
WERROR werr = WERR_OK;
TALLOC_CTX *mem_ctx = talloc_stackframe();
struct registry_key *key = NULL;
werr = libnet_conf_reg_open_service_key(mem_ctx, servicename,
REG_KEY_READ, &key);
if (W_ERROR_IS_OK(werr)) {
ret = true;
}
TALLOC_FREE(mem_ctx);
return ret;
}
/**
* Add a service if it does not already exist.
*/
WERROR libnet_conf_create_share(const char *servicename)
{
WERROR werr;
TALLOC_CTX *mem_ctx = talloc_stackframe();
struct registry_key *key = NULL;
if (libnet_conf_share_exists(servicename)) {
werr = WERR_ALREADY_EXISTS;
goto done;
}
werr = libnet_conf_reg_create_service_key(mem_ctx, servicename, &key);
done:
TALLOC_FREE(mem_ctx);
return werr;
}
/**
* get a definition of a share (service) from configuration.
*/
WERROR libnet_conf_get_share(TALLOC_CTX *mem_ctx, const char *servicename,
uint32_t *num_params, char ***param_names,
char ***param_values)
{
WERROR werr = WERR_OK;
struct registry_key *key = NULL;
werr = libnet_conf_reg_open_service_key(mem_ctx, servicename,
REG_KEY_READ, &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
werr = libnet_conf_reg_get_values(mem_ctx, key, num_params,
param_names, param_values);
done:
TALLOC_FREE(key);
return werr;
}
/**
* delete a service from configuration
*/
WERROR libnet_conf_delete_share(const char *servicename)
{
WERROR werr = WERR_OK;
struct registry_key *key = NULL;
TALLOC_CTX *ctx = talloc_stackframe();
werr = libnet_conf_reg_open_base_key(ctx, REG_KEY_WRITE, &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
werr = reg_deletekey_recursive(key, key, servicename);
done:
TALLOC_FREE(ctx);
return werr;
}
/**
* set a configuration parameter to the value provided.
*/
WERROR libnet_conf_set_parameter(const char *service,
const char *param,
const char *valstr)
{
WERROR werr;
struct registry_key *key = NULL;
TALLOC_CTX *mem_ctx = talloc_stackframe();
if (!libnet_conf_share_exists(service)) {
werr = WERR_NO_SUCH_SERVICE;
goto done;
}
werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_WRITE,
&key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
werr = libnet_conf_reg_set_value(key, param, valstr);
done:
TALLOC_FREE(mem_ctx);
return werr;
}
/**
* get the value of a configuration parameter as a string
*/
WERROR libnet_conf_get_parameter(TALLOC_CTX *mem_ctx,
const char *service,
const char *param,
char **valstr)
{
WERROR werr = WERR_OK;
struct registry_key *key = NULL;
struct registry_value *value = NULL;
if (valstr == NULL) {
werr = WERR_INVALID_PARAM;
goto done;
}
if (!libnet_conf_share_exists(service)) {
werr = WERR_NO_SUCH_SERVICE;
goto done;
}
werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_READ,
&key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
if (!libnet_conf_value_exists(key, param)) {
werr = WERR_INVALID_PARAM;
goto done;
}
werr = reg_queryvalue(mem_ctx, key, param, &value);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
*valstr = libnet_conf_format_registry_value(mem_ctx, value);
if (*valstr == NULL) {
werr = WERR_NOMEM;
}
done:
TALLOC_FREE(key);
TALLOC_FREE(value);
return werr;
}
/**
* delete a parameter from configuration
*/
WERROR libnet_conf_delete_parameter(const char *service, const char *param)
{
struct registry_key *key = NULL;
WERROR werr = WERR_OK;
TALLOC_CTX *mem_ctx = talloc_stackframe();
if (!libnet_smbconf_key_exists(mem_ctx, service)) {
if (!libnet_conf_share_exists(service)) {
return WERR_NO_SUCH_SERVICE;
}
werr = libnet_smbconf_open_path(mem_ctx, service, REG_KEY_READ, &key);
W_ERROR_NOT_OK_RETURN(werr);
werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_ALL,
&key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}
if (!libnet_smbconf_value_exists(mem_ctx, key, param)) {
return WERR_INVALID_PARAM;
if (!libnet_conf_value_exists(key, param)) {
werr = WERR_INVALID_PARAM;
goto done;
}
werr = reg_deletevalue(key, param);
W_ERROR_NOT_OK_RETURN(werr);
return WERR_OK;
done:
TALLOC_FREE(mem_ctx);
return werr;
}
/**********************************************************************
*
* Convenience functions, that are also exportet.
* Convenience functions that are also exported.
*
**********************************************************************/
WERROR libnet_smbconf_set_global_param(TALLOC_CTX *mem_ctx,
const char *param,
const char *val)
WERROR libnet_conf_set_global_parameter(const char *param, const char *val)
{
return libnet_smbconf_setparm(mem_ctx, GLOBAL_NAME, param, val);
return libnet_conf_set_parameter(GLOBAL_NAME, param, val);
}

View File

@ -2,7 +2,7 @@
* Unix SMB/CIFS implementation.
* libnet Join Support
* Copyright (C) Gerald (Jerry) Carter 2006
* Copyright (C) Guenther Deschner 2007
* Copyright (C) Guenther Deschner 2007-2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,12 +22,30 @@
#include "libnet/libnet_join.h"
#include "libnet/libnet_proto.h"
static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
static bool libnet_join_joindomain_store_secrets(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
if (!secrets_store_domain_sid(r->out.netbios_domain_name,
r->out.domain_sid))
{
return false;
}
if (!secrets_store_machine_password(r->in.machine_password,
r->out.netbios_domain_name,
SEC_CHAN_WKSTA))
{
return false;
}
return true;
}
static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_hnd = NULL;
const char *password = NULL;
POLICY_HND sam_pol, domain_pol, user_pol, lsa_pol;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
char *acct_name;
@ -46,17 +64,20 @@ static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
DATA_BLOB digested_session_key;
uchar md4_trust_password[16];
password = talloc_strdup(mem_ctx,
generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH));
NT_STATUS_HAVE_NO_MEMORY(password);
if (!r->in.machine_password) {
r->in.machine_password = talloc_strdup(mem_ctx, generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH));
NT_STATUS_HAVE_NO_MEMORY(r->in.machine_password);
}
status = cli_full_connection(&cli, NULL, r->in.server_name,
status = cli_full_connection(&cli, NULL,
r->in.dc_name,
NULL, 0,
"IPC$", "IPC",
r->in.admin_account,
NULL, //r->in.domain_name,
r->in.password,
0, Undefined, NULL);
NULL,
r->in.admin_password,
0,
Undefined, NULL);
if (!NT_STATUS_IS_OK(status)) {
goto done;
@ -152,15 +173,16 @@ static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
goto done;
}
E_md4hash(r->in.password, md4_trust_password);
encode_pw_buffer(pwbuf, r->in.password, STR_UNICODE);
E_md4hash(r->in.machine_password, md4_trust_password);
encode_pw_buffer(pwbuf, r->in.machine_password, STR_UNICODE);
generate_random_buffer((uint8*)md5buffer, sizeof(md5buffer));
digested_session_key = data_blob_talloc(mem_ctx, 0, 16);
MD5Init(&md5ctx);
MD5Update(&md5ctx, md5buffer, sizeof(md5buffer));
MD5Update(&md5ctx, cli->user_session_key.data, cli->user_session_key.length);
MD5Update(&md5ctx, cli->user_session_key.data,
cli->user_session_key.length);
MD5Final(digested_session_key.data, &md5ctx);
SamOEMhashBlob(pwbuf, sizeof(pwbuf), &digested_session_key);
@ -194,21 +216,6 @@ static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
cli_rpc_pipe_close(pipe_hnd);
if (!secrets_store_domain_sid(r->out.netbios_domain_name,
r->out.domain_sid))
{
status = NT_STATUS_INTERNAL_DB_ERROR;
goto done;
}
if (!secrets_store_machine_password(password,
r->out.netbios_domain_name,
SEC_CHAN_WKSTA))
{
status = NT_STATUS_INTERNAL_DB_ERROR;
goto done;
}
status = NT_STATUS_OK;
done:
if (cli) {
@ -218,8 +225,22 @@ static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
return status;
}
static NTSTATUS do_DomainUnjoin(TALLOC_CTX *mem_ctx,
struct libnet_UnjoinCtx *r)
static bool libnet_join_unjoindomain_remove_secrets(TALLOC_CTX *mem_ctx,
struct libnet_UnjoinCtx *r)
{
if (!secrets_delete_machine_password_ex(lp_workgroup())) {
return false;
}
if (!secrets_delete_domain_sid(lp_workgroup())) {
return false;
}
return true;
}
static NTSTATUS libnet_join_unjoindomain_rpc(TALLOC_CTX *mem_ctx,
struct libnet_UnjoinCtx *r)
{
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_hnd = NULL;
@ -233,12 +254,13 @@ static NTSTATUS do_DomainUnjoin(TALLOC_CTX *mem_ctx,
SAM_USERINFO_CTR ctr, *qctr = NULL;
SAM_USER_INFO_16 p16;
status = cli_full_connection(&cli, NULL, r->in.server_name,
status = cli_full_connection(&cli, NULL,
r->in.dc_name,
NULL, 0,
"IPC$", "IPC",
r->in.admin_account,
NULL, //r->in.domain_name,
r->in.password,
NULL,
r->in.admin_password,
0, Undefined, NULL);
if (!NT_STATUS_IS_OK(status)) {
@ -308,21 +330,12 @@ static NTSTATUS do_DomainUnjoin(TALLOC_CTX *mem_ctx,
rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
if (!secrets_delete_machine_password_ex(lp_workgroup())) {
status = NT_STATUS_INTERNAL_DB_ERROR;
goto done;
}
if (!secrets_delete_domain_sid(lp_workgroup())) {
status = NT_STATUS_INTERNAL_DB_ERROR;
goto done;
}
done:
rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
rpccli_samr_close(pipe_hnd, mem_ctx, &sam_pol);
cli_rpc_pipe_close(pipe_hnd);
if (pipe_hnd) {
rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
rpccli_samr_close(pipe_hnd, mem_ctx, &sam_pol);
cli_rpc_pipe_close(pipe_hnd);
}
if (cli) {
cli_shutdown(cli);
@ -331,20 +344,18 @@ done:
return status;
}
static WERROR do_join_modify_vals_config(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r)
{
WERROR werr;
bool is_ad = false;
if (!(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE)) {
werr = libnet_smbconf_set_global_param(mem_ctx, "security",
"user");
werr = libnet_conf_set_global_parameter("security", "user");
W_ERROR_NOT_OK_RETURN(werr);
werr = libnet_smbconf_set_global_param(mem_ctx, "workgroup",
r->in.domain_name);
werr = libnet_conf_set_global_parameter("workgroup",
r->in.domain_name);
return werr;
}
@ -352,19 +363,18 @@ static WERROR do_join_modify_vals_config(TALLOC_CTX *mem_ctx,
is_ad = true;
}
werr = libnet_smbconf_set_global_param(mem_ctx, "security", "domain");
werr = libnet_conf_set_global_parameter("security", "domain");
W_ERROR_NOT_OK_RETURN(werr);
werr = libnet_smbconf_set_global_param(mem_ctx, "workgroup",
r->out.netbios_domain_name);
werr = libnet_conf_set_global_parameter("workgroup",
r->out.netbios_domain_name);
W_ERROR_NOT_OK_RETURN(werr);
if (is_ad) {
werr = libnet_smbconf_set_global_param(mem_ctx, "security",
"ads");
werr = libnet_conf_set_global_parameter("security", "ads");
W_ERROR_NOT_OK_RETURN(werr);
werr = libnet_smbconf_set_global_param(mem_ctx, "realm",
werr = libnet_conf_set_global_parameter("realm",
r->out.dns_domain_name);
W_ERROR_NOT_OK_RETURN(werr);
}
@ -372,26 +382,23 @@ static WERROR do_join_modify_vals_config(TALLOC_CTX *mem_ctx,
return werr;
}
static WERROR do_unjoin_modify_vals_config(TALLOC_CTX *mem_ctx,
struct libnet_UnjoinCtx *r)
static WERROR do_unjoin_modify_vals_config(struct libnet_UnjoinCtx *r)
{
WERROR werr = WERR_OK;
if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
werr = libnet_smbconf_set_global_param(mem_ctx, "security",
"user");
werr = libnet_conf_set_global_parameter("security", "user");
W_ERROR_NOT_OK_RETURN(werr);
}
werr = libnet_smbconf_delparm(mem_ctx, "GLOBAL", "realm");
werr = libnet_conf_delete_parameter(GLOBAL_NAME, "realm");
return werr;
}
static WERROR do_JoinConfig(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
static WERROR do_JoinConfig(struct libnet_JoinCtx *r)
{
WERROR werr;
@ -403,7 +410,7 @@ static WERROR do_JoinConfig(TALLOC_CTX *mem_ctx,
return WERR_OK;
}
werr = do_join_modify_vals_config(mem_ctx, r);
werr = do_join_modify_vals_config(r);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
@ -414,8 +421,7 @@ static WERROR do_JoinConfig(TALLOC_CTX *mem_ctx,
return werr;
}
static WERROR do_UnjoinConfig(TALLOC_CTX *mem_ctx,
struct libnet_UnjoinCtx *r)
static WERROR do_UnjoinConfig(struct libnet_UnjoinCtx *r)
{
WERROR werr;
@ -427,7 +433,7 @@ static WERROR do_UnjoinConfig(TALLOC_CTX *mem_ctx,
return WERR_OK;
}
werr = do_unjoin_modify_vals_config(mem_ctx, r);
werr = do_unjoin_modify_vals_config(r);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
@ -488,16 +494,20 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
status = do_DomainJoin(mem_ctx, r);
status = libnet_join_joindomain_rpc(mem_ctx, r);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
return WERR_SETUP_ALREADY_JOINED;
}
return ntstatus_to_werror(status);
}
if (!libnet_join_joindomain_store_secrets(mem_ctx, r)) {
return WERR_SETUP_NOT_JOINED;
}
}
werr = do_JoinConfig(mem_ctx, r);
werr = do_JoinConfig(r);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
@ -517,16 +527,18 @@ WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx,
if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
status = do_DomainUnjoin(mem_ctx, r);
status = libnet_join_unjoindomain_rpc(mem_ctx, r);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
return WERR_SETUP_NOT_JOINED;
}
return ntstatus_to_werror(status);
}
libnet_join_unjoindomain_remove_secrets(mem_ctx, r);
}
werr = do_UnjoinConfig(mem_ctx, r);
werr = do_UnjoinConfig(r);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}

View File

@ -1,7 +1,7 @@
/*
* Unix SMB/CIFS implementation.
* libnet Join Support
* Copyright (C) Guenther Deschner 2007
* Copyright (C) Guenther Deschner 2007-2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,11 +22,13 @@
struct libnet_JoinCtx {
struct {
const char *server_name;
const char *dc_name;
const char *machine_name;
const char *domain_name;
const char *account_ou;
const char *admin_account;
const char *password;
const char *admin_password;
const char *machine_password;
uint32_t join_flags;
const char *os_version;
const char *os_string;
@ -47,10 +49,10 @@ struct libnet_JoinCtx {
struct libnet_UnjoinCtx {
struct {
const char *server_name;
const char *dc_name;
const char *domain_name;
const char *admin_account;
const char *password;
const char *admin_password;
uint32_t unjoin_flags;
bool modify_config;
struct dom_sid *domain_sid;

View File

@ -98,7 +98,7 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
/* send a session setup command */
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,10, 0, True);
cli_set_message(cli->outbuf,10, 0, True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
@ -168,7 +168,7 @@ static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
uint32 capabilities = cli_session_setup_capabilities(cli);
memset(cli->outbuf, '\0', smb_size);
set_message(cli->outbuf,13,0,True);
cli_set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
@ -228,7 +228,7 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING);
memset(cli->outbuf, '\0', smb_size);
set_message(cli->outbuf,13,0,True);
cli_set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
@ -377,7 +377,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
/* send a session setup command */
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,13,0,True);
cli_set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
@ -457,7 +457,7 @@ static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
/* send a session setup command */
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,12,0,True);
cli_set_message(cli->outbuf,12,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
@ -1028,7 +1028,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
bool cli_ulogoff(struct cli_state *cli)
{
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,2,0,True);
cli_set_message(cli->outbuf,2,0,True);
SCVAL(cli->outbuf,smb_com,SMBulogoffX);
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0xFF);
@ -1106,7 +1106,7 @@ bool cli_send_tconX(struct cli_state *cli,
slprintf(fullshare, sizeof(fullshare)-1,
"\\\\%s\\%s", cli->desthost, share);
set_message(cli->outbuf,4, 0, True);
cli_set_message(cli->outbuf,4, 0, True);
SCVAL(cli->outbuf,smb_com,SMBtconX);
cli_setup_packet(cli);
@ -1157,7 +1157,7 @@ bool cli_send_tconX(struct cli_state *cli,
bool cli_tdis(struct cli_state *cli)
{
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
cli_set_message(cli->outbuf,0,0,True);
SCVAL(cli->outbuf,smb_com,SMBtdis);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@ -1189,7 +1189,7 @@ void cli_negprot_send(struct cli_state *cli)
memset(cli->outbuf,'\0',smb_size);
/* setup the protocol strings */
set_message(cli->outbuf,0,0,True);
cli_set_message(cli->outbuf,0,0,True);
p = smb_buf(cli->outbuf);
for (numprots=0;
@ -1229,7 +1229,7 @@ bool cli_negprot(struct cli_state *cli)
numprots++)
plength += strlen(prots[numprots].name)+2;
set_message(cli->outbuf,0,plength,True);
cli_set_message(cli->outbuf,0,plength,True);
p = smb_buf(cli->outbuf);
for (numprots=0;
@ -1806,7 +1806,7 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf, 0, 0, True);
cli_set_message(cli->outbuf, 0, 0, True);
SCVAL(cli->outbuf,smb_com,SMBtcon);
cli_setup_packet(cli);

View File

@ -58,6 +58,52 @@ static struct sockaddr_storage dest_ss;
static struct client_connection *connections;
static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
struct cli_state *cli,
const char *sharename,
char **pp_newserver,
char **pp_newshare,
bool force_encrypt,
const char *username,
const char *password,
const char *domain);
/********************************************************************
Ensure a connection is encrypted.
********************************************************************/
NTSTATUS cli_cm_force_encryption(struct cli_state *c,
const char *username,
const char *password,
const char *domain,
const char *sharename)
{
NTSTATUS status = cli_force_encryption(c,
username,
password,
domain);
if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_SUPPORTED)) {
d_printf("Encryption required and "
"server that doesn't support "
"UNIX extensions - failing connect\n");
} else if (NT_STATUS_EQUAL(status,NT_STATUS_UNKNOWN_REVISION)) {
d_printf("Encryption required and "
"can't get UNIX CIFS extensions "
"version from server.\n");
} else if (NT_STATUS_EQUAL(status,NT_STATUS_UNSUPPORTED_COMPRESSION)) {
d_printf("Encryption required and "
"share %s doesn't support "
"encryption.\n", sharename);
} else if (!NT_STATUS_IS_OK(status)) {
d_printf("Encryption required and "
"setup failed with error %s.\n",
nt_errstr(status));
}
return status;
}
/********************************************************************
Return a connection to a server.
********************************************************************/
@ -65,7 +111,8 @@ static struct client_connection *connections;
static struct cli_state *do_connect(TALLOC_CTX *ctx,
const char *server,
const char *share,
bool show_sessetup)
bool show_sessetup,
bool force_encrypt)
{
struct cli_state *c = NULL;
struct nmb_name called, calling;
@ -197,9 +244,14 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
if ((c->capabilities & CAP_DFS) &&
cli_check_msdfs_proxy(ctx, c, sharename,
&newserver, &newshare)) {
&newserver, &newshare,
force_encrypt,
username,
password,
lp_workgroup())) {
cli_shutdown(c);
return do_connect(ctx, newserver, newshare, false);
return do_connect(ctx, newserver,
newshare, false, force_encrypt);
}
/* must be a normal share */
@ -211,6 +263,18 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx,
return NULL;
}
if (force_encrypt) {
status = cli_cm_force_encryption(c,
username,
password,
lp_workgroup(),
sharename);
if (!NT_STATUS_IS_OK(status)) {
cli_shutdown(c);
return NULL;
}
}
DEBUG(4,(" tconx ok\n"));
return c;
}
@ -269,7 +333,8 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
struct cli_state *referring_cli,
const char *server,
const char *share,
bool show_hdr)
bool show_hdr,
bool force_encrypt)
{
struct client_connection *node;
@ -279,7 +344,7 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx,
return NULL;
}
node->cli = do_connect(ctx, server, share, show_hdr);
node->cli = do_connect(ctx, server, share, show_hdr, force_encrypt);
if ( !node->cli ) {
TALLOC_FREE( node );
@ -331,7 +396,8 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
struct cli_state *referring_cli,
const char *server,
const char *share,
bool show_hdr)
bool show_hdr,
bool force_encrypt)
{
struct cli_state *c;
@ -339,7 +405,8 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx,
c = cli_cm_find(server, share);
if (!c) {
c = cli_cm_connect(ctx, referring_cli, server, share, show_hdr);
c = cli_cm_connect(ctx, referring_cli,
server, share, show_hdr, force_encrypt);
}
return c;
@ -776,7 +843,9 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
/* Check for the referral. */
if (!(cli_ipc = cli_cm_open(ctx, rootcli,
rootcli->desthost, "IPC$", false))) {
rootcli->desthost,
"IPC$", false,
(rootcli->trans_enc_state != NULL)))) {
return false;
}
@ -818,7 +887,10 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
/* Open the connection to the target server & share */
if ((*targetcli = cli_cm_open(ctx, rootcli,
server, share, false)) == NULL) {
server,
share,
false,
(rootcli->trans_enc_state != NULL))) == NULL) {
d_printf("Unable to follow dfs referral [\\%s\\%s]\n",
server, share );
return false;
@ -905,11 +977,15 @@ bool cli_resolve_path(TALLOC_CTX *ctx,
/********************************************************************
********************************************************************/
bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
struct cli_state *cli,
const char *sharename,
char **pp_newserver,
char **pp_newshare )
char **pp_newshare,
bool force_encrypt,
const char *username,
const char *password,
const char *domain)
{
CLIENT_DFS_REFERRAL *refs = NULL;
size_t num_refs = 0;
@ -944,6 +1020,17 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
return false;
}
if (force_encrypt) {
NTSTATUS status = cli_cm_force_encryption(cli,
username,
password,
lp_workgroup(),
"IPC$");
if (!NT_STATUS_IS_OK(status)) {
return false;
}
}
res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed);
if (!cli_tdis(cli)) {

View File

@ -81,7 +81,7 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx,
return False;
}
set_message(ptr,17,strlen(mailslot) + 1 + len,True);
cli_set_message(ptr,17,strlen(mailslot) + 1 + len,True);
memcpy(ptr,tmp,4);
SCVAL(ptr,smb_com,SMBtrans);

View File

@ -20,6 +20,21 @@
#include "includes.h"
/*******************************************************************
Setup the word count and byte count for a client smb message.
********************************************************************/
int cli_set_message(char *buf,int num_words,int num_bytes,bool zero)
{
if (zero && (num_words || num_bytes)) {
memset(buf + smb_size,'\0',num_words*2 + num_bytes);
}
SCVAL(buf,smb_wct,num_words);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
return (smb_size + num_words*2 + num_bytes);
}
/****************************************************************************
Change the timeout (in milliseconds).
****************************************************************************/
@ -71,6 +86,17 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen)
break;
}
}
if (cli_encryption_on(cli)) {
NTSTATUS status = cli_decrypt_message(cli);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n",
nt_errstr(status)));
cli->smb_rw_error = SMB_READ_BAD_DECRYPT;
return -1;
}
}
show_msg(cli->inbuf);
return len;
}
@ -85,7 +111,7 @@ bool cli_receive_smb(struct cli_state *cli)
/* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */
if (cli->fd == -1)
return False;
return false;
again:
len = client_receive_smb(cli, 0);
@ -100,7 +126,7 @@ bool cli_receive_smb(struct cli_state *cli)
int fnum = SVAL(cli->inbuf,smb_vwv2);
unsigned char level = CVAL(cli->inbuf,smb_vwv3+1);
if (!cli->oplock_handler(cli, fnum, level)) {
return False;
return false;
}
}
/* try to prevent loops */
@ -114,7 +140,7 @@ bool cli_receive_smb(struct cli_state *cli)
DEBUG(0, ("Receiving SMB: Server stopped responding\n"));
close(cli->fd);
cli->fd = -1;
return False;
return false;
}
if (!cli_check_sign_mac(cli)) {
@ -135,16 +161,16 @@ bool cli_receive_smb(struct cli_state *cli)
* Set bad sig but don't close fd.
*/
cli->smb_rw_error = SMB_READ_BAD_SIG;
return True;
return true;
}
DEBUG(0, ("SMB Signature verification failed on incoming packet!\n"));
cli->smb_rw_error = SMB_READ_BAD_SIG;
close(cli->fd);
cli->fd = -1;
return False;
return false;
};
return True;
return true;
}
/****************************************************************************
@ -164,6 +190,7 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len)
/****************************************************************************
Read a smb readX header.
We can only use this if encryption and signing are off.
****************************************************************************/
bool cli_receive_smb_readX_header(struct cli_state *cli)
@ -171,7 +198,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli)
ssize_t len, offset;
if (cli->fd == -1)
return False;
return false;
again:
@ -199,7 +226,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli)
if (cli->oplock_handler) {
int fnum = SVAL(cli->inbuf,smb_vwv2);
unsigned char level = CVAL(cli->inbuf,smb_vwv3+1);
if (!cli->oplock_handler(cli, fnum, level)) return False;
if (!cli->oplock_handler(cli, fnum, level)) return false;
}
/* try to prevent loops */
SCVAL(cli->inbuf,smb_com,0xFF);
@ -238,14 +265,14 @@ bool cli_receive_smb_readX_header(struct cli_state *cli)
}
}
return True;
return true;
read_err:
cli->smb_rw_error = SMB_READ_ERROR;
close(cli->fd);
cli->fd = -1;
return False;
return false;
}
static ssize_t write_socket(int fd, const char *buf, size_t len)
@ -272,32 +299,54 @@ bool cli_send_smb(struct cli_state *cli)
size_t len;
size_t nwritten=0;
ssize_t ret;
char *buf_out = cli->outbuf;
bool enc_on = cli_encryption_on(cli);
/* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */
if (cli->fd == -1)
return False;
return false;
cli_calculate_sign_mac(cli);
len = smb_len(cli->outbuf) + 4;
if (enc_on) {
NTSTATUS status = cli_encrypt_message(cli, &buf_out);
if (!NT_STATUS_IS_OK(status)) {
close(cli->fd);
cli->fd = -1;
cli->smb_rw_error = SMB_WRITE_ERROR;
DEBUG(0,("Error in encrypting client message. Error %s\n",
nt_errstr(status) ));
return false;
}
}
len = smb_len(buf_out) + 4;
while (nwritten < len) {
ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten);
ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten);
if (ret <= 0) {
if (enc_on) {
cli_free_enc_buffer(cli, buf_out);
}
close(cli->fd);
cli->fd = -1;
cli->smb_rw_error = SMB_WRITE_ERROR;
DEBUG(0,("Error writing %d bytes to client. %d (%s)\n",
(int)len,(int)ret, strerror(errno) ));
return False;
return false;
}
nwritten += ret;
}
if (enc_on) {
cli_free_enc_buffer(cli, buf_out);
}
/* Increment the mid so we can tell between responses. */
cli->mid++;
if (!cli->mid)
cli->mid++;
return True;
return true;
}
/****************************************************************************
@ -347,7 +396,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli,
DEBUG(0,("Error writing %d extradata "
"bytes to client. %d (%s)\n",
(int)extradata,(int)ret, strerror(errno) ));
return False;
return false;
}
nwritten += ret;
}
@ -409,7 +458,7 @@ void cli_init_creds(struct cli_state *cli, const char *username, const char *dom
fstrcpy(cli->user_name, username);
pwd_set_cleartext(&cli->pwd, password);
if (!*username) {
cli->pwd.null_pwd = True;
cli->pwd.null_pwd = true;
}
DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain));
@ -424,16 +473,16 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state)
if (signing_state == Undefined)
return;
if (signing_state == False) {
cli->sign_info.allow_smb_signing = False;
cli->sign_info.mandatory_signing = False;
if (signing_state == false) {
cli->sign_info.allow_smb_signing = false;
cli->sign_info.mandatory_signing = false;
return;
}
cli->sign_info.allow_smb_signing = True;
cli->sign_info.allow_smb_signing = true;
if (signing_state == Required)
cli->sign_info.mandatory_signing = True;
cli->sign_info.mandatory_signing = true;
}
/****************************************************************************
@ -470,7 +519,7 @@ struct cli_state *cli_initialise(void)
cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN);
cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN);
cli->oplock_handler = cli_oplock_ack;
cli->case_sensitive = False;
cli->case_sensitive = false;
cli->smb_rw_error = SMB_READ_OK;
cli->use_spnego = lp_client_use_spnego();
@ -481,13 +530,13 @@ struct cli_state *cli_initialise(void)
client routines using DOS errors instead of STATUS32
ones. This intended only as a temporary hack. */
if (getenv("CLI_FORCE_DOSERR"))
cli->force_dos_errors = True;
cli->force_dos_errors = true;
if (lp_client_signing())
cli->sign_info.allow_smb_signing = True;
cli->sign_info.allow_smb_signing = true;
if (lp_client_signing() == Required)
cli->sign_info.mandatory_signing = True;
cli->sign_info.mandatory_signing = true;
if (!cli->outbuf || !cli->inbuf)
goto error;
@ -522,7 +571,7 @@ struct cli_state *cli_initialise(void)
/****************************************************************************
External interface.
Close an open named pipe over SMB. Free any authentication data.
Returns False if the cli_close call failed.
Returns false if the cli_close call failed.
****************************************************************************/
bool cli_rpc_pipe_close(struct rpc_pipe_client *cli)
@ -530,7 +579,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli)
bool ret;
if (!cli) {
return False;
return false;
}
ret = cli_close(cli->cli, cli->fnum);
@ -650,15 +699,15 @@ bool cli_send_keepalive(struct cli_state *cli)
{
if (cli->fd == -1) {
DEBUG(3, ("cli_send_keepalive: fd == -1\n"));
return False;
return false;
}
if (!send_keepalive(cli->fd)) {
close(cli->fd);
cli->fd = -1;
DEBUG(0,("Error sending keepalive packet to client.\n"));
return False;
return false;
}
return True;
return true;
}
/****************************************************************************
@ -674,7 +723,7 @@ bool cli_echo(struct cli_state *cli, uint16 num_echos,
SMB_ASSERT(length < 1024);
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,1,length,True);
cli_set_message(cli->outbuf,1,length,true);
SCVAL(cli->outbuf,smb_com,SMBecho);
SSVAL(cli->outbuf,smb_tid,65535);
SSVAL(cli->outbuf,smb_vwv0,num_echos);
@ -689,13 +738,13 @@ bool cli_echo(struct cli_state *cli, uint16 num_echos,
for (i=0; i<num_echos; i++) {
if (!cli_receive_smb(cli)) {
return False;
return false;
}
if (cli_is_error(cli)) {
return False;
return false;
}
}
return True;
return true;
}

View File

@ -429,7 +429,7 @@ bool cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,1, 0, true);
cli_set_message(cli->outbuf,1, 0, true);
SCVAL(cli->outbuf,smb_com,SMBmv);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -470,7 +470,7 @@ bool cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf, 4, 0, true);
cli_set_message(cli->outbuf, 4, 0, true);
SCVAL(cli->outbuf,smb_com,SMBntrename);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -512,7 +512,7 @@ bool cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *f
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf, 4, 0, true);
cli_set_message(cli->outbuf, 4, 0, true);
SCVAL(cli->outbuf,smb_com,SMBntrename);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -554,7 +554,7 @@ bool cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs)
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,1, 0, true);
cli_set_message(cli->outbuf,1, 0, true);
SCVAL(cli->outbuf,smb_com,SMBunlink);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -600,7 +600,7 @@ bool cli_mkdir(struct cli_state *cli, const char *dname)
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,0, 0, true);
cli_set_message(cli->outbuf,0, 0, true);
SCVAL(cli->outbuf,smb_com,SMBmkdir);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -636,7 +636,7 @@ bool cli_rmdir(struct cli_state *cli, const char *dname)
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,0, 0, true);
cli_set_message(cli->outbuf,0, 0, true);
SCVAL(cli->outbuf,smb_com,SMBrmdir);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -719,7 +719,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,24,0, true);
cli_set_message(cli->outbuf,24,0, true);
SCVAL(cli->outbuf,smb_com,SMBntcreateX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -815,7 +815,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,15,0, true);
cli_set_message(cli->outbuf,15,0, true);
SCVAL(cli->outbuf,smb_com,SMBopenX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -863,7 +863,7 @@ bool cli_close(struct cli_state *cli, int fnum)
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,3,0,True);
cli_set_message(cli->outbuf,3,0,True);
SCVAL(cli->outbuf,smb_com,SMBclose);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -896,7 +896,7 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0', smb_size);
set_message(cli->outbuf,8,0,True);
cli_set_message(cli->outbuf,8,0,True);
SCVAL(cli->outbuf,smb_com,SMBlockingX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -948,7 +948,7 @@ bool cli_lock(struct cli_state *cli, int fnum,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0', smb_size);
set_message(cli->outbuf,8,0,True);
cli_set_message(cli->outbuf,8,0,True);
SCVAL(cli->outbuf,smb_com,SMBlockingX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -1001,7 +1001,7 @@ bool cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,8,0,True);
cli_set_message(cli->outbuf,8,0,True);
SCVAL(cli->outbuf,smb_com,SMBlockingX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -1053,7 +1053,7 @@ bool cli_lock64(struct cli_state *cli, int fnum,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0', smb_size);
set_message(cli->outbuf,8,0,True);
cli_set_message(cli->outbuf,8,0,True);
SCVAL(cli->outbuf,smb_com,SMBlockingX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -1108,7 +1108,7 @@ bool cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,8,0,True);
cli_set_message(cli->outbuf,8,0,True);
SCVAL(cli->outbuf,smb_com,SMBlockingX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -1255,7 +1255,7 @@ bool cli_getattrE(struct cli_state *cli, int fd,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,1,0,True);
cli_set_message(cli->outbuf,1,0,True);
SCVAL(cli->outbuf,smb_com,SMBgetattrE);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -1307,7 +1307,7 @@ bool cli_getatr(struct cli_state *cli, const char *fname,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
cli_set_message(cli->outbuf,0,0,True);
SCVAL(cli->outbuf,smb_com,SMBgetatr);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -1359,7 +1359,7 @@ bool cli_setattrE(struct cli_state *cli, int fd,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,7,0,True);
cli_set_message(cli->outbuf,7,0,True);
SCVAL(cli->outbuf,smb_com,SMBsetattrE);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -1398,7 +1398,7 @@ bool cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t)
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,8,0,True);
cli_set_message(cli->outbuf,8,0,True);
SCVAL(cli->outbuf,smb_com,SMBsetatr);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -1452,7 +1452,7 @@ bool cli_chkpath(struct cli_state *cli, const char *path)
}
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
cli_set_message(cli->outbuf,0,0,True);
SCVAL(cli->outbuf,smb_com,SMBcheckpath);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@ -1483,7 +1483,7 @@ bool cli_chkpath(struct cli_state *cli, const char *path)
bool cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
{
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
cli_set_message(cli->outbuf,0,0,True);
SCVAL(cli->outbuf,smb_com,SMBdskattr);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@ -1512,7 +1512,7 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path)
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,3,0,True);
cli_set_message(cli->outbuf,3,0,True);
SCVAL(cli->outbuf,smb_com,SMBctemp);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -1565,7 +1565,7 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf, 3, 0, True);
cli_set_message(cli->outbuf, 3, 0, True);
SCVAL(cli->outbuf,smb_com,SMBioctl);
cli_setup_packet(cli);

View File

@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
FS info functions
Copyright (C) Stefan (metze) Metzmacher 2003
Copyright (C) Jeremy Allison 2007
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -301,3 +302,368 @@ cleanup:
return ret;
}
/******************************************************************************
Send/receive the request encryption blob.
******************************************************************************/
static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out, DATA_BLOB *param_out)
{
uint16 setup;
char param[4];
char *rparam=NULL, *rdata=NULL;
unsigned int rparam_count=0, rdata_count=0;
NTSTATUS status = NT_STATUS_OK;
setup = TRANSACT2_SETFSINFO;
SSVAL(param,0,0);
SSVAL(param,2,SMB_REQUEST_TRANSPORT_ENCRYPTION);
if (!cli_send_trans(cli, SMBtrans2,
NULL,
0, 0,
&setup, 1, 0,
param, 4, 0,
(char *)in->data, in->length, CLI_BUFFER_SIZE)) {
status = cli_nt_error(cli);
goto out;
}
if (!cli_receive_trans(cli, SMBtrans2,
&rparam, &rparam_count,
&rdata, &rdata_count)) {
status = cli_nt_error(cli);
goto out;
}
if (cli_is_error(cli)) {
status = cli_nt_error(cli);
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
goto out;
}
}
*out = data_blob(rdata, rdata_count);
*param_out = data_blob(rparam, rparam_count);
out:
SAFE_FREE(rparam);
SAFE_FREE(rdata);
return status;
}
/******************************************************************************
Make a client state struct.
******************************************************************************/
static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type smb_enc_type)
{
struct smb_trans_enc_state *es = NULL;
es = SMB_MALLOC_P(struct smb_trans_enc_state);
if (!es) {
return NULL;
}
ZERO_STRUCTP(es);
es->smb_enc_type = smb_enc_type;
if (smb_enc_type == SMB_TRANS_ENC_GSS) {
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss);
if (!es->s.gss_state) {
SAFE_FREE(es);
return NULL;
}
ZERO_STRUCTP(es->s.gss_state);
#else
DEBUG(0,("make_cli_enc_state: no krb5 compiled.\n"));
SAFE_FREE(es);
return NULL;
#endif
}
return es;
}
/******************************************************************************
Start a raw ntlmssp encryption.
******************************************************************************/
NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli,
const char *user,
const char *pass,
const char *domain)
{
DATA_BLOB blob_in = data_blob_null;
DATA_BLOB blob_out = data_blob_null;
DATA_BLOB param_out = data_blob_null;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_NTLM);
if (!es) {
return NT_STATUS_NO_MEMORY;
}
status = ntlmssp_client_start(&es->s.ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
ntlmssp_want_feature(es->s.ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
es->s.ntlmssp_state->neg_flags |= (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
if (!NT_STATUS_IS_OK(status = ntlmssp_set_username(es->s.ntlmssp_state, user))) {
goto fail;
}
if (!NT_STATUS_IS_OK(status = ntlmssp_set_domain(es->s.ntlmssp_state, domain))) {
goto fail;
}
if (!NT_STATUS_IS_OK(status = ntlmssp_set_password(es->s.ntlmssp_state, pass))) {
goto fail;
}
do {
status = ntlmssp_update(es->s.ntlmssp_state, blob_in, &blob_out);
data_blob_free(&blob_in);
data_blob_free(&param_out);
if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(status)) {
NTSTATUS trans_status = enc_blob_send_receive(cli,
&blob_out,
&blob_in,
&param_out);
if (!NT_STATUS_EQUAL(trans_status,
NT_STATUS_MORE_PROCESSING_REQUIRED) &&
!NT_STATUS_IS_OK(trans_status)) {
status = trans_status;
} else {
if (param_out.length == 2) {
es->enc_ctx_num = SVAL(param_out.data, 0);
}
}
}
data_blob_free(&blob_out);
} while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED));
data_blob_free(&blob_in);
if (NT_STATUS_IS_OK(status)) {
/* Replace the old state, if any. */
if (cli->trans_enc_state) {
common_free_encryption_state(&cli->trans_enc_state);
}
cli->trans_enc_state = es;
cli->trans_enc_state->enc_on = True;
es = NULL;
}
fail:
common_free_encryption_state(&es);
return status;
}
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
#ifndef SMB_GSS_REQUIRED_FLAGS
#define SMB_GSS_REQUIRED_FLAGS (GSS_C_CONF_FLAG|GSS_C_INTEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)
#endif
/******************************************************************************
Get client gss blob to send to a server.
******************************************************************************/
static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es,
const char *service,
const char *host,
NTSTATUS status_in,
DATA_BLOB spnego_blob_in,
DATA_BLOB *p_blob_out)
{
const char *krb_mechs[] = {OID_KERBEROS5, NULL};
OM_uint32 ret;
OM_uint32 min;
gss_name_t srv_name;
gss_buffer_desc input_name;
gss_buffer_desc *p_tok_in;
gss_buffer_desc tok_out, tok_in;
DATA_BLOB blob_out = data_blob_null;
DATA_BLOB blob_in = data_blob_null;
char *host_princ_s = NULL;
OM_uint32 ret_flags = 0;
NTSTATUS status = NT_STATUS_OK;
gss_OID_desc nt_hostbased_service =
{10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")};
memset(&tok_out, '\0', sizeof(tok_out));
/* Get a ticket for the service@host */
asprintf(&host_princ_s, "%s@%s", service, host);
if (host_princ_s == NULL) {
return NT_STATUS_NO_MEMORY;
}
input_name.value = host_princ_s;
input_name.length = strlen(host_princ_s) + 1;
ret = gss_import_name(&min,
&input_name,
&nt_hostbased_service,
&srv_name);
if (ret != GSS_S_COMPLETE) {
SAFE_FREE(host_princ_s);
return map_nt_error_from_gss(ret, min);
}
if (spnego_blob_in.length == 0) {
p_tok_in = GSS_C_NO_BUFFER;
} else {
/* Remove the SPNEGO wrapper */
if (!spnego_parse_auth_response(spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) {
status = NT_STATUS_UNSUCCESSFUL;
goto fail;
}
tok_in.value = blob_in.data;
tok_in.length = blob_in.length;
p_tok_in = &tok_in;
}
ret = gss_init_sec_context(&min,
GSS_C_NO_CREDENTIAL, /* Use our default cred. */
&es->s.gss_state->gss_ctx,
srv_name,
GSS_C_NO_OID, /* default OID. */
GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG,
GSS_C_INDEFINITE, /* requested ticket lifetime. */
NULL, /* no channel bindings */
p_tok_in,
NULL, /* ignore mech type */
&tok_out,
&ret_flags,
NULL); /* ignore time_rec */
status = map_nt_error_from_gss(ret, min);
if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
ADS_STATUS adss = ADS_ERROR_GSS(ret, min);
DEBUG(10,("make_cli_gss_blob: gss_init_sec_context failed with %s\n",
ads_errstr(adss)));
goto fail;
}
if ((ret_flags & SMB_GSS_REQUIRED_FLAGS) != SMB_GSS_REQUIRED_FLAGS) {
status = NT_STATUS_ACCESS_DENIED;
}
blob_out = data_blob(tok_out.value, tok_out.length);
/* Wrap in an SPNEGO wrapper */
*p_blob_out = gen_negTokenTarg(krb_mechs, blob_out);
fail:
data_blob_free(&blob_out);
data_blob_free(&blob_in);
SAFE_FREE(host_princ_s);
gss_release_name(&min, &srv_name);
if (tok_out.value) {
gss_release_buffer(&min, &tok_out);
}
return status;
}
/******************************************************************************
Start a SPNEGO gssapi encryption context.
******************************************************************************/
NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli)
{
DATA_BLOB blob_recv = data_blob_null;
DATA_BLOB blob_send = data_blob_null;
DATA_BLOB param_out = data_blob_null;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
fstring fqdn;
const char *servicename;
struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_GSS);
if (!es) {
return NT_STATUS_NO_MEMORY;
}
name_to_fqdn(fqdn, cli->desthost);
strlower_m(fqdn);
servicename = "cifs";
status = make_cli_gss_blob(es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send);
if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
servicename = "host";
status = make_cli_gss_blob(es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send);
if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
goto fail;
}
}
do {
data_blob_free(&blob_recv);
status = enc_blob_send_receive(cli, &blob_send, &blob_recv, &param_out);
if (param_out.length == 2) {
es->enc_ctx_num = SVAL(param_out.data, 0);
}
data_blob_free(&blob_send);
status = make_cli_gss_blob(es, servicename, fqdn, status, blob_recv, &blob_send);
} while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED));
data_blob_free(&blob_recv);
if (NT_STATUS_IS_OK(status)) {
/* Replace the old state, if any. */
if (cli->trans_enc_state) {
common_free_encryption_state(&cli->trans_enc_state);
}
cli->trans_enc_state = es;
cli->trans_enc_state->enc_on = True;
es = NULL;
}
fail:
common_free_encryption_state(&es);
return status;
}
#else
NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli)
{
return NT_STATUS_NOT_SUPPORTED;
}
#endif
/********************************************************************
Ensure a connection is encrypted.
********************************************************************/
NTSTATUS cli_force_encryption(struct cli_state *c,
const char *username,
const char *password,
const char *domain)
{
uint16 major, minor;
uint32 caplow, caphigh;
if (!SERVER_HAS_UNIX_CIFS(c)) {
return NT_STATUS_NOT_SUPPORTED;
}
if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
return NT_STATUS_UNKNOWN_REVISION;
}
if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
return NT_STATUS_UNSUPPORTED_COMPRESSION;
}
if (c->use_kerberos) {
return cli_gss_smb_encryption_start(c);
}
return cli_raw_ntlm_smb_encryption_start(c,
username,
password,
domain);
}

View File

@ -521,7 +521,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,2,0,True);
cli_set_message(cli->outbuf,2,0,True);
SCVAL(cli->outbuf,smb_com,SMBsearch);
@ -581,7 +581,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,2,0,True);
cli_set_message(cli->outbuf,2,0,True);
SCVAL(cli->outbuf,smb_com,SMBfclose);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);

View File

@ -29,7 +29,7 @@ int cli_message_start_build(struct cli_state *cli, const char *host, const char
/* construct a SMBsendstrt command */
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
cli_set_message(cli->outbuf,0,0,True);
SCVAL(cli->outbuf,smb_com,SMBsendstrt);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@ -75,7 +75,7 @@ int cli_message_text_build(struct cli_state *cli, const char *msg, int len, int
char *p;
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,1,0,True);
cli_set_message(cli->outbuf,1,0,True);
SCVAL(cli->outbuf,smb_com,SMBsendtxt);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
@ -132,7 +132,7 @@ int cli_message_end_build(struct cli_state *cli, int grp)
char *p;
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,1,0,True);
cli_set_message(cli->outbuf,1,0,True);
SCVAL(cli->outbuf,smb_com,SMBsendend);
SSVAL(cli->outbuf,smb_tid,cli->cnum);

View File

@ -32,7 +32,7 @@ bool cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level)
cli->outbuf = buf;
memset(buf,'\0',smb_size);
set_message(buf,8,0,True);
cli_set_message(buf,8,0,True);
SCVAL(buf,smb_com,SMBlockingX);
SSVAL(buf,smb_tid, cli->cnum);

View File

@ -195,7 +195,7 @@ int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,15,0,True);
cli_set_message(cli->outbuf,15,0,True);
SCVAL(cli->outbuf,smb_com,SMBsplopen);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -242,7 +242,7 @@ bool cli_spl_close(struct cli_state *cli, int fnum)
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,3,0,True);
cli_set_message(cli->outbuf,3,0,True);
SCVAL(cli->outbuf,smb_com,SMBsplclose);
SSVAL(cli->outbuf,smb_tid,cli->cnum);

View File

@ -150,7 +150,7 @@ bool cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUC
SIVAL(params, 8,0x00000000);
SIVAL(params,12,0x00000024);
sid_len = sid_size(&pqt->sid);
sid_len = ndr_size_dom_sid(&pqt->sid, 0);
data_len = sid_len+8;
SIVAL(data, 0, 0x00000000);
SIVAL(data, 4, sid_len);
@ -213,7 +213,7 @@ bool cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUC
SSVAL(params,0,quota_fnum);
sid_len = sid_size(&pqt->sid);
sid_len = ndr_size_dom_sid(&pqt->sid, 0);
SIVAL(data,0,0);
SIVAL(data,4,sid_len);
SBIG_UINT(data, 8,(SMB_BIG_UINT)0);

View File

@ -34,7 +34,7 @@ static bool cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
if ((SMB_BIG_UINT)offset >> 32)
bigoffset = True;
set_message(cli->outbuf,bigoffset ? 12 : 10,0,True);
cli_set_message(cli->outbuf,bigoffset ? 12 : 10,0,True);
SCVAL(cli->outbuf,smb_com,SMBreadX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -65,8 +65,8 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
size_t size2;
size_t readsize;
ssize_t total = 0;
/* We can only do direct reads if not signing. */
bool direct_reads = !client_is_signing_on(cli);
/* We can only do direct reads if not signing or encrypting. */
bool direct_reads = !client_is_signing_on(cli) && !cli_encryption_on(cli);
if (size == 0)
return 0;
@ -76,7 +76,9 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_
* rounded down to a multiple of 1024.
*/
if (client_is_signing_on(cli) == False && (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) {
if (client_is_signing_on(cli) == false &&
cli_encryption_on(cli) == false &&
(cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) {
readsize = CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE;
} else if (cli->capabilities & CAP_LARGE_READX) {
if (cli->is_samba) {
@ -203,7 +205,7 @@ static bool cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,10,0,True);
cli_set_message(cli->outbuf,10,0,True);
SCVAL(cli->outbuf,smb_com,SMBreadbraw);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@ -295,8 +297,8 @@ static bool cli_issue_write(struct cli_state *cli,
{
char *p;
bool large_writex = false;
/* We can only do direct writes if not signing. */
bool direct_writes = !client_is_signing_on(cli);
/* We can only do direct writes if not signing and not encrypting. */
bool direct_writes = !client_is_signing_on(cli) && !cli_encryption_on(cli);
if (!direct_writes && size + 1 > cli->bufsize) {
cli->outbuf = (char *)SMB_REALLOC(cli->outbuf, size + 1024);
@ -319,9 +321,9 @@ static bool cli_issue_write(struct cli_state *cli,
}
if (large_writex) {
set_message(cli->outbuf,14,0,True);
cli_set_message(cli->outbuf,14,0,True);
} else {
set_message(cli->outbuf,12,0,True);
cli_set_message(cli->outbuf,12,0,True);
}
SCVAL(cli->outbuf,smb_com,SMBwriteX);
@ -404,16 +406,17 @@ ssize_t cli_write(struct cli_state *cli,
if (write_mode == 0 &&
!client_is_signing_on(cli) &&
!cli_encryption_on(cli) &&
(cli->posix_capabilities & CIFS_UNIX_LARGE_WRITE_CAP) &&
(cli->capabilities & CAP_LARGE_FILES)) {
/* Only do massive writes if we can do them direct
* with no signing - not on a pipe. */
* with no signing or encrypting - not on a pipe. */
writesize = CLI_SAMBA_MAX_POSIX_LARGE_WRITEX_SIZE;
} else if (cli->capabilities & CAP_LARGE_READX) {
} else if (cli->capabilities & CAP_LARGE_WRITEX) {
if (cli->is_samba) {
writesize = CLI_SAMBA_MAX_LARGE_READX_SIZE;
writesize = CLI_SAMBA_MAX_LARGE_WRITEX_SIZE;
} else {
writesize = CLI_WINDOWS_MAX_LARGE_READX_SIZE;
writesize = CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE;
}
} else {
writesize = (cli->max_xmit - (smb_size+32)) & ~1023;
@ -471,7 +474,7 @@ ssize_t cli_smbwrite(struct cli_state *cli,
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,5, 0,True);
cli_set_message(cli->outbuf,5, 0,True);
SCVAL(cli->outbuf,smb_com,SMBwrite);
SSVAL(cli->outbuf,smb_tid,cli->cnum);

View File

@ -28,9 +28,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
char param[8];
char *rparam=NULL, *rdata=NULL;
unsigned int rparam_count=0, rdata_count=0;
prs_struct pd;
bool pd_initialized = False;
SEC_DESC *psd = NULL;
NTSTATUS status;
SIVAL(param, 0, fnum);
SIVAL(param, 4, 0x7);
@ -56,15 +55,12 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
if (cli_is_error(cli))
goto cleanup;
if (!prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL)) {
goto cleanup;
}
pd_initialized = True;
prs_copy_data_in(&pd, rdata, rdata_count);
prs_set_offset(&pd,0);
status = unmarshall_sec_desc(mem_ctx, (uint8 *)rdata, rdata_count,
&psd);
if (!sec_io_desc("sd data", &psd, &pd, 1)) {
DEBUG(1,("Failed to parse secdesc\n"));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("unmarshall_sec_desc failed: %s\n",
nt_errstr(status)));
goto cleanup;
}
@ -73,8 +69,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
SAFE_FREE(rparam);
SAFE_FREE(rdata);
if (pd_initialized)
prs_mem_free(&pd);
return psd;
}
@ -87,20 +81,16 @@ bool cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd)
char *rparam=NULL, *rdata=NULL;
unsigned int rparam_count=0, rdata_count=0;
uint32 sec_info = 0;
TALLOC_CTX *mem_ctx;
prs_struct pd;
TALLOC_CTX *frame = talloc_stackframe();
bool ret = False;
uint8 *data;
size_t len;
NTSTATUS status;
if ((mem_ctx = talloc_init("cli_set_secdesc")) == NULL) {
DEBUG(0,("talloc_init failed.\n"));
goto cleanup;
}
prs_init(&pd, 0, mem_ctx, MARSHALL);
prs_give_memory(&pd, NULL, 0, True);
if (!sec_io_desc("sd data", &sd, &pd, 1)) {
DEBUG(1,("Failed to marshall secdesc\n"));
status = marshall_sec_desc(talloc_tos(), sd, &data, &len);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("marshall_sec_desc failed: %s\n",
nt_errstr(status)));
goto cleanup;
}
@ -119,7 +109,7 @@ bool cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd)
0,
NULL, 0, 0,
param, 8, 0,
prs_data_p(&pd), prs_offset(&pd), 0)) {
(char *)data, len, 0)) {
DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n"));
goto cleanup;
}
@ -139,8 +129,7 @@ bool cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd)
SAFE_FREE(rparam);
SAFE_FREE(rdata);
talloc_destroy(mem_ctx);
TALLOC_FREE(frame);
prs_mem_free(&pd);
return ret;
}

View File

@ -43,7 +43,7 @@ bool cli_send_trans(struct cli_state *cli, int trans,
this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,14+lsetup,0,True);
cli_set_message(cli->outbuf,14+lsetup,0,True);
SCVAL(cli->outbuf,smb_com,trans);
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
@ -107,7 +107,7 @@ bool cli_send_trans(struct cli_state *cli, int trans,
this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */
this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam));
set_message(cli->outbuf,trans==SMBtrans?8:9,0,True);
cli_set_message(cli->outbuf,trans==SMBtrans?8:9,0,True);
SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2));
outparam = smb_buf(cli->outbuf);
@ -368,7 +368,7 @@ bool cli_send_nt_trans(struct cli_state *cli,
this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));
memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,19+lsetup,0,True);
cli_set_message(cli->outbuf,19+lsetup,0,True);
SCVAL(cli->outbuf,smb_com,SMBnttrans);
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
@ -424,7 +424,7 @@ bool cli_send_nt_trans(struct cli_state *cli,
this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */
this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam));
set_message(cli->outbuf,18,0,True);
cli_set_message(cli->outbuf,18,0,True);
SCVAL(cli->outbuf,smb_com,SMBnttranss);
/* XXX - these should probably be aligned */

View File

@ -63,6 +63,7 @@ werror_code_struct dos_errs[] =
{ "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND },
{ "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND },
{ "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN },
{ "WERR_USER_EXISTS", WERR_USER_EXISTS },
{ "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS },
{ "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION },
{ "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE },
@ -77,6 +78,7 @@ werror_code_struct dos_errs[] =
{ "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED },
{ "WERR_SETUP_ALREADY_JOINED", WERR_SETUP_ALREADY_JOINED },
{ "WERR_SETUP_DOMAIN_CONTROLLER", WERR_SETUP_DOMAIN_CONTROLLER },
{ "WERR_DEFAULT_JOIN_REQUIRED", WERR_DEFAULT_JOIN_REQUIRED },
{ "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE },
{ "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE },
{ "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN },
@ -90,6 +92,7 @@ werror_code_struct dos_errs[] =
{ "WERR_REG_CORRUPT", WERR_REG_CORRUPT },
{ "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE },
{ "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID },
{ "WERR_NO_SUCH_SERVICE", WERR_NO_SUCH_SERVICE },
{ "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED },
{ "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE},
{ "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS},
@ -110,6 +113,7 @@ werror_str_struct dos_err_strs[] = {
{ WERR_SETUP_ALREADY_JOINED, "Machine is already joined" },
{ WERR_SETUP_DOMAIN_CONTROLLER, "Machine is a Domain Controller" },
{ WERR_LOGON_FAILURE, "Invalid logon credentials" },
{ WERR_USER_EXISTS, "User account already exists" },
};
/*****************************************************************************

View File

@ -1502,3 +1502,108 @@ WERROR ntstatus_to_werror(NTSTATUS error)
/* a lame guess */
return W_ERROR(NT_STATUS_V(error) & 0xffff);
}
#if defined(HAVE_GSSAPI)
/*******************************************************************************
Map between gssapi errors and NT status. I made these up :-(. JRA.
*******************************************************************************/
static const struct {
unsigned long gss_err;
NTSTATUS ntstatus;
} gss_to_ntstatus_errormap[] = {
#if defined(GSS_S_CALL_INACCESSIBLE_READ)
{GSS_S_CALL_INACCESSIBLE_READ, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_CALL_INACCESSIBLE_WRITE)
{GSS_S_CALL_INACCESSIBLE_WRITE, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_CALL_BAD_STRUCTURE)
{GSS_S_CALL_BAD_STRUCTURE, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_BAD_MECH)
{GSS_S_BAD_MECH, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_BAD_NAME)
{GSS_S_BAD_NAME, NT_STATUS_INVALID_ACCOUNT_NAME},
#endif
#if defined(GSS_S_BAD_NAMETYPE)
{GSS_S_BAD_NAMETYPE, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_BAD_BINDINGS)
{GSS_S_BAD_BINDINGS, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_BAD_STATUS)
{GSS_S_BAD_STATUS, NT_STATUS_UNSUCCESSFUL},
#endif
#if defined(GSS_S_BAD_SIG)
{GSS_S_BAD_SIG, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_NO_CRED)
{GSS_S_NO_CRED, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_NO_CONTEXT)
{GSS_S_NO_CONTEXT, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_DEFECTIVE_TOKEN)
{GSS_S_DEFECTIVE_TOKEN, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_DEFECTIVE_CREDENTIAL)
{GSS_S_DEFECTIVE_CREDENTIAL, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_CREDENTIALS_EXPIRED)
{GSS_S_CREDENTIALS_EXPIRED, NT_STATUS_PASSWORD_EXPIRED},
#endif
#if defined(GSS_S_CONTEXT_EXPIRED)
{GSS_S_CONTEXT_EXPIRED, NT_STATUS_PASSWORD_EXPIRED},
#endif
#if defined(GSS_S_BAD_QOP)
{GSS_S_BAD_QOP, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_UNAUTHORIZED)
{GSS_S_UNAUTHORIZED, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_UNAVAILABLE)
{GSS_S_UNAVAILABLE, NT_STATUS_UNSUCCESSFUL},
#endif
#if defined(GSS_S_DUPLICATE_ELEMENT)
{GSS_S_DUPLICATE_ELEMENT, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_NAME_NOT_MN)
{GSS_S_NAME_NOT_MN, NT_STATUS_INVALID_PARAMETER},
#endif
{ 0, NT_STATUS_OK }
};
/*********************************************************************
Map an NT error code from a gssapi error code.
*********************************************************************/
NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor)
{
int i = 0;
if (gss_maj == GSS_S_COMPLETE) {
return NT_STATUS_OK;
}
if (gss_maj == GSS_S_CONTINUE_NEEDED) {
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
if (gss_maj == GSS_S_FAILURE) {
return map_nt_error_from_unix((int)minor);
}
/* Look through list */
while(gss_to_ntstatus_errormap[i].gss_err != 0) {
if (gss_to_ntstatus_errormap[i].gss_err == gss_maj) {
return gss_to_ntstatus_errormap[i].ntstatus;
}
i++;
}
/* Default return */
return NT_STATUS_ACCESS_DENIED;
}
#endif

View File

@ -6,6 +6,7 @@
Copyright (C) John Terpstra 2000
Copyright (C) Tom Jansen (Ninja ISD) 2002
Copyright (C) Derrell Lipman 2003, 2004
Copyright (C) Jeremy Allison 2007, 2008
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -739,6 +740,12 @@ smbc_server(SMBCCTX *context,
password, strlen(password)+1);
}
/*
* We don't need to renegotiate encryption
* here as the encryption context is not per
* tid.
*/
if (! cli_send_tconX(srv->cli, share, "?????",
password, strlen(password)+1)) {
@ -903,6 +910,30 @@ smbc_server(SMBCCTX *context,
DEBUG(4,(" tconx ok\n"));
if (context->internal->_smb_encryption_level) {
/* Attempt UNIX smb encryption. */
if (!NT_STATUS_IS_OK(cli_force_encryption(c,
username_used,
password,
workgroup))) {
/*
* context->internal->_smb_encryption_level == 1
* means don't fail if encryption can't be negotiated,
* == 2 means fail if encryption can't be negotiated.
*/
DEBUG(4,(" SMB encrypt failed\n"));
if (context->internal->_smb_encryption_level == 2) {
cli_shutdown(c);
errno = EPERM;
return NULL;
}
}
DEBUG(4,(" SMB encrypt ok\n"));
}
/*
* Ok, we have got a nice connection
* Let's allocate a server structure.
@ -1019,6 +1050,30 @@ smbc_attr_server(SMBCCTX *context,
return NULL;
}
if (context->internal->_smb_encryption_level) {
/* Attempt UNIX smb encryption. */
if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli,
username,
password,
workgroup))) {
/*
* context->internal->_smb_encryption_level == 1
* means don't fail if encryption can't be negotiated,
* == 2 means fail if encryption can't be negotiated.
*/
DEBUG(4,(" SMB encrypt failed on IPC$\n"));
if (context->internal->_smb_encryption_level == 2) {
cli_shutdown(ipc_cli);
errno = EPERM;
return NULL;
}
}
DEBUG(4,(" SMB encrypt ok on IPC$\n"));
}
ipc_srv = SMB_MALLOC_P(SMBCSRV);
if (!ipc_srv) {
errno = ENOMEM;
@ -6724,6 +6779,7 @@ smbc_option_set(SMBCCTX *context,
bool b;
smbc_get_auth_data_with_context_fn auth_fn;
void *v;
const char *s;
} option_value;
va_start(ap, option_name);
@ -6772,6 +6828,19 @@ smbc_option_set(SMBCCTX *context,
*/
option_value.v = va_arg(ap, void *);
context->internal->_user_data = option_value.v;
} else if (strcmp(option_name, "smb_encrypt_level") == 0) {
/*
* Save an encoded value for encryption level.
* 0 = off, 1 = attempt, 2 = required.
*/
option_value.s = va_arg(ap, const char *);
if (strcmp(option_value.s, "none") == 0) {
context->internal->_smb_encryption_level = 0;
} else if (strcmp(option_value.s, "request") == 0) {
context->internal->_smb_encryption_level = 1;
} else if (strcmp(option_value.s, "require") == 0) {
context->internal->_smb_encryption_level = 2;
}
}
va_end(ap);
@ -6821,6 +6890,35 @@ smbc_option_get(SMBCCTX *context,
* with smbc_option_get()
*/
return context->internal->_user_data;
} else if (strcmp(option_name, "smb_encrypt_level") == 0) {
/*
* Return the current smb encrypt negotiate option as a string.
*/
switch (context->internal->_smb_encryption_level) {
case 0:
return (void *) "none";
case 1:
return (void *) "request";
case 2:
return (void *) "require";
}
} else if (strcmp(option_name, "smb_encrypt_on") == 0) {
/*
* Return the current smb encrypt status option as a bool.
* false = off, true = on. We don't know what server is
* being requested, so we only return true if all servers
* are using an encrypted connection.
*/
SMBCSRV *s;
unsigned int num_servers = 0;
for (s = context->internal->_servers; s; s = s->next) {
num_servers++;
if (s->cli->trans_enc_state == NULL) {
return (void *)false;
}
}
return (void *) (bool) (num_servers > 0);
}
return NULL;

View File

@ -182,7 +182,10 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx,
DATA_BLOB *user_sess_key,
DATA_BLOB *lm_sess_key)
{
static const unsigned char zeros[8] = { 0, };
unsigned char zeros[8];
ZERO_STRUCT(zeros);
if (nt_pw == NULL) {
DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n",
username));

View File

@ -823,7 +823,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
session_key.data);
DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
} else {
static const uint8 zeros[24] = { 0, };
uint8 zeros[24];
ZERO_STRUCT(zeros);
session_key = data_blob_talloc(
ntlmssp_state->mem_ctx, NULL, 16);
if (session_key.data == NULL) {
@ -1066,9 +1067,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
}
if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) {
static const uchar zeros[16] = { 0, };
uchar zeros[16];
/* do nothing - blobs are zero length */
ZERO_STRUCT(zeros);
/* session key is all zeros */
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);

497
source3/libsmb/smb_seal.c Normal file
View File

@ -0,0 +1,497 @@
/*
Unix SMB/CIFS implementation.
SMB Transport encryption (sealing) code.
Copyright (C) Jeremy Allison 2007.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
/******************************************************************************
Pull out the encryption context for this packet. 0 means global context.
******************************************************************************/
NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16 *p_enc_ctx_num)
{
if (smb_len(buf) < 8) {
return NT_STATUS_INVALID_BUFFER_SIZE;
}
if (buf[4] == 0xFF) {
if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') {
/* Not an encrypted buffer. */
return NT_STATUS_NOT_FOUND;
}
if (buf[5] == 'E') {
*p_enc_ctx_num = SVAL(buf,6);
return NT_STATUS_OK;
}
}
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
/******************************************************************************
Generic code for client and server.
Is encryption turned on ?
******************************************************************************/
bool common_encryption_on(struct smb_trans_enc_state *es)
{
return ((es != NULL) && es->enc_on);
}
/******************************************************************************
Generic code for client and server.
NTLM decrypt an incoming buffer.
Abartlett tells me that SSPI puts the signature first before the encrypted
output, so cope with the same for compatibility.
******************************************************************************/
NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
{
NTSTATUS status;
size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
size_t data_len;
char *inbuf;
DATA_BLOB sig;
if (buf_len < 8 + NTLMSSP_SIG_SIZE) {
return NT_STATUS_BUFFER_TOO_SMALL;
}
inbuf = (char *)smb_xmemdup(buf, buf_len);
/* Adjust for the signature. */
data_len = buf_len - 8 - NTLMSSP_SIG_SIZE;
/* Point at the signature. */
sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE);
status = ntlmssp_unseal_packet(ntlmssp_state,
(unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' <enc> <ctx> */
data_len,
(unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE,
data_len,
&sig);
if (!NT_STATUS_IS_OK(status)) {
SAFE_FREE(inbuf);
return status;
}
memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len);
/* Reset the length and overwrite the header. */
smb_setlen(buf,data_len + 4);
SAFE_FREE(inbuf);
return NT_STATUS_OK;
}
/******************************************************************************
Generic code for client and server.
NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out.
Abartlett tells me that SSPI puts the signature first before the encrypted
output, so do the same for compatibility.
******************************************************************************/
NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state,
uint16 enc_ctx_num,
char *buf,
char **ppbuf_out)
{
NTSTATUS status;
char *buf_out;
size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */
DATA_BLOB sig;
*ppbuf_out = NULL;
if (data_len == 0) {
return NT_STATUS_BUFFER_TOO_SMALL;
}
/*
* We know smb_len can't return a value > 128k, so no int overflow
* check needed.
*/
buf_out = SMB_XMALLOC_ARRAY(char, 8 + NTLMSSP_SIG_SIZE + data_len);
/* Copy the data from the original buffer. */
memcpy(buf_out + 8 + NTLMSSP_SIG_SIZE, buf + 8, data_len);
smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num);
sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
status = ntlmssp_seal_packet(ntlmssp_state,
(unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' <enc> <ctx> */
data_len,
(unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE,
data_len,
&sig);
if (!NT_STATUS_IS_OK(status)) {
data_blob_free(&sig);
SAFE_FREE(buf_out);
return status;
}
/* First 16 data bytes are signature for SSPI compatibility. */
memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE);
*ppbuf_out = buf_out;
return NT_STATUS_OK;
}
/******************************************************************************
Generic code for client and server.
gss-api decrypt an incoming buffer. We insist that the size of the
unwrapped buffer must be smaller or identical to the incoming buffer.
******************************************************************************/
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf)
{
gss_ctx_id_t gss_ctx = gss_state->gss_ctx;
OM_uint32 ret = 0;
OM_uint32 minor = 0;
int flags_got = 0;
gss_buffer_desc in_buf, out_buf;
size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
if (buf_len < 8) {
return NT_STATUS_BUFFER_TOO_SMALL;
}
in_buf.value = buf + 8;
in_buf.length = buf_len - 8;
ret = gss_unwrap(&minor,
gss_ctx,
&in_buf,
&out_buf,
&flags_got, /* did we get sign+seal ? */
(gss_qop_t *) NULL);
if (ret != GSS_S_COMPLETE) {
ADS_STATUS adss = ADS_ERROR_GSS(ret, minor);
DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n",
ads_errstr(adss) ));
return map_nt_error_from_gss(ret, minor);
}
if (out_buf.length > in_buf.length) {
DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap size (%u) too large (%u) !\n",
(unsigned int)out_buf.length,
(unsigned int)in_buf.length ));
gss_release_buffer(&minor, &out_buf);
return NT_STATUS_INVALID_PARAMETER;
}
memcpy(buf + 8, out_buf.value, out_buf.length);
/* Reset the length and overwrite the header. */
smb_setlen(buf, out_buf.length + 4);
gss_release_buffer(&minor, &out_buf);
return NT_STATUS_OK;
}
/******************************************************************************
Generic code for client and server.
gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
******************************************************************************/
static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state,
uint16 enc_ctx_num,
char *buf,
char **ppbuf_out)
{
gss_ctx_id_t gss_ctx = gss_state->gss_ctx;
OM_uint32 ret = 0;
OM_uint32 minor = 0;
int flags_got = 0;
gss_buffer_desc in_buf, out_buf;
size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
*ppbuf_out = NULL;
if (buf_len < 8) {
return NT_STATUS_BUFFER_TOO_SMALL;
}
in_buf.value = buf + 8;
in_buf.length = buf_len - 8;
ret = gss_wrap(&minor,
gss_ctx,
true, /* we want sign+seal. */
GSS_C_QOP_DEFAULT,
&in_buf,
&flags_got, /* did we get sign+seal ? */
&out_buf);
if (ret != GSS_S_COMPLETE) {
ADS_STATUS adss = ADS_ERROR_GSS(ret, minor);
DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n",
ads_errstr(adss) ));
return map_nt_error_from_gss(ret, minor);
}
if (!flags_got) {
/* Sign+seal not supported. */
gss_release_buffer(&minor, &out_buf);
return NT_STATUS_NOT_SUPPORTED;
}
/* Ya see - this is why I *hate* gss-api. I don't
* want to have to malloc another buffer of the
* same size + 8 bytes just to get a continuous
* header + buffer, but gss won't let me pass in
* a pre-allocated buffer. Bastards (and you know
* who you are....). I might fix this by
* going to "encrypt_and_send" passing in a file
* descriptor and doing scatter-gather write with
* TCP cork on Linux. But I shouldn't have to
* bother :-*(. JRA.
*/
*ppbuf_out = (char *)SMB_MALLOC(out_buf.length + 8); /* We know this can't wrap. */
if (!*ppbuf_out) {
gss_release_buffer(&minor, &out_buf);
return NT_STATUS_NO_MEMORY;
}
memcpy(*ppbuf_out+8, out_buf.value, out_buf.length);
smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num);
gss_release_buffer(&minor, &out_buf);
return NT_STATUS_OK;
}
#endif
/******************************************************************************
Generic code for client and server.
Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
******************************************************************************/
NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out)
{
if (!common_encryption_on(es)) {
/* Not encrypting. */
*buf_out = buffer;
return NT_STATUS_OK;
}
switch (es->smb_enc_type) {
case SMB_TRANS_ENC_NTLM:
return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, es->enc_ctx_num, buffer, buf_out);
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
case SMB_TRANS_ENC_GSS:
return common_gss_encrypt_buffer(es->s.gss_state, es->enc_ctx_num, buffer, buf_out);
#endif
default:
return NT_STATUS_NOT_SUPPORTED;
}
}
/******************************************************************************
Generic code for client and server.
Decrypt an incoming SMB buffer. Replaces the data within it.
New data must be less than or equal to the current length.
******************************************************************************/
NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf)
{
if (!common_encryption_on(es)) {
/* Not decrypting. */
return NT_STATUS_OK;
}
switch (es->smb_enc_type) {
case SMB_TRANS_ENC_NTLM:
return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf);
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
case SMB_TRANS_ENC_GSS:
return common_gss_decrypt_buffer(es->s.gss_state, buf);
#endif
default:
return NT_STATUS_NOT_SUPPORTED;
}
}
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
/******************************************************************************
Shutdown a gss encryption state.
******************************************************************************/
static void common_free_gss_state(struct smb_tran_enc_state_gss **pp_gss_state)
{
OM_uint32 minor = 0;
struct smb_tran_enc_state_gss *gss_state = *pp_gss_state;
if (gss_state->creds != GSS_C_NO_CREDENTIAL) {
gss_release_cred(&minor, &gss_state->creds);
}
if (gss_state->gss_ctx != GSS_C_NO_CONTEXT) {
gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL);
}
SAFE_FREE(*pp_gss_state);
}
#endif
/******************************************************************************
Shutdown an encryption state.
******************************************************************************/
void common_free_encryption_state(struct smb_trans_enc_state **pp_es)
{
struct smb_trans_enc_state *es = *pp_es;
if (es == NULL) {
return;
}
if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
if (es->s.ntlmssp_state) {
ntlmssp_end(&es->s.ntlmssp_state);
}
}
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
if (es->smb_enc_type == SMB_TRANS_ENC_GSS) {
/* Free the gss context handle. */
if (es->s.gss_state) {
common_free_gss_state(&es->s.gss_state);
}
}
#endif
SAFE_FREE(es);
*pp_es = NULL;
}
/******************************************************************************
Free an encryption-allocated buffer.
******************************************************************************/
void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf)
{
if (!common_encryption_on(es)) {
return;
}
if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
SAFE_FREE(buf);
return;
}
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
if (es->smb_enc_type == SMB_TRANS_ENC_GSS) {
OM_uint32 min;
gss_buffer_desc rel_buf;
rel_buf.value = buf;
rel_buf.length = smb_len(buf) + 4;
gss_release_buffer(&min, &rel_buf);
}
#endif
}
/******************************************************************************
Client side encryption.
******************************************************************************/
/******************************************************************************
Is client encryption on ?
******************************************************************************/
bool cli_encryption_on(struct cli_state *cli)
{
/* If we supported multiple encrytion contexts
* here we'd look up based on tid.
*/
return common_encryption_on(cli->trans_enc_state);
}
/******************************************************************************
Shutdown a client encryption state.
******************************************************************************/
void cli_free_encryption_context(struct cli_state *cli)
{
common_free_encryption_state(&cli->trans_enc_state);
}
/******************************************************************************
Free an encryption-allocated buffer.
******************************************************************************/
void cli_free_enc_buffer(struct cli_state *cli, char *buf)
{
/* We know this is an smb buffer, and we
* didn't malloc, only copy, for a keepalive,
* so ignore non-session messages. */
if(CVAL(buf,0)) {
return;
}
/* If we supported multiple encrytion contexts
* here we'd look up based on tid.
*/
common_free_enc_buffer(cli->trans_enc_state, buf);
}
/******************************************************************************
Decrypt an incoming buffer.
******************************************************************************/
NTSTATUS cli_decrypt_message(struct cli_state *cli)
{
NTSTATUS status;
uint16 enc_ctx_num;
/* Ignore non-session messages. */
if(CVAL(cli->inbuf,0)) {
return NT_STATUS_OK;
}
status = get_enc_ctx_num((const uint8_t *)cli->inbuf, &enc_ctx_num);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) {
return NT_STATUS_INVALID_HANDLE;
}
return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf);
}
/******************************************************************************
Encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
******************************************************************************/
NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out)
{
/* Ignore non-session messages. */
if(CVAL(cli->outbuf,0)) {
return NT_STATUS_OK;
}
/* If we supported multiple encrytion contexts
* here we'd look up based on tid.
*/
return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out);
}

View File

@ -745,8 +745,8 @@ bool srv_oplock_set_signing(bool onoff)
bool srv_check_sign_mac(const char *inbuf, bool must_be_ok)
{
/* Check if it's a session keepalive. */
if(CVAL(inbuf,0) == SMBkeepalive) {
/* Check if it's a non-session message. */
if(CVAL(inbuf,0)) {
return True;
}
@ -759,8 +759,8 @@ bool srv_check_sign_mac(const char *inbuf, bool must_be_ok)
void srv_calculate_sign_mac(char *outbuf)
{
/* Check if it's a session keepalive. */
if(CVAL(outbuf,0) == SMBkeepalive) {
/* Check if it's a non-session message. */
if(CVAL(outbuf,0)) {
return;
}

View File

@ -704,16 +704,22 @@ char *decrypt_trustdom_secret(const char *pass, DATA_BLOB *data_in)
void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,
const char *pwd,
DATA_BLOB *session_key,
struct wkssvc_PasswordBuffer *pwd_buf)
struct wkssvc_PasswordBuffer **pwd_buf)
{
uint8_t buffer[516];
struct MD5Context ctx;
DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
struct wkssvc_PasswordBuffer *my_pwd_buf = NULL;
DATA_BLOB confounded_session_key;
int confounder_len = 8;
uint8_t confounder[8];
my_pwd_buf = talloc_zero(mem_ctx, struct wkssvc_PasswordBuffer);
if (!my_pwd_buf) {
return;
}
confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16);
encode_pw_buffer(buffer, pwd, STR_UNICODE);
generate_random_buffer((uint8_t *)confounder, confounder_len);
@ -725,10 +731,12 @@ void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,
SamOEMhashBlob(buffer, 516, &confounded_session_key);
memcpy(&pwd_buf->data[0], confounder, confounder_len);
memcpy(&pwd_buf->data[8], buffer, 516);
memcpy(&my_pwd_buf->data[0], confounder, confounder_len);
memcpy(&my_pwd_buf->data[8], buffer, 516);
data_blob_free(&confounded_session_key);
*pwd_buf = my_pwd_buf;
}
WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx,

View File

@ -608,7 +608,10 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
for (i = 0; i < lck->num_share_modes; i++) {
struct share_mode_entry *entry_p = &lck->share_modes[i];
char *str = share_mode_str(NULL, i, entry_p);
char *str = NULL;
if (DEBUGLEVEL >= 10) {
str = share_mode_str(NULL, i, entry_p);
}
DEBUG(10,("parse_share_modes: %s\n",
str ? str : ""));
if (!process_exists(entry_p->pid)) {

View File

@ -309,7 +309,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
}
DEBUG(10, ("smb_get_nt_acl_nfs4_common successfully exited with sd_size %d\n",
sec_desc_size(*ppdesc)));
ndr_size_security_descriptor(*ppdesc, 0)));
return NT_STATUS_OK;
}

View File

@ -264,8 +264,8 @@ int solarisacl_sys_acl_set_fd(vfs_handle_struct *handle,
}
done:
DEBUG(10, ("solarisacl_sys_acl_st_fd %s.\n",
((ret == 0) ? "succeded" : "failed" )));
DEBUG(10, ("solarisacl_sys_acl_set_fd %s.\n",
((ret == 0) ? "succeeded" : "failed" )));
SAFE_FREE(solaris_acl);
SAFE_FREE(default_acl);
return ret;

View File

@ -336,7 +336,9 @@ bool check_elections(void)
for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
struct work_record *work;
for (work = subrec->workgrouplist; work; work = work->next) {
run_any_election |= work->RunningElection;
if (work->RunningElection) {
run_any_election = work->RunningElection;
}
/*
* Start an election if we have any chance of winning.

View File

@ -1613,6 +1613,8 @@ void retransmit_or_expire_response_records(time_t t)
for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
struct response_record *rrec, *nextrrec;
restart:
for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
nextrrec = rrec->next;
@ -1651,6 +1653,9 @@ on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_
no timeout function. */
remove_response_record(subrec, rrec);
}
/* We have changed subrec->responselist,
* restart from the beginning of this list. */
goto restart;
} /* !rrec->in_expitation_processing */
} /* rrec->repeat_count > 0 */
} /* rrec->repeat_time <= t */
@ -1924,7 +1929,7 @@ bool send_mailslot(bool unique, const char *mailslot,char *buf, size_t len,
return false;
}
set_message(ptr,17,strlen(mailslot) + 1 + len,True);
cli_set_message(ptr,17,strlen(mailslot) + 1 + len,True);
memcpy(ptr,tmp,4);
SCVAL(ptr,smb_com,SMBtrans);

View File

@ -31,26 +31,12 @@ int num_response_packets = 0;
static void add_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
struct response_record *rrec2;
num_response_packets++; /* count of total number of packets still around */
DEBUG(4,("add_response_record: adding response record id:%hu to subnet %s. num_records:%d\n",
rrec->response_id, subrec->subnet_name, num_response_packets));
if (!subrec->responselist) {
subrec->responselist = rrec;
rrec->prev = NULL;
rrec->next = NULL;
return;
}
for (rrec2 = subrec->responselist; rrec2->next; rrec2 = rrec2->next)
;
rrec2->next = rrec;
rrec->next = NULL;
rrec->prev = rrec2;
DLIST_ADD_END(subrec->responselist, rrec, struct response_record *);
}
/***************************************************************************
@ -60,13 +46,7 @@ static void add_response_record(struct subnet_record *subrec,
void remove_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
if (rrec->prev)
rrec->prev->next = rrec->next;
if (rrec->next)
rrec->next->prev = rrec->prev;
if (subrec->responselist == rrec)
subrec->responselist = rrec->next;
DLIST_REMOVE(subrec->responselist, rrec);
if(rrec->userdata) {
if(rrec->userdata->free_fn) {

View File

@ -31,7 +31,7 @@
* @return #wbcErr
**/
wbcErr wbcAuthenticateUser(const char *username,
wbcErr wbcAuthenticateUser(const char *username,
const char *password)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
@ -61,5 +61,5 @@ wbcErr wbcAuthenticateUser(const char *username,
BAIL_ON_WBC_ERROR(wbc_status);
done:
return wbc_status;
return wbc_status;
}

View File

@ -228,13 +228,14 @@ wbcErr wbcGetgrnam(const char *name, struct group **grp)
&response);
BAIL_ON_WBC_ERROR(wbc_status);
*grp = copy_group_entry(&response.data.gr, response.extra_data.data);
*grp = copy_group_entry(&response.data.gr,
(char*)response.extra_data.data);
BAIL_ON_PTR_ERROR(*grp, wbc_status);
done:
if (response.extra_data.data)
free(response.extra_data.data);
return wbc_status;
}
@ -270,7 +271,8 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
&response);
BAIL_ON_WBC_ERROR(wbc_status);
*grp = copy_group_entry(&response.data.gr, response.extra_data.data);
*grp = copy_group_entry(&response.data.gr,
(char*)response.extra_data.data);
BAIL_ON_PTR_ERROR(*grp, wbc_status);
done:

View File

@ -265,12 +265,12 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
/* Copy out result */
if (domain != NULL) {
*domain = strdup(response.data.name.dom_name);
*domain = talloc_strdup(NULL, response.data.name.dom_name);
BAIL_ON_PTR_ERROR((*domain), wbc_status);
}
if (name != NULL) {
*name = strdup(response.data.name.name);
*name = talloc_strdup(NULL, response.data.name.name);
BAIL_ON_PTR_ERROR((*name), wbc_status);
}
@ -283,9 +283,9 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
done:
if (!WBC_ERROR_IS_OK(wbc_status)) {
if (*domain)
free(*domain);
talloc_free(*domain);
if (*name)
free(*name);
talloc_free(*name);
}
return wbc_status;
@ -334,11 +334,9 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
ridbuf_size = (sizeof(char)*11) * num_rids + 1;
ridlist = malloc(ridbuf_size);
ridlist = talloc_zero_array(NULL, char, ridbuf_size);
BAIL_ON_PTR_ERROR(ridlist, wbc_status);
memset(ridlist, 0x0, ridbuf_size);
len = 0;
for (i=0; i<num_rids && (len-1)>0; i++) {
char ridstr[12];
@ -356,15 +354,15 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
wbc_status = wbcRequestResponse(WINBINDD_LOOKUPRIDS,
&request,
&response);
free(ridlist);
talloc_free(ridlist);
domain_name = strdup(response.data.domain_name);
domain_name = talloc_strdup(NULL, response.data.domain_name);
BAIL_ON_PTR_ERROR(domain_name, wbc_status);
*names = (const char**)malloc(sizeof(char*) * num_rids);
*names = talloc_array(NULL, const char*, num_rids);
BAIL_ON_PTR_ERROR((*names), wbc_status);
*types = (enum wbcSidType*)malloc(sizeof(enum wbcSidType) * num_rids);
*types = talloc_array(NULL, enum wbcSidType, num_rids);
BAIL_ON_PTR_ERROR((*types), wbc_status);
p = (char *)response.extra_data.data;
@ -393,7 +391,8 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
*q = '\0';
(*names)[i] = strdup(p);
(*names)[i] = talloc_strdup((*names), p);
BAIL_ON_PTR_ERROR(((*names)[i]), wbc_status);
p = q+1;
}
@ -403,18 +402,20 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
BAIL_ON_WBC_ERROR(wbc_status);
}
free(response.extra_data.data);
wbc_status = WBC_ERR_SUCCESS;
done:
if (response.extra_data.data) {
free(response.extra_data.data);
}
if (!WBC_ERROR_IS_OK(wbc_status)) {
if (domain_name)
free(domain_name);
talloc_free(domain_name);
if (*names)
free(*names);
talloc_free(*names);
if (*types)
free(*types);
talloc_free(*types);
} else {
*pp_domain_name = domain_name;
}

View File

@ -51,10 +51,6 @@ wbcErr wbcPing(void)
*
* @return #wbcErr
*
* The char* members of the struct wbcDomainInfo* are malloc()'d
* and it the the responsibility of the caller to free the members
* before discarding the struct.
*
**/
@ -64,7 +60,7 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
struct winbindd_response response;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcDomainInfo *info = NULL;
if (!domain || !dinfo) {
wbc_status = WBC_ERR_INVALID_PARAM;
BAIL_ON_WBC_ERROR(wbc_status);
@ -75,7 +71,7 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
strncpy(request.domain_name, domain,
strncpy(request.domain_name, domain,
sizeof(request.domain_name)-1);
wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_INFO,
@ -86,15 +82,15 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
info = talloc(NULL, struct wbcDomainInfo);
BAIL_ON_PTR_ERROR(info, wbc_status);
info->short_name = talloc_strdup(info,
info->short_name = talloc_strdup(info,
response.data.domain_info.name);
BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
info->dns_name = talloc_strdup(info,
info->dns_name = talloc_strdup(info,
response.data.domain_info.alt_name);
BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
wbc_status = wbcStringToSid(response.data.domain_info.sid,
wbc_status = wbcStringToSid(response.data.domain_info.sid,
&info->sid);
BAIL_ON_WBC_ERROR(wbc_status);
@ -106,7 +102,7 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
info->flags |= WBC_DOMINFO_PRIMARY;
*dinfo = info;
wbc_status = WBC_ERR_SUCCESS;
done:

View File

@ -177,7 +177,7 @@ wbcErr wbcDomainSequenceNumbers(void);
* Athenticate functions
*/
wbcErr wbcAuthenticateUser(const char *username,
wbcErr wbcAuthenticateUser(const char *username,
const char *password);

View File

@ -472,6 +472,7 @@ typedef struct {
int iAioWriteSize;
int iMap_readonly;
int iDirectoryNameCacheSize;
int ismb_encrypt;
param_opt_struct *param_opt;
char dummy[3]; /* for alignment */
@ -617,6 +618,7 @@ static service sDefault = {
#else
100, /* iDirectoryNameCacheSize */
#endif
Auto, /* ismb_encrypt */
NULL, /* Parametric options */
"" /* dummy */
@ -1027,6 +1029,7 @@ static struct parm_struct parm_table[] = {
{"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
{"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
{"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
{"smb encrypt", P_ENUM, P_LOCAL, &sDefault.ismb_encrypt, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
{"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
{"client ldap sasl wrapping", P_ENUM, P_GLOBAL, &Globals.client_ldap_sasl_wrapping, NULL, enum_ldap_sasl_wrapping, FLAG_ADVANCED},
{"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
@ -2173,6 +2176,7 @@ FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
FN_LOCAL_CHAR(lp_magicchar, magic_char)
FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
@ -6218,7 +6222,9 @@ bool lp_use_sendfile(int snum)
if (Protocol < PROTOCOL_NT1) {
return False;
}
return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
return (_lp_use_sendfile(snum) &&
(get_remote_arch() != RA_WIN95) &&
!srv_is_signing_active());
}
/*******************************************************************

View File

@ -25,10 +25,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB
/* Cache of latest SAM lookup query */
static struct samu *csamuser = NULL;
static_decl_pdb;
static struct pdb_init_function_entry *backends = NULL;
@ -208,55 +204,32 @@ static struct pdb_methods *pdb_get_methods(void)
return pdb_get_methods_reload(False);
}
/******************************************************************
Backward compatibility functions for the original passdb interface
*******************************************************************/
bool pdb_setsampwent(bool update, uint16 acb_mask)
{
struct pdb_methods *pdb = pdb_get_methods();
return NT_STATUS_IS_OK(pdb->setsampwent(pdb, update, acb_mask));
}
void pdb_endsampwent(void)
{
struct pdb_methods *pdb = pdb_get_methods();
pdb->endsampwent(pdb);
}
bool pdb_getsampwent(struct samu *user)
{
struct pdb_methods *pdb = pdb_get_methods();
if ( !NT_STATUS_IS_OK(pdb->getsampwent(pdb, user) ) ) {
return False;
}
return True;
}
bool pdb_getsampwnam(struct samu *sam_acct, const char *username)
{
struct pdb_methods *pdb = pdb_get_methods();
struct samu *cache_copy;
const struct dom_sid *user_sid;
if (!NT_STATUS_IS_OK(pdb->getsampwnam(pdb, sam_acct, username))) {
return False;
}
if ( csamuser ) {
TALLOC_FREE(csamuser);
}
csamuser = samu_new( NULL );
if (!csamuser) {
cache_copy = samu_new(NULL);
if (cache_copy == NULL) {
return False;
}
if (!pdb_copy_sam_account(csamuser, sam_acct)) {
TALLOC_FREE(csamuser);
if (!pdb_copy_sam_account(cache_copy, sam_acct)) {
TALLOC_FREE(cache_copy);
return False;
}
user_sid = pdb_get_user_sid(cache_copy);
memcache_add_talloc(NULL, PDB_GETPWSID_CACHE,
data_blob_const(user_sid, sizeof(*user_sid)),
cache_copy);
return True;
}
@ -289,6 +262,7 @@ bool pdb_getsampwsid(struct samu *sam_acct, const DOM_SID *sid)
{
struct pdb_methods *pdb = pdb_get_methods();
uint32 rid;
void *cache_data;
/* hard code the Guest RID of 501 */
@ -301,9 +275,16 @@ bool pdb_getsampwsid(struct samu *sam_acct, const DOM_SID *sid)
}
/* check the cache first */
if ( csamuser && sid_equal(sid, pdb_get_user_sid(csamuser) ) )
return pdb_copy_sam_account(sam_acct, csamuser);
cache_data = memcache_lookup_talloc(
NULL, PDB_GETPWSID_CACHE, data_blob_const(sid, sizeof(*sid)));
if (cache_data != NULL) {
struct samu *cache_copy = talloc_get_type_abort(
cache_data, struct samu);
return pdb_copy_sam_account(sam_acct, cache_copy);
}
return NT_STATUS_IS_OK(pdb->getsampwsid(pdb, sam_acct, sid));
}
@ -498,10 +479,7 @@ NTSTATUS pdb_update_sam_account(struct samu *sam_acct)
{
struct pdb_methods *pdb = pdb_get_methods();
if (csamuser != NULL) {
TALLOC_FREE(csamuser);
csamuser = NULL;
}
memcache_flush(NULL, PDB_GETPWSID_CACHE);
return pdb->update_sam_account(pdb, sam_acct);
}
@ -510,10 +488,7 @@ NTSTATUS pdb_delete_sam_account(struct samu *sam_acct)
{
struct pdb_methods *pdb = pdb_get_methods();
if (csamuser != NULL) {
TALLOC_FREE(csamuser);
csamuser = NULL;
}
memcache_flush(NULL, PDB_GETPWSID_CACHE);
return pdb->delete_sam_account(pdb, sam_acct);
}
@ -524,10 +499,7 @@ NTSTATUS pdb_rename_sam_account(struct samu *oldname, const char *newname)
uid_t uid;
NTSTATUS status;
if (csamuser != NULL) {
TALLOC_FREE(csamuser);
csamuser = NULL;
}
memcache_flush(NULL, PDB_GETPWSID_CACHE);
/* sanity check to make sure we don't rename root */
@ -1181,21 +1153,6 @@ static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods,
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, bool update, uint32 acb_mask)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, struct samu *user)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static void pdb_default_endsampwent(struct pdb_methods *methods)
{
return; /* NT_STATUS_NOT_IMPLEMENTED; */
}
static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
{
return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
@ -1738,7 +1695,7 @@ static NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
}
#endif
static struct pdb_search *pdb_search_init(enum pdb_search_type type)
struct pdb_search *pdb_search_init(enum pdb_search_type type)
{
TALLOC_CTX *mem_ctx;
struct pdb_search *result;
@ -1795,81 +1752,6 @@ static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
entry->description = "";
}
static bool user_search_in_progress = False;
struct user_search {
uint16 acct_flags;
};
static bool next_entry_users(struct pdb_search *s,
struct samr_displayentry *entry)
{
struct user_search *state = (struct user_search *)s->private_data;
struct samu *user = NULL;
next:
if ( !(user = samu_new( NULL )) ) {
DEBUG(0, ("next_entry_users: samu_new() failed!\n"));
return False;
}
if (!pdb_getsampwent(user)) {
TALLOC_FREE(user);
return False;
}
if ((state->acct_flags != 0) &&
((pdb_get_acct_ctrl(user) & state->acct_flags) == 0)) {
TALLOC_FREE(user);
goto next;
}
fill_displayentry(s->mem_ctx, pdb_get_user_rid(user),
pdb_get_acct_ctrl(user), pdb_get_username(user),
pdb_get_fullname(user), pdb_get_acct_desc(user),
entry);
TALLOC_FREE(user);
return True;
}
static void search_end_users(struct pdb_search *search)
{
pdb_endsampwent();
user_search_in_progress = False;
}
static bool pdb_default_search_users(struct pdb_methods *methods,
struct pdb_search *search,
uint32 acct_flags)
{
struct user_search *state;
if (user_search_in_progress) {
DEBUG(1, ("user search in progress\n"));
return False;
}
if (!pdb_setsampwent(False, acct_flags)) {
DEBUG(5, ("Could not start search\n"));
return False;
}
user_search_in_progress = True;
state = TALLOC_P(search->mem_ctx, struct user_search);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
return False;
}
state->acct_flags = acct_flags;
search->private_data = state;
search->next_entry = next_entry_users;
search->search_end = search_end_users;
return True;
}
struct group_search {
GROUP_MAP *groups;
size_t num_groups, current_group;
@ -2136,9 +2018,6 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods )
return NT_STATUS_NO_MEMORY;
}
(*methods)->setsampwent = pdb_default_setsampwent;
(*methods)->endsampwent = pdb_default_endsampwent;
(*methods)->getsampwent = pdb_default_getsampwent;
(*methods)->getsampwnam = pdb_default_getsampwnam;
(*methods)->getsampwsid = pdb_default_getsampwsid;
(*methods)->create_user = pdb_default_create_user;
@ -2180,7 +2059,6 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods )
(*methods)->gid_to_sid = pdb_default_gid_to_sid;
(*methods)->sid_to_id = pdb_default_sid_to_id;
(*methods)->search_users = pdb_default_search_users;
(*methods)->search_groups = pdb_default_search_groups;
(*methods)->search_aliases = pdb_default_search_aliases;

View File

@ -1453,79 +1453,6 @@ static bool init_ldap_from_sam (struct ldapsam_privates *ldap_state,
return True;
}
/**********************************************************************
Connect to LDAP server for password enumeration.
*********************************************************************/
static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, bool update, uint32 acb_mask)
{
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
int rc;
char *filter = NULL;
const char *suffix;
const char **attr_list;
bool machine_mask = False, user_mask = False;
NTSTATUS status = NT_STATUS_OK;
TALLOC_CTX *ctx = talloc_init("ldapsam_setsampwent");
if (!ctx) {
return NT_STATUS_NO_MEMORY;
}
filter = talloc_asprintf(ctx, "(&%s%s)", "(uid=%u)",
get_objclass_filter(ldap_state->schema_ver));
if (!filter) {
status = NT_STATUS_NO_MEMORY;
goto out;
}
filter = talloc_all_string_sub(ctx, filter, "%u", "*");
if (!filter) {
status = NT_STATUS_NO_MEMORY;
goto out;
}
machine_mask = ((acb_mask != 0) && (acb_mask & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)));
user_mask = ((acb_mask != 0) && (acb_mask & ACB_NORMAL));
if (machine_mask) {
suffix = lp_ldap_machine_suffix();
} else if (user_mask) {
suffix = lp_ldap_user_suffix();
} else {
suffix = lp_ldap_suffix();
}
DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n",
acb_mask, suffix));
attr_list = get_userattr_list(NULL, ldap_state->schema_ver);
rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter,
attr_list, 0, &ldap_state->result);
TALLOC_FREE( attr_list );
if (rc != LDAP_SUCCESS) {
DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix, filter));
ldap_msgfree(ldap_state->result);
ldap_state->result = NULL;
status = NT_STATUS_UNSUCCESSFUL;
goto out;
}
DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n",
ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
ldap_state->result), suffix));
ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
ldap_state->result);
ldap_state->index = 0;
out:
TALLOC_FREE(ctx);
return status;
}
/**********************************************************************
End enumeration of the LDAP password list.
*********************************************************************/
@ -1539,32 +1466,6 @@ static void ldapsam_endsampwent(struct pdb_methods *my_methods)
}
}
/**********************************************************************
Get the next entry in the LDAP password database.
*********************************************************************/
static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods,
struct samu *user)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)my_methods->private_data;
bool bret = False;
while (!bret) {
if (!ldap_state->entry)
return ret;
ldap_state->index++;
bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
ldap_state->entry = ldap_next_entry(priv2ld(ldap_state),
ldap_state->entry);
}
return NT_STATUS_OK;
}
static void append_attr(TALLOC_CTX *mem_ctx, const char ***attr_list,
const char *new_attr)
{
@ -1867,6 +1768,10 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
SAFE_FREE(ld_error);
ber_bvfree(bv);
#if defined(LDAP_CONSTRAINT_VIOLATION)
if (rc == LDAP_CONSTRAINT_VIOLATION)
return NT_STATUS_PASSWORD_RESTRICTION;
#endif
return NT_STATUS_UNSUCCESSFUL;
} else {
DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
@ -6172,9 +6077,6 @@ static NTSTATUS pdb_init_ldapsam_common(struct pdb_methods **pdb_method, const c
(*pdb_method)->name = "ldapsam";
(*pdb_method)->setsampwent = ldapsam_setsampwent;
(*pdb_method)->endsampwent = ldapsam_endsampwent;
(*pdb_method)->getsampwent = ldapsam_getsampwent;
(*pdb_method)->getsampwnam = ldapsam_getsampwnam;
(*pdb_method)->getsampwsid = ldapsam_getsampwsid;
(*pdb_method)->add_sam_account = ldapsam_add_sam_account;

View File

@ -1264,79 +1264,6 @@ static bool build_sam_account(struct smbpasswd_privates *smbpasswd_state,
Functions to be implemented by the new passdb API
****************************************************************/
static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, bool update, uint32 acb_mask)
{
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
update ? PWF_UPDATE : PWF_READ,
&(smbpasswd_state->pw_file_lock_depth));
/* did we fail? Should we try to create it? */
if (!smbpasswd_state->pw_file && update && errno == ENOENT) {
FILE *fp;
/* slprintf(msg_str,msg_str_len-1,
"smbpasswd file did not exist - attempting to create it.\n"); */
DEBUG(0,("smbpasswd file did not exist - attempting to create it.\n"));
fp = sys_fopen(smbpasswd_state->smbpasswd_file, "w");
if (fp) {
fprintf(fp, "# Samba SMB password file\n");
fclose(fp);
}
smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
update ? PWF_UPDATE : PWF_READ,
&(smbpasswd_state->pw_file_lock_depth));
}
if (smbpasswd_state->pw_file != NULL)
return NT_STATUS_OK;
else
return NT_STATUS_UNSUCCESSFUL;
}
static void smbpasswd_endsampwent (struct pdb_methods *my_methods)
{
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth));
}
/*****************************************************************
****************************************************************/
static NTSTATUS smbpasswd_getsampwent(struct pdb_methods *my_methods, struct samu *user)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd *pw_buf=NULL;
bool done = False;
DEBUG(5,("pdb_getsampwent\n"));
if ( !user ) {
DEBUG(5,("pdb_getsampwent (smbpasswd): user is NULL\n"));
return nt_status;
}
while (!done) {
/* do we have an entry? */
pw_buf = getsmbfilepwent(smbpasswd_state, smbpasswd_state->pw_file);
if (pw_buf == NULL)
return nt_status;
/* build the struct samu entry from the smb_passwd struct.
We loop in case the user in the pdb does not exist in
the local system password file */
if (build_sam_account(smbpasswd_state, user, pw_buf))
done = True;
}
DEBUG(5,("getsampwent (smbpasswd): done\n"));
/* success */
return NT_STATUS_OK;
}
/****************************************************************
Search smbpasswd file by iterating over the entries. Do not
call getpwnam() for unix account information until we have found
@ -1606,6 +1533,119 @@ static void free_private_data(void **vp)
/* No need to free any further, as it is talloc()ed */
}
struct smbpasswd_search_state {
uint32_t acct_flags;
struct samr_displayentry *entries;
uint32_t num_entries;
ssize_t array_size;
uint32_t current;
};
static void smbpasswd_search_end(struct pdb_search *search)
{
struct smbpasswd_search_state *state = talloc_get_type_abort(
search->private_data, struct smbpasswd_search_state);
TALLOC_FREE(state);
}
static bool smbpasswd_search_next_entry(struct pdb_search *search,
struct samr_displayentry *entry)
{
struct smbpasswd_search_state *state = talloc_get_type_abort(
search->private_data, struct smbpasswd_search_state);
if (state->current == state->num_entries) {
return false;
}
*entry = state->entries[state->current++];
return true;
}
static bool smbpasswd_search_users(struct pdb_methods *methods,
struct pdb_search *search,
uint32_t acct_flags)
{
struct smbpasswd_privates *smbpasswd_state =
(struct smbpasswd_privates*)methods->private_data;
struct smbpasswd_search_state *search_state;
struct smb_passwd *pwd;
FILE *fp;
search_state = TALLOC_ZERO_P(search->mem_ctx,
struct smbpasswd_search_state);
if (search_state == NULL) {
DEBUG(0, ("talloc failed\n"));
return false;
}
search_state->acct_flags = acct_flags;
fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ,
&smbpasswd_state->pw_file_lock_depth);
if (fp == NULL) {
DEBUG(10, ("Unable to open smbpasswd file.\n"));
TALLOC_FREE(search_state);
return false;
}
while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) {
struct samr_displayentry entry;
struct samu *user;
if ((acct_flags != 0)
&& ((acct_flags & pwd->acct_ctrl) == 0)) {
continue;
}
user = samu_new(talloc_tos());
if (user == NULL) {
DEBUG(0, ("samu_new failed\n"));
break;
}
if (!build_sam_account(smbpasswd_state, user, pwd)) {
/* Already got debug msgs... */
break;
}
ZERO_STRUCT(entry);
entry.acct_flags = pdb_get_acct_ctrl(user);
sid_peek_rid(pdb_get_user_sid(user), &entry.rid);
entry.account_name = talloc_strdup(
search_state, pdb_get_username(user));
entry.fullname = talloc_strdup(
search_state, pdb_get_fullname(user));
entry.description = talloc_strdup(
search_state, pdb_get_acct_desc(user));
TALLOC_FREE(user);
if ((entry.account_name == NULL) || (entry.fullname == NULL)
|| (entry.description == NULL)) {
DEBUG(0, ("talloc_strdup failed\n"));
break;
}
ADD_TO_LARGE_ARRAY(search_state, struct samr_displayentry,
entry, &search_state->entries,
&search_state->num_entries,
&search_state->array_size);
}
endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
search->private_data = search_state;
search->next_entry = smbpasswd_search_next_entry;
search->search_end = smbpasswd_search_end;
return true;
}
static NTSTATUS pdb_init_smbpasswd( struct pdb_methods **pdb_method, const char *location )
{
NTSTATUS nt_status;
@ -1617,15 +1657,13 @@ static NTSTATUS pdb_init_smbpasswd( struct pdb_methods **pdb_method, const char
(*pdb_method)->name = "smbpasswd";
(*pdb_method)->setsampwent = smbpasswd_setsampwent;
(*pdb_method)->endsampwent = smbpasswd_endsampwent;
(*pdb_method)->getsampwent = smbpasswd_getsampwent;
(*pdb_method)->getsampwnam = smbpasswd_getsampwnam;
(*pdb_method)->getsampwsid = smbpasswd_getsampwsid;
(*pdb_method)->add_sam_account = smbpasswd_add_sam_account;
(*pdb_method)->update_sam_account = smbpasswd_update_sam_account;
(*pdb_method)->delete_sam_account = smbpasswd_delete_sam_account;
(*pdb_method)->rename_sam_account = smbpasswd_rename_sam_account;
(*pdb_method)->search_users = smbpasswd_search_users;
(*pdb_method)->rid_algorithm = smbpasswd_rid_algorithm;

View File

@ -44,13 +44,6 @@ static int tdbsam_debug_level = DBGC_ALL;
#define RIDPREFIX "RID_"
#define PRIVPREFIX "PRIV_"
struct pwent_list {
struct pwent_list *prev, *next;
TDB_DATA key;
};
static struct pwent_list *tdbsam_pwent_list;
static bool pwent_initialized;
/* GLOBAL TDB SAM CONTEXT */
static TDB_CONTEXT *tdbsam;
@ -891,134 +884,6 @@ void tdbsam_close( void )
return;
}
/****************************************************************************
creates a list of user keys
****************************************************************************/
static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
{
const char *prefix = USERPREFIX;
int prefixlen = strlen (prefix);
struct pwent_list *ptr;
if ( strncmp((const char *)key.dptr, prefix, prefixlen) == 0 ) {
if ( !(ptr=SMB_MALLOC_P(struct pwent_list)) ) {
DEBUG(0,("tdbsam_traverse_setpwent: Failed to malloc new entry for list\n"));
/* just return 0 and let the traversal continue */
return 0;
}
ZERO_STRUCTP(ptr);
/* save a copy of the key */
ptr->key.dptr = (uint8 *)memdup( key.dptr, key.dsize );
if (!ptr->key.dptr) {
DEBUG(0,("tdbsam_traverse_setpwent: memdup failed\n"));
/* just return 0 and let the traversal continue */
SAFE_FREE(ptr);
return 0;
}
ptr->key.dsize = key.dsize;
DLIST_ADD( tdbsam_pwent_list, ptr );
}
return 0;
}
/***************************************************************
Open the TDB passwd database for SAM account enumeration.
Save a list of user keys for iteration.
****************************************************************/
static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, bool update, uint32 acb_mask)
{
if ( !tdbsam_open( tdbsam_filename ) ) {
DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n", tdbsam_filename));
return NT_STATUS_ACCESS_DENIED;
}
tdb_traverse( tdbsam, tdbsam_traverse_setpwent, NULL );
pwent_initialized = True;
return NT_STATUS_OK;
}
/***************************************************************
End enumeration of the TDB passwd list.
****************************************************************/
static void tdbsam_endsampwent(struct pdb_methods *my_methods)
{
struct pwent_list *ptr, *ptr_next;
/* close the tdb only if we have a valid pwent state */
if ( pwent_initialized ) {
DEBUG(7, ("endtdbpwent: closed sam database.\n"));
tdbsam_close();
}
/* clear out any remaining entries in the list */
for ( ptr=tdbsam_pwent_list; ptr; ptr = ptr_next ) {
ptr_next = ptr->next;
DLIST_REMOVE( tdbsam_pwent_list, ptr );
SAFE_FREE( ptr->key.dptr);
SAFE_FREE( ptr );
}
pwent_initialized = False;
}
/*****************************************************************
Get one struct samu from the TDB (next in line)
*****************************************************************/
static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, struct samu *user)
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
TDB_DATA data;
struct pwent_list *pkey;
if ( !user ) {
DEBUG(0,("tdbsam_getsampwent: struct samu is NULL.\n"));
return nt_status;
}
if ( !tdbsam_pwent_list ) {
DEBUG(4,("tdbsam_getsampwent: end of list\n"));
return nt_status;
}
/* pull the next entry */
pkey = tdbsam_pwent_list;
DLIST_REMOVE( tdbsam_pwent_list, pkey );
data = tdb_fetch(tdbsam, pkey->key);
SAFE_FREE( pkey->key.dptr);
SAFE_FREE( pkey);
if ( !data.dptr ) {
DEBUG(5,("pdb_getsampwent: database entry not found. Was the user deleted?\n"));
return nt_status;
}
if ( !init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize) ) {
DEBUG(0,("pdb_getsampwent: Bad struct samu entry returned from TDB!\n"));
}
SAFE_FREE( data.dptr );
return NT_STATUS_OK;
}
/******************************************************************
Lookup a name in the SAM TDB
******************************************************************/
@ -1306,10 +1171,6 @@ static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd,
{
bool result = True;
/* invalidate the existing TDB iterator if it is open */
tdbsam_endsampwent( my_methods );
#if 0
if ( !pdb_get_group_rid(newpwd) ) {
DEBUG (0,("tdb_update_sam: Failing to store a struct samu for [%s] "
@ -1396,10 +1257,6 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
return NT_STATUS_ACCESS_DENIED;
}
/* invalidate the existing TDB iterator if it is open */
tdbsam_endsampwent( my_methods );
if ( !(new_acct = samu_new( NULL )) ) {
return NT_STATUS_NO_MEMORY;
}
@ -1592,6 +1449,139 @@ static bool tdbsam_new_rid(struct pdb_methods *methods, uint32 *prid)
return ret;
}
struct tdbsam_search_state {
struct pdb_methods *methods;
uint32_t acct_flags;
uint32_t *rids;
uint32_t num_rids;
ssize_t array_size;
uint32_t current;
};
static int tdbsam_collect_rids(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data,
void *private_data)
{
struct tdbsam_search_state *state = talloc_get_type_abort(
private_data, struct tdbsam_search_state);
size_t prefixlen = strlen(RIDPREFIX);
uint32 rid;
if ((key.dsize < prefixlen)
|| (strncmp((char *)key.dptr, RIDPREFIX, prefixlen))) {
return 0;
}
rid = strtoul((char *)key.dptr+prefixlen, NULL, 16);
ADD_TO_LARGE_ARRAY(state, uint32, rid, &state->rids, &state->num_rids,
&state->array_size);
return 0;
}
static void tdbsam_search_end(struct pdb_search *search)
{
struct tdbsam_search_state *state = talloc_get_type_abort(
search->private_data, struct tdbsam_search_state);
TALLOC_FREE(state);
}
static bool tdbsam_search_next_entry(struct pdb_search *search,
struct samr_displayentry *entry)
{
struct tdbsam_search_state *state = talloc_get_type_abort(
search->private_data, struct tdbsam_search_state);
struct samu *user = NULL;
NTSTATUS status;
uint32_t rid;
again:
TALLOC_FREE(user);
user = samu_new(talloc_tos());
if (user == NULL) {
DEBUG(0, ("samu_new failed\n"));
return false;
}
if (state->current == state->num_rids) {
return false;
}
rid = state->rids[state->current++];
status = tdbsam_getsampwrid(state->methods, user, rid);
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
/*
* Someone has deleted that user since we listed the RIDs
*/
goto again;
}
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("tdbsam_getsampwrid failed: %s\n",
nt_errstr(status)));
TALLOC_FREE(user);
return false;
}
if ((state->acct_flags != 0) &&
((state->acct_flags & pdb_get_acct_ctrl(user)) == 0)) {
goto again;
}
entry->acct_flags = pdb_get_acct_ctrl(user);
entry->rid = rid;
entry->account_name = talloc_strdup(
search->mem_ctx, pdb_get_username(user));
entry->fullname = talloc_strdup(
search->mem_ctx, pdb_get_fullname(user));
entry->description = talloc_strdup(
search->mem_ctx, pdb_get_acct_desc(user));
TALLOC_FREE(user);
if ((entry->account_name == NULL) || (entry->fullname == NULL)
|| (entry->description == NULL)) {
DEBUG(0, ("talloc_strdup failed\n"));
return false;
}
return true;
}
static bool tdbsam_search_users(struct pdb_methods *methods,
struct pdb_search *search,
uint32 acct_flags)
{
struct tdbsam_search_state *state;
if (!tdbsam_open(tdbsam_filename)) {
DEBUG(0,("tdbsam_getsampwnam: failed to open %s!\n",
tdbsam_filename));
return false;
}
state = TALLOC_ZERO_P(search->mem_ctx, struct tdbsam_search_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
return false;
}
state->acct_flags = acct_flags;
state->methods = methods;
tdb_traverse(tdbsam, tdbsam_collect_rids, state);
tdbsam_close();
search->private_data = state;
search->next_entry = tdbsam_search_next_entry;
search->search_end = tdbsam_search_end;
return true;
}
/*********************************************************************
Initialize the tdb sam backend. Setup the dispath table of methods,
open the tdb, etc...
@ -1609,15 +1599,13 @@ static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *loc
(*pdb_method)->name = "tdbsam";
(*pdb_method)->setsampwent = tdbsam_setsampwent;
(*pdb_method)->endsampwent = tdbsam_endsampwent;
(*pdb_method)->getsampwent = tdbsam_getsampwent;
(*pdb_method)->getsampwnam = tdbsam_getsampwnam;
(*pdb_method)->getsampwsid = tdbsam_getsampwsid;
(*pdb_method)->add_sam_account = tdbsam_add_sam_account;
(*pdb_method)->update_sam_account = tdbsam_update_sam_account;
(*pdb_method)->delete_sam_account = tdbsam_delete_sam_account;
(*pdb_method)->rename_sam_account = tdbsam_rename_sam_account;
(*pdb_method)->search_users = tdbsam_search_users;
(*pdb_method)->rid_algorithm = tdbsam_rid_algorithm;
(*pdb_method)->new_rid = tdbsam_new_rid;
@ -1625,7 +1613,8 @@ static NTSTATUS pdb_init_tdbsam(struct pdb_methods **pdb_method, const char *loc
/* save the path for later */
if (!location) {
if (asprintf(&tdbfile, "%s/%s", get_dyn_STATEDIR(), PASSDB_FILE_NAME) < 0) {
if (asprintf(&tdbfile, "%s/%s", lp_private_dir(),
PASSDB_FILE_NAME) < 0) {
return NT_STATUS_NO_MEMORY;
}
pfile = tdbfile;

View File

@ -429,7 +429,8 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
/* store it back */
sd_size = sec_desc_size(sd_store->sd) + sizeof(SEC_DESC_BUF);
sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
+ sizeof(SEC_DESC_BUF);
prs_init(&ps, sd_size, ctx, MARSHALL);
if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_store, &ps, 1 ) ) {
@ -1866,7 +1867,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
goto err_exit;
}
create_directory(conn, new_dir);
create_directory(conn, NULL, new_dir);
/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
* listed for this driver which has already been moved, skip it (note:
@ -5389,8 +5390,9 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
/* Store the security descriptor in a tdb */
prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sd) +
sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
prs_init(&ps,
(uint32)ndr_size_security_descriptor(new_secdesc_ctr->sd, 0)
+ sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
&ps, 1)) {
@ -5534,7 +5536,7 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
/* Save default security descriptor for later */
prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sd) +
prs_init(&ps, (uint32)ndr_size_security_descriptor((*secdesc_ctr)->sd, 0) +
sizeof(SEC_DESC_BUF), ctx, MARSHALL);
if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {

View File

@ -373,13 +373,17 @@ static struct printjob *print_job_find(const char *sharename, uint32 jobid)
/* Convert a unix jobid to a smb jobid */
static uint32 sysjob_to_jobid_value;
struct unixjob_traverse_state {
int sysjob;
uint32 sysjob_to_jobid_value;
};
static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
TDB_DATA data, void *state)
TDB_DATA data, void *private_data)
{
struct printjob *pjob;
int *sysjob = (int *)state;
struct unixjob_traverse_state *state =
(struct unixjob_traverse_state *)private_data;
if (!data.dptr || data.dsize == 0)
return 0;
@ -388,10 +392,10 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
if (key.dsize != sizeof(uint32))
return 0;
if (*sysjob == pjob->sysjob) {
if (state->sysjob == pjob->sysjob) {
uint32 jobid = IVAL(key.dptr,0);
sysjob_to_jobid_value = jobid;
state->sysjob_to_jobid_value = jobid;
return 1;
}
@ -407,8 +411,10 @@ uint32 sysjob_to_jobid(int unix_jobid)
{
int services = lp_numservices();
int snum;
struct unixjob_traverse_state state;
sysjob_to_jobid_value = (uint32)-1;
state.sysjob = unix_jobid;
state.sysjob_to_jobid_value = (uint32)-1;
for (snum = 0; snum < services; snum++) {
struct tdb_print_db *pdb;
@ -418,10 +424,10 @@ uint32 sysjob_to_jobid(int unix_jobid)
if (!pdb) {
continue;
}
tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
release_print_db(pdb);
if (sysjob_to_jobid_value != (uint32)-1)
return sysjob_to_jobid_value;
if (state.sysjob_to_jobid_value != (uint32)-1)
return state.sysjob_to_jobid_value;
}
return (uint32)-1;
}

View File

@ -378,7 +378,7 @@ WERROR reg_queryinfokey(struct registry_key *key, uint32_t *num_subkeys,
return err;
}
*secdescsize = sec_desc_size(secdesc);
*secdescsize = ndr_size_security_descriptor(secdesc, 0);
TALLOC_FREE(mem_ctx);
*last_changed_time = 0;
@ -729,7 +729,7 @@ WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx,
}
/* recurse through subkeys first */
werr = reg_openkey(mem_ctx, parent, path, REG_KEY_WRITE, &key);
werr = reg_openkey(mem_ctx, parent, path, REG_KEY_ALL, &key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
}

View File

@ -25,19 +25,21 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_REGISTRY
static SORTED_TREE *cache_tree;
static SORTED_TREE *cache_tree = NULL;
extern REGISTRY_OPS regdb_ops; /* these are the default */
static REGISTRY_HOOK default_hook = { KEY_TREE_ROOT, &regdb_ops };
/**********************************************************************
Initialize the cache tree
Initialize the cache tree if it has not been initialized yet.
*********************************************************************/
bool reghook_cache_init( void )
{
cache_tree = pathtree_init( &default_hook, NULL );
if (cache_tree == NULL) {
cache_tree = pathtree_init(&default_hook, NULL);
}
return ( cache_tree == NULL );
return (cache_tree != NULL);
}
/**********************************************************************

View File

@ -259,7 +259,7 @@ bool regdb_init( void )
uint32 vers_id;
if ( tdb_reg )
return True;
return true;
if ( !(tdb_reg = tdb_wrap_open(NULL, state_path("registry.tdb"), 0, REG_TDB_FLAGS, O_RDWR, 0600)) )
{
@ -267,7 +267,7 @@ bool regdb_init( void )
if ( !tdb_reg ) {
DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n",
state_path("registry.tdb"), strerror(errno) ));
return False;
return false;
}
DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
@ -286,11 +286,11 @@ bool regdb_init( void )
/* always setup the necessary keys and values */
if ( !init_registry_data() ) {
DEBUG(0,("init_registry: Failed to initialize data in registry!\n"));
return False;
DEBUG(0,("regdb_init: Failed to initialize data in registry!\n"));
return false;
}
return True;
return true;
}
/***********************************************************************
@ -329,6 +329,10 @@ WERROR regdb_open( void )
int regdb_close( void )
{
if (tdb_refcount == 0) {
return 0;
}
tdb_refcount--;
DEBUG(10,("regdb_close: decrementing refcount (%d)\n", tdb_refcount));
@ -364,7 +368,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
uint8 *buffer = NULL;
int i = 0;
uint32 len, buflen;
bool ret = True;
bool ret = true;
uint32 num_subkeys = regsubkey_ctr_numkeys(ctr);
char *keyname = NULL;
TALLOC_CTX *ctx = talloc_tos();
@ -382,7 +386,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
/* allocate some initial memory */
if (!(buffer = (uint8 *)SMB_MALLOC(1024))) {
return False;
return false;
}
buflen = 1024;
len = 0;
@ -399,7 +403,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
/* allocate some extra space */
if ((buffer = (uint8 *)SMB_REALLOC( buffer, len*2 )) == NULL) {
DEBUG(0,("regdb_store_keys: Failed to realloc memory of size [%d]\n", len*2));
ret = False;
ret = false;
goto done;
}
buflen = len*2;
@ -413,7 +417,7 @@ static bool regdb_store_keys_internal(const char *key, REGSUBKEY_CTR *ctr)
dbuf.dptr = buffer;
dbuf.dsize = len;
if ( tdb_store_bystring( tdb_reg->tdb, keyname, dbuf, TDB_REPLACE ) == -1) {
ret = False;
ret = false;
goto done;
}
@ -801,7 +805,7 @@ bool regdb_store_values( const char *key, REGVAL_CTR *values )
&& (memcmp(old_data.dptr, data.dptr, data.dsize) == 0)) {
SAFE_FREE(old_data.dptr);
SAFE_FREE(data.dptr);
return True;
return true;
}
ret = tdb_trans_store_bystring(tdb_reg->tdb, keystr, data, TDB_REPLACE);

View File

@ -1554,7 +1554,7 @@ static uint32 sk_record_data_size( SEC_DESC * sd )
/* the record size is sizeof(hdr) + name + static members + data_size_field */
size = sizeof(uint32)*5 + sec_desc_size( sd ) + sizeof(uint32);
size = sizeof(uint32)*5 + ndr_size_security_descriptor(sd, 0) + sizeof(uint32);
/* multiple of 8 */
size_mod8 = size & 0xfffffff8;
@ -1784,7 +1784,8 @@ static int hashrec_cmp( REGF_HASH_REC *h1, REGF_HASH_REC *h2 )
nk->sec_desc->ref_count = 0;
/* size value must be self-inclusive */
nk->sec_desc->size = sec_desc_size(sec_desc) + sizeof(uint32);
nk->sec_desc->size = ndr_size_security_descriptor(sec_desc, 0)
+ sizeof(uint32);
DLIST_ADD_END( file->sec_desc_list, nk->sec_desc, REGF_SK_REC *);

View File

@ -978,11 +978,12 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
int validation_level = 3;
const char *workstation_name_slash;
const char *server_name_slash;
static uint8 zeros[16];
uint8 zeros[16];
DOM_CRED clnt_creds;
DOM_CRED ret_creds;
int i;
ZERO_STRUCT(zeros);
ZERO_STRUCT(q);
ZERO_STRUCT(r);
ZERO_STRUCT(ret_creds);
@ -1084,9 +1085,10 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
int validation_level = 3;
const char *workstation_name_slash;
const char *server_name_slash;
static uint8 zeros[16];
uint8 zeros[16];
int i;
ZERO_STRUCT(zeros);
ZERO_STRUCT(q);
ZERO_STRUCT(r);

View File

@ -435,7 +435,7 @@ bool smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC
}
if (*secdesc != NULL) {
buffer->string_at_end -= sec_desc_size(*secdesc);
buffer->string_at_end -= ndr_size_security_descriptor(*secdesc, 0);
if(!prs_set_offset(ps, buffer->string_at_end))
return False;

View File

@ -1544,9 +1544,11 @@ static void schannel_digest(struct schannel_auth_struct *a,
uchar digest_final[16])
{
uchar whole_packet_digest[16];
static const uchar zeros[4] = { 0, };
uchar zeros[4];
struct MD5Context ctx3;
ZERO_STRUCT(zeros);
/* verfiy the signature on the packet by MD5 over various bits */
MD5Init(&ctx3);
/* use our sequence number, which ensures the packet is not
@ -1573,11 +1575,13 @@ static void schannel_get_sealing_key(struct schannel_auth_struct *a,
RPC_AUTH_SCHANNEL_CHK *verf,
uchar sealing_key[16])
{
static const uchar zeros[4] = { 0, };
uchar zeros[4];
uchar digest2[16];
uchar sess_kf0[16];
int i;
ZERO_STRUCT(zeros);
for (i = 0; i < sizeof(sess_kf0); i++) {
sess_kf0[i] = a->sess_key[i] ^ 0xf0;
}
@ -1600,10 +1604,12 @@ static void schannel_get_sealing_key(struct schannel_auth_struct *a,
static void schannel_deal_with_seq_num(struct schannel_auth_struct *a,
RPC_AUTH_SCHANNEL_CHK *verf)
{
static const uchar zeros[4] = { 0, };
uchar zeros[4];
uchar sequence_key[16];
uchar digest1[16];
ZERO_STRUCT(zeros);
hmac_md5(a->sess_key, zeros, sizeof(zeros), digest1);
dump_data_pw("(sequence key) digest1:\n", digest1, sizeof(digest1));

View File

@ -291,14 +291,14 @@ bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
if (psd->owner_sid != NULL) {
off_owner_sid = offset;
offset += sid_size(psd->owner_sid);
offset += ndr_size_dom_sid(psd->owner_sid, 0);
} else {
off_owner_sid = 0;
}
if (psd->group_sid != NULL) {
off_grp_sid = offset;
offset += sid_size(psd->group_sid);
offset += ndr_size_dom_sid(psd->group_sid, 0);
} else {
off_grp_sid = 0;
}
@ -426,7 +426,7 @@ bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int
if(!prs_uint32 ("ptr ", ps, depth, &ptr))
return False;
len = sec_desc_size(psdb->sd);
len = ndr_size_security_descriptor(psdb->sd, 0);
if(!prs_uint32_pre("len ", ps, depth, &len, &off_len))
return False;

View File

@ -3098,7 +3098,7 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
size += 4;
size += sec_desc_size( info->secdesc );
size += ndr_size_security_descriptor( info->secdesc, 0 );
size+=size_of_device_mode( info->devmode );
@ -3185,7 +3185,7 @@ return the size required by a struct in the stream
uint32 spoolss_size_printer_info_3(PRINTER_INFO_3 *info)
{
/* The 8 is for the self relative pointer - 8 byte aligned.. */
return 8 + (uint32)sec_desc_size( info->secdesc );
return 8 + (uint32)ndr_size_security_descriptor( info->secdesc, 0 );
}
/*******************************************************************

View File

@ -507,7 +507,8 @@ static bool srv_io_share_info502_str(const char *desc, SH_INFO_502_STR *sh502, p
if(UNMARSHALLING(ps)) {
sh502->ptrs->sd_size = sh502->sd_size = sec_desc_size(sh502->sd);
sh502->ptrs->sd_size = sh502->sd_size =
ndr_size_security_descriptor(sh502->sd, 0);
prs_set_offset(ps, old_offset + sh502->reserved);
}
@ -1460,7 +1461,7 @@ void init_srv_q_net_share_add(SRV_Q_NET_SHARE_ADD *q, const char *srvname,
{
switch(level) {
case 502: {
size_t sd_size = sec_desc_size(sd);
size_t sd_size = ndr_size_security_descriptor(sd, 0);
q->ptr_srv_name = 1;
init_unistr2(&q->uni_srv_name, srvname, UNI_STR_TERMINATE);
q->info.switch_value = q->info_level = level;

View File

@ -870,13 +870,11 @@ static void init_srv_sess_info_0(pipes_struct *p, SRV_SESS_INFO_0 *ss0, uint32 *
/*******************************************************************
********************************************************************/
/* global needed to make use of the share_mode_forall() callback */
static struct sess_file_count s_file_cnt;
static void sess_file_fn( const struct share_mode_entry *e,
const char *sharepath, const char *fname, void *state )
const char *sharepath, const char *fname,
void *data )
{
struct sess_file_count *sess = &s_file_cnt;
struct sess_file_count *sess = (struct sess_file_count *)data;
if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) {
sess->count++;
@ -890,11 +888,13 @@ static void sess_file_fn( const struct share_mode_entry *e,
static int net_count_files( uid_t uid, struct server_id pid )
{
struct sess_file_count s_file_cnt;
s_file_cnt.count = 0;
s_file_cnt.uid = uid;
s_file_cnt.pid = pid;
share_mode_forall( sess_file_fn, NULL );
share_mode_forall( sess_file_fn, &s_file_cnt );
return s_file_cnt.count;
}
@ -2159,7 +2159,7 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC
goto error_exit;
}
sd_size = sec_desc_size(psd);
sd_size = ndr_size_security_descriptor(psd, 0);
r_u->ptr_response = 1;
r_u->size_response = sd_size;

View File

@ -813,7 +813,7 @@ WERROR _svcctl_query_service_sec( pipes_struct *p, SVCCTL_Q_QUERY_SERVICE_SEC *q
if ( !(sec_desc = svcctl_get_secdesc( p->mem_ctx, info->name, get_root_nt_token() )) )
return WERR_NOMEM;
r_u->needed = sec_desc_size( sec_desc );
r_u->needed = ndr_size_security_descriptor( sec_desc, 0 );
if ( r_u->needed > q_u->buffer_size ) {
ZERO_STRUCTP( &r_u->buffer );

View File

@ -850,6 +850,18 @@ out_free:
goto done;
}
if (get_cmdline_auth_info_smb_encrypt()) {
nt_status = cli_cm_force_encryption(cli,
get_cmdline_auth_info_username(),
get_cmdline_auth_info_password(),
lp_workgroup(),
"IPC$");
if (!NT_STATUS_IS_OK(nt_status)) {
result = 1;
goto done;
}
}
#if 0 /* COMMENT OUT FOR TESTING */
memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
#endif

View File

@ -62,7 +62,6 @@ export PATH SOCKET_WRAPPER_DIR DOMAIN
export PRIVATEDIR LIBDIR PIDDIR LOCKDIR LOGDIR SERVERCONFFILE
export SRCDIR SCRIPTDIR BINDIR
export USERNAME PASSWORD
export SMBTORTURE4
export WORKGROUP SERVER SERVER_IP
export NSS_WRAPPER_PASSWD NSS_WRAPPER_GROUP
export WINBINDD_SOCKET_DIR WINBINDD_PRIV_PIPE_DIR
@ -70,10 +69,20 @@ export WINBINDD_SOCKET_DIR WINBINDD_PRIV_PIPE_DIR
PATH=bin:$PATH
export PATH
LD_LIBRARY_PATH="$LD_LIBRARY_PATH":"$BINDIR"
if test x"$LD_LIBRARY_PATH" != x""; then
LD_LIBRARY_PATH="$BINDIR:$LD_LIBRARY_PATH"
else
LD_LIBRARY_PATH="$BINDIR"
fi
echo "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
SAMBA4BINDIR=`dirname $SMBTORTURE4`
SAMBA4SHAREDDIR="$SAMBA4BINDIR/shared"
export SAMBA4SHAREDDIR
export SMBTORTURE4
##
## verify that we were built with --enable-socket-wrapper
##

View File

@ -2,7 +2,7 @@
# this runs the file serving tests that are expected to pass with samba3
if [ $# != 2 ]; then
if [ $# -lt 2 ]; then
cat <<EOF
Usage: test_smbclient_s3.sh SERVER SERVER_IP
EOF
@ -12,6 +12,8 @@ fi
SERVER="$1"
SERVER_IP="$2"
SMBCLIENT="$VALGRIND ${SMBCLIENT:-$BINDIR/smbclient} $CONFIGURATION"
shift 2
ADDARGS="$*"
incdir=`dirname $0`
. $incdir/test_functions.sh
@ -24,7 +26,7 @@ test_noninteractive_no_prompt()
prompt="smb"
echo du | \
$SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp 2>&1 | \
$SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I SERVER_IP $ADDARGS 2>&1 | \
grep $prompt
if [ $? = 0 ] ; then
@ -48,8 +50,8 @@ quit
EOF
CLI_FORCE_INTERACTIVE=yes \
$SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp \
< $tmpfile 2>/dev/null | \
$SMBCLIENT $CONFIGURATION "$@" -U$USERNAME%$PASSWORD //$SERVER/tmp -I $SERVER_IP \
$ADDARGS < $tmpfile 2>/dev/null | \
grep $prompt
if [ $? = 0 ] ; then
@ -64,7 +66,7 @@ EOF
}
testit "smbclient -L $SERVER_IP" $SMBCLIENT $CONFIGURATION -L $SERVER_IP -N -p 139 || failed=`expr $failed + 1`
testit "smbclient -L $SERVER" $SMBCLIENT $CONFIGURATION -L $SERVER -N -p 139 || failed=`expr $failed + 1`
testit "smbclient -L $SERVER -I $SERVER_IP" $SMBCLIENT $CONFIGURATION -L $SERVER -I $SERVER_IP -N -p 139 || failed=`expr $failed + 1`
testit "noninteractive smbclient does not prompt" \
test_noninteractive_no_prompt || \

Some files were not shown because too many files have changed in this diff Show More