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:
commit
aaa2770666
1
.gitignore
vendored
1
.gitignore
vendored
@ -34,3 +34,4 @@ source/proto_exists
|
||||
source/winbindd/winbindd_proto.h
|
||||
source/cscope.out
|
||||
source/torture.tdb
|
||||
source/pkgconfig/*.pc
|
||||
|
@ -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) "
|
||||
|
@ -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 */
|
||||
|
@ -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 {
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) )
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -49,6 +49,7 @@ struct user_auth_info {
|
||||
bool got_pass;
|
||||
bool use_kerberos;
|
||||
int signing_state;
|
||||
bool smb_encrypt;
|
||||
};
|
||||
|
||||
#endif /* _POPT_COMMON_H */
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -51,4 +51,3 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
|
||||
{
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -84,6 +84,7 @@
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
#define SOCKET_WRAPPER_NOT_REPLACE
|
||||
#include "interfaces.h"
|
||||
#include "lib/replace/replace.h"
|
||||
|
||||
|
@ -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:
|
||||
|
BIN
source3/lib/netapi/examples/netdomjoin-gui/logo-small.png
Normal file
BIN
source3/lib/netapi/examples/netdomjoin-gui/logo-small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(¶m_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,
|
||||
¶m_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, ¶m_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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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" },
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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
497
source3/libsmb/smb_seal.c
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -177,7 +177,7 @@ wbcErr wbcDomainSequenceNumbers(void);
|
||||
* Athenticate functions
|
||||
*/
|
||||
|
||||
wbcErr wbcAuthenticateUser(const char *username,
|
||||
wbcErr wbcAuthenticateUser(const char *username,
|
||||
const char *password);
|
||||
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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, ®db_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);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -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);
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
##
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user