summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-12-02 14:18:11 +0000
committerGerald Carter <jerry@samba.org>2005-12-02 14:18:11 +0000
commitb3651817a4da8c53128cfd07188e809e65d459d4 (patch)
tree09e39fb2dfc6c84f5e13685db9b8b07c49d695c8
parent6c43e50ecd10fb085b4c3dbb83560c759980f917 (diff)
downloadsamba-b3651817a4da8c53128cfd07188e809e65d459d4.tar.gz
samba-b3651817a4da8c53128cfd07188e809e65d459d4.tar.xz
samba-b3651817a4da8c53128cfd07188e809e65d459d4.zip
r12018: more 3.0.21 changes. This is a full sync except for changes to rpc-server/rpc_samr*.c
-rw-r--r--examples/logon/mklogon/mklogon.conf75
-rw-r--r--examples/logon/mklogon/mklogon.pl50
-rw-r--r--examples/perfcounter/perf_writer_util.c6
-rw-r--r--source/Makefile.in4
-rw-r--r--source/auth/auth_rhosts.c30
-rw-r--r--source/auth/auth_util.c30
-rw-r--r--source/client/client.c13
-rwxr-xr-xsource/client/mount.cifs.c164
-rw-r--r--source/client/smbspool.c15
-rw-r--r--source/include/passdb.h15
-rw-r--r--source/include/rpc_dce.h30
-rw-r--r--source/include/rpc_netlogon.h49
-rw-r--r--source/include/rpc_samr.h87
-rw-r--r--source/include/talloc.h38
-rw-r--r--source/lib/talloc.c295
-rw-r--r--source/lib/tallocmsg.c15
-rw-r--r--source/lib/util_unistr.c28
-rw-r--r--source/libsmb/cliconnect.c1
-rw-r--r--source/libsmb/clientgen.c34
-rw-r--r--source/nsswitch/wbinfo.c21
-rw-r--r--source/param/loadparm.c4
-rw-r--r--source/passdb/lookup_sid.c55
-rw-r--r--source/passdb/passdb.c75
-rw-r--r--source/passdb/pdb_interface.c73
-rw-r--r--source/passdb/pdb_ldap.c43
-rw-r--r--source/passdb/util_sam_sid.c25
-rw-r--r--source/printing/print_svid.c29
-rw-r--r--source/registry/reg_eventlog.c8
-rw-r--r--source/registry/reg_printing.c11
-rw-r--r--source/rpc_client/cli_netlogon.c164
-rw-r--r--source/rpc_client/cli_samr.c99
-rw-r--r--source/rpc_parse/parse_lsa.c42
-rw-r--r--source/rpc_parse/parse_net.c308
-rw-r--r--source/rpc_parse/parse_samr.c294
-rw-r--r--source/rpc_server/srv_netlog_nt.c29
-rw-r--r--source/rpc_server/srv_pipe.c49
-rw-r--r--source/rpc_server/srv_pipe_hnd.c81
-rw-r--r--source/rpc_server/srv_samr_nt.c141
-rw-r--r--source/rpc_server/srv_spoolss_nt.c30
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c5
-rw-r--r--source/rpc_server/srv_util.c29
-rw-r--r--source/rpcclient/cmd_lsarpc.c16
-rw-r--r--source/rpcclient/cmd_netlogon.c56
-rw-r--r--source/rpcclient/cmd_samr.c107
-rw-r--r--source/smbd/dosmode.c7
-rw-r--r--source/smbd/filename.c13
-rw-r--r--source/utils/smbcontrol.c4
-rw-r--r--source/utils/testparm.c5
48 files changed, 2322 insertions, 480 deletions
diff --git a/examples/logon/mklogon/mklogon.conf b/examples/logon/mklogon/mklogon.conf
index 1f1faa77e38..b04708977c4 100644
--- a/examples/logon/mklogon/mklogon.conf
+++ b/examples/logon/mklogon/mklogon.conf
@@ -6,72 +6,73 @@
# infront of your # on a comment it breaks ...
# logging = yes # Should Logging be enabled (YES,ON,1 or NO,OFF,0)(if not specified defaults to no)
# logdir = "/root/perl" # What is the base directory the logs should be stored.
-# logfile = "userlogs.txt" # What should the file be named.
-# logtype = file (default) # file will log to the file specified, syslog is well... the system logs ;)
+# logfile = "userlist.txt" # What should the file be named.
+# VERY IMPORTANT anything that has a "\" (backslash) in it ex. "C:\" MUST be changed to a double "\\" for
+# it to be used in the script. ex. "C:\\"
[global]
logging = yes
logdir = "/home/samba/netlogon"
logfile = "UserLogs.txt"
-logtype = system
mkprofile = 1
timesync = yes
sambaconf = "/etc/samba/smb.conf"
+logtype = file
# Change and uncomment the below value to force the servername, some clients ocassionally
# have trouble picking up the right servername so it may need to be set. It CANNOT be left blank AND uncommented.
-# servername = staticservername
+servername = "TIGER"
[common]
public = P:, public
home = H:, /home
[groupmap]
-admin = Y:, UTILS
-adm = R:, NETLOGON
+adm = R:, NETLOGON, Y:, ARCHIVES
+teachers = S:, RECORDS, X:, SIS
+plato = T:, PLATO
+webpage = W:, WEB
+hsoffice = N:, HSOFFICE, Q:, COMMON, X:, SIS
+suoffice = N:, super, Q:, COMMON, X:, SIS
+emoffice = N:, emOFFICE, Q:, COMMON, X:, SIS
+tech = O:, utils
+yearbook = Y:, yearbook
[usermap]
-user1 = G:, GHOST
-beanbags = Q:, STAR
-avinst = P:\\vexira\\vexprof.bat
+rnance = G:, GHOST, I:, TTL, Y:, ARCHIVES, R:, NETLOGON, X:, SIS
+lwatts = G:, GHOST, I:, TTL, Y:, ARCHIVES, R:, NETLOGON, X:, SIS
+droot = U:, stuhomes
+2007mbk = Y:, yearbook
+2008mll = Y:, yearbook
+2008jtj = Y:, yearbook
+2007tja = Y:, yearbook
+2007hms = Y:, yearbook
+2006dpv = Y:, yearbook
+2006jwb2 = Y:, yearbook
+2007npd = Y:, yearbook
+astewart = Y:, yearbook
+
+
# Here is where things get confusing, you can assign a computer, or make a group of computers.
-# The same context will go for ip address's as well.
+# The same context will go for ip address's as well, however you can also specify ip ranges,
+# but I have not yet figured out how to do multiple ranges.
# Use the following examples for help.
# To define a single computer to do commands
# mymachinename = command1, command2
# To define a group of computers to do commands
# mymachinegroup = machinename1, machinename2
-# [preformcommands]
+# [performcommands]
# mymachinegroup = command1,command2
+# iprangegroup1 = 10.1.2.1 - 10.1.3.1
-[machines]
-#emints 1 is jf
-emints1 = school-w88zfod9, school-o8axvv6t, school-mmtudgbo, school-dpokmajd, school-m84hx4iw, school-74548k1j, school-vou4gdap, school-qfuw5uho
-#emints 2 is kh
-emints2 = school-w7loulcx, school-2tbh64eu, school-uunqieuz, school-pow35do4, school-x0v0cbiz, school-zu5qyjhw, school-l4q4j32o
-[ip]
-ipgroup1 = 10.5.1.1 - 10.5.1.10, 10.1.1.255/24
-ipgroup2 = 10.1.1.1
-# This is the section where you can specify things according to the operating system of the client.
-# The clients OS -- Windows 95/98/ME (Win95), Windows NT (WinNT),
-# Windows 2000 (Win2K), Windows XP (WinXP), and Windows 2003
-# (Win2K3). Anything else will be known as ``UNKNOWN''
-# That snippet is directly from man smb.conf.
-#
+[machines]
-[os]
-Win95 = REM your computer is windows 9x based
-WinNT =
-Win2K =
-WinXP =
-Win2K3 =
-UNKNOWN =
+[ip]
+sixthemints = 10.1.5.201 - 10.1.5.215
-[preformcommands]
-emints1 = START \\\\JF-TEACHER\\Brother, START \\\\JF-TEACHER\\Canon, REGEDIT /S P:\\SETHOME-JF.REG, your in emints 1
-emints2 = START \\\\s0034292474\\Brother, START \\\\s0034292474\\Canon, REGEDIT /S P:\\SETHOME-KH.REG
-ipgroup1 = echo your in the ip group
-ipgroup2 = echo your in the ip group 2, start command.com
+[performcommands]
+common = "XCOPY P:\\TYPEN32.INI C:\\WINDOWS\\ /Y \>NUL", "XCOPY P:\\ARPROGRAMS\\DBLOCATION\\\*\.\* C:\\WINDOWS\\ /Y \>NUL", "XCOPY P:\\EMACTIVITIES\\EMGAMESPREFS.INI C:\\WINDOWS\\ /Y \>NUL", "PATH\=\%PATH\%;p:\\PXPerl\parrot\\bin;p:\\PXPerl\\bin"
+sixthemints = "start \\\\10.1.5.20\\printer"
diff --git a/examples/logon/mklogon/mklogon.pl b/examples/logon/mklogon/mklogon.pl
index 88ee97c9799..8bea7b22d36 100644
--- a/examples/logon/mklogon/mklogon.pl
+++ b/examples/logon/mklogon/mklogon.pl
@@ -22,8 +22,8 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
-# Version: 1.1 Beta
-# Revised: 06/28/2005
+# Version: 1.0 (Stable)
+# Revised: 07/28/2005
# Comments...
# Working on logging to the system logs, Logs user activity, but not errors yet.
@@ -144,11 +144,11 @@ if ( defined($smbprof) ) {
print "$smbprof \n";
print "$dir2 \n";
if ( !-e $dir2 ) {
- print "Creating " . $user . "'s profile \n";
+ print "Creating " . $user . "'s profile with a uid of $uid\n";
mkdir $smbprof;
mkdir $dir2;
chomp($user);
- chown $uid, $gid, $smbprof;
+# chown $uid, $gid, $smbprof;
chown $uid, $gid, $dir2;
} else {
print $user . "'s profile already exists \n";
@@ -174,6 +174,13 @@ for my $key ( keys %$common ) {
drive_map( @{ $common->{$key} } );
}
+my @perform_common = $cfg->param("performcommands.common");
+if ( defined( $perform_common[0] ) ) {
+ foreach (@perform_common) {
+ print LOGON "$_ \r\n";
+ }
+}
+
# Map shares on a per user basis.
drive_map(@username);
@@ -195,30 +202,33 @@ for my $key ( keys %$compname ) {
if ( ref $test eq 'ARRAY' ) {
foreach (@$test) {
if ( $_ eq $machine ) {
- my $preformit = $cfg->param("preformcommands.$key");
- if ( defined($preformit) ) {
- if ( ref $preformit ) {
- foreach (@$preformit) { print LOGON "$_ \r\n"; }
+ my $performit = $cfg->param("performcommands.$key");
+ if ( defined($performit) ) {
+ if ( ref $performit ) {
+ foreach (@$performit) { print LOGON "$_ \r\n"; }
} else {
- print LOGON "$preformit \r\n";
+ print LOGON "$performit \r\n";
}
}
}
}
}
elsif ( $test eq $machine ) {
- my $preformit = $cfg->param("preformcommands.$key");
- if ( defined($preformit) ) {
- if ( ref $preformit ) {
- foreach (@$preformit) { print LOGON "$_ \r\n"; }
+ my $performit = $cfg->param("performcommands.$key");
+ if ( defined($performit) ) {
+ if ( ref $performit ) {
+ foreach (@$performit) { print LOGON "$_ \r\n"; }
} else {
- print LOGON "$preformit \r\n";
+ print LOGON "$performit \r\n";
}
}
}
}
# Here is where we test the ip address against the client to see if they have "Special Mapping"
+# A huge portion of the ip matching code was made by
+# Carsten Schaub (rcsu in the #samba chan on freenode.net)
+
my $val;
for my $key ( sort keys %$ipname ) {
if ( ref $ipname->{$key} eq 'ARRAY' ) {
@@ -234,12 +244,12 @@ sub getipval {
my ( $range, $rangename ) = @_;
if ( parse( $ip, ipmap($range) ) ) {
if ( $val eq 'true' ) {
- my $preformit = $cfg->param("preformcommands.$rangename");
- if ( defined($preformit) ) {
- if ( ref $preformit ) {
- foreach (@$preformit) { print LOGON "$_ \r\n"; }
+ my $performit = $cfg->param("performcommands.$rangename");
+ if ( defined($performit) ) {
+ if ( ref $performit ) {
+ foreach (@$performit) { print LOGON "$_ \r\n"; }
} else {
- print LOGON "$preformit \r\n";
+ print LOGON "$performit \r\n";
}
}
} elsif ( $val eq 'false' ) {
@@ -307,7 +317,7 @@ sub drive_map {
my $sharename = $data[$i];
$i++;
if ( $sharename eq '/home' ) {
- print LOGON uc("NET USE $driveletter $sharename \/Y \r\n");
+ print LOGON uc("NET USE $driveletter \\\\$server\\$user \/Y \r\n");
} else {
print LOGON
uc("NET USE $driveletter \\\\$server\\$sharename \/Y \r\n");
diff --git a/examples/perfcounter/perf_writer_util.c b/examples/perfcounter/perf_writer_util.c
index bb6422bac23..78a99fef494 100644
--- a/examples/perfcounter/perf_writer_util.c
+++ b/examples/perfcounter/perf_writer_util.c
@@ -77,7 +77,7 @@ void usage(char *progname)
fprintf(stderr, "Usage: %s [-d] [-f <file_path>].\n", progname);
fprintf(stderr, "\t-d: run as a daemon.\n");
fprintf(stderr, "\t-f <file_path>: path where the TDB files reside.\n");
- fprintf(stderr, "\t\tDEFAULT is /tmp/counters\n");
+ fprintf(stderr, "\t\tDEFAULT is /var/lib/samba/perfmon\n");
exit(1);
}
@@ -116,13 +116,13 @@ void setup_file_paths(RuntimeSettings *rt)
if(strlen(rt->dbDir) == 0)
{
/* No file path was passed in, use default */
- sprintf(rt->dbDir, "/tmp/counters");
+ sprintf(rt->dbDir, "/var/lib/samba/perfmon");
}
sprintf(rt->nameFile, "%s/names.tdb", rt->dbDir);
sprintf(rt->counterFile, "%s/data.tdb", rt->dbDir);
- mkdir(rt->dbDir, O_RDWR);
+ mkdir(rt->dbDir, 0755);
rt->cnames = tdb_open(rt->nameFile, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644);
rt->cdata = tdb_open(rt->counterFile, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644);
diff --git a/source/Makefile.in b/source/Makefile.in
index cca0715a3aa..888a0ebe344 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -106,7 +106,7 @@ LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@
LIBSMBSHAREMODES_MAJOR=0
LIBSMBSHAREMODES_MINOR=1
-FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/tdb @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir)
+FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/tdb @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) -D_SAMBA_BUILD_
FLAGS2 =
FLAGS3 =
FLAGS4 =
@@ -298,7 +298,7 @@ RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o
RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog.o rpc_server/srv_eventlog_nt.o rpc_server/srv_eventlog_lib.o
-RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o rpc_server/srv_util.o \
+RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o \
rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o
RPC_ECHO_OBJ = rpc_server/srv_echo.o rpc_server/srv_echo_nt.o
diff --git a/source/auth/auth_rhosts.c b/source/auth/auth_rhosts.c
index b295df9328f..b561e3d42be 100644
--- a/source/auth/auth_rhosts.c
+++ b/source/auth/auth_rhosts.c
@@ -24,6 +24,36 @@
#define DBGC_CLASS DBGC_AUTH
/****************************************************************************
+ Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from
+ unix info.
+****************************************************************************/
+
+static NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account)
+{
+ BOOL pdb_ret;
+ NTSTATUS nt_status;
+ if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) {
+ return nt_status;
+ }
+
+ become_root();
+ pdb_ret = pdb_getsampwnam(*account, user);
+ unbecome_root();
+
+ if (!pdb_ret) {
+
+ struct passwd *pass = Get_Pwnam(user);
+ if (!pass)
+ return NT_STATUS_NO_SUCH_USER;
+
+ if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) {
+ return nt_status;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
Read the a hosts.equiv or .rhosts file and check if it
allows this user from this machine.
****************************************************************************/
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index 6a92c8782e8..61cb7f31cc7 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -51,36 +51,6 @@ static int smb_create_user(const char *domain, const char *unix_username, const
}
/****************************************************************************
- Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from
- unix info.
-****************************************************************************/
-
-NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account)
-{
- BOOL pdb_ret;
- NTSTATUS nt_status;
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) {
- return nt_status;
- }
-
- become_root();
- pdb_ret = pdb_getsampwnam(*account, user);
- unbecome_root();
-
- if (!pdb_ret) {
-
- struct passwd *pass = Get_Pwnam(user);
- if (!pass)
- return NT_STATUS_NO_SUCH_USER;
-
- if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) {
- return nt_status;
- }
- }
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
Create an auth_usersupplied_data structure
****************************************************************************/
diff --git a/source/client/client.c b/source/client/client.c
index 47a45b8a53b..f95bbea6718 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -3084,11 +3084,20 @@ static void readline_callback(void)
session keepalives and then drop them here.
*/
if (FD_ISSET(cli->fd,&fds)) {
- receive_smb(cli->fd,cli->inbuf,0);
+ if (!receive_smb(cli->fd,cli->inbuf,0)) {
+ DEBUG(0, ("Read from server failed, maybe it closed the "
+ "connection\n"));
+ return;
+ }
goto again;
}
- cli_chkpath(cli, "\\");
+ /* Ping the server to keep the connection alive using SMBecho. */
+ {
+ unsigned char garbage[16];
+ memset(garbage, 0xf0, sizeof(garbage));
+ cli_echo(cli, garbage, sizeof(garbage));
+ }
}
/****************************************************************************
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
index 5750deb31ca..ed88c92c626 100755
--- a/source/client/mount.cifs.c
+++ b/source/client/mount.cifs.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
+#include <grp.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/mount.h>
@@ -39,7 +40,7 @@
#include <fcntl.h>
#define MOUNT_CIFS_VERSION_MAJOR "1"
-#define MOUNT_CIFS_VERSION_MINOR "8"
+#define MOUNT_CIFS_VERSION_MINOR "10"
#ifndef MOUNT_CIFS_VENDOR_SUFFIX
#define MOUNT_CIFS_VENDOR_SUFFIX ""
@@ -83,11 +84,16 @@ static void mount_cifs_usage(void)
printf(" to a local directory.\n\nOptions:\n");
printf("\tuser=<arg>\n\tpass=<arg>\n\tdom=<arg>\n");
printf("\nLess commonly used options:");
- printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,rw,ro,\n\tsep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec,serverino,\n\tdirectio,mapchars,nomapchars");
- printf("\n\nOptions not needed for servers supporting CIFS Unix extensions\n\t(e.g. most Samba versions):");
- printf("\n\tuid=<uid>,gid=<gid>,dir_mode=<mode>,file_mode=<mode>");
+ printf("\n\tcredentials=<filename>,guest,perm,noperm,setuids,nosetuids,rw,ro,");
+ printf("\n\tsep=<char>,iocharset=<codepage>,suid,nosuid,exec,noexec,serverino,");
+ printf("\n\tdirectio,mapchars,nomapchars,nolock,servernetbiosname=<SRV_RFC1001NAME>");
+ printf("\n\nOptions not needed for servers supporting CIFS Unix extensions");
+ printf("\n\t(e.g. unneeded for mounts to most Samba versions):");
+ printf("\n\tuid=<uid>,gid=<gid>,dir_mode=<mode>,file_mode=<mode>,sfu");
printf("\n\nRarely used options:");
- printf("\n\tport=<tcpport>,rsize=<size>,wsize=<size>,unc=<unc_name>,ip=<ip_address>,\n\tdev,nodev,nouser_xattr,netbiosname,hard,soft,intr,nointr,noacl");
+ printf("\n\tport=<tcpport>,rsize=<size>,wsize=<size>,unc=<unc_name>,ip=<ip_address>,");
+ printf("\n\tdev,nodev,nouser_xattr,netbiosname=<OUR_RFC1001NAME>,hard,soft,intr,");
+ printf("\n\tnointr,ignorecase,noposixpaths,noacl");
printf("\n\nOptions are described in more detail in the manual page");
printf("\n\tman 8 mount.cifs\n");
printf("\nTo display the version number of the mount helper:");
@@ -127,8 +133,10 @@ static int open_cred_file(char * file_name)
if(fs == NULL)
return errno;
line_buf = malloc(4096);
- if(line_buf == NULL)
+ if(line_buf == NULL) {
+ fclose(fs);
return -ENOMEM;
+ }
while(fgets(line_buf,4096,fs)) {
/* parse line from credential file */
@@ -282,21 +290,23 @@ static int get_password_from_file(int file_descript, char * filename)
return rc;
}
-static int parse_options(char * options, int * filesys_flags)
+static int parse_options(char ** optionsp, int * filesys_flags)
{
char * data;
char * percent_char = NULL;
char * value = NULL;
char * next_keyword = NULL;
+ char * out = NULL;
+ int out_len = 0;
+ int word_len;
int rc = 0;
- if (!options)
+ if (!optionsp || !*optionsp)
return 1;
- else
- data = options;
+ data = *optionsp;
if(verboseflag)
- printf("parsing options: %s\n", options);
+ printf("parsing options: %s\n", data);
/* BB fixme check for separator override BB */
@@ -314,7 +324,7 @@ static int parse_options(char * options, int * filesys_flags)
/* temporarily null terminate end of keyword=value pair */
if(next_keyword)
- *next_keyword = 0;
+ *next_keyword++ = 0;
/* temporarily null terminate keyword to make keyword and value distinct */
if ((value = strchr(data, '=')) != NULL) {
@@ -324,7 +334,7 @@ static int parse_options(char * options, int * filesys_flags)
if (strncmp(data, "users",5) == 0) {
if(!value || !*value) {
- strncpy(data,",,,,,",5);
+ goto nocopy;
}
} else if (strncmp(data, "user_xattr",10) == 0) {
/* do nothing - need to skip so not parsed as user name */
@@ -336,10 +346,7 @@ static int parse_options(char * options, int * filesys_flags)
printf("\nskipping empty user mount parameter\n");
/* remove the parm since it would otherwise be confusing
to the kernel code which would think it was a real username */
- data[0] = ',';
- data[1] = ',';
- data[2] = ',';
- data[3] = ',';
+ goto nocopy;
} else {
printf("username specified with no parameter\n");
return 1; /* needs_arg; */
@@ -458,10 +465,34 @@ static int parse_options(char * options, int * filesys_flags)
} else if (strncmp(data, "uid", 3) == 0) {
if (value && *value) {
got_uid = 1;
+ if (!isdigit(*value)) {
+ struct passwd *pw;
+ static char temp[32];
+
+ if (!(pw = getpwnam(value))) {
+ printf("bad user name \"%s\"\n", value);
+ exit(1);
+ }
+ sprintf(temp, "%u", pw->pw_uid);
+ value = temp;
+ endpwent();
+ }
}
} else if (strncmp(data, "gid", 3) == 0) {
if (value && *value) {
got_gid = 1;
+ if (!isdigit(*value)) {
+ struct group *gr;
+ static char temp[32];
+
+ if (!(gr = getgrnam(value))) {
+ printf("bad group name \"%s\"\n", value);
+ exit(1);
+ }
+ sprintf(temp, "%u", gr->gr_gid);
+ value = temp;
+ endpwent();
+ }
}
/* fmask and dmask synonyms for people used to smbfs syntax */
} else if (strcmp(data, "file_mode") == 0 || strcmp(data, "fmask")==0) {
@@ -504,6 +535,9 @@ static int parse_options(char * options, int * filesys_flags)
*filesys_flags &= ~MS_NOSUID;
} else if (strncmp(data, "nodev", 5) == 0) {
*filesys_flags |= MS_NODEV;
+ } else if ((strncmp(data, "nobrl", 5) == 0) ||
+ (strncmp(data, "nolock", 6) == 0)) {
+ *filesys_flags &= ~MS_MANDLOCK;
} else if (strncmp(data, "dev", 3) == 0) {
*filesys_flags &= ~MS_NODEV;
} else if (strncmp(data, "noexec", 6) == 0) {
@@ -513,11 +547,7 @@ static int parse_options(char * options, int * filesys_flags)
} else if (strncmp(data, "guest", 5) == 0) {
got_password=1;
/* remove the parm since it would otherwise be logged by kern */
- data[0] = ',';
- data[1] = ',';
- data[2] = ',';
- data[3] = ',';
- data[4] = ',';
+ goto nocopy;
} else if (strncmp(data, "ro", 2) == 0) {
*filesys_flags |= MS_RDONLY;
} else if (strncmp(data, "rw", 2) == 0) {
@@ -545,21 +575,29 @@ static int parse_options(char * options, int * filesys_flags)
} */ /* nothing to do on those four mount options above.
Just pass to kernel and ignore them here */
- /* move to next option */
- data = next_keyword+1;
+ /* Copy (possibly modified) option to out */
+ word_len = strlen(data);
+ if (value)
+ word_len += 1 + strlen(value);
- /* put overwritten equals sign back */
- if(value) {
- value--;
- *value = '=';
+ out = realloc(out, out_len + word_len + 2);
+ if (out == NULL) {
+ perror("malloc");
+ exit(1);
}
-
- /* put previous overwritten comma back */
- if(next_keyword)
- *next_keyword = ','; /* BB handle sep= */
+
+ if (out_len)
+ out[out_len++] = ',';
+ if (value)
+ sprintf(out + out_len, "%s=%s", data, value);
else
- data = NULL;
+ sprintf(out + out_len, "%s", data);
+ out_len = strlen(out);
+
+nocopy:
+ data = next_keyword;
}
+ *optionsp = out;
return 0;
}
@@ -570,13 +608,15 @@ static void check_for_comma(char ** ppasswrd)
char *pass;
int i,j;
int number_of_commas = 0;
- int len = strlen(*ppasswrd);
+ int len;
if(ppasswrd == NULL)
return;
else
(pass = *ppasswrd);
+ len = strlen(pass);
+
for(i=0;i<len;i++) {
if(pass[i] == ',')
number_of_commas++;
@@ -692,7 +732,6 @@ static char * parse_server(char ** punc_name)
char * ipaddress_string = NULL;
struct hostent * host_entry = NULL;
struct in_addr server_ipaddr;
- int rc;
if(length > 1023) {
printf("mount error: UNC name too long");
@@ -715,6 +754,13 @@ static char * parse_server(char ** punc_name)
if(share) {
free_share_name = 1;
*punc_name = malloc(length+3);
+ if(*punc_name == NULL) {
+ /* put the original string back if
+ no memory left */
+ *punc_name = unc_name;
+ return NULL;
+ }
+
*share = '/';
strncpy((*punc_name)+2,unc_name,length);
unc_name = *punc_name;
@@ -744,8 +790,7 @@ continue_unc_parsing:
return NULL;
}
if(host_entry == NULL) {
- printf("mount error: could not find target server. TCP name %s not found ", unc_name);
- printf(" rc = %d\n",rc);
+ printf("mount error: could not find target server. TCP name %s not found\n", unc_name);
return NULL;
} else {
/* BB should we pass an alternate version of the share name as Unicode */
@@ -905,10 +950,44 @@ int main(int argc, char ** argv)
wsize = atoi(optarg);
break;
case '1':
- uid = atoi(optarg);
+ if (isdigit(*optarg)) {
+ char *ep;
+
+ uid = strtoul(optarg, &ep, 10);
+ if (*ep) {
+ printf("bad uid value \"%s\"\n", optarg);
+ exit(1);
+ }
+ } else {
+ struct passwd *pw;
+
+ if (!(pw = getpwnam(optarg))) {
+ printf("bad user name \"%s\"\n", optarg);
+ exit(1);
+ }
+ uid = pw->pw_uid;
+ endpwent();
+ }
break;
case '2':
- gid = atoi(optarg);
+ if (isdigit(*optarg)) {
+ char *ep;
+
+ gid = strtoul(optarg, &ep, 10);
+ if (*ep) {
+ printf("bad gid value \"%s\"\n", optarg);
+ exit(1);
+ }
+ } else {
+ struct group *gr;
+
+ if (!(gr = getgrnam(optarg))) {
+ printf("bad user name \"%s\"\n", optarg);
+ exit(1);
+ }
+ gid = gr->gr_gid;
+ endpwent();
+ }
break;
case 'u':
got_user = 1;
@@ -954,7 +1033,7 @@ int main(int argc, char ** argv)
get_password_from_file(0, getenv("PASSWD_FILE"));
}
- if (orgoptions && parse_options(orgoptions, &flags))
+ if (orgoptions && parse_options(&orgoptions, &flags))
return -1;
ipaddr = parse_server(&share_name);
if((ipaddr == NULL) && (got_ip == 0)) {
@@ -1018,6 +1097,9 @@ mount_retry:
optlen = 0;
if(share_name)
optlen += strlen(share_name) + 4;
+ else {
+ printf("No server share name specified\n");
+ }
if(user_name)
optlen += strlen(user_name) + 6;
if(ipaddr)
@@ -1126,8 +1208,6 @@ mount_retry:
strcat(mountent.mnt_opts,"rw");
if(flags & MS_MANDLOCK)
strcat(mountent.mnt_opts,",mand");
- else
- strcat(mountent.mnt_opts,",nomand");
if(flags & MS_NOEXEC)
strcat(mountent.mnt_opts,",noexec");
if(flags & MS_NOSUID)
diff --git a/source/client/smbspool.c b/source/client/smbspool.c
index aff241adeed..7fe918413d5 100644
--- a/source/client/smbspool.c
+++ b/source/client/smbspool.c
@@ -461,6 +461,7 @@ smb_connect(const char *workgroup, /* I - Workgroup */
{
struct cli_state *cli; /* New connection */
pstring myname; /* Client name */
+ struct passwd *pwd;
/*
* Get the names and addresses of the client and server...
@@ -488,12 +489,24 @@ smb_connect(const char *workgroup, /* I - Workgroup */
if (cli ) { return cli; }
+ /* give a chance for a passwordless NTLMSSP session setup */
+
+ pwd = getpwuid(geteuid());
+ if (pwd == NULL) {
+ return NULL;
+ }
+
+ cli = smb_complete_connection(myname, server, port, pwd->pw_name, "",
+ workgroup, share, 0);
+
+ if (cli) { return cli; }
+
/*
* last try. Use anonymous authentication
*/
+
cli = smb_complete_connection(myname, server, port, "", "",
workgroup, share, 0);
-
/*
* Return the new connection...
*/
diff --git a/source/include/passdb.h b/source/include/passdb.h
index 293d18a42a2..0589b9a7cd4 100644
--- a/source/include/passdb.h
+++ b/source/include/passdb.h
@@ -265,9 +265,12 @@ struct pdb_search {
* This next constant specifies the version number of the PASSDB interface
* this SAMBA will load. Increment this if *ANY* changes are made to the interface.
* Changed interface to fix int -> size_t problems. JRA.
+ * There's no point in allocating arrays in
+ * samr_lookup_rids twice. It was done in the srv_samr_nt.c code as well as in
+ * the pdb module. Remove the latter, this might happen more often. VL.
*/
-#define PASSDB_INTERFACE_VERSION 11
+#define PASSDB_INTERFACE_VERSION 12
typedef struct pdb_context
{
@@ -367,12 +370,11 @@ typedef struct pdb_context
size_t *p_num_alias_rids);
NTSTATUS (*pdb_lookup_rids)(struct pdb_context *context,
- TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
size_t num_rids,
uint32 *rids,
- const char ***pp_names,
- uint32 **attrs);
+ const char **pp_names,
+ uint32 *attrs);
NTSTATUS (*pdb_get_account_policy)(struct pdb_context *context,
int policy_index, uint32 *value);
@@ -491,12 +493,11 @@ typedef struct pdb_methods
size_t *p_num_alias_rids);
NTSTATUS (*lookup_rids)(struct pdb_methods *methods,
- TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
int num_rids,
uint32 *rids,
- const char ***pp_names,
- uint32 **attrs);
+ const char **pp_names,
+ uint32 *attrs);
NTSTATUS (*get_account_policy)(struct pdb_methods *methods,
int policy_index, uint32 *value);
diff --git a/source/include/rpc_dce.h b/source/include/rpc_dce.h
index 3de4d2b691e..e718d92271c 100644
--- a/source/include/rpc_dce.h
+++ b/source/include/rpc_dce.h
@@ -26,15 +26,27 @@
/* DCE/RPC packet types */
enum RPC_PKT_TYPE {
- RPC_REQUEST = 0x00,
- RPC_RESPONSE = 0x02,
- RPC_FAULT = 0x03,
- RPC_BIND = 0x0B,
- RPC_BINDACK = 0x0C,
- RPC_BINDNACK = 0x0D,
- RPC_ALTCONT = 0x0E,
- RPC_ALTCONTRESP = 0x0F,
- RPC_AUTH3 = 0x10 /* not the real name! this is undocumented! */
+ RPC_REQUEST = 0x00, /* Ordinary request. */
+ RPC_PING = 0x01, /* Connectionless is server alive ? */
+ RPC_RESPONSE = 0x02, /* Ordinary reply. */
+ RPC_FAULT = 0x03, /* Fault in processing of call. */
+ RPC_WORKING = 0x04, /* Connectionless reply to a ping when server busy. */
+ RPC_NOCALL = 0x05, /* Connectionless reply to a ping when server has lost part of clients call. */
+ RPC_REJECT = 0x06, /* Refuse a request with a code. */
+ RPC_ACK = 0x07, /* Connectionless client to server code. */
+ RPC_CL_CANCEL= 0x08, /* Connectionless cancel. */
+ RPC_FACK = 0x09, /* Connectionless fragment ack. Both client and server send. */
+ RPC_CANCEL_ACK = 0x0A, /* Server ACK to client cancel request. */
+ RPC_BIND = 0x0B, /* Bind to interface. */
+ RPC_BINDACK = 0x0C, /* Server ack of bind. */
+ RPC_BINDNACK = 0x0D, /* Server nack of bind. */
+ RPC_ALTCONT = 0x0E, /* Alter auth. */
+ RPC_ALTCONTRESP = 0x0F, /* Reply to alter auth. */
+ RPC_AUTH3 = 0x10, /* not the real name! this is undocumented! */
+ RPC_SHUTDOWN = 0x11, /* Server to client request to shutdown. */
+ RPC_CO_CANCEL= 0x12, /* Connection-oriented cancel request. */
+ RPC_ORPHANED = 0x13 /* Client telling server it's aborting a partially sent request or telling
+ server to stop sending replies. */
};
/* DCE/RPC flags */
diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h
index c73cd03f103..fdf2f08c03c 100644
--- a/source/include/rpc_netlogon.h
+++ b/source/include/rpc_netlogon.h
@@ -38,7 +38,9 @@
#define NET_LOGON_CTRL2 0x0e
#define NET_SAM_SYNC 0x10
#define NET_TRUST_DOM_LIST 0x13
+#define NET_DSR_GETDCNAME 0x14
#define NET_AUTH3 0x1a
+#define NET_DSR_GETSITENAME 0x1c
/* Secure Channel types. used in NetrServerAuthenticate negotiation */
#define SEC_CHAN_WKSTA 2
@@ -934,4 +936,51 @@ typedef struct net_r_sam_deltas_info {
NTSTATUS status;
} NET_R_SAM_DELTAS;
+/* NET_Q_DSR_GETDCNAME - Ask a DC for a trusted DC name and its address */
+typedef struct net_q_dsr_getdcname {
+ uint32 ptr_server_unc;
+ UNISTR2 uni_server_unc;
+ uint32 ptr_domain_name;
+ UNISTR2 uni_domain_name;
+ uint32 ptr_domain_guid;
+ struct uuid *domain_guid;
+ uint32 ptr_site_guid;
+ struct uuid *site_guid;
+ uint32_t flags;
+} NET_Q_DSR_GETDCNAME;
+
+/* NET_R_DSR_GETDCNAME - Ask a DC for a trusted DC name and its address */
+typedef struct net_r_dsr_getdcname {
+ uint32 ptr_dc_unc;
+ UNISTR2 uni_dc_unc;
+ uint32 ptr_dc_address;
+ UNISTR2 uni_dc_address;
+ int32 dc_address_type;
+ struct uuid domain_guid;
+ uint32 ptr_domain_name;
+ UNISTR2 uni_domain_name;
+ uint32 ptr_forest_name;
+ UNISTR2 uni_forest_name;
+ uint32 dc_flags;
+ uint32 ptr_dc_site_name;
+ UNISTR2 uni_dc_site_name;
+ uint32 ptr_client_site_name;
+ UNISTR2 uni_client_site_name;
+ WERROR result;
+} NET_R_DSR_GETDCNAME;
+
+/* NET_Q_DSR_GESITENAME */
+typedef struct net_q_dsr_getsitename {
+ uint32 ptr_computer_name;
+ UNISTR2 uni_computer_name;
+} NET_Q_DSR_GETSITENAME;
+
+/* NET_R_DSR_GETSITENAME */
+typedef struct net_r_dsr_getsitename {
+ uint32 ptr_site_name;
+ UNISTR2 uni_site_name;
+ WERROR result;
+} NET_R_DSR_GETSITENAME;
+
+
#endif /* _RPC_NETLOGON_H */
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index f19de2ef4fc..5555aaef0e4 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -143,6 +143,8 @@ SamrTestPrivateFunctionsUser
#define SAMR_CONNECT 0x39
#define SAMR_SET_USERINFO 0x3A
#define SAMR_CONNECT4 0x3E
+#define SAMR_CHGPASSWD3 0x3F
+#define SAMR_CONNECT5 0x40
typedef struct logon_hours_info
{
@@ -592,7 +594,7 @@ typedef struct sam_unknown_info_1_inf
{
uint16 min_length_password;
uint16 password_history;
- uint32 flag;
+ uint32 password_properties;
NTTIME expire;
NTTIME min_passwordage;
@@ -1697,7 +1699,7 @@ typedef struct q_samr_connect_info
/* SAMR_R_CONNECT - probably an open */
typedef struct r_samr_connect_info
{
- POLICY_HND connect_pol; /* policy handle */
+ POLICY_HND connect_pol; /* policy handle */
NTSTATUS status; /* return status */
} SAMR_R_CONNECT;
@@ -1715,6 +1717,31 @@ typedef struct q_samr_connect4_info
/* SAMR_R_CONNECT4 - same format as connect */
typedef struct r_samr_connect_info SAMR_R_CONNECT4;
+/* SAMR_Q_CONNECT5 */
+typedef struct q_samr_connect5_info
+{
+ uint32 ptr_srv_name; /* pointer to server name */
+ UNISTR2 uni_srv_name;
+ uint32 access_mask;
+ uint32 level;
+ /* These following are acutally a level dependent
+ value. Fudge it for now. JRA */
+ uint32 info1_unk1;
+ uint32 info1_unk2;
+} SAMR_Q_CONNECT5;
+
+/* SAMR_R_CONNECT5 */
+typedef struct r_samr_connect_info5
+{
+ uint32 level;
+ uint32 info1_unk1;
+ uint32 info1_unk2;
+ POLICY_HND connect_pol; /* policy handle */
+ NTSTATUS status; /* return status */
+
+} SAMR_R_CONNECT5;
+
+
/* SAMR_Q_GET_DOM_PWINFO */
typedef struct q_samr_get_dom_pwinfo
{
@@ -1724,14 +1751,18 @@ typedef struct q_samr_get_dom_pwinfo
} SAMR_Q_GET_DOM_PWINFO;
+#define DOMAIN_PASSWORD_COMPLEX 0x00000001
+#define DOMAIN_PASSWORD_NO_ANON_CHANGE 0x00000002
+#define DOMAIN_PASSWORD_NO_CLEAR_CHANGE 0x00000004
+#define DOMAIN_LOCKOUT_ADMINS 0x00000008
+#define DOMAIN_PASSWORD_STORE_CLEARTEXT 0x00000010
+#define DOMAIN_REFUSE_PASSWORD_CHANGE 0x00000020
+
/* SAMR_R_GET_DOM_PWINFO */
typedef struct r_samr_get_dom_pwinfo
{
- /*
- * See Samba4 IDL
- */
- uint16 unk_0;
- uint32 unk_1;
+ uint16 min_pwd_length;
+ uint32 password_properties;
NTSTATUS status;
} SAMR_R_GET_DOM_PWINFO;
@@ -1780,6 +1811,48 @@ typedef struct r_samr_chgpasswd_user_info
} SAMR_R_CHGPASSWD_USER;
+/* SAMR_Q_CHGPASSWD3 */
+typedef struct q_samr_chgpasswd3
+{
+ uint32 ptr_0;
+
+ UNIHDR hdr_dest_host; /* server name unicode header */
+ UNISTR2 uni_dest_host; /* server name unicode string */
+
+ UNIHDR hdr_user_name; /* username unicode string header */
+ UNISTR2 uni_user_name; /* username unicode string */
+
+ SAMR_ENC_PASSWD nt_newpass;
+ SAMR_ENC_HASH nt_oldhash;
+
+ uint32 lm_change; /* 0x0000 0001 */
+
+ SAMR_ENC_PASSWD lm_newpass;
+ SAMR_ENC_HASH lm_oldhash;
+
+ SAMR_ENC_PASSWD password3;
+
+} SAMR_Q_CHGPASSWD3;
+
+/* SAMR_CHANGE_REJECT */
+typedef struct samr_change_reject
+{
+ uint32 reject_reason;
+ uint32 unknown1;
+ uint32 unknown2;
+
+} SAMR_CHANGE_REJECT;
+
+/* SAMR_R_CHGPASSWD3 */
+typedef struct r_samr_chgpasswd3
+{
+ SAM_UNK_INFO_1 info;
+ SAMR_CHANGE_REJECT reject;
+ NTSTATUS status; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
+
+} SAMR_R_CHGPASSWD3;
+
+
/* SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN */
typedef struct q_samr_remove_sid_foreign_domain_info
diff --git a/source/include/talloc.h b/source/include/talloc.h
index 738506e323d..1001a951702 100644
--- a/source/include/talloc.h
+++ b/source/include/talloc.h
@@ -6,19 +6,23 @@
Copyright (C) Andrew Tridgell 2004-2005
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ ** NOTE! The following LGPL license applies to the talloc
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
- This program is distributed in the hope that it will be useful,
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* this is only needed for compatibility with the old talloc */
@@ -58,9 +62,18 @@ typedef void TALLOC_CTX;
#define malloc_array_p(type, count) (type *)realloc_array(NULL, sizeof(type), count)
#define realloc_p(p, type, count) (type *)realloc_array(p, sizeof(type), count)
+#if 0
+/* Not correct for Samba3. */
+#define data_blob(ptr, size) data_blob_named(ptr, size, "DATA_BLOB: "__location__)
+#define data_blob_talloc(ctx, ptr, size) data_blob_talloc_named(ctx, ptr, size, "DATA_BLOB: "__location__)
+#define data_blob_dup_talloc(ctx, blob) data_blob_talloc_named(ctx, (blob)->data, (blob)->length, "DATA_BLOB: "__location__)
+#endif
+
#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
+#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
+
#if TALLOC_DEPRECATED
#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
@@ -113,6 +126,7 @@ void *_talloc_zero(const void *ctx, size_t size, const char *name);
void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
char *talloc_strdup(const void *t, const char *p);
char *talloc_strndup(const void *t, const char *p, size_t n);
+char *talloc_append_string(const void *t, char *orig, const char *append);
char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
char *talloc_asprintf_append(char *s,
@@ -123,6 +137,8 @@ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned
void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
void *talloc_autofree_context(void);
size_t talloc_get_size(const void *ctx);
+void *talloc_find_parent_byname(const void *ctx, const char *name);
+void talloc_show_parents(const void *context, FILE *file);
#endif
diff --git a/source/lib/talloc.c b/source/lib/talloc.c
index 2df4588f425..00f889d682c 100644
--- a/source/lib/talloc.c
+++ b/source/lib/talloc.c
@@ -1,4 +1,4 @@
-/*
+/*
Samba Unix SMB/CIFS implementation.
Samba trivial allocation library - new interface
@@ -6,27 +6,30 @@
NOTE: Please read talloc_guide.txt for full documentation
Copyright (C) Andrew Tridgell 2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
+
+ ** NOTE! The following LGPL license applies to the talloc
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
inspired by http://swapped.cc/halloc/
*/
-
#ifdef _SAMBA_BUILD_
#include "includes.h"
#if ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9))
@@ -56,8 +59,9 @@
#define MAX_TALLOC_SIZE 0x10000000
-#define TALLOC_MAGIC 0xe814ec4f
-#define TALLOC_MAGIC_FREE 0x7faebef3
+#define TALLOC_MAGIC 0xe814ec70
+#define TALLOC_FLAG_FREE 0x01
+#define TALLOC_FLAG_LOOP 0x02
#define TALLOC_MAGIC_REFERENCE ((const char *)1)
/* by default we abort when given a bad pointer (such as when talloc_free() is called
@@ -93,27 +97,27 @@ struct talloc_chunk {
struct talloc_chunk *next, *prev;
struct talloc_chunk *parent, *child;
struct talloc_reference_handle *refs;
- size_t size;
talloc_destructor_t destructor;
const char *name;
- union {
- unsigned magic;
- double align_dummy;
- } u;
+ size_t size;
+ unsigned flags;
};
+/* 16 byte alignment seems to keep everyone happy */
+#define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
+#define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
+
/* panic if we get a bad magic value */
static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
{
- struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
- if (tc->u.magic != TALLOC_MAGIC) {
- if (tc->u.magic == TALLOC_MAGIC_FREE) {
- TALLOC_ABORT("Bad talloc magic value - double free");
- } else {
- TALLOC_ABORT("Bad talloc magic value - unknown value");
- }
+ const char *pp = ptr;
+ struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
+ if ((tc->flags & ~0xF) != TALLOC_MAGIC) {
+ TALLOC_ABORT("Bad talloc magic value - unknown value");
+ }
+ if (tc->flags & TALLOC_FLAG_FREE) {
+ TALLOC_ABORT("Bad talloc magic value - double free");
}
-
return tc;
}
@@ -158,7 +162,7 @@ static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
void *talloc_parent(const void *ptr)
{
struct talloc_chunk *tc = talloc_parent_chunk(ptr);
- return tc ? (void *)(tc+1) : NULL;
+ return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
}
/*
@@ -176,11 +180,11 @@ void *_talloc(const void *context, size_t size)
return NULL;
}
- tc = malloc(sizeof(*tc)+size);
+ tc = malloc(TC_HDR_SIZE+size);
if (tc == NULL) return NULL;
tc->size = size;
- tc->u.magic = TALLOC_MAGIC;
+ tc->flags = TALLOC_MAGIC;
tc->destructor = NULL;
tc->child = NULL;
tc->name = NULL;
@@ -200,7 +204,7 @@ void *_talloc(const void *context, size_t size)
tc->next = tc->prev = tc->parent = NULL;
}
- return (void *)(tc+1);
+ return TC_PTR_FROM_CHUNK(tc);
}
@@ -285,7 +289,7 @@ static int talloc_unreference(const void *context, const void *ptr)
for (h=tc->refs;h;h=h->next) {
struct talloc_chunk *p = talloc_parent_chunk(h);
- if ((p==NULL && context==NULL) || p+1 == context) break;
+ if ((p==NULL && context==NULL) || TC_PTR_FROM_CHUNK(p) == context) break;
}
if (h == NULL) {
return -1;
@@ -336,7 +340,7 @@ int talloc_unlink(const void *context, void *ptr)
new_p = talloc_parent_chunk(tc_p->refs);
if (new_p) {
- new_parent = new_p+1;
+ new_parent = TC_PTR_FROM_CHUNK(new_p);
} else {
new_parent = NULL;
}
@@ -464,6 +468,8 @@ void *talloc_init(const char *fmt, ...)
va_list ap;
void *ptr;
+ talloc_enable_null_tracking();
+
ptr = _talloc(NULL, 0);
if (ptr == NULL) return NULL;
@@ -495,16 +501,16 @@ void talloc_free_children(void *ptr)
choice is owner of any remaining reference to this
pointer, the second choice is our parent, and the
final choice is the null context. */
- void *child = tc->child+1;
+ void *child = TC_PTR_FROM_CHUNK(tc->child);
const void *new_parent = null_context;
if (tc->child->refs) {
struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
- if (p) new_parent = p+1;
+ if (p) new_parent = TC_PTR_FROM_CHUNK(p);
}
if (talloc_free(child) == -1) {
if (new_parent == null_context) {
struct talloc_chunk *p = talloc_parent_chunk(ptr);
- if (p) new_parent = p+1;
+ if (p) new_parent = TC_PTR_FROM_CHUNK(p);
}
talloc_steal(new_parent, child);
}
@@ -534,6 +540,11 @@ int talloc_free(void *ptr)
return -1;
}
+ if (tc->flags & TALLOC_FLAG_LOOP) {
+ /* we have a free loop - stop looping */
+ return 0;
+ }
+
if (tc->destructor) {
talloc_destructor_t d = tc->destructor;
if (d == (talloc_destructor_t)-1) {
@@ -547,6 +558,8 @@ int talloc_free(void *ptr)
tc->destructor = NULL;
}
+ tc->flags |= TALLOC_FLAG_LOOP;
+
talloc_free_children(ptr);
if (tc->parent) {
@@ -559,7 +572,7 @@ int talloc_free(void *ptr)
if (tc->next) tc->next->prev = tc->prev;
}
- tc->u.magic = TALLOC_MAGIC_FREE;
+ tc->flags |= TALLOC_FLAG_FREE;
free(tc);
return 0;
@@ -599,24 +612,24 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n
}
/* by resetting magic we catch users of the old memory */
- tc->u.magic = TALLOC_MAGIC_FREE;
+ tc->flags |= TALLOC_FLAG_FREE;
#if ALWAYS_REALLOC
- new_ptr = malloc(size + sizeof(*tc));
+ new_ptr = malloc(size + TC_HDR_SIZE);
if (new_ptr) {
- memcpy(new_ptr, tc, tc->size + sizeof(*tc));
+ memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
free(tc);
}
#else
- new_ptr = realloc(tc, size + sizeof(*tc));
+ new_ptr = realloc(tc, size + TC_HDR_SIZE);
#endif
if (!new_ptr) {
- tc->u.magic = TALLOC_MAGIC;
+ tc->flags &= ~TALLOC_FLAG_FREE;
return NULL;
}
tc = new_ptr;
- tc->u.magic = TALLOC_MAGIC;
+ tc->flags &= ~TALLOC_FLAG_FREE;
if (tc->parent) {
tc->parent->child = new_ptr;
}
@@ -632,9 +645,9 @@ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *n
}
tc->size = size;
- talloc_set_name_const(tc+1, name);
+ talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
- return (void *)(tc+1);
+ return TC_PTR_FROM_CHUNK(tc);
}
/*
@@ -711,10 +724,19 @@ off_t talloc_total_size(const void *ptr)
tc = talloc_chunk_from_ptr(ptr);
+ if (tc->flags & TALLOC_FLAG_LOOP) {
+ return 0;
+ }
+
+ tc->flags |= TALLOC_FLAG_LOOP;
+
total = tc->size;
for (c=tc->child;c;c=c->next) {
- total += talloc_total_size(c+1);
+ total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
}
+
+ tc->flags &= ~TALLOC_FLAG_LOOP;
+
return total;
}
@@ -726,10 +748,19 @@ off_t talloc_total_blocks(const void *ptr)
off_t total = 0;
struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+ if (tc->flags & TALLOC_FLAG_LOOP) {
+ return 0;
+ }
+
+ tc->flags |= TALLOC_FLAG_LOOP;
+
total++;
for (c=tc->child;c;c=c->next) {
- total += talloc_total_blocks(c+1);
+ total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
}
+
+ tc->flags &= ~TALLOC_FLAG_LOOP;
+
return total;
}
@@ -755,23 +786,29 @@ void talloc_report_depth(const void *ptr, FILE *f, int depth)
{
struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+ if (tc->flags & TALLOC_FLAG_LOOP) {
+ return;
+ }
+
+ tc->flags |= TALLOC_FLAG_LOOP;
+
for (c=tc->child;c;c=c->next) {
if (c->name == TALLOC_MAGIC_REFERENCE) {
- struct talloc_reference_handle *handle = (void *)(c+1);
+ struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c);
const char *name2 = talloc_get_name(handle->ptr);
fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
} else {
- const char *name = talloc_get_name(c+1);
+ const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c));
fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
depth*4, "",
name,
- (unsigned long)talloc_total_size(c+1),
- (unsigned long)talloc_total_blocks(c+1),
- talloc_reference_count(c+1));
- talloc_report_depth(c+1, f, depth+1);
+ (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
+ (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
+ talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
+ talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1);
}
}
-
+ tc->flags &= ~TALLOC_FLAG_LOOP;
}
/*
@@ -814,9 +851,9 @@ void talloc_report(const void *ptr, FILE *f)
for (c=tc->child;c;c=c->next) {
fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
- talloc_get_name(c+1),
- (unsigned long)talloc_total_size(c+1),
- (unsigned long)talloc_total_blocks(c+1));
+ talloc_get_name(TC_PTR_FROM_CHUNK(c)),
+ (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
+ (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)));
}
fflush(f);
}
@@ -851,6 +888,74 @@ void talloc_enable_null_tracking(void)
}
}
+#ifdef _SAMBA_BUILD_
+/* Ugly calls to Samba-specific sprintf_append... JRA. */
+
+/*
+ report on memory usage by all children of a pointer, giving a full tree view
+*/
+static void talloc_report_depth_str(const void *ptr, char **pps, ssize_t *plen, size_t *pbuflen, int depth)
+{
+ struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+
+ if (tc->flags & TALLOC_FLAG_LOOP) {
+ return;
+ }
+
+ tc->flags |= TALLOC_FLAG_LOOP;
+
+ for (c=tc->child;c;c=c->next) {
+ if (c->name == TALLOC_MAGIC_REFERENCE) {
+ struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c);
+ const char *name2 = talloc_get_name(handle->ptr);
+
+ sprintf_append(NULL, pps, plen, pbuflen,
+ "%*sreference to: %s\n", depth*4, "", name2);
+
+ } else {
+ const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c));
+
+ sprintf_append(NULL, pps, plen, pbuflen,
+ "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
+ depth*4, "",
+ name,
+ (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
+ (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
+ talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
+
+ talloc_report_depth_str(TC_PTR_FROM_CHUNK(c), pps, plen, pbuflen, depth+1);
+ }
+ }
+ tc->flags &= ~TALLOC_FLAG_LOOP;
+}
+
+/*
+ report on memory usage by all children of a pointer
+*/
+char *talloc_describe_all(void)
+{
+ ssize_t len = 0;
+ size_t buflen = 512;
+ char *s = NULL;
+
+ if (null_context == NULL) {
+ return NULL;
+ }
+
+ sprintf_append(NULL, &s, &len, &buflen,
+ "full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
+ talloc_get_name(null_context),
+ (unsigned long)talloc_total_size(null_context),
+ (unsigned long)talloc_total_blocks(null_context));
+
+ if (!s) {
+ return NULL;
+ }
+ talloc_report_depth_str(null_context, &s, &len, &buflen, 1);
+ return s;
+}
+#endif
+
/*
enable leak reporting on exit
*/
@@ -915,6 +1020,28 @@ char *talloc_strdup(const void *t, const char *p)
}
/*
+ append to a talloced string
+*/
+char *talloc_append_string(const void *t, char *orig, const char *append)
+{
+ char *ret;
+ size_t olen = strlen(orig);
+ size_t alenz = strlen(append) + 1;
+
+ if (!append)
+ return orig;
+
+ ret = talloc_realloc(t, orig, char, olen + alenz);
+ if (!ret)
+ return NULL;
+
+ /* append the string with the trailing \0 */
+ memcpy(&ret[olen], append, alenz);
+
+ return ret;
+}
+
+/*
strndup with a talloc
*/
char *talloc_strndup(const void *t, const char *p, size_t n)
@@ -989,6 +1116,7 @@ static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINT
static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
{
+ struct talloc_chunk *tc;
int len, s_len;
va_list ap2;
@@ -996,9 +1124,11 @@ static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
return talloc_vasprintf(NULL, fmt, ap);
}
+ tc = talloc_chunk_from_ptr(s);
+
VA_COPY(ap2, ap);
- s_len = strlen(s);
+ s_len = tc->size - 1;
len = vsnprintf(NULL, 0, fmt, ap2);
s = talloc_realloc(NULL, s, char, s_len + len+1);
@@ -1102,3 +1232,46 @@ size_t talloc_get_size(const void *context)
return tc->size;
}
+
+/*
+ find a parent of this context that has the given name, if any
+*/
+void *talloc_find_parent_byname(const void *context, const char *name)
+{
+ struct talloc_chunk *tc;
+
+ if (context == NULL) {
+ return NULL;
+ }
+
+ tc = talloc_chunk_from_ptr(context);
+ while (tc) {
+ if (tc->name && strcmp(tc->name, name) == 0) {
+ return TC_PTR_FROM_CHUNK(tc);
+ }
+ while (tc && tc->prev) tc = tc->prev;
+ tc = tc->parent;
+ }
+ return NULL;
+}
+
+/*
+ show the parentage of a context
+*/
+void talloc_show_parents(const void *context, FILE *file)
+{
+ struct talloc_chunk *tc;
+
+ if (context == NULL) {
+ fprintf(file, "talloc no parents for NULL\n");
+ return;
+ }
+
+ tc = talloc_chunk_from_ptr(context);
+ fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
+ while (tc) {
+ fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
+ while (tc && tc->prev) tc = tc->prev;
+ tc = tc->parent;
+ }
+}
diff --git a/source/lib/tallocmsg.c b/source/lib/tallocmsg.c
index 8f03fd66ff1..b515093cd69 100644
--- a/source/lib/tallocmsg.c
+++ b/source/lib/tallocmsg.c
@@ -33,18 +33,23 @@
void msg_pool_usage(int msg_type, struct process_id src_pid,
void *UNUSED(buf), size_t UNUSED(len))
{
- off_t reply;
- fstring reply_str;
+ char *reply = NULL;
SMB_ASSERT(msg_type == MSG_REQ_POOL_USAGE);
DEBUG(2,("Got POOL_USAGE\n"));
- reply = talloc_total_size(NULL);
- fstr_sprintf(reply_str, "%ld", (long)reply);
+ reply = talloc_describe_all();
+ if (!reply) {
+ return;
+ }
+ become_root();
message_send_pid(src_pid, MSG_POOL_USAGE,
- reply_str, strlen(reply_str)+1, True);
+ reply, strlen(reply)+1, True);
+ unbecome_root();
+
+ SAFE_FREE(reply);
}
/**
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index d80bb2ce521..b979745d366 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -265,6 +265,34 @@ int rpcstr_pull_unistr2_fstring(char *dest, UNISTR2 *src)
src->uni_str_len * 2, 0);
}
+/* Helper function to return a talloc'ed string. I have implemented it with a
+ * copy because I don't really know how pull_ucs2 and friends calculate the
+ * target size. If this turns out to be a major bottleneck someone with deeper
+ * multi-byte knowledge needs to revisit this.
+ * My (VL) use is dsr_getdcname, which returns 6 strings, the alternative would
+ * have been to manually talloc_strdup them in rpc_client/cli_netlogon.c.
+ */
+
+size_t rpcstr_pull_unistr2_talloc(TALLOC_CTX *mem_ctx, char **dest,
+ UNISTR2 *src)
+{
+ pstring tmp;
+ size_t result;
+
+ result = pull_ucs2(NULL, tmp, src->buffer, sizeof(tmp),
+ src->uni_str_len * 2, 0);
+ if (result < 0) {
+ return result;
+ }
+
+ *dest = talloc_strdup(mem_ctx, tmp);
+ if (*dest == NULL) {
+ return -1;
+ }
+
+ return result;
+}
+
/* Converts a string from internal samba format to unicode
*/
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index b352d3572a7..ac7d1b1650c 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -163,6 +163,7 @@ static BOOL cli_session_setup_guest(struct cli_state *cli)
char *p;
uint32 capabilities = cli_session_setup_capabilities(cli);
+ memset(cli->outbuf, '\0', smb_size);
set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
cli_setup_packet(cli);
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index bc64cc919b7..6dc7386c03b 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -481,6 +481,7 @@ BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive)
/****************************************************************************
Send a keepalive packet to the server
****************************************************************************/
+
BOOL cli_send_keepalive(struct cli_state *cli)
{
if (cli->fd == -1) {
@@ -495,3 +496,36 @@ BOOL cli_send_keepalive(struct cli_state *cli)
}
return True;
}
+
+/****************************************************************************
+ Send/receive a SMBecho command: ping the server
+****************************************************************************/
+
+BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length)
+{
+ char *p;
+
+ SMB_ASSERT(length < 1024);
+
+ memset(cli->outbuf,'\0',smb_size);
+ set_message(cli->outbuf,1,length,True);
+ SCVAL(cli->outbuf,smb_com,SMBecho);
+ SSVAL(cli->outbuf,smb_tid,65535);
+ SSVAL(cli->outbuf,smb_vwv0,1);
+ cli_setup_packet(cli);
+ p = smb_buf(cli->outbuf);
+ memcpy(p, data, length);
+ p += length;
+
+ cli_setup_bcc(cli, p);
+
+ cli_send_smb(cli);
+ if (!cli_receive_smb(cli)) {
+ return False;
+ }
+
+ if (cli_is_error(cli)) {
+ return False;
+ }
+ return True;
+}
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index 45195fb86ab..aae76e44238 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -30,7 +30,7 @@
extern int winbindd_fd;
-static char winbind_separator(void)
+static char winbind_separator_int(BOOL strict)
{
struct winbindd_response response;
static BOOL got_sep;
@@ -46,6 +46,9 @@ static char winbind_separator(void)
if (winbindd_request_response(WINBINDD_INFO, NULL, &response) !=
NSS_STATUS_SUCCESS) {
d_printf("could not obtain winbind separator!\n");
+ if (strict) {
+ return -1;
+ }
/* HACK: (this module should not call lp_ funtions) */
return *lp_winbind_separator();
}
@@ -55,6 +58,9 @@ static char winbind_separator(void)
if (!sep) {
d_printf("winbind separator was NULL!\n");
+ if (strict) {
+ return -1;
+ }
/* HACK: (this module should not call lp_ funtions) */
sep = *lp_winbind_separator();
}
@@ -62,6 +68,11 @@ static char winbind_separator(void)
return sep;
}
+static char winbind_separator(void)
+{
+ return winbind_separator_int(False);
+}
+
static const char *get_winbind_domain(void)
{
struct winbindd_response response;
@@ -956,7 +967,8 @@ enum {
OPT_SEQUENCE,
OPT_GETDCNAME,
OPT_USERDOMGROUPS,
- OPT_USERSIDS
+ OPT_USERSIDS,
+ OPT_SEPARATOR
};
int main(int argc, char **argv)
@@ -1004,6 +1016,7 @@ int main(int argc, char **argv)
#ifdef WITH_FAKE_KASERVER
{ "klog", 'k', POPT_ARG_STRING, &string_arg, 'k', "set an AFS token from winbind", "user%password" },
#endif
+ { "separator", 0, POPT_ARG_NONE, 0, OPT_SEPARATOR, "Get the active winbind separator", NULL },
POPT_COMMON_VERSION
POPT_TABLEEND
};
@@ -1197,6 +1210,10 @@ int main(int argc, char **argv)
case OPT_GETDCNAME:
wbinfo_getdcname(string_arg);
break;
+ case OPT_SEPARATOR:
+ d_printf("%c\n", winbind_separator_int(True));
+ break;
+
/* generic configuration options */
case OPT_DOMAIN_NAME:
break;
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 86a5353dca7..cdef0340618 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -168,6 +168,7 @@ typedef struct
char *szIdmapUID;
char *szIdmapGID;
BOOL bEnableRidAlgorithm;
+ BOOL bPassdbExpandExplicit;
int AlgorithmicRidBase;
char *szTemplateHomedir;
char *szTemplateShell;
@@ -1240,6 +1241,7 @@ static struct parm_struct parm_table[] = {
{N_("Winbind options"), P_SEP, P_SEPARATOR},
{"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_DEPRECATED},
+ {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
{"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED},
{"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED},
{"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE},
@@ -1603,6 +1605,7 @@ static void init_globals(void)
Globals.szWinbindNssInfo = str_list_make("template", NULL);
Globals.bEnableRidAlgorithm = True;
+ Globals.bPassdbExpandExplicit = True;
Globals.name_cache_timeout = 660; /* In seconds */
@@ -1792,6 +1795,7 @@ FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
FN_GLOBAL_BOOL(lp_enable_rid_algorithm, &Globals.bEnableRidAlgorithm)
+FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
#ifdef WITH_LDAP_SAMCONFIG
FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
index 6b58210919a..b397e084c33 100644
--- a/source/passdb/lookup_sid.c
+++ b/source/passdb/lookup_sid.c
@@ -66,7 +66,8 @@ BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_N
Tries local lookup first - for local sids, then tries winbind.
*****************************************************************/
-BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAME_USE *name_type)
+BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name,
+ enum SID_NAME_USE *name_type)
{
if (!name_type)
return False;
@@ -76,25 +77,51 @@ BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name, enum SID_NAM
/* Check if this is our own sid. This should perhaps be done by
winbind? For the moment handle it here. */
- if (sid->num_auths == 4 && sid_equal(get_global_sam_sid(), sid)) {
- DOM_SID tmp_sid;
- sid_copy(&tmp_sid, sid);
- return map_domain_sid_to_name(&tmp_sid, dom_name) &&
- local_lookup_sid(sid, name, name_type);
+ if (sid_check_is_domain(sid)) {
+ fstrcpy(dom_name, get_global_sam_name());
+ fstrcpy(name, "");
+ *name_type = SID_NAME_DOMAIN;
+ return True;
}
- if (sid->num_auths == 5) {
- DOM_SID tmp_sid;
+ if (sid_check_is_in_our_domain(sid)) {
uint32 rid;
+ SMB_ASSERT(sid_peek_rid(sid, &rid));
+
+ /* For our own domain passdb is responsible */
+ fstrcpy(dom_name, get_global_sam_name());
+ return lookup_global_sam_rid(rid, name, name_type);
+ }
- sid_copy(&tmp_sid, sid);
- sid_split_rid(&tmp_sid, &rid);
+ if (sid_check_is_builtin(sid)) {
- if (sid_equal(get_global_sam_sid(), &tmp_sid)) {
+ /* Got through map_domain_sid_to_name here so that the mapping
+ * of S-1-5-32 to the name "BUILTIN" in as few places as
+ * possible. We might add i18n... */
+ SMB_ASSERT(map_domain_sid_to_name(sid, dom_name));
- return map_domain_sid_to_name(&tmp_sid, dom_name) &&
- local_lookup_sid(sid, name, name_type);
- }
+ /* Yes, W2k3 returns "BUILTIN" both as domain and name here */
+ fstrcpy(name, dom_name);
+
+ *name_type = SID_NAME_DOMAIN;
+ return True;
+ }
+
+ if (sid_check_is_in_builtin(sid)) {
+ uint32 rid;
+
+ SMB_ASSERT(sid_peek_rid(sid, &rid));
+
+ /* Got through map_domain_sid_to_name here so that the mapping
+ * of S-1-5-32 to the name "BUILTIN" in as few places as
+ * possible. We might add i18n... */
+ SMB_ASSERT(map_domain_sid_to_name(&global_sid_Builtin,
+ dom_name));
+
+ /* There's only aliases in S-1-5-32 */
+ *name_type = SID_NAME_ALIAS;
+
+ return lookup_builtin_rid(rid, name);
}
if (winbind_lookup_sid(sid, dom_name, name, name_type)) {
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index a7ff3a04f7e..e073db3499c 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -732,34 +732,25 @@ BOOL algorithmic_pdb_rid_is_user(uint32 rid)
}
/*******************************************************************
- Convert a rid into a name. Used in the lookup SID rpc.
+ Look up a rid in the SAM we're responsible for (i.e. passdb)
********************************************************************/
-BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use)
+BOOL lookup_global_sam_rid(uint32 rid, fstring name,
+ enum SID_NAME_USE *psid_name_use)
{
- uint32 rid;
SAM_ACCOUNT *sam_account = NULL;
GROUP_MAP map;
BOOL ret;
+ DOM_SID sid;
- if (sid_equal(get_global_sam_sid(), sid)) {
- *psid_name_use = SID_NAME_DOMAIN;
- fstrcpy(name, "");
- DEBUG(5,("local_lookup_sid: SID is our own domain-sid: %s.\n",
- sid_string_static(sid)));
- return True;
- }
-
- if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
- DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n",
- sid_string_static(&map.sid)));
- return False;
- }
*psid_name_use = SID_NAME_UNKNOWN;
- DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid));
-
+ DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n",
+ (unsigned int)rid));
+ sid_copy(&sid, get_global_sam_sid());
+ sid_append_rid(&sid, rid);
+
/* see if the passdb can help us with the name of the user */
if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
return False;
@@ -767,8 +758,8 @@ BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_na
/* BEING ROOT BLLOCK */
become_root();
- if (pdb_getsampwsid(sam_account, sid)) {
- unbecome_root(); /* -----> EXIT BECOME_ROOT() */
+ if (pdb_getsampwsid(sam_account, &sid)) {
+ unbecome_root(); /* -----> EXIT BECOME_ROOT() */
fstrcpy(name, pdb_get_username(sam_account));
*psid_name_use = SID_NAME_USER;
@@ -778,15 +769,19 @@ BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_na
}
pdb_free_sam(&sam_account);
- ret = pdb_getgrsid(&map, *sid);
+ ret = pdb_getgrsid(&map, sid);
unbecome_root();
/* END BECOME_ROOT BLOCK */
if ( ret ) {
if (map.gid!=(gid_t)-1) {
- DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
+ DEBUG(5,("lookup_global_sam_rid: mapped group %s to "
+ "gid %u\n", map.nt_name,
+ (unsigned int)map.gid));
} else {
- DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name));
+ DEBUG(5,("lookup_global_sam_rid: mapped group %s to "
+ "no unix gid. Returning name.\n",
+ map.nt_name));
}
fstrcpy(name, map.nt_name);
@@ -809,16 +804,16 @@ BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_na
uid = algorithmic_pdb_user_rid_to_uid(rid);
pw = sys_getpwuid( uid );
- DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
- pw ? "succeeded" : "failed" ));
+ DEBUG(5,("lookup_global_sam_rid: looking up uid %u %s\n",
+ (unsigned int)uid, pw ? "succeeded" : "failed" ));
if ( !pw )
- fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
+ fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
else
fstrcpy( name, pw->pw_name );
- DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
- (unsigned int)rid ));
+ DEBUG(5,("lookup_global_sam_rid: found user %s for rid %u\n",
+ name, (unsigned int)rid ));
*psid_name_use = SID_NAME_USER;
@@ -832,16 +827,16 @@ BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_na
gid = pdb_group_rid_to_gid(rid);
gr = getgrgid(gid);
- DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
- gr ? "succeeded" : "failed" ));
+ DEBUG(5,("lookup_global_sam_rid: looking up gid %u %s\n",
+ (unsigned int)gid, gr ? "succeeded" : "failed" ));
if( !gr )
fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
else
fstrcpy( name, gr->gr_name);
- DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
- (unsigned int)rid ));
+ DEBUG(5,("lookup_global_sam_rid: found group %s for rid %u\n",
+ name, (unsigned int)rid ));
/* assume algorithmic groups are domain global groups */
@@ -1756,6 +1751,7 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
uint32 pwHistLen = 0;
BOOL ret = True;
fstring tmpstring;
+ BOOL expand_explicit = lp_passdb_expand_explicit();
if(sampass == NULL || buf == NULL) {
DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
@@ -1820,7 +1816,10 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
if (homedir) {
fstrcpy( tmpstring, homedir );
- standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ if (expand_explicit) {
+ standard_sub_basic( username, tmpstring,
+ sizeof(tmpstring) );
+ }
pdb_set_homedir(sampass, tmpstring, PDB_SET);
}
else {
@@ -1836,7 +1835,10 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
if (logon_script) {
fstrcpy( tmpstring, logon_script );
- standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ if (expand_explicit) {
+ standard_sub_basic( username, tmpstring,
+ sizeof(tmpstring) );
+ }
pdb_set_logon_script(sampass, tmpstring, PDB_SET);
}
else {
@@ -1847,7 +1849,10 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
if (profile_path) {
fstrcpy( tmpstring, profile_path );
- standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ if (expand_explicit) {
+ standard_sub_basic( username, tmpstring,
+ sizeof(tmpstring) );
+ }
pdb_set_profile_path(sampass, tmpstring, PDB_SET);
}
else {
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 482f3e3c9b8..875e264bf01 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -681,12 +681,11 @@ static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
}
static NTSTATUS context_lookup_rids(struct pdb_context *context,
- TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
size_t num_rids,
uint32 *rids,
- const char ***pp_names,
- uint32 **pp_attrs)
+ const char **pp_names,
+ uint32 *pp_attrs)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
@@ -696,7 +695,7 @@ static NTSTATUS context_lookup_rids(struct pdb_context *context,
}
return context->pdb_methods->lookup_rids(context->pdb_methods,
- mem_ctx, domain_sid, num_rids,
+ domain_sid, num_rids,
rids, pp_names, pp_attrs);
}
@@ -1398,12 +1397,11 @@ BOOL pdb_enum_alias_memberships(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
p_num_alias_rids));
}
-NTSTATUS pdb_lookup_rids(TALLOC_CTX *mem_ctx,
- const DOM_SID *domain_sid,
+NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
int num_rids,
uint32 *rids,
- const char ***names,
- uint32 **attrs)
+ const char **names,
+ uint32 *attrs)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -1411,7 +1409,7 @@ NTSTATUS pdb_lookup_rids(TALLOC_CTX *mem_ctx,
return NT_STATUS_NOT_IMPLEMENTED;
}
- return pdb_context->pdb_lookup_rids(pdb_context, mem_ctx, domain_sid,
+ return pdb_context->pdb_lookup_rids(pdb_context, domain_sid,
num_rids, rids, names, attrs);
}
@@ -1643,51 +1641,58 @@ NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
}
NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
- TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
int num_rids,
uint32 *rids,
- const char ***names,
- uint32 **attrs)
+ const char **names,
+ uint32 *attrs)
{
int i;
NTSTATUS result;
BOOL have_mapped = False;
BOOL have_unmapped = False;
- (*names) = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
- (*attrs) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_rids);
-
- if ((num_rids != 0) && (((*names) == NULL) || ((*attrs) == NULL)))
- return NT_STATUS_NO_MEMORY;
-
- if (!sid_equal(domain_sid, get_global_sam_sid())) {
- /* TODO: Sooner or later we need to look up BUILTIN rids as
- * well. -- vl */
+ if (sid_check_is_builtin(domain_sid)) {
+
+ for (i=0; i<num_rids; i++) {
+ fstring name;
+
+ if (lookup_builtin_rid(rids[i], name)) {
+ attrs[i] = SID_NAME_ALIAS;
+ names[i] = talloc_strdup(names, name);
+ if (names[i] == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ DEBUG(5,("lookup_rids: %s:%d\n",
+ names[i], attrs[i]));
+ have_mapped = True;
+ } else {
+ have_unmapped = True;
+ attrs[i] = SID_NAME_UNKNOWN;
+ }
+ }
goto done;
}
+ /* Should not happen, but better check once too many */
+ if (!sid_check_is_domain(domain_sid)) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
for (i = 0; i < num_rids; i++) {
fstring tmpname;
- fstring domname;
- DOM_SID sid;
enum SID_NAME_USE type;
- (*attrs)[i] = SID_NAME_UNKNOWN;
-
- sid_copy(&sid, domain_sid);
- sid_append_rid(&sid, rids[i]);
-
- if (lookup_sid(&sid, domname, tmpname, &type)) {
- (*attrs)[i] = (uint32)type;
- (*names)[i] = talloc_strdup(mem_ctx, tmpname);
- if ((*names)[i] == NULL)
+ if (lookup_global_sam_rid(rids[i], tmpname, &type)) {
+ attrs[i] = (uint32)type;
+ names[i] = talloc_strdup(names, tmpname);
+ if (names[i] == NULL)
return NT_STATUS_NO_MEMORY;
- DEBUG(5,("lookup_rids: %s:%d\n", (*names)[i],
- (*attrs)[i]));
+ DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
have_mapped = True;
} else {
have_unmapped = True;
+ attrs[i] = SID_NAME_UNKNOWN;
}
}
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 8a9730c3c8a..fac95e37866 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -604,6 +604,7 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
LOGIN_CACHE *cache_entry = NULL;
uint32 pwHistLen;
pstring tmpstring;
+ BOOL expand_explicit = lp_passdb_expand_explicit();
/*
* do a little initialization
@@ -776,7 +777,10 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
PDB_DEFAULT );
} else {
pstrcpy( tmpstring, homedir );
- standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ if (expand_explicit) {
+ standard_sub_basic( username, tmpstring,
+ sizeof(tmpstring) );
+ }
pdb_set_homedir(sampass, tmpstring, PDB_SET);
}
@@ -788,7 +792,10 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
PDB_DEFAULT );
} else {
pstrcpy( tmpstring, logon_script );
- standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ if (expand_explicit) {
+ standard_sub_basic( username, tmpstring,
+ sizeof(tmpstring) );
+ }
pdb_set_logon_script(sampass, tmpstring, PDB_SET);
}
@@ -800,7 +807,10 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
PDB_DEFAULT );
} else {
pstrcpy( tmpstring, profile_path );
- standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ if (expand_explicit) {
+ standard_sub_basic( username, tmpstring,
+ sizeof(tmpstring) );
+ }
pdb_set_profile_path(sampass, tmpstring, PDB_SET);
}
@@ -3503,12 +3513,11 @@ static NTSTATUS ldapsam_get_account_policy(struct pdb_methods *methods, int poli
}
static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
- TALLOC_CTX *mem_ctx,
const DOM_SID *domain_sid,
int num_rids,
uint32 *rids,
- const char ***names,
- uint32 **attrs)
+ const char **names,
+ uint32 *attrs)
{
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)methods->private_data;
@@ -3521,7 +3530,7 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
- return pdb_default_lookup_rids(methods, mem_ctx, domain_sid,
+ return pdb_default_lookup_rids(methods, domain_sid,
num_rids, rids, names, attrs);
if (!sid_equal(domain_sid, get_global_sam_sid())) {
@@ -3530,14 +3539,8 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
goto done;
}
- (*names) = TALLOC_ZERO_ARRAY(mem_ctx, const char *, num_rids);
- (*attrs) = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
-
- if ((num_rids != 0) && (((*names) == NULL) || ((*attrs) == NULL)))
- return NT_STATUS_NO_MEMORY;
-
for (i=0; i<num_rids; i++)
- (*attrs)[i] = SID_NAME_UNKNOWN;
+ attrs[i] = SID_NAME_UNKNOWN;
allsids = SMB_STRDUP("");
if (allsids == NULL) return NT_STATUS_NO_MEMORY;
@@ -3607,9 +3610,9 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
continue;
}
- (*attrs)[rid_index] = SID_NAME_USER;
- (*names)[rid_index] = talloc_strdup(mem_ctx, str);
- if ((*names)[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
+ attrs[rid_index] = SID_NAME_USER;
+ names[rid_index] = talloc_strdup(names, str);
+ if (names[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
num_mapped += 1;
}
@@ -3672,9 +3675,9 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
continue;
}
- (*attrs)[rid_index] = SID_NAME_DOM_GRP;
- (*names)[rid_index] = talloc_strdup(mem_ctx, str);
- if ((*names)[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
+ attrs[rid_index] = SID_NAME_DOM_GRP;
+ names[rid_index] = talloc_strdup(names, str);
+ if (names[rid_index] == NULL) return NT_STATUS_NO_MEMORY;
num_mapped += 1;
}
diff --git a/source/passdb/util_sam_sid.c b/source/passdb/util_sam_sid.c
index 42e4b6df967..822b7f6a349 100644
--- a/source/passdb/util_sam_sid.c
+++ b/source/passdb/util_sam_sid.c
@@ -91,7 +91,7 @@ static struct sid_name_map_info special_domains[] = {
Turns a domain SID into a name, returned in the nt_domain argument.
***************************************************************************/
-BOOL map_domain_sid_to_name(DOM_SID *sid, fstring nt_domain)
+BOOL map_domain_sid_to_name(const DOM_SID *sid, fstring nt_domain)
{
fstring sid_str;
int i = 0;
@@ -100,11 +100,6 @@ BOOL map_domain_sid_to_name(DOM_SID *sid, fstring nt_domain)
DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
- if (sid_check_is_domain(sid)) {
- fstrcpy(nt_domain, get_global_sam_name());
- return True;
- }
-
while (special_domains[i].sid != NULL) {
DEBUG(5,("map_domain_sid_to_name: compare: %s\n",
sid_string_static(special_domains[i].sid)));
@@ -169,6 +164,24 @@ BOOL lookup_special_sid(const DOM_SID *sid, const char **domain,
return False;
}
+/*******************************************************************
+ Look up a rid in the BUILTIN domain
+ ********************************************************************/
+BOOL lookup_builtin_rid(uint32 rid, fstring name)
+{
+ const known_sid_users *aliases = builtin_groups;
+ int i;
+
+ for (i=0; aliases[i].known_user_name != NULL; i++) {
+ if (rid == aliases[i].rid) {
+ fstrcpy(name, aliases[i].known_user_name);
+ return True;
+ }
+ }
+
+ return False;
+}
+
/*****************************************************************
Check if the SID is our domain SID (S-1-5-21-x-y-z).
*****************************************************************/
diff --git a/source/printing/print_svid.c b/source/printing/print_svid.c
index 1213b917342..c369e52cd91 100644
--- a/source/printing/print_svid.c
+++ b/source/printing/print_svid.c
@@ -40,10 +40,39 @@ BOOL sysv_cache_reload(void)
char **lines;
int i;
+#if defined(HPUX)
+ DEBUG(5, ("reloading hpux printcap cache\n"));
+#else
DEBUG(5, ("reloading sysv printcap cache\n"));
+#endif
if ((lines = file_lines_pload("/usr/bin/lpstat -v", NULL)) == NULL)
+ {
+#if defined(HPUX)
+
+ /*
+ * if "lpstat -v" is NULL then we check if schedular is running if it is
+ * that means no printers are added on the HP-UX system, if schedular is not
+ * running we display reload error.
+ */
+
+ char **scheduler;
+ scheduler = file_lines_pload("/usr/bin/lpstat -r", NULL);
+ if(!strcmp(*scheduler,"scheduler is running")){
+ DEBUG(3,("No Printers found!!!\n"));
+ file_lines_free(scheduler);
+ return True;
+ }
+ else{
+ DEBUG(3,("Scheduler is not running!!!\n"));
+ file_lines_free(scheduler);
+ return False;
+ }
+#else
+ DEBUG(3,("No Printers found!!!\n"));
return False;
+#endif
+ }
for (i = 0; lines[i]; i++) {
char *name, *tmp;
diff --git a/source/registry/reg_eventlog.c b/source/registry/reg_eventlog.c
index d802b18aca2..1c65c9b2178 100644
--- a/source/registry/reg_eventlog.c
+++ b/source/registry/reg_eventlog.c
@@ -33,6 +33,7 @@ BOOL eventlog_init_keys( void )
/* Find all of the eventlogs, add keys for each of them */
const char **elogs = lp_eventlog_list( );
pstring evtlogpath;
+ pstring evtfilepath;
REGSUBKEY_CTR *subkeys;
REGVAL_CTR *values;
uint32 uiDisplayNameId;
@@ -98,10 +99,12 @@ BOOL eventlog_init_keys( void )
regval_ctr_addvalue( values, "MaxSize", REG_DWORD,
( char * ) &uiMaxSize,
sizeof( uint32 ) );
+
regval_ctr_addvalue( values, "Retention", REG_DWORD,
( char * ) &uiRetention,
sizeof( uint32 ) );
init_unistr2( &data, *elogs, UNI_STR_TERMINATE );
+
regval_ctr_addvalue( values, "PrimaryModule", REG_SZ,
( char * ) data.buffer,
data.uni_str_len *
@@ -112,6 +115,11 @@ BOOL eventlog_init_keys( void )
( char * ) data.buffer,
data.uni_str_len *
sizeof( uint16 ) );
+
+ pstr_sprintf( evtfilepath, "%%SystemRoot%%\\system32\\config\\%s.tdb", *elogs );
+ init_unistr2( &data, evtfilepath, UNI_STR_TERMINATE );
+ regval_ctr_addvalue( values, "File", REG_EXPAND_SZ, ( char * ) data.buffer,
+ data.uni_str_len * sizeof( uint16 ) );
regdb_store_values( evtlogpath, values );
}
diff --git a/source/registry/reg_printing.c b/source/registry/reg_printing.c
index b07c8e9644f..592069052f8 100644
--- a/source/registry/reg_printing.c
+++ b/source/registry/reg_printing.c
@@ -227,7 +227,16 @@ static int key_printers_fetch_keys( const char *key, REGSUBKEY_CTR *subkeys )
reg_split_path( printers_key, &printername, &printerdatakey );
- if ( find_service(printername) == -1
+ /* validate the printer name */
+
+ for (snum=0; snum<n_services; snum++) {
+ if ( !lp_snum_ok(snum) || !lp_print_ok(snum) )
+ continue;
+ if (strequal( lp_servicename(snum), printername ) )
+ break;
+ }
+
+ if ( snum>=n_services
|| !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) )
{
return -1;
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index af0062f2b39..e3cc97cdc6b 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -417,6 +417,170 @@ NTSTATUS rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
return result;
}
+/* Dsr_GetDCName */
+
+WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *server_name,
+ const char *domain_name,
+ struct uuid *domain_guid,
+ struct uuid *site_guid,
+ uint32_t flags,
+ char **dc_unc, char **dc_address,
+ int32 *dc_address_type,
+ struct uuid *domain_guid_out,
+ char **domain_name_out,
+ char **forest_name,
+ uint32 *dc_flags,
+ char **dc_site_name,
+ char **client_site_name)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_DSR_GETDCNAME q;
+ NET_R_DSR_GETDCNAME r;
+ char *tmp_str;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialize input parameters */
+
+ tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name);
+ if (tmp_str == NULL) {
+ return WERR_NOMEM;
+ }
+
+ init_net_q_dsr_getdcname(&q, tmp_str, domain_name, domain_guid,
+ site_guid, flags);
+
+ /* Marshall data and send request */
+
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAME,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_dsr_getdcname,
+ net_io_r_dsr_getdcname,
+ WERR_GENERAL_FAILURE);
+
+ if (!W_ERROR_IS_OK(r.result)) {
+ return r.result;
+ }
+
+ if (dc_unc != NULL) {
+ char *tmp;
+ if (rpcstr_pull_unistr2_talloc(mem_ctx, &tmp,
+ &r.uni_dc_unc) < 0) {
+ return WERR_GENERAL_FAILURE;
+ }
+ if (*tmp == '\\') tmp += 1;
+ if (*tmp == '\\') tmp += 1;
+
+ /* We have to talloc_strdup, otherwise a talloc_steal would
+ fail */
+ *dc_unc = talloc_strdup(mem_ctx, tmp);
+ if (*dc_unc == NULL) {
+ return WERR_NOMEM;
+ }
+ }
+
+ if (dc_address != NULL) {
+ char *tmp;
+ if (rpcstr_pull_unistr2_talloc(mem_ctx, &tmp,
+ &r.uni_dc_address) < 0) {
+ return WERR_GENERAL_FAILURE;
+ }
+ if (*tmp == '\\') tmp += 1;
+ if (*tmp == '\\') tmp += 1;
+
+ /* We have to talloc_strdup, otherwise a talloc_steal would
+ fail */
+ *dc_address = talloc_strdup(mem_ctx, tmp);
+ if (*dc_address == NULL) {
+ return WERR_NOMEM;
+ }
+ }
+
+ if (dc_address_type != NULL) {
+ *dc_address_type = r.dc_address_type;
+ }
+
+ if (domain_guid_out != NULL) {
+ *domain_guid_out = r.domain_guid;
+ }
+
+ if ((domain_name_out != NULL) &&
+ (rpcstr_pull_unistr2_talloc(mem_ctx, domain_name_out,
+ &r.uni_domain_name) < 1)) {
+ return WERR_GENERAL_FAILURE;
+ }
+
+ if ((forest_name != NULL) &&
+ (rpcstr_pull_unistr2_talloc(mem_ctx, forest_name,
+ &r.uni_forest_name) < 1)) {
+ return WERR_GENERAL_FAILURE;
+ }
+
+ if (dc_flags != NULL) {
+ *dc_flags = r.dc_flags;
+ }
+
+ if ((dc_site_name != NULL) &&
+ (rpcstr_pull_unistr2_talloc(mem_ctx, dc_site_name,
+ &r.uni_dc_site_name) < 1)) {
+ return WERR_GENERAL_FAILURE;
+ }
+
+ if ((client_site_name != NULL) &&
+ (rpcstr_pull_unistr2_talloc(mem_ctx, client_site_name,
+ &r.uni_client_site_name) < 1)) {
+ return WERR_GENERAL_FAILURE;
+ }
+
+ return WERR_OK;
+}
+
+/* Dsr_GetSiteName */
+
+WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *computer_name,
+ char **site_name)
+{
+ prs_struct qbuf, rbuf;
+ NET_Q_DSR_GETSITENAME q;
+ NET_R_DSR_GETSITENAME r;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialize input parameters */
+
+ init_net_q_dsr_getsitename(&q, computer_name);
+
+ /* Marshall data and send request */
+
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETSITENAME,
+ q, r,
+ qbuf, rbuf,
+ net_io_q_dsr_getsitename,
+ net_io_r_dsr_getsitename,
+ WERR_GENERAL_FAILURE);
+
+ if (!W_ERROR_IS_OK(r.result)) {
+ return r.result;
+ }
+
+ if ((site_name != NULL) &&
+ (rpcstr_pull_unistr2_talloc(mem_ctx, site_name,
+ &r.uni_site_name) < 1)) {
+ return WERR_GENERAL_FAILURE;
+ }
+
+ return WERR_OK;
+}
+
+
+
/* Sam synchronisation */
NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
diff --git a/source/rpc_client/cli_samr.c b/source/rpc_client/cli_samr.c
index d68c72e20c8..fb95da97aef 100644
--- a/source/rpc_client/cli_samr.c
+++ b/source/rpc_client/cli_samr.c
@@ -1205,6 +1205,95 @@ NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
return result;
}
+/* change password 3 */
+
+NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *username,
+ const char *newpassword,
+ const char *oldpassword,
+ SAM_UNK_INFO_1 **info,
+ SAMR_CHANGE_REJECT **reject)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_CHGPASSWD3 q;
+ SAMR_R_CHGPASSWD3 r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ uchar new_nt_password[516];
+ uchar new_lm_password[516];
+ uchar old_nt_hash[16];
+ uchar old_lanman_hash[16];
+ uchar old_nt_hash_enc[16];
+ uchar old_lanman_hash_enc[16];
+
+ uchar new_nt_hash[16];
+ uchar new_lanman_hash[16];
+
+ char *srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", cli->cli->desthost);
+
+ DEBUG(10,("rpccli_samr_chgpasswd3\n"));
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ *info = NULL;
+ *reject = NULL;
+
+ /* Calculate the MD4 hash (NT compatible) of the password */
+ E_md4hash(oldpassword, old_nt_hash);
+ E_md4hash(newpassword, new_nt_hash);
+
+ if (lp_client_lanman_auth()
+ && E_deshash(newpassword, new_lanman_hash)
+ && E_deshash(oldpassword, old_lanman_hash)) {
+ /* E_deshash returns false for 'long' passwords (> 14
+ DOS chars). This allows us to match Win2k, which
+ does not store a LM hash for these passwords (which
+ would reduce the effective password length to 14) */
+
+ encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
+
+ SamOEMhash( new_lm_password, old_nt_hash, 516);
+ E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
+ } else {
+ ZERO_STRUCT(new_lm_password);
+ ZERO_STRUCT(old_lanman_hash_enc);
+ }
+
+ encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
+
+ SamOEMhash( new_nt_password, old_nt_hash, 516);
+ E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
+
+ /* Marshall data and send request */
+
+ init_samr_q_chgpasswd3(&q, srv_name_slash, username,
+ new_nt_password,
+ old_nt_hash_enc,
+ new_lm_password,
+ old_lanman_hash_enc);
+
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CHGPASSWD3,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_chgpasswd3,
+ samr_io_r_chgpasswd3,
+ NT_STATUS_UNSUCCESSFUL);
+
+ /* Return output parameters */
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ *info = &r.info;
+ *reject = &r.reject;
+ goto done;
+ }
+
+ done:
+
+ return result;
+}
+
/* This function returns the bizzare set of (max_entries, max_size) required
for the QueryDisplayInfo RPC to actually work against a domain controller
with large (10k and higher) numbers of users. These values were
@@ -1723,7 +1812,7 @@ NTSTATUS rpccli_samr_query_sec_obj(struct rpc_pipe_client *cli, TALLOC_CTX *mem_
/* Get domain password info */
NTSTATUS rpccli_samr_get_dom_pwinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
- uint16 *unk_0, uint16 *unk_1)
+ uint16 *min_pwd_length, uint32 *password_properties)
{
prs_struct qbuf, rbuf;
SAMR_Q_GET_DOM_PWINFO q;
@@ -1751,10 +1840,10 @@ NTSTATUS rpccli_samr_get_dom_pwinfo(struct rpc_pipe_client *cli, TALLOC_CTX *mem
result = r.status;
if (NT_STATUS_IS_OK(result)) {
- if (unk_0)
- *unk_0 = r.unk_0;
- if (unk_1)
- *unk_1 = r.unk_1;
+ if (min_pwd_length)
+ *min_pwd_length = r.min_pwd_length;
+ if (password_properties)
+ *password_properties = r.password_properties;
}
return result;
diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c
index d924ea27d1f..3d28b657f33 100644
--- a/source/rpc_parse/parse_lsa.c
+++ b/source/rpc_parse/parse_lsa.c
@@ -3009,6 +3009,44 @@ static BOOL lsa_io_trustdom_query_4(const char *desc, TRUSTED_DOMAIN_INFO_PASSWO
/*******************************************************************
********************************************************************/
+static BOOL lsa_io_trustdom_query_6(const char *desc, TRUSTED_DOMAIN_INFO_EX *info_ex,
+ prs_struct *ps, int depth)
+{
+ uint32 dom_sid_ptr;
+
+ if (!smb_io_unihdr("domain_name_hdr", &info_ex->domain_name.hdr, ps, depth))
+ return False;
+
+ if (!smb_io_unihdr("netbios_name_hdr", &info_ex->netbios_name.hdr, ps, depth))
+ return False;
+
+ if (!prs_uint32("dom_sid_ptr", ps, depth, &dom_sid_ptr))
+ return False;
+
+ if (!prs_uint32("trust_direction", ps, depth, &info_ex->trust_direction))
+ return False;
+
+ if (!prs_uint32("trust_type", ps, depth, &info_ex->trust_type))
+ return False;
+
+ if (!prs_uint32("trust_attributes", ps, depth, &info_ex->trust_attributes))
+ return False;
+
+ if (!smb_io_unistr2("domain_name_unistring", &info_ex->domain_name.unistring, info_ex->domain_name.hdr.buffer, ps, depth))
+ return False;
+
+ if (!smb_io_unistr2("netbios_name_unistring", &info_ex->netbios_name.unistring, info_ex->netbios_name.hdr.buffer, ps, depth))
+ return False;
+
+ if (!smb_io_dom_sid2("sid", &info_ex->sid, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+
static BOOL lsa_io_trustdom_query(const char *desc, prs_struct *ps, int depth, LSA_TRUSTED_DOMAIN_INFO *info)
{
prs_debug(ps, depth, desc, "lsa_io_trustdom_query");
@@ -3033,6 +3071,10 @@ static BOOL lsa_io_trustdom_query(const char *desc, prs_struct *ps, int depth, L
if(!lsa_io_trustdom_query_4("password", &info->password, ps, depth))
return False;
break;
+ case 6:
+ if(!lsa_io_trustdom_query_6("info_ex", &info->info_ex, ps, depth))
+ return False;
+ break;
default:
DEBUG(0,("unsupported info-level: %d\n", info->info_class));
return False;
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index a32edd43841..ce2a085f478 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -3153,3 +3153,311 @@ BOOL net_io_r_sam_deltas(const char *desc,
return True;
}
+
+/*******************************************************************
+ Inits a NET_Q_DSR_GETDCNAME structure.
+********************************************************************/
+
+void init_net_q_dsr_getdcname(NET_Q_DSR_GETDCNAME *r_t, const char *server_unc,
+ const char *domain_name,
+ struct uuid *domain_guid,
+ struct uuid *site_guid,
+ uint32_t flags)
+{
+ DEBUG(5, ("init_net_q_dsr_getdcname\n"));
+
+ r_t->ptr_server_unc = (server_unc != NULL);
+ init_unistr2(&r_t->uni_server_unc, server_unc, UNI_STR_TERMINATE);
+
+ r_t->ptr_domain_name = (domain_name != NULL);
+ init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE);
+
+ r_t->ptr_domain_guid = (domain_guid != NULL);
+ r_t->domain_guid = domain_guid;
+
+ r_t->ptr_site_guid = (site_guid != NULL);
+ r_t->site_guid = site_guid;
+
+ r_t->flags = flags;
+}
+
+/*******************************************************************
+ Reads or writes an NET_Q_DSR_GETDCNAME structure.
+********************************************************************/
+
+BOOL net_io_q_dsr_getdcname(const char *desc, NET_Q_DSR_GETDCNAME *r_t,
+ prs_struct *ps, int depth)
+{
+ if (r_t == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "net_io_q_dsr_getdcname");
+ depth++;
+
+ if (!prs_uint32("ptr_server_unc", ps, depth, &r_t->ptr_server_unc))
+ return False;
+
+ if (!smb_io_unistr2("server_unc", &r_t->uni_server_unc,
+ r_t->ptr_server_unc, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name))
+ return False;
+
+ if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name,
+ r_t->ptr_domain_name, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("ptr_domain_guid", ps, depth, &r_t->ptr_domain_guid))
+ return False;
+
+ if (UNMARSHALLING(ps) && (r_t->ptr_domain_guid)) {
+ r_t->domain_guid = PRS_ALLOC_MEM(ps, struct uuid, 1);
+ if (r_t->domain_guid == NULL)
+ return False;
+ }
+
+ if ((r_t->ptr_domain_guid) &&
+ (!smb_io_uuid("domain_guid", r_t->domain_guid, ps, depth)))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("ptr_site_guid", ps, depth, &r_t->ptr_site_guid))
+ return False;
+
+ if (UNMARSHALLING(ps) && (r_t->ptr_site_guid)) {
+ r_t->site_guid = PRS_ALLOC_MEM(ps, struct uuid, 1);
+ if (r_t->site_guid == NULL)
+ return False;
+ }
+
+ if ((r_t->ptr_site_guid) &&
+ (!smb_io_uuid("site_guid", r_t->site_guid, ps, depth)))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_uint32("flags", ps, depth, &r_t->flags))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Inits a NET_R_DSR_GETDCNAME structure.
+********************************************************************/
+void init_net_r_dsr_getdcname(NET_R_DSR_GETDCNAME *r_t, const char *dc_unc,
+ const char *dc_address, int32 dc_address_type,
+ struct uuid domain_guid, const char *domain_name,
+ const char *forest_name, uint32 dc_flags,
+ const char *dc_site_name,
+ const char *client_site_name)
+{
+ DEBUG(5, ("init_net_q_dsr_getdcname\n"));
+
+ r_t->ptr_dc_unc = (dc_unc != NULL);
+ init_unistr2(&r_t->uni_dc_unc, dc_unc, UNI_STR_TERMINATE);
+
+ r_t->ptr_dc_address = (dc_address != NULL);
+ init_unistr2(&r_t->uni_dc_address, dc_address, UNI_STR_TERMINATE);
+
+ r_t->dc_address_type = dc_address_type;
+ r_t->domain_guid = domain_guid;
+
+ r_t->ptr_domain_name = (domain_name != NULL);
+ init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE);
+
+ r_t->ptr_forest_name = (forest_name != NULL);
+ init_unistr2(&r_t->uni_forest_name, forest_name, UNI_STR_TERMINATE);
+
+ r_t->dc_flags = dc_flags;
+
+ r_t->ptr_dc_site_name = (dc_site_name != NULL);
+ init_unistr2(&r_t->uni_dc_site_name, dc_site_name, UNI_STR_TERMINATE);
+
+ r_t->ptr_client_site_name = (client_site_name != NULL);
+ init_unistr2(&r_t->uni_client_site_name, client_site_name,
+ UNI_STR_TERMINATE);
+}
+
+/*******************************************************************
+ Reads or writes an NET_R_DSR_GETDCNAME structure.
+********************************************************************/
+
+BOOL net_io_r_dsr_getdcname(const char *desc, NET_R_DSR_GETDCNAME *r_t,
+ prs_struct *ps, int depth)
+{
+ uint32 info_ptr = 1;
+
+ if (r_t == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "net_io_r_dsr_getdcname");
+ depth++;
+
+ /* The reply contains *just* an info struct, this is the ptr to it */
+ if (!prs_uint32("info_ptr", ps, depth, &info_ptr))
+ return False;
+
+ if (info_ptr == 0)
+ return False;
+
+ if (!prs_uint32("ptr_dc_unc", ps, depth, &r_t->ptr_dc_unc))
+ return False;
+
+ if (!prs_uint32("ptr_dc_address", ps, depth, &r_t->ptr_dc_address))
+ return False;
+
+ if (!prs_uint32("dc_address_type", ps, depth, &r_t->dc_address_type))
+ return False;
+
+ if (!smb_io_uuid("domain_guid", &r_t->domain_guid, ps, depth))
+ return False;
+
+ if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name))
+ return False;
+
+ if (!prs_uint32("ptr_forest_name", ps, depth, &r_t->ptr_forest_name))
+ return False;
+
+ if (!prs_uint32("dc_flags", ps, depth, &r_t->dc_flags))
+ return False;
+
+ if (!prs_uint32("ptr_dc_site_name", ps, depth, &r_t->ptr_dc_site_name))
+ return False;
+
+ if (!prs_uint32("ptr_client_site_name", ps, depth,
+ &r_t->ptr_client_site_name))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!smb_io_unistr2("dc_unc", &r_t->uni_dc_unc,
+ r_t->ptr_dc_unc, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!smb_io_unistr2("dc_address", &r_t->uni_dc_address,
+ r_t->ptr_dc_address, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name,
+ r_t->ptr_domain_name, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!smb_io_unistr2("forest_name", &r_t->uni_forest_name,
+ r_t->ptr_forest_name, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!smb_io_unistr2("dc_site_name", &r_t->uni_dc_site_name,
+ r_t->ptr_dc_site_name, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!smb_io_unistr2("client_site_name", &r_t->uni_client_site_name,
+ r_t->ptr_client_site_name, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_werror("result", ps, depth, &r_t->result))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Inits a NET_Q_DSR_GETSITENAME structure.
+********************************************************************/
+
+void init_net_q_dsr_getsitename(NET_Q_DSR_GETSITENAME *r_t, const char *computer_name)
+{
+ DEBUG(5, ("init_net_q_dsr_getsitename\n"));
+
+ r_t->ptr_computer_name = (computer_name != NULL);
+ init_unistr2(&r_t->uni_computer_name, computer_name, UNI_STR_TERMINATE);
+}
+
+/*******************************************************************
+ Reads or writes an NET_Q_DSR_GETSITENAME structure.
+********************************************************************/
+
+BOOL net_io_q_dsr_getsitename(const char *desc, NET_Q_DSR_GETSITENAME *r_t,
+ prs_struct *ps, int depth)
+{
+ if (r_t == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "net_io_q_dsr_getsitename");
+ depth++;
+
+ if (!prs_uint32("ptr_computer_name", ps, depth, &r_t->ptr_computer_name))
+ return False;
+
+ if (!smb_io_unistr2("computer_name", &r_t->uni_computer_name,
+ r_t->ptr_computer_name, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes an NET_R_DSR_GETSITENAME structure.
+********************************************************************/
+
+BOOL net_io_r_dsr_getsitename(const char *desc, NET_R_DSR_GETSITENAME *r_t,
+ prs_struct *ps, int depth)
+{
+ if (r_t == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "net_io_r_dsr_getsitename");
+ depth++;
+
+ if (!prs_uint32("ptr_site_name", ps, depth, &r_t->ptr_site_name))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!smb_io_unistr2("site_name", &r_t->uni_site_name,
+ r_t->ptr_site_name, ps, depth))
+ return False;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (!prs_werror("result", ps, depth, &r_t->result))
+ return False;
+
+ return True;
+}
+
+
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index 2ba99fff495..0a055ff826a 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -778,11 +778,11 @@ inits a structure.
********************************************************************/
void init_unk_info1(SAM_UNK_INFO_1 *u_1, uint16 min_pass_len, uint16 pass_hist,
- uint32 flag, NTTIME nt_expire, NTTIME nt_min_age)
+ uint32 password_properties, NTTIME nt_expire, NTTIME nt_min_age)
{
u_1->min_length_password = min_pass_len;
u_1->password_history = pass_hist;
- u_1->flag = flag;
+ u_1->password_properties = password_properties;
/* password never expire */
u_1->expire.high = nt_expire.high;
@@ -811,7 +811,7 @@ static BOOL sam_io_unk_info1(const char *desc, SAM_UNK_INFO_1 * u_1,
return False;
if(!prs_uint16("password_history", ps, depth, &u_1->password_history))
return False;
- if(!prs_uint32("flag", ps, depth, &u_1->flag))
+ if(!prs_uint32("password_properties", ps, depth, &u_1->password_properties))
return False;
if(!smb_io_time("expire", &u_1->expire, ps, depth))
return False;
@@ -6734,7 +6734,7 @@ inits a SAMR_Q_CONNECT4 structure.
void init_samr_q_connect4(SAMR_Q_CONNECT4 * q_u,
char *srv_name, uint32 access_mask)
{
- DEBUG(5, ("init_samr_q_connect\n"));
+ DEBUG(5, ("init_samr_q_connect4\n"));
/* make PDC server name \\server */
q_u->ptr_srv_name = (srv_name != NULL && *srv_name) ? 1 : 0;
@@ -6804,6 +6804,116 @@ BOOL samr_io_r_connect4(const char *desc, SAMR_R_CONNECT4 * r_u,
}
/*******************************************************************
+inits a SAMR_Q_CONNECT5 structure.
+********************************************************************/
+
+void init_samr_q_connect5(SAMR_Q_CONNECT5 * q_u,
+ char *srv_name, uint32 access_mask)
+{
+ DEBUG(5, ("init_samr_q_connect5\n"));
+
+ /* make PDC server name \\server */
+ q_u->ptr_srv_name = (srv_name != NULL && *srv_name) ? 1 : 0;
+ init_unistr2(&q_u->uni_srv_name, srv_name, UNI_STR_TERMINATE);
+
+ /* example values: 0x0000 0002 */
+ q_u->access_mask = access_mask;
+
+ q_u->level = 1;
+ q_u->info1_unk1 = 3;
+ q_u->info1_unk2 = 0;
+}
+
+/*******************************************************************
+inits a SAMR_R_CONNECT5 structure.
+********************************************************************/
+
+void init_samr_r_connect5(SAMR_R_CONNECT5 * r_u, POLICY_HND *pol, NTSTATUS status)
+{
+ DEBUG(5, ("init_samr_q_connect5\n"));
+
+ r_u->level = 1;
+ r_u->info1_unk1 = 3;
+ r_u->info1_unk2 = 0;
+
+ r_u->connect_pol = *pol;
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_q_connect5(const char *desc, SAMR_Q_CONNECT5 * q_u,
+ prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_connect5");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
+ return False;
+ if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+ if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
+ return False;
+
+ if(!prs_uint32("level", ps, depth, &q_u->level))
+ return False;
+ if(!prs_uint32("level", ps, depth, &q_u->level))
+ return False;
+
+ if(!prs_uint32("info1_unk1", ps, depth, &q_u->info1_unk1))
+ return False;
+ if(!prs_uint32("info1_unk2", ps, depth, &q_u->info1_unk2))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_r_connect5(const char *desc, SAMR_R_CONNECT5 * r_u,
+ prs_struct *ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_connect5");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("level", ps, depth, &r_u->level))
+ return False;
+ if(!prs_uint32("level", ps, depth, &r_u->level))
+ return False;
+ if(!prs_uint32("info1_unk1", ps, depth, &r_u->info1_unk1))
+ return False;
+ if(!prs_uint32("info1_unk2", ps, depth, &r_u->info1_unk2))
+ return False;
+
+ if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
inits a SAMR_Q_CONNECT_ANON structure.
********************************************************************/
@@ -6928,15 +7038,11 @@ BOOL samr_io_r_get_dom_pwinfo(const char *desc, SAMR_R_GET_DOM_PWINFO * r_u,
if(!prs_align(ps))
return False;
- /*
- * see the Samba4 IDL for what these actually are.
- */
-
- if(!prs_uint16("unk_0", ps, depth, &r_u->unk_0))
+ if(!prs_uint16("min_pwd_length", ps, depth, &r_u->min_pwd_length))
return False;
if(!prs_align(ps))
return False;
- if(!prs_uint32("unk_1", ps, depth, &r_u->unk_1))
+ if(!prs_uint32("password_properties", ps, depth, &r_u->password_properties))
return False;
if(!prs_ntstatus("status", ps, depth, &r_u->status))
@@ -7031,7 +7137,7 @@ BOOL samr_io_enc_hash(const char *desc, SAMR_ENC_HASH * hsh,
}
/*******************************************************************
-inits a SAMR_R_GET_DOM_PWINFO structure.
+inits a SAMR_Q_CHGPASSWD_USER structure.
********************************************************************/
void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER * q_u,
@@ -7140,6 +7246,172 @@ BOOL samr_io_r_chgpasswd_user(const char *desc, SAMR_R_CHGPASSWD_USER * r_u,
}
/*******************************************************************
+inits a SAMR_Q_CHGPASSWD3 structure.
+********************************************************************/
+
+void init_samr_q_chgpasswd3(SAMR_Q_CHGPASSWD3 * q_u,
+ const char *dest_host, const char *user_name,
+ const uchar nt_newpass[516],
+ const uchar nt_oldhash[16],
+ const uchar lm_newpass[516],
+ const uchar lm_oldhash[16])
+{
+ DEBUG(5, ("init_samr_q_chgpasswd3\n"));
+
+ q_u->ptr_0 = 1;
+ init_unistr2(&q_u->uni_dest_host, dest_host, UNI_FLAGS_NONE);
+ init_uni_hdr(&q_u->hdr_dest_host, &q_u->uni_dest_host);
+
+ init_unistr2(&q_u->uni_user_name, user_name, UNI_FLAGS_NONE);
+ init_uni_hdr(&q_u->hdr_user_name, &q_u->uni_user_name);
+
+ init_enc_passwd(&q_u->nt_newpass, (const char *)nt_newpass);
+ init_enc_hash(&q_u->nt_oldhash, nt_oldhash);
+
+ q_u->lm_change = 0x01;
+
+ init_enc_passwd(&q_u->lm_newpass, (const char *)lm_newpass);
+ init_enc_hash(&q_u->lm_oldhash, lm_oldhash);
+
+ init_enc_passwd(&q_u->password3, NULL);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_q_chgpasswd3(const char *desc, SAMR_Q_CHGPASSWD3 * q_u,
+ prs_struct *ps, int depth)
+{
+ if (q_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_chgpasswd3");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("ptr_0", ps, depth, &q_u->ptr_0))
+ return False;
+
+ if(!smb_io_unihdr("", &q_u->hdr_dest_host, ps, depth))
+ return False;
+ if(!smb_io_unistr2("", &q_u->uni_dest_host, q_u->hdr_dest_host.buffer, ps, depth))
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+ if(!smb_io_unihdr("", &q_u->hdr_user_name, ps, depth))
+ return False;
+ if(!smb_io_unistr2("", &q_u->uni_user_name, q_u->hdr_user_name.buffer,ps, depth))
+ return False;
+
+ if(!samr_io_enc_passwd("nt_newpass", &q_u->nt_newpass, ps, depth))
+ return False;
+ if(!samr_io_enc_hash("nt_oldhash", &q_u->nt_oldhash, ps, depth))
+ return False;
+
+ if(!prs_uint32("lm_change", ps, depth, &q_u->lm_change))
+ return False;
+
+ if(!samr_io_enc_passwd("lm_newpass", &q_u->lm_newpass, ps, depth))
+ return False;
+ if(!samr_io_enc_hash("lm_oldhash", &q_u->lm_oldhash, ps, depth))
+ return False;
+
+ if(!samr_io_enc_passwd("password3", &q_u->password3, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+inits a SAMR_R_CHGPASSWD3 structure.
+********************************************************************/
+
+void init_samr_r_chgpasswd3(SAMR_R_CHGPASSWD3 * r_u, NTSTATUS status)
+{
+ DEBUG(5, ("init_r_chgpasswd3\n"));
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+ Reads or writes an SAMR_CHANGE_REJECT structure.
+********************************************************************/
+
+BOOL samr_io_change_reject(const char *desc, SAMR_CHANGE_REJECT *reject, prs_struct *ps, int depth)
+{
+ if (reject == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_change_reject");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(UNMARSHALLING(ps))
+ ZERO_STRUCTP(reject);
+
+ if (!prs_uint32("reject_reason", ps, depth, &reject->reject_reason))
+ return False;
+
+ if (!prs_uint32("unknown1", ps, depth, &reject->unknown1))
+ return False;
+
+ if (!prs_uint32("unknown2", ps, depth, &reject->unknown2))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_r_chgpasswd3(const char *desc, SAMR_R_CHGPASSWD3 * r_u,
+ prs_struct *ps, int depth)
+{
+ uint32 ptr_info, ptr_reject;
+
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_chgpasswd3");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint32("ptr_info", ps, depth, &ptr_info))
+ return False;
+
+ if (ptr_info) {
+
+ /* SAM_UNK_INFO_1 */
+ if(!sam_io_unk_info1("info", &r_u->info, ps, depth))
+ return False;
+ }
+
+ if(!prs_uint32("ptr_reject", ps, depth, &ptr_reject))
+ return False;
+
+ if (ptr_reject) {
+
+ /* SAMR_CHANGE_REJECT */
+ if(!samr_io_change_reject("reject", &r_u->reject, ps, depth))
+ return False;
+ }
+
+ if(!prs_ntstatus("status", ps, depth, &r_u->status))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
reads or writes a structure.
********************************************************************/
diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c
index 7903adff6d5..d0d47be9f29 100644
--- a/source/rpc_server/srv_netlog_nt.c
+++ b/source/rpc_server/srv_netlog_nt.c
@@ -584,6 +584,35 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF
}
+/*******************************************************************
+ gets a domain user's groups from their already-calculated NT_USER_TOKEN
+ ********************************************************************/
+static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
+ const NT_USER_TOKEN *nt_token,
+ int *numgroups, DOM_GID **pgids)
+{
+ DOM_GID *gids;
+ int i;
+
+ gids = TALLOC_ARRAY(mem_ctx, DOM_GID, nt_token->num_sids);
+
+ if (!gids) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *numgroups=0;
+
+ for (i=PRIMARY_GROUP_SID_INDEX; i < nt_token->num_sids; i++) {
+ if (sid_compare_domain(domain_sid, &nt_token->user_sids[i])==0) {
+ sid_peek_rid(&nt_token->user_sids[i], &(gids[*numgroups].g_rid));
+ gids[*numgroups].attr= (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_ENABLED);
+ (*numgroups)++;
+ }
+ }
+ *pgids = gids;
+ return NT_STATUS_OK;
+}
+
/*************************************************************************
_net_sam_logon
*************************************************************************/
diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c
index b615080d349..8084e7673a5 100644
--- a/source/rpc_server/srv_pipe.c
+++ b/source/rpc_server/srv_pipe.c
@@ -892,6 +892,55 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
return True;
}
+#if 0
+/*******************************************************************
+ Marshall a cancel_ack pdu.
+ We should probably check the auth-verifier here.
+*******************************************************************/
+
+BOOL setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p)
+{
+ prs_struct outgoing_pdu;
+ RPC_HDR ack_reply_hdr;
+
+ /* Free any memory in the current return data buffer. */
+ prs_mem_free(&p->out_data.rdata);
+
+ /*
+ * Marshall directly into the outgoing PDU space. We
+ * must do this as we need to set to the bind response
+ * header and are never sending more than one PDU here.
+ */
+
+ prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
+ prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
+
+ /*
+ * Initialize a cancel_ack header.
+ */
+
+ init_rpc_hdr(&ack_reply_hdr, RPC_CANCEL_ACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+ p->hdr.call_id, RPC_HEADER_LEN, 0);
+
+ /*
+ * Marshall the header into the outgoing PDU.
+ */
+
+ if(!smb_io_rpc_hdr("", &ack_reply_hdr, &outgoing_pdu, 0)) {
+ DEBUG(0,("setup_cancel_ack_reply: marshalling of RPC_HDR failed.\n"));
+ prs_mem_free(&outgoing_pdu);
+ return False;
+ }
+
+ p->out_data.data_sent_length = 0;
+ p->out_data.current_pdu_len = prs_offset(&outgoing_pdu);
+ p->out_data.current_pdu_sent = 0;
+
+ prs_mem_free(&outgoing_pdu);
+ return True;
+}
+#endif
+
/*******************************************************************
Ensure a bind request has the correct abstract & transfer interface.
Used to reject unknown binds from Win2k.
diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index 6077faed164..5fb84115cc3 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/rpc_server/srv_pipe_hnd.c
@@ -716,6 +716,32 @@ static void process_complete_pdu(pipes_struct *p)
(unsigned int)p->hdr.pkt_type ));
switch (p->hdr.pkt_type) {
+ case RPC_REQUEST:
+ reply = process_request_pdu(p, &rpc_in);
+ break;
+
+ case RPC_PING: /* CL request - ignore... */
+ DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
+ (unsigned int)p->hdr.pkt_type, p->name));
+ break;
+
+ case RPC_RESPONSE: /* No responses here. */
+ DEBUG(0,("process_complete_pdu: Error. RPC_RESPONSE received from client on pipe %s.\n",
+ p->name ));
+ break;
+
+ case RPC_FAULT:
+ case RPC_WORKING: /* CL request - reply to a ping when a call in process. */
+ case RPC_NOCALL: /* CL - server reply to a ping call. */
+ case RPC_REJECT:
+ case RPC_ACK:
+ case RPC_CL_CANCEL:
+ case RPC_FACK:
+ case RPC_CANCEL_ACK:
+ DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
+ (unsigned int)p->hdr.pkt_type, p->name));
+ break;
+
case RPC_BIND:
/*
* We assume that a pipe bind is only in one pdu.
@@ -724,6 +750,14 @@ static void process_complete_pdu(pipes_struct *p)
reply = api_pipe_bind_req(p, &rpc_in);
}
break;
+
+ case RPC_BINDACK:
+ case RPC_BINDNACK:
+ DEBUG(0,("process_complete_pdu: Error. RPC_BINDACK/RPC_BINDNACK packet type %u received on pipe %s.\n",
+ (unsigned int)p->hdr.pkt_type, p->name));
+ break;
+
+
case RPC_ALTCONT:
/*
* We assume that a pipe bind is only in one pdu.
@@ -732,6 +766,12 @@ static void process_complete_pdu(pipes_struct *p)
reply = api_pipe_alter_context(p, &rpc_in);
}
break;
+
+ case RPC_ALTCONTRESP:
+ DEBUG(0,("process_complete_pdu: Error. RPC_ALTCONTRESP on pipe %s: Should only be server -> client.\n",
+ p->name));
+ break;
+
case RPC_AUTH3:
/*
* The third packet in an NTLMSSP auth exchange.
@@ -740,9 +780,38 @@ static void process_complete_pdu(pipes_struct *p)
reply = api_pipe_bind_auth3(p, &rpc_in);
}
break;
- case RPC_REQUEST:
- reply = process_request_pdu(p, &rpc_in);
+
+ case RPC_SHUTDOWN:
+ DEBUG(0,("process_complete_pdu: Error. RPC_SHUTDOWN on pipe %s: Should only be server -> client.\n",
+ p->name));
+ break;
+
+ case RPC_CO_CANCEL:
+ /* For now just free all client data and continue processing. */
+ DEBUG(3,("process_complete_pdu: RPC_ORPHANED. Abandoning rpc call.\n"));
+ /* As we never do asynchronous RPC serving, we can never cancel a
+ call (as far as I know). If we ever did we'd have to send a cancel_ack
+ reply. For now, just free all client data and continue processing. */
+ reply = True;
break;
+#if 0
+ /* Enable this if we're doing async rpc. */
+ /* We must check the call-id matches the outstanding callid. */
+ if(pipe_init_outgoing_data(p)) {
+ /* Send a cancel_ack PDU reply. */
+ /* We should probably check the auth-verifier here. */
+ reply = setup_cancel_ack_reply(p, &rpc_in);
+ }
+ break;
+#endif
+
+ case RPC_ORPHANED:
+ /* We should probably check the auth-verifier here.
+ For now just free all client data and continue processing. */
+ DEBUG(3,("process_complete_pdu: RPC_ORPHANED. Abandoning rpc call.\n"));
+ reply = True;
+ break;
+
default:
DEBUG(0,("process_complete_pdu: Unknown rpc type = %u received.\n", (unsigned int)p->hdr.pkt_type ));
break;
@@ -815,7 +884,13 @@ incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned
*/
if(p->in_data.pdu_needed_len == 0) {
- return unmarshall_rpc_header(p);
+ ssize_t rret = unmarshall_rpc_header(p);
+ if (rret == -1 || p->in_data.pdu_needed_len > 0) {
+ return rret;
+ }
+ /* If rret == 0 and pdu_needed_len == 0 here we have a PDU that consists
+ of an RPC_HEADER only. This is a RPC_SHUTDOWN, RPC_CO_CANCEL or RPC_ORPHANED
+ pdu type. Deal with this in process_complete_pdu(). */
}
/*
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index 4d44f8312b3..8f981dc41d4 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -5,11 +5,12 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Marc Jacobsen 1999,
- * Copyright (C) Jeremy Allison 2001-2002,
+ * Copyright (C) Jeremy Allison 2001-2005,
* Copyright (C) Jean François Micouleau 1998-2001,
* Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
* Copyright (C) Gerald (Jerry) Carter 2003-2004,
* Copyright (C) Simo Sorce 2003.
+ * Copyright (C) Volker Lendecke 2005.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -46,15 +47,16 @@ typedef struct disp_info {
struct disp_info *next, *prev;
TALLOC_CTX *mem_ctx;
DOM_SID sid; /* identify which domain this is. */
+ BOOL builtin_domain; /* Quick flag to check if this is the builtin domain. */
struct pdb_search *users; /* querydispinfo 1 and 4 */
struct pdb_search *machines; /* querydispinfo 2 */
struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
struct pdb_search *aliases; /* enumaliases */
- struct pdb_search *builtins; /* enumaliases */
uint16 enum_acb_mask;
struct pdb_search *enum_users; /* enumusers with a mask */
+
smb_event_id_t di_cache_timeout_event; /* cache idle timeout handler. */
} DISP_INFO;
@@ -66,19 +68,38 @@ static DISP_INFO *disp_info_list;
struct samr_info {
/* for use by the \PIPE\samr policy */
DOM_SID sid;
+ BOOL builtin_domain; /* Quick flag to check if this is the builtin domain. */
uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
uint32 acc_granted;
- uint16 acb_mask;
- BOOL only_machines;
DISP_INFO *disp_info;
TALLOC_CTX *mem_ctx;
};
-struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
-struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
-struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
-struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
-struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
+static struct generic_mapping sam_generic_mapping = {
+ GENERIC_RIGHTS_SAM_READ,
+ GENERIC_RIGHTS_SAM_WRITE,
+ GENERIC_RIGHTS_SAM_EXECUTE,
+ GENERIC_RIGHTS_SAM_ALL_ACCESS};
+static struct generic_mapping dom_generic_mapping = {
+ GENERIC_RIGHTS_DOMAIN_READ,
+ GENERIC_RIGHTS_DOMAIN_WRITE,
+ GENERIC_RIGHTS_DOMAIN_EXECUTE,
+ GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
+static struct generic_mapping usr_generic_mapping = {
+ GENERIC_RIGHTS_USER_READ,
+ GENERIC_RIGHTS_USER_WRITE,
+ GENERIC_RIGHTS_USER_EXECUTE,
+ GENERIC_RIGHTS_USER_ALL_ACCESS};
+static struct generic_mapping grp_generic_mapping = {
+ GENERIC_RIGHTS_GROUP_READ,
+ GENERIC_RIGHTS_GROUP_WRITE,
+ GENERIC_RIGHTS_GROUP_EXECUTE,
+ GENERIC_RIGHTS_GROUP_ALL_ACCESS};
+static struct generic_mapping ali_generic_mapping = {
+ GENERIC_RIGHTS_ALIAS_READ,
+ GENERIC_RIGHTS_ALIAS_WRITE,
+ GENERIC_RIGHTS_ALIAS_EXECUTE,
+ GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
/*******************************************************************
*******************************************************************/
@@ -247,8 +268,12 @@ static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid, const char *sid_str)
return NULL;
dpi->mem_ctx = mem_ctx;
+
if (psid) {
sid_copy( &dpi->sid, psid);
+ dpi->builtin_domain = sid_check_is_builtin(psid);
+ } else {
+ dpi->builtin_domain = False;
}
DLIST_ADD(disp_info_list, dpi);
@@ -280,8 +305,10 @@ static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
if (psid) {
sid_copy( &info->sid, psid);
+ info->builtin_domain = sid_check_is_builtin(psid);
} else {
DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
+ info->builtin_domain = False;
}
info->mem_ctx = mem_ctx;
@@ -328,11 +355,6 @@ static void free_samr_cache(DISP_INFO *disp_info, const char *sid_str)
pdb_search_destroy(disp_info->aliases);
disp_info->aliases = NULL;
}
- if (disp_info->builtins) {
- DEBUG(10,("free_samr_cache: deleting builtins cache\n"));
- pdb_search_destroy(disp_info->builtins);
- disp_info->builtins = NULL;
- }
if (disp_info->enum_users) {
DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
pdb_search_destroy(disp_info->enum_users);
@@ -452,6 +474,12 @@ static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
static uint32 count_sam_users(struct disp_info *info, uint16 acct_flags)
{
struct samr_displayentry *entry;
+
+ if (info->builtin_domain) {
+ /* No users in builtin. */
+ return 0;
+ }
+
if (info->users == NULL) {
info->users = pdb_search_users(acct_flags);
if (info->users == NULL) {
@@ -470,6 +498,12 @@ static uint32 count_sam_users(struct disp_info *info, uint16 acct_flags)
static uint32 count_sam_groups(struct disp_info *info)
{
struct samr_displayentry *entry;
+
+ if (info->builtin_domain) {
+ /* No groups in builtin. */
+ return 0;
+ }
+
if (info->groups == NULL) {
info->groups = pdb_search_groups();
if (info->groups == NULL) {
@@ -485,6 +519,25 @@ static uint32 count_sam_groups(struct disp_info *info)
return info->groups->num_entries;
}
+static uint32 count_sam_aliases(struct disp_info *info)
+{
+ struct samr_displayentry *entry;
+
+ if (info->aliases == NULL) {
+ info->aliases = pdb_search_aliases(&info->sid);
+ if (info->aliases == NULL) {
+ return 0;
+ }
+ }
+ /* Fetch the last possible entry, thus trigger an enumeration */
+ pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
+
+ /* Ensure we cache this enumeration. */
+ set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
+
+ return info->aliases->num_entries;
+}
+
/*******************************************************************
_samr_close_hnd
********************************************************************/
@@ -544,6 +597,11 @@ NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN
if ( !NT_STATUS_IS_OK(status) )
return status;
+ if (!sid_check_is_domain(&q_u->dom_sid.sid) &&
+ !sid_check_is_builtin(&q_u->dom_sid.sid)) {
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+
/* associate the domain SID with the (unique) handle. */
if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
return NT_STATUS_NO_MEMORY;
@@ -756,6 +814,13 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
+ if (info->builtin_domain) {
+ /* No users in builtin. */
+ init_samr_r_enum_dom_users(r_u, q_u->start_idx, 0);
+ DEBUG(5,("_samr_enum_dom_users: No users in BUILTIN\n"));
+ return r_u->status;
+ }
+
become_root();
/* AS ROOT !!!! */
@@ -882,6 +947,13 @@ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAM
DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
+ if (info->builtin_domain) {
+ /* No groups in builtin. */
+ init_samr_r_enum_dom_groups(r_u, q_u->start_idx, 0);
+ DEBUG(5,("_samr_enum_dom_users: No groups in BUILTIN\n"));
+ return r_u->status;
+ }
+
/* the domain group array is being allocated in the function below */
become_root();
@@ -920,7 +992,6 @@ NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, S
{
struct samr_info *info;
struct samr_displayentry *aliases;
- struct pdb_search **search = NULL;
uint32 num_aliases = 0;
/* find the policy handle. open a policy on it. */
@@ -936,25 +1007,17 @@ NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, S
DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n",
sid_string_static(&info->sid)));
- if (sid_check_is_domain(&info->sid))
- search = &info->disp_info->aliases;
- if (sid_check_is_builtin(&info->sid))
- search = &info->disp_info->builtins;
-
- if (search == NULL)
- return NT_STATUS_INVALID_HANDLE;
-
become_root();
- if (*search == NULL) {
- *search = pdb_search_aliases(&info->sid);
- if (*search == NULL) {
+ if (info->disp_info->aliases == NULL) {
+ info->disp_info->aliases = pdb_search_aliases(&info->sid);
+ if (info->disp_info->aliases == NULL) {
unbecome_root();
return NT_STATUS_ACCESS_DENIED;
}
}
- num_aliases = pdb_search_entries(*search, q_u->start_idx,
+ num_aliases = pdb_search_entries(info->disp_info->aliases, q_u->start_idx,
MAX_SAM_ENTRIES, &aliases);
unbecome_root();
@@ -1493,19 +1556,11 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK
if ((num_rids != 0) && ((names == NULL) || (attrs == NULL)))
return NT_STATUS_NO_MEMORY;
- if (!sid_equal(&pol_sid, get_global_sam_sid())) {
- /* TODO: Sooner or later we need to look up BUILTIN rids as
- * well. -- vl */
- goto done;
- }
-
become_root(); /* lookup_sid can require root privs */
- r_u->status = pdb_lookup_rids(p->mem_ctx, &pol_sid, num_rids, q_u->rid,
- &names, &attrs);
+ r_u->status = pdb_lookup_rids(&pol_sid, num_rids, q_u->rid,
+ names, attrs);
unbecome_root();
- done:
-
if(!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
&hdr_name, &uni_name))
return NT_STATUS_NO_MEMORY;
@@ -2081,9 +2136,9 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
/* AS ROOT !!! */
- num_users=count_sam_users(info->disp_info,
- ACB_NORMAL);
- num_groups=count_sam_groups(info->disp_info);
+ num_users = count_sam_users(info->disp_info, ACB_NORMAL);
+ num_groups = count_sam_groups(info->disp_info);
+ num_aliases = count_sam_aliases(info->disp_info);
pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
u_logout = account_policy_temp;
@@ -4623,9 +4678,9 @@ NTSTATUS _samr_query_domain_info2(pipes_struct *p,
break;
case 0x02:
become_root();
- num_users = count_sam_users(info->disp_info,
- ACB_NORMAL);
+ num_users = count_sam_users(info->disp_info, ACB_NORMAL);
num_groups = count_sam_groups(info->disp_info);
+ num_aliases = count_sam_aliases(info->disp_info);
unbecome_root();
pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
@@ -4725,7 +4780,7 @@ NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R
pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
- pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
+ pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.password_properties);
pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
break;
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index e5b3ca3947d..f0ba863b4d7 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -479,29 +479,30 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
DEBUGADD(5, ("searching for [%s]\n", aprinter ));
/* Search all sharenames first as this is easier than pulling
- the printer_info_2 off of disk */
+ the printer_info_2 off of disk. Don't use find_service() since
+ that calls out to map_username() */
- snum = find_service(aprinter);
-
- if ( lp_snum_ok(snum) && lp_print_ok(snum) ) {
- found = True;
- fstrcpy( sname, aprinter );
- }
-
/* do another loop to look for printernames */
for (snum=0; !found && snum<n_services; snum++) {
- /* no point in checking if this is not a printer or
- we aren't allowing printername != sharename */
+ /* no point going on if this is not a printer */
- if ( !(lp_snum_ok(snum)
- && lp_print_ok(snum)
- && !lp_force_printername(snum)) )
- {
+ if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
continue;
+
+ fstrcpy(sname, lp_servicename(snum));
+ if ( strequal( aprinter, sname ) ) {
+ found = True;
+ break;
}
+
+ /* no point looking up the printer object if
+ we aren't allowing printername != sharename */
+ if ( lp_force_printername(snum) )
+ continue;
+
fstrcpy(sname, lp_servicename(snum));
printer = NULL;
@@ -524,6 +525,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
if ( strequal(printername, aprinter) ) {
found = True;
+ break;
}
DEBUGADD(10, ("printername: %s\n", printername));
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index a7162c929db..0e7ded39f57 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -1924,6 +1924,9 @@ WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET
TIME_OF_DAY_INFO *tod;
struct tm *t;
time_t unixdate = time(NULL);
+ /* We do this call first as if we do it *after* the gmtime call
+ it overwrites the pointed-to values. JRA */
+ uint32 zone = get_time_zone(unixdate)/60;
tod = TALLOC_P(p->mem_ctx, TIME_OF_DAY_INFO);
if (!tod)
@@ -1947,7 +1950,7 @@ WERROR _srv_net_remote_tod(pipes_struct *p, SRV_Q_NET_REMOTE_TOD *q_u, SRV_R_NET
t->tm_min,
t->tm_sec,
0,
- get_time_zone(unixdate)/60,
+ zone,
10000,
t->tm_mday,
t->tm_mon + 1,
diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c
index 3666d474787..924e08cc23a 100644
--- a/source/rpc_server/srv_util.c
+++ b/source/rpc_server/srv_util.c
@@ -81,32 +81,3 @@ static const rid_name domain_group_rids[] =
};
#endif
-/*******************************************************************
- gets a domain user's groups from their already-calculated NT_USER_TOKEN
- ********************************************************************/
-NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
- const NT_USER_TOKEN *nt_token,
- int *numgroups, DOM_GID **pgids)
-{
- DOM_GID *gids;
- int i;
-
- gids = TALLOC_ARRAY(mem_ctx, DOM_GID, nt_token->num_sids);
-
- if (!gids) {
- return NT_STATUS_NO_MEMORY;
- }
-
- *numgroups=0;
-
- for (i=PRIMARY_GROUP_SID_INDEX; i < nt_token->num_sids; i++) {
- if (sid_compare_domain(domain_sid, &nt_token->user_sids[i])==0) {
- sid_peek_rid(&nt_token->user_sids[i], &(gids[*numgroups].g_rid));
- gids[*numgroups].attr= (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_ENABLED);
- (*numgroups)++;
- }
- }
- *pgids = gids;
- return NT_STATUS_OK;
-}
-
diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c
index 5a0ba054833..c79508de8d0 100644
--- a/source/rpcclient/cmd_lsarpc.c
+++ b/source/rpcclient/cmd_lsarpc.c
@@ -771,7 +771,7 @@ static void display_trust_dom_info_1(TRUSTED_DOMAIN_INFO_NAME *n)
static void display_trust_dom_info_3(TRUSTED_DOMAIN_INFO_POSIX_OFFSET *p)
{
- printf("Posix Offset:\t%d\n", p->posix_offset);
+ printf("Posix Offset:\t%08x (%d)\n", p->posix_offset, p->posix_offset);
}
static void display_trust_dom_info_4(TRUSTED_DOMAIN_INFO_PASSWORD *p, const char *password)
@@ -800,6 +800,17 @@ static void display_trust_dom_info_4(TRUSTED_DOMAIN_INFO_PASSWORD *p, const char
data_blob_free(&data_old);
}
+static void display_trust_dom_info_6(TRUSTED_DOMAIN_INFO_EX *i)
+{
+ printf("Domain Name:\t\t%s\n", unistr2_static(&i->domain_name.unistring));
+ printf("NetBIOS Name:\t\t%s\n", unistr2_static(&i->netbios_name.unistring));
+ printf("SID:\t\t\t%s\n", sid_string_static(&i->sid.sid));
+ printf("Trust Direction:\t0x%08x\n", i->trust_direction);
+ printf("Trust Type:\t\t0x%08x\n", i->trust_type);
+ printf("Trust Attributes:\t0x%08x\n", i->trust_attributes);
+}
+
+
static void display_trust_dom_info(LSA_TRUSTED_DOMAIN_INFO *info, uint32 info_class, const char *pass)
{
switch (info_class) {
@@ -812,6 +823,9 @@ static void display_trust_dom_info(LSA_TRUSTED_DOMAIN_INFO *info, uint32 info_cl
case 4:
display_trust_dom_info_4(&info->password, pass);
break;
+ case 6:
+ display_trust_dom_info_6(&info->info_ex);
+ break;
default:
printf("unsupported info-class: %d\n", info_class);
break;
diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c
index d8f5a75b54e..9377f8fde8c 100644
--- a/source/rpcclient/cmd_netlogon.c
+++ b/source/rpcclient/cmd_netlogon.c
@@ -70,6 +70,60 @@ static NTSTATUS cmd_netlogon_getdcname(struct rpc_pipe_client *cli,
return result;
}
+static WERROR cmd_netlogon_dsr_getdcname(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ WERROR result;
+ char *dcname, *dcaddress;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s domainname\n", argv[0]);
+ return WERR_OK;
+ }
+
+ result = rpccli_netlogon_dsr_getdcname(
+ cli, mem_ctx, cli->cli->desthost, argv[1], NULL, NULL,
+ 0x40000000, &dcname, &dcaddress, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL);
+
+ if (W_ERROR_IS_OK(result)) {
+ printf("Domain %s's DC is called %s at IP %s\n",
+ argv[1], dcname, dcaddress);
+ return WERR_OK;
+ }
+
+ printf("rpccli_netlogon_dsr_getdcname returned %s\n",
+ nt_errstr(werror_to_ntstatus(result)));
+
+ return result;
+}
+
+static WERROR cmd_netlogon_dsr_getsitename(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ WERROR result;
+ char *sitename;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s computername\n", argv[0]);
+ return WERR_OK;
+ }
+
+ result = rpccli_netlogon_dsr_getsitename(cli, mem_ctx, argv[1], &sitename);
+
+ if (!W_ERROR_IS_OK(result)) {
+ printf("rpccli_netlogon_dsr_gesitename returned %s\n",
+ nt_errstr(werror_to_ntstatus(result)));
+ return result;
+ }
+
+ printf("Computer %s is on Site: %s\n", argv[1], sitename);
+
+ return WERR_OK;
+}
+
static NTSTATUS cmd_netlogon_logon_ctrl(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx, int argc,
const char **argv)
@@ -317,6 +371,8 @@ struct cmd_set netlogon_commands[] = {
{ "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, NULL, "Logon Control 2", "" },
{ "getdcname", RPC_RTYPE_NTSTATUS, cmd_netlogon_getdcname, NULL, PI_NETLOGON, NULL, "Get trusted DC name", "" },
+ { "dsr_getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcname, PI_NETLOGON, NULL, "Get trusted DC name", "" },
+ { "dsr_getsitename", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getsitename, PI_NETLOGON, NULL, "Get sitename", "" },
{ "logonctrl", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl, NULL, PI_NETLOGON, NULL, "Logon Control", "" },
{ "samsync", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync, NULL, PI_NETLOGON, NULL, "Sam Synchronisation", "" },
{ "samdeltas", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas, NULL, PI_NETLOGON, NULL, "Query Sam Deltas", "" },
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index 6ff2bce8518..2050f2a7796 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -165,14 +165,32 @@ static const char* server_role_str(uint32 server_role)
static void display_sam_unk_info_1(SAM_UNK_INFO_1 *info1)
{
- printf("Minimum password length: %d\n", info1->min_length_password);
- printf("Password uniqueness (remember x passwords): %d\n", info1->password_history);
- printf("flag: ");
- if(info1->flag&&2==2) printf("users must open a session to change password ");
- printf("\n");
-
- printf("password expire in: %s\n", display_time(info1->expire));
- printf("Min password age (allow changing in x days): %s\n", display_time(info1->min_passwordage));
+ printf("Minimum password length:\t\t\t%d\n", info1->min_length_password);
+ printf("Password uniqueness (remember x passwords):\t%d\n", info1->password_history);
+ printf("Password Properties:\t\t\t\t0x%08x\n", info1->password_properties);
+
+ if (info1->password_properties & DOMAIN_PASSWORD_COMPLEX)
+ printf("\tDOMAIN_PASSWORD_COMPLEX\n");
+
+ if (info1->password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE) {
+ printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
+ printf("users must open a session to change password ");
+ }
+
+ if (info1->password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
+ printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
+
+ if (info1->password_properties & DOMAIN_LOCKOUT_ADMINS)
+ printf("\tDOMAIN_LOCKOUT_ADMINS\n");
+
+ if (info1->password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
+ printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
+
+ if (info1->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
+ printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
+
+ printf("password expire in:\t\t\t\t%s\n", display_time(info1->expire));
+ printf("Min password age (allow changing in x days):\t%s\n", display_time(info1->min_passwordage));
}
static void display_sam_unk_info_2(SAM_UNK_INFO_2 *info2)
@@ -333,7 +351,7 @@ static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
return NT_STATUS_OK;
}
- sscanf(argv[1], "%i", &user_rid);
+ user_rid = strtoul(argv[1], NULL, 10);
if (argc > 2)
sscanf(argv[2], "%i", &info_level);
@@ -362,6 +380,27 @@ static NTSTATUS cmd_samr_query_user(struct rpc_pipe_client *cli,
access_mask,
user_rid, &user_pol);
+ if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER) &&
+ (user_rid == 0)) {
+
+ /* Probably this was a user name, try lookupnames */
+ uint32 num_rids;
+ uint32 *rids, *types;
+
+ result = rpccli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ 1000, 1, &argv[1],
+ &num_rids, &rids,
+ &types);
+
+ if (NT_STATUS_IS_OK(result)) {
+ result = rpccli_samr_open_user(cli, mem_ctx,
+ &domain_pol,
+ access_mask,
+ rids[0], &user_pol);
+ }
+ }
+
+
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -1457,8 +1496,8 @@ static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
char **names;
int i;
- if (argc < 2) {
- printf("Usage: %s rid1 [rid2 [rid3] [...]]\n", argv[0]);
+ if (argc < 3) {
+ printf("Usage: %s domain|builtin rid1 [rid2 [rid3] [...]]\n", argv[0]);
return NT_STATUS_OK;
}
@@ -1470,20 +1509,27 @@ static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
- MAXIMUM_ALLOWED_ACCESS,
- &domain_sid, &domain_pol);
+ if (StrCaseCmp(argv[1], "domain")==0)
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &domain_sid, &domain_pol);
+ else if (StrCaseCmp(argv[1], "builtin")==0)
+ result = rpccli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ &global_sid_Builtin, &domain_pol);
+ else
+ return NT_STATUS_OK;
if (!NT_STATUS_IS_OK(result))
goto done;
/* Look up rids */
- num_rids = argc - 1;
+ num_rids = argc - 2;
rids = TALLOC_ARRAY(mem_ctx, uint32, num_rids);
- for (i = 0; i < argc - 1; i++)
- sscanf(argv[i + 1], "%i", &rids[i]);
+ for (i = 0; i < argc - 2; i++)
+ sscanf(argv[i + 2], "%i", &rids[i]);
result = rpccli_samr_lookup_rids(cli, mem_ctx, &domain_pol, num_rids, rids,
&num_names, &names, &name_types);
@@ -1663,18 +1709,37 @@ static NTSTATUS cmd_samr_get_dom_pwinfo(struct rpc_pipe_client *cli,
int argc, const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint16 unk_0, unk_1;
+ uint16 min_pwd_length;
+ uint32 password_properties;
if (argc != 1) {
printf("Usage: %s\n", argv[0]);
return NT_STATUS_OK;
}
- result = rpccli_samr_get_dom_pwinfo(cli, mem_ctx, &unk_0, &unk_1) ;
+ result = rpccli_samr_get_dom_pwinfo(cli, mem_ctx, &min_pwd_length, &password_properties) ;
if (NT_STATUS_IS_OK(result)) {
- printf("unk_0 = 0x%08x\n", unk_0);
- printf("unk_1 = 0x%08x\n", unk_1);
+ printf("min_pwd_length: %d\n", min_pwd_length);
+ printf("password_properties: 0x%08x\n", password_properties);
+
+ if (password_properties & DOMAIN_PASSWORD_COMPLEX)
+ printf("\tDOMAIN_PASSWORD_COMPLEX\n");
+
+ if (password_properties & DOMAIN_PASSWORD_NO_ANON_CHANGE)
+ printf("\tDOMAIN_PASSWORD_NO_ANON_CHANGE\n");
+
+ if (password_properties & DOMAIN_PASSWORD_NO_CLEAR_CHANGE)
+ printf("\tDOMAIN_PASSWORD_NO_CLEAR_CHANGE\n");
+
+ if (password_properties & DOMAIN_LOCKOUT_ADMINS)
+ printf("\tDOMAIN_LOCKOUT_ADMINS\n");
+
+ if (password_properties & DOMAIN_PASSWORD_STORE_CLEARTEXT)
+ printf("\tDOMAIN_PASSWORD_STORE_CLEARTEXT\n");
+
+ if (password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE)
+ printf("\tDOMAIN_REFUSE_PASSWORD_CHANGE\n");
}
return result;
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index 532c79043a2..7f3bda582df 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -190,7 +190,8 @@ static BOOL get_ea_dos_attribute(connection_struct *conn, const char *path,SMB_S
return False;
}
- *pattr = 0;
+ /* Don't reset pattr to zero as we may already have filename-based attributes we
+ need to preserve. */
sizeret = SMB_VFS_GETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, sizeof(attrstr));
if (sizeret == -1) {
@@ -337,6 +338,7 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
if (result & aSYSTEM) DEBUG(8, ("s"));
if (result & aDIR ) DEBUG(8, ("d"));
if (result & aARCH ) DEBUG(8, ("a"));
+ if (result & FILE_ATTRIBUTE_SPARSE ) DEBUG(8, ("[sparse]"));
DEBUG(8,("\n"));
@@ -355,6 +357,9 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
mode_t unixmode;
int ret = -1;
+ /* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */
+ dosmode &= SAMBA_ATTRIBUTES_MASK;
+
DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname));
if (!st || (st && !VALID_STAT(*st))) {
st = &st1;
diff --git a/source/smbd/filename.c b/source/smbd/filename.c
index 2ee8ba1e4ff..6c0f8b77585 100644
--- a/source/smbd/filename.c
+++ b/source/smbd/filename.c
@@ -150,6 +150,19 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
pstrcpy(saved_last_component, name);
}
+ /*
+ * Large directory fix normalization. If we're case sensitive, and
+ * the case preserving parameters are set to "no", normalize the case of
+ * the incoming filename from the client WHETHER IT EXISTS OR NOT !
+ * This is in conflict with the current (3.0.20) man page, but is
+ * what people expect from the "large directory howto". I'll update
+ * the man page. Thanks to jht@samba.org for finding this. JRA.
+ */
+
+ if (conn->case_sensitive && !conn->case_preserve && !conn->short_case_preserve) {
+ strnorm(name, lp_defaultcase(SNUM(conn)));
+ }
+
start = name;
pstrcpy(orig_path, name);
diff --git a/source/utils/smbcontrol.c b/source/utils/smbcontrol.c
index a0304eb89a9..25b42a58c1e 100644
--- a/source/utils/smbcontrol.c
+++ b/source/utils/smbcontrol.c
@@ -508,13 +508,13 @@ static BOOL do_poolusage(const struct process_id pid,
return False;
}
+ message_register(MSG_POOL_USAGE, print_string_cb);
+
/* Send a message and register our interest in a reply */
if (!send_message(pid, MSG_REQ_POOL_USAGE, NULL, 0, False))
return False;
- message_register(MSG_POOL_USAGE, print_string_cb);
-
wait_replies(procid_to_pid(&pid) == 0);
/* No replies were received within the timeout period */
diff --git a/source/utils/testparm.c b/source/utils/testparm.c
index b4561b58deb..0ce838e5c76 100644
--- a/source/utils/testparm.c
+++ b/source/utils/testparm.c
@@ -73,6 +73,11 @@ cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
ret = 1;
}
+ if (lp_passdb_expand_explicit()) {
+ fprintf(stderr, "WARNING: passdb expand explicit = yes is "
+ "deprecated\n");
+ }
+
/*
* Password server sanity checks.
*/