]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
syncing tree for 3.0.1rc1
authorGerald Carter <jerry@samba.org>
Thu, 4 Dec 2003 20:35:40 +0000 (20:35 +0000)
committerGerald Carter <jerry@samba.org>
Thu, 4 Dec 2003 20:35:40 +0000 (20:35 +0000)
105 files changed:
WHATSNEW.txt
examples/LDAP/samba.schema
examples/nss/wbtest.c [new file with mode: 0644]
packaging/Mandrake/samba2.spec.tmpl
packaging/Mandrake/smb.conf
packaging/Solaris/samba.server.master
source/Makefile.in
source/VERSION
source/auth/auth.c
source/auth/auth_ntlmssp.c
source/auth/auth_sam.c
source/auth/auth_server.c
source/auth/auth_util.c
source/configure.in
source/groupdb/mapping.c
source/include/auth.h
source/include/client.h
source/include/includes.h
source/include/ntdomain.h
source/include/ntlmssp.h
source/include/passdb.h
source/include/rpc_samr.h
source/include/smb.h
source/include/smbldap.h
source/lib/access.c
source/lib/charcnv.c
source/lib/data_blob.c
source/lib/module.c
source/lib/privileges.c
source/lib/smbldap.c
source/lib/time.c
source/lib/util.c
source/lib/util_str.c
source/libads/kerberos_verify.c
source/libads/ldap.c
source/libsmb/cliconnect.c
source/libsmb/clientgen.c
source/libsmb/clikrb5.c
source/libsmb/clispnego.c
source/libsmb/clitrans.c
source/libsmb/ntlmssp.c
source/libsmb/ntlmssp_parse.c
source/libsmb/ntlmssp_sign.c
source/libsmb/smb_signing.c
source/libsmb/smbdes.c
source/libsmb/smbencrypt.c
source/libsmb/trusts_util.c
source/nsswitch/wbinfo.c
source/nsswitch/winbind_nss_freebsd.c [new file with mode: 0644]
source/nsswitch/winbind_nss_linux.c
source/nsswitch/winbindd.c
source/nsswitch/winbindd_cm.c
source/nsswitch/winbindd_group.c
source/nsswitch/winbindd_nss.h
source/nsswitch/winbindd_pam.c
source/nsswitch/winbindd_rpc.c
source/nsswitch/winbindd_sid.c
source/param/loadparm.c
source/passdb/passdb.c
source/passdb/pdb_ldap.c
source/passdb/util_sam_sid.c
source/printing/print_cups.c
source/printing/printing.c
source/rpc_client/cli_netlogon.c
source/rpc_client/cli_pipe.c
source/rpc_client/cli_samr.c
source/rpc_parse/parse_misc.c
source/rpc_parse/parse_net.c
source/rpc_parse/parse_samr.c
source/rpc_server/srv_dfs_nt.c
source/rpc_server/srv_lsa_nt.c
source/rpc_server/srv_netlog_nt.c
source/rpc_server/srv_pipe.c
source/rpc_server/srv_pipe_hnd.c
source/rpc_server/srv_samr.c
source/rpc_server/srv_samr_nt.c
source/rpc_server/srv_srvsvc_nt.c
source/rpc_server/srv_util.c
source/smbd/chgpasswd.c
source/smbd/dosmode.c
source/smbd/ipc.c
source/smbd/lanman.c
source/smbd/mangle_hash.c
source/smbd/mangle_hash2.c
source/smbd/nttrans.c
source/smbd/open.c
source/smbd/password.c
source/smbd/posix_acls.c
source/smbd/process.c
source/smbd/quotas.c
source/smbd/sesssetup.c
source/smbd/trans2.c
source/smbd/vfs-wrap.c
source/torture/nbio.c
source/utils/net.c
source/utils/net_ads.c
source/utils/net_help.c
source/utils/net_rpc.c
source/utils/net_rpc_join.c
source/utils/ntlm_auth.c
source/utils/pdbedit.c
source/web/cgi.c
source/web/diagnose.c
source/web/swat.c
testsuite/build_farm/runlist

index f01dc7456d4a21f9893045745412acdf006ab002..3b5b6a44bf68b809e5b3356370a4e98465c8c5d7 100644 (file)
@@ -21,6 +21,14 @@ Changes since 3.0.1pre2
 Please refer to the CVS log for the SAMBA_3_0 branch for complete
 details:
 
+1)  Fix for pdbedit error code returns (bug 763).
+
+Changes since 3.0.1pre3
+-----------------------
+
+Please refer to the CVS log for the SAMBA_3_0 branch for complete
+details:
+
 1)  Skip over the winbind separator when looking up a user.
     This fixes the bug that prevented local users from
     matching an AD user when not running winbindd (bug 698).
index 14cd72058803ba0813bb8d033204d5b761eca3f4..a2225faa5849f14a47560ca88547260fb4a95adb 100644 (file)
@@ -236,6 +236,11 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.38 NAME 'sambaDomainName'
        EQUALITY caseIgnoreMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
 
+attributetype ( 1.3.6.1.4.1.7165.2.1.47 NAME 'sambaMungedDial'
+       DESC ''
+       EQUALITY caseExactMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1050} )
+
 ##
 ## SID, of any type
 ##
@@ -308,7 +313,7 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.6 NAME 'sambaSamAccount' SUP top AUXILIARY
               sambaPwdCanChange $ sambaPwdMustChange $ sambaAcctFlags $
                displayName $ sambaHomePath $ sambaHomeDrive $ sambaLogonScript $
               sambaProfilePath $ description $ sambaUserWorkstations $
-              sambaPrimaryGroupSID $ sambaDomainName ))
+              sambaPrimaryGroupSID $ sambaDomainName $ sambaMungedDial))
 
 ##
 ## Group mapping info
diff --git a/examples/nss/wbtest.c b/examples/nss/wbtest.c
new file mode 100644 (file)
index 0000000..fc8f575
--- /dev/null
@@ -0,0 +1,375 @@
+/* 
+   nss sample code for extended winbindd functionality
+
+   Copyright (C) Andrew Tridgell (tridge@samba.org)   
+
+   you are free to use this code in any way you see fit, including
+   without restriction, using this code in your own products. You do
+   not need to give any attribution.
+*/
+
+/*
+   compile like this:
+
+      cc -o wbtest wbtest.c -ldl
+
+   and run like this:
+
+      ./wbtest /lib/libnss_winbind.so
+*/
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <nss.h>
+#include <dlfcn.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+
+typedef enum nss_status NSS_STATUS;
+
+struct nss_state {
+       void *dl_handle;
+       char *nss_name;
+       char pwnam_buf[512];
+};
+
+/*
+  find a function in the nss library
+*/
+static void *find_fn(struct nss_state *nss, const char *name)
+{
+       void *res;
+       char *s = NULL;
+
+       asprintf(&s, "_nss_%s_%s", nss->nss_name, name);
+       if (!s) {
+               errno = ENOMEM;
+               return NULL;
+       }
+       res = dlsym(nss->dl_handle, s);
+       free(s);
+       if (!res) {
+               errno = ENOENT;
+               return NULL;
+       }
+       return res;
+}
+
+/*
+  establish a link to the nss library
+  Return 0 on success and -1 on error
+*/
+int nss_open(struct nss_state *nss, const char *nss_path)
+{
+       char *p;
+       p = strrchr(nss_path, '_');
+       if (!p) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       nss->nss_name = strdup(p+1);
+       p = strchr(nss->nss_name, '.');
+       if (p) *p = 0;
+
+       nss->dl_handle = dlopen(nss_path, RTLD_LAZY);
+       if (!nss->dl_handle) {
+               free(nss->nss_name);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  close and cleanup a nss state
+*/
+void nss_close(struct nss_state *nss)
+{
+       free(nss->nss_name);
+       dlclose(nss->dl_handle);
+}
+
+/*
+  make a getpwnam call. 
+  Return 0 on success and -1 on error
+*/
+int nss_getpwent(struct nss_state *nss, struct passwd *pwd)
+{
+       NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *, 
+                                     size_t , int *) = find_fn(nss, "getpwent_r");
+       NSS_STATUS status;
+       int nss_errno = 0;
+
+       if (!_nss_getpwent_r) {
+               return -1;
+       }
+
+       status = _nss_getpwent_r(pwd, nss->pwnam_buf, sizeof(nss->pwnam_buf), &nss_errno);
+       if (status == NSS_STATUS_NOTFOUND) {
+               errno = ENOENT;
+               return -1;
+       }
+       if (status != NSS_STATUS_SUCCESS) {
+               errno = nss_errno;
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  make a setpwent call. 
+  Return 0 on success and -1 on error
+*/
+int nss_setpwent(struct nss_state *nss)
+{
+       NSS_STATUS (*_nss_setpwent)(void) = find_fn(nss, "setpwent");
+       NSS_STATUS status;
+       if (!_nss_setpwent) {
+               return -1;
+       }
+       status = _nss_setpwent();
+       if (status != NSS_STATUS_SUCCESS) {
+               errno = EINVAL;
+               return -1;
+       }
+       return 0;
+}
+
+/*
+  make a endpwent call. 
+  Return 0 on success and -1 on error
+*/
+int nss_endpwent(struct nss_state *nss)
+{
+       NSS_STATUS (*_nss_endpwent)(void) = find_fn(nss, "endpwent");
+       NSS_STATUS status;
+       if (!_nss_endpwent) {
+               return -1;
+       }
+       status = _nss_endpwent();
+       if (status != NSS_STATUS_SUCCESS) {
+               errno = EINVAL;
+               return -1;
+       }
+       return 0;
+}
+
+
+/*
+  convert a name to a SID
+  caller frees
+  Return 0 on success and -1 on error
+*/
+int nss_nametosid(struct nss_state *nss, const char *name, char **sid)
+{
+       NSS_STATUS (*_nss_nametosid)(const char *, char **, char *, size_t, int *) = 
+               find_fn(nss, "nametosid");
+       NSS_STATUS status;
+       int nss_errno = 0;
+       char buf[200];
+
+       if (!_nss_nametosid) {
+               return -1;
+       }
+
+       status = _nss_nametosid(name, sid, buf, sizeof(buf), &nss_errno);
+       if (status == NSS_STATUS_NOTFOUND) {
+               errno = ENOENT;
+               return -1;
+       }
+       if (status != NSS_STATUS_SUCCESS) {
+               errno = nss_errno;
+               return -1;
+       }
+
+       *sid = strdup(*sid);
+
+       return 0;
+}
+
+/*
+  convert a SID to a name
+  caller frees
+  Return 0 on success and -1 on error
+*/
+int nss_sidtoname(struct nss_state *nss, char *sid, char **name)
+{
+       NSS_STATUS (*_nss_sidtoname)(const char *, char **, char *, size_t, int *) = 
+               find_fn(nss, "sidtoname");
+       NSS_STATUS status;
+       int nss_errno = 0;
+       char buf[200];
+
+       if (!_nss_sidtoname) {
+               return -1;
+       }
+
+       status = _nss_sidtoname(sid, name, buf, sizeof(buf), &nss_errno);
+       if (status == NSS_STATUS_NOTFOUND) {
+               errno = ENOENT;
+               return -1;
+       }
+       if (status != NSS_STATUS_SUCCESS) {
+               errno = nss_errno;
+               return -1;
+       }
+
+       *name = strdup(*name);
+
+       return 0;
+}
+
+/*
+  return a list of group SIDs for a user SID
+  the returned list is NULL terminated
+  Return 0 on success and -1 on error
+*/
+int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids)
+{
+       NSS_STATUS (*_nss_getusersids)(const char *, char **, int *, char *, size_t, int *) = 
+               find_fn(nss, "getusersids");
+       NSS_STATUS status;
+       int nss_errno = 0;
+       char *s;
+       int i, num_groups = 0;
+       unsigned bufsize = 10;
+       char *buf;
+
+       if (!_nss_getusersids) {
+               return -1;
+       }
+
+again:
+       buf = malloc(bufsize);
+       if (!buf) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       status = _nss_getusersids(user_sid, &s, &num_groups, buf, bufsize, &nss_errno);
+       if (status == NSS_STATUS_NOTFOUND) {
+               errno = ENOENT;
+               free(buf);
+               return -1;
+       }
+       
+       if (status == NSS_STATUS_TRYAGAIN) {
+               bufsize *= 2;
+               free(buf);
+               goto again;
+       }
+
+       if (status != NSS_STATUS_SUCCESS) {
+               free(buf);
+               errno = nss_errno;
+               return -1;
+       }
+
+       if (num_groups == 0) {
+               free(buf);
+               return 0;
+       }
+
+       *sids = (char **)malloc(sizeof(char *) * (num_groups+1));
+       if (! *sids) {
+               errno = ENOMEM;
+               free(buf);
+               return -1;
+       }
+
+       for (i=0;i<num_groups;i++) {
+               (*sids)[i] = strdup(s);
+               s += strlen(s) + 1;
+       }
+       (*sids)[i] = NULL;
+
+       free(buf);
+
+       return 0;
+}
+
+
+static int nss_test_users(struct nss_state *nss)
+{
+       struct passwd pwd;
+
+       if (nss_setpwent(nss) != 0) {
+               perror("setpwent");
+               return -1;
+       }
+
+       /* loop over all users */
+       while ((nss_getpwent(nss, &pwd) == 0)) {
+               char *sid, **group_sids, *name2;
+               int i;
+
+               printf("User %s\n", pwd.pw_name);
+               if (nss_nametosid(nss, pwd.pw_name, &sid) != 0) {
+                       perror("nametosid");
+                       return -1;
+               }
+               printf("\tSID %s\n", sid);
+
+               if (nss_sidtoname(nss, sid, &name2) != 0) {
+                       perror("sidtoname");
+                       return -1;
+               }
+               printf("\tSID->name %s\n", name2);
+
+               if (nss_getusersids(nss, sid, &group_sids) != 0) {
+                       perror("getusersids");
+                       return -1;
+               }
+
+               printf("\tGroups:\n");
+               for (i=0; group_sids[i]; i++) {
+                       printf("\t\t%s\n", group_sids[i]);
+                       free(group_sids[i]);
+               }
+
+               free(sid);
+               free(name2);
+               free(group_sids);
+       }
+
+
+       if (nss_endpwent(nss) != 0) {
+               perror("endpwent");
+               return -1;
+       }
+
+       return 0;
+}
+
+
+/*
+  main program. It lists all users, listing user SIDs for each user
+ */
+int main(int argc, char *argv[])
+{      
+       struct nss_state nss;
+       const char *so_path = "/lib/libnss_winbind.so";
+       int ret;
+
+       if (argc > 1) {
+               so_path = argv[1];
+       }
+
+       if (nss_open(&nss, so_path) != 0) {
+               perror("nss_open");
+               exit(1);
+       }
+
+       ret = nss_test_users(&nss);
+
+       nss_close(&nss);
+
+       return ret;
+}
index 28bc8f9dafb68692deb193ca010203ebd547e885..cff54d146b63e07619dbcb35796730ddae7eabb8 100644 (file)
@@ -13,8 +13,8 @@
 # cvs should be submitted for inclusion in samba cvs.
 
 %define pkg_name       samba
-%define ver            3.0.0rc4
-%define rel            2mdk
+%define ver            3.0.1pre3
+%define rel            3mdk
 %define vscanver       0.3.3beta1
 %define libsmbmajor    0
 
@@ -58,6 +58,7 @@
 # We now do detection of the Mandrake release we are building on:
 #%define build_cooker %(if [ `awk '{print $3}' /etc/mandrake-release` = "Cooker" ];then echo 1; else echo 0; fi)
 #%define build_cooker %(if [[ `cat /etc/mandrake-release|grep Cooker` ]];then echo 1; else echo 0; fi)
+%define build_mdk100 %(if [ `awk '{print $4}' /etc/mandrake-release` = 10.0 ];then echo 1; else echo 0; fi)
 %define build_mdk92 %(if [ `awk '{print $4}' /etc/mandrake-release` = 9.2 ];then echo 1; else echo 0; fi)
 %define build_mdk91 %(if [ `awk '{print $4}' /etc/mandrake-release` = 9.1 ];then echo 1; else echo 0; fi)
 %define build_mdk90 %(if [ `awk '{print $4}' /etc/mandrake-release` = 9.0 ];then echo 1; else echo 0; fi)
 %define have_rpmhelper 1
 
 # Set defaults for each version
+%if %build_mdk100
+%define build_system   1
+%define build_alternatives     1
+%define build_cupspc   1
+%endif
+
 %if %build_mdk92
 %define build_alternatives     1
 %define build_cupspc   1
 
 #Standard texts for descriptions:
 %define message_bugzilla() %(echo -e -n "Please file bug reports for this package at Mandrake bugzilla \\n(http://qa.mandrakesoft.com) under the product name %{1}")
-%define message_system %(echo -e -n "NOTE: This is a prerelease of samba-%{samba_major}, not intended for production\\n use. Rather these packages are provided, parallel installable\\nwith samba-2.2.x, for testing purposes")
+%define message_system %(echo -e -n "NOTE: These packages of samba-%{version}, are provided, parallel installable\\nwith samba-2.2.x, to allow easy migration from samba-2.2.x to samba-%{version},\\nbut are not officially supported")
 
 #check gcc version to disable some optimisations on gcc-3.3.1
 %define gcc331 %(gcc -dumpversion|awk '{if ($1>3.3) print 1; else print 0}')
 #Define sets of binaries that we can use in globs and loops:
 %global commonbin net,ntlm_auth,rpcclient,smbcacls,smbcquotas,smbpasswd,smbtree,testparm,testprns
 
-%global serverbin      editreg,pdbedit,profiles,smbcontrol,smbstatus,tdbbackup
-%global serversbin nmbd,samba,smbd
+%global serverbin      editreg,pdbedit,profiles,smbcontrol,smbstatus,tdbbackup,tdbdump
+%global serversbin nmbd,samba,smbd,mkntpwd
 
 %global clientbin      findsmb,nmblookup,smbclient,smbmnt,smbmount,smbprint,smbspool,smbtar,smbumount
 %global client_bin     mount.cifs
 %endif
 
 Summary: Samba SMB server.
-Vendor: Samba Team
 Name: %{pkg_name}%{samba_major}
 
 %if %have_pre
@@ -258,13 +264,10 @@ Source7: README.%{name}-mandrake-rpm
 Source8: samba-vscan-%{vscanver}.tar.bz2
 %endif
 Source10: samba-print-pdf.sh.bz2
-Source11: mount.cifs.8.bz2
 Patch1: smbw.patch.bz2
-Patch3: samba-2.2.0-buildroot.patch.bz2
 Patch4: samba-3.0-smbmount-sbin.patch.bz2
 %if !%have_pversion
 # Version specific patches: current version
-Patch100: samba-3.0.0rc4-mandrake-packaging.patch.bz2
 %else
 # Version specific patches: upcoming version
 %endif
@@ -486,6 +489,11 @@ URL:       http://www.samba.org
 Summary: Samba-winbind daemon, utilities and documentation
 Group: System/Servers
 Requires: %{name}-common = %{version}
+%endif
+%if %build_winbind && !%build_system
+Conflicts: samba-winbind
+%endif
+%if %build_winbind
 %description winbind
 Provides the winbind daemon and testing tools to allow authentication 
 and group/user enumeration from a Windows or Samba domain controller.
@@ -504,6 +512,11 @@ Summary: Name Service Switch service for WINS
 Group: System/Servers
 Requires: %{name}-common = %{version}
 PreReq: glibc
+%endif
+%if %build_wins && !%build_system
+Conflicts: nss_wins
+%endif
+%if %build_wins
 %description -n nss_wins%{samba_major}
 Provides the libnss_wins shared library which resolves NetBIOS names to 
 IP addresses.
@@ -525,7 +538,8 @@ Requires: %{name}-common = %{version}
 %if %build_system && %{?_with_test:1}%{!?_with_test:0}
 Provides:  samba3-test samba3-debug
 Obsoletes: samba3-test samba3-debug
-%else
+%endif
+%if !%build_system && %{?_with_test:1}%{!?_with_test:0}
 Provides: samba-test samba3-debug
 Obsoletes: samba3-debug
 %endif
@@ -607,23 +621,29 @@ allowing the development of other software to access SMB shares.
 URL:           http://www.samba.org
 Summary:       Samba password database plugin for MySQL
 Group:         System/Libraries
+Requires:      %{name}-server = %{version}-%{release}
+%endif
+%ifnarch alpha && %build_system
+Obsoletes:     samba3-passdb-mysql 
+Provides:      samba3-passdb-mysql 
+%endif
+%ifnarch alpha
 
 %description passdb-mysql
 The passdb-mysql package for samba provides a password database
 backend allowing samba to store account details in a MySQL
 database
 %endif
-%ifnarch alpha && %have_pversion
-%message_bugzilla samba3-passdb-mysql
-%endif
-%ifnarch alpha && !%build_system
-%message_system
-%endif
 
 %package passdb-xml
 URL:           http://www.samba.org
 Summary:       Samba password database plugin for XML files
 Group:         System/Libraries
+Requires:      %{name}-server = %{version}-%{release}
+%if %build_system
+Obsoletes:     samba3-passdb-xml 
+Provides:      samba3-passdb-xml 
+%endif
 
 %description passdb-xml
 The passdb-xml package for samba provides a password database
@@ -792,12 +812,10 @@ echo -e "\n%{name}-%{version}-%{release}\n">>%{SOURCE7}
 %endif
 #%patch111 -p1
 %patch1 -p1 -b .smbw
-%patch3 -p1 -b .buildroot
 %patch4 -p1 -b .sbin
 # Version specific patches: current version
 %if !%have_pversion
 echo "Applying patches for current version: %{ver}"
-%patch100 -p1 -b .mdk
 %else
 # Version specific patches: upcoming version
 echo "Applying patches for new versions: %{pversion}"
@@ -990,7 +1008,7 @@ mkdir -p $RPM_BUILD_ROOT%{_datadir}/%{name}/scripts
 #smbwrapper and pam_winbind not handled by make, pam_smbpass.so doesn't build
 #install -m 755 source/bin/smbwrapper.so $RPM_BUILD_ROOT%{_libdir}/smbwrapper%{samba_major}.so
 install -m 755 source/bin/pam_smbpass.so $RPM_BUILD_ROOT/%{_lib}/security/pam_smbpass%{samba_major}.so
-install -m 755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/%{_lib}/security/pam_winbind%{samba_major}.so
+install -m 755 source/nsswitch/pam_winbind.so $RPM_BUILD_ROOT/%{_lib}/security/pam_winbind.so
 
 install -m755 source/bin/libsmbclient.a $RPM_BUILD_ROOT%{_libdir}/libsmbclient.a
 pushd $RPM_BUILD_ROOT/%{_libdir}
@@ -1022,10 +1040,10 @@ popd
 #libnss_* not handled by make:
 # Install the nsswitch library extension file
 for i in wins winbind; do
-  install -m755 source/nsswitch/libnss_${i}.so $RPM_BUILD_ROOT/%{_lib}/libnss_${i}%{samba_major}.so
+  install -m755 source/nsswitch/libnss_${i}.so $RPM_BUILD_ROOT/%{_lib}/libnss_${i}.so
 done
 # Make link for wins and winbind resolvers
-( cd $RPM_BUILD_ROOT/%{_lib}; ln -s libnss_wins%{samba_major}.so libnss_wins%{samba_major}.so.2; ln -s libnss_winbind%{samba_major}.so libnss_winbind%{samba_major}.so.2)
+( cd $RPM_BUILD_ROOT/%{_lib}; ln -s libnss_wins.so libnss_wins.so.2; ln -s libnss_winbind.so libnss_winbind.so.2)
 
 %if %{?_with_test:1}%{!?_with_test:0}
 for i in {%{testbin}};do
@@ -1042,11 +1060,11 @@ done
         install -m755 packaging/Mandrake/findsmb $RPM_BUILD_ROOT/%{_bindir}
         install -m755 packaging/Mandrake/smb.init $RPM_BUILD_ROOT/%{_initrddir}/smb%{samba_major}
         install -m755 packaging/Mandrake/smb.init $RPM_BUILD_ROOT/%{_sbindir}/%{name}
-       install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_initrddir}/winbind%{samba_major}
+       install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_initrddir}/winbind
 #      install -m755 packaging/Mandrake/wrepld.init $RPM_BUILD_ROOT/%{_initrddir}/wrepld%{samba_major}
-       install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_sbindir}/winbind%{samba_major}
+       install -m755 packaging/Mandrake/winbind.init $RPM_BUILD_ROOT/%{_sbindir}/winbind
         install -m644 packaging/Mandrake/samba.pamd $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/%{name}
-       install -m644 packaging/Mandrake/system-auth-winbind.pamd $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/system-auth-winbind%{samba_major}
+       install -m644 packaging/Mandrake/system-auth-winbind.pamd $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/system-auth-winbind
 #
         install -m644 %{SOURCE1} $RPM_BUILD_ROOT/%{_sysconfdir}/logrotate.d/%{name}
 #      install -m644 packaging/Mandrake/samba-slapd-include.conf $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/samba-slapd.include
@@ -1070,6 +1088,7 @@ perl -pi -e 's/^(use|package)(\s+)smbldap_(\w+);$/${1}${2}smbldap_${3}%{samba_ma
 perl -pi -e 's,/usr/local/sbin/mkntpwd,/usr/sbin/mkntpwd%{samba_major},g;s,553,421,g' %{buildroot}/%{_sysconfdir}/%{name}/smbldap_conf.pm
 perl -pi -e 's,\$smbldap_conf::SID,\$smbldap_conf3::SID,g' %{buildroot}/%{_datadir}/%{name}/scripts/smbldap*.p?
 %endif
+perl -pi -e 's,/usr/local/sbin/smbldap-passwd.pl,%{_datadir}/%{name}/scripts/smbldap-passwd.pl,g' %{buildroot}/%{_datadir}/%{name}/scripts/smbldap-useradd.pl 
 
 # Link both smbldap*.pm into vendor-perl (any better ideas?)
 mkdir -p %{buildroot}/%{perl_vendorlib}
@@ -1102,7 +1121,6 @@ perl -pi -e 's/printcap name = lpstat/printcap name = cups/g' $RPM_BUILD_ROOT/%{
 
 #install mount.cifs
 install -m755 source/client/mount.cifs %{buildroot}/bin/mount.cifs%{samba_major}
-#bzcat %{SOURCE11} > %{buildroot}/%{_mandir}/man8/mount.cifs%{samba_major}.8
 
         echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/lmhosts
 
@@ -1173,13 +1191,13 @@ done
 )
 # Server/common binaries are versioned only if not system samba:
 %if !%build_system
-for OLD in %{buildroot}/%{_bindir}/{%{commonbin}} %{buildroot}/%{_bindir}/{%{serverbin},wbinfo} %{buildroot}/%{_sbindir}/{%{serversbin},winbindd,swat}
+for OLD in %{buildroot}/%{_bindir}/{%{commonbin}} %{buildroot}/%{_bindir}/{%{serverbin}} %{buildroot}/%{_sbindir}/{%{serversbin},swat}
 do
     NEW=`echo ${OLD}%{alternative_major}`
     mv $OLD $NEW -f ||:
 done
 # And the man pages too:
-for OLD in %{buildroot}/%{_mandir}/man?/{%{commonbin},%{serverbin},wbinfo,%{serversbin},winbindd,swat,{%testbin},smb.conf,lmhosts}*
+for OLD in %{buildroot}/%{_mandir}/man?/{%{commonbin},%{serverbin},%{serversbin},swat,{%testbin},smb.conf,lmhosts}*
 do
     if [ -e $OLD ]
     then
@@ -1191,14 +1209,12 @@ do
     fi
 done           
 # Replace paths in config files and init scripts:
-for i in smb winbind;do
+for i in smb ;do
        perl -pi -e 's,/subsys/'$i',/subsys/'$i'%{samba_major},g' $RPM_BUILD_ROOT/%{_initrddir}/${i}%{samba_major}
 done
-for i in %{_sysconfdir}/%{name}/smb.conf %{_initrddir}/smb%{samba_major} %{_sbindir}/%{name} %{_initrddir}/winbind%{samba_major} %{_sbindir}/winbind%{samba_major} /%{_sysconfdir}/logrotate.d/%{name} /%{_sysconfdir}/xinetd.d/swat%{samba_major} %{_initrddir}/wrepld%{samba_major}; do
-       perl -pi -e 's,/%{pkg_name},/%{name},g; s,smbd,%{_sbindir}/smbd%{samba_major},g; s,nmbd,%{_sbindir}/nmbd%{samba_major},g; s,winbindd,%{_sbindir}/winbindd%{samba_major},g; s,/usr/sbin/swat,%{_sbindir}/swat%{samba_major},g;s,wrepld,%{_sbindir}/wrepld%{samba_major},g' $RPM_BUILD_ROOT/$i;
+for i in %{_sysconfdir}/%{name}/smb.conf %{_initrddir}/smb%{samba_major} %{_sbindir}/%{name} %{_initrddir}/winbind /%{_sysconfdir}/logrotate.d/%{name} /%{_sysconfdir}/xinetd.d/swat%{samba_major} %{_initrddir}/wrepld%{samba_major}; do
+       perl -pi -e 's,/%{pkg_name},/%{name},g; s,smbd,%{_sbindir}/smbd%{samba_major},g; s,nmbd,%{_sbindir}/nmbd%{samba_major},g; s,/usr/sbin/swat,%{_sbindir}/swat%{samba_major},g;s,wrepld,%{_sbindir}/wrepld%{samba_major},g' $RPM_BUILD_ROOT/$i;
 done
-# Fix pam files
-perl -pi -e 's/winbind/winbind%{samba_major}/g' $RPM_BUILD_ROOT/%{_sysconfdir}/pam.d/system-auth-winbind%{samba_major}
 # Fix xinetd file for swat:
 perl -pi -e 's,/usr/sbin,%{_sbindir},g' $RPM_BUILD_ROOT/%{_sysconfdir}/xinetd.d/swat%{samba_major}
 %endif
@@ -1229,17 +1245,6 @@ if [ -f $i ]; then
 fi
 done
 
-# Remove the transient tdb files (modified from version in off. samba spec:
-for TDB in brlock unexpected locking messages; do
-        if [ -e /var/cache/%{name}/$TDB.tdb ]; then
-                rm -f /var/cache/%{name}/$TDB.tdb;
-        fi;
-done
-
-if [ -d /var/lock/samba ]; then
-        rm -rf /var/lock/samba
-fi
-
 %post common
 # Basic migration script for pre-2.2.1 users,
 # since smb config moved from /etc to %{_sysconfdir}/samba
@@ -1258,12 +1263,6 @@ fi
 # Let's define the proper paths for config files
 perl -pi -e 's/(\/etc\/)(smb)/\1%{name}\/\2/' %{_sysconfdir}/%{name}/smb.conf
 
-# Let's replace lpstat with cups in older smb.conf:
-%if %build_cupspc
-echo "Updating samba printing configuration if necessary..."
-perl -pi -e 's/= lpstat/= cups/' %{_sysconfdir}/%{name}/smb.conf
-%endif
-
 # Fix the logrotate.d file from smb and nmb to smbd and nmbd
 if [ -f %{_sysconfdir}/logrotate.d/samba ]; then
         perl -pi -e 's/smb /smbd /' %{_sysconfdir}/logrotate.d/samba
@@ -1276,14 +1275,14 @@ fi
 %if %build_winbind
 %post winbind
 if [ $1 = 1 ]; then
-    /sbin/chkconfig winbind%{samba_major} on
+    /sbin/chkconfig winbind on
     cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmsave
     cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmtemp
     for i in passwd group;do
-        grep ^$i %{_sysconfdir}/nsswitch.conf |grep -v 'winbind%{samba_major}' >/dev/null
+        grep ^$i %{_sysconfdir}/nsswitch.conf |grep -v 'winbind' >/dev/null
         if [ $? = 0 ];then
-            echo "Adding a winbind%{samba_major} entry to the $i section of %{_sysconfdir}/nsswitch.conf"
-            awk '/^'$i'/ {print $0 " winbind%{samba_major}"};!/^'$i'/ {print}' %{_sysconfdir}/nsswitch.conf.rpmtemp >%{_sysconfdir}/nsswitch.conf;
+            echo "Adding a winbind entry to the $i section of %{_sysconfdir}/nsswitch.conf"
+            awk '/^'$i'/ {print $0 " winbind"};!/^'$i'/ {print}' %{_sysconfdir}/nsswitch.conf.rpmtemp >%{_sysconfdir}/nsswitch.conf;
            cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmtemp
         else
             echo "$i entry found in %{_sysconfdir}/nsswitch.conf"
@@ -1294,10 +1293,10 @@ fi
 
 %preun winbind
 if [ $1 = 0 ]; then
-       echo "Removing winbind%{samba_major} entries from %{_sysconfdir}/nsswitch.conf"
-       perl -pi -e 's/ winbind%{samba_major}//' %{_sysconfdir}/nsswitch.conf
+       echo "Removing winbind entries from %{_sysconfdir}/nsswitch.conf"
+       perl -pi -e 's/ winbind//' %{_sysconfdir}/nsswitch.conf
 
-       /sbin/chkconfig winbind%{samba_major} reset
+       /sbin/chkconfig winbind reset
 fi
 %endif %build_winbind
 
@@ -1305,10 +1304,10 @@ fi
 %post -n nss_wins%{samba_major}
 if [ $1 = 1 ]; then
     cp -af %{_sysconfdir}/nsswitch.conf %{_sysconfdir}/nsswitch.conf.rpmsave
-    grep '^hosts' %{_sysconfdir}/nsswitch.conf |grep -v 'wins%{samba_major}' >/dev/null
+    grep '^hosts' %{_sysconfdir}/nsswitch.conf |grep -v 'wins' >/dev/null
     if [ $? = 0 ];then
         echo "Adding a wins entry to the hosts section of %{_sysconfdir}/nsswitch.conf"
-        awk '/^hosts/ {print $0 " wins%{samba_major}"};!/^hosts/ {print}' %{_sysconfdir}/nsswitch.conf.rpmsave >%{_sysconfdir}/nsswitch.conf;
+        awk '/^hosts/ {print $0 " wins"};!/^hosts/ {print}' %{_sysconfdir}/nsswitch.conf.rpmsave >%{_sysconfdir}/nsswitch.conf;
     else
         echo "wins entry found in %{_sysconfdir}/nsswitch.conf"
     fi
@@ -1319,7 +1318,7 @@ fi
 %preun -n nss_wins%{samba_major}
 if [ $1 = 0 ]; then
        echo "Removing wins entry from %{_sysconfdir}/nsswitch.conf"
-       perl -pi -e 's/ wins%{samba_major}//' %{_sysconfdir}/nsswitch.conf
+       perl -pi -e 's/ wins//' %{_sysconfdir}/nsswitch.conf
 #else
 #      echo "Leaving %{_sysconfdir}/nsswitch.conf intact"
 fi
@@ -1334,15 +1333,6 @@ if [ $1 = 0 ] ; then
 #    /sbin/chkconfig --level 35 smb reset
 # Let's not loose /var/cache/samba
 
-#    for i in browse.dat wins.dat brlock.tdb unexpected.tdb connections.tdb \
-#locking.tdb messages.tdb;do
-#        if [ -e /var/cache/samba/$i ]; then
-#                mv -f /var/cache/samba/$i /var/cache/samba/$i.BAK
-#        fi;
-#    done
-    if [ -d /var/log/%{name} ]; then
-      rm -rf /var/log/%{name}/*
-    fi
     if [ -d /var/cache/%{name} ]; then
       mv -f /var/cache/%{name} /var/cache/%{name}.BAK
     fi
@@ -1384,37 +1374,30 @@ echo -n " --slave ${i} ${j} ${i}%{alternative_major}";done) \
 update-alternatives --auto smbclient
 
 %preun client
-[ $1 = 0 ] && update-alternatives --remove smbclient %{_bindir}/smbclient%{alternative_major}
+[ $1 = 0 ] && update-alternatives --remove smbclient %{_bindir}/smbclient%{alternative_major} ||:
 %endif
 
-%triggerpostun -- samba < 1.9.18p7
-
-if [ $1 != 0 ]; then
-    /sbin/chkconfig --level 35 smb on
-fi
-
-%triggerpostun -- samba < 2.0.5a-3, samba >= 2.0.0
-
-if [ $1 != 0 ]; then
-        [ ! -d /var/lock/samba ] && mkdir -m 0755 /var/lock/samba ||:
-        [ ! -d /var/spool/samba ] && mkdir -m 1777 /var/spool/samba ||:
-        [ -f %{_sysconfdir}/inetd.conf ] && chmod 644 %{_sysconfdir}/services %{_sysconfdir}/inetd.conf ||:
-fi
+%if %build_alternatives
+%triggerpostun client -- samba-client, samba2-client
+[ ! -e %{_bindir}/smbclient ] && update-alternatives --auto smbclient || :
+%endif
 
 %files server
 %defattr(-,root,root)
 #%attr(-,root,root) /sbin/*
-%{_sbindir}/%{name}
-%{_sbindir}/smbd%{samba_major}
-%{_sbindir}/nmbd%{samba_major}
+%(for i in %{_sbindir}/{%{serversbin}}%{samba_major};do echo $i;done)
+#%{_sbindir}/%{name}
+#%{_sbindir}/smbd%{samba_major}
+#%{_sbindir}/nmbd%{samba_major}
+#%{_sbindir}/mkntpwd%{samba_major}
 #%{_sbindir}/wrepld%{samba_major}
-%{_bindir}/smbcontrol%{samba_major}
-%{_sbindir}/mkntpwd%{samba_major}
-%{_bindir}/smbstatus%{samba_major}
-%{_bindir}/pdbedit%{samba_major}
-%{_bindir}/tdbbackup%{samba_major}
-%{_bindir}/profiles%{samba_major}
-%{_bindir}/editreg%{samba_major}
+%(for i in %{_bindir}/{%{serverbin}}%{samba_major};do echo $i;done)
+#%{_bindir}/smbcontrol%{samba_major}
+#%{_bindir}/smbstatus%{samba_major}
+#%{_bindir}/pdbedit%{samba_major}
+#%{_bindir}/tdbbackup%{samba_major}
+#%{_bindir}/profiles%{samba_major}
+#%{_bindir}/editreg%{samba_major}
 %attr(755,root,root) /%{_lib}/security/pam_smbpass*
 %dir %{_libdir}/%{name}/vfs
 %{_libdir}/%{name}/vfs/*.so
@@ -1439,7 +1422,7 @@ fi
 %attr(775,root,adm) %dir %{_localstatedir}/%{name}/netlogon
 %attr(755,root,root) %dir %{_localstatedir}/%{name}/profiles
 %attr(755,root,root) %dir %{_localstatedir}/%{name}/printers
-%attr(775,root,adm) %dir %{_localstatedir}/%{name}/printers/*
+%attr(2775,root,adm) %dir %{_localstatedir}/%{name}/printers/*
 %attr(1777,root,root) %dir /var/spool/%{name}
 %dir %{_datadir}/%{name}
 %dir %{_datadir}/%{name}/scripts
@@ -1477,6 +1460,14 @@ fi
 %lang(ja) %{_datadir}/swat%{samba_major}/lang/ja
 %lang(tr) %{_datadir}/swat%{samba_major}/lang/tr
 %{_mandir}/man8/swat*.8*
+%lang(de) %{_libdir}/%{name}/de.msg
+%lang(en) %{_libdir}/%{name}/en.msg
+%lang(fr) %{_libdir}/%{name}/fr.msg
+%lang(it) %{_libdir}/%{name}/it.msg
+%lang(ja) %{_libdir}/%{name}/ja.msg
+%lang(nl) %{_libdir}/%{name}/nl.msg
+%lang(pl) %{_libdir}/%{name}/pl.msg
+%lang(tr) %{_libdir}/%{name}/tr.msg
 #%doc swat/README
 
 %files client
@@ -1521,18 +1512,18 @@ fi
 %attr(-,root,root) %{_localstatedir}/%{name}/codepages
 %{_mandir}/man5/smb.conf*.5*
 %{_mandir}/man5/lmhosts*.5*
-%{_mandir}/man7/Samba*.7*
+#%{_mandir}/man7/Samba*.7*
 %dir %{_datadir}/swat%{samba_major}
 
 %if %build_winbind
 %files winbind
 %defattr(-,root,root)
-%{_sbindir}/winbindd%{samba_major}
-%{_sbindir}/winbind%{samba_major}
-%{_bindir}/wbinfo%{samba_major}
+%{_sbindir}/winbindd
+%{_sbindir}/winbind
+%{_bindir}/wbinfo
 %attr(755,root,root) /%{_lib}/security/pam_winbind*
-%attr(755,root,root) /%{_lib}/libnss_winbind%{samba_major}*
-%attr(-,root,root) %config(noreplace) %{_initrddir}/winbind%{samba_major}
+%attr(755,root,root) /%{_lib}/libnss_winbind*
+%attr(-,root,root) %config(noreplace) %{_initrddir}/winbind
 %attr(-,root,root) %config(noreplace) %{_sysconfdir}/pam.d/system-auth-winbind*
 %{_mandir}/man8/winbindd*.8*
 %{_mandir}/man1/wbinfo*.1*
@@ -1541,7 +1532,7 @@ fi
 %if %build_wins
 %files -n nss_wins%{samba_major}
 %defattr(-,root,root)
-%attr(755,root,root) /%{_lib}/libnss_wins%{samba_major}.so*
+%attr(755,root,root) /%{_lib}/libnss_wins.so*
 %endif
 
 %if %{?_with_test:1}%{!?_with_test:0}
@@ -1656,6 +1647,29 @@ fi
 %exclude %{_mandir}/man1/smbsh*.1*
 
 %changelog
+* Sun Nov 16 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.rpe3.3mdk
+- Ensure printer drivers keep permissions by default (setgid and inherit perms)
+
+* Fri Nov 14 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.pre3.2mdk
+- 3.0.1pre3
+- Add support for Mandrake 10.0 (as system samba)
+- Fix alternatives triggers
+- Fix obsoletes
+
+* Mon Nov 10 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.pre2.2mdk
+- 3.0.1pre2
+- misc spec files (pointed out by Luca Olivetti)
+- Fix path to smbldap-passwd.pl
+- Only allow one copy of winbind and nss_wins
+- Add trigger for alternatives
+
+* Sun Oct 12 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.1-0.pre1.2mdk
+- 3.0.1pre1
+- remove buildroot patch (p3), fixed upstream
+
+* Thu Sep 25 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-2mdk
+- 3.0.0 final
+
 * Sat Sep 13 2003 Buchan Milne <bgmilne@linux-mandrake.com> 3.0.0-0.rc4.2mdk
 - rc4
 - Don't update alternatives in pre/post scripts when not using alternatives
index 4981d22174bc0c73659983251a08676319c3bf93..6c1c05fa52e54b6338b09b7bd9b0d9fe8f26a976 100644 (file)
 # Use the samba2 LDAP schema:
 ; passdb backend = ldapsam_compat:ldaps://ldap.mydomain.com smbpasswd guest
 
-# idmap uid account range:
+# Idmap settings:
+# Idmap backend to use:
+; idmap backend = ldap:ldap://ldap.mydomain.com
+
 # This is a range of unix user-id's that samba will map non-unix RIDs to,
 # such as when using Winbind
 ; idmap uid = 10000-20000
 # NOTE: If you have a CUPS print system there is no need to 
 # specifically define each individual printer.
 # You must configure the samba printers with the appropriate Windows
-# drivers on your Windows clients. On the Samba server no filtering is
+# drivers on your Windows clients or upload the printer driver to the
+# server from Windows (NT/2000/XP). On the Samba server no filtering is
 # done. If you wish that the server provides the driver and the clients
 # send PostScript ("Generic PostScript Printer" under Windows), you have
-# to swap the 'print command' line below with the commented one.
+# to use 'printcap name = cups' or swap the 'print command' line below 
+# with the commented one. Note that print commands only work if not using 
+# 'printing=cups'
 [printers]
    comment = All Printers
    path = /var/spool/samba
 # =====================================
    print command = lpr-cups -P %p -o raw %s -r   # using client side printer drivers.
 ;   print command = lpr-cups -P %p %s # using cups own drivers (use generic PostScript on clients).
-# The following two commands are the samba defaults for printing=cups
-# change them only if you need different options:
-;   lpq command = lpq -P %p
-;   lprm command = cancel %p-%j
 
 # This share is used for Windows NT-style point-and-print support.
 # To be able to install drivers, you need to be either root, or listed
 # to the directory and share definition to be able to upload the drivers.
 # For more information on this, please see the Printing Support Section of
 # /usr/share/doc/samba-<version>/docs/Samba-HOWTO-Collection.pdf 
+#
+# A special case is using the CUPS Windows Postscript driver, which allows
+# all features available via CUPS on the client, by publishing the ppd file
+# and the cups driver by using the 'cupsaddsmb' tool. This requires the
+# installation of the CUPS driver (http://www.cups.org/windows.php) 
+# on the server, but doesn't require you to use Windows at all :-).
 [print$]
    path = /var/lib/samba/printers
    browseable = yes
-   read only = yes
    write list = @adm root
    guest ok = yes
+   inherit permissions = yes
+   # Settings suitable for Winbind:
+   ; write list = @"Domain Admins" root
+   ; force group = +@"Domain Admins"
 
 # A useful application of samba is to make a PDF-generation service
 # To streamline this, install windows postscript drivers (preferably colour)
 # on the samba server, so that clients can automatically install them.
-# Note that this only works if 'printcap name' is *not* set to 'cups'
+# Note that this only works if 'printing' is *not* set to 'cups'
 
 [pdf-generator]
    path = /var/tmp
index 6de77780b340d09c127485d8b532202e550150fe..d8bea2421c3d73f63bc9096cfb173447402367a1 100755 (executable)
@@ -37,7 +37,7 @@ case "$1" in
 'restart')
    killproc nmbd
    killproc smbd
-   BASE=/usr/local/samba
+   BASE=__BASEDIR__/samba
    $BASE/bin/smbd -D -s$BASE/lib/smb.conf
    $BASE/bin/nmbd -D -l$BASE/var/log -s$BASE/lib/smb.conf
    ;;
index 4aa34020d6cd4c603112c51a4931d76c7c4cc92a..7ac07dbad726b37ad6132a8324f3723d3242188c 100644 (file)
@@ -294,6 +294,7 @@ MYSQL_OBJ = passdb/pdb_mysql.o
 DEVEL_HELP_WEIRD_OBJ = modules/weird.o
 CP850_OBJ = modules/CP850.o
 CP437_OBJ = modules/CP437.o
+CHARSET_MACOSXFS_OBJ = modules/charset_macosxfs.o
 
 GROUPDB_OBJ = groupdb/mapping.o
 
@@ -494,7 +495,8 @@ CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
 NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \
           utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
           utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \
-          utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o
+          utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \
+          utils/net_status.o
 
 NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
          $(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
@@ -1019,7 +1021,7 @@ bin/librpc_echo.@SHLIBEXT@: $(RPC_ECHO_OBJ)
 
 bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy
        @echo "Linking $@"
-       @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) 
+       @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS)
 
 # Please don't add .o files to libnss_winbind, libnss_wins, or the pam_winbind
 # libraries.  Add to the appropriate PICOBJ variable instead.
@@ -1103,6 +1105,11 @@ bin/CP437.@SHLIBEXT@: $(CP437_OBJ:.o=.@PICSUFFIX@)
        @$(SHLD) $(LDSHFLAGS) -o $@ $(CP437_OBJ:.o=.@PICSUFFIX@) \
                @SONAMEFLAG@`basename $@`
 
+bin/macosxfs.@SHLIBEXT@: $(CHARSET_MACOSXFS_OBJ:.o=.po)
+       @echo "Building plugin $@"
+       @$(SHLD) $(LDSHFLAGS) -o $@ $(CHARSET_MACOSXFS_OBJ:.o=.po) \
+               -framework CoreFoundation @SONAMEFLAG@`basename $@`
+
 bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.@PICSUFFIX@)
        @echo "Building plugin $@"
        @$(SHLD) $(LDSHFLAGS) -o $@ $(XML_OBJ:.o=.@PICSUFFIX@) @XML_LIBS@ \
index 3ee23fd66a3f97362aff23b86313a8ea75d57b1b..d727326a6ac96e9d38d78aa81b76408a103f2d3f 100644 (file)
@@ -41,7 +41,7 @@ SAMBA_VERSION_REVISION=
 # e.g. SAMBA_VERSION_PRE_RELEASE=1                     #
 #  ->  "2.2.9pre1"                                     #
 ########################################################
-SAMBA_VERSION_PRE_RELEASE=3
+SAMBA_VERSION_PRE_RELEASE=
 
 ########################################################
 # For 'rc' releases the version will be                #
@@ -51,7 +51,7 @@ SAMBA_VERSION_PRE_RELEASE=3
 # e.g. SAMBA_VERSION_RC_RELEASE=1                      #
 #  ->  "3.0.0rc1"                                      #
 ########################################################
-SAMBA_VERSION_RC_RELEASE=
+SAMBA_VERSION_RC_RELEASE=1
 
 ########################################################
 # For 'beta' releases the version will be              #
index 553d9a686e31b82a6d52b4c5088d1aa67bd12d01..1b49699fbca5e711f126d2fcfee15c415787292a 100644 (file)
@@ -88,6 +88,8 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
                return auth_context->challenge.data;
        }
 
+       auth_context->challenge_may_be_modified = False;
+
        for (auth_method = auth_context->auth_method_list; auth_method; auth_method = auth_method->next) {
                if (auth_method->get_chal == NULL) {
                        DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name));
@@ -127,6 +129,7 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
                                                           chal, sizeof(chal));
                
                challenge_set_by = "random";
+               auth_context->challenge_may_be_modified = True;
        } 
        
        DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by));
@@ -318,9 +321,20 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
 
 static void free_auth_context(struct auth_context **auth_context)
 {
-       if (*auth_context != NULL)
+       auth_methods *auth_method;
+
+       if (*auth_context) {
+               /* Free private data of context's authentication methods */
+               for (auth_method = (*auth_context)->auth_method_list; auth_method; auth_method = auth_method->next) {
+                       if (auth_method->free_private_data) {
+                               auth_method->free_private_data (&auth_method->private_data);
+                               auth_method->private_data = NULL;
+                       }
+               }
+
                talloc_destroy((*auth_context)->mem_ctx);
-       *auth_context = NULL;
+               *auth_context = NULL;
+       }
 }
 
 /***************************************************************************
index 3af0cbaada4fe76dd920847453bc5cad70905315..a5ce101e5e7360b46e458918f0e6dacd549ad2ff 100644 (file)
 
 #include "includes.h"
 
-static const uint8 *auth_ntlmssp_get_challenge(struct ntlmssp_state *ntlmssp_state)
+/**
+ * Return the challenge as determined by the authentication subsystem 
+ * @return an 8 byte random challenge
+ */
+
+static const uint8 *auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state)
 {
        AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
        return auth_ntlmssp_state->auth_context->get_ntlm_challenge(auth_ntlmssp_state->auth_context);
 }
 
-static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state) 
+/**
+ * Some authentication methods 'fix' the challenge, so we may not be able to set it
+ *
+ * @return If the effective challenge used by the auth subsystem may be modified
+ */
+static BOOL auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
+{
+       AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
+       struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
+
+       return auth_context->challenge_may_be_modified;
+}
+
+/**
+ * NTLM2 authentication modifies the effective challange, 
+ * @param challenge The new challenge value
+ */
+static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
+{
+       AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
+       struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
+
+       SMB_ASSERT(challenge->length == 8);
+
+       auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, 
+                                                  challenge->data, challenge->length);
+
+       auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
+
+       DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
+       DEBUG(5, ("challenge is: \n"));
+       dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length);
+       return NT_STATUS_OK;
+}
+
+/**
+ * Check the password on an NTLMSSP login.  
+ *
+ * Return the session keys used on the connection.
+ */
+
+static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key) 
 {
        AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context;
        uint32 auth_flags = AUTH_FLAG_NONE;
@@ -45,7 +91,7 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state)
                auth_flags |= AUTH_FLAG_NTLM_RESP;
        } else  if (auth_ntlmssp_state->ntlmssp_state->nt_resp.length > 24) {
                auth_flags |= AUTH_FLAG_NTLMv2_RESP;
-       };
+       }
 
        /* the client has given us its machine name (which we otherwise would not get on port 445).
           we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
@@ -71,10 +117,26 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state)
                return nt_status;
        }
 
-       nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, user_info, &auth_ntlmssp_state->server_info); 
-                       
+       nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, 
+                                                                         user_info, &auth_ntlmssp_state->server_info); 
+
        free_user_info(&user_info);
 
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               return nt_status;
+       }
+       if (auth_ntlmssp_state->server_info->nt_session_key.length) {
+               DEBUG(10, ("Got NT session key of length %u\n", auth_ntlmssp_state->server_info->nt_session_key.length));
+               *nt_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, 
+                                                  auth_ntlmssp_state->server_info->nt_session_key.data,
+                                                  auth_ntlmssp_state->server_info->nt_session_key.length);
+       }
+       if (auth_ntlmssp_state->server_info->lm_session_key.length) {
+               DEBUG(10, ("Got LM session key of length %u\n", auth_ntlmssp_state->server_info->lm_session_key.length));
+               *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, 
+                                                  auth_ntlmssp_state->server_info->lm_session_key.data,
+                                                  auth_ntlmssp_state->server_info->lm_session_key.length);
+       }
        return nt_status;
 }
 
@@ -106,18 +168,20 @@ NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
 
        (*auth_ntlmssp_state)->ntlmssp_state->auth_context = (*auth_ntlmssp_state);
        (*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
+       (*auth_ntlmssp_state)->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
+       (*auth_ntlmssp_state)->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
        (*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password;
        (*auth_ntlmssp_state)->ntlmssp_state->server_role = lp_server_role();
 
        return NT_STATUS_OK;
 }
 
-NTSTATUS auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
+void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
 {
        TALLOC_CTX *mem_ctx = (*auth_ntlmssp_state)->mem_ctx;
 
        if ((*auth_ntlmssp_state)->ntlmssp_state) {
-               ntlmssp_server_end(&(*auth_ntlmssp_state)->ntlmssp_state);
+               ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state);
        }
        if ((*auth_ntlmssp_state)->auth_context) {
                ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context);
@@ -127,11 +191,10 @@ NTSTATUS auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
        }
        talloc_destroy(mem_ctx);
        *auth_ntlmssp_state = NULL;
-       return NT_STATUS_OK;
 }
 
 NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state, 
                             const DATA_BLOB request, DATA_BLOB *reply) 
 {
-       return ntlmssp_server_update(auth_ntlmssp_state->ntlmssp_state, request, reply);
+       return ntlmssp_update(auth_ntlmssp_state->ntlmssp_state, request, reply);
 }
index 2a00b6fb807712fd93a5e544b77650d4b835003b..7352a9685be2b3b3680822fbfe5a833462818dc3 100644 (file)
@@ -33,7 +33,7 @@
 static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response,
                                 const uchar *part_passwd,
                                 const DATA_BLOB *sec_blob,
-                                uint8 user_sess_key[16])
+                                DATA_BLOB *user_sess_key)
 {
        /* Finish the encryption of part_passwd. */
        uchar p24[24];
@@ -56,7 +56,8 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response,
 
        SMBOWFencrypt(part_passwd, sec_blob->data, p24);
        if (user_sess_key != NULL) {
-               SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key);
+               *user_sess_key = data_blob(NULL, 16);
+               SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data);
        }
        
        
@@ -83,7 +84,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
                                 const uchar *part_passwd,
                                 const DATA_BLOB *sec_blob,
                                 const char *user, const char *domain,
-                                uint8 user_sess_key[16])
+                                DATA_BLOB *user_sess_key)
 {
        /* Finish the encryption of part_passwd. */
        uchar kr[16];
@@ -120,7 +121,8 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
 
        SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption);
        if (user_sess_key != NULL) {
-               SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key);
+               *user_sess_key = data_blob(NULL, 16);
+               SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data);
        }
 
 #if DEBUG_PASSWORD
@@ -148,7 +150,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
                                TALLOC_CTX *mem_ctx,
                                SAM_ACCOUNT *sampass, 
                                const auth_usersupplied_info *user_info, 
-                               uint8 user_sess_key[16])
+                               DATA_BLOB *user_sess_key, 
+                               DATA_BLOB *lm_sess_key)
 {
        uint16 acct_ctrl;
        const uint8 *nt_pw, *lm_pw;
@@ -225,6 +228,16 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
                        if (smb_pwd_check_ntlmv1(&user_info->nt_resp, 
                                                 nt_pw, &auth_context->challenge,
                                                 user_sess_key)) {
+                               /* The LM session key for this response is not very secure, 
+                                  so use it only if we otherwise allow LM authentication */
+                               lm_pw = pdb_get_lanman_passwd(sampass);
+
+                               if (lp_lanman_auth() && lm_pw) {
+                                       uint8 first_8_lm_hash[16];
+                                       memcpy(first_8_lm_hash, lm_pw, 8);
+                                       memset(first_8_lm_hash + 8, '\0', 8);
+                                       *lm_sess_key = data_blob(first_8_lm_hash, 16);
+                               }
                                return NT_STATUS_OK;
                        } else {
                                DEBUG(3,("sam_password_ok: NT MD4 password check failed for user %s\n",pdb_get_username(sampass)));
@@ -252,7 +265,12 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
                        DEBUG(4,("sam_password_ok: Checking LM password\n"));
                        if (smb_pwd_check_ntlmv1(&user_info->lm_resp, 
                                                 lm_pw, &auth_context->challenge,
-                                                user_sess_key)) {
+                                                NULL)) {
+                               uint8 first_8_lm_hash[16];
+                               memcpy(first_8_lm_hash, lm_pw, 8);
+                               memset(first_8_lm_hash + 8, '\0', 8);
+                               *user_sess_key = data_blob(first_8_lm_hash, 16);
+                               *lm_sess_key = data_blob(first_8_lm_hash, 16);
                                return NT_STATUS_OK;
                        }
                }
@@ -272,7 +290,7 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
                                          nt_pw, &auth_context->challenge, 
                                          user_info->smb_name.str, 
                                          user_info->client_domain.str,
-                                         user_sess_key)) {
+                                         NULL)) {
                        return NT_STATUS_OK;
                }
 
@@ -281,7 +299,7 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
                                          nt_pw, &auth_context->challenge, 
                                          user_info->smb_name.str, 
                                          "",
-                                         user_sess_key)) {
+                                         NULL)) {
                        return NT_STATUS_OK;
                }
 
@@ -292,7 +310,19 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
                if (lp_ntlm_auth()) {
                        if (smb_pwd_check_ntlmv1(&user_info->lm_resp, 
                                                 nt_pw, &auth_context->challenge,
-                                                user_sess_key)) {
+                                                NULL)) {
+                               /* The session key for this response is still very odd.  
+                                  It not very secure, so use it only if we otherwise 
+                                  allow LM authentication */
+                               lm_pw = pdb_get_lanman_passwd(sampass);
+                       
+                               if (lp_lanman_auth() && lm_pw) {
+                                       uint8 first_8_lm_hash[16];
+                                       memcpy(first_8_lm_hash, lm_pw, 8);
+                                       memset(first_8_lm_hash + 8, '\0', 8);
+                                       *user_sess_key = data_blob(first_8_lm_hash, 16);
+                                       *lm_sess_key = data_blob(first_8_lm_hash, 16);
+                               }
                                return NT_STATUS_OK;
                        }
                        DEBUG(3,("sam_password_ok: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",pdb_get_username(sampass)));
@@ -301,7 +331,6 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
                        DEBUG(3,("sam_password_ok: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",pdb_get_username(sampass)));
                        return NT_STATUS_WRONG_PASSWORD;
                }
-                       
        }
                
        /* Should not be reached, but if they send nothing... */
@@ -421,8 +450,8 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
        SAM_ACCOUNT *sampass=NULL;
        BOOL ret;
        NTSTATUS nt_status;
-       uint8 user_sess_key[16];
-       const uint8* lm_hash;
+       DATA_BLOB user_sess_key = data_blob(NULL, 0);
+       DATA_BLOB lm_sess_key = data_blob(NULL, 0);
 
        if (!user_info || !auth_context) {
                return NT_STATUS_UNSUCCESSFUL;
@@ -446,7 +475,8 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
                return NT_STATUS_NO_SUCH_USER;
        }
 
-       nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key);
+       nt_status = sam_password_ok(auth_context, mem_ctx, sampass, 
+                                   user_info, &user_sess_key, &lm_sess_key);
        
        if (!NT_STATUS_IS_OK(nt_status)) {
                pdb_free_sam(&sampass);
@@ -465,12 +495,8 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
                return nt_status;
        }
 
-       lm_hash = pdb_get_lanman_passwd((*server_info)->sam_account);
-       if (lm_hash) {
-               memcpy((*server_info)->first_8_lm_hash, lm_hash, 8);
-       }
-       
-       memcpy((*server_info)->session_key, user_sess_key, sizeof(user_sess_key));
+       (*server_info)->nt_session_key = user_sess_key;
+       (*server_info)->lm_session_key = lm_sess_key;
 
        return nt_status;
 }
index b57293943c039346b24053419d1d9e41b3fbeaaa..41adc2178416eee813356d2da5de5d4d6da5c077 100644 (file)
@@ -143,8 +143,10 @@ static void free_server_private_data(void **private_data_pointer)
 {
        struct cli_state **cli = (struct cli_state **)private_data_pointer;
        if (*cli && (*cli)->initialised) {
+               DEBUG(10, ("Shutting down smbserver connection\n"));
                cli_shutdown(*cli);
        }
+       *private_data_pointer = NULL;
 }
 
 /****************************************************************************
index d7d7f53e2d4898c7133d04c16591585c5695c877..5d3f8f02777b2b120bd45b2ce65418283704aa4b 100644 (file)
@@ -900,7 +900,13 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
        nt_status = make_server_info_sam(server_info, sampass);
 
        if (NT_STATUS_IS_OK(nt_status)) {
+               static const char zeros[16];
                (*server_info)->guest = True;
+               
+               /* annoying, but the Guest really does have a session key, 
+                  and it is all zeros! */
+               (*server_info)->nt_session_key = data_blob(zeros, sizeof(zeros));
+               (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
        }
 
        return nt_status;
@@ -992,6 +998,8 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
                                auth_serversupplied_info **server_info, 
                                NET_USER_INFO_3 *info3) 
 {
+       static const char zeros[16];
+
        NTSTATUS nt_status = NT_STATUS_OK;
        char *found_username;
        const char *nt_domain;
@@ -1210,10 +1218,20 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
        (*server_info)->ptok = token; 
 
        SAFE_FREE(all_group_SIDs);
+
+       /* ensure we are never given NULL session keys */
        
-       memcpy((*server_info)->session_key, info3->user_sess_key, sizeof((*server_info)->session_key)/* 16 */);
-       memcpy((*server_info)->first_8_lm_hash, info3->padding, 8);
+       if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
+               (*server_info)->nt_session_key = data_blob(NULL, 0);
+       } else {
+               (*server_info)->nt_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));
+       }
 
+       if (memcmp(info3->padding, zeros, sizeof(zeros)) == 0) {
+               (*server_info)->lm_session_key = data_blob(NULL, 0);
+       } else {
+               (*server_info)->lm_session_key = data_blob(info3->padding, 16);
+       }
        return NT_STATUS_OK;
 }
 
@@ -1256,6 +1274,8 @@ void free_server_info(auth_serversupplied_info **server_info)
                delete_nt_token( &(*server_info)->ptok );
                SAFE_FREE((*server_info)->groups);
                SAFE_FREE((*server_info)->unix_name);
+               data_blob_free(&(*server_info)->lm_session_key);
+               data_blob_free(&(*server_info)->nt_session_key);
                ZERO_STRUCT(**server_info);
        }
        SAFE_FREE(*server_info);
index 6a9a8f0f15ec9a23ba7342791e8f331a5a0ad621..174a48b87e3566c6476f4ab079f458dcdda25116 100644 (file)
@@ -126,6 +126,25 @@ AC_ARG_WITH(logfilebase,
     ;;
   esac])
 
+AC_ARG_WITH(cfenc,
+[  --with-cfenc=HEADERDIR  Use internal CoreFoundation encoding API
+                         for optimization (Mac OS X/Darwin only)],
+[
+# May be in source $withval/CoreFoundation/StringEncodings.subproj.
+# Should have been in framework $withval/CoreFoundation.framework/Headers.
+for d in \
+    $withval/CoreFoundation/StringEncodings.subproj \
+    $withval/StringEncodings.subproj \
+    $withval/CoreFoundation.framework/Headers \
+    $withval/Headers \
+    $withval
+do
+    if test -r $d/CFStringEncodingConverter.h; then
+        ln -sfh $d include/CoreFoundation
+    fi
+done
+])
+
 AC_SUBST(configdir)
 AC_SUBST(lockdir)
 AC_SUBST(piddir)
@@ -201,6 +220,10 @@ OLD_CFLAGS=${CFLAGS}
 AC_PROG_CC
 CFLAGS=${OLD_CFLAGS}
 
+OLD_CFLAGS=${CFLAGS}
+AC_PROG_CPP
+CFLAGS=${OLD_CFLAGS}
+
 AC_PROG_INSTALL
 AC_PROG_AWK
 AC_PATH_PROG(PERL, perl)
@@ -430,7 +453,7 @@ case "$host_os" in
          *)
                CPPFLAGS="$CPPFLAGS -D_SYSV"
                AC_DEFINE(_SYSV, 1, [Whether to enable System V compatibility])
-   esac
+    esac
     ;;
 #
 # Tests needed for SINIX large file support.
@@ -502,15 +525,15 @@ main() {
 #endif
 }
 ], [LINUX_LFS_SUPPORT=yes], [LINUX_LFS_SUPPORT=no], [LINUX_LFS_SUPPORT=cross])
-        CPPFLAGS="$old_CPPFLAGS"
-        if test x$LINUX_LFS_SUPPORT = xyes ; then
-          CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS"
-                 AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support])
-          AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits])
-          AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions])
-        fi
-       AC_MSG_RESULT([$LINUX_LFS_SUPPORT])
-               ;;
+       CPPFLAGS="$old_CPPFLAGS"
+       if test x$LINUX_LFS_SUPPORT = xyes ; then
+               CPPFLAGS="-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $CPPFLAGS"
+               AC_DEFINE(_LARGEFILE64_SOURCE, 1, [Whether to enable large file support])
+               AC_DEFINE(_FILE_OFFSET_BITS, 64, [File offset bits])
+               AC_DEFINE(_GNU_SOURCE, 1, [Whether to use GNU libc extensions])
+       fi
+       AC_MSG_RESULT([$LINUX_LFS_SUPPORT])
+       ;;
 
 #
 # MacOS X is the *only* system that uses compose character in utf8. This
@@ -528,10 +551,16 @@ main() {
 # use that instead of plain dlsym.
 
                AC_CHECK_LIB(dl,dlopen)
-               AC_CHECK_FUNCS(dlsym_prepend_underscore,
-               [CPPFLAGS="$CPPFLAGS -Ddlsym=dlsym_prepend_underscore"])
+               AC_CHECK_FUNCS(dlsym_prepend_underscore,[CPPFLAGS="$CPPFLAGS -Ddlsym=dlsym_prepend_underscore"])
 
-               ;;   
+#Add a system specific charset module.
+
+               default_shared_modules="$default_shared_modules charset_macosxfs"
+               old_CPPFLAGS="$CPPFLAGS"
+               CPPFLAGS="-Iinclude $CPPFLAGS" 
+               AC_CHECK_HEADERS([CoreFoundation/CFStringEncodingConverter.h], [], [AC_CHECK_HEADERS([CFStringEncodingConverter.h])])
+               CPPFLAGS="$old_CPPFLAGS"
+               ;;
     *hurd*)
         AC_MSG_CHECKING([for LFS support])
         old_CPPFLAGS="$CPPFLAGS"
@@ -3931,9 +3960,12 @@ WINBIND_WINS_NSS="nsswitch/libnss_wins.$SHLIBEXT"
 WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS
 
 case "$host_os" in
-       *linux*|*freebsd*)
+       *linux*)
                WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o"
                ;;
+       *freebsd5*)
+               WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_freebsd.o"
+               ;;
        *irix*)
                # IRIX has differently named shared libraries
                WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_irix.o"
@@ -4164,6 +4196,7 @@ SMB_SUBSYSTEM(IDMAP,sam/idmap.o)
 SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET)
 SMB_MODULE(charset_CP850, modules/CP850.o, "bin/CP850.$SHLIBEXT", CHARSET)
 SMB_MODULE(charset_CP437, modules/CP437.o, "bin/CP437.$SHLIBEXT", CHARSET)
+SMB_MODULE(charset_macosxfs, modules/charset_macosxfs.o,"bin/macosxfs.$SHLIBEXT", CHARSET)
 SMB_SUBSYSTEM(CHARSET,lib/iconv.o)
 
 SMB_MODULE(auth_rhosts, \$(AUTH_RHOSTS_OBJ), "bin/rhosts.$SHLIBEXT", AUTH)
index 7a07b5c344816bc3879204de654bed5bd772f2f9..b1c260581ee5ef7f7b943a2199ae532be78a5385 100644 (file)
@@ -547,27 +547,28 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map)
 
 BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map)
 {
-       struct group *grp;
-
        if(!init_group_mapping()) {
                DEBUG(0,("failed to initialize group mapping"));
                return(False);
        }
 
        /* The group is in the mapping table */
-       if(pdb_getgrsid(map, sid)) {
-               if (map->sid_name_use!=SID_NAME_ALIAS) {
-                       return False;
-               }
+       
+       if( !pdb_getgrsid(map, sid) ) 
+               return False;
                
-               if (map->gid==-1) {
-                       return False;
-               }
-
-               if ( (grp=getgrgid(map->gid)) == NULL) {
-                       return False;
-               }
-       } else {
+       if ( (map->sid_name_use != SID_NAME_ALIAS)
+               || (map->gid == -1)
+               || (getgrgid(map->gid) == NULL) ) 
+       {
+               return False;
+       }               
+                       
+#if 0  /* JERRY */
+       /* local groups only exist in the group mapping DB so this 
+          is not necessary */
+          
+       else {
                /* the group isn't in the mapping table.
                 * make one based on the unix information */
                uint32 alias_rid;
@@ -588,6 +589,7 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map)
 
                sid_copy(&map->sid, &sid);
        }
+#endif
 
        return True;
 }
@@ -629,6 +631,7 @@ Returns a GROUP_MAP struct based on the gid.
 BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
 {
        struct group *grp;
+       BOOL ret;
 
        if(!init_group_mapping()) {
                DEBUG(0,("failed to initialize group mapping"));
@@ -641,7 +644,12 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
        /*
         * make a group map from scratch if doesn't exist.
         */
-       if (!pdb_getgrgid(map, gid)) {
+       
+       become_root();
+       ret = pdb_getgrgid(map, gid);
+       unbecome_root();
+       
+       if ( !ret ) {
                map->gid=gid;
                map->sid_name_use=SID_NAME_ALIAS;
 
index 6b42418be8d4d3dce1d1f22509c017225068d95f..ecf4d539d8c032826fc14c0eb4f07742a9eb3f00 100644 (file)
@@ -87,10 +87,9 @@ typedef struct auth_serversupplied_info
        
        NT_USER_TOKEN *ptok;
        
-       uint8 session_key[16];
+       DATA_BLOB nt_session_key;
+       DATA_BLOB lm_session_key;
        
-       uint8 first_8_lm_hash[8];
-
        uint32 sam_fill_level;  /* How far is this structure filled? */
        
        SAM_ACCOUNT *sam_account;
@@ -107,6 +106,8 @@ struct auth_context {
        /* Who set this up in the first place? */ 
        const char *challenge_set_by; 
 
+       BOOL challenge_may_be_modified;
+
        struct auth_methods *challenge_set_method; 
        /* What order are the various methods in?   Try to stop it changing under us */ 
        struct auth_methods *auth_method_list;  
index 598e6c0bda521ef72251cddabc20238c377e4a52..968b73f0b41cdaadd6eee576b5f880e9795d1b3c 100644 (file)
@@ -113,7 +113,7 @@ struct cli_state {
 
        /* the session key for this CLI, outside 
           any per-pipe authenticaion */
-       unsigned char user_session_key[16];
+       DATA_BLOB user_session_key;
 
        /*
         * Only used in NT domain calls.
@@ -133,7 +133,7 @@ struct cli_state {
                                               schannel. */
        struct netsec_auth_struct auth_info;
 
-       NTLMSSP_CLIENT_STATE *ntlmssp_pipe_state;
+       NTLMSSP_STATE *ntlmssp_pipe_state;
 
        unsigned char sess_key[16];        /* Current session key. */
        DOM_CRED clnt_cred;                /* Client credential. */
index ebb09b6c6ceeb62a382976ecf655bdfeb8b37ee4..638648dc44d659cf1a5ec5f56283b9f131174b01 100644 (file)
@@ -1298,7 +1298,7 @@ krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
 krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters);
 krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
 void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);
-BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote);
+BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote);
 #endif /* HAVE_KRB5 */
 
 /* TRUE and FALSE are part of the C99 standard and gcc, but
index 3fe8f41d8d4dcdde8f1d6e55ea8331073f46cad6..b1a4107980d55a2c7cb5067163c4f65523ef1999 100644 (file)
@@ -229,7 +229,7 @@ typedef struct pipes_struct
        fstring pipe_user_name;
        struct current_user pipe_user;
 
-       uint8 session_key[16];
+       DATA_BLOB session_key;
 
        /*
         * Set to true when an RPC bind has been done on this pipe.
index f1b1bc25e43ea6d7dfc5c6f19db23d29c44f7b46..681d4071dbb4ee3dc445213e1b20d8cf0b6c13cb 100644 (file)
@@ -30,6 +30,7 @@ enum NTLMSSP_ROLE
 /* NTLMSSP message types */
 enum NTLM_MESSAGE_TYPE
 {
+       NTLMSSP_INITIAL = 0 /* samba internal state */,
        NTLMSSP_NEGOTIATE = 1,
        NTLMSSP_CHALLENGE = 2,
        NTLMSSP_AUTH      = 3,
@@ -70,29 +71,10 @@ enum NTLM_MESSAGE_TYPE
 typedef struct ntlmssp_state 
 {
        TALLOC_CTX *mem_ctx;
+       unsigned int ref_count;
        enum NTLMSSP_ROLE role;
-       BOOL unicode;
-       char *user;
-       char *domain;
-       char *workstation;
-       DATA_BLOB lm_resp;
-       DATA_BLOB nt_resp;
-       DATA_BLOB chal;
-       void *auth_context;
-       const uint8 *(*get_challenge)(struct ntlmssp_state *ntlmssp_state);
-       NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state);
-
-       const char *(*get_global_myname)(void);
-       const char *(*get_domain)(void);
-
-       int server_role;
+       enum server_types server_role;
        uint32 expected_state;
-} NTLMSSP_STATE;
-
-typedef struct ntlmssp_client_state 
-{
-       TALLOC_CTX *mem_ctx;
-       unsigned int ref_count;
 
        BOOL unicode;
        BOOL use_ntlmv2;
@@ -102,30 +84,78 @@ typedef struct ntlmssp_client_state
        char *password;
        char *server_domain;
 
-       const char *(*get_global_myname)(void);
-       const char *(*get_domain)(void);
+       DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */
 
-       DATA_BLOB chal;
+       DATA_BLOB chal; /* Random challenge as input into the actual NTLM (or NTLM2) authentication */
        DATA_BLOB lm_resp;
        DATA_BLOB nt_resp;
        DATA_BLOB session_key;
        
-       uint32 neg_flags;
+       uint32 neg_flags; /* the current state of negotiation with the NTLMSSP partner */
        
+       void *auth_context;
+
+       /**
+        * Callback to get the 'challenge' used for NTLM authentication.  
+        *
+        * @param ntlmssp_state This structure
+        * @return 8 bytes of challnege data, determined by the server to be the challenge for NTLM authentication
+        *
+        */
+       const uint8 *(*get_challenge)(const struct ntlmssp_state *ntlmssp_state);
+
+       /**
+        * Callback to find if the challenge used by NTLM authentication may be modified 
+        *
+        * The NTLM2 authentication scheme modifies the effective challenge, but this is not compatiable with the
+        * current 'security=server' implementation..  
+        *
+        * @param ntlmssp_state This structure
+        * @return Can the challenge be set to arbitary values?
+        *
+        */
+       BOOL (*may_set_challenge)(const struct ntlmssp_state *ntlmssp_state);
+
+       /**
+        * Callback to set the 'challenge' used for NTLM authentication.  
+        *
+        * The callback may use the void *auth_context to store state information, but the same value is always available
+        * from the DATA_BLOB chal on this structure.
+        *
+        * @param ntlmssp_state This structure
+        * @param challange 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication
+        *
+        */
+       NTSTATUS (*set_challenge)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge);
+
+       /**
+        * Callback to check the user's password.  
+        *
+        * The callback must reads the feilds of this structure for the information it needs on the user 
+        * @param ntlmssp_state This structure
+        * @param nt_session_key If an NT session key is returned by the authentication process, return it here
+        * @param lm_session_key If an LM session key is returned by the authentication process, return it here
+        *
+        */
+       NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key);
+
+       const char *(*get_global_myname)(void);
+       const char *(*get_domain)(void);
+
        /* SMB Signing */
        
        uint32 ntlmssp_seq_num;
 
        /* ntlmv2 */
-       char cli_sign_const[16];
-       char cli_seal_const[16];
-       char srv_sign_const[16];
-       char srv_seal_const[16];
+       char send_sign_const[16];
+       char send_seal_const[16];
+       char recv_sign_const[16];
+       char recv_seal_const[16];
 
-       unsigned char cli_sign_hash[258];
-       unsigned char cli_seal_hash[258];
-       unsigned char srv_sign_hash[258];
-       unsigned char srv_seal_hash[258];
+       unsigned char send_sign_hash[258];
+       unsigned char send_seal_hash[258];
+       unsigned char recv_sign_hash[258];
+       unsigned char recv_seal_hash[258];
 
        /* ntlmv1 */
        unsigned char ntlmssp_hash[258];
@@ -135,5 +165,5 @@ typedef struct ntlmssp_client_state
           Store it here, until we need it */
        DATA_BLOB stored_response; 
        
-} NTLMSSP_CLIENT_STATE;
+} NTLMSSP_STATE;
 
index a4b2bcff3fd34dca18b8114d76845927c83db579..3e9036aef7777c37fa2f63cb4198f99df9009f60 100644 (file)
@@ -98,7 +98,7 @@ typedef struct sam_passwd
        struct pdb_methods *methods;
 
        struct user_data {
-               /* initiailization flags */
+               /* initialization flags */
                struct bitmap *change_flags;
                struct bitmap *set_flags;
 
@@ -161,7 +161,7 @@ typedef struct sam_group {
        struct pdb_methods *methods;
 
        struct group_data {
-               /* initiailization flags */
+               /* initialization flags */
                struct bitmap *change_flags;
                struct bitmap *set_flags;
 
index 3b81042df373d7eb39d3ff8583a58590c5cd9a6e..787535d0e90165dc0ee82a2f049a54a46c1c37d6 100644 (file)
@@ -127,7 +127,7 @@ SamrTestPrivateFunctionsUser
 #define SAMR_UNKNOWN_2a        0x2a
 #define SAMR_UNKNOWN_2b        0x2b
 #define SAMR_GET_USRDOM_PWINFO 0x2c
-#define SAMR_REMOVE_USER_FOREIGN_DOMAIN        0x2d
+#define SAMR_REMOVE_SID_FOREIGN_DOMAIN        0x2d
 #define SAMR_UNKNOWN_2E        0x2e /* looks like an alias for SAMR_QUERY_DOMAIN_INFO */
 #define SAMR_UNKNOWN_2f        0x2f
 #define SAMR_QUERY_DISPINFO3   0x30 /* Alias for SAMR_QUERY_DISPINFO
@@ -1790,21 +1790,21 @@ typedef struct r_samr_chgpasswd_user_info
 } SAMR_R_CHGPASSWD_USER;
 
 
-/* SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN */
-typedef struct q_samr_remove_user_foreign_domain_info
+/* SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN */
+typedef struct q_samr_remove_sid_foreign_domain_info
 {
        POLICY_HND dom_pol;   /* policy handle */
        DOM_SID2 sid;         /* SID */
 
-} SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN;
+} SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN;
 
 
-/* SAMR_R_REMOVE_USER_FOREIGN_DOMAIN */
-typedef struct r_samr_remove_user_foreign_domain_info
+/* SAMR_R_REMOVE_SID_FOREIGN_DOMAIN */
+typedef struct r_samr_remove_sid_foreign_domain_info
 {
        NTSTATUS status;         /* return status */
 
-} SAMR_R_REMOVE_USER_FOREIGN_DOMAIN;
+} SAMR_R_REMOVE_SID_FOREIGN_DOMAIN;
 
 
 
index e41b5834f70b6b1116137da70c13a451a4484d99..4bd40216d7b01765ccd2dcc944996d14e996dec5 100644 (file)
@@ -1546,7 +1546,7 @@ typedef struct user_struct
 
        NT_USER_TOKEN *nt_user_token;
 
-       uint8 session_key[16];
+       DATA_BLOB session_key;
 
        char *session_keystr; /* used by utmp and pam session code.  
                                 TDB key string */
index 9765b9fbd609a062d714fae260a9bd094e19c549..17584c4fe4caa445389334d5c58b999a32488493 100644 (file)
@@ -90,6 +90,7 @@
 #define LDAP_ATTR_NEXT_RID              34
 #define LDAP_ATTR_BAD_PASSWORD_COUNT   35
 #define LDAP_ATTR_LOGON_COUNT          36
+#define LDAP_ATTR_MUNGED_DIAL          37
 
 typedef struct _attrib_map_entry {
        int             attrib;
index a642a92d7163ef97a64dd69e1c83ba122696e586..81eab7c738e81e339d13f000e235ae13f9386cec 100644 (file)
@@ -114,7 +114,7 @@ static BOOL string_match(const char *tok,const char *s, char *invalid_char)
        } else if (strequal(tok, "LOCAL")) {    /* local: no dots */
                if (strchr_m(s, '.') == 0 && !strequal(s, "unknown"))
                        return (True);
-       } else if (!strequal(tok, s)) {   /* match host name or address */
+       } else if (strequal(tok, s)) {   /* match host name or address */
                return (True);
        } else if (tok[(tok_len = strlen(tok)) - 1] == '.') {   /* network */
                if (strncmp(tok, s, tok_len) == 0)
index 0a6a1fc75d6b42cf28508c1f3cdce2a83fe8ac29..6a004021939dbcf411a4052b3ce73e8bba131f15 100644 (file)
@@ -488,7 +488,6 @@ convert:
        }
 }
 
-
 /**
  * Convert between character sets, allocating a new buffer using talloc for the result.
  *
@@ -581,19 +580,19 @@ char *strdup_upper(const char *s)
 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
 {
        size_t size;
-       smb_ucs2_t *buffer;
+       smb_ucs2_t *buffer = NULL;
        
        size = convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, srclen,
                                       (void **) &buffer);
-       if (size == -1) {
+       if (size == -1 || !buffer) {
                smb_panic("failed to create UCS2 buffer");
        }
        if (!strlower_w(buffer) && (dest == src)) {
-               free(buffer);
+               SAFE_FREE(buffer);
                return srclen;
        }
        size = convert_string(CH_UCS2, CH_UNIX, buffer, size, dest, destlen);
-       free(buffer);
+       SAFE_FREE(buffer);
        return size;
 }
 
@@ -604,11 +603,11 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
 char *strdup_lower(const char *s)
 {
        size_t size;
-       smb_ucs2_t *buffer;
+       smb_ucs2_t *buffer = NULL;
        char *out_buffer;
        
        size = push_ucs2_allocate(&buffer, s);
-       if (size == -1) {
+       if (size == -1 || !buffer) {
                return NULL;
        }
 
index 4056212fc5637247cd40504bc9a8dd829f507de9..83afc591a1544f589a08bfc335d579990e94ed28 100644 (file)
@@ -61,14 +61,20 @@ DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
 {
        DATA_BLOB ret;
 
-       if (!p || !length) {
+       if (!length) {
                ZERO_STRUCT(ret);
                return ret;
        }
 
-       ret.data = talloc_memdup(mem_ctx, p, length);
-       if (ret.data == NULL)
-               smb_panic("data_blob_talloc: talloc_memdup failed.\n");
+       if (p) {
+               ret.data = talloc_memdup(mem_ctx, p, length);
+               if (ret.data == NULL)
+                       smb_panic("data_blob_talloc: talloc_memdup failed.\n");
+       } else {
+               ret.data = talloc(mem_ctx, length);
+               if (ret.data == NULL)
+                       smb_panic("data_blob_talloc: talloc failed.\n");
+       }
 
        ret.length = length;
        ret.free = NULL;
index 38fcf0f3297599d55117d48bd011a6cb35880aa2..2abe918ef44c8b07d2b48508ca629a237934b4f9 100644 (file)
@@ -42,9 +42,8 @@ static NTSTATUS do_smb_load_module(const char *module_name, BOOL is_probe)
 
        if(!handle) {
                int level = is_probe ? 3 : 0;
-               DEBUG(level, ("Error loading module '%s': %s\n", module_name, 
-                             sys_dlerror()));
-
+               error = sys_dlerror();
+               DEBUG(level, ("Error loading module '%s': %s\n", module_name, error ? error : ""));
                return NT_STATUS_UNSUCCESSFUL;
        }
 
index 1ed583382de1565f816732c31dbe49c5861a5db1..b9d4df301d95e24b12df8378af21a3aad4b8d1b9 100644 (file)
@@ -69,6 +69,12 @@ NTSTATUS dupalloc_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *
 {
        NTSTATUS ret;
 
+       /* don't crash if the source pointer is NULL (since we don't
+          do priviledges now anyways) */
+
+       if ( !old_la )
+               return NT_STATUS_OK;
+
        *new_la = (LUID_ATTR *)talloc(mem_ctx, sizeof(LUID_ATTR));
        ALLOC_CHECK(new_la, ret, done, "dupalloc_luid_attr");
 
index fe34cfb852e136767e79e0203df0e191160b0a6e..8f6394ea928e67efa0a6873cda60e0c52f2cd08e 100644 (file)
@@ -97,6 +97,7 @@ ATTRIB_MAP_ENTRY attrib_map_v30[] = {
        { LDAP_ATTR_DOMAIN,             "sambaDomainName"       },
        { LDAP_ATTR_OBJCLASS,           "objectClass"           },
        { LDAP_ATTR_ACB_INFO,           "sambaAcctFlags"        },
+       { LDAP_ATTR_MUNGED_DIAL,        "sambaMungedDial"       },
        { LDAP_ATTR_LIST_END,           NULL                    }
 };
 
index 635ede9be2278d7bcdadef73e57ad09e778870fc..faca2cba879b78f62782bfd2fae3d2413350dc8e 100644 (file)
@@ -465,10 +465,9 @@ void unix_to_nt_time_abs(NTTIME *nt, time_t t)
        nt->low=~nt->low;
 }
 
-
 /****************************************************************************
-take an NTTIME structure, containing high / low time.  convert to unix time.
-lkclXXXX this may need 2 SIVALs not a memcpy.  we'll see...
+take a Unix time and convert to an NTTIME structure and place in buffer 
+pointed to by p.
 ****************************************************************************/
 void put_long_date(char *p,time_t t)
 {
index ce1389c8e9c632a736bda7f4b5f052789d829764..39515c65991e0ad66859fe88c52d1ae788f36180 100644 (file)
@@ -2234,7 +2234,7 @@ char *parent_dirname(const char *path)
  Determine if a pattern contains any Microsoft wildcard characters.
 *******************************************************************/
 
-BOOL ms_has_wild(char *s)
+BOOL ms_has_wild(const char *s)
 {
        char c;
        while ((c = *s++)) {
index c244a6b34bf33bd8d94a270d75c25e7c1428fdfa..2928584b8afe3d9cb868d73179b09ad07304735a 100644 (file)
@@ -62,7 +62,7 @@ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
        /* copy over the token */
        pbuf = buff;
        for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
-               if (*s == '\"') {
+               if (*s == '\"' || *s == '\'') {
                        quoted = !quoted;
                } else {
                        len++;
@@ -574,7 +574,7 @@ char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_
        size_t len;
 
        if (!dest) {
-               DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
+               DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
                return NULL;
        }
 
@@ -610,7 +610,7 @@ char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size
        size_t src_len, dest_len;
 
        if (!dest) {
-               DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
+               DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
                return NULL;
        }
 
@@ -654,7 +654,7 @@ char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, con
 #endif
 
        if (!dest) {
-               DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
+               DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
                return NULL;
        }
 
@@ -695,9 +695,11 @@ char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
        clobber_region(fn, line, dest, n+1);
 #endif
 
-       if (!dest)
+       if (!dest) {
+               DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
                return(NULL);
-       
+       }
+
        if (!src) {
                *dest = 0;
                return(dest);
index cdea5a2fe420fe216bbdaceeba82337ae37db9a6..b0efb8f598f15dc6cb55bb473adb1ea8bef8f07c 100644 (file)
@@ -162,7 +162,7 @@ static BOOL setup_keytab(krb5_context context,
 NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket, 
                           char **principal, DATA_BLOB *auth_data,
                           DATA_BLOB *ap_rep,
-                          uint8 session_key[16])
+                          DATA_BLOB *session_key)
 {
        NTSTATUS sret = NT_STATUS_LOGON_FAILURE;
        krb5_context context = NULL;
index b3706cb2403cc28c0739dffa6d0d631bee5682a9..072f42513cb942c2e367980ad7417685ecde9355 100644 (file)
@@ -1933,7 +1933,7 @@ bin/net -Uadministrator%XXXXX ads search '(&(objectclass=crossref)(dnsroot=VNET3
 but you need to force the bind path to match the configurationNamingContext from the rootDSE
 
 */
-ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup)
+ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const char **workgroup)
 {
        char *expr;
        ADS_STATUS rc;
index b5f7b97ae83f9bca6553403d2c8c34c70b0508cc..f6dfd4000688bc0019a5a1d2b34ffa62edc39b0a 100644 (file)
@@ -241,9 +241,16 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
        return True;
 }
 
-static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) 
+/**
+ * Set the user session key for a connection
+ * @param cli The cli structure to add it too
+ * @param session_key The session key used.  (A copy of this is taken for the cli struct)
+ *
+ */
+
+static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) 
 {
-       memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key)));
+       cli->user_session_key = data_blob(session_key.data, session_key.length);
 }
 
 /****************************************************************************
@@ -311,7 +318,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
                        session_key = data_blob(NULL, 16);
                        SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
                }
-               cli_simple_set_signing(cli, session_key.data, nt_response); 
+               cli_simple_set_signing(cli, session_key, nt_response); 
        } else {
                /* pre-encrypted password supplied.  Only used for 
                   security=server, can't do
@@ -373,14 +380,16 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
 
        if (session_key.data) {
                /* Have plaintext orginal */
-               set_cli_session_key(cli, session_key);
+               cli_set_session_key(cli, session_key);
        }
 
        ret = True;
 end:   
        data_blob_free(&lm_response);
        data_blob_free(&nt_response);
-       data_blob_free(&session_key);
+
+       if (!ret)
+               data_blob_free(&session_key);
        return ret;
 }
 
@@ -484,19 +493,19 @@ static void use_in_memory_ccache(void) {
  Do a spnego/kerberos encrypted session setup.
 ****************************************************************************/
 
-static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
+static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
 {
        DATA_BLOB blob2, negTokenTarg;
-       unsigned char session_key_krb5[16];
+       DATA_BLOB session_key_krb5;
        DATA_BLOB null_blob = data_blob(NULL, 0);
        
        DEBUG(2,("Doing kerberos session setup\n"));
 
        /* generate the encapsulated kerberos5 ticket */
-       negTokenTarg = spnego_gen_negTokenTarg(principal, 0, session_key_krb5);
+       negTokenTarg = spnego_gen_negTokenTarg(principal, 0, &session_key_krb5);
 
        if (!negTokenTarg.data)
-               return False;
+               return NT_STATUS_UNSUCCESSFUL;
 
 #if 0
        file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
@@ -509,9 +518,16 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi
        /* we don't need this blob for kerberos */
        data_blob_free(&blob2);
 
+       cli_set_session_key(cli, session_key_krb5);
+
        data_blob_free(&negTokenTarg);
 
-       return !cli_is_error(cli);
+       if (cli_is_error(cli)) {
+               if (NT_STATUS_IS_OK(cli_nt_error(cli))) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+       } 
+       return NT_STATUS_OK;
 }
 #endif /* HAVE_KRB5 */
 
@@ -520,10 +536,10 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi
  Do a spnego/NTLMSSP encrypted session setup.
 ****************************************************************************/
 
-static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, 
+static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, 
                                      const char *pass, const char *workgroup)
 {
-       struct ntlmssp_client_state *ntlmssp_state;
+       struct ntlmssp_state *ntlmssp_state;
        NTSTATUS nt_status;
        int turn = 1;
        DATA_BLOB msg1;
@@ -534,21 +550,21 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
        cli_temp_set_signing(cli);
 
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
-               return False;
+               return nt_status;
        }
 
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
-               return False;
+               return nt_status;
        }
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, workgroup))) {
-               return False;
+               return nt_status;
        }
        if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
-               return False;
+               return nt_status;
        }
 
        do {
-               nt_status = ntlmssp_client_update(ntlmssp_state, 
+               nt_status = ntlmssp_update(ntlmssp_state, 
                                                  blob_in, &blob_out);
                data_blob_free(&blob_in);
                if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
@@ -562,18 +578,27 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
                        }
                
                        cli_simple_set_signing(cli, 
-                                              ntlmssp_state->session_key.data
+                                              data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length)
                                               null_blob); 
                        
                        /* now send that blob on its way */
                        if (!cli_session_setup_blob_send(cli, msg1)) {
-                               return False;
+                               DEBUG(3, ("Failed to send NTLMSSP/SPENGO blob to server!\n"));
+                               nt_status = NT_STATUS_UNSUCCESSFUL;
+                       } else {
+                               data_blob_free(&msg1);
+                               
+                               blob = cli_session_setup_blob_receive(cli);
+                               
+                               nt_status = cli_nt_error(cli);
+                               if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
+                                       if (cli->smb_rw_error == READ_BAD_SIG) {
+                                               nt_status = NT_STATUS_ACCESS_DENIED;
+                                       } else {
+                                               nt_status = NT_STATUS_UNSUCCESSFUL;
+                                       }
+                               }
                        }
-                       data_blob_free(&msg1);
-                       
-                       blob = cli_session_setup_blob_receive(cli);
-
-                       nt_status = cli_nt_error(cli);
                }
                
                if (!blob.length) {
@@ -606,24 +631,22 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
 
        if (NT_STATUS_IS_OK(nt_status)) {
                fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
-               set_cli_session_key(cli, ntlmssp_state->session_key);
+               cli_set_session_key(cli, ntlmssp_state->session_key);
        }
 
        /* we have a reference conter on ntlmssp_state, if we are signing
           then the state will be kept by the signing engine */
 
-       if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) {
-               return False;
-       }
-       
-       return (NT_STATUS_IS_OK(nt_status));
+       ntlmssp_end(&ntlmssp_state);
+
+       return nt_status;
 }
 
 /****************************************************************************
  Do a spnego encrypted session setup.
 ****************************************************************************/
 
-BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, 
+NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, 
                              const char *pass, const char *workgroup)
 {
        char *principal;
@@ -651,7 +674,7 @@ BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user,
           reply */
        if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
                data_blob_free(&blob);
-               return False;
+               return NT_STATUS_INVALID_PARAMETER;
        }
        data_blob_free(&blob);
 
@@ -681,7 +704,7 @@ BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user,
                        
                        if (ret){
                                DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
-                               return False;
+                               return NT_STATUS_LOGON_FAILURE;
                        }
                }
                
@@ -773,8 +796,14 @@ BOOL cli_session_setup(struct cli_state *cli,
 
        /* if the server supports extended security then use SPNEGO */
 
-       if (cli->capabilities & CAP_EXTENDED_SECURITY)
-               return cli_session_setup_spnego(cli, user, pass, workgroup);
+       if (cli->capabilities & CAP_EXTENDED_SECURITY) {
+               NTSTATUS nt_status;
+               if (!NT_STATUS_IS_OK(nt_status = cli_session_setup_spnego(cli, user, pass, workgroup))) {
+                       DEBUG(3, ("SPENGO login failed: %s\n", get_friendly_nt_error_msg(nt_status)));
+                       return False;
+               }
+               return True;
+       }
 
        /* otherwise do a NT1 style session setup */
 
@@ -992,7 +1021,7 @@ BOOL cli_negprot(struct cli_state *cli)
        cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;  
 
        if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
-               DEBUG(1,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
+               DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
                return False;
        }
 
@@ -1028,7 +1057,7 @@ BOOL cli_negprot(struct cli_state *cli)
                if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
                        /* Fail if server says signing is mandatory and we don't want to support it. */
                        if (!cli->sign_info.allow_smb_signing) {
-                               DEBUG(1,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
+                               DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
                                return False;
                        }
                        cli->sign_info.negotiated_smb_signing = True;
index 9b54acf77561f807d3e0f6208e0f6b30f28ab691..0873700fc0ad35e3803c8075d489ee56cffb6b13 100644 (file)
@@ -339,7 +339,7 @@ close the session
 void cli_nt_session_close(struct cli_state *cli)
 {
        if (cli->ntlmssp_pipe_state) {
-               ntlmssp_client_end(&cli->ntlmssp_pipe_state);
+               ntlmssp_end(&cli->ntlmssp_pipe_state);
        }
 
        if (cli->nt_pipe_fnum != 0)
@@ -375,9 +375,10 @@ void cli_close_connection(struct cli_state *cli)
 
        cli_free_signing_context(cli);
        data_blob_free(&cli->secblob);
+       data_blob_free(&cli->user_session_key);
 
        if (cli->ntlmssp_pipe_state) 
-               ntlmssp_client_end(&cli->ntlmssp_pipe_state);
+               ntlmssp_end(&cli->ntlmssp_pipe_state);
 
        if (cli->mem_ctx) {
                talloc_destroy(cli->mem_ctx);
index 1fccc04a013b34107af999280bd0d6536a574afe..5568b5e033253ec82aedce4ad353dd89f05cc5c9 100644 (file)
@@ -307,7 +307,7 @@ cleanup_princ:
 /*
   get a kerberos5 ticket for the given service 
 */
-DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16])
+DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5)
 {
        krb5_error_code retval;
        krb5_data packet;
@@ -369,7 +369,7 @@ failed:
        return data_blob(NULL, 0);
 }
 
- BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote)
+ BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote)
  {
        krb5_keyblock *skey;
        krb5_error_code err;
@@ -383,11 +383,11 @@ failed:
                err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey);
        if (err == 0 && skey != NULL) {
                DEBUG(10, ("Got KRB5 session key of length %d\n",  KRB5_KEY_LENGTH(skey)));
-               if (KRB5_KEY_LENGTH(skey) == 16) {
-                       memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
-                       dump_data_pw("KRB5 Session Key:\n", session_key, 16);
-                       ret = True;
-               }
+               *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
+               dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
+
+               ret = True;
+
                krb5_free_keyblock(context, skey);
        } else {
                DEBUG(10, ("KRB5 error getting session key %d\n", err));
@@ -410,7 +410,7 @@ failed:
 
 #else /* HAVE_KRB5 */
  /* this saves a few linking headaches */
-DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16])
+DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5)
  {
         DEBUG(0,("NO KERBEROS SUPPORT\n"));
         return data_blob(NULL, 0);
index 63076a1a1ce661d9327a61e2da9406cbc27fd447..92543736ff258b767ee766c6a258965c055d8426 100644 (file)
@@ -323,7 +323,7 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
    generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY
    kerberos session setup 
 */
-DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsigned char session_key_krb5[16])
+DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *session_key_krb5)
 {
        DATA_BLOB tkt, tkt_wrapped, targ;
        const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL};
index 92c1cc99eeb8c701e6a3de319e1d05fa588b7552..ae44ca1a779959f0c9e10fbd874d84e0b460a7a5 100644 (file)
@@ -50,6 +50,12 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
        SCVAL(cli->outbuf,smb_com,trans);
        SSVAL(cli->outbuf,smb_tid, cli->cnum);
        cli_setup_packet(cli);
+
+       /*
+        * Save the mid we're using. We need this for finding
+        * signing replies.
+        */
+
        mid = cli->mid;
 
        if (pipe_name) {
@@ -87,16 +93,13 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
 
        show_msg(cli->outbuf);
 
-       cli_signing_trans_start(cli);
        if (!cli_send_smb(cli)) {
-               cli_signing_trans_stop(cli);
                return False;
        }
 
        if (this_ldata < ldata || this_lparam < lparam) {
                /* receive interim response */
                if (!cli_receive_smb(cli) || cli_is_error(cli)) {
-                       cli_signing_trans_stop(cli);
                        return(False);
                }
 
@@ -130,21 +133,29 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
                                memcpy(outdata,data+tot_data,this_ldata);
                        cli_setup_bcc(cli, outdata+this_ldata);
                        
-                       /* Ensure this packet has the same MID as
-                        * the primary. Important in signing. JRA. */
-                       cli->mid = mid;
+                       /*
+                        * Save the mid we're using. We need this for finding
+                        * signing replies.
+                        */
+                       mid = cli->mid;
 
                        show_msg(cli->outbuf);
                        if (!cli_send_smb(cli)) {
-                               cli_signing_trans_stop(cli);
                                return False;
                        }
+
+                       /* Ensure we use the same mid for the secondaries. */
+                       cli->mid = mid;
                        
                        tot_data += this_ldata;
                        tot_param += this_lparam;
                }
        }
 
+       /* Note we're in a trans state. Save the sequence
+        * numbers for replies. */
+
+       cli_signing_trans_start(cli, mid);
        return(True);
 }
 
@@ -352,6 +363,12 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
        SCVAL(cli->outbuf,smb_com,SMBnttrans);
        SSVAL(cli->outbuf,smb_tid, cli->cnum);
        cli_setup_packet(cli);
+
+       /*
+        * Save the mid we're using. We need this for finding
+        * signing replies.
+        */
+
        mid = cli->mid;
 
        outparam = smb_buf(cli->outbuf)+3;
@@ -381,16 +398,13 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
        cli_setup_bcc(cli, outdata+this_ldata);
 
        show_msg(cli->outbuf);
-       cli_signing_trans_start(cli);
        if (!cli_send_smb(cli)) {
-               cli_signing_trans_stop(cli);
                return False;
        }       
 
        if (this_ldata < ldata || this_lparam < lparam) {
                /* receive interim response */
                if (!cli_receive_smb(cli) || cli_is_error(cli)) {
-                       cli_signing_trans_stop(cli);
                        return(False);
                }
 
@@ -423,22 +437,30 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
                                memcpy(outdata,data+tot_data,this_ldata);
                        cli_setup_bcc(cli, outdata+this_ldata);
                        
-                       /* Ensure this packet has the same MID as
-                        * the primary. Important in signing. JRA. */
-                       cli->mid = mid;
+                       /*
+                        * Save the mid we're using. We need this for finding
+                        * signing replies.
+                        */
+                       mid = cli->mid;
 
                        show_msg(cli->outbuf);
 
                        if (!cli_send_smb(cli)) {
-                               cli_signing_trans_stop(cli);
                                return False;
                        }
                        
+                       /* Ensure we use the same mid for the secondaries. */
+                       cli->mid = mid;
+                       
                        tot_data += this_ldata;
                        tot_param += this_lparam;
                }
        }
 
+       /* Note we're in a trans state. Save the sequence
+        * numbers for replies. */
+
+       cli_signing_trans_start(cli, mid);
        return(True);
 }
 
index c51b599b0411c40c1abc43665bf064d66d919fa6..ca1aa674031e765d7b17d68269cdd5972bfad470 100644 (file)
 
 #include "includes.h"
 
+static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
+                                      DATA_BLOB reply, DATA_BLOB *next_request);
+static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
+                                        const DATA_BLOB in, DATA_BLOB *out);
+static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
+                                        const DATA_BLOB reply, DATA_BLOB *next_request);
+static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
+                                   const DATA_BLOB request, DATA_BLOB *reply);
+
+/**
+ * Callbacks for NTLMSSP - for both client and server operating modes
+ * 
+ */
+
+static const struct ntlmssp_callbacks {
+       enum NTLMSSP_ROLE role;
+       enum NTLM_MESSAGE_TYPE ntlmssp_command;
+       NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, 
+                      DATA_BLOB in, DATA_BLOB *out);
+} ntlmssp_callbacks[] = {
+       {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
+       {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
+       {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
+       {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
+       {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
+       {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
+};
+
+
 /**
  * Print out the NTLMSSP flags for debugging 
  * @param neg_flags The flags from the packet
@@ -71,7 +100,7 @@ void debug_ntlmssp_flags(uint32 neg_flags)
  *
  */
    
-static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state)
+static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
 {
        static uchar chal[8];
        generate_random_buffer(chal, sizeof(chal), False);
@@ -79,6 +108,188 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state)
        return chal;
 }
 
+/**
+ * Default 'we can set the challenge to anything we like' implementation
+ *
+ */
+   
+static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
+{
+       return True;
+}
+
+/**
+ * Default 'we can set the challenge to anything we like' implementation
+ *
+ * Does not actually do anything, as the value is always in the structure anyway.
+ *
+ */
+   
+static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
+{
+       SMB_ASSERT(challenge->length == 8);
+       return NT_STATUS_OK;
+}
+
+/** 
+ * Set a username on an NTLMSSP context - ensures it is talloc()ed 
+ *
+ */
+
+NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) 
+{
+       ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user);
+       if (!ntlmssp_state->user) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
+/** 
+ * Set a password on an NTLMSSP context - ensures it is talloc()ed 
+ *
+ */
+NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) 
+{
+       if (!password) {
+               ntlmssp_state->password = NULL;
+       } else {
+               ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password);
+               if (!ntlmssp_state->password) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+       return NT_STATUS_OK;
+}
+
+/** 
+ * Set a domain on an NTLMSSP context - ensures it is talloc()ed 
+ *
+ */
+NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) 
+{
+       ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain);
+       if (!ntlmssp_state->domain) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
+/** 
+ * Set a workstation on an NTLMSSP context - ensures it is talloc()ed 
+ *
+ */
+NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) 
+{
+       ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation);
+       if (!ntlmssp_state->domain) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
+/**
+ *  Store a DATA_BLOB containing an NTLMSSP response, for use later.
+ *  This copies the data blob
+ */
+
+NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
+                               DATA_BLOB response) 
+{
+       ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx, 
+                                                         response.data, response.length);
+       return NT_STATUS_OK;
+}
+
+/**
+ * Next state function for the NTLMSSP state machine
+ * 
+ * @param ntlmssp_state NTLMSSP State
+ * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB
+ * @param out The reply, as an allocated DATA_BLOB, caller to free.
+ * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. 
+ */
+
+NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, 
+                       const DATA_BLOB in, DATA_BLOB *out) 
+{
+       DATA_BLOB input;
+       uint32 ntlmssp_command;
+       int i;
+
+       *out = data_blob(NULL, 0);
+
+       if (!in.length && ntlmssp_state->stored_response.length) {
+               input = ntlmssp_state->stored_response;
+               
+               /* we only want to read the stored response once - overwrite it */
+               ntlmssp_state->stored_response = data_blob(NULL, 0);
+       } else {
+               input = in;
+       }
+
+       if (!input.length) {
+               switch (ntlmssp_state->role) {
+               case NTLMSSP_CLIENT:
+                       ntlmssp_command = NTLMSSP_INITIAL;
+                       break;
+               case NTLMSSP_SERVER:
+                       /* 'datagram' mode - no neg packet */
+                       ntlmssp_command = NTLMSSP_NEGOTIATE;
+                       break;
+               }
+       } else {
+               if (!msrpc_parse(&input, "Cd",
+                                "NTLMSSP",
+                                &ntlmssp_command)) {
+                       DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
+                       dump_data(2, (const char *)input.data, input.length);
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+       }
+
+       if (ntlmssp_command != ntlmssp_state->expected_state) {
+               DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       for (i=0; ntlmssp_callbacks[i].fn; i++) {
+               if (ntlmssp_callbacks[i].role == ntlmssp_state->role 
+                   && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
+                       return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out);
+               }
+       }
+
+       DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", 
+                 ntlmssp_state->role, ntlmssp_command)); 
+
+       return NT_STATUS_INVALID_PARAMETER;
+}
+
+/**
+ * End an NTLMSSP state machine
+ * 
+ * @param ntlmssp_state NTLMSSP State, free()ed by this function
+ */
+
+void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)
+{
+       TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
+
+       (*ntlmssp_state)->ref_count--;
+
+       if ((*ntlmssp_state)->ref_count == 0) {
+               data_blob_free(&(*ntlmssp_state)->chal);
+               data_blob_free(&(*ntlmssp_state)->lm_resp);
+               data_blob_free(&(*ntlmssp_state)->nt_resp);
+
+               talloc_destroy(mem_ctx);
+       }
+
+       *ntlmssp_state = NULL;
+       return;
+}
+
 /**
  * Determine correct target name flags for reply, given server role 
  * and negotiated flags
@@ -107,6 +318,45 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
        }
 }
 
+static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
+                                     uint32 neg_flags, BOOL allow_lm) {
+       if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
+               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
+               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
+               ntlmssp_state->unicode = True;
+       } else {
+               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
+               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
+               ntlmssp_state->unicode = False;
+       }
+
+       if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY && allow_lm) {
+               /* other end forcing us to use LM */
+               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
+               ntlmssp_state->use_ntlmv2 = False;
+       } else {
+               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
+       }
+
+       if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
+               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
+       }
+
+       if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
+               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
+       }
+
+       if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
+               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
+       }
+
+       if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
+               ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
+       }
+       
+}
+
+
 /**
  * Next state function for the Negotiate packet
  * 
@@ -150,31 +400,33 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
                debug_ntlmssp_flags(neg_flags);
        }
        
-       cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
+       ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
 
-       data_blob_free(&ntlmssp_state->chal);
-       ntlmssp_state->chal = data_blob(cryptkey, 8);
+       /* Ask our caller what challenge they would like in the packet */
+       cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
 
-       /* Give them the challenge. For now, ignore neg_flags and just
-          return the flags we want. Obviously this is not correct */
-       
-       chal_flags = 
-               NTLMSSP_NEGOTIATE_128 | 
-               NTLMSSP_NEGOTIATE_NTLM;
-       
-       if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
-               chal_flags |= NTLMSSP_NEGOTIATE_UNICODE;
-               ntlmssp_state->unicode = True;
-       } else {
-               chal_flags |= NTLMSSP_NEGOTIATE_OEM;
+       /* Check if we may set the challenge */
+       if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
+               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
        }
 
+       /* The flags we send back are not just the negotiated flags,
+        * they are also 'what is in this packet'.  Therfore, we
+        * operate on 'chal_flags' from here on 
+        */
+
+       chal_flags = ntlmssp_state->neg_flags;
+
+       /* get the right name to fill in as 'target' */
        target_name = ntlmssp_target_name(ntlmssp_state, 
                                          neg_flags, &chal_flags); 
-
-       if (target_name == NULL)
+       if (target_name == NULL) 
                return NT_STATUS_INVALID_PARAMETER;
 
+       ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
+       ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
+       
+
        /* This should be a 'netbios domain -> DNS domain' mapping */
        dnsdomname[0] = '\0';
        get_mydomname(dnsdomname);
@@ -184,6 +436,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
        get_myfullname(dnsname);
        strlower_m(dnsname);
        
+       /* This creates the 'blob' of names that appears at the end of the packet */
        if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) 
        {
                const char *target_name_dns = "";
@@ -194,16 +447,17 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
                }
 
                msrpc_gen(&struct_blob, "aaaaa",
-                         ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN, target_name,
-                         ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
-                         ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN_DNS, target_name_dns,
-                         ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsdomname,
-                         ntlmssp_state->unicode, 0, "");
+                         NTLMSSP_NAME_TYPE_DOMAIN, target_name,
+                         NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
+                         NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
+                         NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
+                         0, "");
        } else {
                struct_blob = data_blob(NULL, 0);
        }
 
        {
+               /* Marshel the packet in the right format, be it unicode or ASCII */
                const char *gen_string;
                if (ntlmssp_state->unicode) {
                        gen_string = "CdUdbddB";
@@ -240,13 +494,27 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
                                    const DATA_BLOB request, DATA_BLOB *reply) 
 {
-       DATA_BLOB sess_key;
-       uint32 ntlmssp_command, neg_flags;
+       DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
+       DATA_BLOB nt_session_key = data_blob(NULL, 0);
+       DATA_BLOB lm_session_key = data_blob(NULL, 0);
+       DATA_BLOB session_key = data_blob(NULL, 0);
+       uint32 ntlmssp_command, auth_flags;
        NTSTATUS nt_status;
 
+       /* used by NTLM2 */
+       BOOL doing_ntlm2 = False;
+
+       uchar session_nonce[16];
+       uchar session_nonce_hash[16];
+
        const char *parse_string;
+       char *domain = NULL;
+       char *user = NULL;
+       char *workstation = NULL;
 
        /* parse the NTLMSSP packet */
+       *reply = data_blob(NULL, 0);
+
 #if 0
        file_save("ntlmssp_auth.dat", request.data, request.length);
 #endif
@@ -260,9 +528,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
        data_blob_free(&ntlmssp_state->lm_resp);
        data_blob_free(&ntlmssp_state->nt_resp);
 
-       SAFE_FREE(ntlmssp_state->user);
-       SAFE_FREE(ntlmssp_state->domain);
-       SAFE_FREE(ntlmssp_state->workstation);
+       ntlmssp_state->user = NULL;
+       ntlmssp_state->domain = NULL;
+       ntlmssp_state->workstation = NULL;
 
        /* now the NTLMSSP encoded auth hashes */
        if (!msrpc_parse(&request, parse_string,
@@ -270,18 +538,73 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
                         &ntlmssp_command, 
                         &ntlmssp_state->lm_resp,
                         &ntlmssp_state->nt_resp,
-                        &ntlmssp_state->domain, 
-                        &ntlmssp_state->user, 
-                        &ntlmssp_state->workstation,
-                        &sess_key,
-                        &neg_flags)) {
+                        &domain, 
+                        &user, 
+                        &workstation,
+                        &encrypted_session_key,
+                        &auth_flags)) {
                DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
                dump_data(2, (const char *)request.data, request.length);
-               return NT_STATUS_INVALID_PARAMETER;
+               SAFE_FREE(domain);
+               SAFE_FREE(user);
+               SAFE_FREE(workstation);
+               data_blob_free(&encrypted_session_key);
+               auth_flags = 0;
+               
+               /* Try again with a shorter string (Win9X truncates this packet) */
+               if (ntlmssp_state->unicode) {
+                       parse_string = "CdBBUUU";
+               } else {
+                       parse_string = "CdBBAAA";
+               }
+
+               /* now the NTLMSSP encoded auth hashes */
+               if (!msrpc_parse(&request, parse_string,
+                                "NTLMSSP", 
+                                &ntlmssp_command, 
+                                &ntlmssp_state->lm_resp,
+                                &ntlmssp_state->nt_resp,
+                                &domain, 
+                                &user, 
+                                &workstation)) {
+                       DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
+                       dump_data(2, (const char *)request.data, request.length);
+                       SAFE_FREE(domain);
+                       SAFE_FREE(user);
+                       SAFE_FREE(workstation);
+
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
        }
 
-       data_blob_free(&sess_key);
-       
+       if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
+               SAFE_FREE(domain);
+               SAFE_FREE(user);
+               SAFE_FREE(workstation);
+               data_blob_free(&encrypted_session_key);
+               return nt_status;
+       }
+
+       if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
+               SAFE_FREE(domain);
+               SAFE_FREE(user);
+               SAFE_FREE(workstation);
+               data_blob_free(&encrypted_session_key);
+               return nt_status;
+       }
+
+       if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
+               SAFE_FREE(domain);
+               SAFE_FREE(user);
+               SAFE_FREE(workstation);
+               data_blob_free(&encrypted_session_key);
+               return nt_status;
+       }
+
+       SAFE_FREE(domain);
+       SAFE_FREE(user);
+       SAFE_FREE(workstation);
+
        DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
                 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
 
@@ -290,9 +613,98 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
        file_save("lmhash1.dat",  &ntlmssp_state->lm_resp.data,  &ntlmssp_state->lm_resp.length);
 #endif
 
-       nt_status = ntlmssp_state->check_password(ntlmssp_state);
+       /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 
+          client challenge 
        
-       *reply = data_blob(NULL, 0);
+          However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
+       */
+       if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
+               if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
+                       struct MD5Context md5_session_nonce_ctx;
+                       SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
+                       
+                       doing_ntlm2 = True;
+
+                       memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
+                       memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
+                       
+                       MD5Init(&md5_session_nonce_ctx);
+                       MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
+                       MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
+                       
+                       ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);
+
+                       /* LM response is no longer useful */
+                       data_blob_free(&ntlmssp_state->lm_resp);
+
+                       /* We changed the effective challenge - set it */
+                       if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
+                               data_blob_free(&encrypted_session_key);
+                               return nt_status;
+                       }
+               }
+       }
+
+       /* Finally, actually ask if the password is OK */
+       if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) {
+               data_blob_free(&encrypted_session_key);
+               return nt_status;
+       }
+
+       dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length);
+       dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
+
+       /* Handle the different session key derivation for NTLM2 */
+       if (doing_ntlm2) {
+               if (nt_session_key.data && nt_session_key.length == 16) {
+                       session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+                       hmac_md5(nt_session_key.data, session_nonce, 
+                                sizeof(session_nonce), session_key.data);
+                       dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
+
+               }
+       } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
+               if (lm_session_key.data && lm_session_key.length >= 8 && 
+                   ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
+                       session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+                       SMBsesskeygen_lmv1(lm_session_key.data, ntlmssp_state->lm_resp.data, 
+                                          session_key.data);
+                       dump_data_pw("LM session key:\n", session_key.data, session_key.length);
+               }
+       } else if (nt_session_key.data) {
+               session_key = nt_session_key;
+               dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
+       }
+
+       /* With KEY_EXCH, the client supplies the proposed session key, 
+          but encrypts it with the long-term key */
+       if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
+               if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
+                       data_blob_free(&encrypted_session_key);
+                       DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", 
+                                 encrypted_session_key.length));
+                       return NT_STATUS_INVALID_PARAMETER;
+               } else if (!session_key.data || session_key.length != 16) {
+                       DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", 
+                                 session_key.length));
+               } else {
+                       dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
+                       SamOEMhash(encrypted_session_key.data, 
+                                  session_key.data, 
+                                  encrypted_session_key.length);
+                       ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, 
+                                                                     encrypted_session_key.data, 
+                                                                     encrypted_session_key.length);
+                       dump_data_pw("KEY_EXCH session key:\n", session_key.data, session_key.length);
+               }
+       } else {
+               ntlmssp_state->session_key = session_key;
+       }
+
+       data_blob_free(&encrypted_session_key);
+       
+       /* allow arbitarily many authentications */
+       ntlmssp_state->expected_state = NTLMSSP_AUTH;
 
        return nt_status;
 }
@@ -316,8 +728,12 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
                return NT_STATUS_NO_MEMORY;
        }
 
+       (*ntlmssp_state)->role = NTLMSSP_SERVER;
+
        (*ntlmssp_state)->mem_ctx = mem_ctx;
        (*ntlmssp_state)->get_challenge = get_challenge;
+       (*ntlmssp_state)->set_challenge = set_challenge;
+       (*ntlmssp_state)->may_set_challenge = may_set_challenge;
 
        (*ntlmssp_state)->get_global_myname = global_myname;
        (*ntlmssp_state)->get_domain = lp_workgroup;
@@ -325,73 +741,18 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
 
        (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
 
-       return NT_STATUS_OK;
-}
-
-/**
- * End an NTLMSSP state machine
- * 
- * @param ntlmssp_state NTLMSSP State, free()ed by this function
- */
-
-NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state)
-{
-       TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
-
-       data_blob_free(&(*ntlmssp_state)->chal);
-       data_blob_free(&(*ntlmssp_state)->lm_resp);
-       data_blob_free(&(*ntlmssp_state)->nt_resp);
+       (*ntlmssp_state)->ref_count = 1;
 
-       SAFE_FREE((*ntlmssp_state)->user);
-       SAFE_FREE((*ntlmssp_state)->domain);
-       SAFE_FREE((*ntlmssp_state)->workstation);
+       (*ntlmssp_state)->neg_flags = 
+               NTLMSSP_NEGOTIATE_128 |
+               NTLMSSP_NEGOTIATE_NTLM |
+               NTLMSSP_NEGOTIATE_NTLM2 |
+               NTLMSSP_NEGOTIATE_KEY_EXCH |
+               NTLMSSP_NEGOTIATE_SIGN;
 
-       talloc_destroy(mem_ctx);
-       *ntlmssp_state = NULL;
        return NT_STATUS_OK;
 }
 
-/**
- * Next state function for the NTLMSSP state machine
- * 
- * @param ntlmssp_state NTLMSSP State
- * @param request The request, as a DATA_BLOB
- * @param request The reply, as an allocated DATA_BLOB, caller to free.
- * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. 
- */
-
-NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, 
-                              const DATA_BLOB request, DATA_BLOB *reply) 
-{
-       uint32 ntlmssp_command;
-       *reply = data_blob(NULL, 0);
-
-       if (request.length) {
-               if (!msrpc_parse(&request, "Cd",
-                                "NTLMSSP",
-                                &ntlmssp_command)) {
-                       return NT_STATUS_INVALID_PARAMETER;
-               }
-       } else {
-               /* 'datagram' mode - no neg packet */
-               ntlmssp_command = NTLMSSP_NEGOTIATE;
-       }
-
-       if (ntlmssp_command != ntlmssp_state->expected_state) {
-               DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       if (ntlmssp_command == NTLMSSP_NEGOTIATE) {
-               return ntlmssp_server_negotiate(ntlmssp_state, request, reply);
-       } else if (ntlmssp_command == NTLMSSP_AUTH) {
-               return ntlmssp_server_auth(ntlmssp_state, request, reply);
-       } else {
-               DEBUG(1, ("unknown NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-}
-
 /*********************************************************************
  Client side NTLMSSP
 *********************************************************************/
@@ -405,19 +766,19 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state,
  * @return Errors or NT_STATUS_OK. 
  */
 
-static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_state, 
+static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 
                                  DATA_BLOB reply, DATA_BLOB *next_request) 
 {
        if (ntlmssp_state->unicode) {
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
+       } else {
+               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
        }
        
        if (ntlmssp_state->use_ntlmv2) {
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
        }
 
-       ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
-       
        /* generate the ntlmssp negotiate packet */
        msrpc_gen(next_request, "CddAA",
                  "NTLMSSP",
@@ -426,6 +787,8 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat
                  ntlmssp_state->get_domain(), 
                  ntlmssp_state->get_global_myname());
 
+       ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
+
        return NT_STATUS_MORE_PROCESSING_REQUIRED;
 }
 
@@ -438,7 +801,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat
  * @return Errors or NT_STATUS_OK. 
  */
 
-static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_state, 
+static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 
                                         const DATA_BLOB reply, DATA_BLOB *next_request) 
 {
        uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
@@ -452,6 +815,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
        DATA_BLOB nt_response = data_blob(NULL, 0);
        DATA_BLOB session_key = data_blob(NULL, 0);
        DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
+       NTSTATUS nt_status;
 
        if (!msrpc_parse(&reply, "CdBd",
                         "NTLMSSP",
@@ -469,17 +833,16 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
        DEBUG(3, ("Got challenge flags:\n"));
        debug_ntlmssp_flags(chal_flags);
 
-       if (chal_flags & NTLMSSP_NEGOTIATE_UNICODE) {
+       ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
+
+       if (ntlmssp_state->unicode) {
                if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
                        chal_parse_string = "CdUdbddB";
                } else {
                        chal_parse_string = "CdUdbdd";
                }
                auth_gen_string = "CdBBUUUBd";
-               ntlmssp_state->unicode = True;
-               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
-               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
-       } else if (chal_flags & NTLMSSP_NEGOTIATE_OEM) {
+       } else {
                if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
                        chal_parse_string = "CdAdbddB";
                } else {
@@ -487,32 +850,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
                }
 
                auth_gen_string = "CdBBAAABd";
-
-               ntlmssp_state->unicode = False;
-               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
-               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
-       } else {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       if (chal_flags & NTLMSSP_NEGOTIATE_LM_KEY && lp_client_lanman_auth()) {
-               /* server forcing us to use LM */
-               ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
-               ntlmssp_state->use_ntlmv2 = False;
-       } else {
-               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
-       }
-
-       if (!(chal_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
-               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
-       }
-
-       if (!(chal_flags & NTLMSSP_NEGOTIATE_128)) {
-               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
-       }
-
-       if (!(chal_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
-               ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
        }
 
        DEBUG(3, ("NTLMSSP: Set final flags:\n"));
@@ -546,6 +883,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
 
                if (!struct_blob.length) {
                        /* be lazy, match win2k - we can't do NTLMv2 without it */
+                       DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
                        return NT_STATUS_INVALID_PARAMETER;
                }
 
@@ -569,7 +907,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
                uchar nt_session_key[16];
                E_md4hash(ntlmssp_state->password, nt_hash);
                
-               lm_response = data_blob(NULL, 24);
+               lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
                generate_random_buffer(lm_response.data, 8, False);
                memset(lm_response.data+8, 0, 16);
 
@@ -580,16 +918,21 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
                MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
                MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
                MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
+
+               DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
+               DEBUG(5, ("challenge is: \n"));
+               dump_data(5, session_nonce_hash, 8);
                
-               nt_response = data_blob(NULL, 24);
+               nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
                SMBNTencrypt(ntlmssp_state->password,
                             session_nonce_hash,
                             nt_response.data);
 
-               session_key = data_blob(NULL, 16);
+               session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
 
                SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key);
                hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data);
+               dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
        } else {
                
                
@@ -600,22 +943,24 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
                
                /* lanman auth is insecure, it may be disabled */
                if (lp_client_lanman_auth()) {
-                       lm_response = data_blob(NULL, 24);
+                       lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
                        SMBencrypt(ntlmssp_state->password,challenge_blob.data,
                                   lm_response.data);
-                       }
+               }
                
-               nt_response = data_blob(NULL, 24);
+               nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
                SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
                             nt_response.data);
                
-               session_key = data_blob(NULL, 16);
+               session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
                if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 
                    && lp_client_lanman_auth()) {
                        SMBsesskeygen_lmv1(lm_hash, lm_response.data, 
                                           session_key.data);
+                       dump_data_pw("LM session key\n", session_key.data, session_key.length);
                } else {
                        SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+                       dump_data_pw("NT session key:\n", session_key.data, session_key.length);
                }
        }
        data_blob_free(&struct_blob);
@@ -627,9 +972,12 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
                
                generate_random_buffer(client_session_key, sizeof(client_session_key), False);  
                encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
+               dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
+
                SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
                data_blob_free(&session_key);
-               session_key = data_blob(client_session_key, sizeof(client_session_key));
+               session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
+               dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
        }
 
        /* this generates the actual auth packet */
@@ -644,28 +992,29 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
                       encrypted_session_key.data, encrypted_session_key.length,
                       ntlmssp_state->neg_flags)) {
                
-               data_blob_free(&lm_response);
-               data_blob_free(&nt_response);
-               data_blob_free(&session_key);
                return NT_STATUS_NO_MEMORY;
        }
 
        data_blob_free(&encrypted_session_key);
 
        data_blob_free(&ntlmssp_state->chal);
-       data_blob_free(&ntlmssp_state->lm_resp);
-       data_blob_free(&ntlmssp_state->nt_resp);
-       data_blob_free(&ntlmssp_state->session_key);
 
        ntlmssp_state->chal = challenge_blob;
        ntlmssp_state->lm_resp = lm_response;
        ntlmssp_state->nt_resp = nt_response;
        ntlmssp_state->session_key = session_key;
 
+       ntlmssp_state->expected_state = NTLMSSP_UNKNOWN;
+
+       if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
+               DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
+               return nt_status;
+       }
+
        return NT_STATUS_MORE_PROCESSING_REQUIRED;
 }
 
-NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state)
+NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
 {
        TALLOC_CTX *mem_ctx;
 
@@ -678,6 +1027,8 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state)
                return NT_STATUS_NO_MEMORY;
        }
 
+       (*ntlmssp_state)->role = NTLMSSP_CLIENT;
+
        (*ntlmssp_state)->mem_ctx = mem_ctx;
 
        (*ntlmssp_state)->get_global_myname = global_myname;
@@ -687,6 +1038,10 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state)
 
        (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
 
+       (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
+
+       (*ntlmssp_state)->ref_count = 1;
+
        (*ntlmssp_state)->neg_flags = 
                NTLMSSP_NEGOTIATE_128 |
                NTLMSSP_NEGOTIATE_NTLM |
@@ -700,101 +1055,6 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state)
                NTLMSSP_NEGOTIATE_SIGN |
                NTLMSSP_REQUEST_TARGET;
 
-       (*ntlmssp_state)->ref_count = 1;
-
-       return NT_STATUS_OK;
-}
-
-NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state)
-{
-       TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
-
-       (*ntlmssp_state)->ref_count--;
-
-       if ((*ntlmssp_state)->ref_count == 0) {
-               data_blob_free(&(*ntlmssp_state)->chal);
-               data_blob_free(&(*ntlmssp_state)->lm_resp);
-               data_blob_free(&(*ntlmssp_state)->nt_resp);
-               data_blob_free(&(*ntlmssp_state)->session_key);
-               data_blob_free(&(*ntlmssp_state)->stored_response);
-               talloc_destroy(mem_ctx);
-       }
-
-       *ntlmssp_state = NULL;
        return NT_STATUS_OK;
 }
 
-NTSTATUS ntlmssp_client_update(NTLMSSP_CLIENT_STATE *ntlmssp_state, 
-                              DATA_BLOB reply, DATA_BLOB *next_request) 
-{
-       NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER;
-       uint32 ntlmssp_command;
-       *next_request = data_blob(NULL, 0);
-
-       if (!reply.length) {
-               /* If there is a cached reply, use it - otherwise this is the first packet */
-               if (!ntlmssp_state->stored_response.length) {
-                       return ntlmssp_client_initial(ntlmssp_state, reply, next_request);
-               }
-               
-               reply = ntlmssp_state->stored_response;
-       }
-
-       if (!msrpc_parse(&reply, "Cd",
-                        "NTLMSSP",
-                        &ntlmssp_command)) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       if (ntlmssp_command == NTLMSSP_CHALLENGE) {
-               nt_status = ntlmssp_client_challenge(ntlmssp_state, reply, next_request);
-       }
-       if (ntlmssp_state->stored_response.length) {
-               data_blob_free(&ntlmssp_state->stored_response);
-       }
-       return nt_status;
-}
-
-NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *user) 
-{
-       ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user);
-       if (!ntlmssp_state->user) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
-}
-
-NTSTATUS ntlmssp_set_password(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *password) 
-{
-       if (!password) {
-               ntlmssp_state->password = NULL;
-       } else {
-               ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password);
-               if (!ntlmssp_state->password) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-       }
-       return NT_STATUS_OK;
-}
-
-NTSTATUS ntlmssp_set_domain(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *domain) 
-{
-       ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain);
-       if (!ntlmssp_state->domain) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
-}
-
-/**
- *  Store a DATA_BLOB containing an NTLMSSP response, for use later.
- *  This 'keeps' the data blob - the caller must *not* free it.
- */
-
-NTSTATUS ntlmssp_client_store_response(NTLMSSP_CLIENT_STATE *ntlmssp_state,
-                                      DATA_BLOB response) 
-{
-       data_blob_free(&ntlmssp_state->stored_response);
-       ntlmssp_state->stored_response = response;
-       return NT_STATUS_OK;
-}
index b136dacf5a2549792b30498ab8dbd58437be5740..3444db030689ba6194eeeec49d61371ef920dee8 100644 (file)
@@ -31,7 +31,7 @@
   format specifiers are:
 
   U = unicode string (input is unix string)
-  a = address (input is BOOL unicode, char *unix_string)
+  a = address (input is char *unix_string)
       (1 byte type, 1 byte length, unicode/ASCII string, all inline)
   A = ASCII string (input is unix string)
   B = data blob (pointer + length)
@@ -49,7 +49,6 @@ BOOL msrpc_gen(DATA_BLOB *blob,
        uint8 *b;
        int head_size=0, data_size=0;
        int head_ofs, data_ofs;
-       BOOL unicode;
 
        /* first scan the format to work out the header and body size */
        va_start(ap, format);
@@ -66,14 +65,9 @@ BOOL msrpc_gen(DATA_BLOB *blob,
                        data_size += str_ascii_charnum(s);
                        break;
                case 'a':
-                       unicode = va_arg(ap, BOOL);
                        n = va_arg(ap, int);
                        s = va_arg(ap, char *);
-                       if (unicode) {
-                               data_size += (str_charnum(s) * 2) + 4;
-                       } else {
-                               data_size += (str_ascii_charnum(s)) + 4;
-                       }
+                       data_size += (str_charnum(s) * 2) + 4;
                        break;
                case 'B':
                        b = va_arg(ap, uint8 *);
@@ -124,27 +118,16 @@ BOOL msrpc_gen(DATA_BLOB *blob,
                        data_ofs += n;
                        break;
                case 'a':
-                       unicode = va_arg(ap, BOOL);
                        n = va_arg(ap, int);
                        SSVAL(blob->data, data_ofs, n); data_ofs += 2;
                        s = va_arg(ap, char *);
-                       if (unicode) {
-                               n = str_charnum(s);
-                               SSVAL(blob->data, data_ofs, n*2); data_ofs += 2;
-                               if (0 < n) {
-                                       push_string(NULL, blob->data+data_ofs, s, n*2,
-                                                   STR_UNICODE|STR_NOALIGN);
-                               }
-                               data_ofs += n*2;
-                       } else {
-                               n = str_ascii_charnum(s);
-                               SSVAL(blob->data, data_ofs, n); data_ofs += 2;
-                               if (0 < n) {
-                                       push_string(NULL, blob->data+data_ofs, s, n,
-                                                   STR_ASCII|STR_NOALIGN);
-                               }
-                               data_ofs += n;
+                       n = str_charnum(s);
+                       SSVAL(blob->data, data_ofs, n*2); data_ofs += 2;
+                       if (0 < n) {
+                               push_string(NULL, blob->data+data_ofs, s, n*2,
+                                           STR_UNICODE|STR_NOALIGN);
                        }
+                       data_ofs += n*2;
                        break;
 
                case 'B':
index 153c234d1f84b2e080a946efc6b4f1bacc33727b..ea1a7037c9ccb5af0aef247b9d86a7b8fb136838 100644 (file)
@@ -102,7 +102,7 @@ enum ntlmssp_direction {
        NTLMSSP_RECEIVE
 };
 
-static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_state,
+static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state,
                                              const uchar *data, size_t length, 
                                              enum ntlmssp_direction direction,
                                              DATA_BLOB *sig) 
@@ -113,7 +113,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat
                uchar digest[16];
                SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
 
-               hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx);
+               hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
                hmac_md5_update((const unsigned char *)seq_num, 4, &ctx);
                hmac_md5_update(data, length, &ctx);
                hmac_md5_final(digest, &ctx);
@@ -124,10 +124,10 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat
                }
                switch (direction) {
                case NTLMSSP_SEND:
-                       NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash,  sig->data+4, sig->length-4);
+                       NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash,  sig->data+4, sig->length-4);
                        break;
                case NTLMSSP_RECEIVE:
-                       NTLMSSPcalc_ap(ntlmssp_state->srv_sign_hash,  sig->data+4, sig->length-4);
+                       NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash,  sig->data+4, sig->length-4);
                        break;
                }
        } else {
@@ -144,9 +144,9 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat
        return NT_STATUS_OK;
 }
 
-NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
-                                          const uchar *data, size_t length, 
-                                          DATA_BLOB *sig) 
+NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state,
+                                   const uchar *data, size_t length, 
+                                   DATA_BLOB *sig) 
 {
        NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig);
 
@@ -161,9 +161,9 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
  *
  */
 
-NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
-                                    const uchar *data, size_t length, 
-                                    const DATA_BLOB *sig) 
+NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state,
+                             const uchar *data, size_t length, 
+                             const DATA_BLOB *sig) 
 {
        DATA_BLOB local_sig;
        NTSTATUS nt_status;
@@ -204,11 +204,11 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
  *
  */
 
-NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
-                                   uchar *data, size_t length,
-                                   DATA_BLOB *sig)
+NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state,
+                            uchar *data, size_t length,
+                            DATA_BLOB *sig)
 {      
-       DEBUG(10,("ntlmssp_client_seal_data: seal\n"));
+       DEBUG(10,("ntlmssp_seal_data: seal\n"));
        dump_data_pw("ntlmssp clear data\n", data, length);
        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
                HMACMD5Context ctx;
@@ -216,7 +216,7 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
                uchar digest[16];
                SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
 
-               hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx);
+               hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx);
                hmac_md5_update((const unsigned char *)seq_num, 4, &ctx);
                hmac_md5_update(data, length, &ctx);
                hmac_md5_final(digest, &ctx);
@@ -227,13 +227,13 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
                }
 
                dump_data_pw("ntlmssp client sealing hash:\n", 
-                            ntlmssp_state->cli_seal_hash,
-                            sizeof(ntlmssp_state->cli_seal_hash));
-               NTLMSSPcalc_ap(ntlmssp_state->cli_seal_hash, data, length);
+                            ntlmssp_state->send_seal_hash,
+                            sizeof(ntlmssp_state->send_seal_hash));
+               NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length);
                dump_data_pw("ntlmssp client signing hash:\n", 
-                            ntlmssp_state->cli_sign_hash,
-                            sizeof(ntlmssp_state->cli_sign_hash));
-               NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash,  sig->data+4, sig->length-4);
+                            ntlmssp_state->send_sign_hash,
+                            sizeof(ntlmssp_state->send_sign_hash));
+               NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash,  sig->data+4, sig->length-4);
        } else {
                uint32 crc;
                crc = crc32_calc_buffer((const char *)data, length);
@@ -266,14 +266,14 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
  *
  */
 
-NTSTATUS ntlmssp_client_unseal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
+NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state,
                                      uchar *data, size_t length,
                                      DATA_BLOB *sig)
 {
-       DEBUG(10,("ntlmssp_client_unseal_data: seal\n"));
+       DEBUG(10,("ntlmssp__unseal_data: seal\n"));
        dump_data_pw("ntlmssp sealed data\n", data, length);
        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
-               NTLMSSPcalc_ap(ntlmssp_state->srv_seal_hash, data, length);
+               NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length);
        } else {
                dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash,
                             sizeof(ntlmssp_state->ntlmssp_hash));
@@ -281,13 +281,13 @@ NTSTATUS ntlmssp_client_unseal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
        }
        dump_data_pw("ntlmssp clear data\n", data, length);
 
-       return ntlmssp_client_check_packet(ntlmssp_state, data, length, sig);
+       return ntlmssp_check_packet(ntlmssp_state, data, length, sig);
 }
 
 /**
    Initialise the state for NTLMSSP signing.
 */
-NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state)
+NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state)
 {
        unsigned char p24[24];
        ZERO_STRUCT(p24);
@@ -297,34 +297,54 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state)
 
        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
        {
+               const char *send_sign_const;
+               const char *send_seal_const;
+               const char *recv_sign_const;
+               const char *recv_seal_const;
+
+               switch (ntlmssp_state->role) {
+               case NTLMSSP_CLIENT:
+                       send_sign_const = CLI_SIGN;
+                       send_seal_const = CLI_SEAL;
+                       recv_sign_const = SRV_SIGN;
+                       recv_seal_const = SRV_SEAL;
+                       break;
+               case NTLMSSP_SERVER:
+                       send_sign_const = SRV_SIGN;
+                       send_seal_const = SRV_SEAL;
+                       recv_sign_const = CLI_SIGN;
+                       recv_seal_const = CLI_SEAL;
+                       break;
+               }
+
+               calc_ntlmv2_hash(ntlmssp_state->send_sign_hash, 
+                                ntlmssp_state->send_sign_const, 
+                                ntlmssp_state->session_key, send_sign_const);
+               dump_data_pw("NTLMSSP send sign hash:\n", 
+                            ntlmssp_state->send_sign_hash, 
+                            sizeof(ntlmssp_state->send_sign_hash));
+
+               calc_ntlmv2_hash(ntlmssp_state->send_seal_hash, 
+                                ntlmssp_state->send_seal_const, 
+                                ntlmssp_state->session_key, send_seal_const);
+               dump_data_pw("NTLMSSP send sesl hash:\n", 
+                            ntlmssp_state->send_seal_hash, 
+                            sizeof(ntlmssp_state->send_seal_hash));
+
+               calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, 
+                                ntlmssp_state->recv_sign_const, 
+                                ntlmssp_state->session_key, send_sign_const);
+               dump_data_pw("NTLMSSP receive sign hash:\n", 
+                            ntlmssp_state->recv_sign_hash, 
+                            sizeof(ntlmssp_state->recv_sign_hash));
+
+               calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, 
+                                ntlmssp_state->recv_seal_const, 
+                                ntlmssp_state->session_key, send_seal_const);
+               dump_data_pw("NTLMSSP receive seal hash:\n", 
+                            ntlmssp_state->recv_sign_hash, 
+                            sizeof(ntlmssp_state->recv_sign_hash));
 
-               calc_ntlmv2_hash(ntlmssp_state->cli_sign_hash, 
-                                ntlmssp_state->cli_sign_const, 
-                                ntlmssp_state->session_key, CLI_SIGN);
-               dump_data_pw("NTLMSSP client sign hash:\n", 
-                            ntlmssp_state->cli_sign_hash, 
-                            sizeof(ntlmssp_state->cli_sign_hash));
-
-               calc_ntlmv2_hash(ntlmssp_state->cli_seal_hash, 
-                                ntlmssp_state->cli_seal_const, 
-                                ntlmssp_state->session_key, CLI_SEAL);
-               dump_data_pw("NTLMSSP client sesl hash:\n", 
-                            ntlmssp_state->cli_seal_hash, 
-                            sizeof(ntlmssp_state->cli_seal_hash));
-
-               calc_ntlmv2_hash(ntlmssp_state->srv_sign_hash, 
-                                ntlmssp_state->srv_sign_const, 
-                                ntlmssp_state->session_key, SRV_SIGN);
-               dump_data_pw("NTLMSSP server sign hash:\n", 
-                            ntlmssp_state->srv_sign_hash, 
-                            sizeof(ntlmssp_state->srv_sign_hash));
-
-               calc_ntlmv2_hash(ntlmssp_state->srv_seal_hash, 
-                                ntlmssp_state->srv_seal_const, 
-                                ntlmssp_state->session_key, SRV_SEAL);
-               dump_data_pw("NTLMSSP server seal hash:\n", 
-                            ntlmssp_state->cli_sign_hash, 
-                            sizeof(ntlmssp_state->cli_sign_hash));
        } 
        else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
                if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) {
index 91509f0fb81d6cb3a10f5b3f3bd8782d6bf8dca3..6b2abb9ccc835dcecb521ffdee29ebc35e3f885c 100644 (file)
@@ -370,7 +370,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq ));
 #endif /* JRATEST */
 
        } else {
-               DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
+               DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
                dump_data(10, (const char *)server_sent_mac, 8);
        }
        return signing_good(inbuf, si, good, saved_seq);
@@ -405,11 +405,11 @@ static void simple_free_signing_context(struct smb_sign_info *si)
  SMB signing - Simple implementation - setup the MAC key.
 ************************************************************/
 
-BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response)
+BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response)
 {
        struct smb_basic_signing_context *data;
 
-       if (!user_session_key)
+       if (!user_session_key.length)
                return False;
 
        if (!cli_set_smb_signing_common(cli)) {
@@ -425,21 +425,23 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[
 
        cli->sign_info.signing_context = data;
        
-       data->mac_key = data_blob(NULL, response.length + 16);
+       data->mac_key = data_blob(NULL, response.length + user_session_key.length);
 
-       memcpy(&data->mac_key.data[0], user_session_key, 16);
+       memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
 
        DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
-       dump_data(10, (const char *)user_session_key, 16);
+       dump_data(10, (const char *)user_session_key.data, user_session_key.length);
 
        if (response.length) {
-               memcpy(&data->mac_key.data[16],response.data, response.length);
+               memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
                DEBUG(10, ("cli_simple_set_signing: response_data\n"));
                dump_data(10, (const char *)response.data, response.length);
        } else {
                DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
        }
 
+       dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
+
        /* Initialise the sequence number */
        data->send_seq_num = 0;
 
@@ -455,9 +457,12 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[
 
 /***********************************************************
  Tell client code we are in a multiple trans reply state.
+ We call this after the last outgoing trans2 packet (which
+ has incremented the sequence numbers), so we must save the
+ current mid and sequence number -2.
 ************************************************************/
 
-void cli_signing_trans_start(struct cli_state *cli)
+void cli_signing_trans_start(struct cli_state *cli, uint16 mid)
 {
        struct smb_basic_signing_context *data = cli->sign_info.signing_context;
 
@@ -467,9 +472,9 @@ void cli_signing_trans_start(struct cli_state *cli)
        data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
        ZERO_STRUCTP(data->trans_info);
 
-       data->trans_info->send_seq_num = data->send_seq_num;
-       data->trans_info->mid = SVAL(cli->outbuf,smb_mid);
-       data->trans_info->reply_seq_num = data->send_seq_num+1;
+       data->trans_info->send_seq_num = data->send_seq_num-2;
+       data->trans_info->mid = mid;
+       data->trans_info->reply_seq_num = data->send_seq_num-1;
 
        DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
 data->send_seq_num = %u\n",
@@ -490,10 +495,15 @@ void cli_signing_trans_stop(struct cli_state *cli)
        if (!cli->sign_info.doing_signing || !data)
                return;
 
+       DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \
+data->send_seq_num = %u\n",
+                       (unsigned int)data->trans_info->mid,
+                       (unsigned int)data->trans_info->reply_seq_num,
+                       (unsigned int)data->trans_info->send_seq_num,
+                       (unsigned int)data->send_seq_num ));
+
        SAFE_FREE(data->trans_info);
        data->trans_info = NULL;
-
-       data->send_seq_num += 2;
 }
 
 /***********************************************************
@@ -741,7 +751,26 @@ We were expecting seq %u\n", reply_seq_number, saved_seq ));
                DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num));
                dump_data(10, (const char *)server_sent_mac, 8);
        }
-       return signing_good(inbuf, si, good, saved_seq);
+
+       if (!signing_good(inbuf, si, good, saved_seq)) {
+               if (!si->mandatory_signing && (data->send_seq_num < 3)){
+                       /* Non-mandatory signing - just turn off if this is the first bad packet.. */
+                       DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \
+isn't sending correct signatures. Turning off.\n"));
+                       si->negotiated_smb_signing = False;
+                       si->allow_smb_signing = False;
+                       si->doing_signing = False;
+                       free_signing_context(si);
+                       return True;
+               } else {
+                       /* Mandatory signing or bad packet after signing started - fail and disconnect. */
+                       if (saved_seq)
+                               DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u\n", (unsigned int)saved_seq));
+                       return False;
+               }
+       } else {
+               return True;
+       }
 }
 
 /***********************************************************
@@ -928,11 +957,11 @@ data->send_seq_num = %u\n",
  Turn on signing from this packet onwards. 
 ************************************************************/
 
-void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response)
+void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response)
 {
        struct smb_basic_signing_context *data;
 
-       if (!user_session_key)
+       if (!user_session_key.length)
                return;
 
        if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) {
@@ -957,11 +986,17 @@ void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response)
 
        srv_sign_info.signing_context = data;
        
-       data->mac_key = data_blob(NULL, response.length + 16);
+       data->mac_key = data_blob(NULL, response.length + user_session_key.length);
 
-       memcpy(&data->mac_key.data[0], user_session_key, 16);
+       memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length);
        if (response.length)
-               memcpy(&data->mac_key.data[16],response.data, response.length);
+               memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
+
+       dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length);
+
+       DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n",
+                               BOOLSTR(srv_sign_info.negotiated_smb_signing),
+                               BOOLSTR(srv_sign_info.mandatory_signing) ));
 
        /* Initialise the sequence number */
        data->send_seq_num = 0;
index cde77f94a36047001c697a9c0e28089b54544ef7..ae946b4a66090cba869c1565a965b1f51e3d722d 100644 (file)
@@ -397,6 +397,46 @@ void SamOEMhash( unsigned char *data, const unsigned char *key, int val)
   }
 }
 
+void SamOEMhashBlob( unsigned char *data, int len, DATA_BLOB *key)
+{
+  unsigned char s_box[256];
+  unsigned char index_i = 0;
+  unsigned char index_j = 0;
+  unsigned char j = 0;
+  int ind;
+
+  for (ind = 0; ind < 256; ind++)
+  {
+    s_box[ind] = (unsigned char)ind;
+  }
+
+  for( ind = 0; ind < 256; ind++)
+  {
+     unsigned char tc;
+
+     j += (s_box[ind] + key->data[ind%key->length]);
+
+     tc = s_box[ind];
+     s_box[ind] = s_box[j];
+     s_box[j] = tc;
+  }
+  for( ind = 0; ind < len; ind++)
+  {
+    unsigned char tc;
+    unsigned char t;
+
+    index_i++;
+    index_j += s_box[index_i];
+
+    tc = s_box[index_i];
+    s_box[index_i] = s_box[index_j];
+    s_box[index_j] = tc;
+
+    t = s_box[index_i] + s_box[index_j];
+    data[ind] = data[ind] ^ s_box[t];
+  }
+}
+
 /* Decode a sam password hash into a password.  The password hash is the
    same method used to store passwords in the NT registry.  The DES key
    used is based on the RID of the user. */
index ec31bb5dbaabe8552421e497ecfc24100d226163..2d02a2339436c3474432cd6c83c70c8b0ae92f7b 100644 (file)
@@ -331,9 +331,9 @@ DATA_BLOB NTLMv2_generate_names_blob(const char *hostname,
        DATA_BLOB names_blob = data_blob(NULL, 0);
        
        msrpc_gen(&names_blob, "aaa", 
-                 True, NTLMSSP_NAME_TYPE_DOMAIN, domain,
-                 True, NTLMSSP_NAME_TYPE_SERVER, hostname,
-                 True, 0, "");
+                 NTLMSSP_NAME_TYPE_DOMAIN, domain,
+                 NTLMSSP_NAME_TYPE_SERVER, hostname,
+                 0, "");
        return names_blob;
 }
 
index c18641bc8456dbc7d122196028f8c76b524b8f46..2c6eb1b55a807baa8685c367a1370fc02a64f371 100644 (file)
@@ -181,6 +181,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
 done:
        /* cleanup */
        if (cli) {
+               DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n"));
                cli_nt_session_close( cli );
                cli_shutdown( cli );
        }
index 04233bb85cb5db9eb22c01228f135b81d859d90a..1256ec3a3bc35c8ae6f5b012df4f9a4ffe52f458 100644 (file)
@@ -136,6 +136,37 @@ static BOOL wbinfo_get_usergroups(char *user)
        return True;
 }
 
+
+/* List group SIDs a user SID is a member of */
+static BOOL wbinfo_get_usersids(char *user_sid)
+{
+       struct winbindd_request request;
+       struct winbindd_response response;
+       NSS_STATUS result;
+       int i;
+       const char *s;
+
+       ZERO_STRUCT(response);
+
+       /* Send request */
+       fstrcpy(request.data.sid, user_sid);
+
+       result = winbindd_request(WINBINDD_GETUSERSIDS, &request, &response);
+
+       if (result != NSS_STATUS_SUCCESS)
+               return False;
+
+       s = response.extra_data;
+       for (i = 0; i < response.data.num_entries; i++) {
+               d_printf("%s\n", s);
+               s += strlen(s) + 1;
+       }
+
+       SAFE_FREE(response.extra_data);
+
+       return True;
+}
+
 /* Convert NetBIOS name to IP */
 
 static BOOL wbinfo_wins_byname(char *name)
@@ -884,7 +915,8 @@ enum {
        OPT_SET_AUTH_USER = 1000,
        OPT_GET_AUTH_USER,
        OPT_DOMAIN_NAME,
-       OPT_SEQUENCE
+       OPT_SEQUENCE,
+       OPT_USERSIDS
 };
 
 int main(int argc, char **argv)
@@ -923,6 +955,7 @@ int main(int argc, char **argv)
                { "trusted-domains", 'm', POPT_ARG_NONE, 0, 'm', "List trusted domains" },
                { "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" },
                { "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" },
+               { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" },
                { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
                { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
                { "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
@@ -1055,6 +1088,13 @@ int main(int argc, char **argv)
                                goto done;
                        }
                        break;
+               case OPT_USERSIDS:
+                       if (!wbinfo_get_usersids(string_arg)) {
+                               d_printf("Could not get group SIDs for user SID %s\n", 
+                                      string_arg);
+                               goto done;
+                       }
+                       break;
                case 'a': {
                                BOOL got_error = False;
 
diff --git a/source/nsswitch/winbind_nss_freebsd.c b/source/nsswitch/winbind_nss_freebsd.c
new file mode 100644 (file)
index 0000000..b73a4ce
--- /dev/null
@@ -0,0 +1,81 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   AIX loadable authentication module, providing identification 
+   routines against Samba winbind/Windows NT Domain
+
+   Copyright (C) Aaron Collins 2003
+   
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library 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
+   Library General Public License for more details.
+   
+   You should have received a copy of the GNU Library 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.   
+*/
+
+#include "winbind_client.h"
+
+/* Make sure that the module gets registered needed by freebsd 5.1 */
+
+extern enum nss_status _nss_winbind_getgrent_r(struct group *, char *, size_t,
+    int *);
+extern enum nss_status _nss_winbind_getgrnam_r(const char *, struct group *,
+    char *, size_t, int *);
+extern enum nss_status _nss_winbind_getgrgid_r(gid_t gid, struct group *, char *,
+    size_t, int *);
+extern enum nss_status _nss_winbind_setgrent(void);
+extern enum nss_status _nss_winbind_endgrent(void);
+
+extern enum nss_status _nss_winbind_getpwent_r(struct passwd *, char *, size_t,
+    int *);
+extern enum nss_status _nss_winbind_getpwnam_r(const char *, struct passwd *,
+    char *, size_t, int *);
+extern enum nss_status _nss_winbind_getpwuid_r(gid_t gid, struct passwd *, char *,
+    size_t, int *);
+extern enum nss_status _nss_winbind_setpwent(void);
+extern enum nss_status _nss_winbind_endpwent(void);
+
+NSS_METHOD_PROTOTYPE(__nss_compat_getgrnam_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_getgrgid_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_setgrent);
+NSS_METHOD_PROTOTYPE(__nss_compat_endgrent);
+
+NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_getpwent_r);
+NSS_METHOD_PROTOTYPE(__nss_compat_setpwent);
+NSS_METHOD_PROTOTYPE(__nss_compat_endpwent);
+
+static ns_mtab methods[] = {
+{ NSDB_GROUP, "getgrnam_r", __nss_compat_getgrnam_r, _nss_winbind_getgrnam_r },
+{ NSDB_GROUP, "getgrgid_r", __nss_compat_getgrgid_r, _nss_winbind_getgrgid_r },
+{ NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, _nss_winbind_getgrent_r },
+{ NSDB_GROUP, "endgrent",   __nss_compat_setgrent,   _nss_winbind_setgrent },
+{ NSDB_GROUP, "setgrent",   __nss_compat_endgrent,   _nss_winbind_endgrent },
+
+{ NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, _nss_winbind_getpwnam_r },
+{ NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, _nss_winbind_getpwuid_r },
+{ NSDB_PASSWD, "getpwent_r", __nss_compat_getpwent_r, _nss_winbind_getpwent_r },
+{ NSDB_PASSWD, "endpwent",   __nss_compat_setpwent,   _nss_winbind_setpwent },
+{ NSDB_PASSWD, "setpwent",   __nss_compat_endpwent,   _nss_winbind_endpwent },
+
+};
+
+ns_mtab *
+nss_module_register(const char *source, unsigned int *mtabsize,
+    nss_module_unregister_fn *unreg)
+{
+        *mtabsize = sizeof(methods)/sizeof(methods[0]);
+        *unreg = NULL;
+        return (methods);
+}
index 125bc8ccdaf9b6e9f3aff8f854e21bdad1d3c465..ac4a861ff1b8f643ea3c4e9c54f0f5923026f987 100644 (file)
@@ -860,3 +860,152 @@ _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
  done:
        return ret;
 }
+
+
+/* return a list of group SIDs for a user SID */
+NSS_STATUS
+_nss_winbind_getusersids(const char *user_sid, char **group_sids,
+                        int *num_groups,
+                        char *buffer, size_t buf_size, int *errnop)
+{
+       NSS_STATUS ret;
+       struct winbindd_request request;
+       struct winbindd_response response;
+
+#ifdef DEBUG_NSS
+       fprintf(stderr, "[%5d]: getusersids %s\n", getpid(), user_sid);
+#endif
+
+       ZERO_STRUCT(request);
+       ZERO_STRUCT(response);
+
+       strncpy(request.data.sid, user_sid,sizeof(request.data.sid) - 1);
+       request.data.sid[sizeof(request.data.sid) - 1] = '\0';
+
+       ret = winbindd_request(WINBINDD_GETUSERSIDS, &request, &response);
+
+       if (ret != NSS_STATUS_SUCCESS) {
+               goto done;
+       }
+
+       if (buf_size < response.length - sizeof(response)) {
+               ret = NSS_STATUS_TRYAGAIN;
+               errno = *errnop = ERANGE;
+               goto done;
+       }
+
+       *num_groups = response.data.num_entries;
+       *group_sids = buffer;
+       memcpy(buffer, response.extra_data, response.length - sizeof(response));
+       errno = *errnop = 0;
+       
+ done:
+       free_response(&response);
+       return ret;
+}
+
+
+/* map a user or group name to a SID string */
+NSS_STATUS
+_nss_winbind_nametosid(const char *name, char **sid, char *buffer,
+                      size_t buflen, int *errnop)
+{
+       NSS_STATUS ret;
+       struct winbindd_response response;
+       struct winbindd_request request;
+
+#ifdef DEBUG_NSS
+       fprintf(stderr, "[%5d]: nametosid %s\n", getpid(), name);
+#endif
+
+       ZERO_STRUCT(response);
+       ZERO_STRUCT(request);
+
+       strncpy(request.data.name.name, name, 
+               sizeof(request.data.name.name) - 1);
+       request.data.name.name[sizeof(request.data.name.name) - 1] = '\0';
+
+       ret = winbindd_request(WINBINDD_LOOKUPNAME, &request, &response);
+       if (ret != NSS_STATUS_SUCCESS) {
+               *errnop = errno = EINVAL;
+               goto failed;
+       }
+
+       if (buflen < strlen(response.data.sid.sid)+1) {
+               ret = NSS_STATUS_TRYAGAIN;
+               *errnop = errno = ERANGE;
+               goto failed;
+       }
+
+       *errnop = errno = 0;
+       *sid = buffer;
+       strcpy(*sid, response.data.sid.sid);
+
+failed:
+       free_response(&response);
+       return ret;
+}
+
+/* map a sid string to a user or group name */
+NSS_STATUS
+_nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
+                      size_t buflen, int *errnop)
+{
+       NSS_STATUS ret;
+       struct winbindd_response response;
+       struct winbindd_request request;
+       static char sep_char;
+       unsigned needed;
+
+#ifdef DEBUG_NSS
+       fprintf(stderr, "[%5d]: sidtoname %s\n", getpid(), sid);
+#endif
+
+       /* we need to fetch the separator first time through */
+       if (!sep_char) {
+               ZERO_STRUCT(response);
+               ZERO_STRUCT(request);
+
+               ret = winbindd_request(WINBINDD_INFO, &request, &response);
+               if (ret != NSS_STATUS_SUCCESS) {
+                       *errnop = errno = EINVAL;
+                       goto failed;
+               }
+
+               sep_char = response.data.info.winbind_separator;
+               free_response(&response);
+       }
+
+
+       strncpy(request.data.sid, sid, 
+               sizeof(request.data.sid) - 1);
+       request.data.sid[sizeof(request.data.sid) - 1] = '\0';
+
+       ret = winbindd_request(WINBINDD_LOOKUPSID, &request, &response);
+       if (ret != NSS_STATUS_SUCCESS) {
+               *errnop = errno = EINVAL;
+               goto failed;
+       }
+
+       needed = 
+               strlen(response.data.name.dom_name) +
+               strlen(response.data.name.name) + 2;
+
+       if (buflen < needed) {
+               ret = NSS_STATUS_TRYAGAIN;
+               *errnop = errno = ERANGE;
+               goto failed;
+       }
+
+       snprintf(buffer, needed, "%s%c%s", 
+                response.data.name.dom_name,
+                sep_char,
+                response.data.name.name);
+
+       *name = buffer;
+       *errnop = errno = 0;
+
+failed:
+       free_response(&response);
+       return ret;
+}
index d8e233a3a8c218ee57ddebdbb830d795c09203b3..74df934ca2e2cc789e4df079d76227f24f580980 100644 (file)
@@ -221,6 +221,7 @@ static struct dispatch_table dispatch_table[] = {
        { WINBINDD_GETPWENT, winbindd_getpwent, "GETPWENT" },
 
        { WINBINDD_GETGROUPS, winbindd_getgroups, "GETGROUPS" },
+       { WINBINDD_GETUSERSIDS, winbindd_getusersids, "GETUSERSIDS" },
 
        /* Group functions */
 
@@ -722,6 +723,7 @@ static void process_loop(void)
                                            && *(uint32 *) &state->request != sizeof(state->request)) {
                                                DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %ld\n",
                                                                (unsigned long)state->request.pid, *(uint32 *) &state->request, (unsigned long)sizeof(state->request)));
+                                               DEBUGADD(0, ("This usually means that you are running old wbinfo, pam_winbind or libnss_winbind clients\n"));
 
                                                remove_client(state);
                                                break;
index 4bf5a304590dd25640706536e02af39fbdfe8ae4..ac9cd8f332931d329d42ce52b16af3970ac68d47 100644 (file)
@@ -179,10 +179,9 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
 
                                result = NT_STATUS_OK;
 
-                               if (!cli_session_setup_spnego(new_conn->cli, machine_krb5_principal, 
+                               if (!NT_STATUS_IS_OK(result = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal, 
                                                              machine_password, 
-                                                             domain)) {
-                                       result = cli_nt_error(new_conn->cli);
+                                                             domain))) {
                                        DEBUG(4,("failed kerberos session setup with %s\n", nt_errstr(result)));
                                        if (NT_STATUS_IS_OK(result)) 
                                                result = NT_STATUS_UNSUCCESSFUL;
index d951b3433e5d696746f5c168a5e5b3e260344e51..180a3db8e2e02c0968972a10cbcf516284a0e9dc 100644 (file)
@@ -692,8 +692,8 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
                        goto tryagain;
                }
 
-               DEBUG(10, ("got gid %lu for group %x\n", (unsigned long)group_gid,
-                          name_list[ent->sam_entry_index].rid));
+               DEBUG(10, ("got gid %lu for group %lu\n", (unsigned long)group_gid,
+                          (unsigned long)name_list[ent->sam_entry_index].rid));
                
                /* Fill in group entry */
 
@@ -1082,3 +1082,88 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
 
        return result;
 }
+
+
+/* Get user supplementary sids. This is equivalent to the
+   winbindd_getgroups() function but it involves a SID->SIDs mapping
+   rather than a NAME->SID->SIDS->GIDS mapping, which means we avoid
+   idmap. This call is designed to be used with applications that need
+   to do ACL evaluation themselves. Note that the cached info3 data is
+   not used 
+
+   this function assumes that the SID that comes in is a user SID. If
+   you pass in another type of SID then you may get unpredictable
+   results.
+*/
+enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state)
+{
+       DOM_SID user_sid;
+       NTSTATUS status;
+       DOM_SID **user_grpsids;
+       struct winbindd_domain *domain;
+       enum winbindd_result result = WINBINDD_ERROR;
+       unsigned int i;
+       TALLOC_CTX *mem_ctx;
+       char *ret;
+       uint32 num_groups;
+       unsigned ofs, ret_size = 0;
+
+       /* Ensure null termination */
+       state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
+
+       if (!string_to_sid(&user_sid, state->request.data.sid)) {
+               DEBUG(1, ("Could not get convert sid %s from string\n", state->request.data.sid));
+               return WINBINDD_ERROR;
+       }
+
+       if (!(mem_ctx = talloc_init("winbindd_getusersids(%s)",
+                                   state->request.data.username))) {
+               return WINBINDD_ERROR;
+       }
+
+       /* Get info for the domain */   
+       if ((domain = find_domain_from_sid(&user_sid)) == NULL) {
+               DEBUG(0,("could not find domain entry for sid %s\n", 
+                         sid_string_static(&user_sid)));
+               goto done;
+       }
+
+       status = domain->methods->lookup_usergroups(domain, mem_ctx, 
+                                                   &user_sid, &num_groups, 
+                                                   &user_grpsids);
+       if (!NT_STATUS_IS_OK(status)) 
+               goto done;
+
+       if (num_groups == 0) {
+               goto no_groups;
+       }
+
+       /* work out the response size */
+       for (i = 0; i < num_groups; i++) {
+               const char *s = sid_string_static(user_grpsids[i]);
+               ret_size += strlen(s) + 1;
+       }
+
+       /* build the reply */
+       ret = malloc(ret_size);
+       if (!ret) goto done;
+       ofs = 0;
+       for (i = 0; i < num_groups; i++) {
+               const char *s = sid_string_static(user_grpsids[i]);
+               safe_strcpy(ret + ofs, s, ret_size - ofs);
+               ofs += strlen(ret+ofs) + 1;
+       }
+
+no_groups:
+       /* Send data back to client */
+       state->response.data.num_entries = num_groups;
+       state->response.extra_data = ret;
+       state->response.length += ret_size;
+       result = WINBINDD_OK;
+
+ done:
+       talloc_destroy(mem_ctx);
+
+       return result;
+}
+
index 41fecd2816cf8d6d715e1fb73beed2be77ab96ff..76243c57ef33a60b73691908845333e4ef552092 100644 (file)
@@ -118,6 +118,9 @@ enum winbindd_cmd {
        /* find the location of our privileged pipe */
        WINBINDD_PRIV_PIPE_DIR,
 
+       /* return a list of group sids for a user sid */
+       WINBINDD_GETUSERSIDS,   
+
        WINBINDD_NUM_CMDS
 };
 
index d43dca29c5410d922fae2fc21026f38e519df1c3..6e386760b421b4f70ecd29aa8adf89a746fa85c3 100644 (file)
@@ -225,9 +225,15 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
        DATA_BLOB lm_resp, nt_resp;
 
        if (!state->privileged) {
-               DEBUG(2, ("winbindd_pam_auth_crap: non-privileged access denied!\n"));
+               char *error_string = NULL;
+               DEBUG(2, ("winbindd_pam_auth_crap: non-privileged access denied.  !\n"));
+               DEBUGADD(2, ("winbindd_pam_auth_crap: Ensure permissions on %s are set correctly.\n", 
+                            get_winbind_priv_pipe_dir()));
                /* send a better message than ACCESS_DENIED */
-               push_utf8_fstring(state->response.data.auth.error_string, "winbind client not authorized to use winbindd_pam_auth_crap");
+               asprintf(&error_string, "winbind client not authorized to use winbindd_pam_auth_crap.  Ensure permissions on %s are set correctly.",
+                        get_winbind_priv_pipe_dir());
+               push_utf8_fstring(state->response.data.auth.error_string, error_string);
+               SAFE_FREE(error_string);
                result =  NT_STATUS_ACCESS_DENIED;
                goto done;
        }
@@ -378,6 +384,8 @@ done:
        
        state->response.data.auth.nt_status = NT_STATUS_V(result);
        push_utf8_fstring(state->response.data.auth.nt_status_string, nt_errstr(result));
+       
+       /* we might have given a more useful error above */
        if (!*state->response.data.auth.error_string) 
                push_utf8_fstring(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
        state->response.data.auth.pam_error = nt_status_to_pam(result);
index c6711a9ccfab05185ccceccf873bba4c7fcf5b1a..e05d46a936ec6e5c6bff38d9efcafd5374c2918d 100644 (file)
@@ -42,6 +42,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
        BOOL got_dom_pol = False;
        uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
        unsigned int i, start_idx, retry;
+       uint32 loop_count;
 
        DEBUG(3,("rpc: query_user_list\n"));
 
@@ -68,25 +69,36 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
        got_dom_pol = True;
 
        i = start_idx = 0;
+       loop_count = 0;
+
        do {
                TALLOC_CTX *ctx2;
-               char **dom_users;
-               uint32 num_dom_users, *dom_rids, j, size = 0xffff;
-               uint16 acb_mask = ACB_NORMAL;
-
+               uint32 num_dom_users, j;
+               uint32 max_entries, max_size;
+               SAM_DISPINFO_CTR ctr;
+               SAM_DISPINFO_1 info1;
+
+               ZERO_STRUCT( ctr );
+               ZERO_STRUCT( info1 );
+               ctr.sam.info1 = &info1;
+       
                if (!(ctx2 = talloc_init("winbindd enum_users"))) {
                        result = NT_STATUS_NO_MEMORY;
                        goto done;
                }               
 
-               result = cli_samr_enum_dom_users(
-                       hnd->cli, ctx2, &dom_pol, &start_idx, acb_mask,
-                       size, &dom_users, &dom_rids, &num_dom_users);
+               /* this next bit is copied from net_user_list_internal() */
+
+               get_query_dispinfo_params( loop_count, &max_entries, &max_size );
+
+               result = cli_samr_query_dispinfo(hnd->cli, mem_ctx, &dom_pol,
+                       &start_idx, 1, &num_dom_users, max_entries, max_size, &ctr);
+
+               loop_count++;
 
                *num_entries += num_dom_users;
 
-               *info = talloc_realloc(
-                       mem_ctx, *info, 
+               *info = talloc_realloc( mem_ctx, *info, 
                        (*num_entries) * sizeof(WINBIND_USERINFO));
 
                if (!(*info)) {
@@ -96,10 +108,16 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
                }
 
                for (j = 0; j < num_dom_users; i++, j++) {
-                       (*info)[i].acct_name = 
-                               talloc_strdup(mem_ctx, dom_users[j]);
-                       (*info)[i].full_name = talloc_strdup(mem_ctx, "");
-                       (*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, dom_rids[j]);
+                       fstring username, fullname;
+                       uint32 rid = ctr.sam.info1->sam[j].rid_user;
+                       
+                       unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1);
+                       unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1);
+                       
+                       (*info)[i].acct_name = talloc_strdup(mem_ctx, username );
+                       (*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
+                       (*info)[i].user_sid = rid_to_talloced_sid(domain, mem_ctx, rid );
+                       
                        /* For the moment we set the primary group for
                           every user to be the Domain Users group.
                           There are serious problems with determining
@@ -107,10 +125,9 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
                           This should really be made into a 'winbind
                           force group' smb.conf parameter or
                           something like that. */
-                       (*info)[i].group_sid 
-                               = rid_to_talloced_sid(domain, 
-                                                     mem_ctx, 
-                                                     DOMAIN_GROUP_RID_USERS);
+                          
+                       (*info)[i].group_sid = rid_to_talloced_sid(domain, 
+                               mem_ctx, DOMAIN_GROUP_RID_USERS);
                }
 
                talloc_destroy(ctx2);
index 6400a23b7bf5f9eacb6d9030d50f743fa6aec696..7c4c8d804a813a7ff00dcc289ed7654e6a75c3fa 100644 (file)
@@ -84,6 +84,7 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
        char *name_domain, *name_user;
        DOM_SID sid;
        struct winbindd_domain *domain;
+       char *p;
 
        /* Ensure null termination */
        state->request.data.sid[sizeof(state->request.data.name.dom_name)-1]='\0';
@@ -91,13 +92,19 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
        /* Ensure null termination */
        state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0';
 
-       DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
-                 state->request.data.name.dom_name, 
-                 lp_winbind_separator(),
-                 state->request.data.name.name));
+       /* cope with the name being a fully qualified name */
+       p = strstr(state->request.data.name.name, lp_winbind_separator());
+       if (p) {
+               *p = 0;
+               name_domain = state->request.data.name.name;
+               name_user = p+1;
+       } else {
+               name_domain = state->request.data.name.dom_name;
+               name_user = state->request.data.name.name;
+       }
 
-       name_domain = state->request.data.name.dom_name;
-       name_user = state->request.data.name.name;
+       DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
+                 name_domain, lp_winbind_separator(), name_user));
 
        if ((domain = find_domain_from_name(name_domain)) == NULL) {
                DEBUG(0, ("could not find domain entry for domain %s\n", 
index e1308da3aa610fa406b5ac218d077f76dd4cf288..f54c97fc1bb29725e3aa266773f9e31186bd6f6d 100644 (file)
@@ -262,6 +262,7 @@ typedef struct
        BOOL bPamPasswordChange;
        BOOL bUnixPasswdSync;
        BOOL bPasswdChatDebug;
+       int iPasswdChatTimeout;
        BOOL bTimestampLogs;
        BOOL bNTSmbSupport;
        BOOL bNTPipeSupport;
@@ -280,7 +281,6 @@ typedef struct
        BOOL bDebugPid;
        BOOL bDebugUid;
        BOOL bHostMSDfs;
-       BOOL bHideLocalUsers;
        BOOL bUnicode;
        BOOL bUseMmap;
        BOOL bHostnameLookups;
@@ -565,9 +565,6 @@ static BOOL handle_netbios_aliases( const char *pszParmValue, char **ptr );
 static BOOL handle_netbios_scope( const char *pszParmValue, char **ptr );
 static BOOL handle_charset( const char *pszParmValue, char **ptr );
 
-static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr );
-static BOOL handle_ldap_sub_suffix ( const char *pszParmValue, char **ptr );
-
 static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr);
 
 static void set_server_role(void);
@@ -749,6 +746,12 @@ static const struct enum_list enum_map_to_guest[] = {
  *       Any parameter that does NOT have FLAG_ADVANCED will not disply at all
  *      Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
  *        respective views.
+ *
+ * NOTE2: Handling of duplicated (synonym) paramters:
+ *     Only the first occurance of a parameter should be enabled by FLAG_BASIC
+ *     and/or FLAG_ADVANCED. All duplicates following the first mention should be
+ *     set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
+ *     name first, and all synonyms must follow it with the FLAG_HIDE attribute.
  */
 
 static struct parm_struct parm_table[] = {
@@ -801,6 +804,7 @@ static struct parm_struct parm_table[] = {
        {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED}, 
        {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED}, 
        {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED}, 
+       {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED}, 
        {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED}, 
        {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED}, 
        {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED}, 
@@ -1064,11 +1068,11 @@ static struct parm_struct parm_table[] = {
        {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, FLAG_ADVANCED}, 
        {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, FLAG_ADVANCED}, 
 #endif
-       {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED}, 
-       {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, 
-       {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, 
-       {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, 
-       {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED}, 
+       {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED}, 
+       {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED}, 
+       {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED}, 
+       {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED}, 
+       {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED}, 
        {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED}, 
        {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED}, 
        {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, 
@@ -1133,7 +1137,6 @@ static struct parm_struct parm_table[] = {
 
        {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
        {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED}, 
-       {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED}, 
 
        {N_("VFS module options"), P_SEP, P_SEPARATOR}, 
 
@@ -1150,9 +1153,9 @@ static struct parm_struct parm_table[] = {
        {"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_DEPRECATED}, 
        {"idmap backend", P_STRING, 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_ADVANCED}, 
+       {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE}, 
        {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED}, 
-       {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED}, 
+       {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE}, 
        {"template primary group", P_STRING, P_GLOBAL, &Globals.szTemplatePrimaryGroup, NULL, NULL, FLAG_ADVANCED}, 
        {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED}, 
        {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED}, 
@@ -1417,6 +1420,7 @@ static void init_globals(void)
        Globals.bUnixPasswdSync = False;
        Globals.bPamPasswordChange = False;
        Globals.bPasswdChatDebug = False;
+       Globals.iPasswdChatTimeout = 2; /* 2 second default. */
        Globals.bUnicode = True;        /* Do unicode on the wire by default */
        Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
        Globals.bNTStatusSupport = True; /* Use NT status by default. */
@@ -1689,10 +1693,6 @@ FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
 #endif
 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
-FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
-FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
-FN_GLOBAL_STRING(lp_ldap_idmap_suffix, &Globals.szLdapIdmapSuffix)
-FN_GLOBAL_STRING(lp_ldap_group_suffix, &Globals.szLdapGroupSuffix)
 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
@@ -1734,6 +1734,7 @@ FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
+FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
@@ -1894,7 +1895,6 @@ FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
 FN_LOCAL_CHAR(lp_magicchar, magic_char)
 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
-FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
@@ -2992,56 +2992,56 @@ static BOOL handle_debug_list( const char *pszParmValueIn, char **ptr )
 }
 
 /***************************************************************************
- Handle setting ldap suffix and determines whether ldap machine suffix needs
- to be set as well.
- Set all of the sub suffix strings to be the 'ldap suffix' by default
+ Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
 ***************************************************************************/
 
-static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr )
+static char* append_ldap_suffix( const char *str )
 {
-       pstring suffix;
-               
-       pstrcpy(suffix, pszParmValue);
+       char *suffix_string;
 
-       /* set defaults for the the sub-suffixes */
-       
-       if (! *Globals.szLdapMachineSuffix )
-               string_set(&Globals.szLdapMachineSuffix, suffix);
-       if (! *Globals.szLdapUserSuffix ) 
-               string_set(&Globals.szLdapUserSuffix, suffix);
-       if (! *Globals.szLdapGroupSuffix ) 
-               string_set(&Globals.szLdapGroupSuffix, suffix);
-       if (! *Globals.szLdapIdmapSuffix ) 
-               string_set(&Globals.szLdapIdmapSuffix, suffix);
-
-       string_set(ptr, suffix); 
-       return True;
+
+       if (!lp_talloc)
+               lp_talloc = talloc_init("lp_talloc");
+
+       suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
+       if ( !suffix_string ) {
+               DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
+               return NULL;
+       }
+
+       return suffix_string;
 }
 
-/***************************************************************************
- Handle the ldap sub suffix option.
- Always append the 'ldap suffix' if it is set
-***************************************************************************/
+char *lp_ldap_machine_suffix(void)
+{
+       if (Globals.szLdapMachineSuffix[0])
+               return append_ldap_suffix(Globals.szLdapMachineSuffix);
+
+       return lp_string(Globals.szLdapSuffix);
+}
 
-static BOOL handle_ldap_sub_suffix( const char *pszParmValue, char **ptr)
+char *lp_ldap_user_suffix(void)
 {
-       pstring suffix;
-       
-       pstrcpy(suffix, pszParmValue);
+       if (Globals.szLdapUserSuffix[0])
+               return append_ldap_suffix(Globals.szLdapUserSuffix);
 
-       if (! *Globals.szLdapSuffix ) {
-               string_set( ptr, suffix );
-               return True;
-       }
-       else {
-               if ( *pszParmValue )
-                       pstrcat(suffix, ",");
-               pstrcat(suffix, Globals.szLdapSuffix);
-       }
-       
-       string_set( ptr, suffix );
-       return True;
+       return lp_string(Globals.szLdapSuffix);
+}
+
+char *lp_ldap_group_suffix(void)
+{
+       if (Globals.szLdapGroupSuffix[0])
+               return append_ldap_suffix(Globals.szLdapGroupSuffix);
+
+       return lp_string(Globals.szLdapSuffix);
+}
+
+char *lp_ldap_idmap_suffix(void)
+{
+       if (Globals.szLdapIdmapSuffix[0])
+               return append_ldap_suffix(Globals.szLdapIdmapSuffix);
+
+       return lp_string(Globals.szLdapSuffix);
 }
 
 /***************************************************************************
@@ -3311,9 +3311,13 @@ static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
                        if ((char ***)ptr && *(char ***)ptr) {
                                char **list = *(char ***)ptr;
                                
-                               for (; *list; list++)
-                                       fprintf(f, "%s%s", *list,
-                                               ((*(list+1))?", ":""));
+                               for (; *list; list++) {
+                                       /* surround strings with whitespace in single quotes */
+                                       if ( strchr_m( *list, ' ' ) )
+                                               fprintf(f, "\'%s\'%s", *list, ((*(list+1))?", ":""));
+                                       else
+                                               fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
+                               }
                        }
                        break;
 
index 9d8f600eeac9a81703528a40ee5d72d22338977e..6246cdaee138ecc67efb3267df1a407a08427b72 100644 (file)
@@ -416,6 +416,7 @@ NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
 {
        const char *guest_account = lp_guestaccount();
        GROUP_MAP map;
+       BOOL ret;
        
        if (!account_data || !pwd) {
                return NT_STATUS_INVALID_PARAMETER;
@@ -445,7 +446,11 @@ NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
        }
        
        /* call the mapping code here */
-       if(pdb_getgrgid(&map, pwd->pw_gid)) {
+       become_root();
+       ret = pdb_getgrgid(&map, pwd->pw_gid);
+       unbecome_root();
+       
+       if( ret ) {
                if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){
                        DEBUG(0,("Can't set Group SID!\n"));
                        return NT_STATUS_INVALID_PARAMETER;
@@ -725,14 +730,6 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
                return True;
        }
 
-       /*
-        * Don't try to convert the rid to a name if 
-        * running in appliance mode
-        */
-
-       if (lp_hide_local_users())
-               return False;
-               
        if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
                return False;
        }
@@ -852,18 +849,14 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
                return True;
        }
 
-       /* 
-        * Don't lookup local unix users if running in appliance mode
-        */
-       if (lp_hide_local_users()) 
-               return False;
-
        (void)map_username(user);
 
        if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
                return False;
        }
        
+       /* BEGIN ROOT BLOCK */
+       
        become_root();
        if (pdb_getsampwnam(sam_account, user)) {
                unbecome_root();
@@ -873,7 +866,6 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
                pdb_free_sam(&sam_account);
                return True;
        }
-       unbecome_root();
 
        pdb_free_sam(&sam_account);
 
@@ -889,8 +881,10 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
        } else {
                /* it's not a mapped group */
                grp = getgrnam(user);
-               if(!grp)
+               if(!grp) {
+                       unbecome_root();                /* ---> exit form block */      
                        return False;
+               }
                
                /* 
                 *check if it's mapped, if it is reply it doesn't exist
@@ -905,12 +899,15 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
                 */
                
                if (pdb_getgrgid(&map, grp->gr_gid)){
+                       unbecome_root();                /* ---> exit form block */
                        return False;
                }
                
                sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
                *psid_name_use = SID_NAME_ALIAS;
        }
+       unbecome_root();
+       /* END ROOT BLOCK */
 
        sid_copy( psid, &local_sid);
 
index 023e9f3fe0b62eb70879f109a3973a99a7a1a250..4d7c7791bd6b2f417637062bbd044e34f1221355 100644 (file)
@@ -415,8 +415,8 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
                        logon_script,
                        profile_path,
                        acct_desc,
-                       munged_dial,
                        workstations;
+       char            munged_dial[2048];
        uint32          user_rid; 
        uint8           smblmpwd[LM_HASH_LEN],
                        smbntpwd[NT_HASH_LEN];
@@ -660,6 +660,13 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
                pdb_set_workstations(sampass, workstations, PDB_SET);
        }
 
+       if (!smbldap_get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, 
+               get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), munged_dial)) {
+               /* leave as default */;
+       } else {
+               pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
+       }
+       
        /* FIXME: hours stuff should be cleaner */
        
        logon_divs = 168;
@@ -703,7 +710,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
        pdb_set_hours_len(sampass, hours_len, PDB_SET);
        pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
 
-       pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
+/*     pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */
        
        /* pdb_set_unknown_3(sampass, unknown3, PDB_SET); */
 
@@ -851,7 +858,12 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), 
                        pdb_get_workstations(sampass));
-
+       
+       if (need_update(sampass, PDB_MUNGEDDIAL))
+               smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
+                       get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MUNGED_DIAL), 
+                       pdb_get_munged_dial(sampass));
+       
        if (need_update(sampass, PDB_SMBHOME))
                smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
                        get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), 
index 6a7675a12aaadae209a53e2dce676ec0362e3b4d..6e9ccecc9e80f7212aecc5e7bf2c03173ddf50f4 100644 (file)
@@ -76,6 +76,8 @@ static const known_sid_users builtin_groups[] = {
        { BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" },
        { BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" },
        { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" },
+       { BUILTIN_ALIAS_RID_REPLICATOR, SID_NAME_ALIAS, "Replicator" },
+       { BUILTIN_ALIAS_RID_RAS_SERVERS, SID_NAME_ALIAS, "RAS Servers" },
        {  0, (enum SID_NAME_USE)0, NULL}};
 
 /**************************************************************************
@@ -290,7 +292,7 @@ BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char
                        continue;
 
                for (j=0; users[j].known_user_name != NULL; j++) {
-                       if (strequal(users[j].known_user_name, name) == 0) {
+                       if ( strequal(users[j].known_user_name, name) ) {
                                sid_copy(sid, sid_name_map[i].sid);
                                sid_append_rid(sid, users[j].rid);
                                *use = users[j].sid_name_use;
index 34eee7d97f7c569056012627a3dbae32fe58cbc1..f0096a17c2c40a42c082eb0288ac2039716b8e9f 100644 (file)
@@ -681,7 +681,8 @@ cups_job_submit(int snum, struct printjob *pjob)
                        *response;      /* IPP Response */
        cups_lang_t     *language;      /* Default language */
        char            uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
+       char            *clientname;    /* hostname of client for job-originating-host attribute */
+       pstring         new_jobname;
 
        DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
 
@@ -735,12 +736,20 @@ cups_job_submit(int snum, struct printjob *pjob)
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
                     NULL, pjob->user);
 
+       clientname = client_name();
+       if (strcmp(clientname, "UNKNOWN") == 0) {
+               clientname = client_addr();
+       }
+
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                     "job-originating-host-name", NULL,
-                    get_remote_machine_name());
+                     clientname);
+
+        pstr_sprintf(new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX, 
+               (unsigned int)pjob->smbjob, pjob->jobname);
 
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
-                    pjob->jobname);
+                    new_jobname);
 
        /*
        * Do the request and get back a response...
index ad17213c2d65f0d0efeb83cb0d3cad1f446b03fd..bdcd9504505e3b32903f95fe19bcd7f1a36d74c0 100644 (file)
@@ -613,12 +613,14 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
        pj.status = q->status;
        pj.size = q->size;
        pj.spooled = True;
-       pj.smbjob = (old_pj != NULL ? True : False);
        fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
-       if (jobid < UNIX_JOB_START)
+       if (jobid < UNIX_JOB_START) {
+               pj.smbjob = (old_pj != NULL ? True : False);
                fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
-       else
+       } else {
+               pj.smbjob = False;
                fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
+       }
        fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
        fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
 
@@ -2063,6 +2065,8 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
                return True;
        }
 
+       pjob->smbjob = jobid;
+
        ret = (*(current_printif->job_submit))(snum, pjob);
 
        if (ret)
index 97bc4c65b76c68985580c0709bbc859242f9d9d9..70ac4603034a6f57eb7a0d863c3a2c1046351e0a 100644 (file)
@@ -654,11 +654,17 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
        ZERO_STRUCT(netlogon_sess_key);
        memcpy(netlogon_sess_key, cli->sess_key, 8);
        
-       if (memcmp(zeros, info3->user_sess_key, 16) != 0)
+       if (memcmp(zeros, info3->user_sess_key, 16) != 0) {
                SamOEMhash(info3->user_sess_key, netlogon_sess_key, 16);
-               
-       if (memcmp(zeros, info3->padding, 16) != 0)
+       } else {
+               memset(info3->user_sess_key, '\0', 16);
+       }
+
+       if (memcmp(zeros, info3->padding, 16) != 0) {
                SamOEMhash(info3->padding, netlogon_sess_key, 16);
+       } else {
+               memset(info3->padding, '\0', 16);
+       }
 
         /* Return results */
 
index 9ce10202dbe456cb471cb8588bbb3829ede671e6..49abf787eed590562fb7c150f49cc645d219401e 100644 (file)
@@ -264,13 +264,16 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
                           later use */
 
                        DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len);
-                       
+                       BOOL store_ok;
+
                        /* save the reply away, for use a little later */
                        prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len);
 
+                       store_ok = (NT_STATUS_IS_OK(ntlmssp_store_response(cli->ntlmssp_pipe_state, 
+                                                                          ntlmssp_verf)));
 
-                       return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state, 
-                                                                             ntlmssp_verf)));
+                       data_blob_free(&ntlmssp_verf);
+                       return store_ok;
                } 
                else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
                        /* nothing to do here - we don't seem to be able to 
@@ -307,12 +310,12 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
                                DEBUG(1, ("Can't unseal - data_len < 0!!\n"));
                                return False;
                        }
-                       nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state, 
+                       nt_status = ntlmssp_unseal_packet(cli->ntlmssp_pipe_state, 
                                                                 (unsigned char *)reply_data, data_len,
                                                                 &sig);
                } 
                else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
-                       nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state, 
+                       nt_status = ntlmssp_check_packet(cli->ntlmssp_pipe_state, 
                                                                (const unsigned char *)reply_data, data_len,
                                                                &sig);
                }
@@ -674,9 +677,9 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
                DATA_BLOB request;
 
                DEBUG(5, ("Processing NTLMSSP Negotiate\n"));
-               nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state,
-                                                 null_blob,
-                                                 &request);
+               nt_status = ntlmssp_update(cli->ntlmssp_pipe_state,
+                                          null_blob,
+                                          &request);
 
                if (!NT_STATUS_EQUAL(nt_status, 
                                     NT_STATUS_MORE_PROCESSING_REQUIRED)) {
@@ -777,9 +780,9 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli,
 
        /* The response is picked up from the internal cache,
           where it was placed by the rpc_auth_pipe() code */
-       nt_status = ntlmssp_client_update(cli->ntlmssp_pipe_state,
-                                         ntlmssp_null_response,
-                                         &ntlmssp_reply);
+       nt_status = ntlmssp_update(cli->ntlmssp_pipe_state,
+                                  ntlmssp_null_response,
+                                  &ntlmssp_reply);
        
        if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                return nt_status;
@@ -819,14 +822,6 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
-               nt_status = ntlmssp_client_sign_init(cli->ntlmssp_pipe_state);
-               
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       return nt_status;
-               }
-       }
-
        data_blob_free(&ntlmssp_reply);
        return NT_STATUS_OK;
 }
@@ -994,7 +989,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                                 */
                                if (cli->pipe_auth_flags & AUTH_PIPE_SEAL) {
                                        
-                                       nt_status = ntlmssp_client_seal_packet(cli->ntlmssp_pipe_state,
+                                       nt_status = ntlmssp_seal_packet(cli->ntlmssp_pipe_state,
                                                                               (unsigned char*)prs_data_p(&sec_blob),
                                                                               data_and_padding_size,
                                                                               &sign_blob);
@@ -1005,7 +1000,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
                                } 
                                else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
                                        
-                                       nt_status = ntlmssp_client_sign_packet(cli->ntlmssp_pipe_state,
+                                       nt_status = ntlmssp_sign_packet(cli->ntlmssp_pipe_state,
                                                                               (unsigned char*)prs_data_p(&sec_blob),
                                                                               data_and_padding_size, &sign_blob);
                                        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -1231,7 +1226,8 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC
        if ( hdr_ba->addr.len <= 0)
                return False;
                
-       if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe )) 
+       if ( !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].client_pipe) &&
+            !strequal(hdr_ba->addr.str, pipe_names[pipe_idx].server_pipe) )
        {
                DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s.  oh well!\n",
                         pipe_names[i].server_pipe ,hdr_ba->addr.str));
@@ -1332,6 +1328,10 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na
                if (!NT_STATUS_IS_OK(nt_status))
                        return False;
 
+               /* Currently the NTLMSSP code does not implement NTLM2 correctly for signing or sealing */
+
+               cli->ntlmssp_pipe_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
+
                nt_status = ntlmssp_set_username(cli->ntlmssp_pipe_state, 
                                                 cli->user_name);
                if (!NT_STATUS_IS_OK(nt_status))
index e5e67f39dc9a7b0164c7446e7506f8b919df96a1..0eebcd0a6f51204f09f28c42c454ce76157ba020 100644 (file)
@@ -1341,7 +1341,7 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
                                POLICY_HND *user_pol, uint16 switch_value,
-                               uchar sess_key[16], SAM_USERINFO_CTR *ctr)
+                               DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
 {
        prs_struct qbuf, rbuf;
        SAMR_Q_SET_USERINFO q;
@@ -1353,6 +1353,11 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
+       if (!sess_key->length) {
+               DEBUG(1, ("No user session key\n"));
+               return NT_STATUS_NO_USER_SESSION_KEY;
+       }
+
        /* Initialise parse structures */
 
        prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
@@ -1393,7 +1398,7 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
                                 POLICY_HND *user_pol, uint16 switch_value,
-                                uchar sess_key[16], SAM_USERINFO_CTR *ctr)
+                                DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
 {
        prs_struct qbuf, rbuf;
        SAMR_Q_SET_USERINFO2 q;
@@ -1402,6 +1407,11 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 
        DEBUG(10,("cli_samr_set_userinfo2\n"));
 
+       if (!sess_key->length) {
+               DEBUG(1, ("No user session key\n"));
+               return NT_STATUS_NO_USER_SESSION_KEY;
+       }
+
        ZERO_STRUCT(q);
        ZERO_STRUCT(r);
 
index 203122e73c0ebc150afddb841ac45e64a3cdde31..afdf0fc4c9b43ba55dbb909b2c001bcfe6a84cc0 100644 (file)
@@ -1015,7 +1015,11 @@ void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob)
        str->uni_str_len = blob->length / sizeof(uint16);
        str->uni_max_len = str->uni_str_len;
        str->offset = 0;
-       str->buffer = (uint16 *) memdup(blob->data, blob->length);
+       if (blob->length) {
+               str->buffer = (uint16 *) memdup(blob->data, blob->length);
+       } else {
+               str->buffer = NULL;
+       }
        if ((str->buffer == NULL) && (blob->length > 0)) {
                smb_panic("init_unistr2_from_datablob: malloc fail\n");
        }
index 3b096e088ab2aa19dbd62bbf4178d14e94970645..ad0a91e7ea5998f42fe3b57c4fc2e03b34dae67a 100644 (file)
@@ -1265,7 +1265,8 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
                         
                         uint16 logon_count, uint16 bad_pw_count,
                         uint32 num_groups, const DOM_GID *gids,
-                        uint32 user_flgs, uchar sess_key[16],
+                        uint32 user_flgs, uchar nt_session_key[16],
+                        uchar lm_session_key[16],
                         const char *logon_srv, const char *logon_dom,
                         const DOM_SID *dom_sid, const char *other_sids)
 {
@@ -1307,8 +1308,8 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
        usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
        usr->user_flgs = user_flgs;
 
-       if (sess_key != NULL)
-               memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
+       if (nt_session_key != NULL)
+               memcpy(usr->user_sess_key, nt_session_key, sizeof(usr->user_sess_key));
        else
                memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
 
@@ -1316,6 +1317,10 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
 
        memset((char *)usr->padding, '\0', sizeof(usr->padding));
 
+       if (lm_session_key != NULL) 
+               memcpy(usr->padding, lm_session_key, sizeof(usr->user_sess_key));
+
+
        num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
 
        usr->num_other_sids = num_other_sids;
index 73107f8f61e2cdd544faa5720419236f438c1880..607c9ecf64052c0820724cf1612dcb8643742991 100644 (file)
@@ -181,9 +181,9 @@ BOOL samr_io_r_lookup_domain(const char *desc, SAMR_R_LOOKUP_DOMAIN * r_u,
 reads or writes a structure.
 ********************************************************************/
 
-void init_samr_q_remove_user_foreign_domain(SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN * q_u, POLICY_HND *dom_pol, DOM_SID *sid)
+void init_samr_q_remove_sid_foreign_domain(SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN * q_u, POLICY_HND *dom_pol, DOM_SID *sid)
 {
-       DEBUG(5, ("samr_init_samr_q_remove_user_foreign_domain\n"));
+       DEBUG(5, ("samr_init_samr_q_remove_sid_foreign_domain\n"));
 
        q_u->dom_pol = *dom_pol;
        init_dom_sid2(&q_u->sid, sid);
@@ -193,13 +193,13 @@ void init_samr_q_remove_user_foreign_domain(SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *
 reads or writes a structure.
 ********************************************************************/
 
-BOOL samr_io_q_remove_user_foreign_domain(const char *desc, SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN * q_u,
+BOOL samr_io_q_remove_sid_foreign_domain(const char *desc, SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN * q_u,
                          prs_struct *ps, int depth)
 {
        if (q_u == NULL)
                return False;
 
-       prs_debug(ps, depth, desc, "samr_io_q_remove_user_foreign_domain");
+       prs_debug(ps, depth, desc, "samr_io_q_remove_sid_foreign_domain");
        depth++;
 
        if(!prs_align(ps))
@@ -221,13 +221,13 @@ BOOL samr_io_q_remove_user_foreign_domain(const char *desc, SAMR_Q_REMOVE_USER_F
 reads or writes a structure.
 ********************************************************************/
 
-BOOL samr_io_r_remove_user_foreign_domain(const char *desc, SAMR_R_REMOVE_USER_FOREIGN_DOMAIN * r_u,
+BOOL samr_io_r_remove_sid_foreign_domain(const char *desc, SAMR_R_REMOVE_SID_FOREIGN_DOMAIN * r_u,
                          prs_struct *ps, int depth)
 {
        if (r_u == NULL)
                return False;
 
-       prs_debug(ps, depth, desc, "samr_io_r_remove_user_foreign_domain");
+       prs_debug(ps, depth, desc, "samr_io_r_remove_sid_foreign_domain");
        depth++;
 
        if(!prs_align(ps))
@@ -5938,7 +5938,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
        const char*             description = pdb_get_acct_desc(pw);
        const char*             workstations = pdb_get_workstations(pw);
        const char*             munged_dial = pdb_get_munged_dial(pw);
-       DATA_BLOB blob = base64_decode_data_blob(munged_dial);
+       DATA_BLOB               munged_dial_blob;
 
        uint32 user_rid;
        const DOM_SID *user_sid;
@@ -5946,6 +5946,12 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
        uint32 group_rid;
        const DOM_SID *group_sid;
 
+       if (munged_dial) {
+               munged_dial_blob = base64_decode_data_blob(munged_dial);
+       } else {
+               munged_dial_blob = data_blob(NULL, 0);
+       }
+
        /* Create NTTIME structs */
        unix_to_nt_time (&logon_time,           pdb_get_logon_time(pw));
        unix_to_nt_time (&logoff_time,          pdb_get_logoff_time(pw));
@@ -5975,7 +5981,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
                          user_name, 
                          sid_to_string(user_sid_string, user_sid),
                          sid_to_string(domain_sid_string, domain_sid)));
-               data_blob_free(&blob);
+               data_blob_free(&munged_dial_blob);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -5989,7 +5995,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
                          user_name, 
                          sid_to_string(group_sid_string, group_sid),
                          sid_to_string(domain_sid_string, domain_sid)));
-               data_blob_free(&blob);
+               data_blob_free(&munged_dial_blob);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -6049,9 +6055,9 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
        init_unistr2(&usr->uni_unknown_str, NULL, UNI_STR_TERMINATE);
        init_uni_hdr(&usr->hdr_unknown_str, &usr->uni_unknown_str);
 
-       init_unistr2_from_datablob(&usr->uni_munged_dial, &blob);
+       init_unistr2_from_datablob(&usr->uni_munged_dial, &munged_dial_blob);
        init_uni_hdr(&usr->hdr_munged_dial, &usr->uni_munged_dial);
-       data_blob_free(&blob);
+       data_blob_free(&munged_dial_blob);
 
        usr->unknown_6 = pdb_get_unknown_6(pw);
        usr->padding4 = 0;
@@ -6296,8 +6302,8 @@ NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
 inits a SAM_USERINFO_CTR structure.
 ********************************************************************/
 
-void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, uchar * sess_key,
-                           uint16 switch_value, void *info)
+static void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB *sess_key,
+                                  uint16 switch_value, void *info)
 {
        DEBUG(5, ("init_samr_userinfo_ctr\n"));
 
@@ -6306,13 +6312,13 @@ void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, uchar * sess_key,
 
        switch (switch_value) {
        case 0x18:
-               SamOEMhash(ctr->info.id24->pass, sess_key, 516);
-               dump_data(100, (char *)sess_key, 16);
+               SamOEMhashBlob(ctr->info.id24->pass, 516, sess_key);
+               dump_data(100, (char *)sess_key->data, sess_key->length);
                dump_data(100, (char *)ctr->info.id24->pass, 516);
                break;
        case 0x17:
-               SamOEMhash(ctr->info.id23->pass, sess_key, 516);
-               dump_data(100, (char *)sess_key, 16);
+               SamOEMhashBlob(ctr->info.id23->pass, 516, sess_key);
+               dump_data(100, (char *)sess_key->data, sess_key->length);
                dump_data(100, (char *)ctr->info.id23->pass, 516);
                break;
        default:
@@ -6497,7 +6503,7 @@ inits a SAMR_Q_SET_USERINFO structure.
 ********************************************************************/
 
 void init_samr_q_set_userinfo(SAMR_Q_SET_USERINFO * q_u,
-                             POLICY_HND *hnd,  unsigned char sess_key[16],
+                             POLICY_HND *hnd, DATA_BLOB *sess_key,
                              uint16 switch_value, void *info)
 {
        DEBUG(5, ("init_samr_q_set_userinfo\n"));
@@ -6571,7 +6577,7 @@ inits a SAMR_Q_SET_USERINFO2 structure.
 ********************************************************************/
 
 void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
-                              POLICY_HND *hnd, unsigned char sess_key[16],
+                              POLICY_HND *hnd, DATA_BLOB *sess_key,
                               uint16 switch_value, SAM_USERINFO_CTR * ctr)
 {
        DEBUG(5, ("init_samr_q_set_userinfo2\n"));
@@ -6585,9 +6591,9 @@ void init_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 * q_u,
 
        switch (switch_value) {
        case 0x12:
-               SamOEMhash(ctr->info.id12->lm_pwd, sess_key, 16);
-               SamOEMhash(ctr->info.id12->nt_pwd, sess_key, 16);
-               dump_data(100, (char *)sess_key, 16);
+               SamOEMhashBlob(ctr->info.id12->lm_pwd, 16, sess_key);
+               SamOEMhashBlob(ctr->info.id12->nt_pwd, 16, sess_key);
+               dump_data(100, (char *)sess_key->data, sess_key->length);
                dump_data(100, (char *)ctr->info.id12->lm_pwd, 16);
                dump_data(100, (char *)ctr->info.id12->nt_pwd, 16);
                break;
index ac3ed9c3947db3280d06d331bfe9678a86201ff3..f324fd126ed00a5fde30876dd274e33f1c3821f0 100644 (file)
@@ -369,6 +369,7 @@ WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u,
 {
        UNISTR2* uni_path = &q_u->uni_path;
        uint32 level = q_u->level;
+       int consumedcnt = sizeof(pstring);
        pstring path;
        struct junction_map jn;
 
@@ -377,7 +378,7 @@ WERROR _dfs_get_info(pipes_struct *p, DFS_Q_DFS_GET_INFO *q_u,
                return WERR_DFS_NO_SUCH_SERVER;
   
        /* The following call can change the cwd. */
-       if(!get_referred_path(path, &jn, NULL, NULL)) {
+       if(!get_referred_path(path, &jn, &consumedcnt, NULL) || consumedcnt < strlen(path)) {
                vfs_ChDir(p->conn,p->conn->connectpath);
                return WERR_DFS_NO_SUCH_VOL;
        }
index 0a8ad404cb3ccfd9d5c811e33d3c4c18c10815cd..e545d8c2673ac5ec8db4da3f5c54d4faa4d2fc77 100644 (file)
@@ -845,6 +845,7 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU
        int num_entries=0;
        LSA_SID_ENUM *sids=&r_u->sids;
        int i=0,j=0;
+       BOOL ret;
 
        if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
                return NT_STATUS_INVALID_HANDLE;
@@ -858,8 +859,14 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU
                return NT_STATUS_ACCESS_DENIED;
 
        /* get the list of mapped groups (domain, local, builtin) */
-       if(!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED))
+       become_root();
+       ret = pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED);
+       unbecome_root();
+       if( !ret ) {
+               DEBUG(3,("_lsa_enum_accounts: enumeration of groups failed!\n"));
                return NT_STATUS_OK;
+       }
+       
 
        if (q_u->enum_context >= num_entries)
                return NT_STATUS_NO_MORE_ENTRIES;
index e6d005b157526063e89dfdf8aa3c3342e58521af..e8bc6345dee964ced45ccbc11a421c1640356428 100644 (file)
@@ -683,7 +683,8 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
                pstring my_name;
                fstring user_sid_string;
                fstring group_sid_string;
-               uchar user_sess_key[16];
+               uchar nt_session_key[16];
+               uchar lm_session_key[16];
                uchar netlogon_sess_key[16];
 
                sampw = server_info->sam_account;
@@ -718,10 +719,18 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
 
                ZERO_STRUCT(netlogon_sess_key);
                memcpy(netlogon_sess_key, p->dc.sess_key, 8);
-               memcpy(user_sess_key, server_info->session_key, sizeof(user_sess_key));
-               SamOEMhash(user_sess_key, netlogon_sess_key, 16);
+               if (server_info->nt_session_key.length) {
+                       memcpy(nt_session_key, server_info->nt_session_key.data, 
+                              MIN(sizeof(nt_session_key), server_info->nt_session_key.length));
+                       SamOEMhash(nt_session_key, netlogon_sess_key, 16);
+               }
+               if (server_info->lm_session_key.length) {
+                       memcpy(lm_session_key, server_info->lm_session_key.data, 
+                              MIN(sizeof(lm_session_key), server_info->lm_session_key.length));
+                       SamOEMhash(lm_session_key, netlogon_sess_key, 16);
+               }
                ZERO_STRUCT(netlogon_sess_key);
-
+               
                init_net_user_info3(p->mem_ctx, usr_info, 
                                    user_rid,
                                    group_rid,   
@@ -743,14 +752,16 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
                                    num_gids,    /* uint32 num_groups */
                                    gids    , /* DOM_GID *gids */
                                    0x20    , /* uint32 user_flgs (?) */
-                                   user_sess_key,
+                                   server_info->nt_session_key.length ? nt_session_key : NULL,
+                                   server_info->lm_session_key.length ? lm_session_key : NULL,
                                    my_name     , /* char *logon_srv */
                                    pdb_get_domain(sampw),
                                    &domain_sid,     /* DOM_SID *dom_sid */  
                                    /* Should be users domain sid, not servers - for trusted domains */
                                  
                                    NULL); /* char *other_sids */
-               ZERO_STRUCT(user_sess_key);
+               ZERO_STRUCT(nt_session_key);
+               ZERO_STRUCT(lm_session_key);
        }
        free_server_info(&server_info);
        return status;
index 96261c665f7455bf24d8ff2e5c4a375fcbd4645d..fa24efe589bcb21601b852e88cdecb216cf7058d 100644 (file)
@@ -420,9 +420,15 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
         * Set up the sign/seal data.
         */
 
-       {
+       if (server_info->lm_session_key.length != 16) {
+               DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \
+succeeded authentication on named pipe %s, but session key was of incorrect length [%u].\n", 
+                        domain, user_name, wks, p->name, server_info->lm_session_key.length));
+               free_server_info(&server_info);
+               return False;
+       } else {
                uchar p24[24];
-               NTLMSSPOWFencrypt(server_info->first_8_lm_hash, lm_owf, p24);
+               NTLMSSPOWFencrypt(server_info->lm_session_key.data, lm_owf, p24);
                {
                        unsigned char j = 0;
                        int ind;
@@ -468,7 +474,7 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
         * Store the UNIX credential data (uid/gid pair) in the pipe structure.
         */
 
-       memcpy(p->session_key, server_info->session_key, sizeof(p->session_key));
+       p->session_key = data_blob(server_info->lm_session_key.data, server_info->lm_session_key.length);
 
        p->pipe_user.uid = server_info->uid;
        p->pipe_user.gid = server_info->gid;
index 57e45d477fef2ce3e0e182abf4ad3b2a519af435..514c22d471e3dd74547486723d09f0c0299132b4 100644 (file)
@@ -342,7 +342,7 @@ static void *make_internal_rpc_pipe_p(char *pipe_name,
        
        /* Store the session key and NT_TOKEN */
        if (vuser) {
-               memcpy(p->session_key, vuser->session_key, sizeof(p->session_key));
+               p->session_key = data_blob(vuser->session_key.data, vuser->session_key.length);
                p->pipe_user.nt_user_token = dup_nt_token(vuser->nt_user_token);
        }
 
@@ -772,6 +772,7 @@ static ssize_t process_complete_pdu(pipes_struct *p)
 static ssize_t process_incoming_data(pipes_struct *p, char *data, size_t n)
 {
        size_t data_to_copy = MIN(n, MAX_PDU_FRAG_LEN - p->in_data.pdu_received_len);
+       size_t old_pdu_received_len = p->in_data.pdu_received_len;
 
        DEBUG(10,("process_incoming_data: Start: pdu_received_len = %u, pdu_needed_len = %u, incoming data = %u\n",
                (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len,
@@ -831,10 +832,11 @@ incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned
 
        /*
         * Do we have a complete PDU ?
+        * (return the nym of bytes handled in the call)
         */
 
        if(p->in_data.pdu_received_len == p->in_data.pdu_needed_len)
-               return process_complete_pdu(p);
+               return process_complete_pdu(p) - old_pdu_received_len;
 
        DEBUG(10,("process_incoming_data: not a complete PDU yet. pdu_received_len = %u, pdu_needed_len = %u\n",
                (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len ));
index a0f62c20fcaac8d7698f27c7fa9c4ff6c307050d..971f5ed40ce1feeeaf3612b3065b3f8a87e5495f 100644 (file)
@@ -1343,13 +1343,13 @@ static BOOL api_samr_open_group(pipes_struct *p)
 }
 
 /*******************************************************************
- api_samr_remove_user_foreign_domain
+ api_samr_remove_sid_foreign_domain
  ********************************************************************/
 
-static BOOL api_samr_remove_user_foreign_domain(pipes_struct *p)
+static BOOL api_samr_remove_sid_foreign_domain(pipes_struct *p)
 {
-       SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN q_u;
-       SAMR_R_REMOVE_USER_FOREIGN_DOMAIN r_u;
+       SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN q_u;
+       SAMR_R_REMOVE_SID_FOREIGN_DOMAIN r_u;
 
        prs_struct *data = &p->in_data.data;
        prs_struct *rdata = &p->out_data.rdata;
@@ -1357,15 +1357,15 @@ static BOOL api_samr_remove_user_foreign_domain(pipes_struct *p)
        ZERO_STRUCT(q_u);
        ZERO_STRUCT(r_u);
 
-       if (!samr_io_q_remove_user_foreign_domain("", &q_u, data, 0)) {
-               DEBUG(0,("api_samr_remove_user_foreign_domain: unable to unmarshall SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN.\n"));
+       if (!samr_io_q_remove_sid_foreign_domain("", &q_u, data, 0)) {
+               DEBUG(0,("api_samr_remove_sid_foreign_domain: unable to unmarshall SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN.\n"));
                return False;
        }
 
-       r_u.status = _samr_remove_user_foreign_domain(p, &q_u, &r_u);
+       r_u.status = _samr_remove_sid_foreign_domain(p, &q_u, &r_u);
 
-       if (!samr_io_r_remove_user_foreign_domain("", &r_u, rdata, 0)) {
-               DEBUG(0,("api_samr_remove_user_foreign_domain: unable to marshall SAMR_R_REMOVE_USER_FOREIGN_DOMAIN.\n"));
+       if (!samr_io_r_remove_sid_foreign_domain("", &r_u, rdata, 0)) {
+               DEBUG(0,("api_samr_remove_sid_foreign_domain: unable to marshall SAMR_R_REMOVE_SID_FOREIGN_DOMAIN.\n"));
                return False;
        }
 
@@ -1483,7 +1483,7 @@ static struct api_struct api_samr_cmds [] =
       {"SAMR_OPEN_ALIAS"        , SAMR_OPEN_ALIAS       , api_samr_open_alias       },
       {"SAMR_OPEN_GROUP"        , SAMR_OPEN_GROUP       , api_samr_open_group       },
       {"SAMR_OPEN_DOMAIN"       , SAMR_OPEN_DOMAIN      , api_samr_open_domain      },
-      {"SAMR_REMOVE_USER_FOREIGN_DOMAIN"       , SAMR_REMOVE_USER_FOREIGN_DOMAIN      , api_samr_remove_user_foreign_domain      },
+      {"SAMR_REMOVE_SID_FOREIGN_DOMAIN"       , SAMR_REMOVE_SID_FOREIGN_DOMAIN      , api_samr_remove_sid_foreign_domain      },
       {"SAMR_LOOKUP_DOMAIN"     , SAMR_LOOKUP_DOMAIN    , api_samr_lookup_domain    },
       
       {"SAMR_QUERY_SEC_OBJECT"  , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj    },
index b3e6478c8808011cf6853215b88f981810baa61e..7f57a9fc9d42d8c59dbe015470fe1bc49ee40d61 100644 (file)
@@ -292,6 +292,7 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
        uint32 group_entries = 0;
        uint32 i;
        TALLOC_CTX *mem_ctx = info->mem_ctx;
+       BOOL ret;
 
        DEBUG(10,("load_group_domain_entries\n"));
 
@@ -303,13 +304,14 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
        
 
        become_root();
-
-       if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) {
+       ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED); 
+       unbecome_root();
+       
+       if ( !ret ) {
                DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
                return NT_STATUS_NO_MEMORY;
        }
        
-       unbecome_root();
 
        info->disp_info.num_group_account=group_entries;
 
@@ -875,140 +877,11 @@ static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNIST
 
 /*******************************************************************
  Get the group entries - similar to get_sampwd_entries().
- ********************************************************************/
-
-static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
-                                   uint32 *p_num_entries, uint32 max_entries)
-{
-       fstring sid_str;
-       uint32 num_entries = 0;
-       int i;
-       GROUP_MAP smap;
-       GROUP_MAP *map = NULL;
-
-       sid_to_string(sid_str, sid);
-       DEBUG(5, ("get_group_alias_entries: enumerating aliases on SID: %s\n", sid_str));
-
-       *p_num_entries = 0;
-
-       /* well-known aliases */
-       if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
-               
-               become_root();
-               pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED);
-               unbecome_root();
-               
-               if (num_entries != 0) {         
-                       *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
-                       if (*d_grp==NULL)
-                               return NT_STATUS_NO_MEMORY;
-                       
-                       for(i=0; i<num_entries && i<max_entries; i++) {
-                               fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
-                               sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
-                               
-                       }
-               }
-               SAFE_FREE(map);
-               
-       } else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
-               struct sys_grent *glist;
-               struct sys_grent *grp;
-               gid_t winbind_gid_low, winbind_gid_high;
-               BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
-               BOOL ret;
-
-               /* local aliases */
-               /* we return the UNIX groups here.  This seems to be the right */
-               /* thing to do, since NT member servers return their local     */
-                /* groups in the same situation.                               */
-
-               /* use getgrent_list() to retrieve the list of groups to avoid
-                * problems with getgrent possible infinite loop by internal
-                * libc grent structures overwrites by called functions */
-               grp = glist = getgrent_list();
-               if (grp == NULL)
-                       return NT_STATUS_NO_MEMORY;
-               
-               for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
-                       uint32 trid;
-                       
-                       become_root();
-                       ret = pdb_getgrgid(&smap, grp->gr_gid);
-                       unbecome_root();
-                       if( !ret )
-                               continue;
-                       
-                       if (smap.sid_name_use!=SID_NAME_ALIAS) {
-                               continue;
-                       }
-
-                       sid_split_rid(&smap.sid, &trid);
-                       
-                       if (!sid_equal(sid, &smap.sid))
-                               continue;
-
-                       /* Don't return winbind groups as they are not local! */
-                       if (winbind_groups_exist && (grp->gr_gid >= winbind_gid_low)&&(grp->gr_gid <= winbind_gid_high)) {
-                               DEBUG(10,("get_group_alias_entries: not returing %s, not local.\n", smap.nt_name ));
-                               continue;
-                       }
-
-                       /* Don't return user private groups... */
-
-                       if (Get_Pwnam(smap.nt_name) != 0) {
-                               DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
-                               continue;                       
-                       }
-
-                       for( i = 0; i < num_entries; i++)
-                               if ( (*d_grp)[i].rid == trid )
-                                       break;
-
-                       if ( i < num_entries ) {
-                               continue; /* rid was there, dup! */
-                       }
-
-                       /* JRA - added this for large group db enumeration... */
-
-                       if (start_idx > 0) {
-                               /* skip the requested number of entries.
-                                       not very efficient, but hey...
-                               */
-                               start_idx--;
-                               continue;
-                       }
-
-                       *d_grp=talloc_realloc(ctx,*d_grp, (num_entries+1)*sizeof(DOMAIN_GRP));
-                       if (*d_grp==NULL) {
-                               grent_free(glist);
-                               return NT_STATUS_NO_MEMORY;
-                       }
-
-                       fstrcpy((*d_grp)[num_entries].name, smap.nt_name);
-                       (*d_grp)[num_entries].rid = trid;
-                       num_entries++;
-                       DEBUG(10,("get_group_alias_entries: added entry %d, rid:%d\n", num_entries, trid));
-               }
-
-               grent_free(glist);
-       }
-
-       *p_num_entries = num_entries;
-
-       DEBUG(10,("get_group_alias_entries: returning %d entries\n", *p_num_entries));
-
-       if (num_entries >= max_entries)
-               return STATUS_MORE_ENTRIES;
-       return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Get the group entries - similar to get_sampwd_entries().
- ********************************************************************/
+ ******************************************************************/
 
-static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
-                                    uint32 *p_num_entries, uint32 max_entries)
+static NTSTATUS get_group_entries( enum SID_NAME_USE type, TALLOC_CTX *ctx, 
+                                   DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
+                                   uint32 *p_num_entries, uint32 max_entries )
 {
        GROUP_MAP *map=NULL;
        int i;
@@ -1021,7 +894,7 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO
           needed for some passdb backends to enumerate groups */
           
        become_root();
-       pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
+       pdb_enum_group_mapping(type, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
        unbecome_root();
        
        num_entries=group_entries-start_idx;
@@ -1042,13 +915,51 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO
                fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
                fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
                sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
-               (*d_grp)[i].attr=SID_NAME_DOM_GRP;
+               (*d_grp)[i].attr=type;
        }
 
        SAFE_FREE(map);
 
        *p_num_entries = num_entries;
 
+       DEBUG(10,("get_group_entries: returning %d entries\n", *p_num_entries));
+
+       return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Wrapper for enuemrating domain groups
+ ******************************************************************/
+
+static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, 
+                                         DOM_SID *sid, uint32 start_idx, 
+                                         uint32 *p_num_entries, uint32 max_entries )
+{
+       return get_group_entries( SID_NAME_DOM_GRP, ctx, d_grp, sid, start_idx, 
+               p_num_entries, max_entries );
+}
+
+/*******************************************************************
+ Wrapper for enumerating local groups
+ ******************************************************************/
+
+static NTSTATUS get_group_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, 
+                                        DOM_SID *sid, uint32 start_idx,
+                                         uint32 *p_num_entries, uint32 max_entries)
+{
+       if ( sid_equal(sid, &global_sid_Builtin) ) {    
+               return get_group_entries( SID_NAME_WKN_GRP, ctx, d_grp, 
+                       sid, start_idx, p_num_entries, max_entries );
+       }
+       else if ( sid_equal(sid, get_global_sam_sid()) ) {
+               return get_group_entries( SID_NAME_ALIAS, ctx, d_grp, 
+                       sid, start_idx, p_num_entries, max_entries );   
+       }
+
+       /* can't do anything with this SID */
+               
+       *p_num_entries = 0;
+
        return NT_STATUS_OK;
 }
 
@@ -1473,8 +1384,6 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
 
        DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
        
-       become_root(); /* local_lookup_name can require root privs */
-
        for (i = 0; i < num_rids; i++) {
                fstring name;
                DOM_SID sid;
@@ -1510,8 +1419,6 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
                }
        }
 
-       unbecome_root();
-
        init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
 
        DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
@@ -2223,6 +2130,12 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
                return nt_status;
        }
 
+       if (!acb_info) { 
+               /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if 
+                  this parameter is zero (ie, no user type specified) */
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
        /* find the account: tell the caller if it exists.
          lkclXXXX i have *no* idea if this is a problem or not
          or even if you are supposed to construct a different
@@ -3044,7 +2957,10 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
                        break;
 
                case 24:
-                       SamOEMhash(ctr->info.id24->pass, p->session_key, 516);
+                       if (!p->session_key.length) {
+                               return NT_STATUS_NO_USER_SESSION_KEY;
+                       }
+                       SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
 
                        dump_data(100, (char *)ctr->info.id24->pass, 516);
 
@@ -3062,7 +2978,10 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
                         * info level and W2K SP2 drops down to level 23... JRA.
                         */
 
-                       SamOEMhash(ctr->info.id25->pass, p->session_key, 532);
+                       if (!p->session_key.length) {
+                               return NT_STATUS_NO_USER_SESSION_KEY;
+                       }
+                       SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
 
                        dump_data(100, (char *)ctr->info.id25->pass, 532);
 
@@ -3073,7 +2992,10 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
                        return NT_STATUS_INVALID_INFO_CLASS;
 
                case 23:
-                       SamOEMhash(ctr->info.id23->pass, p->session_key, 516);
+                       if (!p->session_key.length) {
+                               return NT_STATUS_NO_USER_SESSION_KEY;
+                       }
+                       SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
 
                        dump_data(100, (char *)ctr->info.id23->pass, 516);
 
@@ -4330,75 +4252,114 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G
 }
 
 /*********************************************************************
- _samr_remove_user_foreign_domain
+ _samr_remove_sid_foreign_domain
 *********************************************************************/
 
-NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p, 
-                                          SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u, 
-                                          SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u)
+NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, 
+                                          SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, 
+                                          SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
 {
-       DOM_SID                 user_sid, dom_sid;
+       DOM_SID                 delete_sid, alias_sid;
        SAM_ACCOUNT             *sam_pass=NULL;
        uint32                  acc_granted;
+       GROUP_MAP               map;
+       BOOL                    is_user = False;
+       NTSTATUS                result;
+       enum SID_NAME_USE       type = SID_NAME_UNKNOWN;
        
-       sid_copy( &user_sid, &q_u->sid.sid );
+       sid_copy( &delete_sid, &q_u->sid.sid );
        
-       DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n",
-               sid_string_static(&user_sid)));
+       DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
+               sid_string_static(&delete_sid)));
                
        /* Find the policy handle. Open a policy on it. */
        
-       if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
+       if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) 
                return NT_STATUS_INVALID_HANDLE;
+       
+       result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, 
+               "_samr_remove_sid_foreign_domain");
                
-       if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 
-               STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain"))) 
-       {
-               return r_u->status;
-       }
+       if (!NT_STATUS_IS_OK(result)) 
+               return result;
+                       
+       DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", 
+               sid_string_static(&alias_sid)));
                
-       if ( !sid_check_is_in_our_domain(&user_sid) ) {
-               DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n"));
-               return NT_STATUS_NO_SUCH_USER;
+       /* make sure we can handle this */
+       
+       if ( sid_check_is_domain(&alias_sid) )
+               type = SID_NAME_DOM_GRP;
+       else if ( sid_check_is_builtin(&alias_sid) )
+               type = SID_NAME_ALIAS;
+       
+       if ( type == SID_NAME_UNKNOWN ) {
+               DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
+               return NT_STATUS_OK;
        }
 
        /* check if the user exists before trying to delete */
        
        pdb_init_sam(&sam_pass);
        
-       if ( !pdb_getsampwsid(sam_pass, &user_sid) ) {
+       if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
+               is_user = True;
+       } else {
+               /* maybe it is a group */
+               if( !pdb_getgrsid(&map, delete_sid) ) {
+                       DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
+                               sid_string_static(&delete_sid)));
+                       result = NT_STATUS_INVALID_SID;
+                       goto done;
+               }
+       }
        
-               DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n", 
-                       sid_string_static(&user_sid)));
-                       
-               pdb_free_sam(&sam_pass);
+       /* we can only delete a user from a group since we don't have 
+          nested groups anyways.  So in the latter case, just say OK */
+          
+       if ( is_user ) {
+               GROUP_MAP       *mappings = NULL;
+               uint32          num_groups, i;
+               struct group    *grp2;
                
-               return NT_STATUS_NO_SUCH_USER;
-       }
+               if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
+               
+                       /* interate over the groups */
+                       for ( i=0; i<num_groups; i++ ) {
 
-       /*
-        * delete the unix side
-        * 
-        * note: we don't check if the delete really happened
-        * as the script is not necessary present
-        * and maybe the sysadmin doesn't want to delete the unix side
-        */
-        
-       smb_delete_user(pdb_get_username(sam_pass));
+                               grp2 = getgrgid(mappings[i].gid);
 
-       /* and delete the samba side */
-       
-       if ( !pdb_delete_sam_account(sam_pass) ) {
-       
-               DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
-               pdb_free_sam(&sam_pass);
-               
-               return NT_STATUS_CANNOT_DELETE;
+                               if ( !grp2 ) {
+                                       DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
+                                       continue;
+                               }
+                       
+                               if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
+                                       continue;
+                               
+                               smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
+                               
+                               if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
+                                       /* should we fail here ? */
+                                       DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
+                                               pdb_get_username(sam_pass), grp2->gr_name ));
+                                       continue;
+                               }
+                                       
+                               DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
+                                       pdb_get_username(sam_pass), grp2->gr_name ));
+                       }
+                       
+                       SAFE_FREE(mappings);
+               }
        }
        
+       result = NT_STATUS_OK;
+done:
+
        pdb_free_sam(&sam_pass);
 
-       return NT_STATUS_OK;
+       return result;
 }
 
 /*******************************************************************
index 4d1cf9bddcb84cd268a1a96c15b8f380d8b4ae10..40d3a43bef9df020823b7afb1b8bbb473f73e1bd 100644 (file)
@@ -487,10 +487,9 @@ static void init_srv_share_info_1501(pipes_struct *p, SRV_SHARE_INFO_1501 *sh150
 
 static BOOL is_hidden_share(int snum)
 {
-       pstring net_name;
+       const char *net_name = lp_servicename(snum);
 
-       pstrcpy(net_name, lp_servicename(snum));
-       return (net_name[strlen(net_name)] == '$') ? True : False;
+       return (net_name[strlen(net_name) - 1] == '$') ? True : False;
 }
 
 /*******************************************************************
index 632d381503ee3317a58271d2a3be70179b5ab11a..c2395e6faecfeed4a78b171c28a9f69d90860679 100644 (file)
@@ -281,6 +281,7 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA
        fstring user_name;
        uint32 grid;
        uint32 tmp_rid;
+       BOOL ret;
 
        *numgroups= 0;
 
@@ -290,15 +291,21 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA
        DEBUG(10,("get_domain_user_groups: searching domain groups [%s] is a member of\n", user_name));
 
        /* we must wrap this is become/unbecome root for ldap backends */
+       
        become_root();
-
        /* first get the list of the domain groups */
-       if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED))
+       ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED);
+       
+       unbecome_root();
+
+       /* end wrapper for group enumeration */
+
+       
+       if ( !ret )
                return False;
+               
        DEBUG(10,("get_domain_user_groups: there are %d mapped groups\n", num_entries));
 
-       unbecome_root();
-       /* end wrapper for group enumeration */
 
        /* 
         * alloc memory. In the worse case, we alloc memory for nothing.
@@ -375,7 +382,7 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA
  done:
        *pgids=gids;
        *numgroups=cur_gid;
-       safe_free(map);
+       SAFE_FREE(map);
 
        return True;
 }
index d99570ff7c0125acbdf5b3c26f3018f4300a2b59..5caf78e41a6bd74aca8d938ee63a28fd36c4b793 100644 (file)
@@ -245,7 +245,8 @@ static int expect(int master, char *issue, char *expected)
                if (strequal(expected, "."))
                        return True;
 
-               timeout = 2000;
+               /* Initial timeout. */
+               timeout = lp_passwd_chat_timeout() * 1000;
                nread = 0;
                buffer[nread] = 0;
 
@@ -261,8 +262,10 @@ static int expect(int master, char *issue, char *expected)
                                pstrcpy( str, buffer);
                                trim_char( str, ' ', ' ');
 
-                               if ((match = (unix_wild_match(expected, str) == 0)))
-                                       timeout = 200;
+                               if ((match = (unix_wild_match(expected, str) == 0))) {
+                                       /* Now data has started to return, lower timeout. */
+                                       timeout = lp_passwd_chat_timeout() * 100;
+                               }
                        }
                }
 
index f88964123e1cf4b1b0c3f94a14b69f28aac76e8d..fb72a2eafc893ed4eb95388a299b8e98b0e5459b 100644 (file)
@@ -183,6 +183,7 @@ uint32 dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf)
 /*******************************************************************
 chmod a file - but preserve some bits
 ********************************************************************/
+
 int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_STAT *st)
 {
        SMB_STRUCT_STAT st1;
@@ -197,6 +198,8 @@ int file_chmod(connection_struct *conn,char *fname, uint32 dosmode,SMB_STRUCT_ST
                        return(-1);
        }
 
+       get_acl_group_bits(conn, fname, &st->st_mode);
+
        if (S_ISDIR(st->st_mode))
                dosmode |= aDIR;
        else
index 86d982b0227819f6fbafdb2add1f61568a222a91..dd92cc4e4d5cdf98913227b2324291a4534bc9ea 100644 (file)
@@ -445,6 +445,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
                   of the parameter/data bytes */
                outsize = set_message(outbuf,0,0,True);
                show_msg(outbuf);
+               srv_signing_trans_stop();
                if (!send_smb(smbd_server_fd(),outbuf))
                        exit_server("reply_trans: send_smb failed.");
        }
@@ -456,6 +457,13 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
       
                ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
 
+               /*
+                * The sequence number for the trans reply is always
+                * based on the last secondary received.
+                */
+
+               srv_signing_trans_start(SVAL(inbuf,smb_mid));
+
                if ((ret && (CVAL(inbuf, smb_com) != SMBtranss)) || !ret) {
                        if(ret) {
                                DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
index 3ea6ab483be4226faf999b960e3ef11152a06125..c53889a7a47fb0d66c574dffb5a2441d4cebf071 100644 (file)
@@ -1635,6 +1635,7 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
        char *str1 = param+2;
        char *str2 = skip_string(str1,1);
        char *p = skip_string(str2,1);
+       BOOL ret;
 
        GROUP_MAP *group_list;
        int num_entries;
@@ -1653,8 +1654,12 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
                return False;
 
        /* get list of domain groups SID_DOMAIN_GRP=2 */
-       if(!pdb_enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False)) {
-               DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
+       become_root();
+       ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False);
+       unbecome_root();
+       
+       if( !ret ) {
+               DEBUG(3,("api_RNetGroupEnum:failed to get group list"));        
                return False;
        }
 
index ac2d7681e8ed12bedfdbe77aed39ae5be8785a55..16722ae6e9d43299aef650fe9c1695bc763a9bb0 100644 (file)
@@ -139,7 +139,7 @@ extern BOOL case_mangle;    /* If true, all chars in 8.3 should be same case. */
 
 /* -------------------------------------------------------------------- */
 
-static NTSTATUS has_valid_chars(const smb_ucs2_t *s, BOOL allow_wildcards)
+static NTSTATUS has_valid_83_chars(const smb_ucs2_t *s, BOOL allow_wildcards)
 {
        if (!s || !*s)
                return NT_STATUS_INVALID_PARAMETER;
@@ -176,7 +176,7 @@ static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **pr
        if ((p = strrchr_w(*prefix, UCS2_CHAR('.')))) {
                ext_len = strlen_w(p+1);
                if ((ext_len > 0) && (ext_len < 4) && (p != *prefix) &&
-                   (NT_STATUS_IS_OK(has_valid_chars(p+1,allow_wildcards)))) /* check extension */ {
+                   (NT_STATUS_IS_OK(has_valid_83_chars(p+1,allow_wildcards)))) /* check extension */ {
                        *p = 0;
                        *extension = strdup_w(p+1);
                        if (!*extension) {
@@ -200,7 +200,7 @@ static NTSTATUS mangle_get_prefix(const smb_ucs2_t *ucs2_string, smb_ucs2_t **pr
  * ************************************************************************** **
  */
 
-static NTSTATUS is_valid_name(const smb_ucs2_t *fname, BOOL allow_wildcards)
+static NTSTATUS is_valid_name(const smb_ucs2_t *fname, BOOL allow_wildcards, BOOL only_8_3)
 {
        smb_ucs2_t *str, *p;
        NTSTATUS ret = NT_STATUS_OK;
@@ -216,9 +216,11 @@ static NTSTATUS is_valid_name(const smb_ucs2_t *fname, BOOL allow_wildcards)
        if (*fname == UCS2_CHAR('.'))
                return NT_STATUS_UNSUCCESSFUL;
        
-       ret = has_valid_chars(fname, allow_wildcards);
-       if (!NT_STATUS_IS_OK(ret))
-               return ret;
+       if (only_8_3) {
+               ret = has_valid_83_chars(fname, allow_wildcards);
+               if (!NT_STATUS_IS_OK(ret))
+                       return ret;
+       }
 
        str = strdup_w(fname);
        p = strchr_w(str, UCS2_CHAR('.'));
@@ -286,7 +288,7 @@ static NTSTATUS is_8_3_w(const smb_ucs2_t *fname, BOOL allow_wildcards)
        if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0)
                return NT_STATUS_OK;
 
-       if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards)))
+       if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards, True)))
                goto done;
 
        if (!NT_STATUS_IS_OK(mangle_get_prefix(fname, &pref, &ext, allow_wildcards)))
@@ -737,7 +739,7 @@ static void name_map(char *OutName, BOOL need83, BOOL cache83)
                return;
        }
 
-       if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False)))
+       if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False, False)))
                need83 = True;
 
        /* check if it's already in 8.3 format */
index 7e7bc8c68cf59cfd22725e7d7146effeea17f02b..8dfa84d0548c279050f6c47b62a4e7d041a932ae 100644 (file)
@@ -325,7 +325,7 @@ static BOOL is_8_3(const char *name, BOOL check_case, BOOL allow_wildcards)
                prefix_len = PTR_DIFF(dot_p, name);
                suffix_len = len - (prefix_len+1);
 
-               if (prefix_len > 8 || suffix_len > 3) {
+               if (prefix_len > 8 || suffix_len > 3 || suffix_len == 0) {
                        return False;
                }
 
index 80297daaef3664fb58798c0ed95de1f5fc60b7b9..767df0b725195878013f0cf7196c3a43155c881a 100644 (file)
@@ -2488,6 +2488,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
                /* We need to send an interim response then receive the rest
                        of the parameter/data bytes */
                outsize = set_message(outbuf,0,0,True);
+               srv_signing_trans_stop();
                if (!send_smb(smbd_server_fd(),outbuf))
                        exit_server("reply_nttrans: send_smb failed.");
 
@@ -2498,6 +2499,13 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
 
                        ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
 
+                       /*
+                        * The sequence number for the trans reply is always
+                        * based on the last secondary received.
+                        */
+
+                       srv_signing_trans_start(SVAL(inbuf,smb_mid));
+
                        if((ret && (CVAL(inbuf, smb_com) != SMBnttranss)) || !ret) {
                                outsize = set_message(outbuf,0,0,True);
                                if(ret) {
index ef7ace862ae3455bd571f3675cd40b25203e5459..3807c18e784a4e9cec6407fe2cb4303fe961b6e0 100644 (file)
@@ -30,7 +30,7 @@ extern BOOL global_client_failed_oplock_break;
  fd support routines - attempt to do a dos_open.
 ****************************************************************************/
 
-static int fd_open(struct connection_struct *conn, char *fname, 
+static int fd_open(struct connection_struct *conn, const char *fname, 
                   int flags, mode_t mode)
 {
        int fd;
@@ -41,13 +41,6 @@ static int fd_open(struct connection_struct *conn, char *fname,
 
        fd = SMB_VFS_OPEN(conn,fname,flags,mode);
 
-       /* Fix for files ending in '.' */
-       if((fd == -1) && (errno == ENOENT) &&
-          (strchr_m(fname,'.')==NULL)) {
-               pstrcat(fname,".");
-               fd = SMB_VFS_OPEN(conn,fname,flags,mode);
-       }
-
        DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname,
                flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" ));
 
@@ -70,7 +63,7 @@ int fd_close(struct connection_struct *conn, files_struct *fsp)
  Check a filename for the pipe string.
 ****************************************************************************/
 
-static void check_for_pipe(char *fname)
+static void check_for_pipe(const char *fname)
 {
        /* special case of pipe opens */
        char s[10];
@@ -89,10 +82,9 @@ static void check_for_pipe(char *fname)
 ****************************************************************************/
 
 static BOOL open_file(files_struct *fsp,connection_struct *conn,
-                     const char *fname1,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
+                     const char *fname,SMB_STRUCT_STAT *psbuf,int flags,mode_t mode, uint32 desired_access)
 {
        extern struct current_user current_user;
-       pstring fname;
        int accmode = (flags & O_ACCMODE);
        int local_flags = flags;
 
@@ -100,8 +92,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
        fsp->oplock_type = NO_OPLOCK;
        errno = EPERM;
 
-       pstrcpy(fname,fname1);
-
        /* Check permissions */
 
        /*
index 958ed663e672008ffa2bed169c4c46bbe15f4aa0..494d9ecd4396582705a6076e73131f6912dcca5f 100644 (file)
@@ -77,6 +77,8 @@ void invalidate_vuid(uint16 vuid)
 
        free_server_info(&vuser->server_info);
 
+       data_blob_free(&vuser->session_key);
+
        DLIST_REMOVE(validated_users, vuser);
 
        /* clear the vuid from the 'cache' on each connection, and
@@ -109,25 +111,36 @@ void invalidate_all_vuids(void)
  *  @param server_info The token returned from the authentication process. 
  *   (now 'owned' by register_vuid)
  *
+ *  @param session_key The User session key for the login session (now also 'owned' by register_vuid)
+ *
+ *  @param respose_blob The NT challenge-response, if available.  (May be freed after this call)
+ *
+ *  @param smb_name The untranslated name of the user
+ *
  *  @return Newly allocated vuid, biased by an offset. (This allows us to
  *   tell random client vuid's (normally zero) from valid vuids.)
  *
  */
 
-int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob, const char *smb_name)
+int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DATA_BLOB response_blob, const char *smb_name)
 {
        user_struct *vuser = NULL;
 
        /* Ensure no vuid gets registered in share level security. */
-       if(lp_security() == SEC_SHARE)
+       if(lp_security() == SEC_SHARE) {
+               data_blob_free(&session_key);
                return UID_FIELD_INVALID;
+       }
 
        /* Limit allowed vuids to 16bits - VUID_OFFSET. */
-       if (num_validated_vuids >= 0xFFFF-VUID_OFFSET)
+       if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) {
+               data_blob_free(&session_key);
                return UID_FIELD_INVALID;
+       }
 
        if((vuser = (user_struct *)malloc( sizeof(user_struct) )) == NULL) {
                DEBUG(0,("Failed to malloc users struct!\n"));
+               data_blob_free(&session_key);
                return UID_FIELD_INVALID;
        }
 
@@ -156,6 +169,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob
        if (vuser->n_groups) {
                if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) {
                        DEBUG(0,("register_vuid: failed to memdup vuser->groups\n"));
+                       data_blob_free(&session_key);
                        free(vuser);
                        free_server_info(&server_info);
                        return UID_FIELD_INVALID;
@@ -197,7 +211,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob
                }
        }
 
-       memcpy(vuser->session_key, server_info->session_key, sizeof(vuser->session_key));
+       vuser->session_key = session_key;
 
        DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", 
                  (unsigned int)vuser->uid, 
@@ -211,6 +225,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob
        } else {
                DEBUG(1, ("server_info does not contain a user_token - cannot continue\n"));
                free_server_info(&server_info);
+               data_blob_free(&session_key);
                SAFE_FREE(vuser->homedir);
                SAFE_FREE(vuser->unix_homedir);
                SAFE_FREE(vuser->logon_script);
index aa1d25c483afb581bae6c13ea68fdc25b3af6d54..8033c694f5db8ab7bba72b7edc528a5b3e795ae5 100644 (file)
@@ -3177,6 +3177,48 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
        return True;
 }
 
+/****************************************************************************
+ Get the actual group bits stored on a file with an ACL. Has no effect if
+ the file has no ACL. Needed in dosmode code where the stat() will return
+ the mask bits, not the real group bits, for a file with an ACL.
+****************************************************************************/
+
+int get_acl_group_bits( connection_struct *conn, char *fname, mode_t *mode )
+{
+       int entry_id = SMB_ACL_FIRST_ENTRY;
+       SMB_ACL_ENTRY_T entry;
+       SMB_ACL_T posix_acl;
+
+       posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
+       if (posix_acl == (SMB_ACL_T)NULL)
+               return -1;
+
+       while (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1) {
+               SMB_ACL_TAG_T tagtype;
+               SMB_ACL_PERMSET_T permset;
+
+               /* get_next... */
+               if (entry_id == SMB_ACL_FIRST_ENTRY)
+                       entry_id = SMB_ACL_NEXT_ENTRY;
+
+               if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) ==-1)
+                       return -1;
+
+               if (tagtype == SMB_ACL_GROUP_OBJ) {
+                       if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
+                               return -1;
+                       } else {
+                               *mode &= ~(S_IRGRP|S_IWGRP|S_IXGRP);
+                               *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? S_IRGRP : 0);
+                               *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? S_IWGRP : 0);
+                               *mode |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? S_IXGRP : 0);
+                               return 0;;
+                       }
+               }
+       }
+       return -1;
+}
+
 /****************************************************************************
  Do a chmod by setting the ACL USER_OBJ, GROUP_OBJ and OTHER bits in an ACL
  and set the mask to rwx. Needed to preserve complex ACLs set by NT.
index 8a90a15d29741d9f810e8f5eb3899e93b3a97b9a..5206dc70f80b754606c57476f65f61f31dc27777 100644 (file)
@@ -924,11 +924,17 @@ const char *smb_fn_name(int type)
        return(smb_messages[type].name);
 }
 
-
 /****************************************************************************
- Helper function for contruct_reply.
+ Helper functions for contruct_reply.
 ****************************************************************************/
 
+static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_EXTENDED_SECURITY|FLAGS2_32_BIT_ERROR_CODES;
+
+void remove_from_common_flags2(uint32 v)
+{
+       common_flags2 &= ~v;
+}
+
 void construct_reply_common(char *inbuf,char *outbuf)
 {
        memset(outbuf,'\0',smb_size);
@@ -941,9 +947,8 @@ void construct_reply_common(char *inbuf,char *outbuf)
        SCVAL(outbuf,smb_reh,0);
        SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); 
        SSVAL(outbuf,smb_flg2,
-             (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
-             FLAGS2_LONG_PATH_COMPONENTS |
-             FLAGS2_32_BIT_ERROR_CODES | FLAGS2_EXTENDED_SECURITY);
+               (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
+               common_flags2);
 
        SSVAL(outbuf,smb_err,SMB_SUCCESS);
        SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
index 91c952aa902bb684b6c9ae08fb2d74db09321eb3..46f688a2194060489566a8bbe207a9042be571fe 100644 (file)
@@ -94,23 +94,30 @@ typedef struct _LINUX_SMB_DISK_QUOTA {
 
 static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
 {
-       int ret = -1;
+       int ret = -1;
 #ifdef HAVE_LINUX_XQM_H
-       struct fs_disk_quota D;
-       ZERO_STRUCT(D);
-
-       if ((ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
-               return ret;
-
-       dp->bsize = (SMB_BIG_UINT)512;
-       dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
-       dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
-       dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
-       dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
-       dp->curinodes = (SMB_BIG_UINT)D.d_icount;
-       dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
+       struct fs_disk_quota D;
+
+       ZERO_STRUCT(D);
+
+       ret = quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
+
+       /* As XFS has group quotas, if getting the user quota fails, try getting the group instead. */
+       if (ret) {
+               ret = quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D);
+               if (ret)
+                       return ret;
+       }
+
+       dp->bsize = (SMB_BIG_UINT)512;
+       dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
+       dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
+       dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
+       dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
+       dp->curinodes = (SMB_BIG_UINT)D.d_icount;
+       dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
 #endif
-       return ret;
+       return ret;
 }
 
 /****************************************************************************
@@ -119,7 +126,7 @@ static int get_smb_linux_xfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU
 
 static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QUOTA *dp)
 {
-       int ret;
+       int ret = 0;
 #ifdef LINUX_QUOTAS_1
        struct dqblk D;
        ZERO_STRUCT(D);
@@ -133,8 +140,14 @@ static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU
        dp->bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
 #endif
 
-       if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D)))
-               return -1;
+       ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), path, euser_id, (caddr_t)&D);
+
+       /* Linux can have group quotas, if getting the user quota fails, try getting the group instead. */
+       if (ret) {
+               ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), path, getegid(), (caddr_t)&D);
+               if (ret)
+                       return ret;
+       }
 
        dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
        dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
@@ -148,7 +161,7 @@ static int get_smb_linux_vfs_quota(char *path, uid_t euser_id, LINUX_SMB_DISK_QU
        dp->curblocks = ((SMB_BIG_UINT)D.dqb_curspace)/ dp->bsize;
 #endif
 
-       return 0;
+       return ret;
 }
 
 /****************************************************************************
index 314ffbb4a9b9a58819dfebb67e38afb8d270a78b..ec01a330ee255d8f568dfa84a7e6d8297b218ae9 100644 (file)
@@ -149,7 +149,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
        DATA_BLOB auth_data;
        DATA_BLOB ap_rep, ap_rep_wrapped, response;
        auth_serversupplied_info *server_info = NULL;
-       uint8 session_key[16];
+       DATA_BLOB session_key;
        uint8 tok_id[2];
        BOOL foreign = False;
        DATA_BLOB nullblob = data_blob(NULL, 0);
@@ -164,7 +164,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
                return ERROR_NT(NT_STATUS_LOGON_FAILURE);
        }
 
-       ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, session_key);
+       ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, &session_key);
 
        data_blob_free(&ticket);
 
@@ -223,11 +223,8 @@ static int reply_spnego_kerberos(connection_struct *conn,
                return ERROR_NT(ret);
        }
 
-       /* Copy out the session key from the AP_REQ. */
-       memcpy(server_info->session_key, session_key, sizeof(session_key));
-
        /* register_vuid keeps the server info */
-       sess_vuid = register_vuid(server_info, nullblob, user);
+       sess_vuid = register_vuid(server_info, session_key, nullblob, user);
 
        free(user);
 
@@ -297,9 +294,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out
        if (NT_STATUS_IS_OK(nt_status)) {
                int sess_vuid;
                DATA_BLOB nullblob = data_blob(NULL, 0);
+               DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length);
 
                /* register_vuid keeps the server info */
-               sess_vuid = register_vuid(server_info, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
+               sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
                (*auth_ntlmssp_state)->server_info = NULL;
 
                if (sess_vuid == -1) {
@@ -474,6 +472,11 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
 
        if (global_client_caps == 0) {
                global_client_caps = IVAL(inbuf,smb_vwv10);
+
+               if (!(global_client_caps & CAP_STATUS32)) {
+                       remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
+               }
+
        }
                
        p = (uint8 *)smb_buf(inbuf);
@@ -566,6 +569,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
        NTSTATUS nt_status;
 
        BOOL doencrypt = global_encrypted_passwords_negotiated;
+
+       DATA_BLOB session_key;
        
        START_PROFILE(SMBsesssetupX);
 
@@ -615,17 +620,22 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                enum remote_arch_types ra_type = get_remote_arch();
                char *p = smb_buf(inbuf);    
 
-               if(global_client_caps == 0)
+               if(global_client_caps == 0) {
                        global_client_caps = IVAL(inbuf,smb_vwv11);
                
-               /* client_caps is used as final determination if client is NT or Win95. 
-                  This is needed to return the correct error codes in some
-                  circumstances.
-               */
+                       if (!(global_client_caps & CAP_STATUS32)) {
+                               remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
+                       }
+
+                       /* client_caps is used as final determination if client is NT or Win95. 
+                          This is needed to return the correct error codes in some
+                          circumstances.
+                       */
                
-               if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) {
-                       if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
-                               set_remote_arch( RA_WIN95);
+                       if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) {
+                               if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
+                                       set_remote_arch( RA_WIN95);
+                               }
                        }
                }
 
@@ -686,7 +696,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                        ra_lanman_string( native_lanman );
 
        }
-       
+
        if (SVAL(inbuf,smb_vwv4) == 0) {
                setup_new_vc_session();
        }
@@ -766,18 +776,28 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
 
        free_user_info(&user_info);
        
-       data_blob_free(&lm_resp);
-       data_blob_clear_free(&plaintext_password);
-       
        if (!NT_STATUS_IS_OK(nt_status)) {
                nt_status = do_map_to_guest(nt_status, &server_info, user, domain);
        }
        
        if (!NT_STATUS_IS_OK(nt_status)) {
                data_blob_free(&nt_resp);
+               data_blob_free(&lm_resp);
+               data_blob_clear_free(&plaintext_password);
                return ERROR_NT(nt_status_squash(nt_status));
        }
 
+       if (server_info->nt_session_key.data) {
+               session_key = data_blob(server_info->nt_session_key.data, server_info->nt_session_key.length);
+       } else if (server_info->lm_session_key.length >= 8 && lm_resp.length == 24) {
+               session_key = data_blob(NULL, 16);
+               SMBsesskeygen_lmv1(server_info->lm_session_key.data, lm_resp.data, 
+                                  session_key.data);
+       }
+
+       data_blob_free(&lm_resp);
+       data_blob_clear_free(&plaintext_password);
+       
        /* it's ok - setup a reply */
        set_message(outbuf,3,0,True);
        if (Protocol >= PROTOCOL_NT1) {
@@ -795,7 +815,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
           to a uid can get through without a password, on the same VC */
 
        /* register_vuid keeps the server info */
-       sess_vuid = register_vuid(server_info, nt_resp, sub_user);
+       sess_vuid = register_vuid(server_info, session_key, nt_resp, sub_user);
        data_blob_free(&nt_resp);
 
        if (sess_vuid == -1) {
index 56d1aae3a2a562fac4804f44f7c2cd2f7e8d6c20..525b0153791f2705f8f4c1af08876026ab4e112b 100644 (file)
@@ -3523,6 +3523,7 @@ int reply_trans2(connection_struct *conn,
                /* We need to send an interim response then receive the rest
                   of the parameter/data bytes */
                outsize = set_message(outbuf,0,0,True);
+               srv_signing_trans_stop();
                if (!send_smb(smbd_server_fd(),outbuf))
                        exit_server("reply_trans2: send_smb failed.");
 
@@ -3536,6 +3537,13 @@ int reply_trans2(connection_struct *conn,
 
                        ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
                        
+                       /*
+                        * The sequence number for the trans reply is always
+                        * based on the last secondary received.
+                        */
+
+                       srv_signing_trans_start(SVAL(inbuf,smb_mid));
+
                        if ((ret && 
                             (CVAL(inbuf, smb_com) != SMBtranss2)) || !ret) {
                                outsize = set_message(outbuf,0,0,True);
index a76a7a6abdcd22413a4e20755bfed64da4d3f0ea..378a0a1e53cce96e1b8763902c626fa615198d2c 100644 (file)
@@ -237,14 +237,104 @@ ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp,
        return result;
 }
 
+/*********************************************************
+ For rename across filesystems Patch from Warren Birnbaum
+ <warrenb@hpcvscdp.cv.hp.com>
+**********************************************************/
+
+static int copy_reg(const char *source, const char *dest)
+{
+       SMB_STRUCT_STAT source_stats;
+       int saved_errno;
+       int ifd = -1;
+       int ofd = -1;
+
+       if (sys_lstat (source, &source_stats) == -1)
+               return -1;
+
+       if (!S_ISREG (source_stats.st_mode))
+               return -1;
+
+       if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
+               return -1;
+
+       if (unlink (dest) && errno != ENOENT)
+               return -1;
+
+#ifdef O_NOFOLLOW
+       if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
+#else
+       if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
+#endif
+               goto err;
+
+       if (transfer_file(ifd, ofd, (size_t)-1) == -1)
+               goto err;
+
+       /*
+        * Try to preserve ownership.  For non-root it might fail, but that's ok.
+        * But root probably wants to know, e.g. if NFS disallows it.
+        */
+
+       if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
+               goto err;
+
+       /*
+        * fchown turns off set[ug]id bits for non-root,
+        * so do the chmod last.
+        */
+
+#if defined(HAVE_FCHMOD)
+       if (fchmod (ofd, source_stats.st_mode & 07777))
+#else
+       if (chmod (dest, source_stats.st_mode & 07777))
+#endif
+               goto err;
+
+       if (close (ifd) == -1)
+               goto err;
+
+       if (close (ofd) == -1)
+               return -1;
+
+       /* Try to copy the old file's modtime and access time.  */
+       {
+               struct utimbuf tv;
+
+               tv.actime = source_stats.st_atime;
+               tv.modtime = source_stats.st_mtime;
+               utime(dest, &tv);
+       }
+
+       if (unlink (source) == -1)
+               return -1;
+
+       return 0;
+
+  err:
+
+       saved_errno = errno;
+       if (ifd != -1)
+               close(ifd);
+       if (ofd != -1)
+               close(ofd);
+       errno = saved_errno;
+       return -1;
+}
+
 int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *old, const char *new)
 {
-    int result;
+       int result;
 
-    START_PROFILE(syscall_rename);
-    result = rename(old, new);
-    END_PROFILE(syscall_rename);
-    return result;
+       START_PROFILE(syscall_rename);
+       result = rename(old, new);
+       if (errno == EXDEV) {
+               /* Rename across filesystems needed. */
+               result = copy_reg(old, new);
+       }
+
+       END_PROFILE(syscall_rename);
+       return result;
 }
 
 int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
index 6c51db3cf3020f93104d836a0f6a74d501338d5a..2e79584d23f7bfa297dce6109d8251674157798c 100644 (file)
@@ -52,7 +52,7 @@ double nbio_total(void)
        return total;
 }
 
-void nb_alarm(void)
+void nb_alarm(int ignore)
 {
        int i;
        int lines=0, num_clients=0;
@@ -79,6 +79,7 @@ void nbio_shmem(int n)
        }
 }
 
+#if 0
 static int ne_find_handle(int handle)
 {
        int i;
@@ -88,6 +89,7 @@ static int ne_find_handle(int handle)
        }
        return -1;
 }
+#endif
 
 static int find_handle(int handle)
 {
index 75fa607caefb83e0433ae062aff1f1099f338d27..4d2b1eb439b99ea7017d3af2ff9b9860f00f5137 100644 (file)
@@ -616,6 +616,7 @@ static struct functable net_func[] = {
        {"GETDOMAINSID", net_getdomainsid},
        {"MAXRID", net_maxrid},
        {"IDMAP", net_idmap},
+       {"STATUS", net_status},
 #ifdef WITH_FAKE_KASERVER
        {"AFSKEY", net_afskey},
 #endif
index cad93608dc42396e13e7607433029f90cd701498..9404ae4b247b5e56bf44e26cf4c8bbf433273332 100644 (file)
@@ -209,7 +209,7 @@ static int net_ads_workgroup(int argc, const char **argv)
 {
        ADS_STRUCT *ads;
        TALLOC_CTX *ctx;
-       char *workgroup;
+       const char *workgroup;
 
        if (!(ads = ads_startup())) return -1;
 
@@ -656,7 +656,7 @@ int net_ads_join(int argc, const char **argv)
        char *ou_str;
        uint32 sec_channel_type = SEC_CHAN_WKSTA;
        uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT;
-       char *short_domain_name = NULL;
+       const char *short_domain_name = NULL;
        TALLOC_CTX *ctx = NULL;
 
        if (argc > 0) org_unit = argv[0];
index c688beef72c8ef33bd9f6fa2ec765db434a5dd71..38261be90a7ef6de6cac3c3f5cd3cf89ba6d1a0f 100644 (file)
@@ -88,11 +88,14 @@ int net_help_group(int argc, const char **argv)
 {
        d_printf("net [<method>] group [misc. options] [targets]"\
                 "\n\tList user groups\n\n");
+       d_printf("net rpc group LIST [global|local|builtin]* [misc. options]"\
+                "\n\tList specific user groups\n\n");
        d_printf("net [<method>] group DELETE <name> "\
                 "[misc. options] [targets]"\
                 "\n\tDelete specified group\n");
        d_printf("\nnet [<method>] group ADD <name> [-C comment] [-c container]"\
                 " [misc. options] [targets]\n\tCreate specified group\n");
+       d_printf("\nnet rpc group MEMBERS <name>\n\tList Group Members\n\n");
        net_common_methods_usage(argc, argv);
        net_common_flags_usage(argc, argv);
        d_printf("\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
@@ -146,6 +149,15 @@ int net_help_file(int argc, const char **argv)
        return -1;
 }
 
+int net_help_status(int argc, const char **argv)
+{
+       d_printf("  net status sessions [parseable] "
+                "Show list of open sessions\n");
+       d_printf("  net status shares [parseable]   "
+                "Show list of open shares\n");
+       return -1;
+}
+
 static int net_usage(int argc, const char **argv)
 {
        d_printf("  net time\t\tto view or set time information\n"\
@@ -159,6 +171,7 @@ static int net_usage(int argc, const char **argv)
                 "  net setlocalsid SID\tto set the local domain SID\n"\
                 "  net changesecretpw\tto change the machine password in the local secrets database only\n"\
                 "                    \tthis requires the -f flag as a safety barrier\n"\
+                "  net status\t\tShow server status\n"\
                 "\n"\
                 "  net ads <command>\tto run ADS commands\n"\
                 "  net rap <command>\tto run RAP (pre-RPC) commands\n"\
index 298e8ff6690772bf9431bfce80da1c93e791d624..04a03307740b2959db25f5e215804342fa05b5e3 100644 (file)
@@ -916,6 +916,26 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
        uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
        struct acct_info *groups;
        DOM_SID global_sid_Builtin;
+       BOOL global = False;
+       BOOL local = False;
+       BOOL builtin = False;
+
+       if (argc == 0) {
+               global = True;
+               local = True;
+               builtin = True;
+       }
+
+       for (i=0; i<argc; i++) {
+               if (strequal(argv[i], "global"))
+                       global = True;
+
+               if (strequal(argv[i], "local"))
+                       local = True;
+
+               if (strequal(argv[i], "builtin"))
+                       builtin = True;
+       }
 
        string_to_sid(&global_sid_Builtin, "S-1-5-32");
 
@@ -949,6 +969,8 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
                ZERO_STRUCT(info3);
                ctr.sam.info3 = &info3;
 
+               if (!global) break;
+
                get_query_dispinfo_params(
                        loop_count, &max_entries, &max_size);
 
@@ -967,12 +989,14 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
                                printf("%-21.21s %-50.50s\n",
                                       group, desc);
                        else
-                               printf("%-21.21s\n", group);
+                               printf("%s\n", group);
                }
        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
        /* query domain aliases */
        start_idx = 0;
        do {
+               if (!local) break;
+
                result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
                                                  &start_idx, max_entries,
                                                  &groups, &num_entries);
@@ -1006,7 +1030,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
                                       groups[i].acct_name,
                                       description);
                        } else {
-                               printf("%-21.21s\n", groups[i].acct_name);
+                               printf("%s\n", groups[i].acct_name);
                        }
                }
        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
@@ -1022,6 +1046,8 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
        /* query builtin aliases */
        start_idx = 0;
        do {
+               if (!builtin) break;
+
                result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
                                                  &start_idx, max_entries,
                                                  &groups, &num_entries);
@@ -1055,7 +1081,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
                                       groups[i].acct_name,
                                       description);
                        } else {
-                               printf("%-21.21s\n", groups[i].acct_name);
+                               printf("%s\n", groups[i].acct_name);
                        }
                }
        } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
@@ -1064,6 +1090,111 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
        return result;
 }
 
+static int rpc_group_list(int argc, const char **argv)
+{
+       return run_rpc_command(NULL, PI_SAMR, 0,
+                              rpc_group_list_internals,
+                              argc, argv);
+}
+static NTSTATUS 
+rpc_group_members_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+                           TALLOC_CTX *mem_ctx, int argc, const char **argv)
+{
+       NTSTATUS result;
+       POLICY_HND connect_pol, domain_pol, group_pol;
+       uint32 num_rids, *rids, *rid_types;
+       uint32 num_members, *group_rids, *group_attrs;
+       uint32 num_names;
+       char **names;
+       uint32 *name_types;
+       int i;
+
+       /* Get sam policy handle */
+       
+       result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS, 
+                                 &connect_pol);
+       if (!NT_STATUS_IS_OK(result)) {
+               goto done;
+       }
+       
+       /* Get domain policy handle */
+       
+       result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+                                     MAXIMUM_ALLOWED_ACCESS,
+                                     domain_sid, &domain_pol);
+       if (!NT_STATUS_IS_OK(result)) {
+               goto done;
+       }
+
+       result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol, 1000,
+                                      1, argv, &num_rids, &rids, &rid_types);
+
+       if (!NT_STATUS_IS_OK(result)) {
+               goto done;
+       }
+
+       if (num_rids != 1) {
+               d_printf("Could not find group %s\n", argv[0]);
+               goto done;
+       }
+
+       if (rid_types[0] != SID_NAME_DOM_GRP) {
+               d_printf("%s is not a domain group\n", argv[0]);
+               goto done;
+       }
+
+       result = cli_samr_open_group(cli, mem_ctx, &domain_pol,
+                                    MAXIMUM_ALLOWED_ACCESS,
+                                    rids[0], &group_pol);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       result = cli_samr_query_groupmem(cli, mem_ctx, &group_pol,
+                                        &num_members, &group_rids,
+                                        &group_attrs);
+
+       if (!NT_STATUS_IS_OK(result))
+               goto done;
+
+       do {
+               int this_time = 512;
+
+               if (num_members < this_time)
+                       this_time = num_members;
+
+               result = cli_samr_lookup_rids(cli, mem_ctx, &domain_pol, 1000,
+                                             this_time, group_rids,
+                                             &num_names, &names, &name_types);
+
+               if (!NT_STATUS_IS_OK(result))
+                       goto done;
+
+               for (i = 0; i < this_time; i++) {
+                       printf("%s\n", names[i]);
+               }
+
+               num_members -= this_time;
+               group_rids += 512;
+
+       } while (num_members > 0);
+
+ done:
+       return result;
+}
+
+static int rpc_group_members(int argc, const char **argv)
+{
+       if (argc != 1) {
+               return rpc_group_usage(argc, argv);
+       }
+
+       return run_rpc_command(NULL, PI_SAMR, 0,
+                              rpc_group_members_internals,
+                              argc, argv);
+}
+
 /** 
  * 'net rpc group' entrypoint.
  * @param argc  Standard main() style argc
@@ -1078,6 +1209,8 @@ int net_rpc_group(int argc, const char **argv)
                {"add", rpc_group_add},
                {"delete", rpc_group_delete},
 #endif
+               {"list", rpc_group_list},
+               {"members", rpc_group_members},
                {NULL, NULL}
        };
        
@@ -1727,7 +1860,7 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli
                ctr.info.id24 = &p24;
 
                result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24,
-                                              cli->user_session_key, &ctr);
+                                              &cli->user_session_key, &ctr);
 
                if (!NT_STATUS_IS_OK(result)) {
                        DEBUG(0,("Could not set trust account password: %s\n",
index 22ed49c74f6b9bd796b229d761824acfe92db123..96943468ad2e05746a2344ff8e233d63671dd106 100644 (file)
@@ -70,7 +70,7 @@ int net_rpc_join_ok(const char *domain)
        /* ensure that schannel uses the right domain */
        fstrcpy(cli->domain, domain);
        if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, channel, stored_md4_trust_password))) {
-               DEBUG(0,("Error in domain join verfication\n"));
+               DEBUG(0,("Error in domain join verfication (fresh connection)\n"));
                goto done;
        }
        
@@ -282,7 +282,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
        ctr.info.id24 = &p24;
 
        CHECK_RPC_ERR(cli_samr_set_userinfo(cli, mem_ctx, &user_pol, 24, 
-                                           cli->user_session_key, &ctr),
+                                           &cli->user_session_key, &ctr),
                      "error setting trust account password");
 
        /* Why do we have to try to (re-)set the ACB to be the same as what
@@ -304,7 +304,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
           as a normal user with "Add workstation to domain" privilege. */
 
        result = cli_samr_set_userinfo2(cli, mem_ctx, &user_pol, 0x10, 
-                                       cli->user_session_key, &ctr);
+                                       &cli->user_session_key, &ctr);
 
        /* Now check the whole process from top-to-bottom */
        cli_samr_close(cli, mem_ctx, &user_pol);
@@ -322,7 +322,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
                                           md4_trust_password);
 
        if (!NT_STATUS_IS_OK(result)) {
-               DEBUG(0, ("Error domain join verification: %s\n\n",
+               DEBUG(0, ("Error domain join verification (reused connection): %s\n\n",
                          nt_errstr(result)));
 
                if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) &&
index 13b9550347db7ce97269d1ae02f18e555a8a3fe0..4461f163dd5d01765e1a1a63e50f3801ea5da569 100644 (file)
 
 #define SQUID_BUFFER_SIZE 2010
 
-enum squid_mode {
+enum stdio_helper_mode {
        SQUID_2_4_BASIC,
        SQUID_2_5_BASIC,
        SQUID_2_5_NTLMSSP,
        GSS_SPNEGO,
-       GSS_SPNEGO_CLIENT
+       GSS_SPNEGO_CLIENT,
+       NUM_HELPER_MODES
+};
+
+typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, 
+                                    char *buf, int length);
+
+static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode, 
+                                       char *buf, int length);
+
+static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, 
+                                         char *buf, int length);
+
+static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode, 
+                                      char *buf, int length);
+
+static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helper_mode, 
+                                             char *buf, int length);
+
+static const struct {
+       enum stdio_helper_mode mode;
+       const char *name;
+       stdio_helper_function fn;
+} stdio_helper_protocols[] = {
+       { SQUID_2_4_BASIC, "squid-2.4-basic", manage_squid_basic_request},
+       { SQUID_2_5_BASIC, "squid-2.5-basic", manage_squid_basic_request},
+       { SQUID_2_5_NTLMSSP, "squid-2.5-ntlmssp", manage_squid_ntlmssp_request},
+       { GSS_SPNEGO, "gss-spnego", manage_gss_spnego_request},
+       { GSS_SPNEGO_CLIENT, "gss-spnego-client", manage_gss_spnego_client_request},
+       { NUM_HELPER_MODES, NULL, NULL}
 };
-       
 
 extern int winbindd_fd;
 
@@ -96,7 +124,7 @@ static const char *get_winbind_domain(void)
 
        if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) !=
            NSS_STATUS_SUCCESS) {
-               d_printf("could not obtain winbind domain name!\n");
+               DEBUG(0, ("could not obtain winbind domain name!\n"));
                return NULL;
        }
 
@@ -122,7 +150,7 @@ static const char *get_winbind_netbios_name(void)
 
        if (winbindd_request(WINBINDD_NETBIOS_NAME, NULL, &response) !=
            NSS_STATUS_SUCCESS) {
-               d_printf("could not obtain winbind netbios name!\n");
+               DEBUG(0, ("could not obtain winbind netbios name!\n"));
                return NULL;
        }
 
@@ -264,20 +292,42 @@ static NTSTATUS contact_winbind_auth_crap(const char *username,
        return nt_status;
 }
                                   
-static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state) 
+static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key
 {
-       return contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain,
-                                        ntlmssp_state->workstation,
-                                        &ntlmssp_state->chal,
-                                        &ntlmssp_state->lm_resp,
-                                        &ntlmssp_state->nt_resp, 
-                                        0,
-                                        NULL, 
-                                        NULL, 
-                                        NULL);
+       static const char zeros[16];
+       NTSTATUS nt_status;
+       char *error_string;
+       uint8 lm_key[8]; 
+       uint8 nt_key[16]; 
+       
+       nt_status = contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain,
+                                             ntlmssp_state->workstation,
+                                             &ntlmssp_state->chal,
+                                             &ntlmssp_state->lm_resp,
+                                             &ntlmssp_state->nt_resp, 
+                                             WBFLAG_PAM_LMKEY | WBFLAG_PAM_NTKEY,
+                                             lm_key, nt_key, 
+                                             &error_string);
+
+       if (NT_STATUS_IS_OK(nt_status)) {
+               if (memcmp(lm_key, zeros, 8) != 0) {
+                       *lm_session_key = data_blob(NULL, 16);
+                       memcpy(lm_session_key->data, lm_key, 8);
+                       memset(lm_session_key->data+8, '\0', 8);
+               }
+               
+               if (memcmp(nt_key, zeros, 16) != 0) {
+                       *nt_session_key = data_blob(nt_key, 16);
+               }
+       } else {
+               DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3, 
+                     ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", 
+                      ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation, error_string ? error_string : "unknown error (NULL)"));
+       }
+       return nt_status;
 }
 
-static void manage_squid_ntlmssp_request(enum squid_mode squid_mode, 
+static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode, 
                                         char *buf, int length) 
 {
        static NTLMSSP_STATE *ntlmssp_state = NULL;
@@ -295,7 +345,7 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode,
        } else if (strcmp(buf, "YR") == 0) {
                request = data_blob(NULL, 0);
                if (ntlmssp_state)
-                       ntlmssp_server_end(&ntlmssp_state);
+                       ntlmssp_end(&ntlmssp_state);
        } else {
                DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
                x_fprintf(x_stdout, "BH\n");
@@ -312,7 +362,7 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode,
        DEBUG(10, ("got NTLMSSP packet:\n"));
        dump_data(10, (const char *)request.data, request.length);
 
-       nt_status = ntlmssp_server_update(ntlmssp_state, request, &reply);
+       nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
        
        if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                char *reply_base64 = base64_encode_data_blob(reply);
@@ -320,6 +370,9 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode,
                SAFE_FREE(reply_base64);
                data_blob_free(&reply);
                DEBUG(10, ("NTLMSSP challenge\n"));
+       } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
+               x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
+               DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
        } else if (!NT_STATUS_IS_OK(nt_status)) {
                x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status));
                DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status)));
@@ -331,7 +384,7 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode,
        data_blob_free(&request);
 }
 
-static void manage_squid_basic_request(enum squid_mode squid_mode, 
+static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode, 
                                       char *buf, int length) 
 {
        char *user, *pass;      
@@ -346,7 +399,7 @@ static void manage_squid_basic_request(enum squid_mode squid_mode,
        *pass='\0';
        pass++;
        
-       if (squid_mode == SQUID_2_5_BASIC) {
+       if (stdio_helper_mode == SQUID_2_5_BASIC) {
                rfc1738_unescape(user);
                rfc1738_unescape(pass);
        }
@@ -409,7 +462,7 @@ static void offer_gss_spnego_mechs(void) {
        return;
 }
 
-static void manage_gss_spnego_request(enum squid_mode squid_mode,
+static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode, 
                                      char *buf, int length) 
 {
        static NTLMSSP_STATE *ntlmssp_state = NULL;
@@ -470,9 +523,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
        if (request.type == SPNEGO_NEG_TOKEN_INIT) {
 
                /* Second request from Client. This is where the
-                  client offers its mechanism to use. We currently
-                  only support NTLMSSP, the decision for Kerberos
-                  would be taken here. */
+                  client offers its mechanism to use. */
 
                if ( (request.negTokenInit.mechTypes == NULL) ||
                     (request.negTokenInit.mechTypes[0] == NULL) ) {
@@ -493,7 +544,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
                                DEBUG(1, ("Client wants a new NTLMSSP challenge, but "
                                          "already got one\n"));
                                x_fprintf(x_stdout, "BH\n");
-                               ntlmssp_server_end(&ntlmssp_state);
+                               ntlmssp_end(&ntlmssp_state);
                                return;
                        }
 
@@ -510,7 +561,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
                        response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
                        response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
 
-                       status = ntlmssp_server_update(ntlmssp_state,
+                       status = ntlmssp_update(ntlmssp_state,
                                                       request.negTokenInit.mechToken,
                                                       &response.negTokenTarg.responseToken);
                }
@@ -521,7 +572,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
                        char *principal;
                        DATA_BLOB auth_data;
                        DATA_BLOB ap_rep;
-                       uint8 session_key[16];
+                       DATA_BLOB session_key;
 
                        if ( request.negTokenInit.mechToken.data == NULL ) {
                                DEBUG(1, ("Client did not provide Kerberos data\n"));
@@ -537,7 +588,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
                        status = ads_verify_ticket(lp_realm(),
                                                   &request.negTokenInit.mechToken,
                                                   &principal, &auth_data, &ap_rep,
-                                                  session_key);
+                                                  &session_key);
 
                        /* Now in "principal" we have the name we are
                            authenticated as. */
@@ -583,7 +634,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
                        return;
                }
 
-               status = ntlmssp_server_update(ntlmssp_state,
+               status = ntlmssp_update(ntlmssp_state,
                                               request.negTokenTarg.responseToken,
                                               &response.negTokenTarg.responseToken);
 
@@ -594,7 +645,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
                if (NT_STATUS_IS_OK(status)) {
                        user = strdup(ntlmssp_state->user);
                        domain = strdup(ntlmssp_state->domain);
-                       ntlmssp_server_end(&ntlmssp_state);
+                       ntlmssp_end(&ntlmssp_state);
                }
        }
 
@@ -638,7 +689,7 @@ static void manage_gss_spnego_request(enum squid_mode squid_mode,
        return;
 }
 
-static NTLMSSP_CLIENT_STATE *client_ntlmssp_state = NULL;
+static NTLMSSP_STATE *client_ntlmssp_state = NULL;
 
 static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
 {
@@ -677,7 +728,7 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Could not start NTLMSSP client: %s\n",
                          nt_errstr(status)));
-               ntlmssp_client_end(&client_ntlmssp_state);
+               ntlmssp_end(&client_ntlmssp_state);
                return False;
        }
 
@@ -686,7 +737,7 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Could not set username: %s\n",
                          nt_errstr(status)));
-               ntlmssp_client_end(&client_ntlmssp_state);
+               ntlmssp_end(&client_ntlmssp_state);
                return False;
        }
 
@@ -695,7 +746,7 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Could not set domain: %s\n",
                          nt_errstr(status)));
-               ntlmssp_client_end(&client_ntlmssp_state);
+               ntlmssp_end(&client_ntlmssp_state);
                return False;
        }
 
@@ -704,7 +755,7 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Could not set password: %s\n",
                          nt_errstr(status)));
-               ntlmssp_client_end(&client_ntlmssp_state);
+               ntlmssp_end(&client_ntlmssp_state);
                return False;
        }
 
@@ -713,13 +764,13 @@ static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
        spnego.negTokenInit.reqFlags = 0;
        spnego.negTokenInit.mechListMIC = null_blob;
 
-       status = ntlmssp_client_update(client_ntlmssp_state, null_blob,
+       status = ntlmssp_update(client_ntlmssp_state, null_blob,
                                       &spnego.negTokenInit.mechToken);
 
        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n",
                          nt_errstr(status)));
-               ntlmssp_client_end(&client_ntlmssp_state);
+               ntlmssp_end(&client_ntlmssp_state);
                return False;
        }
 
@@ -746,23 +797,23 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
        if (client_ntlmssp_state == NULL) {
                DEBUG(1, ("Got NTLMSSP tArg without a client state\n"));
                x_fprintf(x_stdout, "BH\n");
-               ntlmssp_client_end(&client_ntlmssp_state);
+               ntlmssp_end(&client_ntlmssp_state);
                return;
        }
 
        if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) {
                x_fprintf(x_stdout, "NA\n");
-               ntlmssp_client_end(&client_ntlmssp_state);
+               ntlmssp_end(&client_ntlmssp_state);
                return;
        }
 
        if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {
                x_fprintf(x_stdout, "AF\n");
-               ntlmssp_client_end(&client_ntlmssp_state);
+               ntlmssp_end(&client_ntlmssp_state);
                return;
        }
 
-       status = ntlmssp_client_update(client_ntlmssp_state,
+       status = ntlmssp_update(client_ntlmssp_state,
                                       spnego.negTokenTarg.responseToken,
                                       &request);
                
@@ -772,7 +823,7 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
                          nt_errstr(status)));
                x_fprintf(x_stdout, "BH\n");
                data_blob_free(&request);
-               ntlmssp_client_end(&client_ntlmssp_state);
+               ntlmssp_end(&client_ntlmssp_state);
                return;
        }
 
@@ -798,7 +849,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
 {
        char *principal;
        DATA_BLOB tkt, to_server;
-       unsigned char session_key_krb5[16];
+       DATA_BLOB session_key_krb5;
        SPNEGO_DATA reply;
        char *reply_base64;
        
@@ -822,7 +873,7 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
               spnego.negTokenInit.mechListMIC.length);
        principal[spnego.negTokenInit.mechListMIC.length] = '\0';
 
-       tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5);
+       tkt = cli_krb5_get_ticket(principal, 0, &session_key_krb5);
 
        if (tkt.data == NULL) {
 
@@ -845,9 +896,11 @@ static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
                        return True;
                }
 
-               tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5);
+               tkt = cli_krb5_get_ticket(principal, 0, &session_key_krb5);
        }
 
+       data_blob_free(&session_key_krb5);
+
        ZERO_STRUCT(reply);
 
        reply.type = SPNEGO_NEG_TOKEN_INIT;
@@ -896,7 +949,7 @@ static void manage_client_krb5_targ(SPNEGO_DATA spnego)
 
 #endif
 
-static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
+static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode, 
                                             char *buf, int length) 
 {
        DATA_BLOB request;
@@ -1000,7 +1053,7 @@ static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
                                x_fprintf(x_stdout, "BH\n");
                        }
 
-                       ntlmssp_client_end(&client_ntlmssp_state);
+                       ntlmssp_end(&client_ntlmssp_state);
                        goto out;
                }
 
@@ -1029,7 +1082,7 @@ static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
        return;
 }
 
-static void manage_squid_request(enum squid_mode squid_mode
+static void manage_squid_request(enum stdio_helper_mode helper_mode, stdio_helper_function fn
 {
        char buf[SQUID_BUFFER_SIZE+1];
        int length;
@@ -1066,24 +1119,16 @@ static void manage_squid_request(enum squid_mode squid_mode)
                return;
        }
        
-       if (squid_mode == SQUID_2_5_BASIC || squid_mode == SQUID_2_4_BASIC) {
-               manage_squid_basic_request(squid_mode, buf, length);
-       } else if (squid_mode == SQUID_2_5_NTLMSSP) {
-               manage_squid_ntlmssp_request(squid_mode, buf, length);
-       } else if (squid_mode == GSS_SPNEGO) {
-               manage_gss_spnego_request(squid_mode, buf, length);
-       } else if (squid_mode == GSS_SPNEGO_CLIENT) {
-               manage_gss_spnego_client_request(squid_mode, buf, length);
-       }
+       fn(helper_mode, buf, length);
 }
 
 
-static void squid_stream(enum squid_mode squid_mode) {
+static void squid_stream(enum stdio_helper_mode stdio_mode, stdio_helper_function fn) {
        /* initialize FDescs */
        x_setbuf(x_stdout, NULL);
        x_setbuf(x_stderr, NULL);
        while(1) {
-               manage_squid_request(squid_mode);
+               manage_squid_request(stdio_mode, fn);
        }
 }
 
@@ -2019,20 +2064,15 @@ enum {
        }
 
        if (helper_protocol) {
-               if (strcmp(helper_protocol, "squid-2.5-ntlmssp")== 0) {
-                       squid_stream(SQUID_2_5_NTLMSSP);
-               } else if (strcmp(helper_protocol, "squid-2.5-basic")== 0) {
-                       squid_stream(SQUID_2_5_BASIC);
-               } else if (strcmp(helper_protocol, "squid-2.4-basic")== 0) {
-                       squid_stream(SQUID_2_4_BASIC);
-               } else if (strcmp(helper_protocol, "gss-spnego")== 0) {
-                       squid_stream(GSS_SPNEGO);
-               } else if (strcmp(helper_protocol, "gss-spnego-client") == 0) {
-                       squid_stream(GSS_SPNEGO_CLIENT);
-               } else {
-                       x_fprintf(x_stderr, "unknown helper protocol [%s]\n", helper_protocol);
-                       exit(1);
+               int i;
+               for (i=0; i<NUM_HELPER_MODES; i++) {
+                       if (strcmp(helper_protocol, stdio_helper_protocols[i].name) == 0) {
+                               squid_stream(stdio_helper_protocols[i].mode, stdio_helper_protocols[i].fn);
+                               exit(0);
+                       }
                }
+               x_fprintf(x_stderr, "unknown helper protocol [%s]\n", helper_protocol);
+               exit(1);
        }
 
        if (!opt_username) {
index c69b14946944def016e2676f19a0046a355bc46e..d72634d78b52389e2568cc3ac1318faed60fad0f 100644 (file)
@@ -489,7 +489,11 @@ static int delete_user_entry (struct pdb_context *in, const char *username)
                return -1;
        }
 
-       return NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount));
+       if (!NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount))) {
+               fprintf (stderr, "Unable to delete user %s\n", username);
+               return -1;
+       }
+       return 0;
 }
 
 /*********************************************************
@@ -515,7 +519,12 @@ static int delete_machine_entry (struct pdb_context *in, const char *machinename
                return -1;
        }
 
-       return NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount));
+       if (!NT_STATUS_IS_OK(in->pdb_delete_sam_account (in, samaccount))) {
+               fprintf (stderr, "Unable to delete machine %s\n", name);
+               return -1;
+       }
+
+       return 0;
 }
 
 /*********************************************************
index 49a8fa92de4a937da3f44e6bfc344d54856c13c4..07e3ee38fbf68b49dafd16203cd25244adbbc441 100644 (file)
@@ -355,7 +355,8 @@ static BOOL cgi_handle_authorization(char *line)
        }
        
 err:
-       cgi_setup_error("401 Bad Authorization", "", 
+       cgi_setup_error("401 Bad Authorization", 
+                       "WWW-Authenticate: Basic realm=\"SWAT\"\r\n",
                        "username or password incorrect");
 
        passwd_free(&pass);
index efd6d1d0a19c4f69e6a78d43987ccd846152ca8a..46432c41f852049c274644b7b1fb1500e135a9da 100644 (file)
@@ -31,11 +31,7 @@ NSS_STATUS winbindd_request(int req_type,
 
 BOOL winbindd_running(void)
 {
-
-       if (winbindd_request(WINBINDD_PING, NULL, NULL))
-               return False;
-
-       return True;
+       return winbind_ping();
 }      
 #endif
 
index f4046b46a2629f0b64b5600bd65e33800f18f807..1faef46e254e91aace92a188be53920c7138e739 100644 (file)
@@ -212,7 +212,11 @@ static void show_parameter(int snum, struct parm_struct *parm)
                if ((char ***)ptr && *(char ***)ptr && **(char ***)ptr) {
                        char **list = *(char ***)ptr;
                        for (;*list;list++) {
-                               d_printf("%s%s", *list, ((*(list+1))?" ":""));
+                               /* enclose in quotes if the string contains a space */
+                               if ( strchr_m(*list, ' ') ) 
+                                       d_printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
+                               else
+                                       d_printf("%s%s", *list, ((*(list+1))?", ":""));
                        }
                }
                d_printf("\">");
@@ -221,7 +225,11 @@ static void show_parameter(int snum, struct parm_struct *parm)
                if (parm->def.lvalue) {
                        char **list = (char **)(parm->def.lvalue);
                        for (; *list; list++) {
-                               d_printf("%s%s", *list, ((*(list+1))?" ":""));
+                               /* enclose in quotes if the string contains a space */
+                               if ( strchr_m(*list, ' ') ) 
+                                       d_printf("\'%s\'%s", *list, ((*(list+1))?", ":""));
+                               else
+                                       d_printf("%s%s", *list, ((*(list+1))?", ":""));
                        }
                }
                d_printf("\'\">");
index 5996f24ba8960e0f090b9b465f8903fbe5a62372..594c172b6ff713e396a88815046a908ba2f373b7 100644 (file)
@@ -1,6 +1,6 @@
 TEST_ALL="basicsmb-sharelist basicsmb-local-pass-change \
 basicsmb-sharesec basicsmb-usersec \
-basicsmb-serversec basicsmb-domainsec basicsmb-domainsec-nt4 \
+basicsmb-serversec \
 basicsmb-shareguest basicsmb-hostsequiv basicsmb-invalidusers \
 basicsmb-hostsdeny basicsmb-remote-pass-change \
 basicsmb-preexec \
@@ -15,4 +15,4 @@ torture-RW1 torture-RW2 torture-OPEN torture-XCOPY \
 torture-RENAME torture-DELETE torture-PROPERTIES \
 torture-MANGLE torture-FDSESS"
 
-#basicsmb-serversec
+#basicsmb-domainsec basicsmb-domainsec-nt4 
\ No newline at end of file