This is another *BIG* change...
authorAndrew Bartlett <abartlet@samba.org>
Sun, 20 Jan 2002 14:30:58 +0000 (14:30 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 20 Jan 2002 14:30:58 +0000 (14:30 +0000)
Samba now features a pluggable passdb interface, along the same lines as the
one in use in the auth subsystem.  In this case, only one backend may be active
at a time by the 'normal' interface, and only one backend per passdb_context is
permitted outside that.

This pluggable interface is designed to allow any number of passdb backends to
be compiled in, with the selection at runtime.  The 'passdb backend' paramater
has been created (and documented!) to support this.

As such, configure has been modfied to allow (for example) --with-ldap and the
old smbpasswd to be selected at the same time.

This patch also introduces two new backends:  smbpasswd_nua and tdbsam_nua.
These two backends accept 'non unix accounts', where the user does *not* exist
in /etc/passwd.  These accounts' don't have UIDs in the unix sense, but to
avoid conflicts in the algroitmic mapping of RIDs, they use the values
specified in the 'non unix account range' paramter - in the same way as the
winbind ranges are specifed.

While I was at it, I cleaned up some of the code in pdb_tdb (code copied
directly from smbpasswd and not really considered properly).  Most of this was
to do with % macro expansion on stored data.  It isn't easy to get the macros
into the tdb, and the first password change will 'expand' them.  tdbsam needs
to use a similar system to pdb_ldap in this regard.

This patch only makes minor adjustments to pdb_nisplus and pdb_ldap, becouse I
don't have the test facilities for these.  I plan to incoroprate at least
pdb_ldap into this scheme after consultation with Jerry.

Each (converted) passdb module now no longer has any 'static' variables, and
only exports 1 init function outside its .c file.

The non-unix-account support in this patch has been proven!  It is now possible
to join a win2k machine to a Samba PDC without an account in /etc/passwd!

Other changes:

Minor interface adjustments:
pdb_delete_sam_account() now takes a SAM_ACCOUNT, not a char*.

pdb_update_sam_account() no longer takes the 'override' argument that was being
ignored so often (every other passdb backend).  Extra checks have been added in
some places.

Minor code changes:
smbpasswd no longer attempts to initialise the passdb at startup, this is
now done on first use.

pdbedit has lost some of its 'machine account' logic, as this behaviour is now
controlled by the passdb subsystem directly.

The samr subsystem no longer calls 'local password change', but does the pdb
interactions directly.  This allow the ACB_ flags specifed to be transferred
direct to the backend, without interference.

Doco:

I've updated the doco to reflect some of the changes, and removed some paramters
no longer applicable to HEAD.

26 files changed:
docs/docbook/manpages/smb.conf.5.sgml
docs/docbook/manpages/smbpasswd.8.sgml
source/Makefile.in
source/acconfig.h
source/auth/auth_unix.c
source/configure
source/configure.in
source/include/config.h.in
source/include/includes.h
source/include/passdb.h
source/param/loadparm.c
source/passdb/passdb.c
source/passdb/pdb_interface.c [new file with mode: 0644]
source/passdb/pdb_ldap.c
source/passdb/pdb_nisplus.c
source/passdb/pdb_smbpasswd.c
source/passdb/pdb_tdb.c
source/rpc_server/srv_netlog_nt.c
source/rpc_server/srv_samr_nt.c
source/smbd/chgpasswd.c
source/tdb/tdbutil.c
source/utils/pdbedit.c
source/utils/smbpasswd.c
testsuite/build_farm/basicsmb-domainsec-nt4.test
testsuite/build_farm/basicsmb-domainsec.test
testsuite/build_farm/basicsmb.smb.conf.template

index 7aa9ea3b9c57539d2c91a3291ac46a26c53af042..a46464323401d00adc89a987c68cbee50935db41 100644 (file)
                <listitem><para><link linkend="ALLOWTRUSTEDDOMAINS"><parameter>allow trusted domains</parameter></link></para></listitem>
                <listitem><para><link linkend="ANNOUNCEAS"><parameter>announce as</parameter></link></para></listitem>
                <listitem><para><link linkend="ANNOUNCEVERSION"><parameter>announce version</parameter></link></para></listitem>
+               <listitem><para><link linkend="AUTHMETHODS"><parameter>auth methods</parameter></link></para></listitem>
                <listitem><para><link linkend="AUTOSERVICES"><parameter>auto services</parameter></link></para></listitem>
                <listitem><para><link linkend="BINDINTERFACESONLY"><parameter>bind interfaces only</parameter></link></para></listitem>
                <listitem><para><link linkend="BROWSELIST"><parameter>browse list</parameter></link></para></listitem>
                <listitem><para><link linkend="NETBIOSNAME"><parameter>netbios name</parameter></link></para></listitem>
                <listitem><para><link linkend="NETBIOSSCOPE"><parameter>netbios scope</parameter></link></para></listitem>
                <listitem><para><link linkend="NISHOMEDIR"><parameter>nis homedir</parameter></link></para></listitem>
+               <listitem><para><link linkend="NONUNIXACCOUNTRANGE"><parameter>non unix account range</parameter></link></para></listitem>
                <listitem><para><link linkend="NTPIPESUPPORT"><parameter>nt pipe support</parameter></link></para></listitem>
-               <listitem><para><link linkend="NTSMBSUPPORT"><parameter>nt smb support</parameter></link></para></listitem>
                <listitem><para><link linkend="NULLPASSWORDS"><parameter>null passwords</parameter></link></para></listitem>
                <listitem><para><link linkend="OBEYPAMRESTRICTIONS"><parameter>obey pam restrictions</parameter></link></para></listitem>
                <listitem><para><link linkend="OPLOCKBREAKWAITTIME"><parameter>oplock break wait time</parameter></link></para></listitem>
                <listitem><para><link linkend="OS2DRIVERMAP"><parameter>os2 driver map</parameter></link></para></listitem>
                <listitem><para><link linkend="PAMPASSWORDCHANGE"><parameter>pam password change</parameter></link></para></listitem>
                <listitem><para><link linkend="PANICACTION"><parameter>panic action</parameter></link></para></listitem>
+               <listitem><para><link linkend="PASSDBBACKEND"><parameter>passdb backend</parameter></link></para></listitem>
                <listitem><para><link linkend="PASSWDCHAT"><parameter>passwd chat</parameter></link></para></listitem>
                <listitem><para><link linkend="PASSWDCHATDEBUG"><parameter>passwd chat debug</parameter></link></para></listitem>
                <listitem><para><link linkend="PASSWDPROGRAM"><parameter>passwd program</parameter></link></para></listitem>
                
 
 
+               <varlistentry>
+               <term><anchor id="AUTHMETHODS">auth methods (G)</term>
+               <listitem><para>This option allows the administrator to chose what
+                authentication methods <command>smbd</command> will use when authenticating
+                a user.  This option defaults to sensible values based on <link linkend="SECURITY"><parameter>
+               security</parameter></link>.
+
+                Each entry in the list attempts to authenticate the user in turn, until
+                the user authenticates.  In practice only one method will ever actually 
+                be able to complete the authentication.
+               </para>
+
+               <para>Default: <command>auth methods = &lt;empty string&gt;</command></para>
+               <para>Example: <command>auth methods = guest sam ntdomain</command></para>
+               </listitem>
+               </varlistentry>
+
+
                <varlistentry>
                <term><anchor id="AVAILABLE">available (S)</term>
                <listitem><para>This parameter lets you "turn off" a service. If 
                </filename></ulink> file (see the <ulink url="smbpasswd.8.html"><command>
                smbpasswd(8)</command></ulink> program for information on how to set up 
                and maintain this file), or set the <link
-               linkend="SECURITY">security = [server|domain]</link> parameter which 
+               linkend="SECURITY">security = [server|domain|ads]</link> parameter which 
                causes <command>smbd</command> to authenticate against another 
                server.</para>
                
 
 
 
+               <varlistentry>
+               <term><anchor id="NONUNIXACCOUNTRANGE">non unix account range (G)</term>
+               <listitem><para>The non unix account range parameter specifies 
+                the range of 'user ids' that are allocated by the various 'non unix 
+                account' passdb backends.  These backends allow
+                the storage of passwords for users who don't exist in /etc/passwd.  
+                This is most often used for machine account creation. 
+                This range of ids should have no existing local or NIS users within 
+                it as strange conflicts can occur otherwise.</para>
+
+                <para>NOTE: These userids never appear on the system and Samba will never
+                'become' these users. They are used only to ensure that the algorithmic 
+                RID mapping does not conflict with normal users.
+
+               <para>Default: <command>non unix account range = &lt;empty string&gt;
+               </command></para>
+               
+               <para>Example: <command>non unix account range = 10000-20000</command></para>
+               </listitem>
+               </varlistentry>
+
+
+               <listitem><para>This boolean parameter controls whether 
+               <ulink url="smbd.8.html">smbd(8)</ulink> will attempt to map 
+               UNIX permissions into Windows NT access control lists.
+               This parameter was formally a global parameter in releases
+               prior to 2.2.2.</para>
+               
+               <para>Default: <command>nt acl support = yes</command></para>
+               </listitem>
+               </varlistentry>
+
+
+
                <varlistentry>
                <term><anchor id="NTACLSUPPORT">nt acl support (S)</term>
                <listitem><para>This boolean parameter controls whether 
 
 
 
-               <varlistentry>
-               <term><anchor id="NTSMBSUPPORT">nt smb support (G)</term>
-               <listitem><para>This boolean parameter controls whether <ulink 
-               url="smbd.8.html">smbd(8)</ulink> will negotiate NT specific SMB 
-               support with Windows NT clients. Although this is a developer 
-               debugging option and should be left alone, benchmarking has discovered 
-               that Windows NT clients give faster performance with this option 
-               set to <constant>no</constant>. This is still being investigated. 
-               If this option is set to <constant>no</constant> then Samba offers 
-               exactly the same SMB calls that versions prior to Samba 2.0 offered. 
-               This information may be of use if any users are having problems 
-               with NT SMB support.</para>
-               
-               <para>You should not need to ever disable this parameter.</para>
-
-               <para>Default: <command>nt smb support = yes</command></para>
-               </listitem>
-               </varlistentry>
-       
-
-
                <varlistentry>
                <term><anchor id="NULLPASSWORDS">null passwords (G)</term>
                <listitem><para>Allow or disallow client access to accounts 
                </varlistentry>
 
 
+               <varlistentry>
+               <term><anchor id="PASSDBBACKEND">passdb backend (G)</term>
+               <listitem><para>This option allows the administrator to chose what
+                backend in which to store passwords.  This allows (for example) both 
+                smbpasswd and tdbsam to be used without a recompile.  Only one can
+                be used at a time however, and experimental backends must still be selected
+                (eg --with-tdbsam) at configure time.
+               </para>
+
+               <para>Default: <command>passdb backend = smbpasswd</command></para>
+               <para>Example: <command>passdb backend = tdbsam</command></para>
+               </listitem>
+               </varlistentry>
+
+
                <varlistentry>
                <term><anchor id="PASSWDCHAT">passwd chat (G)</term>
                <listitem><para>This string controls the <emphasis>"chat"</emphasis> 
index 098e874cc853ae2a2d074f69c6ec6c5b64a5a7b3..3c7a6a5150a9748f01b0c44b6e254573052b2399 100644 (file)
                new password typed (type &lt;Enter&gt; for the old password). This 
                option is ignored if the username following already exists in 
                the smbpasswd file and it is treated like a regular change 
-               password command. Note that the user to be added must already exist 
-               in the system password file (usually <filename>/etc/passwd</filename>)
-               else the request to add the user will fail. </para>
+               password command.  Note that the default passdb backends require 
+                the user to already exist in the system password file (usually 
+                <filename>/etc/passwd</filename>), else the request to add the 
+                user will fail.  </para>
                
                <para>This option is only available when running smbpasswd 
                as root. </para></listitem>
                
                <para>If the smbpasswd file is in the 'old' format (pre-Samba 2.0 
                format) there is no space in the user's password entry to write
-               this information and so the user is disabled by writing 'X' characters 
-               into the password space in the smbpasswd file. See <command>smbpasswd(5)
+               this information and the command will FAIL. See <command>smbpasswd(5)
                </command> for details on the 'old' and new password file formats.
                </para>
 
                the user will be able to authenticate via SMB once again. </para>
                
                <para>If the smbpasswd file is in the 'old' format, then <command>
-               smbpasswd</command> will prompt for a new password for this user, 
-               otherwise the account will be enabled by removing the <constant>'D'
-               </constant> flag from account control space in the <filename>
-               smbpasswd</filename> file. See <command>smbpasswd (5)</command> for 
+               smbpasswd</command> will FAIL to enable the account.  
+                See <command>smbpasswd (5)</command> for 
                details on the 'old' and new password file formats. </para>
 
                <para>This option is only available when running smbpasswd as root. 
                </varlistentry>
                
                
-               <varlistentry>
-               <term>-j DOMAIN</term>
-               <listitem><para>This option is used to add a Samba server 
-               into a Windows NT Domain, as a Domain member capable of authenticating 
-               user accounts to any Domain Controller in the same way as a Windows 
-               NT Server. See the <command>security = domain</command> option in 
-               the <filename>smb.conf(5)</filename> man page. </para>
-               
-               <para>In order to be used in this way, the Administrator for 
-               the Windows NT Domain must have used the program "Server Manager 
-               for Domains" to add the primary NetBIOS name of  the Samba server 
-               as a member of the Domain. </para>
-               
-               <para>After this has been done, to join the Domain invoke <command>
-               smbpasswd</command> with this parameter. smbpasswd will then 
-               look up the Primary Domain Controller for the Domain (found in 
-               the <filename>smb.conf</filename> file in the parameter 
-               <parameter>password server</parameter> and change the machine account 
-               password used to create the secure Domain communication.  This 
-               password is then stored by smbpasswd in a TDB, writeable only by root, 
-               called <filename>secrets.tdb</filename> </para>
-               
-               <para>Once this operation has been performed the <filename>
-               smb.conf</filename> file may be updated to set the <command>
-               security = domain</command> option and all future logins
-               to the Samba server will be authenticated to the Windows NT 
-               PDC. </para>
-               
-               <para>Note that even though the authentication is being 
-               done to the PDC all users accessing the Samba server must still 
-               have a valid UNIX account on that machine. </para>
-
-
-               <para>This option is only available when running smbpasswd as root. 
-               </para></listitem>
-               </varlistentry>
-               
-               
-               
                <varlistentry>
                <term>-U username</term>
                <listitem><para>This option may only be used in conjunction 
 <refsect1>
        <title>VERSION</title>
 
-       <para>This man page is correct for version 2.2 of 
+       <para>This man page is correct for version 3.0 of 
        the Samba suite.</para>
 </refsect1>
 
 </refsect1>
 
 </refentry>
+
+
+
+
index a024ba664e4aae01d13ed0f5e3ab6bc69158e2c5..6d3a25b4d261b368d59b49ae6dc81324ef1e6499 100644 (file)
@@ -184,7 +184,7 @@ RPC_CLIENT_OBJ = rpc_client/cli_netlogon.o rpc_client/cli_pipe.o \
 
 LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
 
-PASSDB_OBJ = passdb/passdb.o passdb/pdb_get_set.o \
+PASSDB_OBJ = passdb/passdb.o passdb/pdb_interface.o passdb/pdb_get_set.o \
                passdb/machine_sid.o passdb/pdb_smbpasswd.o \
                passdb/pdb_tdb.o passdb/pdb_ldap.o \
                passdb/pdb_nisplus.o
index 5265979efbf158ab9de7f8ecbabf922dad59b5da..8ebb45f3c7005b2d4fd53d7b1c7109511e34cfff 100644 (file)
@@ -60,9 +60,6 @@
 #undef WITH_PROFILE
 #undef WITH_SSL
 #undef SSL_DIR
-#undef WITH_LDAP
-#undef WITH_NISPLUS
-#undef WITH_TDBPWD
 #undef WITH_PAM
 #undef WITH_NISPLUS_HOME
 #undef WITH_AUTOMOUNT
 #undef HAVE_CUPS
 #undef WITH_LDAP_SAM
 #undef WITH_NISPLUS_SAM
-#undef WITH_SMBPASSWD_SAM
 #undef WITH_TDB_SAM
 #undef LINUX_QUOTAS_1
 #undef LINUX_QUOTAS_2
index 73a4c51b4f26cd4493d770794876b35b36409b98..b2e202552c1c2c099c0092bd59befc6739bc091a 100644 (file)
@@ -60,9 +60,7 @@ static BOOL update_smbpassword_file(char *user, char *password)
        /* Now write it into the file. */
        become_root();
 
-       /* Here, the override flag is True, because we want to ignore the
-           XXXXXXX'd out password */
-       ret = pdb_update_sam_account (sampass, True);
+       ret = pdb_update_sam_account (sampass);
 
        unbecome_root();
 
index f6bf9bcc4649642fe9657ae3398cadfff568467a..d0da6e0f1f7afec8cd8d70203b0e25c70f0ba840 100755 (executable)
 ##
 ########################################################################################
 
-## set the with_smbpasswd_sam as the default
-with_smbpasswd_sam=yes
-
-
 #################################################
 # check for a TDB password database
 echo $ac_n "checking whether to use TDB SAM database""... $ac_c" 1>&6
-echo "configure:12379: checking whether to use TDB SAM database" >&5
+echo "configure:12375: checking whether to use TDB SAM database" >&5
 # Check whether --with-tdbsam or --without-tdbsam was given.
 if test "${with_tdbsam+set}" = set; then
   withval="$with_tdbsam"
@@ -12386,7 +12382,6 @@ if test "${with_tdbsam+set}" = set; then
 #define WITH_TDB_SAM 1
 EOF
 
-    with_smbpasswd_sam=no
     ;;
   *)
     echo "$ac_t""no" 1>&6
@@ -12401,7 +12396,7 @@ fi
 #################################################
 # check for a LDAP password database
 echo $ac_n "checking whether to use LDAP SAM database""... $ac_c" 1>&6
-echo "configure:12405: checking whether to use LDAP SAM database" >&5
+echo "configure:12400: checking whether to use LDAP SAM database" >&5
 # Check whether --with-ldapsam or --without-ldapsam was given.
 if test "${with_ldapsam+set}" = set; then
   withval="$with_ldapsam"
@@ -12413,7 +12408,6 @@ if test "${with_ldapsam+set}" = set; then
 EOF
 
     LIBS="-lldap -llber $LIBS"
-    with_smbpasswd_sam=no
     ;;
   *)
     echo "$ac_t""no" 1>&6
@@ -12428,7 +12422,7 @@ fi
 #################################################
 # check for a NISPLUS password database
 echo $ac_n "checking whether to use NISPLUS SAM database""... $ac_c" 1>&6
-echo "configure:12432: checking whether to use NISPLUS SAM database" >&5
+echo "configure:12426: checking whether to use NISPLUS SAM database" >&5
 # Check whether --with-nisplussam or --without-nisplussam was given.
 if test "${with_nisplussam+set}" = set; then
   withval="$with_nisplussam"
@@ -12439,7 +12433,6 @@ if test "${with_nisplussam+set}" = set; then
 #define WITH_NISPLUS_SAM 1
 EOF
 
-    with_smbpasswd_sam=no
     ;;
   *)
     echo "$ac_t""no" 1>&6
@@ -12451,22 +12444,6 @@ else
 fi
 
 
-################################################
-# This test should come last because the
-# smbpasswd SAM is only used if another format
-# has not been defined
-echo $ac_n "checking whether to use traditional smbpasswd file""... $ac_c" 1>&6
-echo "configure:12460: checking whether to use traditional smbpasswd file" >&5
-if test $with_smbpasswd_sam = yes; then
-       echo "$ac_t""yes" 1>&6
-       cat >> confdefs.h <<\EOF
-#define WITH_SMBPASSWD_SAM 1
-EOF
-
-else
-       echo "$ac_t""no" 1>&6
-fi
-
 ########################################################################################
 ##
 ## END OF TESTS FOR SAM BACKENDS.  
@@ -12476,7 +12453,7 @@ fi
 #################################################
 # check for a NISPLUS_HOME support 
 echo $ac_n "checking whether to use NISPLUS_HOME""... $ac_c" 1>&6
-echo "configure:12480: checking whether to use NISPLUS_HOME" >&5
+echo "configure:12457: checking whether to use NISPLUS_HOME" >&5
 # Check whether --with-nisplus-home or --without-nisplus-home was given.
 if test "${with_nisplus_home+set}" = set; then
   withval="$with_nisplus_home"
@@ -12501,7 +12478,7 @@ fi
 #################################################
 # check for the secure socket layer
 echo $ac_n "checking whether to use SSL""... $ac_c" 1>&6
-echo "configure:12505: checking whether to use SSL" >&5
+echo "configure:12482: checking whether to use SSL" >&5
 # Check whether --with-ssl or --without-ssl was given.
 if test "${with_ssl+set}" = set; then
   withval="$with_ssl"
@@ -12575,7 +12552,7 @@ fi
 #################################################
 # check for syslog logging
 echo $ac_n "checking whether to use syslog logging""... $ac_c" 1>&6
-echo "configure:12579: checking whether to use syslog logging" >&5
+echo "configure:12556: checking whether to use syslog logging" >&5
 # Check whether --with-syslog or --without-syslog was given.
 if test "${with_syslog+set}" = set; then
   withval="$with_syslog"
@@ -12600,7 +12577,7 @@ fi
 #################################################
 # check for a shared memory profiling support
 echo $ac_n "checking whether to use profiling""... $ac_c" 1>&6
-echo "configure:12604: checking whether to use profiling" >&5
+echo "configure:12581: checking whether to use profiling" >&5
 # Check whether --with-profiling-data or --without-profiling-data was given.
 if test "${with_profiling_data+set}" = set; then
   withval="$with_profiling_data"
@@ -12628,7 +12605,7 @@ fi
 QUOTAOBJS=smbd/noquotas.o
 
 echo $ac_n "checking whether to support disk-quotas""... $ac_c" 1>&6
-echo "configure:12632: checking whether to support disk-quotas" >&5
+echo "configure:12609: checking whether to support disk-quotas" >&5
 # Check whether --with-quotas or --without-quotas was given.
 if test "${with_quotas+set}" = set; then
   withval="$with_quotas"
@@ -12639,13 +12616,13 @@ if test "${with_quotas+set}" = set; then
       *linux*)
         # Check for kernel 2.4.x quota braindamage...
         echo $ac_n "checking for linux 2.4.x quota braindamage..""... $ac_c" 1>&6
-echo "configure:12643: checking for linux 2.4.x quota braindamage.." >&5
+echo "configure:12620: checking for linux 2.4.x quota braindamage.." >&5
 if eval "test \"`echo '$''{'samba_cv_linux_2_4_quota_braindamage'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
         cat > conftest.$ac_ext <<EOF
-#line 12649 "configure"
+#line 12626 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <sys/types.h>
@@ -12657,7 +12634,7 @@ int main() {
 struct mem_dqblk D;
 ; return 0; }
 EOF
-if { (eval echo configure:12661: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:12638: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_linux_2_4_quota_braindamage=yes
 else
@@ -12706,7 +12683,7 @@ fi
 # check for experimental utmp accounting
 
 echo $ac_n "checking whether to support utmp accounting""... $ac_c" 1>&6
-echo "configure:12710: checking whether to support utmp accounting" >&5
+echo "configure:12687: checking whether to support utmp accounting" >&5
 # Check whether --with-utmp or --without-utmp was given.
 if test "${with_utmp+set}" = set; then
   withval="$with_utmp"
@@ -12806,7 +12783,7 @@ fi
 #################################################
 # choose native language(s) of man pages
 echo $ac_n "checking chosen man pages' language(s)""... $ac_c" 1>&6
-echo "configure:12810: checking chosen man pages' language(s)" >&5
+echo "configure:12787: checking chosen man pages' language(s)" >&5
 # Check whether --with-manpages-langs or --without-manpages-langs was given.
 if test "${with_manpages_langs+set}" = set; then
   withval="$with_manpages_langs"
 #################################################
 # these tests are taken from the GNU fileutils package
 echo "checking how to get filesystem space usage" 1>&6
-echo "configure:12838: checking how to get filesystem space usage" >&5
+echo "configure:12815: checking how to get filesystem space usage" >&5
 space=no
 
 # Test for statvfs64.
 if test $space = no; then
   # SVR4
   echo $ac_n "checking statvfs64 function (SVR4)""... $ac_c" 1>&6
-echo "configure:12845: checking statvfs64 function (SVR4)" >&5
+echo "configure:12822: checking statvfs64 function (SVR4)" >&5
 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs64'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -12849,7 +12826,7 @@ else
   fu_cv_sys_stat_statvfs64=cross
 else
   cat > conftest.$ac_ext <<EOF
-#line 12853 "configure"
+#line 12830 "configure"
 #include "confdefs.h"
 
 #if defined(HAVE_UNISTD_H)
@@ -12863,7 +12840,7 @@ else
     exit (statvfs64 (".", &fsd));
   }
 EOF
-if { (eval echo configure:12867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:12844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statvfs64=yes
 else
 if test $space = no; then
   # SVR4
   echo $ac_n "checking statvfs function (SVR4)""... $ac_c" 1>&6
-echo "configure:12900: checking statvfs function (SVR4)" >&5
+echo "configure:12877: checking statvfs function (SVR4)" >&5
 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 12905 "configure"
+#line 12882 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/statvfs.h>
@@ -12909,7 +12886,7 @@ int main() {
 struct statvfs fsd; statvfs (0, &fsd);
 ; return 0; }
 EOF
-if { (eval echo configure:12913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:12890: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   fu_cv_sys_stat_statvfs=yes
 else
@@ -12934,7 +12911,7 @@ fi
 if test $space = no; then
   # DEC Alpha running OSF/1
   echo $ac_n "checking for 3-argument statfs function (DEC OSF/1)""... $ac_c" 1>&6
-echo "configure:12938: checking for 3-argument statfs function (DEC OSF/1)" >&5
+echo "configure:12915: checking for 3-argument statfs function (DEC OSF/1)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs3_osf1'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -12942,7 +12919,7 @@ else
   fu_cv_sys_stat_statfs3_osf1=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 12946 "configure"
+#line 12923 "configure"
 #include "confdefs.h"
 
 #include <sys/param.h>
@@ -12955,7 +12932,7 @@ else
     exit (statfs (".", &fsd, sizeof (struct statfs)));
   }
 EOF
-if { (eval echo configure:12959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:12936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statfs3_osf1=yes
 else
@@ -12982,7 +12959,7 @@ fi
 if test $space = no; then
 # AIX
   echo $ac_n "checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)""... $ac_c" 1>&6
-echo "configure:12986: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5
+echo "configure:12963: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_bsize'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -12990,7 +12967,7 @@ else
   fu_cv_sys_stat_statfs2_bsize=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 12994 "configure"
+#line 12971 "configure"
 #include "confdefs.h"
 
 #ifdef HAVE_SYS_PARAM_H
@@ -13009,7 +12986,7 @@ else
   exit (statfs (".", &fsd));
   }
 EOF
-if { (eval echo configure:13013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:12990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statfs2_bsize=yes
 else
@@ -13036,7 +13013,7 @@ fi
 if test $space = no; then
 # SVR3
   echo $ac_n "checking for four-argument statfs (AIX-3.2.5, SVR3)""... $ac_c" 1>&6
-echo "configure:13040: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5
+echo "configure:13017: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs4'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -13044,7 +13021,7 @@ else
   fu_cv_sys_stat_statfs4=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 13048 "configure"
+#line 13025 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/statfs.h>
@@ -13054,7 +13031,7 @@ else
   exit (statfs (".", &fsd, sizeof fsd, 0));
   }
 EOF
-if { (eval echo configure:13058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:13035: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statfs4=yes
 else
@@ -13081,7 +13058,7 @@ fi
 if test $space = no; then
 # 4.4BSD and NetBSD
   echo $ac_n "checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)""... $ac_c" 1>&6
-echo "configure:13085: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5
+echo "configure:13062: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_fsize'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -13089,7 +13066,7 @@ else
   fu_cv_sys_stat_statfs2_fsize=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 13093 "configure"
+#line 13070 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #ifdef HAVE_SYS_PARAM_H
@@ -13105,7 +13082,7 @@ else
   exit (statfs (".", &fsd));
   }
 EOF
-if { (eval echo configure:13109: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:13086: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_statfs2_fsize=yes
 else
@@ -13132,7 +13109,7 @@ fi
 if test $space = no; then
   # Ultrix
   echo $ac_n "checking for two-argument statfs with struct fs_data (Ultrix)""... $ac_c" 1>&6
-echo "configure:13136: checking for two-argument statfs with struct fs_data (Ultrix)" >&5
+echo "configure:13113: checking for two-argument statfs with struct fs_data (Ultrix)" >&5
   if eval "test \"`echo '$''{'fu_cv_sys_stat_fs_data'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -13140,7 +13117,7 @@ else
   fu_cv_sys_stat_fs_data=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 13144 "configure"
+#line 13121 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #ifdef HAVE_SYS_PARAM_H
@@ -13160,7 +13137,7 @@ else
   exit (statfs (".", &fsd) != 1);
   }
 EOF
-if { (eval echo configure:13164: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:13141: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   fu_cv_sys_stat_fs_data=yes
 else
@@ -13193,9 +13170,9 @@ fi
 # file support.
 #
 echo $ac_n "checking if large file support can be enabled""... $ac_c" 1>&6
-echo "configure:13197: checking if large file support can be enabled" >&5
+echo "configure:13174: checking if large file support can be enabled" >&5
 cat > conftest.$ac_ext <<EOF
-#line 13199 "configure"
+#line 13176 "configure"
 #include "confdefs.h"
 
 #if defined(HAVE_LONGLONG) && (defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8)))
@@ -13208,7 +13185,7 @@ int main() {
 int i
 ; return 0; }
 EOF
-if { (eval echo configure:13212: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:13189: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes
 else
@@ -13273,7 +13250,7 @@ fi
 # check for ACL support
 
 echo $ac_n "checking whether to support ACLs""... $ac_c" 1>&6
-echo "configure:13277: checking whether to support ACLs" >&5
+echo "configure:13254: checking whether to support ACLs" >&5
 # Check whether --with-acl-support or --without-acl-support was given.
 if test "${with_acl_support+set}" = set; then
   withval="$with_acl_support"
@@ -13326,7 +13303,7 @@ EOF
                ;;
         *)
                echo $ac_n "checking for acl_get_file in -lacl""... $ac_c" 1>&6
-echo "configure:13330: checking for acl_get_file in -lacl" >&5
+echo "configure:13307: checking for acl_get_file in -lacl" >&5
 ac_lib_var=`echo acl'_'acl_get_file | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -13334,7 +13311,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lacl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 13338 "configure"
+#line 13315 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -13345,7 +13322,7 @@ int main() {
 acl_get_file()
 ; return 0; }
 EOF
-if { (eval echo configure:13349: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -13373,13 +13350,13 @@ else
 fi
 
                echo $ac_n "checking for ACL support""... $ac_c" 1>&6
-echo "configure:13377: checking for ACL support" >&5
+echo "configure:13354: checking for ACL support" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_POSIX_ACLS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
                cat > conftest.$ac_ext <<EOF
-#line 13383 "configure"
+#line 13360 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/acl.h>
@@ -13387,7 +13364,7 @@ int main() {
  acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);
 ; return 0; }
 EOF
-if { (eval echo configure:13391: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   samba_cv_HAVE_POSIX_ACLS=yes
 else
@@ -13407,13 +13384,13 @@ echo "$ac_t""$samba_cv_HAVE_POSIX_ACLS" 1>&6
 EOF
 
                                echo $ac_n "checking for acl_get_perm_np""... $ac_c" 1>&6
-echo "configure:13411: checking for acl_get_perm_np" >&5
+echo "configure:13388: checking for acl_get_perm_np" >&5
 if eval "test \"`echo '$''{'samba_cv_HAVE_ACL_GET_PERM_NP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
                                cat > conftest.$ac_ext <<EOF
-#line 13417 "configure"
+#line 13394 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/acl.h>
@@ -13421,7 +13398,7 @@ int main() {
  acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm);
 ; return 0; }
 EOF
-if { (eval echo configure:13425: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13402: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   samba_cv_HAVE_ACL_GET_PERM_NP=yes
 else
@@ -13468,7 +13445,7 @@ fi
 # (WINBIND_STARGETS) and shared libraries (WINBIND_LTARGETS).
 
 echo $ac_n "checking whether to build winbind""... $ac_c" 1>&6
-echo "configure:13472: checking whether to build winbind" >&5
+echo "configure:13449: checking whether to build winbind" >&5
 
 # Initially, the value of $host_os decides whether winbind is supported
 
@@ -13557,7 +13534,7 @@ fi
 
 if test x"$INCLUDED_POPT" != x"yes"; then
     echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6
-echo "configure:13561: checking for poptGetContext in -lpopt" >&5
+echo "configure:13538: checking for poptGetContext in -lpopt" >&5
 ac_lib_var=`echo popt'_'poptGetContext | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -13565,7 +13542,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 13569 "configure"
+#line 13546 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -13576,7 +13553,7 @@ int main() {
 poptGetContext()
 ; return 0; }
 EOF
-if { (eval echo configure:13580: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13557: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -13600,7 +13577,7 @@ fi
 fi
 
 echo $ac_n "checking whether to use included popt""... $ac_c" 1>&6
-echo "configure:13604: checking whether to use included popt" >&5
+echo "configure:13581: checking whether to use included popt" >&5
 if test x"$INCLUDED_POPT" = x"yes"; then
     echo "$ac_t""$srcdir/popt" 1>&6
     BUILD_POPT='$(POPT_OBJS)'
@@ -13620,11 +13597,11 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 13624 "configure"
+#line 13601 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/summary.c"
 EOF
-if { (eval echo configure:13628: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:13605: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   echo "configure OK";
 else
index 9bf64384e16525ce5360940f6457e333a18652bf..9b2f950b9c13c839e7c6cea66c9e834b2858f3bf 100644 (file)
@@ -1911,10 +1911,6 @@ fi
 ##
 ########################################################################################
 
-## set the with_smbpasswd_sam as the default
-with_smbpasswd_sam=yes
-
-
 #################################################
 # check for a TDB password database
 AC_MSG_CHECKING(whether to use TDB SAM database)
@@ -1924,7 +1920,6 @@ AC_ARG_WITH(tdbsam,
   yes)
     AC_MSG_RESULT(yes)
     AC_DEFINE(WITH_TDB_SAM)
-    with_smbpasswd_sam=no
     ;;
   *)
     AC_MSG_RESULT(no)
@@ -1943,7 +1938,6 @@ AC_ARG_WITH(ldapsam,
     AC_MSG_RESULT(yes)
     AC_DEFINE(WITH_LDAP_SAM)
     LIBS="-lldap -llber $LIBS"
-    with_smbpasswd_sam=no
     ;;
   *)
     AC_MSG_RESULT(no)
@@ -1961,7 +1955,6 @@ AC_ARG_WITH(nisplussam,
   yes)
     AC_MSG_RESULT(yes)
     AC_DEFINE(WITH_NISPLUS_SAM)
-    with_smbpasswd_sam=no
     ;;
   *)
     AC_MSG_RESULT(no)
@@ -1970,18 +1963,6 @@ AC_ARG_WITH(nisplussam,
   AC_MSG_RESULT(no)
 )
 
-################################################
-# This test should come last because the
-# smbpasswd SAM is only used if another format
-# has not been defined
-AC_MSG_CHECKING(whether to use traditional smbpasswd file)
-if test $with_smbpasswd_sam = yes; then
-       AC_MSG_RESULT(yes)
-       AC_DEFINE(WITH_SMBPASSWD_SAM)
-else
-       AC_MSG_RESULT(no)
-fi
-
 ########################################################################################
 ##
 ## END OF TESTS FOR SAM BACKENDS.  
index fe4ff0df38847f43cb88e89b5f11fd2cdcffa9e6..310ef32b2fafad687f4a9d24677a2f51cb29227d 100644 (file)
 #undef WITH_PROFILE
 #undef WITH_SSL
 #undef SSL_DIR
-#undef WITH_LDAP
-#undef WITH_NISPLUS
-#undef WITH_TDBPWD
 #undef WITH_PAM
 #undef WITH_NISPLUS_HOME
 #undef WITH_AUTOMOUNT
 #undef HAVE_CUPS
 #undef WITH_LDAP_SAM
 #undef WITH_NISPLUS_SAM
-#undef WITH_SMBPASSWD_SAM
 #undef WITH_TDB_SAM
 #undef LINUX_QUOTAS_1
 #undef LINUX_QUOTAS_2
index 0ea387c19c73b96dfe10fe5f7903eb0f0572cb9f..7f913ba830ffc843c359141f07d4c58a75f2e2be 100644 (file)
@@ -735,6 +735,8 @@ extern int errno;
 
 #include "auth.h"
 
+#include "passdb.h"
+
 #include "session.h"
 
 #include "asn_1.h"
index 4e50ff7da57b0ce2d857f07b66af3c201629b00a..178b3a435925a96f89edbef2220f9979a5645343 100644 (file)
 #define _PASSDB_H
 
 
+/*****************************************************************
+ Functions to be implemented by the new (v2) passdb API 
+****************************************************************/
+
+typedef struct pdb_context 
+{
+       struct pdb_methods *pdb_selected;
+       
+       /* These functions are wrappers for the functions listed above.
+          They may do extra things like re-reading a SAM_ACCOUNT on update */
+
+       BOOL (*pdb_setsampwent)(struct pdb_context *, BOOL update);
+       
+       void (*pdb_endsampwent)(struct pdb_context *);
+       
+       BOOL (*pdb_getsampwent)(struct pdb_context *, SAM_ACCOUNT *user);
+       
+       BOOL (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username);
+       
+       BOOL (*pdb_getsampwrid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, uint32 rid);
+       
+       BOOL (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
+       
+       BOOL (*pdb_update_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
+       
+       BOOL (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username);
+       
+       void (*free_fn)(struct pdb_context **);
+       
+       TALLOC_CTX *mem_ctx;
+       
+} PDB_CONTEXT;
+
+typedef struct pdb_methods 
+{
+       char *name; /* What name got this module */
+
+       BOOL (*setsampwent)(struct pdb_context *, BOOL update);
+       
+       void (*endsampwent)(struct pdb_context *);
+       
+       BOOL (*getsampwent)(struct pdb_context *, SAM_ACCOUNT *user);
+       
+       BOOL (*getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username);
+       
+       BOOL (*getsampwrid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, uint32 rid);
+       
+       BOOL (*add_sam_account)(struct pdb_context *, const SAM_ACCOUNT *sampass);
+       
+       BOOL (*update_sam_account)(struct pdb_context *, const SAM_ACCOUNT *sampass);
+       
+       BOOL (*delete_sam_account)(struct pdb_context *, const SAM_ACCOUNT *username);
+       
+       void *private_data;  /* Private data of some kind */
+       
+       void (*free_private_data)(void **);
+
+} PDB_METHODS;
+
+
+struct pdb_init_function {
+       char *name;
+       /* Function to create a member of the authmethods list */
+       NTSTATUS (*init)(struct pdb_context *pdb_context, 
+                        struct pdb_methods **pdb_method, 
+                        const char *location);
+};
 
 #endif /* _PASSDB_H */
index fce5fcde49885e9f6c3683b9ee483e1cefe1dfef..af8a5df897ae2212b912168eb006084d4a21cc16 100644 (file)
@@ -111,6 +111,7 @@ typedef struct
        char *szSMBPasswdFile;
        char *szPrivateDir;
        char *szPassdbModulePath;
+       char *szPassdbBackend;
        char *szPasswordServer;
        char *szSocketOptions;
        char *szWorkGroup;
@@ -150,6 +151,7 @@ typedef struct
        char *szSourceEnv;
        char *szWinbindUID;
        char *szWinbindGID;
+       char *szNonUnixAccountRange;
        char *szTemplateHomedir;
        char *szTemplateShell;
        char *szWinbindSeparator;
@@ -525,6 +527,7 @@ static BOOL handle_source_env(char *pszParmValue, char **ptr);
 static BOOL handle_netbios_name(char *pszParmValue, char **ptr);
 static BOOL handle_winbind_uid(char *pszParmValue, char **ptr);
 static BOOL handle_winbind_gid(char *pszParmValue, char **ptr);
+static BOOL handle_non_unix_account_range(char *pszParmValue, char **ptr);
 static BOOL handle_wins_server_list(char *pszParmValue, char **ptr);
 static BOOL handle_debug_list( char *pszParmValue, char **ptr );
 
@@ -693,6 +696,8 @@ static struct parm_struct parm_table[] = {
        {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
        {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, 0},
        {"passdb module path", P_STRING, P_GLOBAL, &Globals.szPassdbModulePath, NULL, NULL, 0},
+       {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, 0},
+       {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, 0},
        {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
        {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
        {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
@@ -1200,6 +1205,7 @@ static void init_globals(void)
        string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
        string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
        string_set(&Globals.szPassdbModulePath, "");
+       string_set(&Globals.szPassdbBackend, "smbpasswd");
 
        string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
 
@@ -1454,6 +1460,7 @@ FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
 FN_GLOBAL_STRING(lp_passdb_module_path, &Globals.szPassdbModulePath)
+FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
@@ -2444,7 +2451,7 @@ static BOOL handle_copy(char *pszParmValue, char **ptr)
 }
 
 /***************************************************************************
- Handle winbind uid and gid allocation parameters.  The format of these
+ Handle winbind/non unix account uid and gid allocation parameters.  The format of these
  parameters is:
 
  [global]
@@ -2461,6 +2468,7 @@ static BOOL handle_copy(char *pszParmValue, char **ptr)
 
 static uid_t winbind_uid_low, winbind_uid_high;
 static gid_t winbind_gid_low, winbind_gid_high;
+static uint32 non_unix_account_low, non_unix_account_high;
 
 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
 {
@@ -2490,6 +2498,20 @@ BOOL lp_winbind_gid(gid_t *low, gid_t *high)
         return True;
 }
 
+BOOL lp_non_unix_account_range(uint32 *low, uint32 *high)
+{
+        if (non_unix_account_low == 0 || non_unix_account_high == 0)
+                return False;
+
+        if (low)
+                *low = non_unix_account_low;
+
+        if (high)
+                *high = non_unix_account_high;
+
+        return True;
+}
+
 /* Do some simple checks on "winbind [ug]id" parameter values */
 
 static BOOL handle_winbind_uid(char *pszParmValue, char **ptr)
@@ -2526,6 +2548,25 @@ static BOOL handle_winbind_gid(char *pszParmValue, char **ptr)
        return True;
 }
 
+/* Do some simple checks on "non unix account range" parameter values */
+
+static BOOL handle_non_unix_account_range(char *pszParmValue, char **ptr)
+{
+       uint32 low, high;
+
+       if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
+               return False;
+
+       /* Parse OK */
+
+       string_set(ptr, pszParmValue);
+
+        non_unix_account_low = low;
+        non_unix_account_high = high;
+
+       return True;
+}
+
 /***************************************************************************
  Handle the WINS SERVER list
 ***************************************************************************/
index 4460af05450b07663b9c6a74b4279fe071275b96..2bb4ee0a7580273b0927a65378a80f9b1b98c703 100644 (file)
 
 extern DOM_SID global_sam_sid;
 
-struct passdb_ops *pdb_ops;
-
-#if 0  /* JERRY */
-static void* pdb_handle = NULL;
-#endif
-
-/***************************************************************
- Initialize the password db operations.
-***************************************************************/
-
-BOOL initialize_password_db(BOOL reload)
-{      
-       /* 
-        * This function is unfinished right now, so just 
-        * ignore the details and always return True.  It 
-        * is here only as a placeholder          --jerry 
-        */
-       return True;
-       
-}
-
-
 /************************************************************
  Fill the SAM_ACCOUNT with default values.
  ***********************************************************/
@@ -639,6 +617,7 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
        DOM_SID local_sid;
        fstring user;
        fstring domain;
+       SAM_ACCOUNT *sam_account = NULL;
 
        *psid_name_use = SID_NAME_UNKNOWN;
 
@@ -671,9 +650,20 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
 
        (void)map_username(user);
 
-       if((pass = Get_Pwnam(user))) {
+       if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
+               return False;
+       }
+       
+       if (pdb_getsampwnam(sam_account, user)) {
+               sid_append_rid( &local_sid, pdb_get_user_rid(sam_account));
+               *psid_name_use = SID_NAME_USER;
+               pdb_free_sam(&sam_account);
+
+       } else if((pass = Get_Pwnam(user))) {
                sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
                *psid_name_use = SID_NAME_USER;
+               pdb_free_sam(&sam_account);
+
        } else {
                /*
                 * Maybe it was a group ?
@@ -681,6 +671,8 @@ BOOL local_lookup_name(const char *c_domain, const char *c_user, DOM_SID *psid,
                struct group *grp;
                GROUP_MAP map;
                
+               pdb_free_sam(&sam_account);
+
                /* check if it's a mapped group */
                if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
                        if (map.gid!=-1) {
@@ -1021,29 +1013,33 @@ BOOL local_password_change(const char *user_name, int local_flags,
                pdb_free_sam(&sam_pass);
                
                if (local_flags & LOCAL_ADD_USER) {
-                       /*
-                        * Check for a local account - if we're adding only.
-                        */
-                       
-                       if(!(pwd = getpwnam_alloc(user_name))) {
-                               slprintf(err_str, err_str_len - 1, "User %s does not \
-exist in system password file (usually /etc/passwd). Cannot add \
-account without a valid local system user.\n", user_name);
-                               return False;
-                       }
+                       pwd = getpwnam_alloc(user_name);
                } else {
                        slprintf(err_str, err_str_len-1,"Failed to find entry for user %s.\n", user_name);
                        return False;
                }
-
-               if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sam_pass, pwd))){
-                       slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
+               
+               if (pwd) {
+                       /* Local user found, so init from this */
+                       if (!NT_STATUS_IS_OK(pdb_init_sam_pw(&sam_pass, pwd))){
+                               slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
+                               passwd_free(&pwd);
+                               return False;
+                       }
+               
                        passwd_free(&pwd);
-                       return False;
+               } else {
+                       if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_pass))){
+                               slprintf(err_str, err_str_len-1, "Failed initialise SAM_ACCOUNT for user %s.\n", user_name);
+                               return False;
+                       }
+
+                       if (!pdb_set_username(sam_pass, user_name)) {
+                               slprintf(err_str, err_str_len - 1, "Failed to set username for user %s.\n", user_name);
+                               pdb_free_sam(&sam_pass);
+                               return False;
+                       }
                }
-               
-               passwd_free(&pwd);
-       
                if (local_flags & LOCAL_TRUST_ACCOUNT) {
                        if (!pdb_set_acct_ctrl(sam_pass, ACB_WSTRUST)) {
                                slprintf(err_str, err_str_len - 1, "Failed to set 'trusted workstation account' flags for user %s.\n", user_name);
@@ -1135,14 +1131,14 @@ account without a valid local system user.\n", user_name);
                        return False;
                }
        } else if (local_flags & LOCAL_DELETE_USER) {
-               if (!pdb_delete_sam_account(user_name)) {
+               if (!pdb_delete_sam_account(sam_pass)) {
                        slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
                        pdb_free_sam(&sam_pass);
                        return False;
                }
                slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
        } else {
-               if(!pdb_update_sam_account(sam_pass, True)) {
+               if(!pdb_update_sam_account(sam_pass)) {
                        slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
                        pdb_free_sam(&sam_pass);
                        return False;
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
new file mode 100644 (file)
index 0000000..b5e7273
--- /dev/null
@@ -0,0 +1,368 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0
+   Password and authentication handling
+   Copyright (C) Andrew Bartlett                   2002
+      
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/** List of various built-in passdb modules */
+
+const struct pdb_init_function builtin_pdb_init_functions[] = {
+       { "smbpasswd", pdb_init_smbpasswd },
+       { "smbpasswd_nua", pdb_init_smbpasswd_nua },
+       { "tdbsam", pdb_init_tdbsam },
+       { "tdbsam_nua", pdb_init_tdbsam_nua },
+#if 0
+       { "ldap", pdb_init_ldap },
+       { "nisplus", pdb_init_nisplus },        
+       { "unix", pdb_init_unix },
+#endif
+       { NULL, NULL}
+};
+
+static BOOL context_setsampwent(struct pdb_context *context, BOOL update)
+{
+       if ((!context) || (!context->pdb_selected)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+       
+       return context->pdb_selected->setsampwent(context, update);
+}
+
+static void context_endsampwent(struct pdb_context *context)
+{
+       if ((!context) || (!context->pdb_selected)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return;
+       }
+       
+       context->pdb_selected->endsampwent(context);
+}
+
+static BOOL context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
+{
+       if ((!context) || (!context->pdb_selected)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+       
+       return context->pdb_selected->getsampwent(context, user);
+}
+
+static BOOL context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
+{
+       if ((!context) || (!context->pdb_selected)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+       
+       return context->pdb_selected->getsampwnam(context, sam_acct, username);
+}
+
+static BOOL context_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, uint32 rid)
+{
+       if ((!context) || (!context->pdb_selected)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+       
+       return context->pdb_selected->getsampwrid(context, sam_acct, rid);
+}
+
+static BOOL context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
+{
+       if ((!context) || (!context->pdb_selected)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+       
+       /** @todo  This is where a 're-read on add' should be done */
+  
+       return context->pdb_selected->add_sam_account(context, sam_acct);
+}
+
+static BOOL context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
+{
+       if ((!context) || (!context->pdb_selected)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+       
+       /** @todo  This is where a 're-read on update' should be done */
+       
+       return context->pdb_selected->update_sam_account(context, sam_acct);
+}
+
+static BOOL context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
+{
+       if ((!context) || (!context->pdb_selected)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+       
+       return context->pdb_selected->delete_sam_account(context, sam_acct);
+}
+
+static void free_pdb_context(struct pdb_context **context) 
+{
+       if (((*context)->pdb_selected) && ((*context)->pdb_selected->free_private_data)) {
+               (*context)->pdb_selected->free_private_data((*context)->pdb_selected->private_data);
+       }
+
+       talloc_destroy((*context)->mem_ctx);
+       *context = NULL;
+}
+
+/******************************************************************
+ Make a pdb_context from scratch.
+*******************************************************************/
+
+static NTSTATUS make_pdb_context(struct pdb_context **context) 
+{
+       TALLOC_CTX *mem_ctx;
+       
+       mem_ctx = talloc_init_named("pdb_context internal allocation context");
+
+       if (!mem_ctx) {
+               DEBUG(0, ("make_pdb_context: talloc init failed!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }               
+
+       *context = talloc(mem_ctx, sizeof(**context));
+       if (!*context) {
+               DEBUG(0, ("make_pdb_context: talloc failed!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       ZERO_STRUCTP(*context);
+
+       (*context)->mem_ctx = mem_ctx;
+
+       (*context)->pdb_setsampwent = context_setsampwent;
+       (*context)->pdb_endsampwent = context_endsampwent;
+       (*context)->pdb_getsampwent = context_getsampwent;
+       (*context)->pdb_getsampwnam = context_getsampwnam;
+       (*context)->pdb_getsampwrid = context_getsampwrid;
+       (*context)->pdb_add_sam_account = context_add_sam_account;
+       (*context)->pdb_update_sam_account = context_update_sam_account;
+       (*context)->pdb_delete_sam_account = context_delete_sam_account;
+
+       (*context)->free_fn = free_pdb_context;
+       
+       return NT_STATUS_OK;
+}
+
+
+/******************************************************************
+ Make a pdb_context, given a text string.
+*******************************************************************/
+
+NTSTATUS make_pdb_context_name(struct pdb_context **context, char *selected) 
+{
+       /* HINT: Don't store 'selected' becouse its often an lp_ string and will 'go away' */
+       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+       int i;
+       
+       if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) {
+               return nt_status;
+       }
+       
+       DEBUG(5,("Attempting to find an passdb backend to match %s\n", selected));
+       for (i = 0; builtin_pdb_init_functions[i].name; i++)
+       {
+               if (strequal(builtin_pdb_init_functions[i].name, selected))
+               {
+                       DEBUG(5,("Found pdb backend %s (at pos %d)\n", selected, i));
+                       if (NT_STATUS_IS_OK(nt_status 
+                                           = builtin_pdb_init_functions[i].init(*context, &(*context)->pdb_selected, NULL))) {
+                               DEBUG(5,("pdb backend %s has a valid init\n", selected));
+                               (*context)->pdb_selected->name = builtin_pdb_init_functions[i].name;
+                       } else {
+                               DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, get_nt_error_msg(nt_status)));
+                               (*context)->pdb_selected = NULL;
+                       }
+                       break;
+               }
+       }
+       
+       if (!(*context)->pdb_selected) {
+               DEBUG(0,("failed to select passdb backed!\n"));
+               talloc_destroy((*context)->mem_ctx);
+               *context = NULL;
+               return nt_status;
+       }
+
+       return NT_STATUS_OK;
+}
+
+
+/******************************************************************
+ Return an already initilised pdb_context, to facilitate backward 
+ compatiablity (see functions below).
+*******************************************************************/
+
+static struct pdb_context *pdb_get_static_context(BOOL reload) 
+{
+       static struct pdb_context *pdb_context = NULL;
+       
+       if ((pdb_context) && (reload)) {
+               pdb_context->free_fn(&pdb_context);
+               if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) {
+                       return NULL;
+               }
+       }
+       
+       if (!pdb_context) {
+               if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) {
+                       return NULL;
+               }
+       }
+       
+       return pdb_context;
+}
+
+#if !defined(WITH_LDAP_SAM) && !defined(WITH_NISPLUS_SAM)
+
+/******************************************************************
+ Backward compatability functions for the original passdb interface
+*******************************************************************/
+
+BOOL pdb_setsampwent(BOOL update) 
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return False;
+       }
+
+       return pdb_context->pdb_setsampwent(pdb_context, update);
+}
+
+void pdb_endsampwent(void) 
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return;
+       }
+
+       pdb_context->pdb_endsampwent(pdb_context);
+}
+
+BOOL pdb_getsampwent(SAM_ACCOUNT *user) 
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return False;
+       }
+
+       return pdb_context->pdb_getsampwent(pdb_context, user);
+}
+
+BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username) 
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return False;
+       }
+
+       return pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username);
+}
+
+BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct, uint32 rid) 
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return False;
+       }
+
+       return pdb_context->pdb_getsampwrid(pdb_context, sam_acct, rid);
+}
+
+BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) 
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return False;
+       }
+
+       return pdb_context->pdb_add_sam_account(pdb_context, sam_acct);
+}
+
+BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct) 
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (!pdb_context) {
+               return False;
+       }
+
+       return pdb_context->pdb_update_sam_account(pdb_context, sam_acct);
+}
+
+BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct) 
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+       
+       if (!pdb_context) {
+               return False;
+       }
+       
+       return pdb_context->pdb_delete_sam_account(pdb_context, sam_acct);
+}
+
+#endif /* !defined(WITH_LDAP_SAM) && !defined(WITH_NISPLUS_SAM) */
+
+/***************************************************************
+ Initialize the static context (at smbd startup etc). 
+
+ If uninitialised, context will auto-init on first use.
+***************************************************************/
+
+BOOL initialize_password_db(BOOL reload)
+{      
+       return (pdb_get_static_context(reload) != NULL);
+}
+
+
+NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) 
+{
+       *methods = talloc(mem_ctx, sizeof(struct pdb_methods));
+
+       if (!*methods) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       ZERO_STRUCTP(*methods);
+
+       return NT_STATUS_OK;
+}
+
+
+
+
+
+
+
+
index b687f494cc40655025611b93718fbe56588758fe..4e602cae404c2751eacc695fb8990277507c1edc 100644 (file)
@@ -840,14 +840,22 @@ BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
 /**********************************************************************
 Delete entry from LDAP for username 
 *********************************************************************/
-BOOL pdb_delete_sam_account(const char *sname)
+BOOL pdb_delete_sam_account(SAM_ACCOUNT * sam_acct)
 {
+       const char *sname;
        int rc;
        char *dn;
        LDAP *ldap_struct;
        LDAPMessage *entry;
        LDAPMessage *result;
 
+       if (!sam_acct) {
+               DEBUG(0, ("sam_acct was NULL!\n"));
+               return False;
+       }
+
+       sname = pdb_get_username(sam_acct);
+
        if (!ldap_open_connection (&ldap_struct))
                return False;
 
@@ -891,7 +899,7 @@ BOOL pdb_delete_sam_account(const char *sname)
 /**********************************************************************
 Update SAM_ACCOUNT 
 *********************************************************************/
-BOOL pdb_update_sam_account(const SAM_ACCOUNT * newpwd, BOOL override)
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd)
 {
        int rc;
        char *dn;
@@ -952,7 +960,7 @@ BOOL pdb_update_sam_account(const SAM_ACCOUNT * newpwd, BOOL override)
 /**********************************************************************
 Add SAM_ACCOUNT to LDAP 
 *********************************************************************/
-BOOL pdb_add_sam_account(const SAM_ACCOUNT * newpwd)
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
 {
        int rc;
        pstring filter;
index 446ba0ce391ddb1458db2313c2e481facb16b908..687115733a54ac305c7942fca724d76b772f3539 100644 (file)
@@ -1039,14 +1039,22 @@ BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
 /*************************************************************************
  Routine to remove entry from the nisplus smbpasswd table
  *************************************************************************/
-BOOL pdb_delete_sam_account(const char *sname)
+BOOL pdb_delete_sam_account(SAM_ACCOUNT * user)
 {
+  const char *sname;
   char *pfile = lp_smb_passwd_file();
   pstring nisname;
   nis_result *result, *delresult;
   nis_object *obj;
   int i;
-  
+  if (!user) {
+         DEBUG(0, ("no SAM_ACCOUNT specified!\n"));
+         return False;
+  }
+
+  suser = pdb_get_username(user);
+
   if (!*pfile)
     {
       DEBUG(0, ("no SMB password file set\n"));
@@ -1095,7 +1103,7 @@ BOOL pdb_delete_sam_account(const char *sname)
 /************************************************************************
  Routine to add an entry to the nisplus passwd file.
 *************************************************************************/
-BOOL pdb_add_sam_account(const SAM_ACCOUNT * newpwd)
+BOOL pdb_add_sam_account(SAM_ACCOUNT * newpwd)
 {
   int local_user = 0;
   char           *pfile;
@@ -1290,7 +1298,7 @@ BOOL pdb_add_sam_account(const SAM_ACCOUNT * newpwd)
 /************************************************************************
  Routine to modify the nisplus passwd entry.
 ************************************************************************/
-BOOL pdb_update_sam_account(const SAM_ACCOUNT * newpwd, BOOL override)
+BOOL pdb_update_sam_account(SAM_ACCOUNT * newpwd)
 {
   nis_result *result, *addresult;
   nis_object *obj;
index a464312ad6b2808bc6525d1a89e3bbca8c6a3f2e..3039e6681c900714fbb8a360a44cd829c097ec10 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (C) Andrew Tridgell 1992-1998 
  * Modified by Jeremy Allison 1995.
  * Modified by Gerald (Jerry) Carter 2000-2001
+ * Modified by Andrew Bartlett 2002.
  * 
  * This program is free software; you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free
@@ -22,8 +23,6 @@
 
 #include "includes.h"
 
-#ifdef WITH_SMBPASSWD_SAM
-
 
 /* 
    smb_passwd is analogous to sam_passwd used everywhere
@@ -33,7 +32,8 @@
  
 struct smb_passwd
 {
-        uid_t smb_userid;     /* this is actually the unix uid_t */
+        BOOL smb_userid_set;     /* this is actually the unix uid_t */
+        uint32 smb_userid;     /* this is actually the unix uid_t */
         const char *smb_name;     /* username string */
 
         const unsigned char *smb_passwd; /* Null if no password */
@@ -43,13 +43,29 @@ struct smb_passwd
         time_t pass_last_set_time;    /* password last set time */
 };
 
+struct smbpasswd_privates
+{
+       /* used for maintain locks on the smbpasswd file */
+       int     pw_file_lock_depth;
+       
+       /* Global File pointer */
+       FILE    *pw_file;
+       
+       /* formerly static variables */
+       struct smb_passwd pw_buf;
+       pstring  user_name;
+       unsigned char smbpwd[16];
+       unsigned char smbntpwd[16];
 
-extern struct passdb_ops pdb_ops;
+       /* retrive-once info */
+       const char *smbpasswd_file;
 
-/* used for maintain locks on the smbpasswd file */
-static int     pw_file_lock_depth;
-static void    *global_vp;
+       BOOL permit_non_unix_accounts;
 
+       uint32 low_nua_userid; 
+       uint32 high_nua_userid; 
+
+};
 
 enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE };
 
@@ -116,7 +132,7 @@ static void pdb_init_smb(struct smb_passwd *user)
  been granted to prevent race conditions. JRA.
 ****************************************************************/
 
-static void *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int *lock_depth)
+static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int *lock_depth)
 {
   FILE *fp = NULL;
   const char *open_mode = NULL;
@@ -238,15 +254,14 @@ Error was %s\n.", pfile, strerror(errno) ));
   }
 
   /* We have a lock on the file. */
-  return (void *)fp;
+  return fp;
 }
 
 /***************************************************************
  End enumeration of the smbpasswd list.
 ****************************************************************/
-static void endsmbfilepwent(void *vp, int *lock_depth)
+static void endsmbfilepwent(FILE *fp, int *lock_depth)
 {
-  FILE *fp = (FILE *)vp;
 
   pw_file_unlock(fileno(fp), lock_depth);
   fclose(fp);
@@ -257,14 +272,13 @@ static void endsmbfilepwent(void *vp, int *lock_depth)
  Routine to return the next entry in the smbpasswd list.
  *************************************************************************/
 
-static struct smb_passwd *getsmbfilepwent(void *vp)
+static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_state, FILE *fp)
 {
   /* Static buffers we will return. */
-  static struct smb_passwd pw_buf;
-  static pstring  user_name;
-  static unsigned char smbpwd[16];
-  static unsigned char smbntpwd[16];
-  FILE *fp = (FILE *)vp;
+  struct smb_passwd *pw_buf = &smbpasswd_state->pw_buf;
+  char  *user_name = smbpasswd_state->user_name;
+  unsigned char *smbpwd = smbpasswd_state->smbpwd;
+  unsigned char *smbntpwd = smbpasswd_state->smbntpwd;
   char            linebuf[256];
   unsigned char   c;
   unsigned char  *p;
@@ -276,9 +290,9 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
     return NULL;
   }
 
-  pdb_init_smb(&pw_buf);
+  pdb_init_smb(pw_buf);
 
-  pw_buf.acct_ctrl = ACB_NORMAL;  
+  pw_buf->acct_ctrl = ACB_NORMAL;  
 
   /*
    * Scan the file, a line at a time and check if the name matches.
@@ -370,8 +384,8 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
       continue;
     }
 
-    pw_buf.smb_name = user_name;
-    pw_buf.smb_userid = uidval;
+    pw_buf->smb_name = user_name;
+    pw_buf->smb_userid = uidval;
 
     /*
      * Now get the password value - this should be 32 hex digits
@@ -385,10 +399,10 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
     if (*p == '*' || *p == 'X') {
       /* Password deliberately invalid - end here. */
       DEBUG(10, ("getsmbfilepwent: entry invalidated for user %s\n", user_name));
-      pw_buf.smb_nt_passwd = NULL;
-      pw_buf.smb_passwd = NULL;
-      pw_buf.acct_ctrl |= ACB_DISABLED;
-      return &pw_buf;
+      pw_buf->smb_nt_passwd = NULL;
+      pw_buf->smb_passwd = NULL;
+      pw_buf->acct_ctrl |= ACB_DISABLED;
+      return pw_buf;
     }
 
     if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
@@ -402,28 +416,28 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
     }
 
     if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
-      pw_buf.smb_passwd = NULL;
-      pw_buf.acct_ctrl |= ACB_PWNOTREQ;
+      pw_buf->smb_passwd = NULL;
+      pw_buf->acct_ctrl |= ACB_PWNOTREQ;
     } else {
       if (!pdb_gethexpwd((char *)p, smbpwd)) {
         DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
         continue;
       }
-      pw_buf.smb_passwd = smbpwd;
+      pw_buf->smb_passwd = smbpwd;
     }
 
     /* 
      * Now check if the NT compatible password is
      * available.
      */
-    pw_buf.smb_nt_passwd = NULL;
+    pw_buf->smb_nt_passwd = NULL;
 
     p += 33; /* Move to the first character of the line after
                 the lanman password. */
     if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
       if (*p != '*' && *p != 'X') {
         if(pdb_gethexpwd((char *)p,smbntpwd))
-          pw_buf.smb_nt_passwd = smbntpwd;
+          pw_buf->smb_nt_passwd = smbntpwd;
       }
       p += 33; /* Move to the first character of the line after
                   the NT password. */
@@ -435,11 +449,11 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
     if (*p == '[')
        {
       unsigned char *end_p = (unsigned char *)strchr_m((char *)p, ']');
-      pw_buf.acct_ctrl = pdb_decode_acct_ctrl((char*)p);
+      pw_buf->acct_ctrl = pdb_decode_acct_ctrl((char*)p);
 
       /* Must have some account type set. */
-      if(pw_buf.acct_ctrl == 0)
-        pw_buf.acct_ctrl = ACB_NORMAL;
+      if(pw_buf->acct_ctrl == 0)
+        pw_buf->acct_ctrl = ACB_NORMAL;
 
       /* Now try and get the last change time. */
       if(end_p)
@@ -459,7 +473,7 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
              * read into a time_t as the seconds since
              * 1970 that the password was last changed.
              */
-            pw_buf.pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
+            pw_buf->pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
           }
         }
       }
@@ -470,13 +484,13 @@ static struct smb_passwd *getsmbfilepwent(void *vp)
        * password file as 'normal accounts'. If this changes
        * we will have to fix this code. JRA.
        */
-      if(pw_buf.smb_name[strlen(pw_buf.smb_name) - 1] == '$') {
-        pw_buf.acct_ctrl &= ~ACB_NORMAL;
-        pw_buf.acct_ctrl |= ACB_WSTRUST;
+      if(pw_buf->smb_name[strlen(pw_buf->smb_name) - 1] == '$') {
+        pw_buf->acct_ctrl &= ~ACB_NORMAL;
+        pw_buf->acct_ctrl |= ACB_WSTRUST;
       }
     }
 
-    return &pw_buf;
+    return pw_buf;
   }
 
   DEBUG(5,("getsmbfilepwent: end of file reached.\n"));
@@ -547,9 +561,9 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
  Routine to add an entry to the smbpasswd file.
 *************************************************************************/
 
-static BOOL add_smbfilepwd_entry(const struct smb_passwd *newpwd)
+static BOOL add_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, struct smb_passwd *newpwd)
 {
-  char *pfile = lp_smb_passwd_file();
+  const char *pfile = smbpasswd_state->smbpasswd_file;
   struct smb_passwd *pwd = NULL;
   FILE *fp = NULL;
   int wr_len;
@@ -557,13 +571,14 @@ static BOOL add_smbfilepwd_entry(const struct smb_passwd *newpwd)
   size_t new_entry_length;
   char *new_entry;
   SMB_OFF_T offpos;
-
+  uint32 max_found_uid = 0;
   /* Open the smbpassword file - for update. */
-  fp = startsmbfilepwent(pfile, PWF_UPDATE, &pw_file_lock_depth);
+  fp = startsmbfilepwent(pfile, PWF_UPDATE, &(smbpasswd_state->pw_file_lock_depth));
 
   if (fp == NULL && errno == ENOENT) {
        /* Try again - create. */
-       fp = startsmbfilepwent(pfile, PWF_CREATE, &pw_file_lock_depth);
+       fp = startsmbfilepwent(pfile, PWF_CREATE, &(smbpasswd_state->pw_file_lock_depth));
   }
 
   if (fp == NULL) {
@@ -575,18 +590,45 @@ static BOOL add_smbfilepwd_entry(const struct smb_passwd *newpwd)
    * Scan the file, a line at a time and check if the name matches.
    */
 
-  while ((pwd = getsmbfilepwent(fp)) != NULL) 
+  while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) 
   {
     if (strequal(newpwd->smb_name, pwd->smb_name)) 
     {
        DEBUG(0, ("add_smbfilepwd_entry: entry with name %s already exists\n", pwd->smb_name));
-       endsmbfilepwent(fp, &pw_file_lock_depth);
+       endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
        return False;
     }
-  }
+    
+    /* Look for a free uid for use in non-unix accounts */
+    if (pwd->smb_userid > max_found_uid) {
+           max_found_uid = pwd->smb_userid;
+    }
+   }
 
   /* Ok - entry doesn't exist. We can add it */
 
+  /* Account not in /etc/passwd hack!!! */
+  if (!newpwd->smb_userid_set) {
+         if (!smbpasswd_state->permit_non_unix_accounts) {
+                 DEBUG(0, ("add_smbfilepwd_entry: cannot add account %s without unix identity\n", pwd->smb_name));
+                 endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+                 return False;
+         }
+
+         if (max_found_uid < smbpasswd_state->low_nua_userid) {
+                 newpwd->smb_userid = smbpasswd_state->low_nua_userid;
+                 newpwd->smb_userid_set = True;
+         } else if (max_found_uid >= smbpasswd_state->high_nua_userid) {
+                 DEBUG(0, ("add_smbfilepwd_entry: cannot add machine %s, no uids are free! \n", newpwd->smb_name));
+                 endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
+                 return False;           
+         } else {
+                 newpwd->smb_userid = max_found_uid + 1;
+                 newpwd->smb_userid_set = True;
+         }
+  }
+
+
   /* Create a new smb passwd entry and set it to the given password. */
   /* 
    * The add user write needs to be atomic - so get the fd from 
@@ -598,7 +640,7 @@ static BOOL add_smbfilepwd_entry(const struct smb_passwd *newpwd)
   {
        DEBUG(0, ("add_smbfilepwd_entry(sys_lseek): Failed to add entry for user %s to file %s. \
 Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
-       endsmbfilepwent(fp, &pw_file_lock_depth);
+       endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
        return False;
   }
 
@@ -606,7 +648,7 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
   {
        DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \
 Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
-       endsmbfilepwent(fp, &pw_file_lock_depth);
+       endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
        return False;
   }
 
@@ -630,13 +672,13 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
                newpwd->smb_name, strerror(errno)));
        }
 
-       endsmbfilepwent(fp, &pw_file_lock_depth);
+       endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
        free(new_entry);
        return False;
   }
 
   free(new_entry);
-  endsmbfilepwent(fp, &pw_file_lock_depth);
+  endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
   return True;
 }
 
@@ -649,10 +691,10 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
  override = True, override XXXXXXXX'd out password or NO PASS
 ************************************************************************/
 
-static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
+static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd)
 {
   /* Static buffers we will return. */
-  static pstring  user_name;
+  char * user_name = smbpasswd_state->user_name;
 
   char            linebuf[256];
   char            readbuf[1024];
@@ -663,7 +705,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
   size_t            linebuf_len = 0;
   FILE           *fp;
   int             lockfd;
-  char           *pfile = lp_smb_passwd_file();
+  const char     *pfile = smbpasswd_state->smbpasswd_file;
   BOOL found_entry = False;
   BOOL got_pass_last_set_time = False;
 
@@ -690,7 +732,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
 
   lockfd = fileno(fp);
 
-  if (!pw_file_lock(lockfd, F_WRLCK, 5, &pw_file_lock_depth)) {
+  if (!pw_file_lock(lockfd, F_WRLCK, 5, &(smbpasswd_state->pw_file_lock_depth))) {
     DEBUG(0, ("mod_smbfilepwd_entry: unable to lock file %s\n", pfile));
     fclose(fp);
     return False;
@@ -710,7 +752,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
 
     fgets(linebuf, sizeof(linebuf), fp);
     if (ferror(fp)) {
-      pw_file_unlock(lockfd, &pw_file_lock_depth);
+      pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
       fclose(fp);
       return False;
     }
@@ -779,7 +821,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
   }
 
   if (!found_entry) {
-    pw_file_unlock(lockfd, &pw_file_lock_depth);
+    pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
@@ -791,7 +833,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
 
   if (!isdigit(*p)) {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (uid not number)\n"));
-    pw_file_unlock(lockfd, &pw_file_lock_depth);
+    pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
@@ -800,7 +842,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
     p++;
   if (*p != ':') {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no : after uid)\n"));
-    pw_file_unlock(lockfd, &pw_file_lock_depth);
+    pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
@@ -815,30 +857,16 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
   /* Record exact password position */
   pwd_seekpos += PTR_DIFF(p, linebuf);
 
-  if (!override && (*p == '*' || *p == 'X')) {
-    /* Password deliberately invalid - end here. */
-    DEBUG(10, ("mod_smbfilepwd_entry: entry invalidated for user %s\n", user_name));
-    pw_file_unlock(lockfd, &pw_file_lock_depth);
-    fclose(fp);
-    return False;
-  }
-
   if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return (False);
   }
 
   if (p[32] != ':') {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
-    fclose(fp);
-    return False;
-  }
-
-  if (!override && (*p == '*' || *p == 'X')) {
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
@@ -849,14 +877,14 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
               the lanman password. */
   if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return (False);
   }
 
   if (p[32] != ':') {
     DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
@@ -966,7 +994,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
 
   if(wr_len > sizeof(linebuf)) {
     DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return (False);
   }
@@ -984,7 +1012,7 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
 
   if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
     DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
@@ -992,33 +1020,33 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
   /* Sanity check - ensure the areas we are writing are framed by ':' */
   if (read(fd, linebuf, wr_len+1) != wr_len+1) {
     DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
 
   if ((linebuf[0] != ':') || (linebuf[wr_len] != ':')) {
     DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
  
   if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) {
     DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
 
   if (write(fd, ascii_p16, wr_len) != wr_len) {
     DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile));
-    pw_file_unlock(lockfd,&pw_file_lock_depth);
+    pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
     fclose(fp);
     return False;
   }
 
-  pw_file_unlock(lockfd,&pw_file_lock_depth);
+  pw_file_unlock(lockfd,&(smbpasswd_state->pw_file_lock_depth));
   fclose(fp);
   return True;
 }
@@ -1027,9 +1055,9 @@ static BOOL mod_smbfilepwd_entry(const struct smb_passwd* pwd, BOOL override)
  Routine to delete an entry in the smbpasswd file by name.
 *************************************************************************/
 
-static BOOL del_smbfilepwd_entry(const char *name)
+static BOOL del_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const char *name)
 {
-  char *pfile = lp_smb_passwd_file();
+       const char *pfile = smbpasswd_state->smbpasswd_file;
   pstring pfile2;
   struct smb_passwd *pwd = NULL;
   FILE *fp = NULL;
@@ -1044,7 +1072,7 @@ static BOOL del_smbfilepwd_entry(const char *name)
    * it.
    */
 
-  if((fp = startsmbfilepwent(pfile, PWF_UPDATE, &pw_file_lock_depth)) == NULL) {
+  if((fp = startsmbfilepwent(pfile, PWF_UPDATE, &(smbpasswd_state->pw_file_lock_depth))) == NULL) {
     DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
     return False;
   }
@@ -1054,7 +1082,7 @@ static BOOL del_smbfilepwd_entry(const char *name)
    */
   if((fp_write = startsmbfilepwent(pfile2, PWF_CREATE, &pfile2_lockdepth)) == NULL) {
     DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
-    endsmbfilepwent(fp, &pw_file_lock_depth);
+    endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
     return False;
   }
 
@@ -1062,7 +1090,7 @@ static BOOL del_smbfilepwd_entry(const char *name)
    * Scan the file, a line at a time and check if the name matches.
    */
 
-  while ((pwd = getsmbfilepwent(fp)) != NULL) {
+  while ((pwd = getsmbfilepwent(smbpasswd_state, fp)) != NULL) {
     char *new_entry;
     size_t new_entry_length;
 
@@ -1080,7 +1108,7 @@ static BOOL del_smbfilepwd_entry(const char *name)
        DEBUG(0, ("del_smbfilepwd_entry(malloc): Failed to copy entry for user %s to file %s. \
 Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
        unlink(pfile2);
-       endsmbfilepwent(fp, &pw_file_lock_depth);
+       endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
        endsmbfilepwent(fp_write, &pfile2_lockdepth);
        return False;
     }
@@ -1092,7 +1120,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
        DEBUG(0, ("del_smbfilepwd_entry(write): Failed to copy entry for user %s to file %s. \
 Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
        unlink(pfile2);
-       endsmbfilepwent(fp, &pw_file_lock_depth);
+       endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
        endsmbfilepwent(fp_write, &pfile2_lockdepth);
        free(new_entry);
        return False;
@@ -1108,7 +1136,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
   if(fflush(fp_write) != 0) 
   {
        DEBUG(0, ("del_smbfilepwd_entry: Failed to flush file %s. Error was %s\n", pfile2, strerror(errno)));
-       endsmbfilepwent(fp, &pw_file_lock_depth);
+       endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
        endsmbfilepwent(fp_write,&pfile2_lockdepth);
        return False;
   }
@@ -1121,7 +1149,7 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
     unlink(pfile2);
   }
   
-  endsmbfilepwent(fp, &pw_file_lock_depth);
+  endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
   endsmbfilepwent(fp_write,&pfile2_lockdepth);
   return True;
 }
@@ -1134,21 +1162,27 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
 static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass)
 {
        uid_t uid;
-       gid_t gid;
 
        if (sampass == NULL) 
                return False;
-       uid = pdb_get_uid(sampass);
-       gid = pdb_get_gid(sampass);
 
-       if (!IS_SAM_UNIX_USER(sampass)) {
-               DEBUG(0,("build_sam_pass: Failing attempt to store user without a UNIX uid or gid. \n"));
-               return False;
-       }
+       ZERO_STRUCTP(smb_pw);
+        if (!IS_SAM_UNIX_USER(sampass)) {
+               smb_pw->smb_userid_set = False;
+               DEBUG(5,("build_sam_pass: storing user without a UNIX uid or gid. \n"));
+       } else {
+               smb_pw->smb_userid_set = True;
+               uid = pdb_get_uid(sampass);
 
-       ZERO_STRUCTP(smb_pw);
+               if (uid != pdb_user_rid_to_uid(pdb_get_user_rid(sampass))) {
+                       DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
+                       return False;
+               }
+
+               smb_pw->smb_userid=uid;
+        }
 
-       smb_pw->smb_userid=uid;
        smb_pw->smb_name=(const char*)pdb_get_username(sampass);
 
        smb_pw->smb_passwd=pdb_get_lanman_passwd(sampass);
@@ -1157,11 +1191,6 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
        smb_pw->acct_ctrl=pdb_get_acct_ctrl(sampass);
        smb_pw->pass_last_set_time=pdb_get_pass_last_set_time(sampass);
 
-       if (uid != pdb_user_rid_to_uid(pdb_get_user_rid(sampass))) {
-               DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
-               return False;
-       }
-
 #if 0
        /*
         * ifdef'out by JFM on 11/29/2001.
@@ -1187,7 +1216,7 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
 /*********************************************************************
  Create a SAM_ACCOUNT from a smb_passwd struct
  ********************************************************************/
-static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
+static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
 {
        struct passwd *pwfile;
        
@@ -1196,34 +1225,76 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw
                return False;
        }
                
-       /* Verify in system password file...
-          FIXME!!!  This is where we should look up an internal
-          mapping of allocated uid for machine accounts as well 
-          --jerry */ 
-       pwfile = getpwnam_alloc(pw_buf->smb_name);
-       if (pwfile == NULL) {
-               DEBUG(0,("build_sam_account: smbpasswd database is corrupt!  username %s not in unix passwd database!\n", pw_buf->smb_name));
-               return False;
-       }
-
-       pdb_set_uid (sam_pass, pwfile->pw_uid);
-       pdb_set_gid (sam_pass, pwfile->pw_gid);
+       if ((smbpasswd_state->permit_non_unix_accounts) 
+           && (pw_buf->smb_userid >= smbpasswd_state->low_nua_userid) 
+           && (pw_buf->smb_userid <= smbpasswd_state->high_nua_userid)) {
+
+               pdb_set_user_rid(sam_pass, pdb_uid_to_user_rid (pw_buf->smb_userid));
+
+               /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. 
+                  
+                  This was down the bottom for machines, but it looks pretty good as
+                  a general default for non-unix users. --abartlet 2002-01-08
+               */
+               pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); 
                
-       pdb_set_fullname(sam_pass, pwfile->pw_gecos);           
-       
-       pdb_set_user_rid(sam_pass, pdb_uid_to_user_rid (pwfile->pw_uid));
+       } else {
 
-       {
-               uint32 rid;
+               uint32 grid;
                GROUP_MAP map;
        
+               /* Verify in system password file...
+                  FIXME!!!  This is where we should look up an internal
+                  mapping of allocated uid for machine accounts as well 
+                  --jerry */ 
+               pwfile = getpwnam_alloc(pw_buf->smb_name);
+               if (pwfile == NULL) {
+                       DEBUG(0,("build_sam_account: smbpasswd database is corrupt!  username %s not in unix passwd database!\n", pw_buf->smb_name));
+                       return False;
+               }
+
+               pdb_set_uid (sam_pass, pwfile->pw_uid);
+               pdb_set_gid (sam_pass, pwfile->pw_gid);
+               
+               pdb_set_fullname(sam_pass, pwfile->pw_gecos);           
+       
+               pdb_set_user_rid(sam_pass, pdb_uid_to_user_rid (pwfile->pw_uid));
+
                if (get_group_map_from_gid(pwfile->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
-                       sid_peek_rid(&map.sid, &rid);
+                       sid_peek_rid(&map.sid, &grid);
+               } else { 
+                       grid=pdb_gid_to_group_rid(pwfile->pw_gid);
                }
-               else 
-                       rid=pdb_gid_to_group_rid(pwfile->pw_gid);
 
-               pdb_set_group_rid(sam_pass, rid); 
+               pdb_set_group_rid(sam_pass, grid); 
+
+               /* check if this is a user account or a machine account */
+               if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$')
+               {
+                       pstring         str;
+                       
+                       pstrcpy(str, lp_logon_path());
+                       standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
+                       pdb_set_profile_path(sam_pass, str, False);
+                       
+                       pstrcpy(str, lp_logon_home());
+                       standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
+                       pdb_set_homedir(sam_pass, str, False);
+                       
+                       pstrcpy(str, lp_logon_drive());
+                       standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
+                       pdb_set_dir_drive(sam_pass, str, False);
+                       
+                       pstrcpy(str, lp_logon_script());
+                       standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
+                       pdb_set_logon_script(sam_pass, str, False);
+                       
+               } else {
+                       /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
+                       /*pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); */
+               }
+               
+               passwd_free(&pwfile);
        }
        
        pdb_set_username (sam_pass, pw_buf->smb_name);
@@ -1243,84 +1314,61 @@ static BOOL build_sam_account(SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw
        */
        pdb_set_pass_must_change_time (sam_pass, pw_buf->pass_last_set_time + MAX_PASSWORD_AGE);
 #endif
-       /* check if this is a user account or a machine account */
-       if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$')
-       {
-               pstring         str;
-               
-               pstrcpy(str, lp_logon_path());
-               standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
-               pdb_set_profile_path(sam_pass, str, False);
-               
-               pstrcpy(str, lp_logon_home());
-               standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
-               pdb_set_homedir(sam_pass, str, False);
-               
-               pstrcpy(str, lp_logon_drive());
-               standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
-               pdb_set_dir_drive(sam_pass, str, False);
-               
-               pstrcpy(str, lp_logon_script());
-               standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
-               pdb_set_logon_script(sam_pass, str, False);
-               
-       } else {
-               /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
-               /*pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); */
-       }
-
-       passwd_free(&pwfile);
-       
        return True;
 }
+
 /*****************************************************************
  Functions to be implemented by the new passdb API 
  ****************************************************************/
-BOOL pdb_setsampwent (BOOL update)
+static BOOL smbpasswd_setsampwent (struct pdb_context *context, BOOL update)
 {
-       global_vp = startsmbfilepwent(lp_smb_passwd_file(), 
-                               update ? PWF_UPDATE : PWF_READ, 
-                               &pw_file_lock_depth);
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       
+       smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file, 
+                                                      update ? PWF_UPDATE : PWF_READ, 
+                                                      &(smbpasswd_state->pw_file_lock_depth));
                                   
        /* did we fail?  Should we try to create it? */
-       if (!global_vp && update && errno == ENOENT) 
+       if (!smbpasswd_state->pw_file && update && errno == ENOENT) 
        {
                FILE *fp;
                /* slprintf(msg_str,msg_str_len-1,
-                       "smbpasswd file did not exist - attempting to create it.\n"); */
+                  "smbpasswd file did not exist - attempting to create it.\n"); */
                DEBUG(0,("smbpasswd file did not exist - attempting to create it.\n"));
-               fp = sys_fopen(lp_smb_passwd_file(), "w");
+               fp = sys_fopen(smbpasswd_state->smbpasswd_file, "w");
                if (fp) 
                {
                        fprintf(fp, "# Samba SMB password file\n");
                        fclose(fp);
                }
                
-               global_vp = startsmbfilepwent(lp_smb_passwd_file()
-                                       update ? PWF_UPDATE : PWF_READ, 
-                                       &pw_file_lock_depth);
+               smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file
+                                                            update ? PWF_UPDATE : PWF_READ, 
+                                                            &(smbpasswd_state->pw_file_lock_depth));
        }
        
-       return (global_vp != NULL);                
+       return (smbpasswd_state->pw_file != NULL);                 
 }
 
-void pdb_endsampwent (void)
+static void smbpasswd_endsampwent (struct pdb_context *context)
 {
-       endsmbfilepwent(global_vp, &pw_file_lock_depth);
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+       endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth));
 }
  
 /*****************************************************************
  ****************************************************************/
-BOOL pdb_getsampwent(SAM_ACCOUNT *user)
+static BOOL smbpasswd_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
 {
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
        struct smb_passwd *pw_buf=NULL;
        BOOL done = False;
        DEBUG(5,("pdb_getsampwent\n"));
 
        if (user==NULL) {
-               DEBUG(5,("pdb_getsampwent: user is NULL\n"));
+               DEBUG(5,("pdb_getsampwent (smbpasswd): user is NULL\n"));
 #if 0
-               smb_panic("NULL pointer passed to pdb_getsampwent\n");
+               smb_panic("NULL pointer passed to getsampwent (smbpasswd)\n");
 #endif
                return False;
        }
@@ -1328,18 +1376,18 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
        while (!done)
        {
                /* do we have an entry? */
-               pw_buf = getsmbfilepwent(global_vp);
+               pw_buf = getsmbfilepwent(smbpasswd_state, smbpasswd_state->pw_file);
                if (pw_buf == NULL) 
                        return False;
 
                /* build the SAM_ACCOUNT entry from the smb_passwd struct. 
                   We loop in case the user in the pdb does not exist in 
                   the local system password file */
-               if (build_sam_account(user, pw_buf))
+               if (build_sam_account(smbpasswd_state, user, pw_buf))
                        done = True;
        }
 
-       DEBUG(5,("pdb_getsampwent:done\n"));
+       DEBUG(5,("getsampwent (smbpasswd): done\n"));
 
        /* success */
        return True;
@@ -1351,15 +1399,16 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
  call getpwnam() for unix account information until we have found
  the correct entry
  ***************************************************************/
-BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
+static BOOL smbpasswd_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
 {
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
        struct smb_passwd *smb_pw;
        void *fp = NULL;
        char *domain = NULL;
        char *user = NULL;
        fstring name;
 
-       DEBUG(10, ("pdb_getsampwnam: search by name: %s\n", username));
+       DEBUG(10, ("getsampwnam (smbpasswd): search by name: %s\n", username));
 
        
        /* break the username from the domain if we have 
@@ -1379,7 +1428,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
        /* startsmbfilepwent() is used here as we don't want to lookup
           the UNIX account in the local system password file until
           we have a match.  */
-       fp = startsmbfilepwent(lp_smb_passwd_file(), PWF_READ, &pw_file_lock_depth);
+       fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth));
 
        if (fp == NULL) {
                DEBUG(0, ("unable to open passdb database.\n"));
@@ -1391,20 +1440,20 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
        if ( domain )
                map_username(user);
 
-       while ( ((smb_pw=getsmbfilepwent(fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
+       while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
                /* do nothing....another loop */ ;
        
-       endsmbfilepwent(fp, &pw_file_lock_depth);
+       endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
 
 
        /* did we locate the username in smbpasswd  */
        if (smb_pw == NULL)
                return False;
        
-       DEBUG(10, ("pdb_getsampwnam: found by name: %s\n", smb_pw->smb_name));
+       DEBUG(10, ("getsampwnam (smbpasswd): found by name: %s\n", smb_pw->smb_name));
 
        if (!sam_acct) {
-               DEBUG(10,("pdb_getsampwnam:SAM_ACCOUNT is NULL\n"));
+               DEBUG(10,("getsampwnam (smbpasswd): SAM_ACCOUNT is NULL\n"));
 #if 0
                smb_panic("NULL pointer passed to pdb_getsampwnam\n");
 #endif
@@ -1412,7 +1461,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
        }
                
        /* now build the SAM_ACCOUNT */
-       if (!build_sam_account(sam_acct, smb_pw))
+       if (!build_sam_account(smbpasswd_state, sam_acct, smb_pw))
                return False;
 
        /* success */
@@ -1420,35 +1469,36 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
 }
 
 
-BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct,uint32 rid)
+static BOOL smbpasswd_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct,uint32 rid)
 {
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
        struct smb_passwd *smb_pw;
        void *fp = NULL;
 
        DEBUG(10, ("pdb_getsampwrid: search by rid: %d\n", rid));
 
        /* Open the sam password file - not for update. */
-       fp = startsmbfilepwent(lp_smb_passwd_file(), PWF_READ, &pw_file_lock_depth);
+       fp = startsmbfilepwent(smbpasswd_state->smbpasswd_file, PWF_READ, &(smbpasswd_state->pw_file_lock_depth));
 
        if (fp == NULL) {
                DEBUG(0, ("unable to open passdb database.\n"));
                return False;
        }
 
-       while ( ((smb_pw=getsmbfilepwent(fp)) != NULL) && (pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
+       while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
                /* do nothing */ ;
 
-       endsmbfilepwent(fp, &pw_file_lock_depth);
+       endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
 
 
        /* did we locate the username in smbpasswd  */
        if (smb_pw == NULL)
                return False;
        
-       DEBUG(10, ("pdb_getsampwrid: found by name: %s\n", smb_pw->smb_name));
+       DEBUG(10, ("getsampwrid (smbpasswd): found by name: %s\n", smb_pw->smb_name));
                
        if (!sam_acct) {
-               DEBUG(10,("pdb_getsampwrid:SAM_ACCOUNT is NULL\n"));
+               DEBUG(10,("getsampwrid: (smbpasswd) SAM_ACCOUNT is NULL\n"));
 #if 0
                smb_panic("NULL pointer passed to pdb_getsampwrid\n");
 #endif
@@ -1456,15 +1506,16 @@ BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct,uint32 rid)
        }
 
        /* now build the SAM_ACCOUNT */
-       if (!build_sam_account (sam_acct, smb_pw))
+       if (!build_sam_account (smbpasswd_state, sam_acct, smb_pw))
                return False;
 
        /* success */
        return True;
 }
 
-BOOL pdb_add_sam_account(const SAM_ACCOUNT *sampass)
+static BOOL smbpasswd_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass)
 {
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
        struct smb_passwd smb_pw;
        
        /* convert the SAM_ACCOUNT */
@@ -1473,15 +1524,16 @@ BOOL pdb_add_sam_account(const SAM_ACCOUNT *sampass)
        }
        
        /* add the entry */
-       if(!add_smbfilepwd_entry(&smb_pw)) {
+       if(!add_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {
                return False;
        }
-
+       
        return True;
 }
 
-BOOL pdb_update_sam_account(const SAM_ACCOUNT *sampass, BOOL override)
+static BOOL smbpasswd_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass)
 {
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
        struct smb_passwd smb_pw;
        
        /* convert the SAM_ACCOUNT */
@@ -1489,19 +1541,97 @@ BOOL pdb_update_sam_account(const SAM_ACCOUNT *sampass, BOOL override)
                return False;
        
        /* update the entry */
-       if(!mod_smbfilepwd_entry(&smb_pw, override))
+       if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw))
                return False;
                
        return True;
 }
 
-BOOL pdb_delete_sam_account (const char* username)
+static BOOL smbpasswd_delete_sam_account (struct pdb_context *context, const SAM_ACCOUNT *sampass)
 {
-       return del_smbfilepwd_entry(username);
+       struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+
+       const char *username = pdb_get_username(sampass);
+
+       return del_smbfilepwd_entry(smbpasswd_state, username);
+}
+
+static void free_private_data(void **vp) 
+{
+       struct smbpasswd_privates **privates = (struct smbpasswd_privates**)vp;
+       
+       endsmbfilepwent((*privates)->pw_file, &((*privates)->pw_file_lock_depth));
+       
+       *privates = NULL;
+       /* No need to free any further, as it is talloc()ed */
 }
 
-#else
- /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
- void smbpass_dummy_function(void) { } /* stop some compilers complaining */
-#endif /* WTH_SMBPASSWD_SAM*/
 
+NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+       NTSTATUS nt_status;
+       struct smbpasswd_privates *privates;
+
+       if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+               return nt_status;
+       }
+
+       (*pdb_method)->setsampwent = smbpasswd_setsampwent;
+       (*pdb_method)->endsampwent = smbpasswd_endsampwent;
+       (*pdb_method)->getsampwent = smbpasswd_getsampwent;
+       (*pdb_method)->getsampwnam = smbpasswd_getsampwnam;
+       (*pdb_method)->getsampwrid = smbpasswd_getsampwrid;
+       (*pdb_method)->add_sam_account = smbpasswd_add_sam_account;
+       (*pdb_method)->update_sam_account = smbpasswd_update_sam_account;
+       (*pdb_method)->delete_sam_account = smbpasswd_delete_sam_account;
+
+       /* Setup private data and free function */
+
+       privates = talloc_zero(pdb_context->mem_ctx, sizeof(struct smbpasswd_privates));
+
+       if (!privates) {
+               DEBUG(0, ("talloc() failed for smbpasswd private_data!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       /* Store some config details */
+
+       if (location) {
+               privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, location);
+       } else {
+               privates->smbpasswd_file = talloc_strdup(pdb_context->mem_ctx, lp_smb_passwd_file());
+       }
+       
+       if (!privates->smbpasswd_file) {
+               DEBUG(0, ("talloc_strdp() failed for storing smbpasswd location!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       (*pdb_method)->private_data = privates;
+
+
+       (*pdb_method)->free_private_data = free_private_data;
+
+       return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_init_smbpasswd_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+       NTSTATUS nt_status;
+       struct smbpasswd_privates *privates;
+
+       if (!NT_STATUS_IS_OK(nt_status = pdb_init_smbpasswd(pdb_context, pdb_method, location))) {
+               return nt_status;
+       }
+
+       privates = (*pdb_method)->private_data;
+       
+       privates->permit_non_unix_accounts = True;
+
+       if (!lp_non_unix_account_range(&privates->low_nua_userid, &privates->high_nua_userid)) {
+               DEBUG(0, ("cannot use smbpasswd_nua without 'non unix account range' in smb.conf!\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       return NT_STATUS_OK;
+}
index b33e684c7a17af3d22bd5ba05c01922072e795c0..0e0bf541e390e757cd3dad93173b21db6fce5bc9 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright (C) Simo Sorce 2000
  * Copyright (C) Gerald Carter 2000
  * Copyright (C) Jeremy Allison 2001
+ * Copyright (C) Andrew Bartlett 2002
  * 
  * This program is free software; you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free
 #define USERPREFIX             "USER_"
 #define RIDPREFIX              "RID_"
 
-extern int             DEBUGLEVEL;
-
-struct tdb_enum_info {
+struct tdbsam_privates {
        TDB_CONTEXT     *passwd_tdb;
        TDB_DATA        key;
-};
 
-static struct tdb_enum_info    global_tdb_ent;
-/*static SAM_ACCOUNT           global_sam_pass;*/
+       /* retrive-once info */
+       const char *tdbsam_location;
+
+       BOOL permit_non_unix_accounts;
+
+       uint32 low_nua_rid; 
+       uint32 high_nua_rid; 
+};
 
 /**********************************************************************
  Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
  *********************************************************************/
 
-static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
+static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
+                                 SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
 {
 
        /* times are stored as 32bit integer
@@ -150,8 +155,6 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 bufle
                goto done;
        }
 
-       /*pdb_set_uid(sampass, uid);
-       pdb_set_gid(sampass, gid);*/
        pdb_set_user_rid(sampass, user_rid);
        pdb_set_group_rid(sampass, group_rid);
        pdb_set_unknown_3(sampass, unknown_3);
@@ -162,6 +165,28 @@ static BOOL init_sam_from_buffer (SAM_ACCOUNT *sampass, uint8 *buf, uint32 bufle
        pdb_set_logon_divs(sampass, logon_divs);
        pdb_set_hours(sampass, hours);
 
+       if ((tdb_state->permit_non_unix_accounts) 
+           && (pdb_get_user_rid(sampass) >= tdb_state->low_nua_rid)
+           && (pdb_get_user_rid(sampass) <= tdb_state->high_nua_rid)) {
+               
+       } else {
+               struct passwd *pw;
+               /* validate the account and fill in UNIX uid and gid.  sys_getpwnam()
+                  is used instaed of Get_Pwnam() as we do not need to try case
+                  permutations */
+
+               if ((pw=getpwnam_alloc(pdb_get_username(sampass))) == NULL) {
+                       DEBUG(0,("init_sam_from_buffer: (tdbsam) getpwnam(%s) return NULL.  User does not exist!\n", 
+                                pdb_get_username(sampass)));
+                       return False;
+               }
+
+               pdb_set_uid(sampass, pw->pw_uid);
+               pdb_set_gid(sampass, pw->pw_gid);
+               
+               passwd_free(&pw);
+       }
+
 done:
 
        SAFE_FREE(username);
@@ -182,7 +207,8 @@ done:
 /**********************************************************************
  Intialize a BYTE buffer from a SAM_ACCOUNT struct
  *********************************************************************/
-static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
+static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state, uint8 **buf, 
+                                   const SAM_ACCOUNT *sampass, uint32 user_rid, uint32 group_rid)
 {
        size_t          len, buflen;
 
@@ -321,8 +347,8 @@ static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
                workstations_len, workstations,
                unknown_str_len, unknown_str,
                munged_dial_len, munged_dial,
-               pdb_get_user_rid(sampass),
-               pdb_get_group_rid(sampass),
+               user_rid,
+               group_rid,
                lm_pw_len, lm_pw,
                nt_pw_len, nt_pw,
                pdb_get_acct_ctrl(sampass),
@@ -360,8 +386,8 @@ static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
                workstations_len, workstations,
                unknown_str_len, unknown_str,
                munged_dial_len, munged_dial,
-               pdb_get_user_rid(sampass),
-               pdb_get_group_rid(sampass),
+               user_rid,
+               group_rid,
                lm_pw_len, lm_pw,
                nt_pw_len, nt_pw,
                pdb_get_acct_ctrl(sampass),
@@ -375,6 +401,8 @@ static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
        
        /* check to make sure we got it correct */
        if (buflen != len) {
+               DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n", 
+                         buflen, len));  
                /* error */
                SAFE_FREE (*buf);
                return (-1);
@@ -387,35 +415,38 @@ static uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass)
  Open the TDB passwd database for SAM account enumeration.
 ****************************************************************/
 
-BOOL pdb_setsampwent(BOOL update)
+static BOOL tdbsam_setsampwent(struct pdb_context *context, BOOL update)
 {
-       pstring         tdbfile;
-       
-       get_private_directory(tdbfile);
-       pstrcat (tdbfile, PASSDB_FILE_NAME);
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
        
        /* Open tdb passwd */
-       if (!(global_tdb_ent.passwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600)))
+       if (!(tdb_state->passwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600)))
        {
                DEBUG(0, ("Unable to open/create TDB passwd\n"));
                return False;
        }
        
-       global_tdb_ent.key = tdb_firstkey(global_tdb_ent.passwd_tdb);
+       tdb_state->key = tdb_firstkey(tdb_state->passwd_tdb);
 
        return True;
 }
 
+static void close_tdb(struct tdbsam_privates *tdb_state) 
+{
+       if (tdb_state->passwd_tdb) {
+               tdb_close(tdb_state->passwd_tdb);
+               tdb_state->passwd_tdb = NULL;
+       }
+}
+
 /***************************************************************
  End enumeration of the TDB passwd list.
 ****************************************************************/
 
-void pdb_endsampwent(void)
+static void tdbsam_endsampwent(struct pdb_context *context)
 {
-       if (global_tdb_ent.passwd_tdb) {
-               tdb_close(global_tdb_ent.passwd_tdb);
-               global_tdb_ent.passwd_tdb = NULL;
-       }
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+       close_tdb(tdb_state);
        
        DEBUG(7, ("endtdbpwent: closed sam database.\n"));
 }
@@ -424,17 +455,13 @@ void pdb_endsampwent(void)
  Get one SAM_ACCOUNT from the TDB (next in line)
 *****************************************************************/
 
-BOOL pdb_getsampwent(SAM_ACCOUNT *user)
+static BOOL tdbsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
 {
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
        TDB_DATA        data;
-       struct passwd   *pw;
-       uid_t           uid;
-       gid_t           gid;
        char *prefix = USERPREFIX;
        int  prefixlen = strlen (prefix);
 
-       const char *sam_user;
-       pstring sam_subst;
 
        if (user==NULL) {
                DEBUG(0,("pdb_get_sampwent: SAM_ACCOUNT is NULL.\n"));
@@ -442,62 +469,32 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
        }
 
        /* skip all non-USER entries (eg. RIDs) */
-       while ((global_tdb_ent.key.dsize != 0) && (strncmp(global_tdb_ent.key.dptr, prefix, prefixlen)))
+       while ((tdb_state->key.dsize != 0) && (strncmp(tdb_state->key.dptr, prefix, prefixlen)))
                /* increment to next in line */
-               global_tdb_ent.key = tdb_nextkey(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
+               tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
 
        /* do we have an valid interation pointer? */
-       if(global_tdb_ent.passwd_tdb == NULL) {
+       if(tdb_state->passwd_tdb == NULL) {
                DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
                return False;
        }
 
-       data = tdb_fetch(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
+       data = tdb_fetch(tdb_state->passwd_tdb, tdb_state->key);
        if (!data.dptr) {
                DEBUG(5,("pdb_getsampwent: database entry not found.\n"));
                return False;
        }
   
        /* unpack the buffer */
-       if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
+       if (!init_sam_from_buffer(tdb_state, user, data.dptr, data.dsize)) {
                DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
                SAFE_FREE(data.dptr);
                return False;
        }
        SAFE_FREE(data.dptr);
        
-       /* validate the account and fill in UNIX uid and gid.  sys_getpwnam()
-          is used instaed of Get_Pwnam() as we do not need to try case
-          permutations */
-       if ((pw=getpwnam_alloc(pdb_get_username(user))) == NULL) {
-               DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL.  User does not exist!\n", 
-                         pdb_get_username(user)));
-               return False;
-       }
-
-       uid = pw->pw_uid;
-       gid = pw->pw_gid;
-       pdb_set_uid(user, uid);
-       pdb_set_gid(user, gid);
-
-       passwd_free(&pw);
-
-       /* 21 days from present */
-       pdb_set_pass_must_change_time(user, time(NULL)+1814400);
-
-       sam_user = pdb_get_username(user);
-       pstrcpy(sam_subst, pdb_get_logon_script(user));
-       standard_sub_advanced(-1, sam_user, "", gid, sam_user, sam_subst);
-       if (!pdb_set_logon_script(user, sam_subst, True)) return False;
-       pstrcpy(sam_subst, pdb_get_profile_path(user));
-       standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_username(user), sam_subst);
-       if (!pdb_set_profile_path(user, sam_subst, True)) return False;
-       pstrcpy(sam_subst, pdb_get_homedir(user));
-       standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_username(user), sam_subst);
-       if (!pdb_set_homedir(user, sam_subst, True)) return False;
-
        /* increment to next in line */
-       global_tdb_ent.key = tdb_nextkey(global_tdb_ent.passwd_tdb, global_tdb_ent.key);
+       tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
 
        return True;
 }
@@ -506,19 +503,13 @@ BOOL pdb_getsampwent(SAM_ACCOUNT *user)
  Lookup a name in the SAM TDB
 ******************************************************************/
 
-BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
+static BOOL tdbsam_getsampwnam (struct pdb_context *context, SAM_ACCOUNT *user, const char *sname)
 {
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
        TDB_CONTEXT     *pwd_tdb;
        TDB_DATA        data, key;
        fstring         keystr;
-       struct passwd   *pw;
-       pstring         tdbfile;
        fstring         name;
-       uid_t           uid;
-       gid_t           gid;
-
-       const char *sam_user;
-       pstring sam_subst;
 
        if (user==NULL) {
                DEBUG(0,("pdb_getsampwnam: SAM_ACCOUNT is NULL.\n"));
@@ -528,17 +519,14 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
        /* Data is stored in all lower-case */
        unix_strlower(sname, -1, name, sizeof(name));
 
-       get_private_directory(tdbfile);
-       pstrcat(tdbfile, PASSDB_FILE_NAME);
-       
        /* set search key */
        slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
        key.dptr = keystr;
        key.dsize = strlen(keystr) + 1;
 
        /* open the accounts TDB */
-       if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
-               DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd!\n"));
+       if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
+               DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
                return False;
        }
 
@@ -547,12 +535,13 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
        if (!data.dptr) {
                DEBUG(5,("pdb_getsampwnam (TDB): error fetching database.\n"));
                DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
+               DEBUGADD(5, (" Key: %s\n", keystr));
                tdb_close(pwd_tdb);
                return False;
        }
   
        /* unpack the buffer */
-       if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
+       if (!init_sam_from_buffer(tdb_state, user, data.dptr, data.dsize)) {
                DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
                SAFE_FREE(data.dptr);
                tdb_close(pwd_tdb);
@@ -563,37 +552,6 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
        /* no further use for database, close it now */
        tdb_close(pwd_tdb);
        
-       /* validate the account and fill in UNIX uid and gid.  sys_getpwnam()
-          is used instead of Get_Pwnam() as we do not need to try case
-          permutations */
-       if ((pw=getpwnam_alloc(pdb_get_username(user)))) {
-               uid = pw->pw_uid;
-               gid = pw->pw_gid;
-               pdb_set_uid(user, uid);
-               pdb_set_gid(user, gid);
-
-               /* 21 days from present */
-               pdb_set_pass_must_change_time(user, time(NULL)+1814400);
-
-               sam_user = pdb_get_username(user);
-               pstrcpy(sam_subst, pdb_get_logon_script(user));
-               standard_sub_advanced(-1, sam_user, "", gid, sam_user, sam_subst);
-               if (!pdb_set_logon_script(user, sam_subst, True)) return False;
-               pstrcpy(sam_subst, pdb_get_profile_path(user));
-               standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_username(user), sam_subst);
-               if (!pdb_set_profile_path(user, sam_subst, True)) return False;
-               pstrcpy(sam_subst, pdb_get_homedir(user));
-               standard_sub_advanced(-1, pdb_get_username(user), "", gid, pdb_get_username(user), sam_subst);
-               if (!pdb_set_homedir(user, sam_subst, True)) return False;
-       }
-       else {
-               DEBUG(0,("pdb_getsampwent: getpwnam(%s) return NULL.  User does not exist!\n", 
-                         pdb_get_username(user)));
-               return False;
-       }
-
-       passwd_free(&pw);
-
        return True;
 }
 
@@ -601,12 +559,12 @@ BOOL pdb_getsampwnam (SAM_ACCOUNT *user, const char *sname)
  Search by rid
  **************************************************************************/
 
-BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
+static BOOL tdbsam_getsampwrid (struct pdb_context *context, SAM_ACCOUNT *user, uint32 rid)
 {
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
        TDB_CONTEXT             *pwd_tdb;
        TDB_DATA                data, key;
        fstring                 keystr;
-       pstring                 tdbfile;
        fstring                 name;
        
        if (user==NULL) {
@@ -614,16 +572,13 @@ BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
                return False;
        }
 
-       get_private_directory(tdbfile);
-       pstrcat (tdbfile, PASSDB_FILE_NAME);
-       
        /* set search key */
        slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, rid);
        key.dptr = keystr;
        key.dsize = strlen (keystr) + 1;
 
        /* open the accounts TDB */
-       if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
+       if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
                DEBUG(0, ("pdb_getsampwrid: Unable to open TDB rid database!\n"));
                return False;
        }
@@ -642,30 +597,26 @@ BOOL pdb_getsampwrid (SAM_ACCOUNT *user, uint32 rid)
        
        tdb_close (pwd_tdb);
        
-       return pdb_getsampwnam (user, name);
+       return tdbsam_getsampwnam (context, user, name);
 }
 
 /***************************************************************************
  Delete a SAM_ACCOUNT
 ****************************************************************************/
 
-BOOL pdb_delete_sam_account(const char *sname)
+static BOOL tdbsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sam_pass)
 {
-       SAM_ACCOUNT     *sam_pass = NULL;
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
        TDB_CONTEXT     *pwd_tdb;
-       TDB_DATA        key, data;
+       TDB_DATA        key;
        fstring         keystr;
-       pstring         tdbfile;
        uint32          rid;
        fstring         name;
        
-       unix_strlower(sname, -1, name, sizeof(name));
+       unix_strlower(pdb_get_username(sam_pass), -1, name, sizeof(name));
        
-       get_private_directory(tdbfile);
-       pstrcat (tdbfile, PASSDB_FILE_NAME);
-
        /* open the TDB */
-       if (!(pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0600))) {
+       if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR, 0600))) {
                DEBUG(0, ("Unable to open TDB passwd!"));
                return False;
        }
@@ -675,33 +626,8 @@ BOOL pdb_delete_sam_account(const char *sname)
        key.dptr = keystr;
        key.dsize = strlen (keystr) + 1;
        
-       /* get the record */
-       data = tdb_fetch (pwd_tdb, key);
-       if (!data.dptr) {
-               DEBUG(5,("pdb_delete_sam_account (TDB): error fetching database.\n"));
-               DEBUGADD(5, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
-               tdb_close (pwd_tdb);
-               return False;
-       }
-  
-       /* unpack the buffer */
-       if (!NT_STATUS_IS_OK(pdb_init_sam (&sam_pass))) {
-               tdb_close (pwd_tdb);
-               return False;
-       }
-       
-       if (!init_sam_from_buffer (sam_pass, data.dptr, data.dsize)) {
-               DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
-               tdb_close (pwd_tdb);
-               SAFE_FREE(data.dptr);
-               return False;
-       }
-       SAFE_FREE(data.dptr);
-
        rid = pdb_get_user_rid(sam_pass);
 
-       pdb_free_sam (&sam_pass);
-       
        /* it's outaa here!  8^) */
        if (tdb_delete(pwd_tdb, key) != TDB_SUCCESS) {
                DEBUG(5, ("Error deleting entry from tdb passwd database!\n"));
@@ -734,27 +660,62 @@ BOOL pdb_delete_sam_account(const char *sname)
  Update the TDB SAM
 ****************************************************************************/
 
-static BOOL tdb_update_sam(const SAM_ACCOUNT* newpwd, BOOL override, int flag)
+static BOOL tdb_update_sam(struct pdb_context *context, const SAM_ACCOUNT* newpwd, int flag)
 {
+       struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
        TDB_CONTEXT     *pwd_tdb = NULL;
        TDB_DATA        key, data;
        uint8           *buf = NULL;
        fstring         keystr;
-       pstring         tdbfile;
        fstring         name;
        BOOL            ret = True;
-       
-       get_private_directory(tdbfile);
-       pstrcat (tdbfile, PASSDB_FILE_NAME);
-       
-       /* if we don't have a RID, then FAIL */
-       if (!pdb_get_user_rid(newpwd))
-               DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd)));
-       if (!pdb_get_group_rid(newpwd))
-               DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd)));
+       uint32          user_rid;
+       uint32         group_rid;
+       int32          tdb_ret;
+
+       /* invalidate the existing TDB iterator if it is open */
+       if (tdb_state->passwd_tdb) {
+               tdb_close(tdb_state->passwd_tdb);
+               tdb_state->passwd_tdb = NULL;
+       }
+
+       /* open the account TDB passwd*/
+       pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
+       if (!pwd_tdb)
+       {
+               DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
+               return False;
+       }
+
+       /* if we don't have a RID, then make them up. */
+       if (!(user_rid = pdb_get_user_rid(newpwd))) {
+               if (!tdb_state->permit_non_unix_accounts) {
+                       DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd)));
+                       ret = False;
+                       goto done;
+               } else {
+                       user_rid = tdb_state->low_nua_rid;
+                       tdb_ret = tdb_change_int32_atomic(pwd_tdb, "NUA_NEXT_RID", &user_rid, RID_MULTIPLIER);
+                       if (tdb_ret == -1) {
+                               ret = False;
+                               goto done;
+                       }
+               }
+       }
+
+       if (!(group_rid = pdb_get_group_rid(newpwd))) {
+               if (!tdb_state->permit_non_unix_accounts) {
+                       DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd)));
+                       ret = False;
+                       goto done;
+               } else {
+                       /* This seems like a good default choice for non-unix users */
+                       group_rid = DOMAIN_GROUP_RID_USERS;
+               }
+       }
 
        /* copy the SAM_ACCOUNT struct into a BYTE buffer for storage */
-       if ((data.dsize=init_buffer_from_sam (&buf, newpwd)) == -1) {
+       if ((data.dsize=init_buffer_from_sam (tdb_state, &buf, newpwd, user_rid, group_rid)) == -1) {
                DEBUG(0,("tdb_update_sam: ERROR - Unable to copy SAM_ACCOUNT info BYTE buffer!\n"));
                ret = False;
                goto done;
@@ -763,29 +724,18 @@ static BOOL tdb_update_sam(const SAM_ACCOUNT* newpwd, BOOL override, int flag)
 
        unix_strlower(pdb_get_username(newpwd), -1, name, sizeof(name));
        
+       DEBUG(5, ("Storing %saccount %s with RID %d\n", flag == TDB_INSERT ? "(new) " : "", name, user_rid));
+
        /* setup the USER index key */
        slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name);
        key.dptr = keystr;
        key.dsize = strlen (keystr) + 1;
 
-       /* invalidate the existing TDB iterator if it is open */
-       if (global_tdb_ent.passwd_tdb) {
-               tdb_close(global_tdb_ent.passwd_tdb);
-               global_tdb_ent.passwd_tdb = NULL;
-       }
-
-       /* open the account TDB passwd*/
-       pwd_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
-       if (!pwd_tdb)
-       {
-               DEBUG(0, ("tdb_update_sam: Unable to open TDB passwd!\n"));
-               return False;
-       }
-
        /* add the account */
        if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
                DEBUG(0, ("Unable to modify passwd TDB!"));
-               DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
+               DEBUGADD(0, (" Error: %s", tdb_errorstr(pwd_tdb)));
+               DEBUGADD(0, (" occured while storing the main record (%s)\n", keystr));
                ret = False;
                goto done;
        }
@@ -795,7 +745,7 @@ static BOOL tdb_update_sam(const SAM_ACCOUNT* newpwd, BOOL override, int flag)
        data.dptr = name;
 
        /* setup the RID index key */
-       slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, pdb_get_user_rid(newpwd));
+       slprintf(keystr, sizeof(keystr)-1, "%s%.8x", RIDPREFIX, user_rid);
        key.dptr = keystr;
        key.dsize = strlen (keystr) + 1;
        
@@ -803,6 +753,7 @@ static BOOL tdb_update_sam(const SAM_ACCOUNT* newpwd, BOOL override, int flag)
        if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) {
                DEBUG(0, ("Unable to modify TDB passwd !"));
                DEBUGADD(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
+               DEBUGADD(0, (" occured while storing the RID index (%s)\n", keystr));
                ret = False;
                goto done;
        }
@@ -819,21 +770,113 @@ done:
  Modifies an existing SAM_ACCOUNT
 ****************************************************************************/
 
-BOOL pdb_update_sam_account (const SAM_ACCOUNT *newpwd, BOOL override)
+static BOOL tdbsam_update_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd)
 {
-       return (tdb_update_sam(newpwd, override, TDB_MODIFY));
+       return (tdb_update_sam(context, newpwd, TDB_MODIFY));
 }
 
 /***************************************************************************
  Adds an existing SAM_ACCOUNT
 ****************************************************************************/
 
-BOOL pdb_add_sam_account (const SAM_ACCOUNT *newpwd)
+static BOOL tdbsam_add_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd)
+{
+       return (tdb_update_sam(context, newpwd, TDB_INSERT));
+}
+
+static void free_private_data(void **vp) 
 {
-       return (tdb_update_sam(newpwd, True, TDB_INSERT));
+       struct tdbsam_privates **tdb_state = (struct tdbsam_privates **)vp;
+       close_tdb(*tdb_state);
+       *tdb_state = NULL;
+
+       /* No need to free any further, as it is talloc()ed */
 }
 
+
+NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+       NTSTATUS nt_status;
+       struct tdbsam_privates *tdb_state;
+
+       if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+               return nt_status;
+       }
+
+       (*pdb_method)->setsampwent = tdbsam_setsampwent;
+       (*pdb_method)->endsampwent = tdbsam_endsampwent;
+       (*pdb_method)->getsampwent = tdbsam_getsampwent;
+       (*pdb_method)->getsampwnam = tdbsam_getsampwnam;
+       (*pdb_method)->getsampwrid = tdbsam_getsampwrid;
+       (*pdb_method)->add_sam_account = tdbsam_add_sam_account;
+       (*pdb_method)->update_sam_account = tdbsam_update_sam_account;
+       (*pdb_method)->delete_sam_account = tdbsam_delete_sam_account;
+
+       /* TODO: Setup private data and free */
+
+       tdb_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct tdbsam_privates));
+
+       if (!tdb_state) {
+               DEBUG(0, ("talloc() failed for tdbsam private_data!\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (location) {
+               tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, location);
+       } else {
+               pstring tdbfile;
+               get_private_directory(tdbfile);
+               pstrcat (tdbfile, PASSDB_FILE_NAME);
+               tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, tdbfile);
+       }
+
+       (*pdb_method)->private_data = tdb_state;
+
+       (*pdb_method)->free_private_data = free_private_data;
+
+       return NT_STATUS_OK;
+}
+
+NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+       NTSTATUS nt_status;
+       struct tdbsam_privates *tdb_state;
+       uint32 low_nua_uid, high_nua_uid;
+
+       if (!NT_STATUS_IS_OK(nt_status = pdb_init_tdbsam(pdb_context, pdb_method, location))) {
+               return nt_status;
+       }
+
+       tdb_state = (*pdb_method)->private_data;
+       
+       tdb_state->permit_non_unix_accounts = True;
+
+       if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
+               DEBUG(0, ("cannot use tdbsam_nua without 'non unix account range' in smb.conf!\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       tdb_state->low_nua_rid=pdb_uid_to_user_rid(low_nua_uid);
+
+       tdb_state->high_nua_rid=pdb_uid_to_user_rid(high_nua_uid);
+
+       return NT_STATUS_OK;
+}
+
+
 #else
-       /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
-       void samtdb_dummy_function(void) { } /* stop some compilers complaining */
-#endif /* WITH_TDB_SAM */
+
+NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+       DEBUG(0, ("tdbsam not compiled in!\n"));
+       return NT_STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+       DEBUG(0, ("tdbsam_nua not compiled in!\n"));
+       return NT_STATUS_UNSUCCESSFUL;
+}
+
+
+#endif
index 1ae1b65fddccf9b83c587b28b8b1f646a29f3448..077dbb0e2bf143fe0bd03fc586d43226e6c6ddf3 100644 (file)
@@ -410,6 +410,11 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *
                return NT_STATUS_NO_SUCH_USER;
        }
        
+       if (!(pdb_get_acct_ctrl(sampass) & ACB_DISABLED)) {
+               pdb_free_sam(&sampass);
+               return NT_STATUS_ACCOUNT_DISABLED;
+       }
+
        DEBUG(100,("Server password set : new given value was :\n"));
        for(i = 0; i < 16; i++)
                DEBUG(100,("%02X ", q_u->pwd[i]));
@@ -441,7 +446,7 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *
        }
  
        become_root();
-       ret = pdb_update_sam_account (sampass,False);
+       ret = pdb_update_sam_account (sampass);
        unbecome_root();
  
        if (ret)
index cf9be78f3d96996bac47fcc815482e12708507f6..d079403455d8a4260514ce05407cecbce2babdbb 100644 (file)
@@ -1869,9 +1869,6 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
 {
        SAM_ACCOUNT *sam_pass=NULL;
        fstring account;
-       pstring err_str;
-       pstring msg_str;
-       int local_flags=0;
        DOM_SID sid;
        pstring add_script;
        POLICY_HND dom_pol = q_u->domain_pol;
@@ -1880,6 +1877,8 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
        POLICY_HND *user_pol = &r_u->user_pol;
        struct samr_info *info = NULL;
        BOOL ret;
+       NTSTATUS nt_status;
+       struct passwd *pw;
 
        /* find the policy handle.  open a policy on it. */
        if (!find_policy_by_hnd(p, &dom_pol, NULL))
@@ -1905,8 +1904,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
                return NT_STATUS_USER_EXISTS;
        }
 
-       local_flags=LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_SET_NO_PASSWORD;
-       local_flags|= (acb_info & ACB_WSTRUST) ? LOCAL_TRUST_ACCOUNT:0;
+       pdb_free_sam(&sam_pass);
 
        /*
         * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
@@ -1955,32 +1953,54 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
                pstrcpy(add_script, lp_adduser_script());
 
        if(*add_script) {
-               int add_ret;
-               all_string_sub(add_script, "%u", account, sizeof(account));
-               add_ret = smbrun(add_script,NULL);
-               DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n",add_script,add_ret));
-       }
+               int add_ret;
+               all_string_sub(add_script, "%u", account, sizeof(account));
+               add_ret = smbrun(add_script,NULL);
+               DEBUG(3,("_api_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
+       }
+       
+       pw = getpwnam_alloc(account);
 
-       /* add the user in the smbpasswd file or the Samba authority database */
-       if (!local_password_change(account, local_flags, NULL, err_str,
-           sizeof(err_str), msg_str, sizeof(msg_str))) {
-               DEBUG(0, ("%s\n", err_str));
-               pdb_free_sam(&sam_pass);
-               return NT_STATUS_ACCESS_DENIED;
+       if (pw) {
+               if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sam_pass, pw))) {
+                       passwd_free(&pw);
+                       return nt_status;
+               }
+               passwd_free(&pw); /* done with this now */
+       } else {
+               DEBUG(3,("attempting to create non-unix account %s\n", account));
+               
+               if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sam_pass))) {
+                       return nt_status;
+               }
+               
+               if (!pdb_set_username(sam_pass, account)) {
+                       pdb_free_sam(&sam_pass);
+                       return NT_STATUS_NO_MEMORY;
+               }
        }
 
-       become_root();
-       ret = pdb_getsampwnam(sam_pass, account);
-       unbecome_root();
-       if (ret == False) {
-               /* account doesn't exist: say so */
-               pdb_free_sam(&sam_pass);
-               return NT_STATUS_ACCESS_DENIED;
-       }
+       pdb_set_acct_ctrl(sam_pass, acb_info);
+       if (!pdb_add_sam_account(sam_pass)) {
+               pdb_free_sam(&sam_pass);
+               DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
+                         account));
+               return NT_STATUS_ACCESS_DENIED;         
+       }
 
-       /* Get the domain SID stored in the domain policy */
-       if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
-               pdb_free_sam(&sam_pass);
+       pdb_reset_sam(sam_pass);
+       
+       if (!pdb_getsampwnam(sam_pass, account)) {
+               pdb_free_sam(&sam_pass);
+               DEBUG(0, ("could not find user/computer %s just added to passdb?!?\n", 
+                         account));
+               return NT_STATUS_ACCESS_DENIED;         
+       }
+       
+       /* Get the domain SID stored in the domain policy */
+       if(!get_lsa_policy_samr_sid(p, &dom_pol, &sid)) {
+               pdb_free_sam(&sam_pass);
                return NT_STATUS_INVALID_HANDLE;
        }
 
@@ -2214,7 +2234,7 @@ static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
                return False;
        }
 
-       if(!pdb_update_sam_account(pwd, True)) {
+       if(!pdb_update_sam_account(pwd)) {
                pdb_free_sam(&pwd);
                return False;
        }
@@ -2258,7 +2278,7 @@ static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, uint32 rid)
                return False; 
        }
  
-       if(!pdb_update_sam_account(pwd, True)) {
+       if(!pdb_update_sam_account(pwd)) {
                pdb_free_sam(&pwd);
                return False;
        }
@@ -2297,7 +2317,7 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
         */
  
        /* write the change out */
-       if(!pdb_update_sam_account(pwd, True)) {
+       if(!pdb_update_sam_account(pwd)) {
                pdb_free_sam(&pwd);
                return False;
        }
@@ -2330,6 +2350,9 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
                return False;
        }
 
+       DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
+                 pdb_get_username(pwd)));
+
        acct_ctrl = pdb_get_acct_ctrl(pwd);
 
        copy_id23_to_sam_passwd(pwd, id23);
@@ -2345,10 +2368,11 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
        }
  
        /* if it's a trust account, don't update /etc/passwd */
-       if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
-            ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
-            ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
-            DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
+       if ( (!IS_SAM_UNIX_USER(pwd)) ||
+               ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
+               ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
+               ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
+               DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
        } else  {
                /* update the UNIX password */
                if (lp_unix_password_sync() )
@@ -2360,7 +2384,7 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, uint32 rid)
  
        ZERO_STRUCT(plaintext_buf);
  
-       if(!pdb_update_sam_account(pwd, True)) {
+       if(!pdb_update_sam_account(pwd)) {
                pdb_free_sam(&pwd);
                return False;
        }
@@ -2388,6 +2412,9 @@ static BOOL set_user_info_pw(char *pass, uint32 rid)
                return False;
        }
        
+       DEBUG(5, ("Attempting administrator password change for user %s\n",
+                 pdb_get_username(pwd)));
+
        acct_ctrl = pdb_get_acct_ctrl(pwd);
 
        ZERO_STRUCT(plaintext_buf);
@@ -2403,25 +2430,27 @@ static BOOL set_user_info_pw(char *pass, uint32 rid)
        }
  
        /* if it's a trust account, don't update /etc/passwd */
-       if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
-            ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
-            ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
-            DEBUG(5, ("Changing trust account password, not updating /etc/passwd\n"));
+       if ( (!IS_SAM_UNIX_USER(pwd)) ||
+               ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
+               ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
+               ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
+               DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
        } else {
                /* update the UNIX password */
-               if (lp_unix_password_sync())
+               if (lp_unix_password_sync()) {
                        if(!chgpasswd(pdb_get_username(pwd), "", plaintext_buf, True)) {
                                pdb_free_sam(&pwd);
                                return False;
                        }
+               }
        }
  
        ZERO_STRUCT(plaintext_buf);
  
-       DEBUG(5,("set_user_info_pw: pdb_update_sam_account()\n"));
+       DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
  
        /* update the SAMBA password */
-       if(!pdb_update_sam_account(pwd, True)) {
+       if(!pdb_update_sam_account(pwd)) {
                pdb_free_sam(&pwd);
                return False;
        }
@@ -2442,7 +2471,6 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
        POLICY_HND *pol = &q_u->pol;
        uint16 switch_value = q_u->switch_value;
        SAM_USERINFO_CTR *ctr = q_u->ctr;
-       BOOL ret;
 
        DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
 
@@ -3052,7 +3080,7 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
        smb_delete_user(pdb_get_username(sam_pass));
 
        /* and delete the samba side */
-       if (!pdb_delete_sam_account(pdb_get_username(sam_pass))) {
+       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;
index 5e646b622580444311ab7e15a1a189e156f50a69..9a30838cac571390e5edcad73afaa9d51edb12cb 100644 (file)
@@ -718,7 +718,7 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar * pass1,
  
        /* Now flush the sam_passwd struct to persistent storage */
        become_root();
-       ret = pdb_update_sam_account (sampass, False);
+       ret = pdb_update_sam_account (sampass);
        unbecome_root();
 
        return ret;
@@ -928,7 +928,7 @@ BOOL change_oem_password(SAM_ACCOUNT *hnd, char *new_passwd)
 
        /* Now write it into the file. */
        become_root();
-       ret = pdb_update_sam_account (hnd, False);
+       ret = pdb_update_sam_account (hnd);
        unbecome_root();
 
        return ret;
index 87dabf165d41ac009710f7e5c6c1c91b88cdf7d2..9ca4430136628dc6f93bb622782c7774462a2b56 100644 (file)
@@ -481,7 +481,7 @@ static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
  the samba DEBUG() system.
 ****************************************************************************/
 
-TDB_CONTEXT *tdb_open_log(char *name, int hash_size, int tdb_flags,
+TDB_CONTEXT *tdb_open_log(const char *name, int hash_size, int tdb_flags,
                          int open_flags, mode_t mode)
 {
        TDB_CONTEXT *tdb;
index ae600f6a6a7f2b5bc2b819c4b8e635ca9b5d272f..33b62ebd42ed6891f8b7097ed566ff6e1db97857 100644 (file)
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-/* base uid for trust accounts is set to 60000 ! 
- * May be we should add the defines in smb.h to make it possible having 
- * different values on different platforms?
- */
-
-#define BASE_MACHINE_UID 60000
-#define MAX_MACHINE_UID 65500 /* 5500 trust accounts aren't enough? */
-
 #include "includes.h"
 
 extern pstring global_myname;
@@ -213,7 +205,7 @@ static int set_user_info (char *username, char *fullname, char *homedir, char *d
        if (profile)
                pdb_set_profile_path (sam_pwent, profile, True);
        
-       if (pdb_update_sam_account (sam_pwent, True))
+       if (pdb_update_sam_account (sam_pwent))
                print_user_info (username, True, False);
        else {
                fprintf (stderr, "Unable to modify entry!\n");
@@ -284,10 +276,8 @@ static int new_user (char *username, char *fullname, char *homedir, char *drive,
 static int new_machine (char *machinename)
 {
        SAM_ACCOUNT *sam_pwent=NULL;
-       SAM_ACCOUNT *sam_trust=NULL;
        char name[16];
        char *password = NULL;
-       uid_t uid;
        
        pdb_init_sam (&sam_pwent);
 
@@ -304,23 +294,6 @@ static int new_machine (char *machinename)
 
        pdb_set_username (sam_pwent, name);
        
-       for (uid=BASE_MACHINE_UID; uid<=MAX_MACHINE_UID; uid++) {
-               pdb_init_sam (&sam_trust);
-               if (pdb_getsampwrid (sam_trust, pdb_uid_to_user_rid (uid))) {
-                       pdb_free_sam (&sam_trust);
-               } else {
-                       break;
-               }
-       }
-
-       if (uid>MAX_MACHINE_UID) {
-               fprintf (stderr, "No more free UIDs available to Machine accounts!\n");
-               pdb_free_sam(&sam_pwent);               
-               return -1;
-       }
-
-       pdb_set_user_rid (sam_pwent,pdb_uid_to_user_rid (uid));
-       pdb_set_group_rid (sam_pwent, pdb_gid_to_group_rid (BASE_MACHINE_UID));
        pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST);
        
        if (pdb_add_sam_account (sam_pwent)) {
@@ -340,7 +313,16 @@ static int new_machine (char *machinename)
 
 static int delete_user_entry (char *username)
 {
-       return pdb_delete_sam_account (username);
+       SAM_ACCOUNT *samaccount;
+
+       pdb_init_sam(&samaccount);
+
+       if (!pdb_getsampwnam(samaccount, username)) {
+               fprintf (stderr, "user %s does not exist in the passdb\n", username);
+               return -1;
+       }
+
+       return pdb_delete_sam_account (samaccount);
 }
 
 /*********************************************************
@@ -350,11 +332,20 @@ static int delete_user_entry (char *username)
 static int delete_machine_entry (char *machinename)
 {
        char name[16];
+       SAM_ACCOUNT *samaccount;
        
        safe_strcpy (name, machinename, 16);
        if (name[strlen(name)] != '$')
                safe_strcat (name, "$", 16);
-       return pdb_delete_sam_account (name);
+
+       pdb_init_sam(&samaccount);
+
+       if (!pdb_getsampwnam(samaccount, name)) {
+               fprintf (stderr, "user %s does not exist in the passdb\n", name);
+               return -1;
+       }
+
+       return pdb_delete_sam_account (samaccount);
 }
 
 /*********************************************************
@@ -564,11 +555,6 @@ int main (int argc, char **argv)
                return 0;
        }
        
-       if(!initialize_password_db(True)) {
-               fprintf(stderr, "Can't setup password database vectors.\n");
-               exit(1);
-       }
-       
        DEBUGLEVEL = 1;
        AllowDebugChange = False;
 
@@ -578,6 +564,11 @@ int main (int argc, char **argv)
                exit(1);
        }
        
+       if(!initialize_password_db(True)) {
+               fprintf(stderr, "Can't setup password database vectors.\n");
+               exit(1);
+       }
+       
        while ((ch = getopt(argc, argv, "ad:f:h:i:lmp:s:u:vwx")) != EOF) {
                switch(ch) {
                case 'a':
index 6a20e71d966a8992acccf3a715b162f3a248ff41..a4abca2ce63f0e0daef0a79d8d456ba4091f6938 100644 (file)
@@ -575,11 +575,6 @@ int main(int argc, char **argv)
 
        setup_logging("smbpasswd", True);
        
-       if(!initialize_password_db(True)) {
-               fprintf(stderr, "Can't setup password database vectors.\n");
-               exit(1);
-       }
-
        if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
                fprintf(stderr, "Can't load %s - run testparm to debug it\n", 
                        dyn_CONFIGFILE);
index 933f8f9804cb428eacef9123e2f603e21441f9b6..5bf3305516a9303f6d6812db4232c6ac59c7d780 100644 (file)
@@ -6,15 +6,15 @@ fi
 
 test_joindomain_nt4() {
 
-       smbpasswd -a -m buildfarm$
+       smbpasswd -L -a -m buildfarm$
 
-       echo $prefix/bin/smbpasswd -L -j TESTWG
-       $prefix/bin/smbpasswd -L -j TESTWG
+       echo $prefix/bin/net rpc join oldstyle -S localhost
+        $prefix/bin/net rpc join oldstyle -S localhost
        status=$?
        if [ $status = 0 ]; then
-           echo "smbpasswd correctly joined the domain ($workgroup)"
+           echo "'net rpc join oldstyle' correctly joined the domain ($workgroup)"
        else
-           echo "smbpasswd failed to join the domain ($workgroup)! (status $status)"
+           echo "'net rpc join oldstyle' failed to join the domain ($workgroup)! (status $status)"
            return 1
        fi
        return 0
index ff184c4c7f307b2d4c67f8505663b66c2fda3f5f..5dd005a6ee7ac2e854f8453ce3b0b9322ffb8d3f 100644 (file)
@@ -1,19 +1,16 @@
-if [ $whoami != "root" ]; then
-       exit 0;
-fi
 
 . basicsmb.fns
 
 test_joindomain() {
        test_joindomain_password="$1"
 
-       echo "$prefix/bin/smbpasswd -L -j TESTWG -U $whoami%$test_join_domain_password"
-       $prefix/bin/smbpasswd -L -j TESTWG -U $whoami%$test_join_domain_password
+       echo "$prefix/bin/net rpc join -S localhost  -U $whoami%$test_join_domain_password"
+       $prefix/bin/net rpc join -S localhost  -U $whoami%$test_join_domain_password
        status=$?
        if [ $status = 0 ]; then
-           echo "smbpasswd correctly joined the domain ($workgroup)"
+           echo "'net rpc join' correctly joined the domain ($workgroup)"
        else
-           echo "smbpasswd failed to join the domain ($workgroup)! (status $status)"
+           echo "'net rpc join' failed to join the domain ($workgroup)! (status $status)"
            return 1
        fi
        return 0
index ff837bbb09897a9f6fdaf668f69cf6a42077df87..8b75f299a218d38a0760bf86f79f02de9b32c638 100644 (file)
 
     panic action = echo bt | gdb PREFIX/sbin/smbd %d
 
+    passdb backend = smbpasswd_nua
+
+    non unix account range = 10000-20000
+
 [test]
     path = PREFIX/testdir
     read only = no