sync 3.0 branch with head
authorJelmer Vernooij <jelmer@samba.org>
Sat, 17 Aug 2002 17:00:51 +0000 (17:00 +0000)
committerJelmer Vernooij <jelmer@samba.org>
Sat, 17 Aug 2002 17:00:51 +0000 (17:00 +0000)
103 files changed:
WHATSNEW.txt
source/auth/auth.c
source/auth/auth_domain.c
source/auth/auth_sam.c
source/auth/auth_util.c
source/auth/auth_winbind.c
source/client/clitar.c
source/client/smbmount.c
source/client/smbspool.c
source/configure
source/configure.in
source/include/ads.h
source/include/config.h.in
source/include/includes.h
source/include/local.h
source/include/messages.h
source/include/nameserv.h
source/include/nt_printing.h
source/include/passdb.h
source/include/rpc_lsa.h
source/include/rpc_reg.h
source/include/rpc_samr.h
source/include/rpc_spoolss.h
source/include/rpc_srvsvc.h
source/include/secrets.h
source/include/smb.h
source/include/version.h
source/include/vfs.h
source/intl/lang_tdb.c
source/lib/account_pol.c
source/lib/charcnv.c
source/lib/debug.c
source/lib/genrand.c
source/lib/replace.c
source/lib/smbrun.c
source/lib/substitute.c
source/lib/system.c
source/lib/username.c
source/lib/util.c
source/lib/util_getent.c
source/lib/util_sid.c
source/lib/util_sock.c
source/lib/util_str.c
source/lib/wins_srv.c
source/lib/xfile.c
source/libads/ads_struct.c
source/libads/kerberos.c
source/libads/kerberos_verify.c
source/libads/ldap.c
source/libads/ldap_user.c
source/libads/sasl.c
source/libads/util.c
source/libsmb/cliconnect.c
source/libsmb/clispnego.c
source/libsmb/namequery.c
source/libsmb/smbencrypt.c
source/libsmb/trust_passwd.c
source/nmbd/asyncdns.c
source/nmbd/nmbd.c
source/nmbd/nmbd_become_dmb.c
source/nmbd/nmbd_mynames.c
source/nmbd/nmbd_nameregister.c
source/nmbd/nmbd_packets.c
source/nmbd/nmbd_processlogon.c
source/nsswitch/pam_winbind.c
source/nsswitch/wb_client.c
source/nsswitch/wb_common.c
source/nsswitch/wbinfo.c
source/nsswitch/winbindd.c
source/nsswitch/winbindd.h
source/nsswitch/winbindd_ads.c
source/nsswitch/winbindd_cache.c
source/nsswitch/winbindd_cm.c
source/nsswitch/winbindd_group.c
source/nsswitch/winbindd_nss.h
source/nsswitch/winbindd_pam.c
source/nsswitch/winbindd_rpc.c
source/nsswitch/winbindd_sid.c
source/nsswitch/winbindd_user.c
source/nsswitch/winbindd_util.c
source/nsswitch/winbindd_wins.c
source/param/loadparm.c
source/passdb/passdb.c
source/passdb/pdb_get_set.c
source/passdb/pdb_interface.c
source/passdb/pdb_ldap.c
source/passdb/pdb_nisplus.c
source/passdb/pdb_smbpasswd.c
source/passdb/pdb_tdb.c
source/passdb/pdb_unix.c
source/passdb/secrets.c
source/passdb/util_sam_sid.c
source/printing/pcap.c
source/printing/print_svid.c
source/printing/printfsp.c
source/printing/printing.c
source/rpc_parse/parse_lsa.c
source/rpc_parse/parse_net.c
source/rpc_parse/parse_prs.c
source/rpc_parse/parse_reg.c
source/rpc_parse/parse_samr.c
source/rpc_parse/parse_spoolss.c
source/rpc_parse/parse_srv.c

index ba9956cdbbb43109336184a1b79dc2efe839d8f7..80383d8eeb199441fb6cc73bb79c92a279f7afc4 100644 (file)
@@ -1,6 +1,104 @@
               WHATS NEW IN Samba 3.0 alphaX
               =============================
 
+Changes in alpha19
+ - Heavy registry updates (jerry)
+ - Use 850 as the default DOS character set in smb.conf (tpot)
+ - printer fixes - removed encoding of queueid in job number (jra)
+ - A lot of small fixes (jra)
+ - virtual registry framework with initial printing hooks (jerry)
+ - Don't crash on setfileinfo on printer fsp(jra)
+ - fixed line buffer mode in XFILE(jra)
+ - update samba.schema from 2.2 (jerry,idra)
+ - Fix problem with oplock breaks and win2k - 
+   noticed by Lev Iserovich <lev@ciprico.com> (jra)
+ - Give different error message when PDC is down - 
+   thanks to Mark Kaplan from Quantum (abartlet)
+ - Add wrapper for dup2() (abartlet)
+ - Update smbgroupedit to document -d - thanks to metze (abartlet)
+ - Support weird behaviour used by win9x pass-through auth (abartlet,tpot)
+ - Support for duplicating stderr in log files (abartlet)
+ - Move startup time initialisation to server.c (abartlet)
+ - *A lot* of fixes and cleanups (abartlet)
+ - Fix up compiler warnings (abartlet)
+ - Few small fixes (tpot)
+ - Renamed new_cli_netlogon_* -> cli_netlogon_* (tpot)
+ - Fixed segfault in net time when host is unavailable (tridge)
+ - Ensure to be root when opening printer backend tdb (jra)
+ - Merges from APPLIANCE_HEAD (tpot,jerry)
+ - configure updates (tridge)
+ - particularly getgrouplist() (tridge)
+ - Make sure to be root when accessing pdb (abartlet)
+ - Better PAM error message (abartlet)
+ - Support for pdbedit to query account policy values (abartlet)
+ - Fix few typos (mimir, abartlet)
+ - Allow one to create trusting domain account using smbpasswd (mimir,abartlet)
+ - 'Net rpc trustdom list' (mimir, abartlet)
+ - Fix fallback to anonymous connection (mimir, abartlet)
+ - Add debugging info to secrets.c (mimir, abartlet)
+ - Fix for pdb_ldap and OpenLDAP 2.1
+ - Added support in swat to determine whether winbind is running (idra)
+ - Add 'hide unwritable' option (idra)
+ - Correct pickup of [homes] share after subsequent session setups (abartlet)
+ - Update rebind code in pdb_ldap (abartlet)
+ - Add some info levels to RPC srvsvc code - 
+   thanks to Nigel Williams" <nigel@veritas.com> (abartlet)
+ - Small doc fixes (tridge)
+ - good security patch from Timothy.Sell@unisys.com (tridge)
+ - fix minor nits in nmbd from adtam@cup.hp.com (tridge)
+ - make sure async dns nmbd child dies (tridge)
+ - interim fix for nmbd not registering DOMAIN#1b (tridge)
+ - fix for smbtar filename matching (tridge)
+ - Better quote handling in smb.conf (abartlet)
+ - Support browsers setting multiple languages in swat (idra)
+ - Changed str_list_make to be able to use a different separator string (idra)
+ - Remove use of strtof because of portability issues (idra)
+ - Common popt definition for -d option (tpot)
+ - Samsync support to insert account info into the pdb (tpot)
+ - Don't hide unwritable dirs when 'hide unwritable' is enabled - 
+   suggested by Alexander Oswald <oswald@is.haw-hamburg.de> (idra)
+ - Fix for handling sparse files in smbd (tridge)
+ - Merges from 2_2 (jerry)
+ - Add cvslog.pl file
+ - Minor printer fixes (jerry)
+ - Fix SID lookup code to never do recursive winbind (abartlet)
+ - Fix SID lookup code to never use algoritmic rid for fixed mappings (abartlet)
+ - Cascaded VFS (Alexander Bokovoy, idra)
+ - Optimisations when in ADS mode (tridge)
+ - Try netbios-less connections when in ADS mode (tridge)
+ - Minor ADS tweaks (tridge)
+ - Fix plaintext passwords with win2k (tridge)
+ - 'net ads info' reports IP of LDAP server (tridge)
+ - Add LSA RPC 0x2E, lsa_query_info2 (jmcd)
+ - Add 'smb ports = ' option (tridge)
+ - Various small fixes (tridge)
+ - Add 'disable netbios = yes/no' (tridge)
+ - Passdb security checks (abartlet)
+ - Large winbind updates (abartlet)
+ - Moved rpc client routines from libsmb to rpc_client (tpot)
+ - Few nmbd fixes (jmcd)
+ - Fix swat to handle new debug level (idra)
+ - Fix name length in namequeries (tridge)
+ - Netbios-less setup ADS fixes (tridge)
+ - Add SAMR 0x3e, which is samr_connect4 (jmcd)
+ - Add consts to passdb (abartlet)
+ - Don't client binaries depend on libs they don't use - 
+   patch from Steve Langasek <vorlon@netexpress.net> (abartlet)
+ - Printing change notification (merged from HEAD_APPLIANCE) (jerry)
+ - fix delete printer driver (from HEAD_APPLIANCE) (jerry)
+ - Added pdb_xml and pdb_mysql (jelmer)
+ - Update pdb_test (jelmer)
+ - Fix security issues with %m (abartlet)
+ - Add client side support for samr connect4 (0x3e) (jmcd)
+ - Add lsa 0x2e (queryinfo2) client side (jmcd)
+ - Support for service joins from win2k AND use SPNEGO (jmcd)
+ - pdbedit -i and -e fix, add -b (idra)
+ - textdocs converted to sgml (jelmer, jerry)
+ - Merge netbios namecache code from APPLIANCE_HEAD (tpot)
+ - Fix segs in new NTLMSSP code (abartlet)
+ - Always make guest rid 501 (abartlet)
+
 Changes in alpha18
  - huge number of changes! really too many to list ... (and its 1am
    here, and I'm too tired) 
index 4f7a5c24a00c6114843ef7de7a1dfe7530042cd0..d43afc71e14294c2e93a57c1d9d211c48605fdf9 100644 (file)
@@ -395,33 +395,33 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
                {
                case SEC_DOMAIN:
                        DEBUG(5,("Making default auth method list for security=domain\n"));
-                       auth_method_list = str_list_make("guest sam ntdomain");
+                       auth_method_list = str_list_make("guest sam winbind ntdomain", NULL);
                        break;
                case SEC_SERVER:
                        DEBUG(5,("Making default auth method list for security=server\n"));
-                       auth_method_list = str_list_make("guest sam smbserver");
+                       auth_method_list = str_list_make("guest sam smbserver", NULL);
                        break;
                case SEC_USER:
                        if (lp_encrypted_passwords()) { 
                                DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n"));
-                               auth_method_list = str_list_make("guest sam");
+                               auth_method_list = str_list_make("guest sam", NULL);
                        } else {
                                DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
-                               auth_method_list = str_list_make("guest unix");
+                               auth_method_list = str_list_make("guest unix", NULL);
                        }
                        break;
                case SEC_SHARE:
                        if (lp_encrypted_passwords()) {
                                DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
-                               auth_method_list = str_list_make("guest sam");
+                               auth_method_list = str_list_make("guest sam", NULL);
                        } else {
                                DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
-                               auth_method_list = str_list_make("guest unix");
+                               auth_method_list = str_list_make("guest unix", NULL);
                        }
                        break;
                case SEC_ADS:
                        DEBUG(5,("Making default auth method list for security=ADS\n"));
-                       auth_method_list = str_list_make("guest sam ads ntdomain");
+                       auth_method_list = str_list_make("guest sam ads winbind ntdomain", NULL);
                        break;
                default:
                        DEBUG(5,("Unknown auth method!\n"));
index 3352c5f9c894907c9ddae74da08d6086042d8c3d..d48cec5b2932444b7e102f90410bf7c7c6614501 100644 (file)
@@ -29,6 +29,88 @@ BOOL global_machine_password_needs_changing = False;
 extern pstring global_myname;
 extern userdom_struct current_user_info;
 
+
+/*
+  resolve the name of a DC in ways appropriate for an ADS domain mode
+  an ADS domain may not have Netbios enabled at all, so this is 
+  quite different from the RPC case
+  Note that we ignore the 'server' parameter here. That has the effect of using
+  the 'ADS server' smb.conf parameter, which is what we really want anyway
+ */
+static NTSTATUS ads_resolve_dc(fstring remote_machine, 
+                              struct in_addr *dest_ip)
+{
+       ADS_STRUCT *ads;
+       ads = ads_init_simple();
+       if (!ads) {
+               return NT_STATUS_NO_LOGON_SERVERS;              
+       }
+
+       DEBUG(4,("ads_resolve_dc: realm=%s\n", ads->config.realm));
+
+       ads->auth.no_bind = 1;
+
+#ifdef HAVE_ADS
+       /* a full ads_connect() is actually overkill, as we don't srictly need
+          to do the SASL auth in order to get the info we need, but libads
+          doesn't offer a better way right now */
+       ads_connect(ads);
+#endif
+
+       fstrcpy(remote_machine, ads->config.ldap_server_name);
+       strupper(remote_machine);
+       *dest_ip = ads->ldap_ip;
+       ads_destroy(&ads);
+       
+       if (!*remote_machine || is_zero_ip(*dest_ip)) {
+               return NT_STATUS_NO_LOGON_SERVERS;              
+       }
+
+       DEBUG(4,("ads_resolve_dc: using server='%s' IP=%s\n",
+                remote_machine, inet_ntoa(*dest_ip)));
+       
+       return NT_STATUS_OK;
+}
+
+/*
+  resolve the name of a DC in ways appropriate for RPC domain mode
+  this relies on the server supporting netbios and port 137 not being
+  firewalled
+ */
+static NTSTATUS rpc_resolve_dc(const char *server, 
+                              fstring remote_machine, 
+                              struct in_addr *dest_ip)
+{
+       if (is_ipaddress(server)) {
+               struct in_addr to_ip = *interpret_addr2(server);
+
+               /* we need to know the machines netbios name - this is a lousy
+                  way to find it, but until we have a RPC call that does this
+                  it will have to do */
+               if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
+                       DEBUG(2, ("connect_to_domain_password_server: Can't "
+                                 "resolve name for IP %s\n", server));
+                       return NT_STATUS_NO_LOGON_SERVERS;
+               }
+
+               *dest_ip = to_ip;
+               return NT_STATUS_OK;
+       } 
+
+       fstrcpy(remote_machine, server);
+       strupper(remote_machine);
+       if (!resolve_name(remote_machine, dest_ip, 0x20)) {
+               DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", 
+                        remote_machine));
+               return NT_STATUS_NO_LOGON_SERVERS;
+       }
+
+       DEBUG(4,("rpc_resolve_dc: using server='%s' IP=%s\n",
+                remote_machine, inet_ntoa(*dest_ip)));
+
+       return NT_STATUS_OK;
+}
+
 /**
  * Connect to a remote server for domain security authenticaion.
  *
@@ -50,37 +132,22 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
        fstring remote_machine;
         NTSTATUS result;
 
-       if (is_ipaddress(server)) {
-               struct in_addr to_ip;
-         
-               /* we shouldn't have 255.255.255.255 forthe IP address of 
-                  a password server anyways */
-               if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) {
-                       DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server));
-                       return NT_STATUS_UNSUCCESSFUL;
-               }
-
-               if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
-                       DEBUG(0, ("connect_to_domain_password_server: Can't "
-                                 "resolve name for IP %s\n", server));
-                       return NT_STATUS_UNSUCCESSFUL;
-               }
+       if (lp_security() == SEC_ADS) {
+               result = ads_resolve_dc(remote_machine, &dest_ip);
        } else {
-               fstrcpy(remote_machine, server);
+               result = rpc_resolve_dc(server, remote_machine, &dest_ip);
        }
 
-       standard_sub_basic(current_user_info.smb_name, remote_machine, sizeof(remote_machine));
-       strupper(remote_machine);
-
-       if(!resolve_name( remote_machine, &dest_ip, 0x20)) {
-               DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine));
-               return NT_STATUS_UNSUCCESSFUL;
+       if (!NT_STATUS_IS_OK(result)) {
+               DEBUG(2,("connect_to_domain_password_server: unable to resolve DC: %s\n", 
+                        nt_errstr(result)));
+               return result;
        }
-  
+
        if (ismyip(dest_ip)) {
                DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n",
                         remote_machine));
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_NO_LOGON_SERVERS;
        }
   
        /* TODO: Send a SAMLOGON request to determine whether this is a valid
@@ -98,11 +165,11 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
         */
 
        if (!grab_server_mutex(server))
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_NO_LOGON_SERVERS;
        
        /* Attempt connection */
-       result = cli_full_connection(cli, global_myname, server,
-                                    &dest_ip, 0, "IPC$", "IPC", "", "", "", 0);
+       result = cli_full_connection(cli, global_myname, remote_machine,
+                                    &dest_ip, 0, "IPC$", "IPC", "", "", "",0);
 
        if (!NT_STATUS_IS_OK(result)) {
                release_server_mutex();
@@ -129,7 +196,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
                cli_ulogoff(*cli);
                cli_shutdown(*cli);
                release_server_mutex();
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_NO_LOGON_SERVERS;
        }
 
        snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as);
@@ -139,7 +206,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
                return NT_STATUS_NO_MEMORY;
        }
 
-       result = new_cli_nt_setup_creds(*cli, sec_chan, trust_passwd);
+       result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd);
 
         if (!NT_STATUS_IS_OK(result)) {
                DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \
@@ -174,10 +241,10 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli,
         */
 
        if (is_zero_ip(*ip))
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_NO_LOGON_SERVERS;
 
        if (!lookup_dc_name(global_myname, domain, ip, dc_name))
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_NO_LOGON_SERVERS;
 
        return connect_to_domain_password_server(cli, dc_name, setup_creds_as, sec_chan, trust_passwd);
 }
@@ -196,7 +263,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
        struct in_addr *ip_list = NULL;
        int count = 0;
        int i;
-       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+       NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
        time_t time_now = time(NULL);
        BOOL use_pdc_only = False;
 
@@ -212,7 +279,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
                use_pdc_only = True;
 
        if (!get_dc_list(use_pdc_only, domain, &ip_list, &count))
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_NO_LOGON_SERVERS;
 
        /*
         * Firstly try and contact a PDC/BDC who has the same
@@ -288,7 +355,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
        fstring remote_machine;
        NET_USER_INFO_3 info3;
        struct cli_state *cli = NULL;
-       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+       NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
 
        /*
         * At this point, smb_apasswd points to the lanman response to
@@ -300,7 +367,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
 
        while (!NT_STATUS_IS_OK(nt_status) &&
               next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) {
-               if(strequal(remote_machine, "*")) {
+               if(lp_security() != SEC_ADS && strequal(remote_machine, "*")) {
                        nt_status = find_connect_pdc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time);
                } else {
                        nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as, sec_chan, trust_passwd);
@@ -503,7 +570,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
 #ifdef DEBUG_PASSWORD
        DEBUG(100, ("Trust password for domain %s is %s\n", user_info->domain.str, trust_password));
 #endif
-       E_md4hash((uchar *)trust_password, trust_md4_password);
+       E_md4hash(trust_password, trust_md4_password);
        SAFE_FREE(trust_password);
 
 #if 0
index 76579150ce9da4918f91c38c08a93852d961c512..155370546a5b3827f56f85ecbbd4b8c766c305e5 100644 (file)
@@ -107,7 +107,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
        memcpy(client_response, ntv2_response.data, sizeof(client_response));
 
        ntv2_owf_gen(part_passwd, user, domain, kr);
-       SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, (char *)value_from_encryption);
+       SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, value_from_encryption);
        if (user_sess_key != NULL)
        {
                SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key);
@@ -232,11 +232,26 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
                {
                        return NT_STATUS_OK;
                } else {
+                       if (lp_ntlm_auth()) {                           
+                               /* Apparently NT accepts NT responses in the LM feild
+                                  - I think this is related to Win9X pass-though authenticaion
+                               */
+                               DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM feild\n"));
+                               if (smb_pwd_check_ntlmv1(user_info->lm_resp, 
+                                                        nt_pw, auth_context->challenge,
+                                                        user_sess_key)) 
+                               {
+                                       return NT_STATUS_OK;
+                               } else {
+                                       DEBUG(3,("sam_password_ok: NT MD4 password in LM feild failed for user %s\n",pdb_get_username(sampass)));
+                                       return NT_STATUS_WRONG_PASSWORD;
+                               }
+                       }
                        DEBUG(4,("sam_password_ok: LM password check failed for user %s\n",pdb_get_username(sampass)));
                        return NT_STATUS_WRONG_PASSWORD;
                } 
        }
-
+               
        /* Should not be reached, but if they send nothing... */
        DEBUG(3,("sam_password_ok: NEITHER LanMan nor NT password supplied for user %s\n",pdb_get_username(sampass)));
        return NT_STATUS_WRONG_PASSWORD;
index 3ade220c0f02878dfb4dea7b244b3cbc9897a592..f914d918715dd7dfc3a7a1e14db91109ee546785 100644 (file)
@@ -25,7 +25,6 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
 
-extern fstring remote_machine;
 extern pstring global_myname;
 
 /****************************************************************************
@@ -394,7 +393,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
        
        ret = make_user_info_map(user_info, smb_name,
                                 client_domain, 
-                                remote_machine,
+                                get_remote_machine_name(),
                                 local_lm_blob,
                                 local_nt_blob,
                                 plaintext_password, 
@@ -429,7 +428,7 @@ BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
 
        return make_user_info_map(user_info, smb_name, 
                                 client_domain, 
-                                remote_machine
+                                get_remote_machine_name()
                                 lm_resp, 
                                 nt_resp, 
                                 no_plaintext_blob, 
index 671e198bf59beaf1845f8baaac47527405195392..5bdccd39f3e88543689091e12ba3a5c2bea42881 100644 (file)
@@ -32,6 +32,30 @@ NSS_STATUS winbindd_request(int req_type,
                            struct winbindd_request *request,
                            struct winbindd_response *response);
 
+NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response *response, NET_USER_INFO_3 *info3)
+{
+       uint8 *info3_ndr;
+       size_t len = response->length - sizeof(response);
+       prs_struct ps;
+       if (len > 0) {
+               info3_ndr = response->extra_data;
+               if (!prs_init(&ps, len, mem_ctx, UNMARSHALL)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               prs_append_data(&ps, info3_ndr, len);
+               ps.data_offset = 0;
+               if (!net_io_user_info3("", info3, &ps, 1, 3)) {
+                       DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+               prs_mem_free(&ps);
+
+               return NT_STATUS_OK;
+       } else {
+               DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+}
 
 /* Authenticate a user with a challenge/response */
 
@@ -44,11 +68,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
        struct winbindd_request request;
        struct winbindd_response response;
         NSS_STATUS result;
-        struct passwd *pw;
        NTSTATUS nt_status;
+        NET_USER_INFO_3 info3;
 
        if (!user_info) {
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_INVALID_PARAMETER;
        }
 
        if (!auth_context) {
@@ -62,11 +86,14 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
        ZERO_STRUCT(request);
        ZERO_STRUCT(response);
 
-       snprintf(request.data.auth_crap.user, sizeof(request.data.auth_crap.user),
-                "%s\\%s", user_info->domain.str, user_info->smb_name.str);
+       request.data.auth_crap.flags = WINBIND_PAM_INFO3_NDR;
 
-       fstrcpy(request.data.auth_crap.user, user_info->smb_name.str);
-       fstrcpy(request.data.auth_crap.domain, user_info->domain.str);
+       push_utf8_fstring(request.data.auth_crap.user, 
+                         user_info->smb_name.str);
+       push_utf8_fstring(request.data.auth_crap.domain, 
+                         user_info->domain.str);
+       push_utf8_fstring(request.data.auth_crap.workstation, 
+                         user_info->wksta_name.str);
 
        memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
        
@@ -76,27 +103,28 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
                                                 sizeof(request.data.auth_crap.nt_resp));
        
        memcpy(request.data.auth_crap.lm_resp, user_info->lm_resp.data, 
-              sizeof(request.data.auth_crap.lm_resp_len));
-       memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data, 
               request.data.auth_crap.lm_resp_len);
+       memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data, 
+              request.data.auth_crap.nt_resp_len);
        
        result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
 
-       if (result == NSS_STATUS_SUCCESS) {
-               
-               pw = Get_Pwnam(user_info->internal_username.str);
-               
-               if (pw) {                       
-                       if (make_server_info_pw(server_info, pw)) {
-                               nt_status = NT_STATUS_OK;
-                       } else {
-                               nt_status = NT_STATUS_NO_MEMORY;
+       nt_status = NT_STATUS(response.data.auth.nt_status);
+
+       if (result == NSS_STATUS_SUCCESS && response.extra_data) {
+               if (NT_STATUS_IS_OK(nt_status)) {
+                       if (NT_STATUS_IS_OK(nt_status = get_info3_from_ndr(mem_ctx, &response, &info3))) { 
+                               nt_status = 
+                                       make_server_info_info3(mem_ctx, 
+                                                              user_info->internal_username.str, 
+                                                              user_info->smb_name.str, 
+                                                              user_info->domain.str, 
+                                                              server_info, 
+                                                              &info3); 
                        }
-               } else {
-                       nt_status = NT_STATUS_NO_SUCH_USER;
                }
-       } else {
-               nt_status = NT_STATUS_LOGON_FAILURE;
+       } else if (NT_STATUS_IS_OK(nt_status)) {
+               nt_status = NT_STATUS_UNSUCCESSFUL;
        }
 
         return nt_status;
index 43b0ef44bc745aec7752eaa3aa63c8180377ed2c..c453cfbb5488bbe4fedd9902570c912d05b83372 100644 (file)
@@ -492,7 +492,7 @@ static int strslashcmp(char *s1, char *s2)
   if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0;
 
   /* check for s1 is an "initial" string of s2 */
-  if (*s2 == '/' || *s2 == '\\') return 0;
+  if ((*s2 == '/' || *s2 == '\\') && !*s1) return 0;
 
   return *s1-*s2;
 }
index ad050063ec4e7dbd0b679d440829426a79def887..0db990e8bd63204a2fb9841a38e6f90a8cd2f1f6 100644 (file)
@@ -29,7 +29,6 @@
 extern BOOL in_client;
 extern pstring user_socket_options;
 extern BOOL append_log;
-extern fstring remote_machine;
 
 static pstring credentials;
 static pstring my_netbios_name;
@@ -377,7 +376,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
                        }
 
                        /* here we are no longer interactive */
-                       pstrcpy(remote_machine, "smbmount");    /* sneaky ... */
+                       set_remote_machine_name("smbmount");    /* sneaky ... */
                        setup_logging("mount.smbfs", False);
                        append_log = True;
                        reopen_logs();
index b78d9d22a80212cafcc4140044e6ae82e6bcc322..ecb5c311c54394bed89574196acc516b71311fc8 100644 (file)
@@ -282,20 +282,17 @@ smb_connect(char *workgroup,              /* I - Workgroup */
   get_myname(myname);  
        
   nt_status = cli_full_connection(&c, myname, server, NULL, 0, share, "?????", 
-                                 username, lp_workgroup(), password, 0);
+                                 username, workgroup, password, 0);
   
-  if (NT_STATUS_IS_OK(nt_status)) {
-         return c;
-  } else {
+  if (!NT_STATUS_IS_OK(nt_status)) {
          fprintf(stderr, "ERROR:  Connection failed with error %s\n", nt_errstr(nt_status));
          return NULL;
   }
 
-
- /*
-  * Return the new connection...
-  */
-
+  /*
+   * Return the new connection...
+   */
+  
   return (c);
 }
 
index be0e78133a745c50d4b6993c856abfd334be45d6..06694c8e64a87c6c042a806bde5c704b2e26af9d 100755 (executable)
@@ -5932,7 +5932,7 @@ else
 fi
 done
 
-for ac_func in syslog vsyslog
+for ac_func in syslog vsyslog getgrouplist
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
 echo "configure:5939: checking for $ac_func" >&5
@@ -13763,6 +13763,10 @@ WINBIND_PAM_PROGS=""
 
 if test x"$HAVE_WINBIND" = x"yes"; then
         echo "$ac_t""yes" 1>&6
+       cat >> confdefs.h <<\EOF
+#define WITH_WINBIND 1
+EOF
+
 
        WINBIND_TARGETS="bin/wbinfo"
        WINBIND_STARGETS="bin/winbindd"
@@ -13777,58 +13781,6 @@ else
 fi
 
 
-# Check for FreeBSD problem with getgroups
-# It returns EGID too many times in the list of groups
-# and causes a security problem
-echo $ac_n "checking whether or not getgroups returns EGID too many times""... $ac_c" 1>&6
-echo "configure:13785: checking whether or not getgroups returns EGID too many times" >&5
-if eval "test \"`echo '$''{'samba_cv_have_getgroups_too_many_egids'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  samba_cv_have_getgroups_too_many_egids=cross
-else
-  cat > conftest.$ac_ext <<EOF
-#line 13793 "configure"
-#include "confdefs.h"
-
-#include <sys/types.h>
-#include <stdio.h>
-
-int main(int argc, char *argv[])
-{
-  gid_t groups[10];
-  int n = 10;
-
-  n = getgroups(n, &groups);
-  /* Could actually pass back the number of EGIDs there ... */
-  exit((n > 1 && groups[0] == getegid() && groups[1] == getegid()) ? 1 : 0);
-}
-EOF
-if { (eval echo configure:13809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
-  samba_cv_have_getgroups_too_many_egids=no
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  samba_cv_have_getgroups_too_many_egids=yes
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$samba_cv_have_getgroups_too_many_egids" 1>&6
-if test x"$samba_cv_have_getgroups_too_many_egids" = x"yes"; then
-    cat >> confdefs.h <<\EOF
-#define HAVE_GETGROUPS_TOO_MANY_EGIDS 1
-EOF
-
-fi
-
-
-
 # Substitution time!
 
 
 #              [#include <pwd.h>])
 
 echo $ac_n "checking whether struct passwd has pw_comment""... $ac_c" 1>&6
-echo "configure:13852: checking whether struct passwd has pw_comment" >&5
+echo "configure:13804: checking whether struct passwd has pw_comment" >&5
 if eval "test \"`echo '$''{'samba_cv_passwd_pw_comment'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
     cat > conftest.$ac_ext <<EOF
-#line 13858 "configure"
+#line 13810 "configure"
 #include "confdefs.h"
 #include <pwd.h>
 int main() {
 struct passwd p; p.pw_comment;
 ; return 0; }
 EOF
-if { (eval echo configure:13865: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:13817: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_passwd_pw_comment=yes
 else
 #              [#include <pwd.h>])
 
 echo $ac_n "checking whether struct passwd has pw_age""... $ac_c" 1>&6
-echo "configure:13890: checking whether struct passwd has pw_age" >&5
+echo "configure:13842: checking whether struct passwd has pw_age" >&5
 if eval "test \"`echo '$''{'samba_cv_passwd_pw_age'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
     cat > conftest.$ac_ext <<EOF
-#line 13896 "configure"
+#line 13848 "configure"
 #include "confdefs.h"
 #include <pwd.h>
 int main() {
 struct passwd p; p.pw_age;
 ; return 0; }
 EOF
-if { (eval echo configure:13903: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:13855: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   samba_cv_passwd_pw_age=yes
 else
@@ -13938,7 +13890,7 @@ fi
 
 if test x"$INCLUDED_POPT" != x"yes"; then
     echo $ac_n "checking for poptGetContext in -lpopt""... $ac_c" 1>&6
-echo "configure:13942: checking for poptGetContext in -lpopt" >&5
+echo "configure:13894: 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
@@ -13946,7 +13898,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lpopt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 13950 "configure"
+#line 13902 "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
@@ -13957,7 +13909,7 @@ int main() {
 poptGetContext()
 ; return 0; }
 EOF
-if { (eval echo configure:13961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:13913: \"$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
@@ -13981,9 +13933,9 @@ fi
 fi
 
 echo $ac_n "checking whether to use included popt""... $ac_c" 1>&6
-echo "configure:13985: checking whether to use included popt" >&5
+echo "configure:13937: checking whether to use included popt" >&5
 if test x"$INCLUDED_POPT" = x"yes"; then
-    echo "$ac_t""$srcdir/popt" 1>&6
+    echo "$ac_t""yes" 1>&6
     BUILD_POPT='$(POPT_OBJS)'
     FLAGS1="-I$srcdir/popt"
 else
 # final configure stuff
 
 echo $ac_n "checking configure summary""... $ac_c" 1>&6
-echo "configure:14008: checking configure summary" >&5
+echo "configure:13960: checking configure summary" >&5
 if test "$cross_compiling" = yes; then
   echo "configure: warning: cannot run when cross-compiling" 1>&2
 else
   cat > conftest.$ac_ext <<EOF
-#line 14013 "configure"
+#line 13965 "configure"
 #include "confdefs.h"
 #include "${srcdir-.}/tests/summary.c"
 EOF
-if { (eval echo configure:14017: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:13969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   echo "$ac_t""yes" 1>&6
 else
@@ -14130,7 +14082,7 @@ done
 ac_given_srcdir=$srcdir
 ac_given_INSTALL="$INSTALL"
 
-trap 'rm -fr `echo "include/stamp-h Makefile script/findsmb include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+trap 'rm -fr `echo "include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
 
@@ -14264,7 +14216,7 @@ EOF
 
 cat >> $CONFIG_STATUS <<EOF
 
-CONFIG_FILES=\${CONFIG_FILES-"include/stamp-h Makefile script/findsmb"}
+CONFIG_FILES=\${CONFIG_FILES-"include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
index 915c91e5850d7f0684597abd8e8ed1b0f20b3514..db34c266c584a72442e06b518b066e1e8da48638 100644 (file)
@@ -746,7 +746,7 @@ AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate
 AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64)
 AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf)
 AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink)
-AC_CHECK_FUNCS(syslog vsyslog)
+AC_CHECK_FUNCS(syslog vsyslog getgrouplist)
 # setbuffer is needed for smbtorture
 AC_CHECK_FUNCS(setbuffer)
 
@@ -2695,6 +2695,7 @@ WINBIND_PAM_PROGS=""
 
 if test x"$HAVE_WINBIND" = x"yes"; then
         AC_MSG_RESULT(yes)
+       AC_DEFINE(WITH_WINBIND)
 
        WINBIND_TARGETS="bin/wbinfo"
        WINBIND_STARGETS="bin/winbindd"
@@ -2709,30 +2710,6 @@ else
 fi
 
 
-# Check for FreeBSD problem with getgroups
-# It returns EGID too many times in the list of groups
-# and causes a security problem
-AC_CACHE_CHECK([whether or not getgroups returns EGID too many times],
-    samba_cv_have_getgroups_too_many_egids,[AC_TRY_RUN([
-#include <sys/types.h>
-#include <stdio.h>
-
-int main(int argc, char *argv[])
-{
-  gid_t groups[10];
-  int n = 10;
-
-  n = getgroups(n, &groups);
-  /* Could actually pass back the number of EGIDs there ... */
-  exit((n > 1 && groups[0] == getegid() && groups[1] == getegid()) ? 1 : 0);
-}],
-       samba_cv_have_getgroups_too_many_egids=no,samba_cv_have_getgroups_too_many_egids=yes, samba_cv_have_getgroups_too_many_egids=cross)])
-if test x"$samba_cv_have_getgroups_too_many_egids" = x"yes"; then
-    AC_DEFINE(HAVE_GETGROUPS_TOO_MANY_EGIDS)
-fi
-
-
-
 # Substitution time!
 
 AC_SUBST(WINBIND_TARGETS)
@@ -2791,7 +2768,7 @@ fi
 
 AC_MSG_CHECKING(whether to use included popt)
 if test x"$INCLUDED_POPT" = x"yes"; then
-    AC_MSG_RESULT($srcdir/popt)
+    AC_MSG_RESULT(yes)
     BUILD_POPT='$(POPT_OBJS)'
     FLAGS1="-I$srcdir/popt"
 else
@@ -2820,7 +2797,7 @@ AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
 builddir=`pwd`
 AC_SUBST(builddir)
 
-AC_OUTPUT(include/stamp-h Makefile script/findsmb)
+AC_OUTPUT(include/stamp-h Makefile script/findsmb ../examples/VFS/Makefile ../examples/VFS/block/Makefile)
 
 #################################################
 # Print very concise instructions on building/use
index b3e18f18b8ddd29d1a63dbc2f1452df54ae49192..7504a369b4b9aab5d8803b81d34f53a904239e55 100644 (file)
@@ -5,18 +5,34 @@
 */
 
 typedef struct {
-       void *ld;
-       char *realm;
-       char *workgroup;
-       char *ldap_server;
-       char *ldap_server_name;
-       char *kdc_server;
+       void *ld; /* the active ldap structure */
+       struct in_addr ldap_ip; /* the ip of the active connection, if any */
+       time_t last_attempt; /* last attempt to reconnect */
        int ldap_port;
-       char *bind_path;
-       time_t last_attempt;
-       char *password;
-       char *user_name;
-       char *server_realm;
+       
+       /* info needed to find the server */
+       struct {
+               char *realm;
+               char *workgroup;
+               char *ldap_server;
+               int foreign; /* set to 1 if connecting to a foreign realm */
+       } server;
+
+       /* info needed to authenticate */
+       struct {
+               char *realm;
+               char *password;
+               char *user_name;
+               char *kdc_server;
+               int no_bind;
+       } auth;
+
+       /* info derived from the servers config */
+       struct {
+               char *realm;
+               char *bind_path;
+               char *ldap_server_name;
+       } config;
 } ADS_STRUCT;
 
 typedef struct {
@@ -94,7 +110,7 @@ typedef void **ADS_MODLIST;
 
 /* macros to simplify error returning */
 #define ADS_ERROR(rc) ads_build_error(ADS_ERROR_LDAP, rc, 0)
-#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc, 0)
+#define ADS_ERROR_SYSTEM(rc) ads_build_error(ADS_ERROR_SYSTEM, rc?rc:EINVAL, 0)
 #define ADS_ERROR_KRB5(rc) ads_build_error(ADS_ERROR_KRB5, rc, 0)
 #define ADS_ERROR_GSS(rc, minor) ads_build_error(ADS_ERROR_GSS, rc, minor)
 
@@ -129,3 +145,25 @@ typedef void **ADS_MODLIST;
 /* account types */
 #define ATYPE_GROUP               0x10000000
 #define ATYPE_USER                0x30000000
+
+/* Mailslot or cldap getdcname response flags */
+#define ADS_PDC            0x00000001  /* DC is PDC */
+#define ADS_GC             0x00000004  /* DC is a GC of forest */
+#define ADS_LDAP           0x00000008  /* DC is an LDAP server */
+#define ADS_DS             0x00000010  /* DC supports DS */
+#define ADS_KDC            0x00000020  /* DC is running KDC */
+#define ADS_TIMESERV       0x00000040  /* DC is running time services */
+#define ADS_CLOSEST        0x00000080  /* DC is closest to client */
+#define ADS_WRITABLE       0x00000100  /* DC has writable DS */
+#define ADS_GOOD_TIMESERV  0x00000200  /* DC has hardware clock
+                                        (and running time) */
+#define ADS_NDNC           0x00000400  /* DomainName is non-domain NC serviced
+                                        by LDAP server */
+#define ADS_PINGS          0x0000FFFF  /* Ping response */
+#define ADS_DNS_CONTROLLER 0x20000000  /* DomainControllerName is a DNS name*/
+#define ADS_DNS_DOMAIN     0x40000000  /* DomainName is a DNS name */
+#define ADS_DNS_FOREST     0x80000000  /* DnsForestName is a DNS name */
+
+/* DomainCntrollerAddressType */
+#define ADS_INET_ADDRESS      0x00000001
+#define ADS_NETBIOS_ADDRESS   0x00000002
index ac28c0856cf3fb71874ed64d987281cf2bb93c29..4a138b6db6ad5d97c52e1f930b9d503f539b6cab 100644 (file)
 #undef _GNU_SOURCE
 #endif
 
+#undef LDAP_SET_REBIND_PROC_ARGS
+
 /* The number of bytes in a int.  */
 #undef SIZEOF_INT
 
 /* Define if you have the getgrnam function.  */
 #undef HAVE_GETGRNAM
 
+/* Define if you have the getgrouplist function.  */
+#undef HAVE_GETGROUPLIST
+
 /* Define if you have the getnetgrent function.  */
 #undef HAVE_GETNETGRENT
 
 /* Define if you have the innetgr function.  */
 #undef HAVE_INNETGR
 
+/* Define if you have the ldap_set_rebind_proc function.  */
+#undef HAVE_LDAP_SET_REBIND_PROC
+
 /* Define if you have the link function.  */
 #undef HAVE_LINK
 
 /* Define if you have the <ctype.h> header file.  */
 #undef HAVE_CTYPE_H
 
-/* Define if you have the <cups/cups.h> header file.  */
-#undef HAVE_CUPS_CUPS_H
-
-/* Define if you have the <cups/language.h> header file.  */
-#undef HAVE_CUPS_LANGUAGE_H
-
 /* Define if you have the <dirent.h> header file.  */
 #undef HAVE_DIRENT_H
 
 /* Define if you have the acl library (-lacl).  */
 #undef HAVE_LIBACL
 
-/* Define if you have the cups library (-lcups).  */
-#undef HAVE_LIBCUPS
-
 /* Define if you have the gen library (-lgen).  */
 #undef HAVE_LIBGEN
 
index 435810a1babc51c3f54fb4a2ae07be1c9c25e67d..6084d583ed6aa5b5235f520f16a76ce39bc81188 100644 (file)
@@ -707,9 +707,11 @@ extern int errno;
 #include "hash.h"
 #include "trans2.h"
 #include "nterr.h"
+#include "ntioctl.h"
 #include "messages.h"
 #include "charset.h"
 #include "dynconfig.h"
+#include "adt_tree.h"
 
 #include "util_getent.h"
 
index 24f3fa772463b8e361ef3186a3db9161dad41a69..2538715c4122985046f1368e7478e3be99db7053 100644 (file)
    than 62*62 for the current code */
 #define MAX_SESSION_ID 3000
 
+/* For the benifit of PAM and the 'session exec' scripts, we fake up a terminal
+   name. This can be in one of two forms:  The first for systems not using
+   utmp (and therefore not constrained as to length or the need for a number
+   < 3000 or so) and the second for systems with this 'well behaved terminal
+   like name' constraint.
+*/
+
 #ifndef SESSION_TEMPLATE
-#define SESSION_TEMPLATE "smb/%d"
+/* Paramaters are 'pid' and 'vuid' */
+#define SESSION_TEMPLATE "smb/%lu/%d"
+#endif
+
+#ifndef SESSION_UTMP_TEMPLATE
+#define SESSION_UTMP_TEMPLATE "smb/%d"
 #endif
 
 /* the maximum age in seconds of a password. Should be a lp_ parameter */
index 79a08a754626f7b39f05c8f3313f9b0dd5ee2c02..58e606b40fa453c0242319082edc501610e4a69a 100644 (file)
@@ -51,6 +51,7 @@
 /* #define MSG_PRINTER_NOTIFY  2001*/ /* Obsolete */
 #define MSG_PRINTER_DRVUPGRADE 2002
 #define MSG_PRINTER_NOTIFY2     2003
+#define MSG_PRINTERDATA_INIT_RESET     2004
 
 /* smbd messages */
 #define MSG_SMB_CONF_UPDATED 3001
index fefa243c3fda805ad13faee0840dc32da4340cdc..14561cf44d1e0ae3f6f2ea5c9e06b633c689807a 100644 (file)
@@ -557,6 +557,8 @@ struct packet_struct
 #define SAMLOGON       18
 #define SAMLOGON_R     19
 #define SAMLOGON_UNK_R 21
+#define SAMLOGON_AD_UNK_R 23
+#define SAMLOGON_AD_R   25
 
 /* Ids for netbios packet types. */
 
index 57181c66591912fcc3f7d38feb992524488e0c93..5e2b8f7f64a35825eb5e729af363402c0fd770b7 100644 (file)
@@ -174,14 +174,27 @@ typedef struct nt_printer_driver_info_level
        NT_PRINTER_DRIVER_INFO_LEVEL_6 *info_6;
 } NT_PRINTER_DRIVER_INFO_LEVEL;
 
-typedef struct nt_printer_param
-{
-       fstring value;
-       uint32 type;
-       uint8 *data;
-       int data_len;
-       struct nt_printer_param *next;
-} NT_PRINTER_PARAM;
+/* predefined registry key names for printer data */
+
+#define SPOOL_PRINTERDATA_KEY          "PrinterDriverData"
+#define SPOOL_DSSPOOLER_KEY            "DsSpooler"
+#define SPOOL_DSDRIVER_KEY             "DsDriver"
+#define SPOOL_DSUSER_KEY               "DsUser"
+#define SPOOL_PNPDATA_KEY              "PnPData"
+
+/* container for a single registry key */
+
+typedef struct {
+       char            *name;
+       REGVAL_CTR      values;
+} NT_PRINTER_KEY;
+
+/* container for all printer data */
+
+typedef struct {
+       int             num_keys;
+       NT_PRINTER_KEY  *keys;
+} NT_PRINTER_DATA;
 
 typedef struct ntdevicemode
 {
@@ -246,9 +259,8 @@ typedef struct nt_printer_info_level_2
        fstring printprocessor;
        fstring datatype;
        fstring parameters;
-       NT_PRINTER_PARAM *specific;
+       NT_PRINTER_DATA data;
        SEC_DESC_BUF *secdesc_buf;
-       /* not used but ... and how ??? */
        uint32 changeid;
        uint32 c_setprinter;
        uint32 setuptime;       
index a79c8a0289fd6b76f510ba4b7dfe24deaa5391a0..7a791ddac4fd67e3c3026254fb615dc86a4522a1 100644 (file)
@@ -57,7 +57,7 @@ typedef struct pdb_context
        
        BOOL (*pdb_getsampwnam)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const char *username);
        
-       BOOL (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, DOM_SID *sid);
+       BOOL (*pdb_getsampwsid)(struct pdb_context *, SAM_ACCOUNT *sam_acct, const DOM_SID *sid);
        
        BOOL (*pdb_add_sam_account)(struct pdb_context *, SAM_ACCOUNT *sampass);
        
@@ -88,7 +88,7 @@ typedef struct pdb_methods
        
        BOOL (*getsampwnam)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const char *username);
        
-       BOOL (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, DOM_SID *Sid);
+       BOOL (*getsampwsid)(struct pdb_methods *, SAM_ACCOUNT *sam_acct, const DOM_SID *Sid);
        
        BOOL (*add_sam_account)(struct pdb_methods *, SAM_ACCOUNT *sampass);
        
index 8e42ac7d2cb9a345e455edb59221b8f01f77148f..39f3e47dc852892889cab4edb826dc0d16f90888 100644 (file)
@@ -73,6 +73,7 @@
 #define LSA_RETRPRIVDATA       0x2b
 #define LSA_OPENPOLICY2        0x2c
 #define LSA_UNK_GET_CONNUSER   0x2d /* LsaGetConnectedCredentials ? */
+#define LSA_QUERYINFO2         0x2e
 
 /* XXXX these are here to get a compile! */
 #define LSA_LOOKUPRIDS      0xFD
@@ -261,6 +262,43 @@ typedef struct lsa_r_query_info
 
 } LSA_R_QUERY_INFO;
 
+/* LSA_DNS_DOM_INFO - DNS domain info - info class 12*/
+typedef struct lsa_dns_dom_info
+{
+       UNIHDR  hdr_nb_dom_name; /* netbios domain name */
+       UNIHDR  hdr_dns_dom_name;
+       UNIHDR  hdr_forest_name;
+
+       GUID       dom_guid; /* domain GUID */
+
+       UNISTR2 uni_nb_dom_name;
+       UNISTR2 uni_dns_dom_name;
+       UNISTR2 uni_forest_name;
+
+       uint32 ptr_dom_sid;
+       DOM_SID2   dom_sid; /* domain SID */
+} LSA_DNS_DOM_INFO;
+
+typedef union lsa_info2_union
+{
+       LSA_DNS_DOM_INFO dns_dom_info;
+} LSA_INFO2_UNION;
+
+/* LSA_Q_QUERY_INFO2 - LSA query info */
+typedef struct lsa_q_query_info2
+{
+       POLICY_HND pol;    /* policy handle */
+       uint16 info_class; /* info class */
+} LSA_Q_QUERY_INFO2;
+
+typedef struct lsa_r_query_info2
+{
+       uint32 ptr;    /* pointer to info struct */
+       uint16 info_class;
+       LSA_INFO2_UNION info; /* so far the only one */
+       NTSTATUS status;
+} LSA_R_QUERY_INFO2;
+
 /* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
 typedef struct lsa_enum_trust_dom_info
 {
index 3f3db0f2ba0f9f96532d680af548d0dbf6f31063..92175cf287bd3983ba9e89f4d45da02ef6247d51 100644 (file)
@@ -1,9 +1,10 @@
 /* 
    Unix SMB/CIFS implementation.
    SMB parameters and setup
-   Copyright (C) Andrew Tridgell 1992-1997
-   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
-   Copyright (C) Paul Ashton 1997
+   Copyright (C) Andrew Tridgell                 1992-1997.
+   Copyright (C) Luke Kenneth Casson Leighton    1996-1997.
+   Copyright (C) Paul Ashton                          1997.
+   Copyright (C) Gerald Carter                        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
 
 /* winreg pipe defines 
    NOT IMPLEMENTED !!
-#define REG_OPEN_HKCR          0x00
 #define _REG_UNK_01            0x01
 #define _REG_UNK_03            0x03
 #define REG_CREATE_KEY         0x06
 #define REG_DELETE_KEY         0x07
 #define REG_DELETE_VALUE       0x08
-#define REG_ENUM_VALUE         0x0a
 #define REG_FLUSH_KEY          0x0b
 #define REG_GET_KEY_SEC                0x0c
 #define        _REG_UNK_0D             0x0d
 #define _REG_UNK_0E            0x0e
 #define        _REG_UNK_12             0x12
 #define _REG_UNK_13            0x13
-#define        _REG_UNK_14             0x14
 #define REG_SET_KEY_SEC                0x15
 #define REG_CREATE_VALUE       0x16
 #define        _REG_UNK_17             0x17
 */
 
 /* Implemented */
+#define REG_OPEN_HKCR          0x00
 #define REG_OPEN_HKLM          0x02
 #define REG_OPEN_HKU           0x04
 #define REG_CLOSE              0x05
 #define REG_ENUM_KEY           0x09
+#define REG_ENUM_VALUE         0x0a
 #define REG_OPEN_ENTRY         0x0f
 #define REG_QUERY_KEY          0x10
 #define REG_INFO               0x11
 #define REG_SHUTDOWN           0x18
 #define REG_ABORT_SHUTDOWN     0x19
+#define        REG_SAVE_KEY            0x14    /* no idea what the real name is */
 #define REG_UNKNOWN_1A         0x1a
 
 
 #define HKEY_LOCAL_MACHINE     0x80000002
 #define HKEY_USERS             0x80000003
 
+#define KEY_HKLM       "HKLM"
+#define KEY_HKU                "HKU"
+#define KEY_HKCR       "HKCR"
+#define KEY_PRINTING   "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print"
+#define KEY_TREE_ROOT  ""
+
 /* Registry data types */
 
 #define REG_NONE                       0
 #define REG_FORCE_SHUTDOWN 0x001
 #define REG_REBOOT_ON_SHUTDOWN 0x100
 
+/* structure to contain registry values */
+
+typedef struct {
+       fstring         valuename;
+       uint16          type;
+       uint32          size;   /* in bytes */
+       uint8           *data_p;
+} REGISTRY_VALUE;
+
+/* container for regostry values */
+
+typedef struct {
+       TALLOC_CTX      *ctx;
+       uint32          num_values;
+       REGISTRY_VALUE  **values;
+} REGVAL_CTR;
+
+/* container for registry subkey names */
+
+typedef struct {
+       TALLOC_CTX      *ctx;
+       uint32          num_subkeys;
+       char            **subkeys;
+} REGSUBKEY_CTR;
+
+
+/* 
+ * container for function pointers to enumeration routines
+ * for vitural registry view 
+ */ 
+typedef struct {
+       /* functions for enumerating subkeys and values */      
+       int     (*subkey_fn)( char *key, REGSUBKEY_CTR *subkeys);
+       int     (*value_fn) ( char *key, REGVAL_CTR *val );
+       BOOL    (*store_subkeys_fn)( char *key, REGSUBKEY_CTR *subkeys );
+       BOOL    (*store_values_fn)( char *key, REGVAL_CTR *val );
+} REGISTRY_OPS;
+
+typedef struct {
+       char            *keyname;       /* full path to name of key */
+       REGISTRY_OPS    *ops;           /* registry function hooks */
+} REGISTRY_HOOK;
+
+
+
+/* structure to store the registry handles */
+
+typedef struct _RegistryKey {
+
+       struct _RegistryKey *prev, *next;
+
+       POLICY_HND      hnd;
+       pstring         name;   /* full name of registry key */
+       REGISTRY_HOOK   *hook;
+       
+} REGISTRY_KEY;
+
+
 /* REG_Q_OPEN_HKCR   */
 typedef struct q_reg_open_hkcr_info
 {
@@ -107,7 +173,7 @@ typedef struct q_reg_open_hklm_info
        uint32 ptr;
        uint16 unknown_0;       /* 0xE084      - 16 bit unknown */
        uint16 unknown_1;       /* random.  changes */
-       uint32 access_mask;     /* 0x0000 0002 - 32 bit unknown */
+       uint32 access_mask;
 
 }
 REG_Q_OPEN_HKLM;
@@ -246,6 +312,7 @@ typedef struct q_reg_query_value_info
        uint32 ptr2;       /* pointer */
        uint32 len_value2; /* */
 
+
 } REG_Q_ENUM_VALUE;
 
 /* REG_R_ENUM_VALUE */
@@ -258,7 +325,7 @@ typedef struct r_reg_enum_value_info
        uint32 type;        /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */
 
        uint32 ptr_value;       /* pointer */
-       BUFFER2 *buf_value;    /* value, in byte buffer */
+       BUFFER2 buf_value;    /* value, in byte buffer */
 
        uint32 ptr1;            /* pointer */
        uint32 len_value1;       /* */
@@ -388,6 +455,29 @@ typedef struct r_reg_unk_1a_info
 } REG_R_UNKNOWN_1A;
 
 
+/* REG_Q_UNKNOWN_1A */
+typedef struct q_reg_unknown_14
+{
+       POLICY_HND pol;       /* policy handle */
+       
+       UNIHDR  hdr_file;       /* unicode product type header */
+       UNISTR2 uni_file;       /* local filename to save key as from regedt32.exe */
+                               /* e.g. "c:\temp\test.dat" */
+       
+       uint32 unknown;         /* 0x0000 0000 */
+
+} REG_Q_SAVE_KEY;
+
+
+/* REG_R_UNKNOWN_1A */
+typedef struct r_reg_unknown_14
+{
+       NTSTATUS status;         /* return status */
+
+} REG_R_SAVE_KEY;
+
+
+
 /* REG_Q_CLOSE */
 typedef struct reg_q_close_info
 {
@@ -481,7 +571,7 @@ typedef struct r_reg_info_info
        uint32 type;            /* key datatype  */
 
        uint32 ptr_uni_val;     /* key value pointer */
-       BUFFER2 *uni_val;       /* key value */
+       BUFFER2 uni_val;        /* key value */
 
        uint32 ptr_max_len;
        uint32 buf_max_len;
index 78d5c244a6f99dd76b0f69685da5636b01c41503..11438ae06760263a906eba6f6150518b7e291afe 100644 (file)
@@ -4,7 +4,10 @@
    Copyright (C) Andrew Tridgell              1992-2000
    Copyright (C) Luke Kenneth Casson Leighton 1996-2000
    Copyright (C) Paul Ashton                  1997-2000
-   Copyright (C) Jean François Micouleau      1998-2001.
+   Copyright (C) Jean François Micouleau      1998-2001
+   Copyright (C) Anthony Liguori              2002
+   Copyright (C) Jim McDonough                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
 #ifndef _RPC_SAMR_H /* _RPC_SAMR_H */
 #define _RPC_SAMR_H 
 
-
 #include "rpc_misc.h"
 
-
 /*******************************************************************
  the following information comes from a QuickView on samsrv.dll,
  and gives an idea of exactly what is needed:
@@ -144,6 +145,7 @@ SamrTestPrivateFunctionsUser
 #define SAMR_GET_DOM_PWINFO    0x38
 #define SAMR_CONNECT           0x39
 #define SAMR_SET_USERINFO      0x3A
+#define SAMR_CONNECT4          0x3E
 
 /* Access bits to the SAM-object */
 
@@ -176,17 +178,17 @@ SamrTestPrivateFunctionsUser
 
 /* Access bits to Domain-objects */
 
-#define DOMAIN_ACCESS_LOOKUP_INFO_1  0x000000001
-#define DOMAIN_ACCESS_SET_INFO_1     0x000000002
-#define DOMAIN_ACCESS_LOOKUP_INFO_2  0x000000004
-#define DOMAIN_ACCESS_SET_INFO_2     0x000000008
-#define DOMAIN_ACCESS_CREATE_USER    0x000000010
-#define DOMAIN_ACCESS_CREATE_GROUP   0x000000020
-#define DOMAIN_ACCESS_CREATE_ALIAS   0x000000040
-#define DOMAIN_ACCESS_UNKNOWN_80     0x000000080
-#define DOMAIN_ACCESS_ENUM_ACCOUNTS  0x000000100
-#define DOMAIN_ACCESS_OPEN_ACCOUNT   0x000000200
-#define DOMAIN_ACCESS_SET_INFO_3     0x000000400
+#define DOMAIN_ACCESS_LOOKUP_INFO_1  0x00000001
+#define DOMAIN_ACCESS_SET_INFO_1     0x00000002
+#define DOMAIN_ACCESS_LOOKUP_INFO_2  0x00000004
+#define DOMAIN_ACCESS_SET_INFO_2     0x00000008
+#define DOMAIN_ACCESS_CREATE_USER    0x00000010
+#define DOMAIN_ACCESS_CREATE_GROUP   0x00000020
+#define DOMAIN_ACCESS_CREATE_ALIAS   0x00000040
+#define DOMAIN_ACCESS_UNKNOWN_80     0x00000080
+#define DOMAIN_ACCESS_ENUM_ACCOUNTS  0x00000100
+#define DOMAIN_ACCESS_OPEN_ACCOUNT   0x00000200
+#define DOMAIN_ACCESS_SET_INFO_3     0x00000400
 
 #define DOMAIN_ALL_ACCESS  ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
                              DOMAIN_ACCESS_SET_INFO_3        | \
@@ -220,17 +222,17 @@ SamrTestPrivateFunctionsUser
 
 /* Access bits to User-objects */
 
-#define USER_ACCESS_GET_NAME_ETC     0x000000001
-#define USER_ACCESS_GET_LOCALE       0x000000002
-#define USER_ACCESS_SET_LOC_COM      0x000000004
-#define USER_ACCESS_GET_LOGONINFO    0x000000008
-#define USER_ACCESS_UNKNOWN_10       0x000000010
-#define USER_ACCESS_SET_ATTRIBUTES   0x000000020
-#define USER_ACCESS_CHANGE_PASSWORD  0x000000040
-#define USER_ACCESS_SET_PASSWORD     0x000000080
-#define USER_ACCESS_GET_GROUPS       0x000000100
-#define USER_ACCESS_UNKNOWN_200      0x000000200
-#define USER_ACCESS_UNKNOWN_400      0x000000400
+#define USER_ACCESS_GET_NAME_ETC     0x00000001
+#define USER_ACCESS_GET_LOCALE       0x00000002
+#define USER_ACCESS_SET_LOC_COM      0x00000004
+#define USER_ACCESS_GET_LOGONINFO    0x00000008
+#define USER_ACCESS_UNKNOWN_10       0x00000010
+#define USER_ACCESS_SET_ATTRIBUTES   0x00000020
+#define USER_ACCESS_CHANGE_PASSWORD  0x00000040
+#define USER_ACCESS_SET_PASSWORD     0x00000080
+#define USER_ACCESS_GET_GROUPS       0x00000100
+#define USER_ACCESS_UNKNOWN_200      0x00000200
+#define USER_ACCESS_UNKNOWN_400      0x00000400
 
 #define USER_ALL_ACCESS    ( STANDARD_RIGHTS_REQUIRED_ACCESS | \
                              USER_ACCESS_UNKNOWN_400       | \
@@ -312,9 +314,6 @@ SamrTestPrivateFunctionsUser
 #define ALIAS_EXECUTE      ( STANDARD_RIGHTS_EXECUTE_ACCESS  | \
                              ALIAS_ACCESS_LOOKUP_INFO )
 
-
-
-
 typedef struct _DISP_USER_INFO {
        SAM_ACCOUNT *sam;
 } DISP_USER_INFO;
@@ -1647,7 +1646,7 @@ typedef struct r_samr_create_user_info
 {
        POLICY_HND user_pol;       /* policy handle associated with user */
 
-       uint32 unknown_0;     /* 0x0007 03ff */
+       uint32 access_granted;
        uint32 user_rid;      /* user RID */
        NTSTATUS status;         /* return status */
 
@@ -1870,6 +1869,19 @@ typedef struct r_samr_connect_info
 
 } SAMR_R_CONNECT;
 
+/* SAMR_Q_CONNECT4 */
+typedef struct q_samr_connect4_info
+{
+       uint32 ptr_srv_name; /* pointer to server name */
+       UNISTR2 uni_srv_name;
+
+       uint32 unk_0; /* possible server name type, 1 for IP num, 2 for name */
+       uint32 access_mask;
+} SAMR_Q_CONNECT4;
+
+/* SAMR_R_CONNECT4 - same format as connect */
+typedef struct r_samr_connect_info SAMR_R_CONNECT4;       
+
 /* SAMR_Q_GET_DOM_PWINFO */
 typedef struct q_samr_get_dom_pwinfo
 {
@@ -2008,6 +2020,4 @@ typedef struct r_samr_set_domain_info
 
 } SAMR_R_SET_DOMAIN_INFO;
 
-
 #endif /* _RPC_SAMR_H */
-
index 7ec9a509bf32ecbe18404dccc0626a983373a817..b7acf44c5de65e036591b499581a1e7829cbbe80 100755 (executable)
 #define NOTIFY_TWO_VALUE 2             /* Notify data is stored in value2 */
 #define NOTIFY_POINTER   3             /* Data is a pointer to a buffer */
 #define NOTIFY_STRING    4             /* Data is a pointer to a buffer w/length */
+#define NOTIFY_SECDESC   5             /* Data is a security descriptor */
 
 #define PRINTER_NOTIFY_TYPE 0x00
 #define JOB_NOTIFY_TYPE     0x01
@@ -801,15 +802,16 @@ typedef struct spool_notify_info_data
        uint16 field;
        uint32 reserved;
        uint32 id;
-       union
-       {
+       union {
                uint32 value[2];
-               struct
-               {
+               struct {
                        uint32 length;
                        uint16 *string;
-               }
-               data;
+               } data;
+               struct {
+                       uint32  size;
+                       SEC_DESC *desc;
+               } sd;
        }
        notify_data;
        uint32 size;
index 1753c19783bb10d93fb4b433aac163f3d962c89f..94d23bb4bc429e136e53a57f53a555e1a88e9255 100644 (file)
@@ -4,6 +4,7 @@
    Copyright (C) Andrew Tridgell 1992-1997
    Copyright (C) Luke Kenneth Casson Leighton 1996-1997
    Copyright (C) Paul Ashton 1997
+   Copyright (C) Nigel Williams 2001
    
    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
@@ -33,6 +34,7 @@
 #define SRV_NET_SHARE_GET_INFO     0x10
 #define SRV_NET_SHARE_SET_INFO     0x11
 #define SRV_NET_SHARE_DEL          0x12
+#define SRV_NET_SHARE_DEL_STICKY   0x13
 #define SRV_NET_SRV_GET_INFO       0x15
 #define SRV_NET_SRV_SET_INFO       0x16
 #define SRV_NET_DISK_ENUM          0x17
@@ -54,7 +56,7 @@ typedef struct disk_enum_container {
        uint32 entries_read;
        uint32 unknown;
        uint32 disk_info_ptr;
-       DISK_INFO disk_info[MAX_SERVER_DISK_ENTRIES];
+       DISK_INFO *disk_info;
 } DISK_ENUM_CONTAINER;
 
 typedef struct net_srv_disk_enum {
@@ -294,6 +296,29 @@ typedef struct r_net_conn_enum_info
 
 } SRV_R_NET_CONN_ENUM;
 
+/* SH_INFO_0 */
+typedef struct ptr_share_info0
+{
+       uint32 ptr_netname; /* pointer to net name. */
+} SH_INFO_0;
+
+/* SH_INFO_0_STR (level 0 share info strings) */
+typedef struct str_share_info0
+{
+        SH_INFO_0 *ptrs;
+
+       UNISTR2 uni_netname; /* unicode string of net name */
+
+} SH_INFO_0_STR;
+
+/* SRV_SHARE_INFO_0 */
+typedef struct share_info_0_info
+{
+       SH_INFO_0 info_0;
+       SH_INFO_0_STR info_0_str;
+
+} SRV_SHARE_INFO_0;
+
 /* SH_INFO_1 (pointers to level 1 share info strings) */
 typedef struct ptr_share_info1
 {
@@ -306,6 +331,8 @@ typedef struct ptr_share_info1
 /* SH_INFO_1_STR (level 1 share info strings) */
 typedef struct str_share_info1
 {
+        SH_INFO_1 *ptrs;
+
        UNISTR2 uni_netname; /* unicode string of net name */
        UNISTR2 uni_remark; /* unicode string of comment */
 
@@ -336,6 +363,8 @@ typedef struct ptr_share_info2
 /* SH_INFO_2_STR (level 2 share info strings) */
 typedef struct str_share_info2
 {
+       SH_INFO_2 *ptrs;
+
        UNISTR2 uni_netname; /* unicode string of net name (e.g NETLOGON) */
        UNISTR2 uni_remark;  /* unicode string of comment (e.g "Logon server share") */
        UNISTR2 uni_path;    /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */
@@ -383,6 +412,8 @@ typedef struct ptr_share_info502
        uint32 num_uses;   /* current uses */
        uint32 ptr_path;   /* pointer to path name */
        uint32 ptr_passwd; /* pointer to password */
+        uint32 reserved;    /* this holds the space taken by the sd in the rpc packet */
+        uint32 reserved_offset;   /* required for _post operation when marshalling */
        uint32 sd_size;    /* size of security descriptor */
        uint32 ptr_sd;     /* pointer to security descriptor */
 
@@ -398,6 +429,7 @@ typedef struct str_share_info502
        UNISTR2 uni_path;    /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */
        UNISTR2 uni_passwd;  /* unicode string of password - presumably for share level security (e.g NULL) */
 
+        uint32 reserved;
        uint32 sd_size;
        SEC_DESC *sd;
 
@@ -411,12 +443,57 @@ typedef struct share_info_502_info
 
 } SRV_SHARE_INFO_502;
 
-/* SRV_SHARE_INFO_1005 */
+typedef struct ptr_share_info1004
+{
+       uint32 ptr_remark;
+
+} SH_INFO_1004;
+
+typedef struct str_share_info1004
+{
+       SH_INFO_1004 *ptrs;
+
+       UNISTR2 uni_remark;
+
+} SH_INFO_1004_STR;
+
+typedef struct ptr_info_1004_info
+{
+       SH_INFO_1004     info_1004; 
+       SH_INFO_1004_STR info_1004_str; 
+} SRV_SHARE_INFO_1004;
+
 typedef struct share_info_1005_info
 {
   uint32 dfs_root_flag; 
 } SRV_SHARE_INFO_1005;
 
+typedef struct share_info_1006_info
+{
+       uint32 max_uses; 
+} SRV_SHARE_INFO_1006;
+
+typedef struct ptr_share_info1007
+{
+       uint32 flags;
+       uint32 ptr_AlternateDirectoryName;
+
+} SH_INFO_1007;
+
+typedef struct str_share_info1007
+{
+       SH_INFO_1007 *ptrs;
+
+       UNISTR2 uni_AlternateDirectoryName;
+
+} SH_INFO_1007_STR;
+
+typedef struct ptr_info_1007_info
+{
+       SH_INFO_1007     info_1007; 
+       SH_INFO_1007_STR info_1007_str; 
+} SRV_SHARE_INFO_1007;
+
 /* SRV_SHARE_INFO_1501 */
 typedef struct share_info_1501_info
 {
@@ -435,10 +512,16 @@ typedef struct srv_share_info_ctr_info
        uint32 num_entries2;
 
        union {
-               SRV_SHARE_INFO_1 *info1; /* share info level 1 */
-               SRV_SHARE_INFO_2 *info2; /* share info level 2 */
-               SRV_SHARE_INFO_501 *info501; /* share info level 501 */
-               SRV_SHARE_INFO_502 *info502; /* share info level 502 */
+               SRV_SHARE_INFO_0    *info0;
+               SRV_SHARE_INFO_1    *info1;    /* share info level 1 */
+               SRV_SHARE_INFO_2    *info2;    /* share info level 2 */
+               SRV_SHARE_INFO_501  *info501;  /* share info level 501 */
+               SRV_SHARE_INFO_502  *info502;  /* share info level 502 */
+               SRV_SHARE_INFO_1004 *info1004;
+               SRV_SHARE_INFO_1005 *info1005;
+               SRV_SHARE_INFO_1006 *info1006;
+               SRV_SHARE_INFO_1007 *info1007;
+               SRV_SHARE_INFO_1501 *info1501;
                void *info;
 
        } share;
@@ -484,19 +567,21 @@ typedef struct q_net_share_get_info_info
 
 } SRV_Q_NET_SHARE_GET_INFO;
 
-/* JRA. NB. We also need level 1004 and 1006 here. */
-
 /* SRV_SHARE_INFO */
 typedef struct srv_share_info {
        uint32 switch_value;
        uint32 ptr_share_ctr;
 
        union {
+               SRV_SHARE_INFO_0    info0;
                SRV_SHARE_INFO_1 info1;
                SRV_SHARE_INFO_2 info2;
                SRV_SHARE_INFO_501 info501;
                SRV_SHARE_INFO_502 info502;
+               SRV_SHARE_INFO_1004 info1004;
                SRV_SHARE_INFO_1005 info1005;
+               SRV_SHARE_INFO_1006 info1006;
+               SRV_SHARE_INFO_1007 info1007;
                SRV_SHARE_INFO_1501 info1501;
        } share;
 } SRV_SHARE_INFO;
@@ -520,12 +605,16 @@ typedef struct q_net_share_set_info_info
 
        SRV_SHARE_INFO info;
 
+        uint32 ptr_parm_error;
+        uint32 parm_error;
+
 } SRV_Q_NET_SHARE_SET_INFO;
 
 /* SRV_R_NET_SHARE_SET_INFO */
 typedef struct r_net_share_set_info
 {
-       uint32 switch_value;         /* switch value */
+        uint32 ptr_parm_error;
+        uint32 parm_error;
 
        WERROR status;               /* return status */
 
@@ -549,7 +638,9 @@ typedef struct q_net_share_add
 /* SRV_R_NET_SHARE_ADD */
 typedef struct r_net_share_add
 {
-       uint32 switch_value;         /* switch value */
+
+        uint32 ptr_parm_error;
+        uint32 parm_error;
 
        WERROR status;               /* return status */
 
@@ -594,9 +685,12 @@ typedef struct str_file_info3_info
 /* SRV_FILE_INFO_3 */
 typedef struct srv_file_info_3
 {
+       uint32 num_entries_read;                     /* EntriesRead */
+       uint32 ptr_file_info;                        /* Buffer */
+
+       uint32 num_entries_read2;                    /* EntriesRead */
        FILE_INFO_3     info_3;     /* file entry details */
        FILE_INFO_3_STR info_3_str; /* file entry strings */
-
 } SRV_FILE_INFO_3;
 
 /* SRV_FILE_INFO_CTR */
index 8a5a573bcc0109471cbdb4e254fe1dbb2a6562aa..183b29d7a8a594baf9cb826cc70b9db6da8e6f93 100644 (file)
 #define SECRETS_DOMAIN_SID    "SECRETS/SID"
 #define SECRETS_SAM_SID       "SAM/SID"
 
+/* The domain GUID and server GUID (NOT the same) are also not secret */
+#define SECRETS_DOMAIN_GUID   "SECRETS/DOMGUID"
+#define SECRETS_SERVER_GUID   "SECRETS/GUID"
+
 #define SECRETS_LDAP_BIND_PW "SECRETS/LDAP_BIND_PW"
 
 /* Authenticated user info is stored in secrets.tdb under these keys */
index a67101ff0997bfa2bd5a28f4e5b64a1a45796995..263dd67c548197e42fda5510a951dcedbe560d0c 100644 (file)
@@ -38,7 +38,9 @@
 
 #define NMB_PORT 137
 #define DGRAM_PORT 138
-#define SMB_PORT 139
+#define SMB_PORT1 445
+#define SMB_PORT2 139
+#define SMB_PORTS "445 139"
 
 #define False (0)
 #define True (1)
@@ -383,7 +385,7 @@ typedef struct files_struct
        int fnum;
        struct connection_struct *conn;
        int fd;
-       int print_jobid;
+       uint32 print_jobid;
        SMB_DEV_T dev;
        SMB_INO_T inode;
        BOOL delete_on_close;
@@ -444,6 +446,15 @@ typedef struct
 #include "smb_acls.h"
 #include "vfs.h"
 
+typedef struct smb_vfs_handle_struct
+{
+    void *data;
+    /* Handle on dlopen() call */
+    void *handle;
+    struct smb_vfs_handle_struct  *next, *prev;
+    
+} smb_vfs_handle_struct;
+
 typedef struct connection_struct
 {
        struct connection_struct *next, *prev;
@@ -461,9 +472,7 @@ typedef struct connection_struct
        char *origpath;
 
        struct vfs_ops vfs_ops;                   /* Filesystem operations */
-       /* Handle on dlopen() call */
-       void *dl_handle;
-       void *vfs_private;
+       struct smb_vfs_handle_struct *vfs_private;
 
        char *user; /* name of user who *opened* this connection */
        uid_t uid; /* uid of user who *opened* this connection */
@@ -1594,8 +1603,8 @@ typedef struct user_struct
 
        uint8 session_key[16];
 
-       int session_id; /* used by utmp and pam session code */
-       
+       char *session_keystr; /* used by utmp and pam session code.  
+                                TDB key string */
        int homes_snum;
 
 } user_struct;
@@ -1667,4 +1676,8 @@ typedef struct {
 
 #define DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH 14
 
+/* Common popt structures */
+
+extern struct poptOption popt_common_debug[];
+
 #endif /* _SMB_H */
index afc40a8cf90cecd58bbbf582cd6948cd29142f1e..74df1c99141c4c7adee3b3cf9fd809f87affddf0 100644 (file)
@@ -1 +1 @@
-#define VERSION "3.0-alpha17"
+#define VERSION "3.0-alpha18"
index 2f9fedf77d3495cf7b4b72b14dc9decc9dbde323..1b1a13d7c125c43ee453812903a8403bb0354725 100644 (file)
@@ -1,7 +1,8 @@
 /* 
    Unix SMB/CIFS implementation.
    VFS structures and parameters
-   Copyright (C) Tim Potter 1999
+   Copyright (C) Tim Potter                            1999
+   Copyright (C) Alexander Bokovoy                     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
@@ -16,6 +17,8 @@
    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.
+
+   This work was sponsored by Optifacio Software Services, Inc.
 */
 
 #ifndef _VFS_H
 
 /* Changed to version 2 for CIFS UNIX extensions (mknod and link added). JRA. */
 /* Changed to version 3 for POSIX acl extensions. JRA. */
-#define SMB_VFS_INTERFACE_VERSION 3
+/* Changed to version 4 for cascaded VFS interface. Alexander Bokovoy. */
+#define SMB_VFS_INTERFACE_VERSION 5
+
+
+/* Version of supported cascaded interface backward copmatibility.
+   (version 4 corresponds to SMB_VFS_INTERFACE_VERSION 4)
+   It is used in vfs_init_custom() to detect VFS modules which conform to cascaded 
+   VFS interface but implement elder version than current version of Samba uses.
+   This allows to use old modules with new VFS interface as far as combined VFS operation
+   set is coherent (will be in most cases). 
+*/
+#define SMB_VFS_INTERFACE_CASCADED 4
+
+/*
+    Each VFS module must provide following global functions:
+    vfs_init   -- initialization function
+    vfs_done   -- finalization function
+    
+    vfs_init must return proper initialized vfs_op_tuple[] array
+    which describes all operations this module claims to intercept. This function
+    is called whenever module is loaded into smbd process using sys_dlopen().
+    
+    vfs_init must store somewhere vfs_handle reference if module wants to store per-instance
+    private information for further usage. vfs_handle->data should be used to
+    store such information. Do not try to change other fields in this structure
+    or results likely to be unpredictable.
+    
+    vfs_done must perform finalization of the module. In particular,
+    this function must free vfs_ops structure returned to module from smb_vfs_get_opaque_ops()
+    function if it is used (see below). This function is called whenever module 
+    is unloaded from smbd process using sys_dlclose().
+    
+    Prototypes:
+    vfs_op_tuple *vfs_init(int *vfs_version, const struct vfs_ops *def_vfs_ops,
+                           struct smb_vfs_handle_struct *vfs_handle);
+    void         vfs_done(connection_struct *conn);
+    
+    All intercepted VFS operations must be declared as static functions inside module source
+    in order to keep smbd namespace unpolluted. See source of skel, audit, and recycle bin
+    example VFS modules for more details.
+    
+*/
 
 /* VFS operations structure */
 
@@ -135,4 +179,157 @@ struct vfs_options {
     char *value;
 };
 
+/*
+    Available VFS operations. These values must be in sync with vfs_ops struct.
+    In particular, if new operations are added to vfs_ops, appropriate constants
+    should be added to vfs_op_type so that order of them kept same as in vfs_ops.
+*/
+
+typedef enum _vfs_op_type {
+
+       SMB_VFS_OP_NOOP = -1,
+       
+       /* Disk operations */
+
+       SMB_VFS_OP_CONNECT = 0,
+       SMB_VFS_OP_DISCONNECT,
+       SMB_VFS_OP_DISK_FREE,
+
+       /* Directory operations */
+
+       SMB_VFS_OP_OPENDIR,
+       SMB_VFS_OP_READDIR,
+       SMB_VFS_OP_MKDIR,
+       SMB_VFS_OP_RMDIR,
+       SMB_VFS_OP_CLOSEDIR,
+
+       /* File operations */
+
+       SMB_VFS_OP_OPEN,
+       SMB_VFS_OP_CLOSE,
+       SMB_VFS_OP_READ,
+       SMB_VFS_OP_WRITE,
+       SMB_VFS_OP_LSEEK,
+       SMB_VFS_OP_RENAME,
+       SMB_VFS_OP_FSYNC,
+       SMB_VFS_OP_STAT,
+       SMB_VFS_OP_FSTAT,
+       SMB_VFS_OP_LSTAT,
+       SMB_VFS_OP_UNLINK,
+       SMB_VFS_OP_CHMOD,
+       SMB_VFS_OP_FCHMOD,
+       SMB_VFS_OP_CHOWN,
+       SMB_VFS_OP_FCHOWN,
+       SMB_VFS_OP_CHDIR,
+       SMB_VFS_OP_GETWD,
+       SMB_VFS_OP_UTIME,
+       SMB_VFS_OP_FTRUNCATE,
+       SMB_VFS_OP_LOCK,
+       SMB_VFS_OP_SYMLINK,
+       SMB_VFS_OP_READLINK,
+       SMB_VFS_OP_LINK,
+       SMB_VFS_OP_MKNOD,
+       SMB_VFS_OP_REALPATH,
+
+       /* NT ACL operations. */
+
+       SMB_VFS_OP_FGET_NT_ACL,
+       SMB_VFS_OP_GET_NT_ACL,
+       SMB_VFS_OP_FSET_NT_ACL,
+       SMB_VFS_OP_SET_NT_ACL,
+
+       /* POSIX ACL operations. */
+
+       SMB_VFS_OP_CHMOD_ACL,
+       SMB_VFS_OP_FCHMOD_ACL,
+
+       SMB_VFS_OP_SYS_ACL_GET_ENTRY,
+       SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE,
+       SMB_VFS_OP_SYS_ACL_GET_PERMSET,
+       SMB_VFS_OP_SYS_ACL_GET_QUALIFIER,
+       SMB_VFS_OP_SYS_ACL_GET_FILE,
+       SMB_VFS_OP_SYS_ACL_GET_FD,
+       SMB_VFS_OP_SYS_ACL_CLEAR_PERMS,
+       SMB_VFS_OP_SYS_ACL_ADD_PERM,
+       SMB_VFS_OP_SYS_ACL_TO_TEXT,
+       SMB_VFS_OP_SYS_ACL_INIT,
+       SMB_VFS_OP_SYS_ACL_CREATE_ENTRY,
+       SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE,
+       SMB_VFS_OP_SYS_ACL_SET_QUALIFIER,
+       SMB_VFS_OP_SYS_ACL_SET_PERMSET,
+       SMB_VFS_OP_SYS_ACL_VALID,
+       SMB_VFS_OP_SYS_ACL_SET_FILE,
+       SMB_VFS_OP_SYS_ACL_SET_FD,
+       SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
+       SMB_VFS_OP_SYS_ACL_GET_PERM,
+       SMB_VFS_OP_SYS_ACL_FREE_TEXT,
+       SMB_VFS_OP_SYS_ACL_FREE_ACL,
+       SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
+       
+       /* This should always be last enum value */
+       
+       SMB_VFS_OP_LAST
+} vfs_op_type;
+
+/*
+    Possible VFS operation layers (per-operation)
+    
+    These values are used by VFS subsystem when building vfs_ops for connection
+    from multiple VFS modules. Internally, Samba differentiates only opaque and
+    transparent layers at this process. Other types are used for providing better
+    diagnosing facilities.
+    
+    Most modules will provide transparent layers. Opaque layer is for modules
+    which implement actual file system calls (like DB-based VFS). For example,
+    default POSIX VFS which is built in into Samba is an opaque VFS module.
+    
+    Other layer types (audit, splitter, scanner) were designed to provide different 
+    degree of transparency and for diagnosing VFS module behaviour.
+    
+    Each module can implement several layers at the same time provided that only
+    one layer is used per each operation.
+    
+*/
+
+typedef enum _vfs_op_layer {
+       SMB_VFS_LAYER_NOOP = -1,        /* - For using in VFS module to indicate end of array */
+                                       /*   of operations description */
+       SMB_VFS_LAYER_OPAQUE = 0,       /* - Final level, does not call anything beyond itself */
+       SMB_VFS_LAYER_TRANSPARENT,      /* - Normal operation, calls underlying layer after */
+                                       /*   possibly changing passed data */
+       SMB_VFS_LAYER_LOGGER,           /* - Logs data, calls underlying layer, logging does not */
+                                       /*   use Samba VFS */
+       SMB_VFS_LAYER_SPLITTER,         /* - Splits operation, calls underlying layer _and_ own facility, */
+                                       /*   then combines result */
+       SMB_VFS_LAYER_SCANNER           /* - Checks data and possibly initiates additional */
+                                       /*   file activity like logging to files _inside_ samba VFS */
+} vfs_op_layer;
+
+/*
+    VFS operation description. Each VFS module initialization function returns to VFS subsystem 
+    an array of vfs_op_tuple which describes all operations this module is willing to intercept. 
+    VFS subsystem initializes then vfs_ops using this information and passes it 
+    to next VFS module as underlying vfs_ops and to connection after all VFS modules are initialized.
+*/
+
+typedef struct _vfs_op_tuple {
+       void* op;
+       vfs_op_type type;
+       vfs_op_layer layer;
+} vfs_op_tuple;
+
+/*
+    Return vfs_ops filled with current opaque VFS operations. This function is designed to
+    be called from VFS module initialization function for those modules which needs 'direct' VFS
+    access (loggers or initiators of file operations other than connection asks for).
+    
+    Returned vfs_ops must be cleaned up in VFS module's finalizer function (vfs_done_<module_name>)
+    using safe_free().
+    
+    Prototype:
+    struct vfs_ops *smb_vfs_get_opaque_ops();
+    
+    This prototype will be available via include/proto.h
+*/
+
 #endif /* _VFS_H */
index d5e8bd41bd5b6c280c027a77e79c1384181299b0..a86ea0a3f9a8cad5e0d716a0f7c44c6ed373b355 100644 (file)
@@ -106,8 +106,10 @@ BOOL lang_tdb_init(const char *lang)
 
        if (initialised) {
                /* we are re-initialising, free up any old init */
-               tdb_close(tdb);
-               tdb = NULL;
+               if (tdb) {
+                       tdb_close(tdb);
+                       tdb = NULL;
+               }
                SAFE_FREE(current_lang);
        }
 
index 07676e22022119ca558d7ecdeacb1359b4013589..07b5e2ecfc649066ff90afbfd0b088a03d036fb1 100644 (file)
@@ -2,6 +2,7 @@
  *  Unix SMB/CIFS implementation.
  *  account policy storage
  *  Copyright (C) Jean François Micouleau      1998-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
@@ -31,6 +32,7 @@ BOOL init_account_policy(void)
 {
        static pid_t local_pid;
        char *vstring = "INFO/version";
+       uint32 version;
 
        if (tdb && local_pid == sys_getpid())
                return True;
@@ -44,9 +46,9 @@ BOOL init_account_policy(void)
 
        /* handle a Samba upgrade */
        tdb_lock_bystring(tdb, vstring);
-       if (tdb_fetch_int32(tdb, vstring) != DATABASE_VERSION) {
+       if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
                tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
-               tdb_store_int32(tdb, vstring, DATABASE_VERSION);
+               tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
                
                account_policy_set(AP_MIN_PASSWORD_LEN, MINPASSWDLENGTH);   /* 5 chars minimum             */
                account_policy_set(AP_PASSWORD_HISTORY, 0);                 /* don't keep any old password */
@@ -63,33 +65,50 @@ BOOL init_account_policy(void)
        return True;
 }
 
+static const struct {
+       int field;
+       char *string;
+} account_policy_names[] = {
+       {AP_MIN_PASSWORD_LEN, "min password length"},
+       {AP_PASSWORD_HISTORY, "password history"},
+       {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password"},
+       {AP_MAX_PASSWORD_AGE, "maximum password age"},
+       {AP_MIN_PASSWORD_AGE,"minimum password age"},
+       {AP_LOCK_ACCOUNT_DURATION, "lockout duration"},
+       {AP_RESET_COUNT_TIME, "reset count minutes"},
+       {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt"},
+       {AP_TIME_TO_LOGOUT, "disconnect time"},
+       {0, NULL}
+};
+
+/****************************************************************************
+Get the account policy name as a string from its #define'ed number
+****************************************************************************/
+
+static const char *decode_account_policy_name(int field)
+{
+       int i;
+       for (i=0; account_policy_names[i].string; i++) {
+               if (field == account_policy_names[i].field)
+                       return account_policy_names[i].string;
+       }
+       return NULL;
+
+}
+
 /****************************************************************************
+Get the account policy name as a string from its #define'ed number
 ****************************************************************************/
 
-static char *decode_account_policy_name(int field)
+int account_policy_name_to_fieldnum(const char *name)
 {
-       switch (field) {
-               case AP_MIN_PASSWORD_LEN:
-                       return "min password length";
-               case AP_PASSWORD_HISTORY:
-                       return "password history";
-               case AP_USER_MUST_LOGON_TO_CHG_PASS:
-                       return "user must logon to change password";
-               case AP_MAX_PASSWORD_AGE:
-                       return "maximum password age";
-               case AP_MIN_PASSWORD_AGE:
-                       return "minimum password age";
-               case AP_LOCK_ACCOUNT_DURATION:
-                       return "lockout duration";
-               case AP_RESET_COUNT_TIME:
-                       return "reset count minutes";
-               case AP_BAD_ATTEMPT_LOCKOUT:
-                       return "bad lockout attempt";
-               case AP_TIME_TO_LOGOUT:
-                       return "disconnect time";
-               default:
-                       return "undefined value";
+       int i;
+       for (i=0; account_policy_names[i].string; i++) {
+               if (strcmp(name, account_policy_names[i].string) == 0)
+                       return account_policy_names[i].field;
        }
+       return 0;
+
 }
 
 
@@ -101,8 +120,17 @@ BOOL account_policy_get(int field, uint32 *value)
 
        init_account_policy();
 
+       *value = 0;
+
        fstrcpy(name, decode_account_policy_name(field));
-       *value=tdb_fetch_int32(tdb, name);
+       if (!*name) {
+               DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type!  Cannot get, returning 0.\n", field));
+               return False;
+       }
+       if (!tdb_fetch_uint32(tdb, name, value)) {
+               DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for feild %d (%s), returning 0", field, name));
+               return False;
+       }
        DEBUG(10,("account_policy_get: %s:%d\n", name, *value));
        return True;
 }
@@ -117,8 +145,16 @@ BOOL account_policy_set(int field, uint32 value)
        init_account_policy();
 
        fstrcpy(name, decode_account_policy_name(field));
-       if ( tdb_store_int32(tdb, name, value)== -1)
+       if (!*name) {
+               DEBUG(1, ("Field %d is not a valid account policy type!  Cannot set.\n", field));
                return False;
+       }
+
+       if (!tdb_store_uint32(tdb, name, value)) {
+               DEBUG(1, ("tdb_store_uint32 failed for feild %d (%s) on value %u", field, name, value));
+               return False;
+       }
+
        DEBUG(10,("account_policy_set: %s:%d\n", name, value));
        
        return True;
index d42dc994b0032b90e90c06dedac65648d3c7530a..6e961366435b983e528b3a45181cbce10bec8e8e 100644 (file)
@@ -249,15 +249,15 @@ convert:
 size_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
                                void const *src, size_t srclen, void **dest)
 {
-       void *ob;
+       void *alloced_string;
        size_t dest_len;
 
        *dest = NULL;
-       dest_len=convert_string_allocate(from, to, src, srclen, (void **)&ob);
+       dest_len=convert_string_allocate(from, to, src, srclen, &alloced_string);
        if (dest_len == -1)
                return -1;
-       *dest = talloc_strdup(ctx, (char *)ob);
-       SAFE_FREE(ob);
+       *dest = talloc_memdup(ctx, alloced_string, dest_len);
+       SAFE_FREE(alloced_string);
        if (*dest == NULL)
                return -1;
        return dest_len;
@@ -505,12 +505,12 @@ int push_utf8_pstring(void *dest, const char *src)
  *
  * @retval The number of bytes occupied by the string in the destination
  **/
-int push_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src)
+int push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
 {
        int src_len = strlen(src)+1;
 
        *dest = NULL;
-       return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, dest);
+       return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void**)dest);
 }
 
 /**
@@ -562,7 +562,8 @@ int pull_ucs2(const void *base_ptr, char *dest, const void *src, int dest_len, i
        }
 
        /* ucs2 is always a multiple of 2 bytes */
-       src_len &= ~1;
+       if (src_len != -1)
+               src_len &= ~1;
        
        ret = convert_string(CH_UCS2, CH_UNIX, src, src_len, dest, dest_len);
        if (dest_len) dest[MIN(ret, dest_len-1)] = 0;
@@ -658,11 +659,11 @@ int pull_utf8_fstring(char *dest, const void *src)
  *
  * @retval The number of bytes occupied by the string in the destination
  **/
-int pull_utf8_talloc(TALLOC_CTX *ctx, void **dest, const char *src)
+int pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
 {
        int src_len = strlen(src)+1;
        *dest = NULL;
-       return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, dest);        
+       return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest);       
 }
 
 /**
index f41c3b649760961fa8a4514036a3f731b4c9b1f8..842d2dac1d62650b431de0ec459397c855c5006c 100644 (file)
@@ -423,7 +423,7 @@ BOOL debug_parse_levels(const char *params_str)
        if (AllowDebugChange == False)
                return True;
 
-       params = str_list_make(params_str);
+       params = str_list_make(params_str, NULL);
 
        if (debug_parse_params(params, DEBUGLEVEL_CLASS,
                               DEBUGLEVEL_CLASS_ISSET))
@@ -602,6 +602,12 @@ BOOL reopen_logs( void )
        force_check_log_size();
        (void)umask(oldumask);
 
+       /* Take over stderr to catch ouput into logs */
+       if (dbf && sys_dup2(dbf->fd, 2) == -1) {
+               close_low_fds(True); /* Close stderr too, if dup2 can't point it
+                                       at the logfile */
+       }
+
        return ret;
 }
 
index ee8bc0b1d5abc59a11e75596cdc39872d3a0c874..fe756169a669735b58b0dfa81ac32bf43a4f5293 100644 (file)
@@ -259,7 +259,7 @@ char *generate_random_str(size_t len)
                len = sizeof(retstr) -1;
        generate_random_buffer( retstr, len, False);
        for (i = 0; i < len; i++)
-               retstr[i] = c_list[ retstr[i] % sizeof(c_list) ];
+               retstr[i] = c_list[ retstr[i] % (sizeof(c_list)-1) ];
 
        retstr[i] = '\0';
 
index 2cc7d48adb34f8a6d0816f8d3a28f89176afd662..fd7b2cf7f016cb27ee8da91e5111ad98fa9903d1 100644 (file)
@@ -428,3 +428,5 @@ char *rep_inet_ntoa(struct in_addr ip)
 }
 #endif /* HAVE_SYSLOG */
 #endif /* HAVE_VSYSLOG */
+
+
index 67f82ed0ad43cdf1c853e4a67583352d5fd20a93..592543bc43be89dc7fd8ab722a7145f00bd7c401 100644 (file)
@@ -143,7 +143,7 @@ int smbrun(char *cmd, int *outfd)
        /* point our stdout at the file we want output to go into */
        if (outfd) {
                close(1);
-               if (dup2(*outfd,1) != 1) {
+               if (sys_dup2(*outfd,1) != 1) {
                        DEBUG(2,("Failed to create stdout file descriptor\n"));
                        close(*outfd);
                        exit(80);
index 6d96a1820f1484fcd997ff5774c313936bab0e5d..026df0f67f1518ae2a76bced7e347f1db855cc9c 100644 (file)
@@ -25,9 +25,41 @@ fstring local_machine="";
 fstring remote_arch="UNKNOWN";
 userdom_struct current_user_info;
 fstring remote_proto="UNKNOWN";
-fstring remote_machine="";
 extern pstring global_myname;
 
+static fstring remote_machine="";
+
+
+void set_local_machine_name(const char* local_name)
+{
+       fstring tmp_local_machine;
+
+       fstrcpy(tmp_local_machine,local_name);
+       trim_string(tmp_local_machine," "," ");
+       strlower(tmp_local_machine);
+       alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
+}
+
+void set_remote_machine_name(const char* remote_name)
+{
+       fstring tmp_remote_machine;
+
+       fstrcpy(tmp_remote_machine,remote_name);
+       trim_string(tmp_remote_machine," "," ");
+       strlower(tmp_remote_machine);
+       alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
+}
+
+const char* get_remote_machine_name(void) 
+{
+       return remote_machine;
+}
+
+const char* get_local_machine_name(void) 
+{
+       return local_machine;
+}
+
 /*******************************************************************
  Given a pointer to a %$(NAME) expand it as an environment variable.
  Return the number of characters by which the pointer should be advanced.
@@ -188,14 +220,15 @@ static char *automount_path(const char *user_name)
  moved out to a separate function.
 *******************************************************************/
 
-static char *automount_server(const char *user_name)
+static const char *automount_server(const char *user_name)
 {
        static pstring server_name;
+       const char *local_machine_name = get_local_machine_name(); 
 
        /* use the local machine name as the default */
        /* this will be the default if WITH_AUTOMOUNT is not used or fails */
-       if (*local_machine)
-               pstrcpy(server_name, local_machine);
+       if (local_machine_name && *local_machine_name)
+               pstrcpy(server_name, local_machine_name);
        else
                pstrcpy(server_name, global_myname);
        
@@ -229,6 +262,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
        char *p, *s;
        fstring pidstr;
        struct passwd *pass;
+       const char *local_machine_name = get_local_machine_name();
 
        for (s=str; (p=strchr_m(s, '%'));s=p) {
                fstring tmp_str;
@@ -261,8 +295,8 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
                        string_sub(p,"%I", client_addr(),l);
                        break;
                case 'L' : 
-                       if (*local_machine)
-                               string_sub(p,"%L", local_machine,l); 
+                       if (local_machine_name && *local_machine_name)
+                               string_sub(p,"%L", local_machine_name,l); 
                        else
                                string_sub(p,"%L", global_myname,l); 
                        break;
@@ -286,7 +320,7 @@ void standard_sub_basic(const char *smb_name, char *str,size_t len)
                        string_sub(p,"%h", myhostname(),l);
                        break;
                case 'm' :
-                       string_sub(p,"%m", remote_machine,l);
+                       string_sub(p,"%m", get_remote_machine_name(),l);
                        break;
                case 'v' :
                        string_sub(p,"%v", VERSION,l);
@@ -381,6 +415,7 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
        char *b, *p, *s, *t, *r, *a_string;
        fstring pidstr;
        struct passwd *pass;
+       const char *local_machine_name = get_local_machine_name();
 
        a_string = strdup(str);
        if (a_string == NULL) {
@@ -415,8 +450,8 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
                        t = realloc_string_sub(t, "%I", client_addr());
                        break;
                case 'L' : 
-                       if (*local_machine)
-                               t = realloc_string_sub(t, "%L", local_machine); 
+                       if (local_machine_name && *local_machine_name)
+                               t = realloc_string_sub(t, "%L", local_machine_name); 
                        else
                                t = realloc_string_sub(t, "%L", global_myname); 
                        break;
index 8b2ba800f53efcea927dd518f3b6f0aaa0c785b7..edda54a78d2745f04c557becbf82982ec25ee7ca 100644 (file)
@@ -1219,6 +1219,16 @@ const char *sys_dlerror(void)
 #endif
 }
 
+int sys_dup2(int oldfd, int newfd) 
+{
+#if defined(HAVE_DUP2)
+       return dup2(oldfd, newfd);
+#else
+       errno = ENOSYS;
+       return -1;
+#endif
+}
+
 /**************************************************************************
  Wrapper for Admin Logs.
 ****************************************************************************/
index 4813c8fd194c20ba5b2df04c25d6aaa5faab4a54..5db7f58b1e254dd42346b33270bc84e9f11ce00c 100644 (file)
@@ -163,7 +163,7 @@ BOOL map_username(char *user)
                        }
                }
 
-               dosuserlist = str_list_make(dosname);
+               dosuserlist = str_list_make(dosname, NULL);
                if (!dosuserlist) {
                        DEBUG(0,("Unable to build user list\n"));
                        return False;
index be108aa40566df448805281bc7ef6796990fb9a1..ae94b710b2cbabc2603294bab617c9678a5f4d40 100644 (file)
@@ -100,7 +100,7 @@ char *tmpdir(void)
  Determine whether we are in the specified group.
 ****************************************************************************/
 
-BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
+BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups)
 {
        int i;
 
@@ -503,27 +503,32 @@ void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,ti
 /*******************************************************************
 close the low 3 fd's and open dev/null in their place
 ********************************************************************/
-void close_low_fds(void)
+void close_low_fds(BOOL stderr_too)
 {
   int fd;
   int i;
   close(0); close(1); 
-#ifndef __INSURE__
-  close(2);
-#endif
+
+  if (stderr_too) {
+         close(2);
+  }
+
   /* try and use up these file descriptors, so silly
      library routines writing to stdout etc won't cause havoc */
   for (i=0;i<3;i++) {
-    fd = sys_open("/dev/null",O_RDWR,0);
-    if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0);
-    if (fd < 0) {
-      DEBUG(0,("Can't open /dev/null\n"));
-      return;
-    }
-    if (fd != i) {
-      DEBUG(0,("Didn't get file descriptor %d\n",i));
-      return;
-    }
+         if (i == 2 && !stderr_too)
+                 continue;
+
+         fd = sys_open("/dev/null",O_RDWR,0);
+         if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0);
+         if (fd < 0) {
+                 DEBUG(0,("Can't open /dev/null\n"));
+                 return;
+         }
+         if (fd != i) {
+                 DEBUG(0,("Didn't get file descriptor %d\n",i));
+                 return;
+         }
   }
 }
 
@@ -678,7 +683,8 @@ void become_daemon(void)
 #endif /* HAVE_SETSID */
 
        /* Close fd's 0,1,2. Needed if started by rsh */
-       close_low_fds();
+       close_low_fds(False);  /* Don't close stderr, let the debug system
+                                 attach it to the logfile */
 }
 
 
index 2e76121aae1b672a7ac5501f294f422153a15d5c..6699ce3e92393ebfab01a37210c730a2e5eb9f34 100644 (file)
 
 #include "includes.h"
 
-#if 0
-static void print_grent_list(struct sys_grent *glist)
-{
-       DEBUG(100, ("print_grent_list: %x\n", glist ));
-       while (glist) {
-               DEBUG(100,("glist: %x ", glist));
-               if (glist->gr_name)
-                       DEBUG(100,(": gr_name = (%x) %s ", glist->gr_name, glist->gr_name));
-               if (glist->gr_passwd)
-                       DEBUG(100,(": gr_passwd = (%x) %s ", glist->gr_passwd, glist->gr_passwd));
-               if (glist->gr_mem) {
-                       int i;
-                       for (i = 0; glist->gr_mem[i]; i++)
-                               DEBUG(100,(" : gr_mem[%d] = (%x) %s ", i, glist->gr_mem[i], glist->gr_mem[i]));
-               }
-               DEBUG(100,(": gr_next = %x\n", glist->next ));
-               glist = glist->next;
-       }
-       DEBUG(100,("FINISHED !\n\n"));
-}
-#endif
 
 /****************************************************************
  Returns a single linked list of group entries.
index 5dd1d75c701f56e20bd563ca22063fc3088b0f40..ad09f9123460d937250cf0f53c86d703768a4b25 100644 (file)
@@ -365,6 +365,9 @@ BOOL sid_parse(char *inbuf, size_t len, DOM_SID *sid)
 {
        int i;
        if (len < 8) return False;
+
+       ZERO_STRUCTP(sid);
+
        sid->sid_rev_num = CVAL(inbuf, 0);
        sid->num_auths = CVAL(inbuf, 1);
        memcpy(sid->id_auth, inbuf+2, 6);
index 4f1f2a1470ad8f25a0f874732f5836fbc93785a6..5e2b7c5ed97f1c2bfba6785502b174dc1864ee44 100644 (file)
@@ -708,7 +708,7 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb
 
        /* now we've got a socket - we need to bind it */
        if( bind( res, (struct sockaddr *)&sock, sizeof(sock) ) == -1 ) {
-               if( DEBUGLVL(dlevel) && (port == SMB_PORT || port == NMB_PORT) ) {
+               if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || port == SMB_PORT2 || port == NMB_PORT) ) {
                        dbgtext( "bind failed on port %d ", port );
                        dbgtext( "socket_addr = %s.\n", inet_ntoa( sock.sin_addr ) );
                        dbgtext( "Error = %s\n", strerror(errno) );
index 88a72f1536032f4b948f942dc92dddab725b5dc4..19d92eec8fb44bb17fe2eba0c112eda116b36151 100644 (file)
@@ -212,6 +212,18 @@ int strwicmp(const char *psz1, const char *psz2)
 }
 
 
+/* Convert a string to upper case, but don't modify it */
+
+char *strupper_static(const char *s)
+{
+       static pstring str;
+
+       pstrcpy(str, s);
+       strupper(str);
+
+       return str;
+}
+
 /*******************************************************************
   convert a string to "normal" form
 ********************************************************************/
@@ -299,7 +311,7 @@ BOOL trim_string(char *s,const char *front,const char *back)
        }
        
        if (back_len) {
-               while (strncmp(s+len-back_len,back,back_len)==0) {
+               while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
                        s[len-back_len]='\0';
                        len -= back_len;
                        ret=True;
@@ -667,7 +679,7 @@ void string_sub(char *s,const char *pattern, const char *insert, size_t len)
        li = (ssize_t)strlen(insert);
 
        if (len == 0)
-               len = ls;
+               len = ls + 1; /* len is number of *bytes* */
 
        while (lp <= ls && (p = strstr(s,pattern))) {
                if (ls + (li-lp) >= len) {
@@ -798,7 +810,7 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
                return;
        
        if (len == 0)
-               len = ls;
+               len = ls + 1; /* len is number of *bytes* */
        
        while (lp <= ls && (p = strstr(s,pattern))) {
                if (ls + (li-lp) >= len) {
@@ -826,7 +838,8 @@ return a new allocate unicode string.
 smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
                                const smb_ucs2_t *insert)
 {
-       smb_ucs2_t *r, *rp, *sp;
+       smb_ucs2_t *r, *rp;
+       const smb_ucs2_t *sp;
        size_t  lr, lp, li, lt;
 
        if (!insert || !pattern || !*pattern || !s) return NULL;
@@ -836,7 +849,7 @@ smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
        li = (size_t)strlen_w(insert);
 
        if (li > lp) {
-               smb_ucs2_t *st = s;
+               const smb_ucs2_t *st = s;
                int ld = li - lp;
                while ((sp = strstr_w(st, pattern))) {
                        st = sp + lp;
@@ -879,68 +892,59 @@ smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
 }
 
 /****************************************************************************
splits out the front and back at a separator.
Splits out the front and back at a separator.
 ****************************************************************************/
+
 void split_at_last_component(char *path, char *front, char sep, char *back)
 {
        char *p = strrchr_m(path, sep);
 
        if (p != NULL)
-       {
                *p = 0;
-       }
+
        if (front != NULL)
-       {
                pstrcpy(front, path);
-       }
-       if (p != NULL)
-       {
+
+       if (p != NULL) {
                if (back != NULL)
-               {
                        pstrcpy(back, p+1);
-               }
                *p = '\\';
-       }
-       else
-       {
+       } else {
                if (back != NULL)
-               {
                        back[0] = 0;
-               }
        }
 }
 
-
 /****************************************************************************
-write an octal as a string
+ Write an octal as a string.
 ****************************************************************************/
+
 char *octal_string(int i)
 {
        static char ret[64];
-       if (i == -1) {
+       if (i == -1)
                return "-1";
-       }
        slprintf(ret, sizeof(ret)-1, "0%o", i);
        return ret;
 }
 
 
 /****************************************************************************
-truncate a string at a specified length
+ Truncate a string at a specified length.
 ****************************************************************************/
+
 char *string_truncate(char *s, int length)
 {
-       if (s && strlen(s) > length) {
+       if (s && strlen(s) > length)
                s[length] = 0;
-       }
        return s;
 }
 
-
 /****************************************************************************
-strchr and strrchr_m are very hard to do on general multi-byte strings. 
-we convert via ucs2 for now
+ Strchr and strrchr_m are very hard to do on general multi-byte strings. 
+ We convert via ucs2 for now.
 ****************************************************************************/
+
 char *strchr_m(const char *s, char c)
 {
        wpstring ws;
@@ -949,7 +953,8 @@ char *strchr_m(const char *s, char c)
 
        push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
        p = strchr_w(ws, UCS2_CHAR(c));
-       if (!p) return NULL;
+       if (!p)
+               return NULL;
        *p = 0;
        pull_ucs2_pstring(s2, ws);
        return (char *)(s+strlen(s2));
@@ -963,26 +968,29 @@ char *strrchr_m(const char *s, char c)
 
        push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
        p = strrchr_w(ws, UCS2_CHAR(c));
-       if (!p) return NULL;
+       if (!p)
+               return NULL;
        *p = 0;
        pull_ucs2_pstring(s2, ws);
        return (char *)(s+strlen(s2));
 }
 
 /*******************************************************************
-  convert a string to lower case
+ Convert a string to lower case.
 ********************************************************************/
+
 void strlower_m(char *s)
 {
        /* this is quite a common operation, so we want it to be
           fast. We optimise for the ascii case, knowing that all our
           supported multi-byte character sets are ascii-compatible
           (ie. they match for the first 128 chars) */
-       while (*s && !(((unsigned char)s[0]) & 0x7F)) {
+
+       while (*s && !(((unsigned char)s[0]) & 0x7F))
                *s++ = tolower((unsigned char)*s);
-       }
 
-       if (!*s) return;
+       if (!*s)
+               return;
 
        /* I assume that lowercased string takes the same number of bytes
         * as source string even in UTF-8 encoding. (VIV) */
@@ -990,8 +998,9 @@ void strlower_m(char *s)
 }
 
 /*******************************************************************
-  duplicate convert a string to lower case
+ Duplicate convert a string to lower case.
 ********************************************************************/
+
 char *strdup_lower(const char *s)
 {
        char *t = strdup(s);
@@ -1004,19 +1013,21 @@ char *strdup_lower(const char *s)
 }
 
 /*******************************************************************
-  convert a string to upper case
+ Convert a string to upper case.
 ********************************************************************/
+
 void strupper_m(char *s)
 {
        /* this is quite a common operation, so we want it to be
           fast. We optimise for the ascii case, knowing that all our
           supported multi-byte character sets are ascii-compatible
           (ie. they match for the first 128 chars) */
-       while (*s && !(((unsigned char)s[0]) & 0x7F)) {
+
+       while (*s && !(((unsigned char)s[0]) & 0x7F))
                *s++ = toupper((unsigned char)*s);
-       }
 
-       if (!*s) return;
+       if (!*s)
+               return;
 
        /* I assume that lowercased string takes the same number of bytes
         * as source string even in multibyte encoding. (VIV) */
@@ -1024,8 +1035,9 @@ void strupper_m(char *s)
 }
 
 /*******************************************************************
-  convert a string to upper case
+ Convert a string to upper case.
 ********************************************************************/
+
 char *strdup_upper(const char *s)
 {
        char *t = strdup(s);
@@ -1048,7 +1060,8 @@ char *binary_string(char *buf, int len)
        int i, j;
        const char *hex = "0123456789ABCDEF";
        s = malloc(len * 3 + 1);
-       if (!s) return NULL;
+       if (!s)
+               return NULL;
        for (j=i=0;i<len;i++) {
                s[j] = '\\';
                s[j+1] = hex[((unsigned char)buf[i]) >> 4];
@@ -1059,8 +1072,8 @@ char *binary_string(char *buf, int len)
        return s;
 }
 
-
 /* Just a typesafety wrapper for snprintf into a pstring */
+
 int pstr_sprintf(pstring s, const char *fmt, ...)
 {
        va_list ap;
@@ -1072,8 +1085,8 @@ int pstr_sprintf(pstring s, const char *fmt, ...)
        return ret;
 }
 
-
 /* Just a typesafety wrapper for snprintf into a fstring */
+
 int fstr_sprintf(fstring s, const char *fmt, ...)
 {
        va_list ap;
@@ -1085,18 +1098,19 @@ int fstr_sprintf(fstring s, const char *fmt, ...)
        return ret;
 }
 
-
 #ifndef HAVE_STRNDUP
 /*******************************************************************
-some platforms don't have strndup
+ Some platforms don't have strndup.
 ********************************************************************/
+
  char *strndup(const char *s, size_t n)
 {
        char *ret;
        
        n = strnlen(s, n);
        ret = malloc(n+1);
-       if (!ret) return NULL;
+       if (!ret)
+               return NULL;
        memcpy(ret, s, n);
        ret[n] = 0;
 
@@ -1111,39 +1125,39 @@ some platforms don't have strnlen
  size_t strnlen(const char *s, size_t n)
 {
        int i;
-       for (i=0; s[i] && i<n; i++) /* noop */ ;
+       for (i=0; s[i] && i<n; i++)
+               /* noop */ ;
        return i;
 }
 #endif
 
-
-
 /***********************************************************
  List of Strings manipulation functions
 ***********************************************************/
 
 #define S_LIST_ABS 16 /* List Allocation Block Size */
 
-char **str_list_make(const char *string)
+char **str_list_make(const char *string, const char *sep)
 {
        char **list, **rlist;
        char *str, *s;
        int num, lsize;
        pstring tok;
        
-       if (!string || !*string) return NULL;
+       if (!string || !*string)
+               return NULL;
        s = strdup(string);
        if (!s) {
                DEBUG(0,("str_list_make: Unable to allocate memory"));
                return NULL;
        }
+       if (!sep) sep = LIST_SEP;
        
        num = lsize = 0;
        list = NULL;
        
        str = s;
-       while (next_token(&str, tok, LIST_SEP, sizeof(tok)))
-       {               
+       while (next_token(&str, tok, sep, sizeof(tok))) {               
                if (num == lsize) {
                        lsize += S_LIST_ABS;
                        rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
@@ -1178,13 +1192,13 @@ BOOL str_list_copy(char ***dest, char **src)
        int num, lsize;
        
        *dest = NULL;
-       if (!src) return False;
+       if (!src)
+               return False;
        
        num = lsize = 0;
        list = NULL;
                
-       while (src[num])
-       {
+       while (src[num]) {
                if (num == lsize) {
                        lsize += S_LIST_ABS;
                        rlist = (char **)Realloc(list, ((sizeof(char **)) * (lsize +1)));
@@ -1212,17 +1226,22 @@ BOOL str_list_copy(char ***dest, char **src)
 }
 
 /* return true if all the elemnts of the list matches exactly */
+
 BOOL str_list_compare(char **list1, char **list2)
 {
        int num;
        
-       if (!list1 || !list2) return (list1 == list2); 
+       if (!list1 || !list2)
+               return (list1 == list2); 
        
        for (num = 0; list1[num]; num++) {
-               if (!list2[num]) return False;
-               if (!strcsequal(list1[num], list2[num])) return False;
+               if (!list2[num])
+                       return False;
+               if (!strcsequal(list1[num], list2[num]))
+                       return False;
        }
-       if (list2[num]) return False; /* if list2 has more elements than list1 fail */
+       if (list2[num])
+               return False; /* if list2 has more elements than list1 fail */
        
        return True;
 }
@@ -1231,9 +1250,11 @@ void str_list_free(char ***list)
 {
        char **tlist;
        
-       if (!list || !*list) return;
+       if (!list || !*list)
+               return;
        tlist = *list;
-       for(; *tlist; tlist++) SAFE_FREE(*tlist);
+       for(; *tlist; tlist++)
+               SAFE_FREE(*tlist);
        SAFE_FREE(*list);
 }
 
@@ -1242,25 +1263,25 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
        char *p, *s, *t;
        ssize_t ls, lp, li, ld, i, d;
 
-       if (!list) return False;
-       if (!pattern) return False;
-       if (!insert) return False;
+       if (!list)
+               return False;
+       if (!pattern)
+               return False;
+       if (!insert)
+               return False;
 
        lp = (ssize_t)strlen(pattern);
        li = (ssize_t)strlen(insert);
        ld = li -lp;
                        
-       while (*list)
-       {
+       while (*list) {
                s = *list;
                ls = (ssize_t)strlen(s);
 
-               while ((p = strstr(s, pattern)))
-               {
+               while ((p = strstr(s, pattern))) {
                        t = *list;
                        d = p -t;
-                       if (ld)
-                       {
+                       if (ld) {
                                t = (char *) malloc(ls +ld +1);
                                if (!t) {
                                        DEBUG(0,("str_list_substitute: Unable to allocate memory"));
index adf405ae7e247b55b1f5e339e26e6cdab8129c90..61e77aca58717e5d1332fd9839500c9864f62c91 100644 (file)
@@ -236,7 +236,7 @@ char **wins_srv_tags(void)
                }
 
                /* add it to the list */
-               ret = (char **)Realloc(ret, (count+1) * sizeof(char *));
+               ret = (char **)Realloc(ret, (count+2) * sizeof(char *));
                ret[count] = strdup(t_ip.tag);
                if (!ret[count]) break;
                count++;
index 903dfb1ae0ad8d3c3a3ef2fea85dc435d6a4c82f..b5710f3a39e15e648f349c21f379d11eaa87489b 100644 (file)
@@ -171,7 +171,7 @@ int x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f)
           flush a bit more than necessary, but that is harmless */
        if (f->buftype == X_IOLBF && f->bufused) {
                int i;
-               for (i=size-1; i>=0; i--) {
+               for (i=(size*nmemb)-1; i>=0; i--) {
                        if (*(i+(const char *)p) == '\n') {
                                x_fflush(f);
                                break;
index 638dc0b22e5afe1b20175b7094da553186e6b01b..b68c822ce3519513e8160b42e0f8918201a4396d 100644 (file)
@@ -72,47 +72,6 @@ char *ads_build_dn(const char *realm)
 }
 
 
-#ifdef HAVE_LDAP
-/*
-  find the ldap server from DNS
-*/
-static char *find_ldap_server(ADS_STRUCT *ads)
-{
-       char *list = NULL;
-       struct in_addr ip;
-
-       if (ads->realm &&
-           strcasecmp(ads->workgroup, lp_workgroup()) == 0 &&
-           ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) {
-               char *p;
-               p = strchr(list, ':');
-               if (p) *p = 0;
-               return list;
-       }
-
-       /* get desperate, find the domain controller IP */
-       if (resolve_name(ads->workgroup, &ip, 0x1B)) {
-               return strdup(inet_ntoa(ip));
-       }
-       
-       /* or a BDC ... */
-       if (resolve_name(ads->workgroup, &ip, 0x1C)) {
-               return strdup(inet_ntoa(ip));
-       }
-
-       return NULL;
-}
-
-#else 
-
-static char *find_ldap_server(ADS_STRUCT *ads)
-{
-       /* Without LDAP this doesn't make much sense */
-       return NULL;
-}
-
-#endif 
-
 #ifndef LDAP_PORT
 #define LDAP_PORT 389
 #endif
@@ -122,46 +81,24 @@ static char *find_ldap_server(ADS_STRUCT *ads)
 */
 ADS_STRUCT *ads_init(const char *realm, 
                     const char *workgroup,
-                    const char *ldap_server,
-                    const char *bind_path,
-                    const char *password)
+                    const char *ldap_server)
 {
        ADS_STRUCT *ads;
        
        ads = (ADS_STRUCT *)smb_xmalloc(sizeof(*ads));
        ZERO_STRUCTP(ads);
        
-       if (!workgroup) {
-               workgroup = lp_workgroup();
+       ads->server.realm = realm? strdup(realm) : NULL;
+       ads->server.workgroup = workgroup ? strdup(workgroup) : NULL;
+       ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL;
+
+       /* we need to know if this is a foreign realm to know if we can
+          use lp_ads_server() */
+       if (realm && strcasecmp(lp_realm(), realm) != 0) {
+               ads->server.foreign = 1;
        }
-
-       ads->realm = realm? strdup(realm) : NULL;
-       ads->workgroup = strdup(workgroup);
-       ads->ldap_server = ldap_server? strdup(ldap_server) : NULL;
-       ads->bind_path = bind_path? strdup(bind_path) : NULL;
-       ads->ldap_port = LDAP_PORT;
-       if (password) ads->password = strdup(password);
-
-       if (!ads->realm) {
-               ads->realm = strdup(lp_realm());
-               if (!ads->realm[0]) {
-                       SAFE_FREE(ads->realm);
-               }
-       }
-       if (!ads->bind_path && ads->realm) {
-               ads->bind_path = ads_build_dn(ads->realm);
-       }
-       if (!ads->ldap_server) {
-               if (strcasecmp(ads->workgroup, lp_workgroup()) == 0) {
-                       ads->ldap_server = strdup(lp_ads_server());
-               }
-               if (!ads->ldap_server || !ads->ldap_server[0]) {
-                       ads->ldap_server = find_ldap_server(ads);
-               }
-       }
-       if (!ads->kdc_server) {
-               /* assume its the same as LDAP */
-               ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL;
+       if (workgroup && strcasecmp(lp_workgroup(), workgroup) != 0) {
+               ads->server.foreign = 1;
        }
 
        return ads;
@@ -170,7 +107,7 @@ ADS_STRUCT *ads_init(const char *realm,
 /* a simpler ads_init() interface using all defaults */
 ADS_STRUCT *ads_init_simple(void)
 {
-       return ads_init(NULL, NULL, NULL, NULL, NULL);
+       return ads_init(NULL, NULL, NULL);
 }
 
 /*
@@ -182,13 +119,19 @@ void ads_destroy(ADS_STRUCT **ads)
 #if HAVE_LDAP
                if ((*ads)->ld) ldap_unbind((*ads)->ld);
 #endif
-               SAFE_FREE((*ads)->realm);
-               SAFE_FREE((*ads)->ldap_server);
-               SAFE_FREE((*ads)->ldap_server_name);
-               SAFE_FREE((*ads)->kdc_server);
-               SAFE_FREE((*ads)->bind_path);
-               SAFE_FREE((*ads)->password);
-               SAFE_FREE((*ads)->user_name);
+               SAFE_FREE((*ads)->server.realm);
+               SAFE_FREE((*ads)->server.workgroup);
+               SAFE_FREE((*ads)->server.ldap_server);
+
+               SAFE_FREE((*ads)->auth.realm);
+               SAFE_FREE((*ads)->auth.password);
+               SAFE_FREE((*ads)->auth.user_name);
+               SAFE_FREE((*ads)->auth.kdc_server);
+
+               SAFE_FREE((*ads)->config.realm);
+               SAFE_FREE((*ads)->config.bind_path);
+               SAFE_FREE((*ads)->config.ldap_server_name);
+
                ZERO_STRUCTP(*ads);
                SAFE_FREE(*ads);
        }
index 1ba5d978e8c7203add7015a78159638b49f6db0c..9a486237c9fe9a65c198bd924f96aab0b8163a50 100644 (file)
@@ -110,16 +110,8 @@ int ads_kinit_password(ADS_STRUCT *ads)
        char *s;
        int ret;
 
-       if (!ads->user_name) {
-               /* by default use the machine account */
-               extern pstring global_myname;
-               fstring myname;
-               fstrcpy(myname, global_myname);
-               strlower(myname);
-               asprintf(&ads->user_name, "HOST/%s", global_myname);
-       }
-       asprintf(&s, "%s@%s", ads->user_name, ads->realm);
-       ret = kerberos_kinit_password(s, ads->password);
+       asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm);
+       ret = kerberos_kinit_password(s, ads->auth.password);
 
        if (ret) {
                DEBUG(0,("kerberos_kinit_password %s failed: %s\n", 
index dac90908c456ab4d5a5885a8e08bd4cbd3866f04..22b58f47dd90ed646b6515f035b1faf9af1c5345 100644 (file)
@@ -67,7 +67,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
                return NT_STATUS_LOGON_FAILURE;
        }
 
-       ret = krb5_set_default_realm(context, ads->realm);
+       ret = krb5_set_default_realm(context, ads->auth.realm);
        if (ret) {
                DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret)));
                ads_destroy(&ads);
index 9d15c4e33cccdf10652150863e5071ab9e740778..26724894829c2ffa2087f399904f081b0846fa40 100644 (file)
  * codepoints in UTF-8).  This may have to change at some point
  **/
 
+
+/*
+  try a connection to a given ldap server, returning True and setting the servers IP
+  in the ads struct if successful
+ */
+static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port)
+{
+       char *srv;
+
+       if (!server || !*server) {
+               return False;
+       }
+
+       DEBUG(5,("ads_try_connect: trying ldap server '%s' port %u\n", server, port));
+
+       /* this copes with inet_ntoa brokenness */
+       srv = strdup(server);
+
+       ads->ld = ldap_open(srv, port);
+       if (!ads->ld) {
+               free(srv);
+               return False;
+       }
+       ads->ldap_port = port;
+       ads->ldap_ip = *interpret_addr2(srv);
+       free(srv);
+       return True;
+}
+
+/* used by the IP comparison function */
+struct ldap_ip {
+       struct in_addr ip;
+       unsigned port;
+};
+
+/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */
+static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2)
+{
+       return ip_compare(&ip1->ip, &ip2->ip);
+}
+
+/* try connecting to a ldap server via DNS */
+static BOOL ads_try_dns(ADS_STRUCT *ads)
+{
+       char *realm, *ptr;
+       char *list = NULL;
+       pstring tok;
+       struct ldap_ip *ip_list;
+       int count, i=0;
+
+       realm = ads->server.realm;
+       if (!realm || !*realm) {
+               realm = lp_realm();
+       }
+       if (!realm || !*realm) {
+               realm = ads->server.workgroup;
+       }
+       if (!realm || !*realm) {
+               realm = lp_workgroup();
+       }
+       if (!realm) {
+               return False;
+       }
+       realm = smb_xstrdup(realm);
+
+       DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm));
+       if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) {
+               SAFE_FREE(realm);
+               return False;
+       }
+
+       DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list));
+       SAFE_FREE(realm);
+
+       count = count_chars(list, ' ') + 1;
+       ip_list = malloc(count * sizeof(struct ldap_ip));
+       if (!ip_list) {
+               return False;
+       }
+
+       ptr = list;
+       while (next_token(&ptr, tok, " ", sizeof(tok))) {
+               unsigned port = LDAP_PORT;
+               char *p = strchr(tok, ':');
+               if (p) {
+                       *p = 0;
+                       port = atoi(p+1);
+               }
+               ip_list[i].ip = *interpret_addr2(tok);
+               ip_list[i].port = port;
+               if (!is_zero_ip(ip_list[i].ip)) {
+                       i++;
+               }
+       }
+       free(list);
+
+       count = i;
+
+       /* we sort the list of addresses by closeness to our interfaces. This
+          tries to prevent us using a DC on the other side of the country */
+       if (count > 1) {
+               qsort(ip_list, count, sizeof(struct ldap_ip), 
+                     QSORT_CAST ldap_ip_compare);      
+       }
+
+       for (i=0;i<count;i++) {
+               if (ads_try_connect(ads, inet_ntoa(ip_list[i].ip), ip_list[i].port)) {
+                       free(ip_list);
+                       return True;
+               }
+       }
+
+       SAFE_FREE(ip_list);
+       return False;
+}
+
+/* try connecting to a ldap server via netbios */
+static BOOL ads_try_netbios(ADS_STRUCT *ads)
+{
+       struct in_addr *ip_list;
+       int count;
+       int i;
+       char *workgroup = ads->server.workgroup;
+
+       if (!workgroup) {
+               workgroup = lp_workgroup();
+       }
+
+       DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup));
+
+       /* try the PDC first */
+       if (get_dc_list(True, workgroup, &ip_list, &count)) { 
+               for (i=0;i<count;i++) {
+                       DEBUG(6,("ads_try_netbios: trying server '%s'\n", 
+                                inet_ntoa(ip_list[i])));
+                       if (ads_try_connect(ads, inet_ntoa(ip_list[i]), LDAP_PORT)) {
+                               free(ip_list);
+                               return True;
+                       }
+               }
+               free(ip_list);
+       }
+
+       /* now any DC, including backups */
+       if (get_dc_list(False, workgroup, &ip_list, &count)) { 
+               for (i=0;i<count;i++) {
+                       DEBUG(6,("ads_try_netbios: trying server '%s'\n", 
+                                inet_ntoa(ip_list[i])));
+                       if (ads_try_connect(ads, inet_ntoa(ip_list[i]), LDAP_PORT)) {
+                               free(ip_list);
+                               return True;
+                       }
+               }
+               free(ip_list);
+       }
+
+       return False;
+}
+
 /**
  * Connect to the LDAP server
  * @param ads Pointer to an existing ADS_STRUCT
@@ -49,38 +208,35 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
        ADS_STATUS status;
 
        ads->last_attempt = time(NULL);
-
        ads->ld = NULL;
 
-       if (ads->ldap_server) {
-               ads->ld = ldap_open(ads->ldap_server, ads->ldap_port);
+       /* try with a user specified server */
+       if (ads->server.ldap_server && 
+           ads_try_connect(ads, ads->server.ldap_server, LDAP_PORT)) {
+               goto got_connection;
        }
 
-       /* if that failed then try each of the BDC's in turn */
-       if (!ads->ld) {
-               struct in_addr *ip_list;
-               int count;
-
-               if (get_dc_list(False, ads->workgroup, &ip_list, &count)) {
-                       int i;
-                       for (i=0;i<count;i++) {
-                               ads->ld = ldap_open(inet_ntoa(ip_list[i]),
-                                                   ads->ldap_port);
-                               if (ads->ld) break;
-                       }
-                       if (ads->ld) {
-                               SAFE_FREE(ads->ldap_server);
-                               ads->ldap_server = strdup(inet_ntoa(ip_list[i]));
-                       }
-                       free(ip_list);
-               }
+       /* try with a smb.conf ads server setting if we are connecting
+           to the primary workgroup or realm */
+       if (!ads->server.foreign &&
+           ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) {
+               goto got_connection;
        }
 
-       if (!ads->ld) {
-               return ADS_ERROR_SYSTEM(errno);
+       /* try via DNS */
+       if (ads_try_dns(ads)) {
+               goto got_connection;
+               }
+
+       /* try via netbios lookups */
+       if (!lp_disable_netbios() && ads_try_netbios(ads)) {
+               goto got_connection;
        }
 
-       DEBUG(3,("Connected to LDAP server %s\n", ads->ldap_server));
+       return ADS_ERROR_SYSTEM(errno?errno:ENOENT);
+
+got_connection:
+       DEBUG(3,("Connected to LDAP server %s\n", inet_ntoa(ads->ldap_ip)));
 
        status = ads_server_info(ads);
        if (!ADS_ERR_OK(status)) {
@@ -90,22 +246,43 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
 
        ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
 
+       if (!ads->auth.user_name) {
+               /* by default use the machine account */
+               extern pstring global_myname;
+               fstring myname;
+               fstrcpy(myname, global_myname);
+               strlower(myname);
+               asprintf(&ads->auth.user_name, "HOST/%s", myname);
+       }
+
+       if (!ads->auth.realm) {
+               ads->auth.realm = strdup(ads->config.realm);
+       }
+
+       if (!ads->auth.kdc_server) {
+               ads->auth.kdc_server = strdup(inet_ntoa(ads->ldap_ip));
+       }
+
 #if KRB5_DNS_HACK
        /* this is a really nasty hack to avoid ADS DNS problems. It needs a patch
           to MIT kerberos to work (tridge) */
        {
                char *env;
-               asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->server_realm);
-               setenv(env, inet_ntoa(*interpret_addr2(ads->ldap_server)), 1);
+               asprintf(&env, "KRB5_KDC_ADDRESS_%s", ads->config.realm);
+               setenv(env, ads->auth.kdc_server, 1);
                free(env);
        }
 #endif
 
-       if (ads->password) {
+       if (ads->auth.password) {
                if ((code = ads_kinit_password(ads)))
                        return ADS_ERROR_KRB5(code);
        }
 
+       if (ads->auth.no_bind) {
+               return ADS_SUCCESS;
+       }
+
        return ads_sasl_bind(ads);
 }
 
@@ -161,7 +338,7 @@ static char **ads_push_strvals(TALLOC_CTX *ctx, const char **in_vals)
        if (!values) return NULL;
 
        for (i=0; in_vals[i]; i++) {
-               push_utf8_talloc(ctx, (void **) &values[i], in_vals[i]);
+               push_utf8_talloc(ctx, &values[i], in_vals[i]);
        }
        return values;
 }
@@ -180,7 +357,7 @@ static char **ads_pull_strvals(TALLOC_CTX *ctx, const char **in_vals)
        if (!values) return NULL;
 
        for (i=0; in_vals[i]; i++) {
-               pull_utf8_talloc(ctx, (void **) &values[i], in_vals[i]);
+               pull_utf8_talloc(ctx, &values[i], in_vals[i]);
        }
        return values;
 }
@@ -219,8 +396,8 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
        /* 0 means the conversion worked but the result was empty 
           so we only fail if it's negative.  In any case, it always 
           at least nulls out the dest */
-       if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) ||
-           (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) {
+       if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) ||
+           (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) {
                rc = LDAP_NO_MEMORY;
                goto done;
        }
@@ -230,7 +407,7 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
        else {
                /* This would be the utf8-encoded version...*/
                /* if (!(search_attrs = ads_push_strvals(ctx, attrs))) */
-                       if (!(str_list_copy(&search_attrs, (char **) attrs)))
+               if (!(str_list_copy(&search_attrs, attrs)))
                {
                        rc = LDAP_NO_MEMORY;
                        goto done;
@@ -442,8 +619,8 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
        /* 0 means the conversion worked but the result was empty 
           so we only fail if it's negative.  In any case, it always 
           at least nulls out the dest */
-       if ((push_utf8_talloc(ctx, (void **) &utf8_exp, exp) < 0) ||
-           (push_utf8_talloc(ctx, (void **) &utf8_path, bind_path) < 0)) {
+       if ((push_utf8_talloc(ctx, &utf8_exp, exp) < 0) ||
+           (push_utf8_talloc(ctx, &utf8_path, bind_path) < 0)) {
                rc = LDAP_NO_MEMORY;
                goto done;
        }
@@ -453,7 +630,7 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
        else {
                /* This would be the utf8-encoded version...*/
                /* if (!(search_attrs = ads_push_strvals(ctx, attrs)))  */
-               if (!(str_list_copy(&search_attrs, (char **) attrs)))
+               if (!(str_list_copy(&search_attrs, attrs)))
                {
                        rc = LDAP_NO_MEMORY;
                        goto done;
@@ -494,7 +671,7 @@ ADS_STATUS ads_search(ADS_STRUCT *ads, void **res,
                      const char *exp, 
                      const char **attrs)
 {
-       return ads_do_search(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, 
+       return ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE, 
                             exp, attrs, res);
 }
 
@@ -805,11 +982,11 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
 
        if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", hostname)))
                goto done;
-       if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->realm)))
+       if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm)))
                goto done;
        ou_str = ads_ou_string(org_unit);
        new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", hostname, ou_str, 
-                                ads->bind_path);
+                                ads->config.bind_path);
        free(ou_str);
        if (!new_dn)
                goto done;
@@ -925,6 +1102,7 @@ static BOOL ads_dump_field(char *field, void **values, void *data_area)
        } handlers[] = {
                {"objectGUID", False, dump_binary},
                {"nTSecurityDescriptor", False, dump_sd},
+               {"dnsRecord", False, dump_binary},
                {"objectSid", False, dump_sid},
                {NULL, True, NULL}
        };
@@ -999,7 +1177,7 @@ void ads_process_results(ADS_STRUCT *ads, void *res,
                        char *field;
                        BOOL string; 
 
-                       pull_utf8_talloc(ctx, (void **) &field, utf8_field);
+                       pull_utf8_talloc(ctx, &field, utf8_field);
                        string = fn(field, NULL, data_area);
 
                        if (string) {
@@ -1061,7 +1239,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org
                status = ads_leave_realm(ads, host);
                if (!ADS_ERR_OK(status)) {
                        DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", 
-                                 host, ads->realm));
+                                 host, ads->config.realm));
                        return status;
                }
        }
@@ -1224,20 +1402,15 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
        char *host = strdup(hostname);
        char *principal; 
 
-        if (!ads->kdc_server) {
-               DEBUG(0, ("Unable to find KDC server\n"));
-               return ADS_ERROR(LDAP_SERVER_DOWN);
-       }
-
        strlower(host);
 
        /*
          we need to use the '$' form of the name here, as otherwise the
          server might end up setting the password for a user instead
         */
-       asprintf(&principal, "%s$@%s", host, ads->realm);
+       asprintf(&principal, "%s$@%s", host, ads->auth.realm);
        
-       status = krb5_set_password(ads->kdc_server, principal, password);
+       status = krb5_set_password(ads->auth.kdc_server, principal, password);
        
        free(host);
        free(principal);
@@ -1287,7 +1460,7 @@ char *ads_pull_string(ADS_STRUCT *ads,
        if (!values) return NULL;
        
        if (values[0]) {
-               rc = pull_utf8_talloc(mem_ctx, (void **)&ux_string, 
+               rc = pull_utf8_talloc(mem_ctx, &ux_string, 
                                      values[0]);
                if (rc != -1)
                        ret = ux_string;
@@ -1321,7 +1494,7 @@ char **ads_pull_strings(ADS_STRUCT *ads,
        ret = talloc(mem_ctx, sizeof(char *) * (n+1));
 
        for (i=0;i<n;i++) {
-               if (pull_utf8_talloc(mem_ctx, (void **)&ret[i], values[i]) == -1) {
+               if (pull_utf8_talloc(mem_ctx, &ret[i], values[i]) == -1) {
                        return NULL;
                }
        }
@@ -1472,33 +1645,27 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
                return ADS_ERROR(LDAP_DECODING_ERROR);
        }
 
-       SAFE_FREE(ads->ldap_server_name);
+       SAFE_FREE(ads->config.ldap_server_name);
 
-       ads->ldap_server_name = strdup(p+1);
-       p = strchr(ads->ldap_server_name, '$');
+       ads->config.ldap_server_name = strdup(p+1);
+       p = strchr(ads->config.ldap_server_name, '$');
        if (!p || p[1] != '@') {
                ldap_value_free(values);
                ldap_msgfree(res);
-               SAFE_FREE(ads->ldap_server_name);
+               SAFE_FREE(ads->config.ldap_server_name);
                return ADS_ERROR(LDAP_DECODING_ERROR);
        }
 
        *p = 0;
 
-       SAFE_FREE(ads->server_realm);
-       SAFE_FREE(ads->bind_path);
+       SAFE_FREE(ads->config.realm);
+       SAFE_FREE(ads->config.bind_path);
 
-       ads->server_realm = strdup(p+2);
-       ads->bind_path = ads_build_dn(ads->server_realm);
-
-       /* in case the realm isn't configured in smb.conf */
-       if (!ads->realm || !ads->realm[0]) {
-               SAFE_FREE(ads->realm);
-               ads->realm = strdup(ads->server_realm);
-       }
+       ads->config.realm = strdup(p+2);
+       ads->config.bind_path = ads_build_dn(ads->config.realm);
 
        DEBUG(3,("got ldap server name %s@%s\n", 
-                ads->ldap_server_name, ads->realm));
+                ads->config.ldap_server_name, ads->config.realm));
 
        return ADS_SUCCESS;
 }
@@ -1514,9 +1681,13 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
  * @return the count of SIDs pulled
  **/
 ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, 
-                              int *num_trusts, char ***names, DOM_SID **sids)
+                              int *num_trusts, 
+                              char ***names, 
+                              char ***alt_names,
+                              DOM_SID **sids)
 {
-       const char *attrs[] = {"flatName", "securityIdentifier", NULL};
+       const char *attrs[] = {"name", "flatname", "securityIdentifier", 
+                              "trustDirection", NULL};
        ADS_STATUS status;
        void *res, *msg;
        int count, i;
@@ -1533,11 +1704,31 @@ ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
        }
 
        (*names) = talloc(mem_ctx, sizeof(char *) * count);
+       (*alt_names) = talloc(mem_ctx, sizeof(char *) * count);
        (*sids) = talloc(mem_ctx, sizeof(DOM_SID) * count);
        if (! *names || ! *sids) return ADS_ERROR(LDAP_NO_MEMORY);
 
        for (i=0, msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
-               (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatName");
+               uint32 direction;
+
+               /* direction is a 2 bit bitfield, 1 means they trust us 
+                  but we don't trust them, so we should not list them
+                  as users from that domain can't login */
+               if (ads_pull_uint32(ads, msg, "trustDirection", &direction) &&
+                   direction == 1) {
+                       continue;
+               }
+               
+               (*names)[i] = ads_pull_string(ads, mem_ctx, msg, "name");
+               (*alt_names)[i] = ads_pull_string(ads, mem_ctx, msg, "flatname");
+
+               if ((*alt_names)[i] && (*alt_names)[i][0]) {
+                       /* we prefer the flatname as the primary name
+                          for consistency with RPC */
+                       char *name = (*alt_names)[i];
+                       (*alt_names)[i] = (*names)[i];
+                       (*names)[i] = name;
+               }
                if (ads_pull_sid(ads, msg, "securityIdentifier", &(*sids)[i])) {
                        i++;
                }
@@ -1562,7 +1753,7 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
        void *res;
        ADS_STATUS rc;
 
-       rc = ads_do_search(ads, ads->bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", 
+       rc = ads_do_search(ads, ads->config.bind_path, LDAP_SCOPE_BASE, "(objectclass=*)", 
                           attrs, &res);
        if (!ADS_ERR_OK(rc)) return rc;
        if (!ads_pull_sid(ads, res, "objectSid", sid)) {
@@ -1573,4 +1764,66 @@ ADS_STATUS ads_domain_sid(ADS_STRUCT *ads, DOM_SID *sid)
        return ADS_SUCCESS;
 }
 
+/* this is rather complex - we need to find the allternate (netbios) name
+   for the domain, but there isn't a simple query to do this. Instead
+   we look for the principle names on the DCs account and find one that has 
+   the right form, then extract the netbios name of the domain from that
+*/
+ADS_STATUS ads_workgroup_name(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **workgroup)
+{
+       char *exp;
+       ADS_STATUS rc;
+       char **principles;
+       char *prefix;
+       int prefix_length;
+       int i;
+       void *res;
+       const char *attrs[] = {"servicePrincipalName", NULL};
+
+       (*workgroup) = NULL;
+
+       asprintf(&exp, "(&(objectclass=computer)(dnshostname=%s.%s))", 
+                ads->config.ldap_server_name, ads->config.realm);
+       rc = ads_search(ads, &res, exp, attrs);
+       free(exp);
+
+       if (!ADS_ERR_OK(rc)) {
+               return rc;
+       }
+
+       principles = ads_pull_strings(ads, mem_ctx, res, "servicePrincipalName");
+
+       ads_msgfree(ads, res);
+
+       if (!principles) {
+               return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
+       }
+
+       asprintf(&prefix, "HOST/%s.%s/", 
+                ads->config.ldap_server_name, 
+                ads->config.realm);
+
+       prefix_length = strlen(prefix);
+
+       for (i=0;principles[i]; i++) {
+               if (strncasecmp(principles[i], prefix, prefix_length) == 0 &&
+                   strcasecmp(ads->config.realm, principles[i]+prefix_length) != 0 &&
+                   !strchr(principles[i]+prefix_length, '.')) {
+                       /* found an alternate (short) name for the domain. */
+                       DEBUG(3,("Found alternate name '%s' for realm '%s'\n",
+                                principles[i]+prefix_length, 
+                                ads->config.realm));
+                       (*workgroup) = talloc_strdup(mem_ctx, principles[i]+prefix_length);
+                       break;
+               }
+       }
+       free(prefix);
+
+       if (!*workgroup) {
+               return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
+       }
+       
+       return ADS_SUCCESS;
+}
+
 #endif
index b6e3d189c514e0146182558d496d9e922f44b9d4..b6fef24b5c19573ccbd37ea61025c1c5d1d94df2 100644 (file)
@@ -55,10 +55,10 @@ ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user,
 
        status = ADS_ERROR(LDAP_NO_MEMORY);
 
-       if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->realm)))
+       if (!(upn = talloc_asprintf(ctx, "%s@%s", user, ads->config.realm)))
                goto done;
        if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", name, 
-                                      ads->bind_path)))
+                                      ads->config.bind_path)))
                goto done;
        if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT)))
                goto done;
@@ -94,7 +94,7 @@ ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group,
        status = ADS_ERROR(LDAP_NO_MEMORY);
 
        if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group, 
-                                      ads->bind_path)))
+                                      ads->config.bind_path)))
                goto done;
        if (!(mods = ads_init_mods(ctx)))
                goto done;
index 1b55453cac9f2d780715a177c26eca74c37983b2..81dedb0a81e7c257c2fd27bef5fcad5157c6c634 100644 (file)
@@ -77,7 +77,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
 
        /* we need to fetch a service ticket as the ldap user in the
           servers realm, regardless of our realm */
-       asprintf(&sname, "ldap/%s@%s", ads->ldap_server_name, ads->server_realm);
+       asprintf(&sname, "ldap/%s@%s", ads->config.ldap_server_name, ads->config.realm);
        krb5_init_context(&ctx);
        krb5_set_default_tgs_ktypes(ctx, enc_types);
        krb5_parse_name(ctx, sname, &principal);
@@ -163,7 +163,7 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
 
        gss_release_buffer(&minor_status, &output_token);
 
-       output_token.value = malloc(strlen(ads->bind_path) + 8);
+       output_token.value = malloc(strlen(ads->config.bind_path) + 8);
        p = output_token.value;
 
        *p++ = 1; /* no sign or seal */
@@ -171,9 +171,10 @@ ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
        *p++ = max_msg_size>>16;
        *p++ = max_msg_size>>8;
        *p++ = max_msg_size;
-       snprintf(p, strlen(ads->bind_path)+4, "dn:%s", ads->bind_path);
+       snprintf(p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
+       p += strlen(ads->config.bind_path);
 
-       output_token.length = strlen(ads->bind_path) + 8;
+       output_token.length = strlen(ads->config.bind_path) + 8;
 
        gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
                          &output_token, &conf_state,
index d48eb10b710857b13172a3448872be84b5a79b56..b10b130a313bea604c90aca6cabea30d4b69f83f 100644 (file)
@@ -39,7 +39,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip
     new_password = strdup(tmp_password);
     asprintf(&service_principal, "HOST/%s", host_principal);
     
-    ret = kerberos_set_password(ads->kdc_server, host_principal, password, 
+    ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, 
                                service_principal, new_password);
 
     if (!secrets_store_machine_password(new_password)) {
index 472db69fd0d9ae5f791c0d9e5ad65f4463243f96..93cf3d95db71e11b3f1078c2e4514fdfa0bcd3a5 100644 (file)
@@ -54,9 +54,6 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user,
                return False;
        }
 
-       /* Lanman2 cannot use SMB signing. */
-       cli->sign_info.use_smb_signing = False;
-
        /* if in share level security then don't send a password now */
        if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
                passlen = 0;
@@ -209,12 +206,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user,
        SSVAL(cli->outbuf,smb_vwv3,2);
        SSVAL(cli->outbuf,smb_vwv4,cli->pid);
        SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
-       SSVAL(cli->outbuf,smb_vwv7,passlen);
        SSVAL(cli->outbuf,smb_vwv8,0);
        SIVAL(cli->outbuf,smb_vwv11,capabilities); 
        p = smb_buf(cli->outbuf);
-       memcpy(p, pword, passlen);
-       p += passlen;
+       p += clistr_push(cli, p, pword, -1, STR_TERMINATE); /* password */
+       SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
        p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
        p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
        p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
@@ -257,11 +253,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
                                  char *workgroup)
 {
        uint32 capabilities = cli_session_setup_capabilities(cli);
-       fstring pword, ntpword;
+       uchar pword[24];
+       uchar ntpword[24];
        char *p;
        BOOL tried_signing = False;
 
-       if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
+       if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) {
                return False;
        }
 
@@ -269,15 +266,21 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
                /* non encrypted password supplied. Ignore ntpass. */
                passlen = 24;
                ntpasslen = 24;
-               SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword);
-               SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword);
+               SMBencrypt(pass,cli->secblob.data,pword);
+               SMBNTencrypt(pass,cli->secblob.data,ntpword);
                if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) {
-                       cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword);
+                       cli_calculate_mac_key(cli, pass, ntpword);
                        tried_signing = True;
                }
        } else {
-               memcpy(pword, pass, passlen);
-               memcpy(ntpword, ntpass, ntpasslen);
+               /* pre-encrypted password supplied.  Only used for security=server, can't do
+                  signing becouse we don't have oringial key */
+               memcpy(pword, pass, 24);
+               if (ntpasslen == 24) {
+                       memcpy(ntpword, ntpass, 24);
+               } else {
+                       ZERO_STRUCT(ntpword);
+               }
        }
 
        /* send a session setup command */
@@ -305,8 +308,13 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
        cli_setup_bcc(cli, p);
 
        cli_send_smb(cli);
-       if (!cli_receive_smb(cli))
+       if (!cli_receive_smb(cli)) {
+               if (tried_signing) {
+                       /* We only use it if we have a successful non-guest connect */
+                       cli->sign_info.use_smb_signing = False;
+               }
                return False;
+       }
 
        show_msg(cli->inbuf);
 
@@ -482,8 +490,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user,
 
        /* encrypt the password with the challenge */
        memcpy(challenge, chal1.data + 24, 8);
-       SMBencrypt((unsigned char *)pass, challenge,lmhash);
-       SMBNTencrypt((unsigned char *)pass, challenge,nthash);
+       SMBencrypt(pass, challenge,lmhash);
+       SMBNTencrypt(pass, challenge,nthash);
 
 #if 0
        file_save("nthash.dat", nthash, 24);
@@ -1062,7 +1070,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
        }
        if (cli->fd == -1) {
                DEBUG(1,("Error connecting to %s (%s)\n",
-                        inet_ntoa(*ip),strerror(errno)));
+                        ip?inet_ntoa(*ip):host,strerror(errno)));
                return False;
        }
 
@@ -1182,9 +1190,8 @@ again:
        if (!cli_session_setup(cli, user, password, strlen(password)+1, 
                               password, strlen(password)+1, 
                               domain)) {
-               if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) 
-                   || cli_session_setup(cli, "", "", 0, 
-                                        "", 0, domain)) {
+               if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK)
+                   && cli_session_setup(cli, "", "", 0, "", 0, domain)) {
                } else {
                        nt_status = cli_nt_error(cli);
                        DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status)));
index 469b946088c22a24819b48b841477f477a229bc3..16702c375b25d41c67b7ce7380ff15e8e3aca5bb 100644 (file)
@@ -2,6 +2,7 @@
    Unix SMB/CIFS implementation.
    simple kerberos5/SPNEGO routines
    Copyright (C) Andrew Tridgell 2001
+   Copyright (C) Jim McDonough   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
@@ -439,6 +440,28 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
        return True;
 }
 
+/*
+  generate a minimal SPNEGO NTLMSSP response packet.  Doesn't contain much.
+*/
+DATA_BLOB spnego_gen_auth_response(void)
+{
+       ASN1_DATA data;
+       DATA_BLOB ret;
+
+       memset(&data, 0, sizeof(data));
+
+       asn1_push_tag(&data, ASN1_CONTEXT(1));
+       asn1_push_tag(&data, ASN1_SEQUENCE(0));
+       asn1_push_tag(&data, ASN1_CONTEXT(0));
+       asn1_write_enumerated(&data, 0);        
+       asn1_pop_tag(&data);
+       asn1_pop_tag(&data);
+       asn1_pop_tag(&data);
+
+       ret = data_blob(data.data, data.length);
+       asn1_free(&data);
+       return ret;
+}
 
 /*
   this is a tiny msrpc packet generator. I am only using this to
@@ -449,6 +472,7 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
   format specifiers are:
 
   U = unicode string (input is unix string)
+  a = address (1 byte type, 1 byte length, unicode string, all inline)
   B = data blob (pointer + length)
   b = data blob in header (pointer + length)
   d = word (4 bytes)
@@ -473,6 +497,11 @@ BOOL msrpc_gen(DATA_BLOB *blob,
                        head_size += 8;
                        data_size += str_charnum(s) * 2;
                        break;
+               case 'a':
+                       n = va_arg(ap, int);
+                       s = va_arg(ap, char *);
+                       data_size += (str_charnum(s) * 2) + 4;
+                       break;
                case 'B':
                        b = va_arg(ap, uint8 *);
                        head_size += 8;
@@ -512,6 +541,19 @@ BOOL msrpc_gen(DATA_BLOB *blob,
                        push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN);
                        data_ofs += n*2;
                        break;
+               case 'a':
+                       n = va_arg(ap, int);
+                       SSVAL(blob->data, data_ofs, n); data_ofs += 2;
+                       s = va_arg(ap, char *);
+                       n = str_charnum(s);
+                       SSVAL(blob->data, data_ofs, n*2); data_ofs += 2;
+                       if (0 < n) {
+                               push_string(NULL, blob->data+data_ofs, s, n*2,
+                                           STR_UNICODE|STR_NOALIGN);
+                       }
+                       data_ofs += n*2;
+                       break;
+                       
                case 'B':
                        b = va_arg(ap, uint8 *);
                        n = va_arg(ap, int);
@@ -550,6 +592,7 @@ BOOL msrpc_gen(DATA_BLOB *blob,
   format specifiers are:
 
   U = unicode string (output is unix string)
+  A = ascii string
   B = data blob
   b = data blob in header
   d = word (4 bytes)
@@ -584,6 +627,24 @@ BOOL msrpc_parse(DATA_BLOB *blob,
                                    STR_UNICODE|STR_NOALIGN);
                        (*ps) = strdup(p);
                        break;
+               case 'A':
+                       len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
+                       len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
+                       ptr =  IVAL(blob->data, head_ofs); head_ofs += 4;
+
+                       /* make sure its in the right format - be strict */
+                       if (len1 != len2 || ptr + len1 > blob->length) {
+                               return False;
+                       }
+                       ps = va_arg(ap, char **);
+                       if (0 < len1) {
+                               pull_string(NULL, p, blob->data + ptr, -1, 
+                                           len1, STR_ASCII|STR_NOALIGN);
+                               (*ps) = strdup(p);
+                       } else {
+                               (*ps) = NULL;
+                       }
+                       break;
                case 'B':
                        len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
                        len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
index 18564bccf43e4fa344ace85a89bf405b64df7c96..40a353fa8b62c97f4e0098169cfa4d3ba077a8eb 100644 (file)
@@ -170,6 +170,11 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
        int sock;
        BOOL result = False;
 
+       if (lp_disable_netbios()) {
+               DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
+               return False;
+       }
+
        DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, 
                   q_type, inet_ntoa(to_ip)));
 
@@ -191,7 +196,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
        if (i == count)
                goto done;
 
-       pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE);
+       pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
        result = True;
 
  done:
@@ -211,7 +216,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
 /*
   comparison function used by sort_ip_list
 */
-static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
+int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
 {
        int max_bits1=0, max_bits2=0;
        int num_interfaces = iface_count();
@@ -273,6 +278,11 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
        struct nmb_packet *nmb = &p.packet.nmb;
        struct in_addr *ip_list = NULL;
 
+       if (lp_disable_netbios()) {
+               DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
+               return NULL;
+       }
+
        if (timed_out) {
                *timed_out = False;
        }
@@ -556,6 +566,11 @@ BOOL name_resolve_bcast(const char *name, int name_type,
        int sock, i;
        int num_interfaces = iface_count();
 
+       if (lp_disable_netbios()) {
+               DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
+               return False;
+       }
+
        *return_ip_list = NULL;
        *return_count = 0;
        
@@ -602,6 +617,11 @@ BOOL resolve_wins(const char *name, int name_type,
        char **wins_tags;
        struct in_addr src_ip;
 
+       if (lp_disable_netbios()) {
+               DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
+               return False;
+       }
+
        *return_iplist = NULL;
        *return_count = 0;
        
@@ -763,7 +783,7 @@ static BOOL resolve_hosts(const char *name,
 *********************************************************/
 
 static BOOL internal_resolve_name(const char *name, int name_type,
-                                       struct in_addr **return_iplist, int *return_count)
+                                 struct in_addr **return_iplist, int *return_count)
 {
   pstring name_resolve_list;
   fstring tok;
@@ -796,6 +816,15 @@ static BOOL internal_resolve_name(const char *name, int name_type,
     return True;
   }
   
+  /* Check netbios name cache */
+
+  if (namecache_fetch(name, name_type, return_iplist, return_count)) {
+
+         /* This could be a negative response */
+
+         return (*return_count > 0);
+  }
+
   pstrcpy(name_resolve_list, lp_name_resolve_order());
   ptr = name_resolve_list;
   if (!ptr || !*ptr)
@@ -803,9 +832,16 @@ static BOOL internal_resolve_name(const char *name, int name_type,
 
   while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
          if((strequal(tok, "host") || strequal(tok, "hosts"))) {
-                 if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
-                   result = True;
-                   goto done;
+                 if (name_type == 0x20) {
+                         if (resolve_hosts(name, return_iplist, return_count)) {
+                                 result = True;
+                                 goto done;
+                         } else {
+
+                                 /* Store negative lookup result */
+
+                                 namecache_store(name, name_type, 0, NULL);
+                         }
                  }
          } else if(strequal( tok, "lmhosts")) {
                  if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
@@ -877,6 +913,10 @@ static BOOL internal_resolve_name(const char *name, int name_type,
          *return_iplist = nodupes_iplist;
          *return_count = nodupes_count;
   }
+  /* Save in name cache */
+
+  namecache_store(name, name_type, *return_count, *return_iplist);
 
   /* Display some debugging info */
 
@@ -930,11 +970,16 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
  Find the IP address of the master browser or DMB for a workgroup.
 *********************************************************/
 
-BOOL find_master_ip(char *group, struct in_addr *master_ip)
+BOOL find_master_ip(const char *group, struct in_addr *master_ip)
 {
        struct in_addr *ip_list = NULL;
        int count = 0;
 
+       if (lp_disable_netbios()) {
+               DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
+               return False;
+       }
+
        if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
                *master_ip = ip_list[0];
                SAFE_FREE(ip_list);
@@ -957,10 +1002,14 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip)
 BOOL lookup_dc_name(const char *srcname, const char *domain, 
                    struct in_addr *dc_ip, char *ret_name)
 {
-#if !defined(I_HATE_WINDOWS_REPLY_CODE)
-       
+#if !defined(I_HATE_WINDOWS_REPLY_CODE)        
        fstring dc_name;
        BOOL ret;
+
+       if (lp_disable_netbios()) {
+               DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
+               return False;
+       }
        
        /*
         * Due to the fact win WinNT *sucks* we must do a node status
index 95434d0ae4e102f42a54377906721b280bc3d6fa..dfa355a7ec611f84a9c69a0a12718d3672d7dc17 100644 (file)
@@ -28,7 +28,7 @@
    This implements the X/Open SMB password encryption
    It takes a password ('unix' string), a 8 byte "crypt key" 
    and puts 24 bytes of encrypted password into p24 */
-void SMBencrypt(const char *passwd, const uchar *c8, uchar *p24)
+void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24])
 {
        uchar p21[21];
 
@@ -66,9 +66,9 @@ void E_md4hash(const char *passwd, uchar p16[16])
 }
 
 /**
- * Creates the MD4 Hash of the users password in NT UNICODE.
+ * Creates the DES forward-only Hash of the users password in DOS ASCII charset
  * @param passwd password in 'unix' charset.
- * @param p16 return password hashed with md4, caller allocated 16 byte buffer
+ * @param p16 return password hashed with DES, caller allocated 16 byte buffer
  */
  
 void E_deshash(const char *passwd, uchar p16[16])
@@ -77,7 +77,7 @@ void E_deshash(const char *passwd, uchar p16[16])
        ZERO_STRUCT(dospwd);
        ZERO_STRUCTP(p16);
        
-       /* Password must be converted to DOS charset - null terminated. */
+       /* Password must be converted to DOS charset - null terminated, uppercase. */
        push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE);
 
        E_P16(dospwd, p16);
@@ -175,7 +175,7 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p
 
 /* Does the NT MD4 hash then des encryption. */
  
-void SMBNTencrypt(const uchar *passwd, uchar *c8, uchar *p24)
+void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24)
 {
        uchar p21[21];
  
@@ -226,14 +226,14 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
 void SMBOWFencrypt_ntv2(const uchar kr[16],
                        const DATA_BLOB srv_chal,
                        const DATA_BLOB cli_chal,
-                       char resp_buf[16])
+                       uchar resp_buf[16])
 {
        HMACMD5Context ctx;
 
        hmac_md5_init_limK_to_64(kr, 16, &ctx);
        hmac_md5_update(srv_chal.data, srv_chal.length, &ctx);
        hmac_md5_update(cli_chal.data, cli_chal.length, &ctx);
-       hmac_md5_final((unsigned char *)resp_buf, &ctx);
+       hmac_md5_final(resp_buf, &ctx);
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
@@ -337,7 +337,7 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
  SMB signing - setup the MAC key.
 ************************************************************/
 
-void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, const uchar resp[24])
+void cli_calculate_mac_key(struct cli_state *cli, const char *ntpasswd, const uchar resp[24])
 {
        /* Get first 16 bytes. */
        E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]);
index 3b77f7330eb30a3b620bf742ef0cefce5bd846be..fe6b673e39e9acbb2c57867a760f8ca3db5673f4 100644 (file)
@@ -35,7 +35,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_
                                         unsigned char new_trust_passwd_hash[16])
 {
        NTSTATUS result;
-       result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+       result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
                                   SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash);
        
        if (!NT_STATUS_IS_OK(result)) {
index 6c2f8de3b181e52658b126433f20ae411e791ba8..c86ee69a097db639d9a5f3a3f64519730fad0995 100644 (file)
@@ -122,6 +122,7 @@ void kill_async_dns_child(void)
 {
        if (child_pid > 0) {
                kill(child_pid, SIGTERM);
+               child_pid = -1;
        }
 }
 
index d30efb550cef5e3cb02bcefcfb2d80d5d8fbd2b7..05ea4997d5fdb0dfdbd1ee25a1d45c426d012ecb 100644 (file)
@@ -269,9 +269,8 @@ static BOOL reload_interfaces(time_t t)
 static BOOL reload_nmbd_services(BOOL test)
 {
        BOOL ret;
-       extern fstring remote_machine;
 
-       fstrcpy( remote_machine, "nmbd" );
+       set_remote_machine_name("nmbd");
 
        if ( lp_loaded() ) {
                pstring fname;
@@ -861,8 +860,10 @@ static void usage(char *pname)
 
   DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
 
-  if ( !open_sockets( is_daemon, global_nmb_port ) )
+  if ( !open_sockets( is_daemon, global_nmb_port ) ) {
+    kill_async_dns_child();
     return 1;
+  }
 
   /* Determine all the IP addresses we have. */
   load_interfaces();
@@ -871,6 +872,7 @@ static void usage(char *pname)
   if( False == create_subnets() )
   {
     DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
+    kill_async_dns_child();
     exit(1);
   }
 
@@ -882,6 +884,7 @@ static void usage(char *pname)
   if( !initialise_wins() )
   {
     DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
+    kill_async_dns_child();
     exit(1);
   }
 
@@ -896,6 +899,7 @@ static void usage(char *pname)
   if( False == register_my_workgroup_and_names() )
   {
     DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
+    kill_async_dns_child();
     exit(1);
   }
 
@@ -906,5 +910,6 @@ static void usage(char *pname)
 
   if (dbf)
     x_fclose(dbf);
+  kill_async_dns_child();
   return(0);
 }
index 7f4a7a21447045c8adf446a99b97a492c5ee2d24..ccc1f7e8ada0b01bf800e573253bed51ada80329 100644 (file)
@@ -347,7 +347,7 @@ static void become_domain_master_browser_wins(char *workgroup_name)
          we can become a domain master browser. 
        */
 
-      DEBUG(0,("become_domain_master_browser_wins: querying WINS server at IP %s \
+      DEBUG(0,("become_domain_master_browser_wins: querying WINS server from IP %s \
 for domain master browser name %s on workgroup %s\n",
          inet_ntoa(unicast_subnet->myip), nmb_namestr(&nmbname), workgroup_name));
 
index 345245c57d0f23f6edd39d3383082246767bb38b..ba7d509a77f320d511f6f425d97d0b3c2bd4cee8 100644 (file)
@@ -225,7 +225,7 @@ void refresh_my_names(time_t t)
                                wins_refresh_name(namerec);
                        }
                        namerec->data.death_time = t + lp_max_ttl();
-                       namerec->data.refresh_time = t + MIN(lp_max_ttl(), MAX_REFRESH_TIME);
+                       namerec->data.refresh_time = t + MIN(lp_max_ttl()/2, MAX_REFRESH_TIME);
                }
        }
 }
index 4ac5473d4ae69c958769297fb3e156698caf114f..b6d3c20d9956913f5082e3af87e60b4d4dedf116 100644 (file)
@@ -106,17 +106,7 @@ static void register_name_response(struct subnet_record *subrec,
                success = False;
        } else {
                /* Unicast - check to see if the response allows us to have the name. */
-               if(nmb->header.rcode != 0) {
-                       /* Error code - we didn't get the name. */
-                       success = False;
-
-                       DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n", 
-                                subrec==unicast_subnet?"WINS ":"",
-                                inet_ntoa(p->ip), 
-                                nmb_namestr(answer_name), 
-                                reg_name,
-                                nmb->header.rcode));
-               } else if (nmb->header.opcode == NMB_WACK_OPCODE) {
+               if (nmb->header.opcode == NMB_WACK_OPCODE) {
                        /* WINS server is telling us to wait. Pretend we didn't get
                           the response but don't send out any more register requests. */
 
@@ -128,6 +118,16 @@ static void register_name_response(struct subnet_record *subrec,
                        rrec->repeat_time = p->timestamp + nmb->answers->ttl;
                        rrec->num_msgs--;
                        return;
+               } else if (nmb->header.rcode != 0) {
+                       /* Error code - we didn't get the name. */
+                       success = False;
+
+                       DEBUG(0,("register_name_response: %sserver at IP %s rejected our name registration of %s IP %s with error code %d.\n", 
+                                subrec==unicast_subnet?"WINS ":"",
+                                inet_ntoa(p->ip), 
+                                nmb_namestr(answer_name), 
+                                reg_name,
+                                nmb->header.rcode));
                } else {
                        success = True;
                        /* Get the data we need to pass to the success function. */
index a20ebf16fde44851aa606882fa3999c27395719f..d252b98ed6904fd4c94f9a3ef101a74e4bfcd1b0 100644 (file)
@@ -705,14 +705,33 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
 {
   struct packet_struct *p;
   struct response_record *rrec;
+  struct in_addr to_ip;
 
   if(assert_check_subnet(subrec))
     return NULL;
 
+  to_ip = subrec->bcast_ip;
+  
+  /* queries to the WINS server turn up here as queries to IP 0.0.0.0 
+     These need to be handled a bit differently */
+  if (subrec->type == UNICAST_SUBNET && is_zero_ip(to_ip)) {
+         /* what we really need to do is loop over each of our wins
+          * servers and wins server tags here, but that just doesn't
+          * fit our architecture at the moment (userdata may already
+          * be used when we get here). For now we just query the first
+          * active wins server on the first tag. */
+         char **tags = wins_srv_tags();
+         if (!tags) {
+                 return NULL;
+         }
+         to_ip = wins_srv_ip_tag(tags[0], to_ip);
+         wins_srv_tags_free(tags);
+  }
+
   if(( p = create_and_init_netbios_packet(nmbname, 
                                          (subrec != unicast_subnet), 
                                          (subrec == unicast_subnet), 
-                                         subrec->bcast_ip)) == NULL)
+                                         to_ip)) == NULL)
     return NULL;
 
   if(lp_bind_interfaces_only()) {
@@ -1670,7 +1689,7 @@ void retransmit_or_expire_response_records(time_t t)
 to IP %s on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), 
                           subrec->subnet_name));
           }
-          rrec->repeat_time += rrec->repeat_interval;
+          rrec->repeat_time = t + rrec->repeat_interval;
           rrec->repeat_count--;
         }
         else
@@ -1950,7 +1969,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
   /* Setup the smb part. */
   ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
   memcpy(tmp,ptr,4);
-  set_message(ptr,17,17 + len,True);
+  set_message(ptr,17,23 + len,True);
   memcpy(ptr,tmp,4);
 
   SCVAL(ptr,smb_com,SMBtrans);
index 23e4f935cabdbd8612ef42c58c3ede89c7d78255..d6605d08f56c92bcc8cd456ef7bc2ce34c217357 100644 (file)
@@ -4,6 +4,8 @@
    Copyright (C) Andrew Tridgell 1994-1998
    Copyright (C) Luke Kenneth Casson Leighton 1994-1998
    Copyright (C) Jeremy Allison 1994-1998
+   Copyright (C) Jim McDonough 2002
+   Copyright (C) Anthony Liguori 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
@@ -284,19 +286,108 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
       /* Construct reply. */
 
       q = outbuf;
-      if (SVAL(uniuser, 0) == 0) {
-             SSVAL(q, 0, SAMLOGON_UNK_R);      /* user unknown */
-      }        else {
-             SSVAL(q, 0, SAMLOGON_R);
-      }
-      q += 2;
-
-      q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
-      q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
-      q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True);
+      /* we want the simple version unless we are an ADS PDC..which means  */
+      /* never, at least for now */
+      if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
+       if (SVAL(uniuser, 0) == 0) {
+         SSVAL(q, 0, SAMLOGON_UNK_R);  /* user unknown */
+       } else {
+         SSVAL(q, 0, SAMLOGON_R);
+       }
+
+       q += 2;
+
+       q += dos_PutUniCode(q, reply_name,sizeof(pstring), True);
+       q += dos_PutUniCode(q, ascuser, sizeof(pstring), True);
+       q += dos_PutUniCode(q, global_myworkgroup,sizeof(pstring), True);
+      } 
+#ifdef HAVE_ADS
+      else {
+       GUID domain_guid;
+       pstring domain;
+       char *component, *dc, *q1;
+       uint8 size;
+
+       safe_strcpy(domain, lp_realm(), sizeof(domain));
+       
+       if (SVAL(uniuser, 0) == 0) {
+         SSVAL(q, 0, SAMLOGON_AD_UNK_R);       /* user unknown */
+       } else {
+         SSVAL(q, 0, SAMLOGON_AD_R);
+       }
+       q += 2;
+
+       SSVAL(q, 0, 0);
+       q += 2;
+       SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS|
+                   ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE);
+       q += 4;
+
+       /* Push Domain GUID */
+       if (False == secrets_fetch_domain_guid(domain, &domain_guid)) {
+         DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain));
+         return;
+       }
+       memcpy(q, &domain_guid, sizeof(domain_guid));
+       q += sizeof(domain_guid);
+
+       /* Push domain components */
+       dc = domain;
+       q1 = q;
+       while ((component = strsep(&dc, "."))) {
+         size = push_ascii(&q[1], component, -1, 0);
+         SCVAL(q, 0, size);
+         q += (size + 1);
+       }
+       SCVAL(q, 0, 0); q++;
+       SSVAL(q, 0, 0x18c0); /* not sure what this is for, but  */
+       q += 2;              /* it must follow the domain name. */
+
+       /* Push dns host name */
+       size = push_ascii(&q[1], global_myname, -1, 0);
+       SCVAL(q, 0, size);
+       q += (size + 1);
+       SSVAL(q, 0, 0x18c0); /* not sure what this is for, but  */
+       q += 2;              /* it must follow the domain name. */
+
+       /* Push NETBIOS of domain */
+       size = push_ascii(&q[1], domain, -1, STR_UPPER);
+       SCVAL(q, 0, size);
+       q += (size + 1);
+       SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */
+       /* null terminator would not be needed because size is included */
+
+       /* Push NETBIOS of hostname */
+       size = push_ascii(&q[1], my_name, -1, 0);
+       SCVAL(q, 0, size);
+       q += (size + 1);
+       SCVAL(q, 0, 0); q++; /* null terminator or empty field? */
+
+       /* Push user account */
+       size = push_ascii(&q[1], ascuser, -1, 0);
+       SCVAL(q, 0, size);
+       q += (size + 1);
+
+       /* Push 'Default-First-Site-Name' */
+       size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0);
+       SCVAL(q, 0, size);
+       q += (size + 1);
+
+       SSVAL(q, 0, 0xc000); /* unknown */
+       SCVAL(q, 2, PTR_DIFF(q,q1));
+       SCVAL(q, 3, 0x10); /* unknown */
+       q += 4;
+
+       SIVAL(q, 0, 0x00000002); q += 4; /* unknown */
+       SIVAL(q, 0, (iface_ip(p->ip))->s_addr); q += 4;
+       SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
+       SIVAL(q, 0, 0x00000000); q += 4; /* unknown */
+      }        
+#endif
 
       /* tell the client what version we are */
-      SIVAL(q, 0, 1); /* our ntversion */
+      SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13); 
+      /* our ntversion */
       SSVAL(q, 4, 0xffff); /* our lmnttoken */ 
       SSVAL(q, 6, 0xffff); /* our lm20token */
       q += 8;
index 4739cfbf7adc9be4f7d694ac1d19451d3aed6001..29ceca4e79ef877e2aede66a4a70af7ffef3fb01 100644 (file)
@@ -79,7 +79,7 @@ static int converse(pam_handle_t *pamh, int nargs,
 }
 
 
-int _make_remark(pam_handle_t * pamh, int type, const char *text)
+static int _make_remark(pam_handle_t * pamh, int type, const char *text)
 {
        int retval = PAM_SUCCESS;
 
@@ -163,6 +163,10 @@ static int winbind_auth_request(const char *user, const char *pass, int ctrl)
                /* password expired */
                _pam_log(LOG_WARNING, "user `%s' password expired", user);
                return retval;
+       case PAM_NEW_AUTHTOK_REQD:
+               /* password expired */
+               _pam_log(LOG_WARNING, "user `%s' new password required", user);
+               return retval;
        case PAM_USER_UNKNOWN:
                /* the user does not exist */
                if (ctrl & WINBIND_DEBUG_ARG)
@@ -241,12 +245,12 @@ static char *_pam_delete(register char *xx)
  * obtain a password from the user
  */
 
-int _winbind_read_password(pam_handle_t * pamh
-                       ,unsigned int ctrl
-                       ,const char *comment
-                       ,const char *prompt1
-                       ,const char *prompt2
-                       ,const char **pass)
+static int _winbind_read_password(pam_handle_t * pamh
+                                 ,unsigned int ctrl
+                                 ,const char *comment
+                                 ,const char *prompt1
+                                 ,const char *prompt2
+                                 ,const char **pass)
 {
        int authtok_flag;
        int retval;
index bcb339864aecb16700712c7eef7051ea46f81ea4..9ac1515d7d3f29e81215775879970a8166c0e6b8 100644 (file)
@@ -65,7 +65,7 @@ BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
 
 /* Call winbindd to convert sid to name */
 
-BOOL winbind_lookup_sid(DOM_SID *sid, 
+BOOL winbind_lookup_sid(const DOM_SID *sid, 
                        fstring dom_name, fstring name, 
                         enum SID_NAME_USE *name_type)
 {
@@ -102,7 +102,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid,
 
 /* Call winbindd to convert SID to uid */
 
-BOOL winbind_sid_to_uid(uid_t *puid, DOM_SID *sid)
+BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
 {
        struct winbindd_request request;
        struct winbindd_response response;
@@ -168,7 +168,7 @@ BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
 
 /* Call winbindd to convert SID to gid */
 
-BOOL winbind_sid_to_gid(gid_t *pgid, DOM_SID *sid)
+BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
 {
        struct winbindd_request request;
        struct winbindd_response response;
index 89dd6252412719eede0aab1756b7efea0b637fce..9bc9faafb50e62794c6e71f8f43605e763843662 100644 (file)
@@ -28,7 +28,6 @@
 /* Global variables.  These are effectively the client state information */
 
 int winbindd_fd = -1;           /* fd for winbindd socket */
-static char *excluded_domain;
 
 /* Free a response structure */
 
@@ -40,16 +39,6 @@ void free_response(struct winbindd_response *response)
                SAFE_FREE(response->extra_data);
 }
 
-/*
-  smbd needs to be able to exclude lookups for its own domain
-*/
-void winbind_exclude_domain(const char *domain)
-{
-       SAFE_FREE(excluded_domain);
-       excluded_domain = strdup(domain);
-}
-
-
 /* Initialise a request structure */
 
 void init_request(struct winbindd_request *request, int request_type)
@@ -325,12 +314,6 @@ NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
                return NSS_STATUS_NOTFOUND;
        }
 
-       /* smbd may have excluded this domain */
-       if (excluded_domain && 
-           strcasecmp(excluded_domain, request->domain) == 0) {
-               return NSS_STATUS_NOTFOUND;
-       }
-
        if (!request) {
                ZERO_STRUCT(lrequest);
                request = &lrequest;
index d0af10a0e6fbb3f6c0be46417a5cda6b973ffef2..4d36acc51b3259ded314598b8c61a3bc842240d3 100644 (file)
@@ -255,8 +255,7 @@ static BOOL wbinfo_check_secret(void)
 
         ZERO_STRUCT(response);
 
-        result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response) ==
-                NSS_STATUS_SUCCESS;
+        result = winbindd_request(WINBINDD_CHECK_MACHACC, NULL, &response);
                
        d_printf("checking the trust secret via RPC calls %s\n", 
                 (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
@@ -490,9 +489,9 @@ static BOOL wbinfo_auth_crap(char *username)
 
        generate_random_buffer(request.data.auth_crap.chal, 8, False);
         
-        SMBencrypt((uchar *)pass, request.data.auth_crap.chal, 
+        SMBencrypt(pass, request.data.auth_crap.chal, 
                    (uchar *)request.data.auth_crap.lm_resp);
-        SMBNTencrypt((uchar *)pass, request.data.auth_crap.chal,
+        SMBNTencrypt(pass, request.data.auth_crap.chal,
                      (uchar *)request.data.auth_crap.nt_resp);
 
         request.data.auth_crap.lm_resp_len = 24;
index 358d9add3a388c10f3de544bcbfe8f3a8e946c2d..256c0203c0e2c2bb9dff2f139c55ac0e47b44fde 100644 (file)
@@ -25,7 +25,7 @@
 
 /* List of all connected clients */
 
-struct winbindd_cli_state *client_list;
+static struct winbindd_cli_state *client_list;
 static int num_clients;
 BOOL opt_nocache = False;
 BOOL opt_dual_daemon = False;
@@ -375,6 +375,9 @@ void winbind_process_packet(struct winbindd_cli_state *state)
 {
        /* Process request */
        
+       /* Ensure null termination of entire request */
+       state->request.domain[sizeof(state->request.domain)-1]='\0';
+
        state->pid = state->request.pid;
        
        process_request(state);
@@ -688,6 +691,8 @@ int winbind_setup_common(void)
 
        }
 
+       namecache_enable();     /* Enable netbios namecache */
+
        /* Get list of domains we look up requests for.  This includes the
           domain which we are a member of as well as any trusted
           domains. */ 
index 11d399be49a101792dfa5ccb8c1198eef05acb54..dd92ecefe61c3a411b32bd1c4b2d1842f9cf1a75 100644 (file)
@@ -88,7 +88,7 @@ typedef struct {
 
 struct winbindd_domain {
        fstring name;                          /* Domain name */        
-       fstring full_name;                     /* full Domain name (realm) */   
+       fstring alt_name;                      /* alt Domain name (if any) */
        DOM_SID sid;                           /* SID for this domain */
 
        /* Lookup methods for this domain (LDAP or RPC) */
@@ -170,11 +170,15 @@ struct winbindd_methods {
                                    TALLOC_CTX *mem_ctx,
                                    uint32 *num_domains,
                                    char ***names,
+                                   char ***alt_names,
                                    DOM_SID **dom_sids);
 
        /* find the domain sid */
        NTSTATUS (*domain_sid)(struct winbindd_domain *domain,
                               DOM_SID *sid);
+
+       /* setup the list of alternate names for the domain, if any */
+       NTSTATUS (*alternate_name)(struct winbindd_domain *domain);
 };
 
 /* Used to glue a policy handle and cli_state together */
@@ -190,6 +194,8 @@ typedef struct {
 #include "rpc_client.h"
 
 #define WINBINDD_ESTABLISH_LOOP 30
+#define WINBINDD_RESCAN_FREQ 300
+
 #define DOM_SEQUENCE_NONE ((uint32)-1)
 
 /* SETENV */
index b61348adfe76ab801e087f672917849f67d7d782..b0b70178a45ca9ea2e07cfbd5111fdc5ff1a3524 100644 (file)
@@ -61,8 +61,8 @@ ADS_STATUS ads_do_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope
 
                if (*res) ads_msgfree(ads, *res);
                *res = NULL;
-               DEBUG(3,("Reopening ads connection to %s after error %s\n", 
-                        ads->ldap_server, ads_errstr(status)));
+               DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n", 
+                        ads->config.realm, ads_errstr(status)));
                if (ads->ld) {
                        ldap_unbind(ads->ld); 
                }
@@ -87,7 +87,7 @@ ADS_STATUS ads_search_retry(ADS_STRUCT *ads, void **res,
                            const char *exp, 
                            const char **attrs)
 {
-       return ads_do_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE,
+       return ads_do_search_retry(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
                                   exp, attrs, res);
 }
 
@@ -108,8 +108,6 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
        ADS_STRUCT *ads;
        ADS_STATUS status;
        char *ccache;
-       struct in_addr server_ip;
-       char *sname;
 
        if (domain->private) {
                return (ADS_STRUCT *)domain->private;
@@ -120,30 +118,23 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
        SETENV("KRB5CCNAME", ccache, 1);
        unlink(ccache);
 
-       if (resolve_name(domain->name, &server_ip, 0x1b)) {
-               sname = inet_ntoa(server_ip);
-       } else if (resolve_name(domain->name, &server_ip, 0x1c)) {
-               sname = inet_ntoa(server_ip);
-       } else {
-               if (strcasecmp(domain->name, lp_workgroup()) != 0) {
-                       DEBUG(1,("can't find domain controller for %s\n", domain->name));
-                       return NULL;
-               }
-               sname = NULL;
-       }
-
-       ads = ads_init(primary_realm, domain->name, NULL, NULL, NULL);
+       ads = ads_init(domain->alt_name, domain->name, NULL);
        if (!ads) {
                DEBUG(1,("ads_init for domain %s failed\n", domain->name));
                return NULL;
        }
 
        /* the machine acct password might have change - fetch it every time */
-       SAFE_FREE(ads->password);
-       ads->password = secrets_fetch_machine_password();
+       SAFE_FREE(ads->auth.password);
+       ads->auth.password = secrets_fetch_machine_password();
+
+       if (primary_realm) {
+               SAFE_FREE(ads->auth.realm);
+               ads->auth.realm = strdup(primary_realm);
+       }
 
        status = ads_connect(ads);
-       if (!ADS_ERR_OK(status) || !ads->realm) {
+       if (!ADS_ERR_OK(status) || !ads->config.realm) {
                extern struct winbindd_methods msrpc_methods;
                DEBUG(1,("ads_connect for domain %s failed: %s\n", 
                         domain->name, ads_errstr(status)));
@@ -161,11 +152,9 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
 
        /* remember our primary realm for trusted domain support */
        if (!primary_realm) {
-               primary_realm = strdup(ads->realm);
+               primary_realm = strdup(ads->config.realm);
        }
 
-       fstrcpy(domain->full_name, ads->server_realm);
-
        domain->private = (void *)ads;
        return ads;
 }
@@ -405,7 +394,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
 
        /* accept either the win2000 or the pre-win2000 username */
        asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))", 
-                name, name, ads->realm);
+                name, name, ads->config.realm);
        rc = ads_search_retry(ads, &res, exp, attrs);
        free(exp);
        if (!ADS_ERR_OK(rc)) {
@@ -535,49 +524,6 @@ failed:
        return False;
 }
 
-
-/* convert a sid to a distnguished name */
-static NTSTATUS sid_to_distinguished_name(struct winbindd_domain *domain,
-                                         TALLOC_CTX *mem_ctx,
-                                         DOM_SID *sid,
-                                         char **dn)
-{
-       ADS_STRUCT *ads = NULL;
-       const char *attrs[] = {"distinguishedName", NULL};
-       ADS_STATUS rc;
-       void *msg = NULL;
-       char *exp;
-       char *sidstr;
-       NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-
-       DEBUG(3,("ads: sid_to_distinguished_name\n"));
-
-       ads = ads_cached_connection(domain);
-       if (!ads) goto done;
-
-       sidstr = sid_binstring(sid);
-       asprintf(&exp, "(objectSid=%s)", sidstr);
-       rc = ads_search_retry(ads, &msg, exp, attrs);
-       free(exp);
-       free(sidstr);
-       if (!ADS_ERR_OK(rc)) {
-               DEBUG(1,("sid_to_distinguished_name ads_search: %s\n", ads_errstr(rc)));
-               goto done;
-       }
-
-       *dn = ads_pull_string(ads, mem_ctx, msg, "distinguishedName");
-
-       status = NT_STATUS_OK;
-
-       DEBUG(3,("ads sid_to_distinguished_name mapped %s\n", *dn));
-
-done:
-       if (msg) ads_msgfree(ads, msg);
-
-       return status;
-}
-
-
 /* Lookup user information from a rid */
 static NTSTATUS query_user(struct winbindd_domain *domain, 
                           TALLOC_CTX *mem_ctx, 
@@ -831,6 +777,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
                                TALLOC_CTX *mem_ctx,
                                uint32 *num_domains,
                                char ***names,
+                               char ***alt_names,
                                DOM_SID **dom_sids)
 {
        ADS_STRUCT *ads;
@@ -842,7 +789,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
        ads = ads_cached_connection(domain);
        if (!ads) return NT_STATUS_UNSUCCESSFUL;
 
-       rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, dom_sids);
+       rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, alt_names, dom_sids);
 
        return ads_ntstatus(rc);
 }
@@ -867,6 +814,37 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
        return ads_ntstatus(rc);
 }
 
+
+/* find alternate names list for the domain - for ADS this is the
+   netbios name */
+static NTSTATUS alternate_name(struct winbindd_domain *domain)
+{
+       ADS_STRUCT *ads;
+       ADS_STATUS rc;
+       TALLOC_CTX *ctx;
+       char *workgroup;
+
+       ads = ads_cached_connection(domain);
+       if (!ads) return NT_STATUS_UNSUCCESSFUL;
+
+       if (!(ctx = talloc_init_named("alternate_name"))) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       rc = ads_workgroup_name(ads, ctx, &workgroup);
+
+       if (ADS_ERR_OK(rc)) {
+               fstrcpy(domain->name, workgroup);
+               fstrcpy(domain->alt_name, ads->config.realm);
+               strupper(domain->alt_name);
+               strupper(domain->name);
+       }
+
+       talloc_destroy(ctx);
+
+       return ads_ntstatus(rc);        
+}
+
 /* the ADS backend methods are exposed via this structure */
 struct winbindd_methods ads_methods = {
        True,
@@ -879,7 +857,8 @@ struct winbindd_methods ads_methods = {
        lookup_groupmem,
        sequence_number,
        trusted_domains,
-       domain_sid
+       domain_sid,
+       alternate_name
 };
 
 #endif
index a607727867fd86140c95b98d4fac6e0998bd739f..060139af3ed1b0101203a7ac67bc70b606d40c05 100644 (file)
@@ -873,13 +873,14 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
                                TALLOC_CTX *mem_ctx,
                                uint32 *num_domains,
                                char ***names,
+                               char ***alt_names,
                                DOM_SID **dom_sids)
 {
        struct winbind_cache *cache = get_cache(domain);
 
        /* we don't cache this call */
        return cache->backend->trusted_domains(domain, mem_ctx, num_domains, 
-                                              names, dom_sids);
+                                              names, alt_names, dom_sids);
 }
 
 /* find the domain sid */
@@ -891,6 +892,15 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
        return cache->backend->domain_sid(domain, sid);
 }
 
+/* find the alternate names for the domain, if any */
+static NTSTATUS alternate_name(struct winbindd_domain *domain)
+{
+       struct winbind_cache *cache = get_cache(domain);
+
+       /* we don't cache this call */
+       return cache->backend->alternate_name(domain);
+}
+
 /* the ADS backend methods are exposed via this structure */
 struct winbindd_methods cache_methods = {
        True,
@@ -903,5 +913,6 @@ struct winbindd_methods cache_methods = {
        lookup_groupmem,
        sequence_number,
        trusted_domains,
-       domain_sid
+       domain_sid,
+       alternate_name
 };
index 3ab97ed408f6731c984bde529a3854ab48b70fa8..2dec9f0558606ca33fdc24fecac34679f28d2af4 100644 (file)
@@ -90,12 +90,122 @@ struct get_dc_name_cache {
        struct get_dc_name_cache *prev, *next;
 };
 
+
+/*
+  find the DC for a domain using methods appropriate for a ADS domain
+*/
+static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
+{
+       ADS_STRUCT *ads;
+       const char *realm = domain;
+
+       if (strcasecmp(realm, lp_workgroup()) == 0) {
+               realm = lp_realm();
+       }
+
+       ads = ads_init(realm, domain, NULL);
+       if (!ads) {
+               return False;
+       }
+
+       /* we don't need to bind, just connect */
+       ads->auth.no_bind = 1;
+
+       DEBUG(4,("cm_ads_find_dc: domain=%s\n", domain));
+
+#ifdef HAVE_ADS
+       /* a full ads_connect() is actually overkill, as we don't srictly need
+          to do the SASL auth in order to get the info we need, but libads
+          doesn't offer a better way right now */
+       ads_connect(ads);
+#endif
+
+       if (!ads->config.realm) {
+               return False;
+       }
+
+       fstrcpy(srv_name, ads->config.ldap_server_name);
+       strupper(srv_name);
+       *dc_ip = ads->ldap_ip;
+       ads_destroy(&ads);
+       
+       DEBUG(4,("cm_ads_find_dc: using server='%s' IP=%s\n",
+                srv_name, inet_ntoa(*dc_ip)));
+       
+       return True;
+}
+
+/*
+  find the DC for a domain using methods appropriate for a RPC domain
+*/
+static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
+{
+       struct in_addr *ip_list = NULL;
+       int count, i;
+
+       /* Lookup domain controller name. Try the real PDC first to avoid
+          SAM sync delays */
+       if (!get_dc_list(True, domain, &ip_list, &count)) {
+               if (!get_dc_list(False, domain, &ip_list, &count)) {
+                       DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
+                       return False;
+               }
+       }
+
+       /* Pick a nice close server */
+       /* Look for DC on local net */
+       for (i = 0; i < count; i++) {
+               if (!is_local_net(ip_list[i]))
+                       continue;
+               
+               if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
+                       *dc_ip = ip_list[i];
+                       SAFE_FREE(ip_list);
+                       return True;
+               }
+               zero_ip(&ip_list[i]);
+       }
+
+       /*
+        * Secondly try and contact a random PDC/BDC.
+        */
+
+       i = (sys_random() % count);
+
+       if (!is_zero_ip(ip_list[i]) &&
+           name_status_find(domain, 0x1c, 0x20,
+                            ip_list[i], srv_name)) {
+               *dc_ip = ip_list[i];
+               SAFE_FREE(ip_list);
+               return True;
+       }
+       zero_ip(&ip_list[i]); /* Tried and failed. */
+
+       /* Finally return first DC that we can contact using a node
+          status */
+       for (i = 0; i < count; i++) {
+               if (is_zero_ip(ip_list[i]))
+                       continue;
+
+               if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
+                       *dc_ip = ip_list[i];
+                       SAFE_FREE(ip_list);
+                       return True;
+               }
+       }
+
+       SAFE_FREE(ip_list);
+
+       return False;
+}
+
+
 static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
 {
        static struct get_dc_name_cache *get_dc_name_cache;
        struct get_dc_name_cache *dcc;
-       struct in_addr *ip_list, dc_ip;
-       int count, i;
+       struct in_addr dc_ip;
+       BOOL ret;
 
        /* Check the cache for previous lookups */
 
@@ -144,66 +254,22 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr
 
        DLIST_ADD(get_dc_name_cache, dcc);
 
-       /* Lookup domain controller name. Try the real PDC first to avoid
-          SAM sync delays */
-       if (!get_dc_list(True, domain, &ip_list, &count)) {
-               if (!get_dc_list(False, domain, &ip_list, &count)) {
-                       DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
-                       return False;
-               }
-       }
+       zero_ip(&dc_ip);
 
-       /* Pick a nice close server */
-       /* Look for DC on local net */
-
-       for (i = 0; i < count; i++) {
-               if (!is_local_net(ip_list[i]))
-                       continue;
-               
-               if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
-                       dc_ip = ip_list[i];
-                       goto done;
-               }
-               zero_ip(&ip_list[i]);
+       ret = False;
+       if (lp_security() == SEC_ADS) {
+               ret = cm_ads_find_dc(domain, &dc_ip, srv_name);
        }
-
-       /*
-        * Secondly try and contact a random PDC/BDC.
-        */
-
-       i = (sys_random() % count);
-
-       if (!is_zero_ip(ip_list[i]) &&
-           name_status_find(domain, 0x1c, 0x20,
-                            ip_list[i], srv_name)) {
-               dc_ip = ip_list[i];
-               goto done;
+       if (!ret) {
+               /* fall back on rpc methods if the ADS methods fail */
+               ret = cm_rpc_find_dc(domain, &dc_ip, srv_name);
        }
-       zero_ip(&ip_list[i]); /* Tried and failed. */
 
-       /* Finally return first DC that we can contact */
-
-       for (i = 0; i < count; i++) {
-               if (is_zero_ip(ip_list[i]))
-                       continue;
-
-               if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
-                       dc_ip = ip_list[i];
-                       goto done;
-               }
+       if (!ret) {
+               return False;
        }
 
-       /* No-one to talk to )-: */
-       return False;           /* Boo-hoo */
-       
- done:
-       /* We have the netbios name and IP address of a domain controller.
-          Ideally we should sent a SAMLOGON request to determine whether
-          the DC is alive and kicking.  If we can catch a dead DC before
-          performing a cli_connect() we can avoid a 30-second timeout. */
-
        /* We have a name so make the cache entry positive now */
-
        fstrcpy(dcc->srv_name, srv_name);
 
        DEBUG(3, ("cm_get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
@@ -211,8 +277,6 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr
 
        *ip_out = dc_ip;
 
-       SAFE_FREE(ip_list);
-
        return True;
 }
 
@@ -262,11 +326,23 @@ static struct failed_connection_cache *failed_connection_cache;
 
 /* Add an entry to the failed conneciton cache */
 
-static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn, NTSTATUS result) {
+static void add_failed_connection_entry(struct winbindd_cm_conn *new_conn, 
+                                       NTSTATUS result) 
+{
        struct failed_connection_cache *fcc;
 
        SMB_ASSERT(!NT_STATUS_IS_OK(result));
 
+       /* Check we already aren't in the cache */
+
+       for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
+               if (strequal(fcc->domain_name, new_conn->domain)) {
+                       DEBUG(10, ("domain %s already tried and failed\n",
+                                  fcc->domain_name));
+                       return;
+               }
+       }
+
        /* Create negative lookup cache entry for this domain and controller */
 
        if (!(fcc = (struct failed_connection_cache *)
@@ -794,7 +870,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
                return result;
        }
        
-       result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+       result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
                                        SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
 
        if (!NT_STATUS_IS_OK(result)) {
@@ -808,7 +884,7 @@ NTSTATUS cm_get_netlogon_cli(char *domain, unsigned char *trust_passwd,
                        }
                        
                        /* Try again */
-                       result = new_cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+                       result = cli_nt_setup_creds(conn->cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
                                                        SEC_CHAN_WKSTA : SEC_CHAN_BDC, trust_passwd);
                }
                
index 20563ba7bd7cf856b6a5441e798706bd37f50e31..abb6b9da75745b93b1fa846361442d161d221655 100644 (file)
@@ -196,6 +196,9 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
        gid_t gid;
        int gr_mem_len;
        
+       /* Ensure null termination */
+       state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
+
        DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid,
                  state->request.data.groupname));
 
@@ -783,6 +786,9 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
        int i;
        TALLOC_CTX *mem_ctx;
        
+       /* Ensure null termination */
+       state->request.data.username[sizeof(state->request.data.username)-1]='\0';
+
        DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
                  state->request.data.username));
 
index 0f0e40a2ecad24f1782bf7b8d1725dfd22afdc1c..9eea94e7c0d60cbeed27fe04eca6ad0d4c4a7c3d 100644 (file)
@@ -36,7 +36,7 @@
 
 /* Update this when you change the interface.  */
 
-#define WINBIND_INTERFACE_VERSION 4
+#define WINBIND_INTERFACE_VERSION 5
 
 /* Socket commands */
 
@@ -107,6 +107,12 @@ enum winbindd_cmd {
        WINBINDD_NUM_CMDS
 };
 
+#define WINBIND_PAM_INFO3_NDR  0x0001
+#define WINBIND_PAM_INFO3_TEXT 0x0002
+#define WINBIND_PAM_NTKEY      0x0004
+#define WINBIND_PAM_LMKEY      0x0008
+#define WINBIND_PAM_CONTACT_TRUSTDOM 0x0010
+
 /* Winbind request structure */
 
 struct winbindd_request {
@@ -132,6 +138,8 @@ struct winbindd_request {
                         uint16 lm_resp_len;
                         fstring nt_resp;
                         uint16 nt_resp_len;
+                       fstring workstation;
+                       uint32 flags;
                 } auth_crap;
                 struct {
                     fstring user;
@@ -216,6 +224,8 @@ struct winbindd_response {
                        fstring nt_status_string;
                        fstring error_string;
                        int pam_error;
+                       char nt_session_key[16];
+                       char first_8_lm_hash[8];
                } auth;
        } data;
 
index e608f826c917f2f9b64aaa59e9b9382d9885c799..a8b508a49c6b93ae4f374b460dc30a57fc0b247c 100644 (file)
 */
 
 #include "winbindd.h"
-
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
+
+static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx, 
+                                   struct winbindd_cli_state *state, 
+                                   NET_USER_INFO_3 *info3) 
+{
+       prs_struct ps;
+       uint32 size;
+       if (!prs_init(&ps, 256 /* Random, non-zero number */, mem_ctx, MARSHALL)) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       if (!net_io_user_info3("", info3, &ps, 1, 3)) {
+               prs_mem_free(&ps);
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       size = prs_data_size(&ps);
+       state->response.extra_data = memdup(prs_data_p(&ps), size);
+       if (!state->response.extra_data) {
+               prs_mem_free(&ps);
+               return NT_STATUS_NO_MEMORY;
+       }
+       state->response.length += size;
+       prs_mem_free(&ps);
+       return NT_STATUS_OK;
+}
+
 /* Return a password structure from a username.  */
 
 enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) 
 {
        NTSTATUS result;
        fstring name_domain, name_user;
-       int passlen;
        unsigned char trust_passwd[16];
        time_t last_change_time;
         uint32 smb_uid_low;
@@ -46,6 +70,12 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
 
        extern pstring global_myname;
 
+       /* Ensure null termination */
+       state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
+
+       /* Ensure null termination */
+       state->request.data.auth.pass[sizeof(state->request.data.auth.pass)-1]='\0';
+
        DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
                  state->request.data.auth.user));
 
@@ -64,16 +94,14 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
                goto done;
        }
 
-       passlen = strlen(state->request.data.auth.pass);
-               
        {
                unsigned char local_lm_response[24];
                unsigned char local_nt_response[24];
                
                generate_random_buffer(chal, 8, False);
-               SMBencrypt( (const uchar *)state->request.data.auth.pass, chal, local_lm_response);
+               SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
                
-               SMBNTencrypt((const uchar *)state->request.data.auth.pass, chal, local_nt_response);
+               SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);
 
                lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
                nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
@@ -140,34 +168,67 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
         NET_USER_INFO_3 info3;
         struct cli_state *cli = NULL;
        TALLOC_CTX *mem_ctx = NULL;
-       const char *domain = NULL;
+       char *user = NULL;
+       char *domain = NULL;
+       char *contact_domain;
+       char *workstation;
 
        DATA_BLOB lm_resp, nt_resp;
 
        extern pstring global_myname;
 
-       DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
-                 state->request.data.auth_crap.domain, state->request.data.auth_crap.user));
+       /* Ensure null termination */
+       state->request.data.auth_crap.user[sizeof(state->request.data.auth_crap.user)-1]='\0';
+
+       /* Ensure null termination */
+       state->request.data.auth_crap.domain[sizeof(state->request.data.auth_crap.domain)-1]='\0';
 
-       if (!(mem_ctx = talloc_init_named("winbind pam auth crap for %s", state->request.data.auth.user))) {
+       if (!(mem_ctx = talloc_init_named("winbind pam auth crap for (utf8) %s", state->request.data.auth.user))) {
                DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n"));
                result = NT_STATUS_NO_MEMORY;
                goto done;
        }
 
+        if (pull_utf8_talloc(mem_ctx, &user, state->request.data.auth_crap.user) < 0) {
+               DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
+       }
+
        if (*state->request.data.auth_crap.domain) {
-               domain = talloc_strdup(mem_ctx, state->request.data.auth_crap.domain);
+               if (pull_utf8_talloc(mem_ctx, &domain, state->request.data.auth_crap.domain) < 0) {
+                       DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
+               }
        } else if (lp_winbind_use_default_domain()) {
-               domain = talloc_strdup(mem_ctx, lp_workgroup());
+               domain = lp_workgroup();
        } else {
-               DEBUG(5,("no domain specified with username (%s) - failing auth\n", state->request.data.auth.user));
+               DEBUG(5,("no domain specified with username (%s) - failing auth\n", 
+                        user));
                result = NT_STATUS_INVALID_PARAMETER;
                goto done;
        }
 
-       if (!domain) {
-               DEBUG(0,("winbindd_pam_auth_crap: talloc_strdup failed!\n"));
-               result = NT_STATUS_NO_MEMORY;
+       DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
+                 domain, user));
+
+       if (lp_allow_trusted_domains() && (state->request.data.auth_crap.flags & WINBIND_PAM_CONTACT_TRUSTDOM)) {
+               contact_domain = domain;
+       } else {
+               contact_domain = lp_workgroup();
+       }
+
+       if (*state->request.data.auth_crap.workstation) {
+               if (pull_utf8_talloc(mem_ctx, &workstation, state->request.data.auth_crap.workstation) < 0) {
+                       DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
+               }
+       } else {
+               workstation = global_myname;
+       }
+
+       if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
+               || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
+               DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", 
+                         state->request.data.auth_crap.lm_resp_len, 
+                         state->request.data.auth_crap.nt_resp_len));
+               result = NT_STATUS_INVALID_PARAMETER;
                goto done;
        }
 
@@ -175,13 +236,15 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
        nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
        
        /*
-        * Get the machine account password for our primary domain
+        * Get the machine account password for the domain to contact.
+        * This is either our own domain for a workstation, or possibly
+        * any domain for a PDC with trusted domains.
         */
 
-       if (!secrets_fetch_trust_account_password(
-                lp_workgroup(), trust_passwd, &last_change_time)) {
+       if (!secrets_fetch_trust_account_password (
+                contact_domain, trust_passwd, &last_change_time)) {
                DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
-                          "password for domain %s\n", lp_workgroup()));
+                          "password for domain %s\n", contact_domain));
                result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
                goto done;
        }
@@ -189,7 +252,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
        ZERO_STRUCT(info3);
 
        /* Don't shut this down - it belongs to the connection cache code */
-        result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
+        result = cm_get_netlogon_cli(contact_domain, trust_passwd, &cli);
 
         if (!NT_STATUS_IS_OK(result)) {
                 DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", nt_errstr(result)));
@@ -197,27 +260,43 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
         }
 
        result = cli_netlogon_sam_network_logon(cli, mem_ctx,
-                                               state->request.data.auth_crap.user, domain,
-                                               global_myname, state->request.data.auth_crap.chal, 
+                                               user, domain,
+                                               workstation, state->request.data.auth_crap.chal, 
                                                lm_resp, nt_resp, 
                                                &info3);
         
        if (NT_STATUS_IS_OK(result)) {
                uni_group_cache_store_netlogon(mem_ctx, &info3);
+               if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) {
+                       result = append_info3_as_ndr(mem_ctx, state, &info3);
+               }
+
+#if 0
+               /* we don't currently do this stuff right */
+               if (state->request.data.auth_crap.flags & WINBIND_PAM_NTKEY) {
+                       SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) == sizeof(info3.user_sess_key)); 
+                       memcpy(state->response.data.auth.nt_session_key, info3.user_sess_key, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
+               }
+               if (state->request.data.auth_crap.flags & WINBIND_PAM_LMKEY) {
+                       SMB_ASSERT(sizeof(state->response.data.auth.nt_session_key) <= sizeof(info3.user_sess_key)); 
+                       memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
+               }
+#endif
        }
 
 done:
 
        state->response.data.auth.nt_status = NT_STATUS_V(result);
-       fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
-       fstrcpy(state->response.data.auth.error_string, nt_errstr(result));
+       push_utf8_fstring(state->response.data.auth.nt_status_string, nt_errstr(result));
+       push_utf8_fstring(state->response.data.auth.error_string, nt_errstr(result));
        state->response.data.auth.pam_error = nt_status_to_pam(result);
 
-       DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("NTLM CRAP authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n", 
-             state->request.data.auth_crap.domain, 
-             state->request.data.auth_crap.user, 
-             state->response.data.auth.nt_status_string,
-             state->response.data.auth.pam_error));          
+       DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, 
+             ("NTLM CRAP authenticaion for user [%s]\\[%s] returned %s (PAM: %d)\n", 
+              domain,
+              user,
+              state->response.data.auth.nt_status_string,
+              state->response.data.auth.pam_error));         
 
        if (mem_ctx) 
                talloc_destroy(mem_ctx);
index 2bb0e8c49f46d6661f5d0e3ad966658fbc1f9c63..5ec34f663d8ee583020f28da821a279fa49402a5 100644 (file)
@@ -575,22 +575,23 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
                                TALLOC_CTX *mem_ctx,
                                uint32 *num_domains,
                                char ***names,
+                               char ***alt_names,
                                DOM_SID **dom_sids)
 {
        CLI_POLICY_HND *hnd;
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
        uint32 enum_ctx = 0;
-       uint32 pref_num_domains = 5;
 
        DEBUG(3,("rpc: trusted_domains\n"));
 
        *num_domains = 0;
+       *alt_names = NULL;
 
        if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
                goto done;
 
        result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
-                                       &hnd->pol, &enum_ctx, &pref_num_domains,
+                                       &hnd->pol, &enum_ctx,
                                        num_domains, names, dom_sids);
 done:
        return result;
@@ -621,6 +622,13 @@ done:
        return status;
 }
 
+/* find alternate names list for the domain - none for rpc */
+static NTSTATUS alternate_name(struct winbindd_domain *domain)
+{
+       return NT_STATUS_OK;
+}
+
+
 /* the rpc backend methods are exposed via this structure */
 struct winbindd_methods msrpc_methods = {
        False,
@@ -633,5 +641,6 @@ struct winbindd_methods msrpc_methods = {
        lookup_groupmem,
        sequence_number,
        trusted_domains,
-       domain_sid
+       domain_sid,
+       alternate_name
 };
index 372898a08a4562fd7de3b6793c9a938c67e5106f..44f857d6be017a3718f9b9f6f8c8c76420d3e646 100644 (file)
@@ -36,6 +36,9 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state)
        fstring name;
        fstring dom_name;
 
+       /* Ensure null termination */
+       state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
+
        DEBUG(3, ("[%5d]: lookupsid %s\n", state->pid, 
                  state->request.data.sid));
 
@@ -79,6 +82,12 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
        DOM_SID sid;
        struct winbindd_domain *domain;
 
+       /* Ensure null termination */
+       state->request.data.sid[sizeof(state->request.data.name.dom_name)-1]='\0';
+
+       /* Ensure null termination */
+       state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0';
+
        DEBUG(3, ("[%5d]: lookupname %s%s%s\n", state->pid,
                  state->request.data.name.dom_name, 
                  lp_winbind_separator(),
@@ -112,6 +121,9 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
 {
        DOM_SID sid;
 
+       /* Ensure null termination */
+       state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
+
        DEBUG(3, ("[%5d]: sid to uid %s\n", state->pid,
                  state->request.data.sid));
 
@@ -139,6 +151,9 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
 {
        DOM_SID sid;
 
+       /* Ensure null termination */
+       state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
+
        DEBUG(3, ("[%5d]: sid to gid %s\n", state->pid, 
                  state->request.data.sid));
 
index 55593d6ae57dc8c6325d950c50381d4872a30b75..4f57fd2c7225ce786bc148de89566cad26141811 100644 (file)
@@ -103,6 +103,9 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
        struct winbindd_domain *domain;
        TALLOC_CTX *mem_ctx;
        
+       /* Ensure null termination */
+       state->request.data.username[sizeof(state->request.data.username)-1]='\0';
+
        DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
                  state->request.data.username));
        
index d5668a2bb68eee85b892a52bfc26df5d8d30a70d..daa3abb3400529179ca1fdb3f21b462df6c15bea 100644 (file)
@@ -74,19 +74,17 @@ void free_domain_list(void)
 }
 
 /* Add a trusted domain to our list of domains */
-
-static struct winbindd_domain *add_trusted_domain(char *domain_name,
-                                                 struct winbindd_methods *methods)
+static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
+                                                 struct winbindd_methods *methods,
+                                                 DOM_SID *sid)
 {
        struct winbindd_domain *domain;
         
        /* We can't call domain_list() as this function is called from
           init_domain_list() and we'll get stuck in a loop. */
-
        for (domain = _domain_list; domain; domain = domain->next) {
-               if (strcmp(domain_name, domain->name) == 0) {
-                       DEBUG(3, ("domain %s already in domain list\n", 
-                                 domain_name));
+               if (strcmp(domain_name, domain->name) == 0 ||
+                   strcmp(domain_name, domain->alt_name) == 0) {
                        return domain;
                }
        }
@@ -101,40 +99,95 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name,
         
        ZERO_STRUCTP(domain);
 
+       /* prioritise the short name */
+       if (strchr_m(domain_name, '.') && alt_name && *alt_name) {
+               fstrcpy(domain->name, alt_name);
+               fstrcpy(domain->alt_name, domain_name);
+       } else {
        fstrcpy(domain->name, domain_name);
+               if (alt_name) {
+                       fstrcpy(domain->alt_name, alt_name);
+               }
+       }
+
         domain->methods = methods;
        domain->sequence_number = DOM_SEQUENCE_NONE;
        domain->last_seq_check = 0;
+       if (sid) {
+               sid_copy(&domain->sid, sid);
+       }
 
        /* Link to domain list */
-        
        DLIST_ADD(_domain_list, domain);
         
+       DEBUG(1,("Added domain %s %s %s\n", 
+                domain->name, domain->alt_name,
+                sid?sid_string_static(&domain->sid):""));
+        
        return domain;
 }
 
-/* Look up global info for the winbind daemon */
 
+/*
+  rescan our domains looking for new trusted domains
+ */
+void rescan_trusted_domains(void)
+{
+       struct winbindd_domain *domain;
+       TALLOC_CTX *mem_ctx;
+       static time_t last_scan;
+       time_t t = time(NULL);
+
+       /* ony rescan every few minutes */
+       if ((unsigned)(t - last_scan) < WINBINDD_RESCAN_FREQ) {
+               return;
+       }
+       last_scan = time(NULL);
+       
+       DEBUG(1, ("scanning trusted domain list\n"));
+
+       if (!(mem_ctx = talloc_init_named("init_domain_list")))
+               return;
+
+       for (domain = _domain_list; domain; domain = domain->next) {
+               NTSTATUS result;
+               char **names;
+               char **alt_names;
+               int num_domains = 0;
+               DOM_SID *dom_sids;
+               int i;
+
+               result = domain->methods->trusted_domains(domain, mem_ctx, &num_domains,
+                                                         &names, &alt_names, &dom_sids);
+               if (!NT_STATUS_IS_OK(result)) {
+                       continue;
+               }
+
+               /* Add each domain to the trusted domain list. Each domain inherits
+                  the access methods of its parent */
+               for(i = 0; i < num_domains; i++) {
+                       DEBUG(10,("Found domain %s\n", names[i]));
+                       add_trusted_domain(names[i], 
+                                          alt_names?alt_names[i]:NULL, 
+                                          domain->methods, &dom_sids[i]);
+               }
+       }
+
+       talloc_destroy(mem_ctx);
+}
+
+/* Look up global info for the winbind daemon */
 BOOL init_domain_list(void)
 {
        NTSTATUS result;
-       TALLOC_CTX *mem_ctx;
        extern struct winbindd_methods cache_methods;
        struct winbindd_domain *domain;
-       DOM_SID *dom_sids;
-       char **names;
-       int num_domains = 0;
-
-       if (!(mem_ctx = talloc_init_named("init_domain_list")))
-               return False;
 
        /* Free existing list */
-
        free_domain_list();
 
        /* Add ourselves as the first entry */
-
-       domain = add_trusted_domain(lp_workgroup(), &cache_methods);
+       domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL);
 
        /* Now we *must* get the domain sid for our primary domain. Go into
           a holding pattern until that is available */
@@ -147,29 +200,12 @@ BOOL init_domain_list(void)
                result = cache_methods.domain_sid(domain, &domain->sid);
        }
        
-       DEBUG(1,("Added domain %s (%s)\n", 
-                domain->name, 
-                sid_string_static(&domain->sid)));
-
-       DEBUG(1, ("getting trusted domain list\n"));
+       /* get any alternate name for the primary domain */
+       cache_methods.alternate_name(domain);
 
-       result = cache_methods.trusted_domains(domain, mem_ctx, &num_domains,
-                                              &names, &dom_sids);
+       /* do an initial scan for trusted domains */
+       rescan_trusted_domains();
 
-       /* Add each domain to the trusted domain list */
-       if (NT_STATUS_IS_OK(result)) {
-               int i;
-               for(i = 0; i < num_domains; i++) {
-                       domain = add_trusted_domain(names[i], &cache_methods);
-                       if (!domain) continue;
-                       sid_copy(&domain->sid, &dom_sids[i]);
-                       DEBUG(1,("Added domain %s (%s)\n", 
-                                domain->name, 
-                                sid_string_static(&domain->sid)));
-               }
-       }
-
-       talloc_destroy(mem_ctx);
        return True;
 }
 
@@ -184,7 +220,7 @@ struct winbindd_domain *find_domain_from_name(const char *domain_name)
 
        for (domain = domain_list(); domain != NULL; domain = domain->next) {
                if (strequal(domain_name, domain->name) ||
-                   strequal(domain_name, domain->full_name))
+                   (domain->alt_name[0] && strequal(domain_name, domain->alt_name)))
                        return domain;
        }
 
index 8f9a7414bdc3208c5eca5b5e96d67a4a4236683d..8ddd5dc10df1522558e020cb0761c5ff47bf1f0d 100644 (file)
@@ -122,6 +122,9 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
        int i, count, maxlen, size;
        struct node_status *status;
 
+       /* Ensure null termination */
+       state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
+
        DEBUG(3, ("[%5d]: wins_byip %s\n", state->pid,
                state->request.data.winsreq));
 
@@ -166,6 +169,9 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
        fstring response;
        char * addr;
 
+       /* Ensure null termination */
+       state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
+
        DEBUG(3, ("[%5d]: wins_byname %s\n", state->pid,
                state->request.data.winsreq));
 
index 6e3ce460cd4d7aaadcee051da2c88f15f124e16a..b16f4483f842547e56bcbe629386bb7ec10d6e3d 100644 (file)
@@ -87,6 +87,7 @@ static BOOL defaults_saved = False;
  */
 typedef struct
 {
+       char *smb_ports;
        char *dos_charset;
        char *unix_charset;
        char *display_charset;
@@ -165,6 +166,7 @@ typedef struct
        char *szGuestaccount;
        char *szManglingMethod;
        int max_log_size;
+       char *szLogLevel;
        int mangled_stack;
        int max_xmit;
        int max_mux;
@@ -256,7 +258,9 @@ typedef struct
        BOOL bHostnameLookups;
        BOOL bUseSpnego;
        BOOL bUnixExtensions;
+       BOOL bDisableNetbios;
        int restrict_anonymous;
+       int name_cache_timeout;
 }
 global;
 
@@ -313,6 +317,7 @@ typedef struct
        char *fstype;
        char *szVfsObjectFile;
        char *szVfsOptions;
+       char *szVfsPath;
        int iMinPrintSpace;
        int iMaxPrintJobs;
        int iWriteCacheSize;
@@ -339,6 +344,7 @@ typedef struct
        BOOL bCaseMangle;
        BOOL bHideDotFiles;
        BOOL bHideUnReadable;
+       BOOL bHideUnWriteableFiles;
        BOOL bBrowseable;
        BOOL bAvailable;
        BOOL bRead_only;
@@ -431,6 +437,7 @@ static service sDefault = {
        NULL,                   /* fstype */
        NULL,                   /* vfs object */
        NULL,                   /* vfs options */
+       NULL,                   /* vfs path */
        0,                      /* iMinPrintSpace */
        1000,                   /* iMaxPrintJobs */
        0,                      /* iWriteCacheSize */
@@ -457,6 +464,7 @@ static service sDefault = {
        False,                  /* case mangle */
        True,                   /* bHideDotFiles */
        False,                  /* bHideUnReadable */
+       False,                  /* bHideUnWriteableFiles */
        True,                   /* bBrowseable */
        True,                   /* bAvailable */
        True,                   /* bRead_only */
@@ -545,7 +553,9 @@ static struct enum_list enum_security[] = {
        {SEC_USER, "USER"},
        {SEC_SERVER, "SERVER"},
        {SEC_DOMAIN, "DOMAIN"},
+#ifdef HAVE_ADS
        {SEC_ADS, "ADS"},
+#endif
        {-1, NULL}
 };
 
@@ -759,8 +769,8 @@ static struct parm_struct parm_table[] = {
        {"Logging Options", P_SEP, P_SEPARATOR},
 
        {"admin log", P_BOOL, P_GLOBAL, &Globals.bAdminLog, NULL, NULL, 0},
-       {"log level", P_STRING, P_GLOBAL, NULL, handle_debug_list, NULL, 0},
-       {"debuglevel", P_STRING, P_GLOBAL, NULL, handle_debug_list, NULL, 0},
+       {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, 0},
+       {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, 0},
        {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
        {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
        {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
@@ -774,6 +784,7 @@ static struct parm_struct parm_table[] = {
        
        {"Protocol Options", P_SEP, P_SEPARATOR},
        
+       {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, 0},
        {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
        {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, 0},
        {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
@@ -782,6 +793,7 @@ static struct parm_struct parm_table[] = {
        {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
        {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
        {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
+       {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, 0},
        
        {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0},
        {"nt acl support", P_BOOL,  P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE },
@@ -827,6 +839,8 @@ static struct parm_struct parm_table[] = {
        {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, 0},
        {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
 
+       {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, 0},
+
        {"Printing Options", P_SEP, P_SEPARATOR},
        
        {"total print jobs", P_INTEGER, P_GLOBAL, &Globals.iTotalPrintJobs, NULL, NULL, FLAG_PRINT},
@@ -875,6 +889,7 @@ static struct parm_struct parm_table[] = {
        {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
        {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
        {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
+       {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
        {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
        {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
        {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
@@ -1021,6 +1036,7 @@ static struct parm_struct parm_table[] = {
        
        {"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, FLAG_SHARE},
        {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE},
+       {"vfs path", P_STRING, P_LOCAL, &sDefault.szVfsPath, NULL, NULL, FLAG_SHARE},
 
        
        {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
@@ -1057,26 +1073,26 @@ static void init_printer_values(void)
                case PRINT_AIX:
                case PRINT_LPRNT:
                case PRINT_LPROS2:
-                       string_set(&sDefault.szLpqcommand, "lpq -P%p");
-                       string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
+                       string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
+                       string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
                        string_set(&sDefault.szPrintcommand,
-                                  "lpr -r -P%p %s");
+                                  "lpr -r -P'%p' %s");
                        break;
 
                case PRINT_LPRNG:
                case PRINT_PLP:
-                       string_set(&sDefault.szLpqcommand, "lpq -P%p");
-                       string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
+                       string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
+                       string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
                        string_set(&sDefault.szPrintcommand,
-                                  "lpr -r -P%p %s");
+                                  "lpr -r -P'%p' %s");
                        string_set(&sDefault.szQueuepausecommand,
-                                  "lpc stop %p");
+                                  "lpc stop '%p'");
                        string_set(&sDefault.szQueueresumecommand,
-                                  "lpc start %p");
+                                  "lpc start '%p'");
                        string_set(&sDefault.szLppausecommand,
-                                  "lpc hold %p %j");
+                                  "lpc hold '%p' %j");
                        string_set(&sDefault.szLpresumecommand,
-                                  "lpc release %p %j");
+                                  "lpc release '%p' %j");
                        break;
 
                case PRINT_CUPS:
@@ -1092,19 +1108,19 @@ static void init_printer_values(void)
                        string_set(&Globals.szPrintcapname, "cups");
 #else
                        string_set(&sDefault.szLpqcommand,
-                                  "/usr/bin/lpstat -o %p");
+                                  "/usr/bin/lpstat -o '%p'");
                        string_set(&sDefault.szLprmcommand,
-                                  "/usr/bin/cancel %p-%j");
+                                  "/usr/bin/cancel '%p-%j'");
                        string_set(&sDefault.szPrintcommand,
-                                  "/usr/bin/lp -d %p %s; rm %s");
+                                  "/usr/bin/lp -d '%p' %s; rm %s");
                        string_set(&sDefault.szLppausecommand,
-                                  "lp -i %p-%j -H hold");
+                                  "lp -i '%p-%j' -H hold");
                        string_set(&sDefault.szLpresumecommand,
-                                  "lp -i %p-%j -H resume");
+                                  "lp -i '%p-%j' -H resume");
                        string_set(&sDefault.szQueuepausecommand,
-                                  "/usr/bin/disable %p");
+                                  "/usr/bin/disable '%p'");
                        string_set(&sDefault.szQueueresumecommand,
-                                  "/usr/bin/enable %p");
+                                  "/usr/bin/enable '%p'");
                        string_set(&Globals.szPrintcapname, "lpstat");
 #endif /* HAVE_CUPS */
                        break;
@@ -1191,7 +1207,7 @@ static void init_globals(void)
 
        string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
        string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
-       Globals.szPassdbBackend = str_list_make("smbpasswd unixsam");
+       Globals.szPassdbBackend = str_list_make("smbpasswd unixsam", NULL);
 
        /* use the new 'hash2' method by default */
        string_set(&Globals.szManglingMethod, "hash2");
@@ -1201,6 +1217,9 @@ static void init_globals(void)
        /* using UTF8 by default allows us to support all chars */
        string_set(&Globals.unix_charset, "UTF8");
 
+       /* Use codepage 850 as a default for the dos character set */
+       string_set(&Globals.dos_charset, "CP850");
+
        /*
         * Allow the default PASSWD_CHAT to be overridden in local.h.
         */
@@ -1262,6 +1281,7 @@ static void init_globals(void)
        Globals.bSyslogOnly = False;
        Globals.bAdminLog = False;
        Globals.bTimestampLogs = True;
+       string_set(&Globals.szLogLevel, "0");
        Globals.bDebugHiresTimestamp = False;
        Globals.bDebugPid = False;
        Globals.bDebugUid = False;
@@ -1358,8 +1378,11 @@ static void init_globals(void)
        Globals.bWinbindEnumGroups = True;
        Globals.bWinbindUseDefaultDomain = False;
 
+       Globals.name_cache_timeout = 660; /* In seconds */
+
        Globals.bUseSpnego = True;
 
+       string_set(&Globals.smb_ports, SMB_PORTS);
 }
 
 static TALLOC_CTX *lp_talloc;
@@ -1407,7 +1430,10 @@ static char *lp_string(const char *s)
        else
                StrnCpy(ret, s, len);
 
-       trim_string(ret, "\"", "\"");
+       if (trim_string(ret, "\"", "\"")) {
+               if (strchr(ret,'"') != NULL)
+                       StrnCpy(ret, s, len);
+       }
 
        standard_sub_basic(current_user_info.smb_name,ret,len+100);
        return (ret);
@@ -1445,6 +1471,7 @@ static char *lp_string(const char *s)
 #define FN_LOCAL_INTEGER(fn_name,val) \
  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
 
+FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
@@ -1498,7 +1525,7 @@ FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
 
-FN_GLOBAL_STRING(lp_guestaccount, &Globals.szGuestaccount)
+FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
@@ -1527,6 +1554,7 @@ FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
 
+FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
@@ -1642,6 +1670,7 @@ FN_LOCAL_LIST(lp_printer_admin, printer_admin)
 FN_LOCAL_STRING(lp_fstype, fstype)
 FN_LOCAL_STRING(lp_vfsobj, szVfsObjectFile)
 FN_LOCAL_STRING(lp_vfs_options, szVfsOptions)
+FN_LOCAL_STRING(lp_vfs_path, szVfsPath)
 static FN_LOCAL_STRING(lp_volume, volume)
 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
@@ -1658,6 +1687,7 @@ FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
 FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
+FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
 FN_LOCAL_BOOL(lp_readonly, bRead_only)
 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
@@ -1715,6 +1745,7 @@ FN_LOCAL_CHAR(lp_magicchar, magic_char)
 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
 FN_GLOBAL_BOOL(lp_algorithmic_rid_base, &Globals.bAlgorithmicRidBase)
+FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
 
 typedef struct _param_opt_struct param_opt_struct;
 struct _param_opt_struct {
@@ -1904,8 +1935,8 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService,
        if (i < 0)
                return (False);
 
-       if (!(*(ServicePtrs[i]->szPath))
-           || strequal(ServicePtrs[i]->szPath, lp_pathname(-1))) {
+       if (!(*(ServicePtrs[iDefaultService]->szPath))
+           || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
                pstrcpy(newHomedir, pszHomedir);
        } else {
                pstrcpy(newHomedir, lp_pathname(iDefaultService));
@@ -1925,7 +1956,7 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService,
        ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
 
        DEBUG(3,
-             ("adding home's share [%s] for user %s at %s\n", pszHomename, 
+             ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
               user, newHomedir));
        
        return (True);
@@ -1971,14 +2002,12 @@ static BOOL lp_add_ipc(char *ipc_name, BOOL guest_ok)
        return (True);
 }
 
-BOOL (*register_printer_fn)(const char *);
-
 /***************************************************************************
 add a new printer service, with defaults coming from service iFrom.
 ***************************************************************************/
-BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
+BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
 {
-       char *comment = "From Printcap";
+       const char *comment = "From Printcap";
        int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
 
        if (i < 0)
@@ -2005,8 +2034,6 @@ BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
        DEBUG(3, ("adding printer service %s\n", pszPrintername));
 
        update_server_announce_as_printserver();
-       if (register_printer_fn && (!(*register_printer_fn)(pszPrintername)))
-               return False;
 
        return (True);
 }
@@ -2623,6 +2650,7 @@ static BOOL handle_debug_list( char *pszParmValueIn, char **ptr )
        pstring pszParmValue;
 
        pstrcpy(pszParmValue, pszParmValueIn);
+       string_set(ptr, pszParmValueIn);
        return debug_parse_levels( pszParmValue );
 }
 
@@ -2844,7 +2872,7 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
                        break;
 
                case P_LIST:
-                       *(char ***)parm_ptr = str_list_make(pszParmValue);
+                       *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
                        break;
 
                case P_STRING:
@@ -3485,8 +3513,8 @@ static void set_server_role(void)
                case SEC_DOMAIN:
                case SEC_ADS:
                        if (lp_domain_logons()) {
-                               server_role = ROLE_DOMAIN_BDC;
-                               DEBUG(10,("set_server_role:ROLE_DOMAIN_BDC\n"));
+                               server_role = ROLE_DOMAIN_PDC;
+                               DEBUG(10,("set_server_role:ROLE_DOMAIN_PDC\n"));
                                break;
                        }
                        server_role = ROLE_DOMAIN_MEMBER;
index 4e3d558e987e0de863be78dc857e3cab14ea75c3..a9c6f0729bd0e60627c5880b461c4de7e03c24bb 100644 (file)
@@ -157,6 +157,12 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
 {
        GROUP_MAP map;
 
+       const char *guest_account = lp_guestaccount();
+       if (!(guest_account && *guest_account)) {
+               DEBUG(1, ("NULL guest account!?!?\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
        if (!pwd) {
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -183,24 +189,36 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
           -- abartlet 11-May-02
        */
 
-       if (!pdb_set_user_sid_from_rid(sam_account, 
-                                      fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
-               DEBUG(0,("Can't set User SID from RID!\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
 
-       /* call the mapping code here */
-       if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
-               if (!pdb_set_group_sid(sam_account,&map.sid)){
-                       DEBUG(0,("Can't set Group SID!\n"));
-                       return NT_STATUS_INVALID_PARAMETER;
+       /* Ensure this *must* be set right */
+       if (strcmp(pwd->pw_name, guest_account) == 0) {
+               if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST)) {
+                       return NT_STATUS_UNSUCCESSFUL;
                }
-       } 
-       else {
-               if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
-                       DEBUG(0,("Can't set Group SID\n"));
+               if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS)) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+       } else {
+
+               if (!pdb_set_user_sid_from_rid(sam_account, 
+                                              fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
+                       DEBUG(0,("Can't set User SID from RID!\n"));
                        return NT_STATUS_INVALID_PARAMETER;
                }
+               
+               /* call the mapping code here */
+               if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
+                       if (!pdb_set_group_sid(sam_account,&map.sid)){
+                               DEBUG(0,("Can't set Group SID!\n"));
+                               return NT_STATUS_INVALID_PARAMETER;
+                       }
+               } 
+               else {
+                       if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
+                               DEBUG(0,("Can't set Group SID\n"));
+                               return NT_STATUS_INVALID_PARAMETER;
+                       }
+               }
        }
 
        /* check if this is a user account or a machine account */
@@ -528,6 +546,9 @@ BOOL pdb_rid_is_user(uint32 rid)
    * such that it can be identified as either a user, group etc
    * type.  there are 5 such categories, and they are documented.
    */
+       /* However, they are not in the RID, just somthing you can query
+          seperatly.  Sorry luke :-) */
+
    if(pdb_rid_is_well_known(rid)) {
       /*
        * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
@@ -571,14 +592,6 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
                        fstrcpy(name, "Administrator");
                }
                return True;
-
-       } else if (rid == DOMAIN_USER_RID_GUEST) {
-               char *p = lp_guestaccount();
-               *psid_name_use = SID_NAME_USER;
-               if(!next_token(&p, name, NULL, sizeof(fstring)))
-                       fstrcpy(name, "Guest");
-               return True;
-
        }
 
        /*
@@ -594,6 +607,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
        }
                
        /* This now does the 'generic' mapping in pdb_unix */
+       /* 'guest' is also handled there */
        if (pdb_getsampwsid(sam_account, sid)) {
                fstrcpy(name, pdb_get_username(sam_account));
                *psid_name_use = SID_NAME_USER;
@@ -716,15 +730,9 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
 
        /* check if it's a mapped group */
        if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
-               if (map.gid!=-1) {
-                       /* yes it's a mapped group to a valid unix group */
-                       sid_copy(&local_sid, &map.sid);
-                       *psid_name_use = map.sid_name_use;
-               }
-               else {
-                               /* it's a correct name but not mapped so it points to nothing*/
-                       return False;
-               }
+               /* yes it's a mapped group */
+               sid_copy(&local_sid, &map.sid);
+               *psid_name_use = map.sid_name_use;
        } else {
                /* it's not a mapped group */
                grp = getgrnam(user);
@@ -777,6 +785,8 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
                
                if (pdb_getsampwnam(sam_user, pass->pw_name)) {
                        sid_copy(psid, pdb_get_user_sid(sam_user));
+               } else if (strcmp(pass->pw_name, lp_guestaccount()) == 0) {
+                       sid_append_rid(psid, DOMAIN_USER_RID_GUEST);
                } else {
                        sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid));
                }
@@ -802,25 +812,13 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
  Convert a SID to uid - locally.
 ****************************************************************************/
 
-BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
+BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
 {
-       DOM_SID dom_sid;
-       uint32 rid;
        fstring str;
        SAM_ACCOUNT *sam_user = NULL;
 
        *name_type = SID_NAME_UNKNOWN;
 
-       sid_copy(&dom_sid, psid);
-       sid_split_rid(&dom_sid, &rid);
-
-       /*
-        * We can only convert to a uid if this is our local
-        * Domain SID (ie. we are the controling authority).
-        */
-       if (!sid_equal(get_global_sam_sid(), &dom_sid))
-               return False;
-
        if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user)))
                return False;
        
@@ -832,12 +830,37 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
                }
                DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
                          (unsigned int)*puid, pdb_get_username(sam_user)));
-       } else {
-               DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID was not found in passdb.\n", sid_to_string( str, psid)));
                pdb_free_sam(&sam_user);
-               return False;
+       } else {
+
+               DOM_SID dom_sid;
+               uint32 rid;
+               GROUP_MAP map;
+
+               pdb_free_sam(&sam_user);  
+
+               if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) {
+                       DEBUG(3, ("local_sid_to_uid: SID '%s' is a group, not a user... \n", sid_to_string(str, psid)));
+                       /* It's a group, not a user... */
+                       return False;
+               }
+
+               sid_copy(&dom_sid, psid);
+               if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
+                       DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid)));
+                       return False;
+               }
+
+               if (!pdb_rid_is_user(rid)) {
+                       DEBUG(3, ("local_sid_to_uid: sid '%s' cannot be mapped to a uid algorithmicly becouse it is a group\n", sid_to_string(str, psid)));
+                       return False;
+               }
+               
+               *puid = fallback_pdb_user_rid_to_uid(rid);
+               
+               DEBUG(5,("local_sid_to_uid: SID %s algorithmicly mapped to %ld mapped becouse SID was not found in passdb.\n", 
+                        sid_to_string(str, psid), (signed long int)(*puid)));
        }
-       pdb_free_sam(&sam_user);
 
        *name_type = SID_NAME_USER;
 
@@ -868,18 +891,13 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
  Convert a SID to gid - locally.
 ****************************************************************************/
 
-BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
+BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type)
 {
-       DOM_SID dom_sid;
-       uint32 rid;
        fstring str;
        GROUP_MAP map;
 
        *name_type = SID_NAME_UNKNOWN;
 
-       sid_copy(&dom_sid, psid);
-       sid_split_rid(&dom_sid, &rid);
-
        /*
         * We can only convert to a gid if this is our local
         * Domain SID (ie. we are the controling authority).
@@ -887,35 +905,45 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
         * Or in the Builtin SID too. JFM, 11/30/2001
         */
 
-       if (!sid_equal(get_global_sam_sid(), &dom_sid))
-               return False;
-
        if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) {
                
                /* the SID is in the mapping table but not mapped */
                if (map.gid==-1)
                        return False;
 
-               if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)){
-                       DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n",
-                               sid_string_static(&map.sid)));
-                       return False;
-               }
                *pgid = map.gid;
                *name_type = map.sid_name_use;
-               DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", sid_to_string( str, psid),
+               DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", 
+                         sid_to_string( str, psid),
                          map.nt_name, (unsigned int)*pgid));
 
        } else {
-               if (pdb_rid_is_user(rid))
+               uint32 rid;
+               SAM_ACCOUNT *sam_user = NULL;
+               if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user)))
+                       return False;
+               
+               if (pdb_getsampwsid(sam_user, psid)) {
                        return False;
+                       pdb_free_sam(&sam_user);
+               }
+
+               pdb_free_sam(&sam_user);
 
+               if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
+                       DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid)));
+                       return False;
+               }
+
+               if (pdb_rid_is_user(rid))
+                       return False;
+               
                *pgid = pdb_group_rid_to_gid(rid);
                *name_type = SID_NAME_ALIAS;
                DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u).\n", sid_to_string( str, psid),
                          (unsigned int)*pgid));
        }
-
+       
        return True;
 }
 
index dff4b40f4de71ab8ad84969e763c877c04aa0d4e..2da6de7270113b9c9117eb20d12132815482c276 100644 (file)
@@ -250,7 +250,7 @@ const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass)
                return (NULL);
 }
 
-const char* pdb_get_dirdrive (const SAM_ACCOUNT *sampass)
+const char* pdb_get_dir_drive (const SAM_ACCOUNT *sampass)
 {
        if (sampass)
                return (sampass->private.dir_drive);
@@ -1028,15 +1028,14 @@ BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
        if (!pdb_set_pass_last_set_time (sampass, time(NULL)))
                return False;
 
-       account_policy_get(AP_MAX_PASSWORD_AGE, &expire);
-
-       if (expire==(uint32)-1) {
+       if (!account_policy_get(AP_MAX_PASSWORD_AGE, &expire) 
+           || (expire==(uint32)-1)) {
                if (!pdb_set_pass_must_change_time (sampass, get_time_t_max(), False))
                        return False;
        } else {
                if (!pdb_set_pass_must_change_time (sampass, 
-                                           pdb_get_pass_last_set_time(sampass)
-                                           + expire, True))
+                                                   pdb_get_pass_last_set_time(sampass)
+                                                   + expire, True))
                        return False;
        }
        
index 3b0f54b2b3ac037d3126d969fefc30436fe18639..f311223d772c63c7bd8725a7112e79d0573d4d49 100644 (file)
@@ -123,7 +123,7 @@ static BOOL context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_ac
        return False;
 }
 
-static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, DOM_SID *sid)
+static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
 {
        struct pdb_methods *curmethods;
        if ((!context)) {
@@ -353,7 +353,7 @@ NTSTATUS make_pdb_context_list(struct pdb_context **context, char **selected)
 NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected) 
 {
        NTSTATUS ret;
-       char **newsel = str_list_make(selected);
+       char **newsel = str_list_make(selected, NULL);
        ret = make_pdb_context_list(context, newsel);
        str_list_free(&newsel);
        return ret;
@@ -434,7 +434,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
        return pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username);
 }
 
-BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, DOM_SID *sid) 
+BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid) 
 {
        struct pdb_context *pdb_context = pdb_get_static_context(False);
 
index 24eb7b9dc1f5e6cd6ac9b17d4cc030a6806ac18b..f82cb4488fc59ff298a9c0520b0233409341f4f5 100644 (file)
@@ -1,11 +1,12 @@
 /* 
    Unix SMB/CIFS implementation.
    LDAP protocol helper functions for SAMBA
-   Copyright (C) Gerald Carter 2001
-   Copyright (C) Shahms King 2001
-   Copyright (C) Jean François Micouleau 1998
-   Copyright (C) Andrew Bartlett 2002
-   
+   Copyright (C) Jean François Micouleau       1998
+   Copyright (C) Gerald Carter                         2001
+   Copyright (C) Shahms King                   2001
+   Copyright (C) Andrew Bartlett               2002
+   Copyright (C) Stefan (metze) Metzmacher     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
@@ -70,8 +71,14 @@ struct ldapsam_privates {
        
        uint32 low_nua_rid; 
        uint32 high_nua_rid; 
+
+       char *bind_dn;
+       char *bind_secret;
 };
 
+
+static struct ldapsam_privates *static_ldap_state;
+
 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
 
 /*******************************************************************
@@ -153,11 +160,13 @@ static const char *attr[] = {"uid", "pwdLastSet", "logonTime",
 static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
 {
 
+       int version;
+
        if (geteuid() != 0) {
                DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n"));
                return False;
        }
-       
+
 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
        DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
        
@@ -165,6 +174,16 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
                DEBUG(0, ("ldap_initialize: %s\n", strerror(errno)));
                return (False);
        }
+       
+       if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
+       {
+               if (version != LDAP_VERSION3)
+               {
+                       version = LDAP_VERSION3;
+                       ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
+               }
+       }
+
 #else 
 
        /* Parse the string manually */
@@ -173,7 +192,6 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
                int rc;
                int tls = LDAP_OPT_X_TLS_HARD;
                int port = 0;
-               int version;
                fstring protocol;
                fstring host;
                const char *p = ldap_state->uri; 
@@ -252,42 +270,91 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
 
 
 /*******************************************************************
- Add a rebind function for authenticated referrals
+ a rebind function for authenticated referrals
+ This version takes a void* that we can shove useful stuff in :-)
 ******************************************************************/
 
-static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
-                      int *method, int freeit )
+static int rebindproc_with_state  (LDAP * ld, char **whop, char **credp, 
+                                  int *methodp, int freeit, void *arg)
 {
-       int rc;
-       char *ldap_dn;
-       char *ldap_secret;
+       struct ldapsam_privates *ldap_state = arg;
        
        /** @TODO Should we be doing something to check what servers we rebind to?
            Could we get a referral to a machine that we don't want to give our
            username and password to? */
        
-       if (freeit != 0)
-       {
-               
-               if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret)) 
-               {
-                       DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
-                       return LDAP_OPERATIONS_ERROR;  /* No idea what to return */
-               }
-               
+       if (freeit) {
+               SAFE_FREE(*whop);
+               memset(*credp, '\0', strlen(*credp));
+               SAFE_FREE(*credp);
+       } else {
                DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", 
-                         ldap_dn));
-
-               rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
-               
-               SAFE_FREE(ldap_dn);
-               SAFE_FREE(ldap_secret);
+                         ldap_state->bind_dn));
 
-               return rc;
+               *whop = strdup(ldap_state->bind_dn);
+               if (!*whop) {
+                       return LDAP_NO_MEMORY;
+               }
+               *credp = strdup(ldap_state->bind_secret);
+               if (!*credp) {
+                       SAFE_FREE(*whop);
+                       return LDAP_NO_MEMORY;
+               }
+               *methodp = LDAP_AUTH_SIMPLE;
        }
        return 0;
 }
 
+/*******************************************************************
+ a rebind function for authenticated referrals
+ This version takes a void* that we can shove useful stuff in :-)
+ and actually does the connection.
+******************************************************************/
+
+static int rebindproc_connect_with_state (LDAP *ldap_struct, 
+                                         LDAP_CONST char *url, 
+                                         ber_tag_t request,
+                                         ber_int_t msgid, void *arg)
+{
+       struct ldapsam_privates *ldap_state = arg;
+       int rc;
+       DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", 
+                ldap_state->bind_dn));
+       
+       /** @TODO Should we be doing something to check what servers we rebind to?
+           Could we get a referral to a machine that we don't want to give our
+           username and password to? */
+
+       rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
+       
+       return rc;
+}
+
+/*******************************************************************
+ Add a rebind function for authenticated referrals
+******************************************************************/
+
+static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
+                      int *method, int freeit )
+{
+       return rebindproc_with_state(ldap_struct, whop, credp,
+                                  method, freeit, static_ldap_state);
+       
+}
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ this also does the connection, but no void*.
+******************************************************************/
+
+static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
+                              ber_int_t msgid)
+{
+       return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, 
+                                            static_ldap_state);
+}
+
+
 /*******************************************************************
  connect to the ldap server under system privilege.
 ******************************************************************/
@@ -297,6 +364,10 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
        char *ldap_dn;
        char *ldap_secret;
 
+       /* The rebind proc needs this *HACK*.  We are not multithreaded, so
+          this will work, but it's not nice. */
+       static_ldap_state = ldap_state;
+
        /* get the password */
        if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
        {
@@ -304,19 +375,32 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
                return False;
        }
 
+       ldap_state->bind_dn = ldap_dn;
+       ldap_state->bind_secret = ldap_secret;
+
        /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite 
           (OpenLDAP) doesnt' seem to support it */
           
        DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
                ldap_dn));
-       
-       ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc));   
 
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+# if LDAP_SET_REBIND_PROC_ARGS == 2    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc_connect); 
+# endif
+# if LDAP_SET_REBIND_PROC_ARGS == 3    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);  
+# endif
+#else
+# if LDAP_SET_REBIND_PROC_ARGS == 2    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc); 
+# endif
+# if LDAP_SET_REBIND_PROC_ARGS == 3    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);  
+# endif
+#endif
        rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
 
-       SAFE_FREE(ldap_dn);
-       SAFE_FREE(ldap_secret);
-
        if (rc != LDAP_SUCCESS)
        {
                DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
@@ -756,18 +840,20 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
                /* leave as default */
        } else {
                pdb_gethexpwd(temp, smblmpwd);
-               memset((char *)temp, '\0', sizeof(temp));
+               memset((char *)temp, '\0', strlen(temp)+1);
                if (!pdb_set_lanman_passwd(sampass, smblmpwd))
                        return False;
+               ZERO_STRUCT(smblmpwd);
        }
 
        if (!get_single_attribute (ldap_struct, entry, "ntPassword", temp)) {
                /* leave as default */
        } else {
                pdb_gethexpwd(temp, smbntpwd);
-               memset((char *)temp, '\0', sizeof(temp));
+               memset((char *)temp, '\0', strlen(temp)+1);
                if (!pdb_set_nt_passwd(sampass, smbntpwd))
                        return False;
+               ZERO_STRUCT(smbntpwd);
        }
 
        if (!get_single_attribute (ldap_struct, entry, "acctFlags", temp)) {
@@ -880,7 +966,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
                make_a_mod(mods, ldap_op, "smbHome", pdb_get_homedir(sampass));
                
        if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE))
-               make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dirdrive(sampass));
+               make_a_mod(mods, ldap_op, "homeDrive", pdb_get_dir_drive(sampass));
        
        if (IS_SAM_SET(sampass, FLAG_SAM_LOGONSCRIPT))
                make_a_mod(mods, ldap_op, "scriptPath", pdb_get_logon_script(sampass));
@@ -1153,6 +1239,10 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        BOOL ret = False;
 
+       /* The rebind proc needs this *HACK*.  We are not multithreaded, so
+          this will work, but it's not nice. */
+       static_ldap_state = ldap_state;
+
        while (!ret) {
                if (!ldap_state->entry)
                        return False;
@@ -1203,7 +1293,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us
        if (entry)
        {
                if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) {
-                       DEBUG(0,("ldapsam_getsampwnam: init_sam_from_ldap failed!\n"));
+                       DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
                        ldap_msgfree(result);
                        ldap_unbind(ldap_struct);
                        return False;
@@ -1247,7 +1337,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
 
        if (ldap_count_entries(ldap_struct, result) < 1)
        {
-               DEBUG(0,
+               DEBUG(4,
                      ("We don't find this rid [%i] count=%d\n", rid,
                       ldap_count_entries(ldap_struct, result)));
                ldap_unbind(ldap_struct);
@@ -1258,7 +1348,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
        if (entry)
        {
                if (!init_sam_from_ldap(ldap_state, user, ldap_struct, entry)) {
-                       DEBUG(0,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
+                       DEBUG(1,("ldapsam_getsampwrid: init_sam_from_ldap failed!\n"));
                        ldap_msgfree(result);
                        ldap_unbind(ldap_struct);
                        return False;
@@ -1275,7 +1365,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
        }
 }
 
-static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
+static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
 {
        uint32 rid;
        if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
@@ -1530,6 +1620,13 @@ static void free_private_data(void **vp)
                ldap_unbind((*ldap_state)->ldap_struct);
        }
 
+       if ((*ldap_state)->bind_secret) {
+               memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
+       }
+
+       SAFE_FREE((*ldap_state)->bind_dn);
+       SAFE_FREE((*ldap_state)->bind_secret);
+
        *ldap_state = NULL;
 
        /* No need to free any further, as it is talloc()ed */
index 9c5b2e1171b2e14380772d4fbbec8e5841f67817..2d37c3b8fbba5967e01d10cc4dbf582f153c6dc1 100644 (file)
@@ -735,17 +735,17 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
     
     /* dir_drive */
     /* must support set, unset and change */
-    if( (pdb_get_dirdrive(sampass) && 
+    if( (pdb_get_dir_drive(sampass) && 
         !ENTRY_VAL(old, NPF_DIR_DRIVE)) ||
        (ENTRY_VAL(old, NPF_DIR_DRIVE) && 
-        !pdb_get_dirdrive(sampass)) ||
+        !pdb_get_dir_drive(sampass)) ||
        (ENTRY_VAL(old, NPF_DIR_DRIVE) && 
-        pdb_get_dirdrive(sampass) &&
+        pdb_get_dir_drive(sampass) &&
         strcmp( ENTRY_VAL(old, NPF_DIR_DRIVE),
-                pdb_get_dirdrive(sampass)))) {
+                pdb_get_dir_drive(sampass)))) {
       need_to_modify = True;
-      set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dirdrive(sampass),
-                          strlen(pdb_get_dirdrive(sampass)), EN_MODIFIED);
+      set_single_attribute(obj, NPF_DIR_DRIVE, pdb_get_dir_drive(sampass),
+                          strlen(pdb_get_dir_drive(sampass)), EN_MODIFIED);
     }
     
     /* logon_script */
@@ -860,7 +860,7 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
     set_single_attribute(obj, NPF_HOME_DIR,
                         homedir, strlen(homedir), 0);
     
-    if(!(dirdrive = pdb_get_dirdrive(sampass)))
+    if(!(dirdrive = pdb_get_dir_drive(sampass)))
        dirdrive = empty;
        
     set_single_attribute(obj, NPF_DIR_DRIVE,
@@ -1032,7 +1032,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname)
  Routine to search the nisplus passwd file for an entry matching the username
  *************************************************************************/
 
-BOOL pdb_getsampwsid(SAM_ACCOUNT * user, DOM_SID *sid)
+BOOL pdb_getsampwsid(SAM_ACCOUNT * user, const DOM_SID *sid)
 {
        uint32 rid;
        if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
index 8c7ba364b8aa394762303bd32f6ef296b0dae29e..d40ea03511cd2aaef81e78fe0ef27c45e7b6b659 100644 (file)
@@ -1149,7 +1149,7 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
                uid = pdb_get_uid(sampass);
 
                /* If the user specified a RID, make sure its able to be both stored and retreived */
-               if (rid && uid != fallback_pdb_user_rid_to_uid(rid)) {
+               if (rid && rid != DOMAIN_USER_RID_GUEST && uid != fallback_pdb_user_rid_to_uid(rid)) {
                        DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n"));
                        return False;
                }
@@ -1417,7 +1417,7 @@ static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *s
        return True;
 }
 
-static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
+static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
 {
        uint32 rid;
        if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
index 62793189696ad795598ed977ec859c9c265ed58f..27453fc1af76f2557eb5e992466d431feefc07a1 100644 (file)
@@ -354,7 +354,8 @@ static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state,
         * Only updates fields which have been set (not defaults from smb.conf)
         */
 
-       if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE)) dir_drive = pdb_get_dirdrive(sampass);
+       if (IS_SAM_SET(sampass, FLAG_SAM_DRIVE)) 
+         dir_drive = pdb_get_dir_drive(sampass);
        else dir_drive = NULL;
        if (dir_drive) dir_drive_len = strlen(dir_drive) +1;
        else dir_drive_len = 0;
@@ -541,7 +542,7 @@ static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user
                /* increment to next in line */
                tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
 
-       /* do we have an valid interation pointer? */
+       /* do we have an valid iteration pointer? */
        if(tdb_state->passwd_tdb == NULL) {
                DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
                return False;
@@ -668,7 +669,7 @@ static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *use
        return tdbsam_getsampwnam (my_methods, user, name);
 }
 
-static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
+static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
 {
        uint32 rid;
        if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
index b4092b88f8acbe053e2dae685d21bb5e84598283..06f12164eb871ee84b3502d0c0a531fe74aa90e1 100644 (file)
@@ -49,23 +49,36 @@ static BOOL unixsam_getsampwrid (struct pdb_methods *methods,
 {
        struct passwd *pass;
        BOOL ret = False;
+       const char *guest_account = lp_guestaccount();
+       if (!(guest_account && *guest_account)) {
+               DEBUG(1, ("NULL guest account!?!?\n"));
+               return False;
+       }
+
        if (!methods) {
                DEBUG(0,("invalid methods\n"));
                return False;
        }
-
-       if (pdb_rid_is_user(rid)) {
-               pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid));
-               
-               if (pass) {
-                       ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
-                       passwd_free(&pass);
+       
+       if (rid == DOMAIN_USER_RID_GUEST) {
+               pass = getpwnam_alloc(guest_account);
+               if (!pass) {
+                       DEBUG(1, ("guest account %s does not seem to exist...\n", guest_account));
+                       return False;
                }
+       } else if (pdb_rid_is_user(rid)) {
+               pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid));
+       } else {
+               return False;
        }
+
+       ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
+       passwd_free(&pass);
+
        return ret;
 }
 
-static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
+static BOOL unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
 {
        uint32 rid;
        if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
index 3ecaf52e58674ab9a611b5f0a2701a655aa4756a..ec67b74390030dbf63560932b23892d5681bfa39 100644 (file)
@@ -128,6 +128,47 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
        return True;
 }
 
+BOOL secrets_store_domain_guid(char *domain, GUID *guid)
+{
+       fstring key;
+
+       slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
+       strupper(key);
+       return secrets_store(key, guid, sizeof(GUID));
+}
+
+BOOL secrets_fetch_domain_guid(char *domain, GUID *guid)
+{
+       GUID *dyn_guid;
+       fstring key;
+       size_t size;
+       GUID new_guid;
+
+       slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
+       strupper(key);
+       dyn_guid = (GUID *)secrets_fetch(key, &size);
+
+       DEBUG(6,("key is %s, guid is at %x, size is %d\n", key, dyn_guid, size));
+
+       if ((NULL == dyn_guid) && (ROLE_DOMAIN_PDC == lp_server_role())) {
+               uuid_generate_random(&new_guid);
+               if (!secrets_store_domain_guid(domain, &new_guid))
+                       return False;
+               dyn_guid = (GUID *)secrets_fetch(key, &size);
+               if (dyn_guid == NULL)
+                       return False;
+       }
+
+       if (size != sizeof(GUID))
+       { 
+               SAFE_FREE(dyn_guid);
+               return False;
+       }
+
+       *guid = *dyn_guid;
+       SAFE_FREE(dyn_guid);
+       return True;
+}
 
 /**
  * Form a key for fetching the machine trust account password
@@ -178,7 +219,7 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16],
        if (plaintext) {
                /* we have an ADS password - use that */
                DEBUG(4,("Using ADS machine password\n"));
-               E_md4hash((uchar *)plaintext, ret_pwd);
+               E_md4hash(plaintext, ret_pwd);
                SAFE_FREE(plaintext);
                return True;
        }
@@ -388,7 +429,9 @@ BOOL secrets_store_ldap_pw(const char* dn, char* pw)
 
 
 /**
- * The linked list is allocated on the supplied talloc context, caller gets to destory
+ * Get trusted domains info from secrets.tdb.
+ *
+ * The linked list is allocated on the supplied talloc context, caller gets to destroy
  * when done.
  *
  * @param ctx Allocation context
@@ -409,10 +452,11 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
        int start_idx;
        uint32 idx = 0;
        size_t size;
+       fstring dom_name;
        struct trusted_dom_pass *pass;
        NTSTATUS status;
 
-       secrets_init();
+       if (!secrets_init()) return NT_STATUS_ACCESS_DENIED;
 
        *num_domains = 0;
        start_idx = *enum_ctx;
@@ -455,6 +499,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
                        SAFE_FREE(pass);
                        continue;
                }
+               
+               pull_ucs2_fstring(dom_name, pass->uni_name);
+               DEBUG(18, ("Fetched secret record num %d.\nDomain name: %s, SID: %s\n",
+                          idx, dom_name, sid_string_static(&pass->domain_sid)));
 
                SAFE_FREE(secrets_key);
 
@@ -475,6 +523,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
                        dom->name = talloc_strdup_w(ctx, pass->uni_name);
                        
                        (*domains)[idx - start_idx] = dom;
+                       
+                       DEBUG(18, ("Secret record is in required range.\n \
+                                  start_idx = %d, max_num_domains = %d. Added to returned array.\n",
+                                  start_idx, max_num_domains));
 
                        *enum_ctx = idx + 1;
                        (*num_domains)++;
@@ -487,6 +539,10 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
                                /* this is the last entry in the whole enumeration */
                                status = NT_STATUS_OK;
                        }
+               } else {
+                       DEBUG(18, ("Secret is outside the required range.\n \
+                                  start_idx = %d, max_num_domains = %d. Not added to returned array\n",
+                                  start_idx, max_num_domains));
                }
                
                idx++;
index 2c574f4a61e7d681917ca59a54c2875892830a3f..6ec1e48ab3a503e52984530bba5dfabc74abe41e 100644 (file)
@@ -95,6 +95,9 @@ static void init_sid_name_map (void)
 
        if ((lp_security() == SEC_USER) && lp_domain_logons()) {
                sid_name_map[i].sid = get_global_sam_sid();
+               /* This is not lp_workgroup() for good reason:
+                  it must stay around longer than the lp_*() 
+                  strings do */
                sid_name_map[i].name = global_myworkgroup;
                sid_name_map[i].known_users = NULL;
                i++;
index 4bca63fffb1fd52745e33a9a4e0c359f38135e88..86489e9587c18f631d54e8e8bc88b9905ffbd775 100644 (file)
@@ -241,15 +241,12 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
 Scan printcap file pszPrintcapname for a printer called pszPrintername. 
 Return True if found, else False. Returns False on error, too, after logging 
 the error at level 0. For generality, the printcap name may be passed - if
-passed as NULL, the configuration will be queried for the name. pszPrintername
-must be in DOS codepage.
-The xxx_printername_ok functions need fixing to understand they are being
-given a DOS codepage. FIXME !! JRA.
+passed as NULL, the configuration will be queried for the name. 
 ***************************************************************************/
-BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
+BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname)
 {
   char *line=NULL;
-  char *psz;
+  const char *psz;
   char *p,*q;
   XFILE *pfile;
 
@@ -305,8 +302,6 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
 
          if (strequal(p,pszPrintername))
            {
-             /* normalise the case */
-             pstrcpy(pszPrintername,p);
              SAFE_FREE(line);
              x_fclose(pfile);
              return(True);           
index 44127c3700af77ff62ae43223e3c25ae1b1a6222..837a2fba483e8bb4f8673ba680f76a61d6c5f807 100644 (file)
@@ -126,7 +126,7 @@ void sysv_printer_fn(void (*fn)(char *, char *))
  * provide the equivalent of pcap_printername_ok() for SVID/XPG4 conforming
  * systems.
  */
-int sysv_printername_ok(char *name)
+int sysv_printername_ok(const char *name)
 {
        printer_t *tmp;
 
index 9f33d57ad5214722e0602880e2a2b3ad64bbac61..ff50ac47c492e18d6e939935e55ccc6705c49bd2 100644 (file)
@@ -54,7 +54,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
 
        /* setup a full fsp */
        fsp->print_jobid = jobid;
-       fsp->fd = print_job_fd(jobid);
+       fsp->fd = print_job_fd(SNUM(conn),jobid);
        GetTimeOfDay(&fsp->open_time);
        fsp->vuid = current_user.vuid;
        fsp->size = 0;
@@ -70,7 +70,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
        fsp->is_directory = False;
        fsp->directory_delete_on_close = False;
        fsp->conn = conn;
-       string_set(&fsp->fsp_name,print_job_fname(jobid));
+       string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid));
        fsp->wbmpx_ptr = NULL;      
        fsp->wcp = NULL; 
        conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf);
@@ -96,7 +96,7 @@ void print_fsp_end(files_struct *fsp, BOOL normal_close)
                sys_ftruncate(fsp->fd, 0);
        }
 
-       print_job_end(fsp->print_jobid, normal_close);
+       print_job_end(SNUM(fsp->conn),fsp->print_jobid, normal_close);
 
        if (fsp->fsp_name) {
                string_free(&fsp->fsp_name);
index 7bfce43af61209aa8c4779e8f078c5efc9616f54..cb689c05d6636bec15f554424db2c55f67009fe9 100644 (file)
@@ -39,98 +39,97 @@ static struct printif *current_printif = &generic_printif;
    jobids are assigned when a job starts spooling. 
 */
 
-static pid_t local_pid;
-
-/* Mapping between printer names and queue id's in job id's. */
-struct printer_queueid_map {
-       struct printer_queueid_map *next, *prev;
-       char *printername;
-       uint32 queueid;
-};
-
-static struct printer_queueid_map *printer_queueid_map_head;
-static uint32 last_queueid;
-
-#define QUEUEID_BITS 12
-#define QUEUEID_MASK ((1<<(QUEUEID_BITS))-1)
-#define QUEUEID_TO_JOBID(queueid) (((queueid) & QUEUEID_MASK) << 20 )
+/***************************************************************************
+ Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
+ bit RPC jobids.... JRA.
+***************************************************************************/
 
-/****************************************************************************
- Create an association between a printer name and a queueid. Used to encode
- the printer queueid in jobid's.
- This could be converted to use an internal tdb if searching the list is
- too slow. JRA.
-****************************************************************************/
+static TDB_CONTEXT *rap_tdb;
+static uint16 next_rap_jobid;
 
-BOOL create_printer_queueid(const char *printername)
+uint16 pjobid_to_rap(int snum, uint32 jobid)
 {
-       struct printer_queueid_map *p;
+       uint16 rap_jobid;
+       TDB_DATA data, key;
+       char jinfo[8];
 
-       for (p = printer_queueid_map_head; p; p = p->next) {
-               if (strequal(p->printername, printername))
-                       return True;
+       if (!rap_tdb) {
+               /* Create the in-memory tdb. */
+               rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
+               if (!rap_tdb)
+                       return 0;
        }
 
-       p = (struct printer_queueid_map *)malloc(sizeof(*p));
-       if (!p) {
-               DEBUG(0,("create_printer_queueid: malloc fail !\n"));
-               return False;
-       }
-       ZERO_STRUCTP(p);
-       p->printername = strdup(printername);
-       if (!p->printername) {
-               DEBUG(0,("create_printer_queueid: malloc fail !\n"));
-               SAFE_FREE(p);
-               return False;
-       }
-       p->queueid = (++last_queueid);
-       if (p->queueid > QUEUEID_MASK) {
-               DEBUG(0,("create_printer_queueid: malloc fail !\n"));
-               SAFE_FREE(p->printername);
-               SAFE_FREE(p);
-               return False;
+       SIVAL(&jinfo,0,(int32)snum);
+       SIVAL(&jinfo,4,jobid);
+
+       key.dptr = (char *)&jinfo;
+       key.dsize = sizeof(jinfo);
+       data = tdb_fetch(rap_tdb, key);
+       if (data.dptr && data.dsize == sizeof(uint16)) {
+               memcpy(&rap_jobid, data.dptr, sizeof(uint16));
+               SAFE_FREE(data.dptr);
+               return rap_jobid;
        }
-       DLIST_ADD(printer_queueid_map_head, p);
-       return True;
+       /* Not found - create and store mapping. */
+       rap_jobid = ++next_rap_jobid;
+       if (rap_jobid == 0)
+               rap_jobid = ++next_rap_jobid;
+       data.dptr = (char *)&rap_jobid;
+       data.dsize = sizeof(rap_jobid);
+       tdb_store(rap_tdb, key, data, TDB_REPLACE);
+       tdb_store(rap_tdb, data, key, TDB_REPLACE);
+       return rap_jobid;
 }
 
-void set_register_printer_fn(void)
+BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
 {
-       extern BOOL (*register_printer_fn)(const char *);
-       register_printer_fn = create_printer_queueid;
-}
-
-/****************************************************************************
- Lookups.
-****************************************************************************/
+       TDB_DATA data, key;
+       char jinfo[8];
 
-static uint32 get_printer_queueid_byname(const char *printername)
-{
-       struct printer_queueid_map *p;
+       if (!rap_tdb)
+               return False;
 
-       for (p = printer_queueid_map_head; p; p = p->next) {
-               if (strequal(p->printername, printername))
-                       return p->queueid;
+       key.dptr = (char *)&rap_jobid;
+       key.dsize = sizeof(rap_jobid);
+       data = tdb_fetch(rap_tdb, key);
+       if (data.dptr && data.dsize == sizeof(jinfo)) {
+               *psnum = IVAL(&jinfo,0);
+               *pjobid = IVAL(&jinfo,4);
+               SAFE_FREE(data.dptr);
+               return True;
        }
-       return 0;
+       return False;
 }
 
-/****************************************************************************
- Lookups.
-****************************************************************************/
-
-static const char *get_printer_name_byjobid(uint32 jobid)
+static void rap_jobid_delete(int snum, uint32 jobid)
 {
-       struct printer_queueid_map *p;
-       uint32 queueid = (((jobid)>>20) & QUEUEID_MASK);
+       TDB_DATA key, data;
+       uint16 rap_jobid;
+       char jinfo[8];
 
-       for (p = printer_queueid_map_head; p; p = p->next) {
-               if (p->queueid == queueid)
-                       return p->printername;
-       }
-       return NULL;
+       if (!rap_tdb)
+               return;
+
+       SIVAL(&jinfo,0,(int32)snum);
+       SIVAL(&jinfo,4,jobid);
+
+       key.dptr = (char *)&jinfo;
+       key.dsize = sizeof(jinfo);
+       data = tdb_fetch(rap_tdb, key);
+       if (!data.dptr || (data.dsize != sizeof(uint16)))
+               return;
+
+       memcpy(&rap_jobid, data.dptr, sizeof(uint16));
+       SAFE_FREE(data.dptr);
+       data.dptr = (char *)&rap_jobid;
+       data.dsize = sizeof(rap_jobid);
+       tdb_delete(rap_tdb, key);
+       tdb_delete(rap_tdb, data);
 }
 
+static pid_t local_pid;
+
 static int get_queue_status(int, print_status_struct *);
 
 #define MAX_PRINT_DBS_OPEN 1
@@ -186,9 +185,14 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
                DLIST_ADD(print_db_head, p);
        }
 
-       pstrcpy(printdb_path, lock_path(printername));
+       pstrcpy(printdb_path, lock_path("printing/"));
+       pstrcat(printdb_path, printername);
        pstrcat(printdb_path, ".tdb");
+
+       become_root();
        p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+       unbecome_root();
+
        if (!p->tdb) {
                DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
                                        printdb_path ));
@@ -200,14 +204,6 @@ static struct tdb_print_db *get_print_db_byname(const char *printername)
        return p;
 }
 
-static struct tdb_print_db *get_print_db_byjobid( uint32 jobid)
-{
-       const char *printername = get_printer_name_byjobid(jobid);
-       if (!printername)
-               return NULL;
-       return get_print_db_byname(printername);
-}
-
 /****************************************************************************
  Initialise the printing backend. Called once at startup. 
  Does not survive a fork
@@ -215,20 +211,28 @@ static struct tdb_print_db *get_print_db_byjobid( uint32 jobid)
 
 BOOL print_backend_init(void)
 {
-       struct printer_queueid_map *p;
        char *sversion = "INFO/version";
+       pstring printing_path;
+       int services = lp_numservices();
+       int snum;
 
        if (local_pid == sys_getpid())
                return True;
 
        unlink(lock_path("printing.tdb"));
+       pstrcpy(printing_path,lock_path("printing"));
+       mkdir(printing_path,0755);
+
        local_pid = sys_getpid();
 
        /* handle a Samba upgrade */
 
-       for (p = printer_queueid_map_head; p; p = p->next) {
-               struct tdb_print_db *pdb = get_print_db_byname(p->printername);
+       for (snum = 0; snum < services; snum++) {
+               struct tdb_print_db *pdb;
+               if (!lp_print_ok(snum))
+                       continue;
 
+               pdb = get_print_db_byname(lp_const_servicename(snum));
                if (!pdb)
                        continue;
                tdb_lock_bystring(pdb->tdb, sversion);
@@ -286,11 +290,11 @@ static TDB_DATA print_key(uint32 jobid)
  Useful function to find a print job in the database.
 ****************************************************************************/
 
-static struct printjob *print_job_find(uint32 jobid)
+static struct printjob *print_job_find(int snum, uint32 jobid)
 {
        static struct printjob pjob;
        TDB_DATA ret;
-       struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
+       struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
 
        if (!pdb)
                return NULL;
@@ -334,11 +338,16 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
 
 uint32 sysjob_to_jobid(int unix_jobid)
 {
-       struct printer_queueid_map *p;
+       int services = lp_numservices();
+       int snum;
+
        sysjob_to_jobid_value = (uint32)-1;
 
-       for (p = printer_queueid_map_head; p; p = p->next) {
-               struct tdb_print_db *pdb = get_print_db_byname(p->printername);
+       for (snum = 0; snum < services; snum++) {
+               struct tdb_print_db *pdb;
+               if (!lp_print_ok(snum))
+                       continue;
+               pdb = get_print_db_byname(lp_const_servicename(snum));
                if (pdb)
                        tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
                if (sysjob_to_jobid_value != (uint32)-1)
@@ -385,14 +394,10 @@ static uint32 map_to_spoolss_status(uint32 lpq_status)
        return 0;
 }
 
-static void pjob_store_notify(uint32 jobid, struct printjob *old_data,
+static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
                              struct printjob *new_data)
 {
        BOOL new_job = False;
-       int snum = print_job_snum(jobid);
-
-       if (snum == -1)
-               return;
 
        if (!old_data)
                new_job = True;
@@ -427,11 +432,11 @@ static void pjob_store_notify(uint32 jobid, struct printjob *old_data,
  Store a job structure back to the database.
 ****************************************************************************/
 
-static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
+static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
 {
        TDB_DATA old_data, new_data;
        BOOL ret;
-       struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
+       struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
 
        if (!pdb)
                return False;
@@ -450,7 +455,7 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
 
        if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) {
                pjob_store_notify(
-                       jobid, (struct printjob *)old_data.dptr,
+                       snum, jobid, (struct printjob *)old_data.dptr,
                        (struct printjob *)new_data.dptr);
                free(old_data.dptr);
        }
@@ -462,12 +467,11 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob)
  Remove a job structure from the database.
 ****************************************************************************/
 
-static void pjob_delete(uint32 jobid)
+static void pjob_delete(int snum, uint32 jobid)
 {
-       int snum;
-       struct printjob *pjob = print_job_find(jobid);
+       struct printjob *pjob = print_job_find(snum, jobid);
        uint32 job_status = 0;
-       struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
+       struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
 
        if (!pdb)
                return;
@@ -486,7 +490,6 @@ static void pjob_delete(uint32 jobid)
            JOB_STATUS_DELETED for the port monitor to delete the job
            properly. */
        
-       snum = print_job_snum(jobid);
        job_status |= JOB_STATUS_DELETING;
        notify_job_status(snum, jobid, job_status);
        
@@ -496,6 +499,7 @@ static void pjob_delete(uint32 jobid)
        /* Remove from printing.tdb */
 
        tdb_delete(pdb->tdb, print_key(jobid));
+       rap_jobid_delete(snum, jobid);
 }
 
 /****************************************************************************
@@ -523,13 +527,12 @@ static uint32 print_parse_jobid(char *fname)
 
 static void print_unix_job(int snum, print_queue_struct *q)
 {
-       uint32 queueid = get_printer_queueid_byname(PRINTERNAME(snum));
-       uint32 jobid = (q->job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid);
+       uint32 jobid = q->job + UNIX_JOB_START;
        struct printjob pj, *old_pj;
 
        /* Preserve the timestamp on an existing unix print job */
 
-       old_pj = print_job_find(jobid);
+       old_pj = print_job_find(snum, jobid);
 
        ZERO_STRUCT(pj);
 
@@ -546,7 +549,7 @@ static void print_unix_job(int snum, print_queue_struct *q)
        fstrcpy(pj.user, q->fs_user);
        fstrcpy(pj.queuename, lp_const_servicename(snum));
 
-       pjob_store(jobid, &pj);
+       pjob_store(snum, jobid, &pj);
 }
 
 
@@ -561,7 +564,6 @@ struct traverse_struct {
 
 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
 {
-       uint32 queueid;
        struct traverse_struct *ts = (struct traverse_struct *)state;
        struct printjob pjob;
        uint32 jobid;
@@ -577,18 +579,16 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                return 0;
        }
 
-       queueid = get_printer_queueid_byname(pjob.queuename);
-
        if (!pjob.smbjob) {
                /* remove a unix job if it isn't in the system queue any more */
 
                for (i=0;i<ts->qcount;i++) {
-                       uint32 u_jobid = ((ts->queue[i].job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid));
+                       uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
                        if (jobid == u_jobid)
                                break;
                }
                if (i == ts->qcount)
-                       pjob_delete(jobid);
+                       pjob_delete(ts->snum, jobid);
                else
                        ts->total_jobs++;
                return 0;
@@ -600,14 +600,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                    exist then kill it. This cleans up after smbd
                    deaths */
                if (!process_exists(pjob.pid))
-                       pjob_delete(jobid);
+                       pjob_delete(ts->snum, jobid);
                else
                        ts->total_jobs++;
                return 0;
        }
 
        for (i=0;i<ts->qcount;i++) {
-               uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file) | QUEUEID_TO_JOBID(queueid);
+               uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
                if (jobid == curr_jobid)
                        break;
        }
@@ -627,7 +627,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                   submitted less than lp_lpqcachetime() seconds ago. */
 
                if ((cur_t - pjob.starttime) > lp_lpqcachetime())
-                       pjob_delete(jobid);
+                       pjob_delete(ts->snum, jobid);
                else
                        ts->total_jobs++;
        }
@@ -688,7 +688,7 @@ static pid_t get_updating_pid(fstring printer_name)
  in the tdb.
 ****************************************************************************/
 
-static void set_updating_pid(fstring printer_name, BOOL delete)
+static void set_updating_pid(const fstring printer_name, BOOL delete)
 {
        fstring keystr;
        TDB_DATA key;
@@ -813,7 +813,7 @@ static void print_queue_update(int snum)
                }
 
                /* we have an active SMB print job - update its status */
-               pjob = print_job_find(jobid);
+               pjob = print_job_find(snum, jobid);
                if (!pjob) {
                        /* err, somethings wrong. Probably smbd was restarted
                           with jobs in the queue. All we can do is treat them
@@ -825,7 +825,7 @@ static void print_queue_update(int snum)
                pjob->sysjob = queue[i].job;
                pjob->status = queue[i].status;
 
-               pjob_store(jobid, pjob);
+               pjob_store(snum, jobid, pjob);
        }
 
        /* now delete any queued entries that don't appear in the
@@ -871,36 +871,21 @@ static void print_queue_update(int snum)
  Check if a jobid is valid. It is valid if it exists in the database.
 ****************************************************************************/
 
-BOOL print_job_exists(uint32 jobid)
+BOOL print_job_exists(int snum, uint32 jobid)
 {
-       struct tdb_print_db *pdb = get_print_db_byjobid(jobid);
+       struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
        if (!pdb)
                return False;
        return tdb_exists(pdb->tdb, print_key(jobid));
 }
 
-/****************************************************************************
- Work out which service a jobid is for.
- Note that we have to look up by queue name to ensure that it works for 
- other than the process that started the job.
-****************************************************************************/
-
-int print_job_snum(uint32 jobid)
-{
-       struct printjob *pjob = print_job_find(jobid);
-       if (!pjob)
-               return -1;
-
-       return find_service(pjob->queuename);
-}
-
 /****************************************************************************
  Give the fd used for a jobid.
 ****************************************************************************/
 
-int print_job_fd(uint32 jobid)
+int print_job_fd(int snum, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(jobid);
+       struct printjob *pjob = print_job_find(snum, jobid);
        if (!pjob)
                return -1;
        /* don't allow another process to get this info - it is meaningless */
@@ -915,9 +900,9 @@ int print_job_fd(uint32 jobid)
  has not been spooled.
 ****************************************************************************/
 
-char *print_job_fname(uint32 jobid)
+char *print_job_fname(int snum, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(jobid);
+       struct printjob *pjob = print_job_find(snum, jobid);
        if (!pjob || pjob->spooled || pjob->pid != local_pid)
                return NULL;
        return pjob->filename;
@@ -927,7 +912,7 @@ char *print_job_fname(uint32 jobid)
  Set the place in the queue for a job.
 ****************************************************************************/
 
-BOOL print_job_set_place(uint32 jobid, int place)
+BOOL print_job_set_place(int snum, uint32 jobid, int place)
 {
        DEBUG(2,("print_job_set_place not implemented yet\n"));
        return False;
@@ -937,24 +922,24 @@ BOOL print_job_set_place(uint32 jobid, int place)
  Set the name of a job. Only possible for owner.
 ****************************************************************************/
 
-BOOL print_job_set_name(uint32 jobid, char *name)
+BOOL print_job_set_name(int snum, uint32 jobid, char *name)
 {
-       struct printjob *pjob = print_job_find(jobid);
+       struct printjob *pjob = print_job_find(snum, jobid);
        if (!pjob || pjob->pid != local_pid)
                return False;
 
        fstrcpy(pjob->jobname, name);
-       return pjob_store(jobid, pjob);
+       return pjob_store(snum, jobid, pjob);
 }
 
 /****************************************************************************
  Delete a print job - don't update queue.
 ****************************************************************************/
 
-static BOOL print_job_delete1(uint32 jobid)
+static BOOL print_job_delete1(int snum, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(jobid);
-       int snum, result = 0;
+       struct printjob *pjob = print_job_find(snum, jobid);
+       int result = 0;
 
        if (!pjob)
                return False;
@@ -966,12 +951,6 @@ static BOOL print_job_delete1(uint32 jobid)
        if (pjob->status == LPQ_DELETING)
                return True;
 
-       snum = print_job_snum(jobid);
-       if (snum == -1) {
-               DEBUG(5,("print_job_delete1: unknown service number for jobid %u\n", (unsigned int)jobid));
-               return False;
-       }
-
        /* Hrm - we need to be able to cope with deleting a job before it
           has reached the spooler. */
 
@@ -982,7 +961,7 @@ static BOOL print_job_delete1(uint32 jobid)
        /* Set the tdb entry to be deleting. */
 
        pjob->status = LPQ_DELETING;
-       pjob_store(jobid, pjob);
+       pjob_store(snum, jobid, pjob);
 
        if (pjob->spooled && pjob->sysjob != -1)
                result = (*(current_printif->job_delete))(snum, pjob);
@@ -991,7 +970,7 @@ static BOOL print_job_delete1(uint32 jobid)
           been spooled. */
 
        if (result == 0)
-               pjob_delete(jobid);
+               pjob_delete(snum, jobid);
 
        return (result == 0);
 }
@@ -1000,9 +979,9 @@ static BOOL print_job_delete1(uint32 jobid)
  Return true if the current user owns the print job.
 ****************************************************************************/
 
-static BOOL is_owner(struct current_user *user, uint32 jobid)
+static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(jobid);
+       struct printjob *pjob = print_job_find(snum, jobid);
        user_struct *vuser;
 
        if (!pjob || !user)
@@ -1019,17 +998,11 @@ static BOOL is_owner(struct current_user *user, uint32 jobid)
  Delete a print job.
 ****************************************************************************/
 
-BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode)
+BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
 {
-       int snum = print_job_snum(jobid);
        BOOL owner;
 
-       if (snum == -1) {
-               DEBUG(5,("print_job_delete: unknown service number for jobid %d\n", jobid));
-               return False;
-       }
-
-       owner = is_owner(user, jobid);
+       owner = is_owner(user, snum, jobid);
        
        /* Check access against security descriptor or whether the user
           owns their job. */
@@ -1041,7 +1014,7 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode)
                return False;
        }
 
-       if (!print_job_delete1(jobid)) 
+       if (!print_job_delete1(snum, jobid)) 
                return False;
 
        /* force update the database and say the delete failed if the
@@ -1049,17 +1022,17 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode)
 
        print_queue_update(snum);
 
-       return !print_job_exists(jobid);
+       return !print_job_exists(snum, jobid);
 }
 
 /****************************************************************************
  Pause a job.
 ****************************************************************************/
 
-BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode)
+BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
 {
-       struct printjob *pjob = print_job_find(jobid);
-       int snum, ret = -1;
+       struct printjob *pjob = print_job_find(snum, jobid);
+       int ret = -1;
        
        if (!pjob || !user) 
                return False;
@@ -1067,13 +1040,7 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode)
        if (!pjob->spooled || pjob->sysjob == -1) 
                return False;
 
-       snum = print_job_snum(jobid);
-       if (snum == -1) {
-               DEBUG(5,("print_job_pause: unknown service number for jobid %u\n", (unsigned int)jobid));
-               return False;
-       }
-
-       if (!is_owner(user, jobid) &&
+       if (!is_owner(user, snum, jobid) &&
            !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
                DEBUG(3, ("pause denied by security descriptor\n"));
                *errcode = WERR_ACCESS_DENIED;
@@ -1104,10 +1071,10 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode)
  Resume a job.
 ****************************************************************************/
 
-BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode)
+BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
 {
-       struct printjob *pjob = print_job_find(jobid);
-       int snum, ret;
+       struct printjob *pjob = print_job_find(snum, jobid);
+       int ret;
        
        if (!pjob || !user)
                return False;
@@ -1115,13 +1082,7 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode)
        if (!pjob->spooled || pjob->sysjob == -1)
                return False;
 
-       snum = print_job_snum(jobid);
-       if (snum == -1) {
-               DEBUG(5,("print_job_resume: unknown service number for jobid %u\n", (unsigned int)jobid));
-               return False;
-       }
-
-       if (!is_owner(user, jobid) &&
+       if (!is_owner(user, snum, jobid) &&
            !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
                DEBUG(3, ("resume denied by security descriptor\n"));
                *errcode = WERR_ACCESS_DENIED;
@@ -1149,10 +1110,10 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode)
  Write to a print file.
 ****************************************************************************/
 
-int print_job_write(uint32 jobid, const char *buf, int size)
+int print_job_write(int snum, uint32 jobid, const char *buf, int size)
 {
        int return_code;
-       struct printjob *pjob = print_job_find(jobid);
+       struct printjob *pjob = print_job_find(snum, jobid);
 
        if (!pjob)
                return -1;
@@ -1163,7 +1124,7 @@ int print_job_write(uint32 jobid, const char *buf, int size)
        return_code = write(pjob->fd, buf, size);
        if (return_code>0) {
                pjob->size += size;
-               pjob_store(jobid, pjob);
+               pjob_store(snum, jobid, pjob);
        }
        return return_code;
 }
@@ -1260,18 +1221,24 @@ int print_queue_length(int snum, print_status_struct *pstatus)
 
 static int get_total_jobs(void)
 {
-       int total_jobs;
-       struct printer_queueid_map *p;
+       int total_jobs = 0;
+       int snum;
+       int services = lp_numservices();
 
-       for (p = printer_queueid_map_head; p; p = p->next) {
+       for (snum = 0; snum < services; snum++) {
+               struct tdb_print_db *pdb;
                int jobs;
-               struct tdb_print_db *pdb = get_print_db_byname(p->printername);
+
+               if (!lp_print_ok(snum))
+                       continue;
+
+               pdb = get_print_db_byname(lp_const_servicename(snum));
                if (!pdb)
                        continue;
 
                /* make sure the database is up to date */
-               if (print_cache_expired(lp_servicenumber(p->printername)))
-                       print_queue_update(lp_servicenumber(p->printername));
+               if (print_cache_expired(snum))
+                       print_queue_update(snum);
 
                jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
                if (jobs > 0)
@@ -1294,7 +1261,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
        int njobs = 0;
        const char *printername = lp_const_servicename(snum);
        struct tdb_print_db *pdb = get_print_db_byname(printername);
-       uint32 queueid = queueid = get_printer_queueid_byname(printername);
 
        errno = 0;
 
@@ -1376,10 +1342,10 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
                next_jobid = 1;
 
        for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
-               if (!print_job_exists(jobid | QUEUEID_TO_JOBID(queueid)))
+               if (!print_job_exists(snum, jobid))
                        break;
        }
-       if (jobid == next_jobid || !pjob_store(jobid | QUEUEID_TO_JOBID(queueid), &pjob)) {
+       if (jobid == next_jobid || !pjob_store(snum, jobid, &pjob)) {
                DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n",
                                jobid, next_jobid ));
                jobid = -1;
@@ -1392,9 +1358,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname)
                goto fail;
        }
 
-       /* Ensure the queuid is added to the jobid. */
-       jobid |= QUEUEID_TO_JOBID(queueid);
-
        /* we have a job entry - now create the spool file */
        slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
                 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
@@ -1413,7 +1376,7 @@ to open spool file %s.\n", pjob.filename));
                goto fail;
        }
 
-       pjob_store(jobid, &pjob);
+       pjob_store(snum, jobid, &pjob);
 
        tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
 
@@ -1425,14 +1388,14 @@ to open spool file %s.\n", pjob.filename));
         * tim@fsg.com 09/06/94
         */
        if (lp_postscript(snum)) {
-               print_job_write(jobid, "%!\n",3);
+               print_job_write(snum, jobid, "%!\n",3);
        }
 
        return jobid;
 
  fail:
        if (jobid != -1)
-               pjob_delete(jobid);
+               pjob_delete(snum, jobid);
 
        tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
 
@@ -1444,9 +1407,9 @@ to open spool file %s.\n", pjob.filename));
  Update the number of pages spooled to jobid
 ****************************************************************************/
 
-void print_job_endpage(uint32 jobid)
+void print_job_endpage(int snum, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(jobid);
+       struct printjob *pjob = print_job_find(snum, jobid);
        if (!pjob)
                return;
        /* don't allow another process to get this info - it is meaningless */
@@ -1454,7 +1417,7 @@ void print_job_endpage(uint32 jobid)
                return;
 
        pjob->page_count++;
-       pjob_store(jobid, pjob);
+       pjob_store(snum, jobid, pjob);
 }
 
 /****************************************************************************
@@ -1463,10 +1426,10 @@ void print_job_endpage(uint32 jobid)
  error.
 ****************************************************************************/
 
-BOOL print_job_end(uint32 jobid, BOOL normal_close)
+BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
 {
-       struct printjob *pjob = print_job_find(jobid);
-       int snum, ret;
+       struct printjob *pjob = print_job_find(snum, jobid);
+       int ret;
        SMB_STRUCT_STAT sbuf;
 
        if (!pjob)
@@ -1475,12 +1438,6 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close)
        if (pjob->spooled || pjob->pid != local_pid)
                return False;
 
-       snum = print_job_snum(jobid);
-       if (snum == -1) {
-               DEBUG(5,("print_job_end: unknown service number for jobid %u\n", (unsigned int)jobid));
-               return False;
-       }
-
        if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
                pjob->size = sbuf.st_size;
                close(pjob->fd);
@@ -1505,7 +1462,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close)
                DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
                        pjob->filename, pjob->size ? "deleted" : "zero length" ));
                unlink(pjob->filename);
-               pjob_delete(jobid);
+               pjob_delete(snum, jobid);
                return True;
        }
 
@@ -1518,7 +1475,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close)
        
        pjob->spooled = True;
        pjob->status = LPQ_QUEUED;
-       pjob_store(jobid, pjob);
+       pjob_store(snum, jobid, pjob);
        
        /* make sure the database is up to date */
        if (print_cache_expired(snum))
@@ -1531,7 +1488,7 @@ fail:
        /* The print job was not succesfully started. Cleanup */
        /* Still need to add proper error return propagation! 010122:JRR */
        unlink(pjob->filename);
-       pjob_delete(jobid);
+       pjob_delete(snum, jobid);
        return False;
 }
 
@@ -1793,10 +1750,10 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
        njobs = print_queue_status(snum, &queue, &status);
 
        for (i=0;i<njobs;i++) {
-               BOOL owner = is_owner(user, queue[i].job);
+               BOOL owner = is_owner(user, snum, queue[i].job);
 
                if (owner || can_job_admin) {
-                       print_job_delete1(queue[i].job);
+                       print_job_delete1(snum, queue[i].job);
                }
        }
 
index a6aecb796726a499b40918a3969d40f6971cab06..375bbd31d74dd23bd49da522b1dcaea92a1f67ed 100644 (file)
@@ -3,8 +3,9 @@
  *  RPC Pipe client / server routines
  *  Copyright (C) Andrew Tridgell              1992-1997,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- *  Copyright (C) Paul Ashton                       1997.
- *  Copyright (C) Andrew Bartlett                   2002.
+ *  Copyright (C) Paul Ashton                       1997,
+ *  Copyright (C) Andrew Bartlett                   2002,
+ *  Copyright (C) Jim McDonough                     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
@@ -2117,3 +2118,121 @@ BOOL policy_handle_is_valid(const POLICY_HND *hnd)
        ZERO_STRUCT(zero_pol);
        return ((memcmp(&zero_pol, hnd, sizeof(POLICY_HND)) == 0) ? False : True );
 }
+
+/*******************************************************************
+ Reads or writes an LSA_DNS_DOM_INFO structure.
+********************************************************************/
+
+BOOL lsa_io_dns_dom_info(char *desc, LSA_DNS_DOM_INFO *info,
+                        prs_struct *ps, int depth)
+{
+       prs_debug(ps, depth, desc, "lsa_io_dns_dom_info");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       if(!smb_io_unihdr("nb_name", &info->hdr_nb_dom_name, ps, depth))
+               return False;
+       if(!smb_io_unihdr("dns_name", &info->hdr_dns_dom_name, ps, depth))
+               return False;
+       if(!smb_io_unihdr("forest", &info->hdr_forest_name, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+       if (!prs_uint8s(False, "dom_guid", ps, depth, info->dom_guid.info, GUID_SIZE))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("dom_sid", ps, depth, &info->ptr_dom_sid))
+               return False;
+
+       if(!smb_io_unistr2("nb_name", &info->uni_nb_dom_name,
+                          info->hdr_nb_dom_name.buffer, ps, depth))
+               return False;
+       if(!smb_io_unistr2("dns_name", &info->uni_dns_dom_name, 
+                          info->hdr_dns_dom_name.buffer, ps, depth))
+               return False;
+       if(!smb_io_unistr2("forest", &info->uni_forest_name, 
+                          info->hdr_forest_name.buffer, ps, depth))
+               return False;
+
+       if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth))
+               return False;
+
+       return True;
+       
+}
+
+/*******************************************************************
+ Inits an LSA_Q_QUERY_INFO2 structure.
+********************************************************************/
+
+void init_q_query2(LSA_Q_QUERY_INFO2 *q_q, POLICY_HND *hnd, uint16 info_class)
+{
+       DEBUG(5, ("init_q_query2\n"));
+
+       memcpy(&q_q->pol, hnd, sizeof(q_q->pol));
+
+       q_q->info_class = info_class;
+}
+
+/*******************************************************************
+ Reads or writes an LSA_Q_QUERY_DNSDOMINFO structure.
+********************************************************************/
+
+BOOL lsa_io_q_query_info2(char *desc, LSA_Q_QUERY_INFO2 *q_c,
+                         prs_struct *ps, int depth)
+{
+       prs_debug(ps, depth, desc, "lsa_io_q_query_info2");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       if(!smb_io_pol_hnd("pol", &q_c->pol, ps, depth))
+               return False;
+       
+       if(!prs_uint16("info_class", ps, depth, &q_c->info_class))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ Reads or writes an LSA_R_QUERY_DNSDOMINFO structure.
+********************************************************************/
+
+BOOL lsa_io_r_query_info2(char *desc, LSA_R_QUERY_INFO2 *r_c,
+                         prs_struct *ps, int depth)
+{
+       prs_debug(ps, depth, desc, "lsa_io_r_query_info2");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr", ps, depth, &r_c->ptr))
+               return False;
+       if(!prs_uint16("info_class", ps, depth, &r_c->info_class))
+               return False;
+       switch(r_c->info_class) {
+       case 0x000c:
+               if (!lsa_io_dns_dom_info("info12", &r_c->info.dns_dom_info,
+                                        ps, depth))
+                       return False;
+               break;
+       default:
+               DEBUG(0,("lsa_io_r_query_info2: unknown info class %d\n",
+                        r_c->info_class));
+               return False;
+       }
+
+       if(!prs_align(ps))
+               return False;
+       if(!prs_ntstatus("status", ps, depth, &r_c->status))
+               return False;
+
+       return True;
+}
index 46fdce63ff4233505a8014bae13ef8be04032356..da49a6531d057d715e1bb5fd4822c95c952269d5 100644 (file)
@@ -1335,7 +1335,7 @@ void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr,
 ********************************************************************/
 
 BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, 
-                             int depth, uint16 validation_level)
+                      int depth, uint16 validation_level)
 {
        int i;
 
index 2ab8c7246e19184ce0e9226edded4010d77e175f..4de6b88e9ccae430cc5752c620e328086cde7a14 100644 (file)
@@ -893,9 +893,11 @@ BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *
                return False;
 
        if (UNMARSHALLING(ps)) {
-               str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
-               if (str->buffer == NULL)
-                       return False;
+               if ( str->buf_len ) {
+                       str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len);
+                       if ( str->buffer == NULL )
+                               return False;
+               }
        }
 
        p = (char *)str->buffer;
index 1ebc1532f3153b17ceaae923ad3891aaf59fcffe..365ad2dc70be13817448b51498cddd6e34826559 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  *  Unix SMB/CIFS implementation.
  *  RPC Pipe client / server routines
  *  Copyright (C) Andrew Tridgell              1992-1997,
@@ -6,6 +6,7 @@
  *  Copyright (C) Paul Ashton                       1997.
  *  Copyright (C) Marc Jacobsen                     1999.
  *  Copyright (C) Simo Sorce                        2000.
+ *  Copyright (C) Gerald Carter                     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
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
 
+/*******************************************************************
+ Fill in a BUFFER2 for the data given a REGISTRY_VALUE
+ *******************************************************************/
+
+static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val )
+{
+       UNISTR2         unistr;
+       uint32          real_size = 0;
+       char            *string;
+       char            *list = NULL;
+       char            *list2 = NULL;
+       
+       if ( !buf2 || !val )
+               return 0;
+               
+       real_size = val->size;
+               
+       switch (val->type )
+       {
+               case REG_SZ:
+                       string = (char*)val->data_p;
+                       DEBUG(10,("reg_init_buffer2: REG_SZ string => [%s]\n", string));
+                       
+                       init_unistr2( &unistr, (char*)val->data_p, strlen((char*)val->data_p)+1 );
+                       init_buffer2( buf2, (char*)unistr.buffer, unistr.uni_str_len*2 );
+                       real_size = unistr.uni_str_len*2;
+                       break;
+                       
+               case REG_MULTI_SZ:
+                       string = (char*)val->data_p;
+                       real_size = 0;
+                       while ( string && *string )
+                       {
+                               DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ string => [%s], size => [%d]\n", string, real_size ));
+                               
+                               init_unistr2( &unistr, string, strlen(string)+1 );
+                               
+                               list2 = Realloc( list, real_size + unistr.uni_str_len*2 );
+                               if ( !list2 )
+                                       break;
+                               list = list2;
+                               
+                               memcpy( list+real_size, unistr.buffer, unistr.uni_str_len*2 );
+                               
+                               real_size += unistr.uni_str_len*2;
+                               
+                               string += strlen(string)+1;
+                       }
+                       
+                       list2 = Realloc( list, real_size + 2 );
+                       if ( !list2 )
+                               break;
+                       list = list2;
+                       list[real_size++] = 0x0;
+                       list[real_size++] = 0x0;
+                       
+                       init_buffer2( buf2, (char*)list, real_size );
+                       
+                       DEBUG(10,("reg_init_buffer2: REG_MULTI_SZ size => [%d]\n", real_size ));
+                       
+                       break;
+                       
+               case REG_BINARY:
+                       DEBUG(10,("reg_init_buffer2: REG_BINARY size => [%d]\n", val->size ));
+                       
+                       init_buffer2( buf2, val->data_p, val->size );
+                       break;
+                       
+               case REG_DWORD: 
+                       DEBUG(10,("reg_init_buffer2: REG_DWORD value => [%d]\n", *(uint32*)val->data_p));
+                       init_buffer2( buf2, val->data_p, val->size );
+                       break;
+                       
+               default:
+                       DEBUG(0,("reg_init_buffer2: Unsupported registry data type [%d]\n", val->type));
+                       break;
+       }
+       
+       SAFE_FREE( list );
+
+       return real_size;
+}
+
 /*******************************************************************
  Inits a structure.
 ********************************************************************/
@@ -165,6 +249,8 @@ BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
 }
 
 
+
+
 /*******************************************************************
  Inits a structure.
 ********************************************************************/
@@ -583,7 +669,7 @@ BOOL reg_io_r_query_key(char *desc,  REG_R_QUERY_KEY *r_r, prs_struct *ps, int d
                return False;
        if(!smb_io_time("mod_time     ", &r_r->mod_time, ps, depth))
                return False;
-       
+
        if(!prs_ntstatus("status", ps, depth, &r_r->status))
                return False;
 
@@ -599,6 +685,7 @@ void init_reg_q_unknown_1a(REG_Q_UNKNOWN_1A *q_o, POLICY_HND *hnd)
        memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
 }
 
+
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
@@ -613,7 +700,7 @@ BOOL reg_io_q_unknown_1a(char *desc,  REG_Q_UNKNOWN_1A *r_q, prs_struct *ps, int
 
        if(!prs_align(ps))
                return False;
-       
+
        if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
                return False;
 
@@ -634,7 +721,7 @@ BOOL reg_io_r_unknown_1a(char *desc,  REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int
 
        if(!prs_align(ps))
                return False;
-       
+
        if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
                return False;
        if(!prs_ntstatus("status" , ps, depth, &r_r->status))
@@ -643,6 +730,57 @@ BOOL reg_io_r_unknown_1a(char *desc,  REG_R_UNKNOWN_1A *r_r, prs_struct *ps, int
        return True;
 }
 
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL reg_io_q_save_key(char *desc,  REG_Q_SAVE_KEY *r_q, prs_struct *ps, int depth)
+{
+       if (r_q == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "reg_io_q_save_key");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
+               return False;
+
+       if(!smb_io_unihdr ("hdr_file", &r_q->hdr_file, ps, depth))
+               return False;
+       if(!smb_io_unistr2("uni_file", &r_q->uni_file, r_q->hdr_file.buffer, ps, depth))
+               return False;
+
+       if(!prs_uint32("unknown", ps, depth, &r_q->unknown))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL reg_io_r_save_key(char *desc,  REG_R_SAVE_KEY *r_r, prs_struct *ps, int depth)
+{
+       if (r_r == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "reg_io_r_save_key");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       
+       if(!prs_ntstatus("status" , ps, depth, &r_r->status))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
  Inits a structure.
 ********************************************************************/
@@ -1023,6 +1161,51 @@ BOOL reg_io_q_info(char *desc,  REG_Q_INFO *r_q, prs_struct *ps, int depth)
        return True;
 }
 
+/*******************************************************************
+ Inits a structure.
+ New version to replace older init_reg_r_info()
+********************************************************************/
+
+BOOL new_init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
+                    REGISTRY_VALUE *val, NTSTATUS status)
+{
+       uint32          buf_len = 0;
+       BUFFER2         buf2;
+               
+       if(r_r == NULL)
+               return False;
+       
+       if ( !val )
+               return False;
+  
+       r_r->ptr_type = 1;
+       r_r->type = val->type;
+
+       /* if include_keyval is not set, don't send the key value, just
+          the buflen data. probably used by NT5 to allocate buffer space - SK */
+
+       if ( include_keyval ) {
+               r_r->ptr_uni_val = 1;
+               buf_len = reg_init_buffer2( &r_r->uni_val, val );
+       
+       }
+       else {
+               /* dummy buffer used so we can get the size */
+               r_r->ptr_uni_val = 0;
+               buf_len = reg_init_buffer2( &buf2, val );
+       }
+
+       r_r->ptr_max_len = 1;
+       r_r->buf_max_len = buf_len;
+
+       r_r->ptr_len = 1;
+       r_r->buf_len = buf_len;
+
+       r_r->status = status;
+
+       return True;
+}
+
 /*******************************************************************
  Inits a structure.
 ********************************************************************/
@@ -1030,28 +1213,27 @@ BOOL reg_io_q_info(char *desc,  REG_Q_INFO *r_q, prs_struct *ps, int depth)
 BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
                     BUFFER2* buf, uint32 type, NTSTATUS status)
 {
-  if(r_r == NULL)
-    return False;
-
+       if(r_r == NULL)
+               return False;
   
-  r_r->ptr_type = 1;
-  r_r->type = type;
+       r_r->ptr_type = 1;
+       r_r->type = type;
 
-  /* if include_keyval is not set, don't send the key value, just
-     the buflen data. probably used by NT5 to allocate buffer space - SK */
-  r_r->ptr_uni_val = include_keyval ? 1:0;
-  r_r->uni_val = buf;
+       /* if include_keyval is not set, don't send the key value, just
+          the buflen data. probably used by NT5 to allocate buffer space - SK */
 
-  r_r->ptr_max_len = 1;
-  r_r->buf_max_len = r_r->uni_val->buf_max_len;
+       r_r->ptr_uni_val = include_keyval ? 1:0;
+       r_r->uni_val = *buf;
 
-  r_r->ptr_len = 1;
-  r_r->buf_len = r_r->uni_val->buf_len;
+       r_r->ptr_max_len = 1;
+       r_r->buf_max_len = r_r->uni_val.buf_max_len;
 
-  r_r->status = status;
+       r_r->ptr_len = 1;
+       r_r->buf_len = r_r->uni_val.buf_len;
 
-  return True;
-  
+       r_r->status = status;
+
+       return True;
 }
 
 /*******************************************************************
@@ -1081,7 +1263,7 @@ BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
                return False;
 
        if(r_r->ptr_uni_val != 0) {
-               if(!smb_io_buffer2("uni_val", r_r->uni_val, r_r->ptr_uni_val, ps, depth))
+               if(!smb_io_buffer2("uni_val", &r_r->uni_val, r_r->ptr_uni_val, ps, depth))
                        return False;
        }
 
@@ -1138,6 +1320,46 @@ void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
        q_i->len_value2 = 0;
 }
 
+/*******************************************************************
+makes a structure.
+********************************************************************/
+
+void init_reg_r_enum_val(REG_R_ENUM_VALUE *r_u, REGISTRY_VALUE *val )
+{
+       uint32 real_size;
+       
+       DEBUG(8,("init_reg_r_enum_val: Enter\n"));
+       
+       ZERO_STRUCTP(r_u);
+
+       /* value name */
+
+       DEBUG(10,("init_reg_r_enum_val: Valuename => [%s]\n", val->valuename));
+       
+       init_uni_hdr( &r_u->hdr_name, strlen(val->valuename)+1 );
+       init_unistr2( &r_u->uni_name, val->valuename, strlen(val->valuename)+1 );
+               
+       /* type */
+       
+       r_u->ptr_type = 1;
+       r_u->type = val->type;
+
+       /* REG_SZ & REG_MULTI_SZ must be converted to UNICODE */
+       
+       r_u->ptr_value = 1;
+       real_size = reg_init_buffer2( &r_u->buf_value, val );
+       
+       /* lengths */
+
+       r_u->ptr1 = 1;
+       r_u->len_value1 = real_size;
+       
+       r_u->ptr2 = 1;
+       r_u->len_value2 = real_size;
+               
+       DEBUG(8,("init_reg_r_enum_val: Exit\n"));
+}
+
 /*******************************************************************
 reads or writes a structure.
 ********************************************************************/
@@ -1158,6 +1380,7 @@ BOOL reg_io_q_enum_val(char *desc,  REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int d
        
        if(!prs_uint32("val_index", ps, depth, &q_q->val_index))
                return False;
+               
        if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
                return False;
        if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
@@ -1228,7 +1451,7 @@ BOOL reg_io_r_enum_val(char *desc,  REG_R_ENUM_VALUE *r_q, prs_struct *ps, int d
 
        if(!prs_uint32("ptr_value", ps, depth, &r_q->ptr_value))
                return False;
-       if(!smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth))
+       if(!smb_io_buffer2("buf_value", &r_q->buf_value, r_q->ptr_value, ps, depth))
                return False;
        if(!prs_align(ps))
                return False;
@@ -1531,7 +1754,7 @@ BOOL reg_io_q_open_entry(char *desc,  REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int
        
        if(!prs_uint32("unknown_0        ", ps, depth, &r_q->unknown_0))
                return False;
-       if(!prs_uint32("asccess_desired  ", ps, depth, &r_q->access_desired))
+       if(!prs_uint32("access_desired  ", ps, depth, &r_q->access_desired))
                return False;
 
        return True;
index c16232204cd24085a1d56c262691c640aa156459..1137993bb6070161e36de849646bc0548cbabb66 100644 (file)
@@ -5,8 +5,10 @@
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
  *  Copyright (C) Paul Ashton                  1997-2000,
  *  Copyright (C) Elrond                            2000,
- *  Copyright (C) Jeremy Allison                    2001
- *  Copyright (C) Jean François Micouleau      1998-2001.
+ *  Copyright (C) Jeremy Allison                    2001,
+ *  Copyright (C) Jean François Micouleau      1998-2001,
+ *  Copyright (C) Anthony Liguori                   2002,
+ *  Copyright (C) Jim McDonough                     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
@@ -5067,7 +5069,7 @@ BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER * r_u,
        if(!smb_io_pol_hnd("user_pol", &r_u->user_pol, ps, depth))
                return False;
 
-       if(!prs_uint32("unknown_0", ps, depth, &r_u->unknown_0))
+       if(!prs_uint32("access_granted", ps, depth, &r_u->access_granted))
                return False;
        if(!prs_uint32("user_rid ", ps, depth, &r_u->user_rid))
                return False;
@@ -5945,7 +5947,7 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, SAM_ACCOUNT *pw, DOM_SID *
        const char*             user_name = pdb_get_username(pw);
        const char*             full_name = pdb_get_fullname(pw);
        const char*             home_dir  = pdb_get_homedir(pw);
-       const char*             dir_drive = pdb_get_dirdrive(pw);
+       const char*             dir_drive = pdb_get_dir_drive(pw);
        const char*             logon_script = pdb_get_logon_script(pw);
        const char*             profile_path = pdb_get_profile_path(pw);
        const char*             description = pdb_get_acct_desc(pw);
@@ -6716,6 +6718,84 @@ BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT * r_u,
        return True;
 }
 
+/*******************************************************************
+inits a SAMR_Q_CONNECT4 structure.
+********************************************************************/
+
+void init_samr_q_connect4(SAMR_Q_CONNECT4 * q_u,
+                         char *srv_name, uint32 access_mask)
+{
+       int len_srv_name = strlen(srv_name);
+
+       DEBUG(5, ("init_samr_q_connect\n"));
+
+       /* make PDC server name \\server */
+       q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0;
+       init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name + 1);
+
+       /* Only value we've seen, possibly an address type ? */
+       q_u->unk_0 = 2;
+
+       /* example values: 0x0000 0002 */
+       q_u->access_mask = access_mask;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_q_connect4(char *desc, SAMR_Q_CONNECT4 * q_u,
+                       prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_q_connect4");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("unk_0", ps, depth, &q_u->unk_0))
+               return False;
+       if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_r_connect4(char *desc, SAMR_R_CONNECT4 * r_u,
+                       prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_r_connect4");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
+               return False;
+
+       if(!prs_ntstatus("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
 inits a SAMR_Q_CONNECT_ANON structure.
 ********************************************************************/
index b10a5c4377158414e42d6879b798125019720163..3a7f4b57ae61c04c8f27f8de88d8a0444a87bb00 100644 (file)
@@ -322,7 +322,7 @@ reads or writes an NOTIFY INFO DATA structure.
 
 static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
 {
-       uint32 useless_ptr=0xADDE0FF0;
+       uint32 useless_ptr=0x0FF0ADDE;
 
        prs_debug(ps, depth, desc, "smb_io_notify_info_data");
        depth++;
@@ -378,6 +378,14 @@ static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs
 
                break;
 
+       case NOTIFY_SECDESC:
+               if( !prs_uint32( "sd size", ps, depth, &data->notify_data.sd.size ) )
+                       return False;
+               if( !prs_uint32( "pointer", ps, depth, &useless_ptr ) )
+                       return False;
+               
+               break;
+
        default:
                DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data\n",
                          data->enc_type));
@@ -451,6 +459,13 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
 
                break;
 
+       case NOTIFY_SECDESC:    
+               if( !prs_uint32("secdesc size ", ps, depth, &data->notify_data.sd.size ) )
+                       return False;
+               if ( !sec_io_desc( "sec_desc", &data->notify_data.sd.desc, ps, depth ) )
+                       return False;
+               break;
+
        default:
                DEBUG(3, ("invalid enc_type %d for smb_io_notify_info_data_strings\n",
                          data->enc_type));
@@ -675,9 +690,11 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo
           Let the size determine that */
           
        switch (devmode->specversion) {
+               /* list of observed spec version's */
                case 0x0320:
                case 0x0400:
                case 0x0401:
+               case 0x040d:
                        break;
                        
                default:
@@ -5183,7 +5200,7 @@ static BOOL uniarray_2_dosarray(BUFFER5 *buf5, fstring **ar)
        *ar = NULL;
 
        while (src < ((char *)buf5->buffer) + buf5->buf_len*2) {
-               rpcstr_pull(f, src, sizeof(f)-1, -1, 0);
+               rpcstr_pull(f, src, sizeof(f)-1, -1, STR_TERMINATE);
                src = skip_unibuf(src, 2*buf5->buf_len - PTR_DIFF(src,buf5->buffer));
                tar = (fstring *)Realloc(*ar, sizeof(fstring)*(n+2));
                if (!tar)
@@ -6169,42 +6186,6 @@ BOOL spoolss_io_r_resetprinter(char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct
        return True;
 }
 
-/*******************************************************************
-********************************************************************/  
-BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
-                               uint32 type, const uint8 *data, uint32 len)
-{
-       DEBUG(5,("converting a specific param struct\n"));
-
-       if (*param == NULL)
-       {
-               *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM));
-               if(*param == NULL)
-                       return False;
-               memset((char *)*param, '\0', sizeof(NT_PRINTER_PARAM));
-               DEBUGADD(6,("Allocated a new PARAM struct\n"));
-       }
-       unistr2_to_ascii((*param)->value, value, sizeof((*param)->value)-1);
-       (*param)->type = type;
-       
-       /* le champ data n'est pas NULL termine */
-       /* on stocke donc la longueur */
-       
-       (*param)->data_len=len;
-       
-       if (len) {
-               (*param)->data=(uint8 *)malloc(len * sizeof(uint8));
-               if((*param)->data == NULL)
-                       return False;
-               memcpy((*param)->data, data, len);
-       }
-               
-       DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len));
-       dump_data(10, (char *)(*param)->data, (*param)->data_len);
-
-       return True;
-}
-
 /*******************************************************************
 ********************************************************************/  
 
@@ -6750,7 +6731,7 @@ BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd,
        q_u->unknown0=0x0;
        q_u->unknown1=0x0;
 
-       q_u->info_ptr=0xaddee11e;
+       q_u->info_ptr=0x0FF0ADDE;
 
        q_u->info.version=2;
        
@@ -7528,3 +7509,31 @@ BOOL make_spoolss_q_deleteprinterdata(SPOOL_Q_DELETEPRINTERDATA *q_u,
 
        return True;
 }
+
+/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+
+BOOL make_spoolss_q_rffpcnex(SPOOL_Q_RFFPCNEX *q_u, POLICY_HND *handle,
+                            uint32 flags, uint32 options, char *localmachine,
+                            uint32 printerlocal, SPOOL_NOTIFY_OPTION *option)
+{
+        memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
+
+       q_u->flags = flags;
+       q_u->options = options;
+
+       q_u->localmachine_ptr = 1;
+
+       init_unistr2(&q_u->localmachine, localmachine, 
+                    strlen(localmachine) + 1);
+
+       q_u->printerlocal = printerlocal;
+
+       if (option)
+               q_u->option_ptr = 1;
+
+       q_u->option = option;
+
+       return True;
+}
index 3dc054d2b172b7400fff2299a3c70dc52f4aeee6..531267c308c822ab82815be311a409cb66e6275d 100644 (file)
@@ -3,9 +3,10 @@
  *  RPC Pipe client / server routines
  *  Copyright (C) Andrew Tridgell              1992-1997,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- *  Copyright (C) Paul Ashton                       1997.
- *  Copyright (C) Jeremy Allison                   1999.
- *  Copyright (C) Jim McDonough (jmcd@us.ibm.com)   2002
+ *  Copyright (C) Paul Ashton                       1997,
+ *  Copyright (C) Jeremy Allison                   1999,
+ *  Copyright (C) Nigel Williams                   2001,
+ *  Copyright (C) Jim McDonough (jmcd@us.ibm.com)   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
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_PARSE
 
+/*******************************************************************
+ Inits a SH_INFO_0_STR structure
+********************************************************************/
+
+void init_srv_share_info0_str(SH_INFO_0_STR *sh0, char *net_name)
+{
+       DEBUG(5,("init_srv_share_info0_str\n"));
+
+       if(net_name)
+               init_unistr2(&sh0->uni_netname, net_name, strlen(net_name)+1);
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+static BOOL srv_io_share_info0_str(char *desc, SH_INFO_0_STR *sh0, prs_struct *ps, int depth)
+{
+       if (sh0 == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_share_info0_str");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       if(sh0->ptrs->ptr_netname)
+               if(!smb_io_unistr2("", &sh0->uni_netname, True, ps, depth))
+                       return False;
+
+       return True;
+}
+
+/*******************************************************************
+ makes a SH_INFO_0 structure
+********************************************************************/
+
+void init_srv_share_info0(SH_INFO_0 *sh0, char *net_name)
+{
+       DEBUG(5,("init_srv_share_info0: %s\n", net_name));
+
+       sh0->ptr_netname = (net_name != NULL) ? 1 : 0;
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+static BOOL srv_io_share_info0(char *desc, SH_INFO_0 *sh0, prs_struct *ps, int depth)
+{
+       if (sh0 == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_share_info0");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_netname", ps, depth, &sh0->ptr_netname))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
  Inits a SH_INFO_1_STR structure
 ********************************************************************/
@@ -35,8 +101,10 @@ void init_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark)
 {
        DEBUG(5,("init_srv_share_info1_str\n"));
 
-       init_unistr2(&sh1->uni_netname, net_name, strlen(net_name)+1);
-       init_unistr2(&sh1->uni_remark, remark, strlen(remark)+1);
+       if(net_name)
+               init_unistr2(&sh1->uni_netname, net_name, strlen(net_name)+1);
+       if(remark)
+               init_unistr2(&sh1->uni_remark, remark, strlen(remark)+1);
 }
 
 /*******************************************************************
@@ -47,20 +115,24 @@ static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *p
 {
        if (sh1 == NULL)
                return False;
-
+       
        prs_debug(ps, depth, desc, "srv_io_share_info1_str");
        depth++;
-
+       
        if(!prs_align(ps))
                return False;
-       if(!smb_io_unistr2("", &sh1->uni_netname, True, ps, depth))
-               return False;
 
+       if(sh1->ptrs->ptr_netname)
+               if(!smb_io_unistr2("", &sh1->uni_netname, True, ps, depth))
+                       return False;
+       
        if(!prs_align(ps))
                return False;
-       if(!smb_io_unistr2("", &sh1->uni_remark, True, ps, depth))
-               return False;
-
+       
+       if(sh1->ptrs->ptr_remark)
+               if(!smb_io_unistr2("", &sh1->uni_remark, True, ps, depth))
+                       return False;
+       
        return True;
 }
 
@@ -71,7 +143,7 @@ static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *p
 void init_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark)
 {
        DEBUG(5,("init_srv_share_info1: %s %8x %s\n", net_name, type, remark));
-
+       
        sh1->ptr_netname = (net_name != NULL) ? 1 : 0;
        sh1->type        = type;
        sh1->ptr_remark  = (remark != NULL) ? 1 : 0;
@@ -139,6 +211,7 @@ static BOOL srv_io_share_info2_str(char *desc, SH_INFO_2 *sh, SH_INFO_2_STR *sh2
 
        if(!prs_align(ps))
                return False;
+
        if (sh->ptr_netname)
                if(!smb_io_unistr2("", &sh2->uni_netname, True, ps, depth))
                        return False;
@@ -175,7 +248,6 @@ void init_srv_share_info2(SH_INFO_2 *sh2,
        sh2->perms       = perms;
        sh2->max_uses    = max_uses;
        sh2->num_uses    = num_uses;
-       sh2->type        = type;
        sh2->ptr_path    = (path != NULL) ? 1 : 0;
        sh2->ptr_passwd  = (passwd != NULL) ? 1 : 0;
 }
@@ -215,6 +287,21 @@ static BOOL srv_io_share_info2(char *desc, SH_INFO_2 *sh2, prs_struct *ps, int d
        return True;
 }
 
+/*******************************************************************
+ Inits a SH_INFO_501_STR structure
+********************************************************************/
+
+void init_srv_share_info501_str(SH_INFO_501_STR *sh501,
+                               char *net_name, char *remark)
+{
+       DEBUG(5,("init_srv_share_info501_str\n"));
+
+       if(net_name)
+               init_unistr2(&sh501->uni_netname, net_name, strlen(net_name)+1);
+       if(remark)
+               init_unistr2(&sh501->uni_remark, remark, strlen(remark)+1);
+}
+
 /*******************************************************************
  Inits a SH_INFO_2 structure
 *******************************************************************/
@@ -259,18 +346,6 @@ static BOOL srv_io_share_info501(char *desc, SH_INFO_501 *sh501, prs_struct *ps,
        return True;
 }
 
-/********************************************************************
- Inits a SH_INFO_501_STR structure
-********************************************************************/
-
-void init_srv_share_info501_str(SH_INFO_501_STR *sh501, char *net_name, char *remark)
-{
-       DEBUG(5,("init_srv_share_info501_str\n"));
-
-       init_unistr2(&sh501->uni_netname, net_name, strlen(net_name)+1);
-       init_unistr2(&sh501->uni_remark, remark, strlen(remark)+1);
-}
-
 /*******************************************************************
  Reads or writes a structure.
 ********************************************************************/
@@ -301,7 +376,7 @@ static BOOL srv_io_share_info501_str(char *desc, SH_INFO_501_STR *sh501, prs_str
 ********************************************************************/
 
 void init_srv_share_info502(SH_INFO_502 *sh502,
-                               char *net_name, uint32 type, char *remark,
+                               const char *net_name, uint32 type, char *remark,
                                uint32 perms, uint32 max_uses, uint32 num_uses,
                                char *path, char *passwd, SEC_DESC *psd, size_t sd_size)
 {
@@ -315,9 +390,9 @@ void init_srv_share_info502(SH_INFO_502 *sh502,
        sh502->perms       = perms;
        sh502->max_uses    = max_uses;
        sh502->num_uses    = num_uses;
-       sh502->type        = type;
        sh502->ptr_path    = (path != NULL) ? 1 : 0;
        sh502->ptr_passwd  = (passwd != NULL) ? 1 : 0;
+       sh502->reserved    = 0;  /* actual size within rpc */
        sh502->sd_size     = (uint32)sd_size;
        sh502->ptr_sd      = (psd != NULL) ? 1 : 0;
 }
@@ -353,7 +428,7 @@ static BOOL srv_io_share_info502(char *desc, SH_INFO_502 *sh502, prs_struct *ps,
                return False;
        if(!prs_uint32("ptr_passwd ", ps, depth, &sh502->ptr_passwd))
                return False;
-       if(!prs_uint32("sd_size    ", ps, depth, &sh502->sd_size))
+       if(!prs_uint32_pre("reserved   ", ps, depth, &sh502->reserved, &sh502->reserved_offset))
                return False;
        if(!prs_uint32("ptr_sd     ", ps, depth, &sh502->ptr_sd))
                return False;
@@ -366,26 +441,22 @@ static BOOL srv_io_share_info502(char *desc, SH_INFO_502 *sh502, prs_struct *ps,
 ********************************************************************/
 
 void init_srv_share_info502_str(SH_INFO_502_STR *sh502str,
-                               SH_INFO_502 *ptrs,
                                char *net_name, char *remark,
                                char *path, char *passwd, SEC_DESC *psd, size_t sd_size)
 {
        DEBUG(5,("init_srv_share_info502_str\n"));
 
-       sh502str->ptrs = ptrs;
-
-       if(sh502str->ptrs->ptr_netname)
+       if(net_name)
                init_unistr2(&sh502str->uni_netname, net_name, strlen(net_name)+1);
-       if(sh502str->ptrs->ptr_remark)
+       if(remark)
                init_unistr2(&sh502str->uni_remark, remark, strlen(remark)+1);
-       if(sh502str->ptrs->ptr_path)
+       if(path)
                init_unistr2(&sh502str->uni_path, path, strlen(path)+1);
-       if(sh502str->ptrs->ptr_passwd)
+       if(passwd)
                init_unistr2(&sh502str->uni_passwd, passwd, strlen(passwd)+1);
-       if(sh502str->ptrs->ptr_sd) {
                sh502str->sd = psd;
+       sh502str->reserved = 0;
                sh502str->sd_size = sd_size;
-       }
 }
 
 /*******************************************************************
@@ -436,21 +507,112 @@ static BOOL srv_io_share_info502_str(char *desc, SH_INFO_502_STR *sh502, prs_str
                return False;
 
        if(sh502->ptrs->ptr_sd) {
-               if(!prs_uint32("sd_size   ", ps, depth, &sh502->sd_size))
+               uint32 old_offset;
+               uint32 reserved_offset;
+
+               if(!prs_uint32_pre("reserved ", ps, depth, &sh502->reserved, &reserved_offset))
                        return False;
+         
+               old_offset = prs_offset(ps);
+         
                if (!sec_io_desc(desc, &sh502->sd, ps, depth))
                        return False;
+
+               if(UNMARSHALLING(ps)) {
+
+                       sh502->ptrs->sd_size = sh502->sd_size = sec_desc_size(sh502->sd);
+
+                       prs_set_offset(ps, old_offset + sh502->reserved);
+               }
+
+               prs_align(ps);
+
+               if(MARSHALLING(ps)) {
+
+                       sh502->ptrs->reserved = sh502->reserved = prs_offset(ps) - old_offset;
+               }
+           
+               if(!prs_uint32_post("reserved ", ps, depth, 
+                                   &sh502->reserved, reserved_offset, sh502->reserved))
+                       return False;
+               if(!prs_uint32_post("reserved ", ps, depth, 
+                                   &sh502->ptrs->reserved, sh502->ptrs->reserved_offset, sh502->ptrs->reserved))
+                       return False;
        }
 
        return True;
 }
 
+/*******************************************************************
+ Inits a SH_INFO_1004_STR structure
+********************************************************************/
+
+void init_srv_share_info1004_str(SH_INFO_1004_STR *sh1004, char *remark)
+{
+       DEBUG(5,("init_srv_share_info1004_str\n"));
+
+       if(remark)
+               init_unistr2(&sh1004->uni_remark, remark, strlen(remark)+1);
+}
+
 /*******************************************************************
  Reads or writes a structure.
 ********************************************************************/
 
-static BOOL srv_io_share_info1005(char* desc, SRV_SHARE_INFO_1005* sh1005,
-                                 prs_struct* ps, int depth)
+static BOOL srv_io_share_info1004_str(char *desc, SH_INFO_1004_STR *sh1004, prs_struct *ps, int depth)
+{
+       if (sh1004 == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_share_info1004_str");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       if(sh1004->ptrs->ptr_remark)
+               if(!smb_io_unistr2("", &sh1004->uni_remark, True, ps, depth))
+                       return False;
+
+       return True;
+}
+
+/*******************************************************************
+ makes a SH_INFO_1004 structure
+********************************************************************/
+
+void init_srv_share_info1004(SH_INFO_1004 *sh1004, char *remark)
+{
+       DEBUG(5,("init_srv_share_info1004: %s\n", remark));
+
+       sh1004->ptr_remark = (remark != NULL) ? 1 : 0;
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+static BOOL srv_io_share_info1004(char *desc, SH_INFO_1004 *sh1004, prs_struct *ps, int depth)
+{
+       if (sh1004 == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_share_info1004");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_remark", ps, depth, &sh1004->ptr_remark))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+static BOOL srv_io_share_info1005(char* desc, SRV_SHARE_INFO_1005* sh1005, prs_struct* ps, int depth)
 {
        if(sh1005 == NULL)
                return False;
@@ -471,6 +633,95 @@ static BOOL srv_io_share_info1005(char* desc, SRV_SHARE_INFO_1005* sh1005,
  Reads or writes a structure.
 ********************************************************************/
 
+static BOOL srv_io_share_info1006(char* desc, SRV_SHARE_INFO_1006* sh1006, prs_struct* ps, int depth)
+{
+       if(sh1006 == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_share_info1006");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("max uses     ", ps, depth, &sh1006->max_uses))
+               return False;
+
+       return True;
+}   
+
+/*******************************************************************
+ Inits a SH_INFO_1007_STR structure
+********************************************************************/
+
+void init_srv_share_info1007_str(SH_INFO_1007_STR *sh1007, const char *alternate_directory_name)
+{
+       DEBUG(5,("init_srv_share_info1007_str\n"));
+
+       if(alternate_directory_name)
+               init_unistr2(&sh1007->uni_AlternateDirectoryName, alternate_directory_name, strlen(alternate_directory_name)+1);
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+static BOOL srv_io_share_info1007_str(char *desc, SH_INFO_1007_STR *sh1007, prs_struct *ps, int depth)
+{
+       if (sh1007 == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_share_info1007_str");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+       if(sh1007->ptrs->ptr_AlternateDirectoryName)
+               if(!smb_io_unistr2("", &sh1007->uni_AlternateDirectoryName, True, ps, depth))
+                       return False;
+
+       return True;
+}
+
+/*******************************************************************
+ makes a SH_INFO_1007 structure
+********************************************************************/
+
+void init_srv_share_info1007(SH_INFO_1007 *sh1007, uint32 flags, const char *alternate_directory_name)
+{
+       DEBUG(5,("init_srv_share_info1007: %s\n", alternate_directory_name));
+
+       sh1007->flags                      = flags;
+       sh1007->ptr_AlternateDirectoryName = (alternate_directory_name != NULL) ? 1 : 0;
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
+static BOOL srv_io_share_info1007(char *desc, SH_INFO_1007 *sh1007, prs_struct *ps, int depth)
+{
+       if (sh1007 == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "srv_io_share_info1007");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("flags      ", ps, depth, &sh1007->flags))
+               return False;
+       if(!prs_uint32("ptr_Alter..", ps, depth, &sh1007->ptr_AlternateDirectoryName))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+ Reads or writes a structure.
+********************************************************************/
+
 static BOOL srv_io_share_info1501(char* desc, SRV_SHARE_INFO_1501* sh1501,
                                  prs_struct* ps, int depth)
 {
@@ -511,9 +762,6 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
        if(!prs_uint32("info_level", ps, depth, &ctr->info_level))
                return False;
 
-       if (ctr->info_level == 0)
-               return True;
-
        if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
                return False;
        if(!prs_uint32("ptr_share_info", ps, depth, &ctr->ptr_share_info))
@@ -541,6 +789,33 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
                return False;
 
        switch (ctr->switch_value) {
+
+       case 0:
+       {
+               SRV_SHARE_INFO_0 *info0 = ctr->share.info0;
+               int num_entries = ctr->num_entries;
+               int i;
+
+               if (UNMARSHALLING(ps)) {
+                       if (!(info0 = (SRV_SHARE_INFO_0 *)prs_alloc_mem(ps, num_entries * sizeof(SRV_SHARE_INFO_0))))
+                               return False;
+                       ctr->share.info0 = info0;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info0("", &info0[i].info_0, ps, depth))
+                               return False;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       info0[i].info_0_str.ptrs = &info0[i].info_0;
+                       if(!srv_io_share_info0_str("", &info0[i].info_0_str, ps, depth))
+                               return False;
+               }
+
+               break;
+       }
+
        case 1:
        {
                SRV_SHARE_INFO_1 *info1 = ctr->share.info1;
@@ -559,6 +834,7 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
                }
 
                for (i = 0; i < num_entries; i++) {
+                       info1[i].info_1_str.ptrs = &info1[i].info_1;
                        if(!srv_io_share_info1_str("", &info1[i].info_1_str, ps, depth))
                                return False;
                }
@@ -632,8 +908,8 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
                for (i = 0; i < num_entries; i++) {
                        if(!srv_io_share_info502("", &info502[i].info_502, ps, depth))
                                return False;
-               }
-
+       }
+               
                for (i = 0; i < num_entries; i++) {
                        info502[i].info_502_str.ptrs = &info502[i].info_502;
                        if(!srv_io_share_info502_str("", &info502[i].info_502_str, ps, depth))
@@ -643,6 +919,118 @@ static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct
                break;
        }
 
+       case 1004:
+       {
+               SRV_SHARE_INFO_1004 *info1004 = ctr->share.info1004;
+               int num_entries = ctr->num_entries;
+               int i;
+
+               if (UNMARSHALLING(ps)) {
+                       if (!(info1004 = (SRV_SHARE_INFO_1004 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1004))))
+                               return False;
+                       ctr->share.info1004 = info1004;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info1004("", &info1004[i].info_1004, ps, depth))
+                               return False;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       info1004[i].info_1004_str.ptrs = &info1004[i].info_1004;
+                       if(!srv_io_share_info1004_str("", &info1004[i].info_1004_str, ps, depth))
+                               return False;
+               }
+
+               break;
+       }
+
+       case 1005:
+       {
+               SRV_SHARE_INFO_1005 *info1005 = ctr->share.info1005;
+               int num_entries = ctr->num_entries;
+               int i;
+
+               if (UNMARSHALLING(ps)) {
+                       if (!(info1005 = (SRV_SHARE_INFO_1005 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1005))))
+                               return False;
+                       ctr->share.info1005 = info1005;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info1005("", &info1005[i], ps, depth))
+                               return False;
+               }
+
+               break;
+       }
+
+       case 1006:
+       {
+               SRV_SHARE_INFO_1006 *info1006 = ctr->share.info1006;
+               int num_entries = ctr->num_entries;
+               int i;
+
+               if (UNMARSHALLING(ps)) {
+                       if (!(info1006 = (SRV_SHARE_INFO_1006 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1006))))
+                               return False;
+                       ctr->share.info1006 = info1006;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info1006("", &info1006[i], ps, depth))
+                               return False;
+               }
+
+               break;
+       }
+
+       case 1007:
+       {
+               SRV_SHARE_INFO_1007 *info1007 = ctr->share.info1007;
+               int num_entries = ctr->num_entries;
+               int i;
+
+               if (UNMARSHALLING(ps)) {
+                       if (!(info1007 = (SRV_SHARE_INFO_1007 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1007))))
+                               return False;
+                       ctr->share.info1007 = info1007;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info1007("", &info1007[i].info_1007, ps, depth))
+                               return False;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       info1007[i].info_1007_str.ptrs = &info1007[i].info_1007;
+                       if(!srv_io_share_info1007_str("", &info1007[i].info_1007_str, ps, depth))
+                               return False;
+               }
+
+               break;
+       }
+
+       case 1501:
+       {
+               SRV_SHARE_INFO_1501 *info1501 = ctr->share.info1501;
+               int num_entries = ctr->num_entries;
+               int i;
+
+               if (UNMARSHALLING(ps)) {
+                       if (!(info1501 = (SRV_SHARE_INFO_1501 *)prs_alloc_mem(ps,num_entries * sizeof(SRV_SHARE_INFO_1501))))
+                               return False;
+                       ctr->share.info1501 = info1501;
+               }
+
+               for (i = 0; i < num_entries; i++) {
+                       if(!srv_io_share_info1501("", &info1501[i], ps, depth))
+                               return False;
+               }
+
+               break;
+       }
+
        default:
                DEBUG(5,("%s no share info at switch_value %d\n",
                         tab_depth(depth), ctr->switch_value));
@@ -667,8 +1055,9 @@ void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
 
        q_n->ctr.info_level = q_n->ctr.switch_value = info_level;
        q_n->ctr.ptr_share_info = 1;
-       q_n->ctr.num_entries = 0;
-       q_n->ctr.ptr_entries = 0;
+       q_n->ctr.num_entries  = 0;
+       q_n->ctr.ptr_entries  = 0;
+       q_n->ctr.num_entries2 = 0;
        q_n->preferred_len = preferred_len;
 
        memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
@@ -729,14 +1118,37 @@ BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *
 
        if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
                return False;
-       if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
-               return False;
+
+       if(r_n->total_entries != 0) {
+               if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
+                       return False;
+       }
+
        if(!prs_werror("status", ps, depth, &r_n->status))
                return False;
 
        return True;
 }
 
+/*******************************************************************
+ initialises a structure.
+********************************************************************/
+
+BOOL init_srv_q_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n, const char *srv_name, const char *share_name, uint32 info_level)
+{
+
+       uint32 ptr_share_name;
+
+       DEBUG(5,("init_srv_q_net_share_get_info\n"));
+
+       init_buf_unistr2(&q_n->uni_srv_name,   &q_n->ptr_srv_name, srv_name);
+       init_buf_unistr2(&q_n->uni_share_name, &ptr_share_name,    share_name);
+
+       q_n->info_level = info_level;
+
+       return True;
+}
+
 /*******************************************************************
  Reads or writes a structure.
 ********************************************************************/
@@ -792,10 +1204,24 @@ static BOOL srv_io_srv_share_info(char *desc, prs_struct *ps, int depth, SRV_SHA
 
        if (r_n->ptr_share_ctr != 0) {
                switch (r_n->switch_value) {
+               case 0:
+                       if(!srv_io_share_info0("", &r_n->share.info0.info_0, ps, depth))
+                               return False;
+
+                       /* allow access to pointers in the str part. */
+                       r_n->share.info0.info_0_str.ptrs = &r_n->share.info0.info_0;
+
+                       if(!srv_io_share_info0_str("", &r_n->share.info0.info_0_str, ps, depth))
+                               return False;
+
+                       break;
                case 1:
                        if(!srv_io_share_info1("", &r_n->share.info1.info_1, ps, depth))
                                return False;
 
+                       /* allow access to pointers in the str part. */
+                       r_n->share.info1.info_1_str.ptrs = &r_n->share.info1.info_1;
+
                        if(!srv_io_share_info1_str("", &r_n->share.info1.info_1_str, ps, depth))
                                return False;
 
@@ -819,16 +1245,40 @@ static BOOL srv_io_srv_share_info(char *desc, prs_struct *ps, int depth, SRV_SHA
                        if(!srv_io_share_info502("", &r_n->share.info502.info_502, ps, depth))
                                return False;
 
-                       /*allow access to pointers in the str part. */
+                       /* allow access to pointers in the str part. */
                        r_n->share.info502.info_502_str.ptrs = &r_n->share.info502.info_502;
 
                        if(!srv_io_share_info502_str("", &r_n->share.info502.info_502_str, ps, depth))
                                return False;
                        break;
+               case 1004:
+                       if(!srv_io_share_info1004("", &r_n->share.info1004.info_1004, ps, depth))
+                               return False;
+
+                       /* allow access to pointers in the str part. */
+                       r_n->share.info1004.info_1004_str.ptrs = &r_n->share.info1004.info_1004;
+
+                       if(!srv_io_share_info1004_str("", &r_n->share.info1004.info_1004_str, ps, depth))
+                               return False;
+                       break;
                case 1005:
                        if(!srv_io_share_info1005("", &r_n->share.info1005, ps, depth))
                                return False;           
                        break;
+               case 1006:
+                       if(!srv_io_share_info1006("", &r_n->share.info1006, ps, depth))
+                               return False;           
+                       break;
+               case 1007:
+                       if(!srv_io_share_info1007("", &r_n->share.info1007.info_1007, ps, depth))
+                               return False;
+
+                       /* allow access to pointers in the str part. */
+                       r_n->share.info1007.info_1007_str.ptrs = &r_n->share.info1007.info_1007;
+
+                       if(!srv_io_share_info1007_str("", &r_n->share.info1007.info_1007_str, ps, depth))
+                               return False;
+                       break;
                case 1501:
                        if (!srv_io_share_info1501("", &r_n->share.info1501, ps, depth))
                                return False;
@@ -869,6 +1319,34 @@ BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n, prs_
        return True;
 }
 
+/*******************************************************************
+ intialises a structure.
+********************************************************************/
+
+BOOL init_srv_q_net_share_set_info(SRV_Q_NET_SHARE_SET_INFO *q_n, 
+                                  const char *srv_name, 
+                                  const char *share_name, 
+                                  uint32 info_level, 
+                                  const SRV_SHARE_INFO *info) 
+{
+
+       uint32 ptr_share_name;
+
+       DEBUG(5,("init_srv_q_net_share_set_info\n"));
+
+       init_buf_unistr2(&q_n->uni_srv_name,   &q_n->ptr_srv_name, srv_name);
+       init_buf_unistr2(&q_n->uni_share_name, &ptr_share_name,    share_name);
+
+       q_n->info_level = info_level;
+  
+       q_n->info = *info;
+
+       q_n->ptr_parm_error = 1;
+       q_n->parm_error     = 0;
+
+       return True;
+}
+
 /*******************************************************************
  Reads or writes a structure.
 ********************************************************************/
@@ -904,6 +1382,15 @@ BOOL srv_io_q_net_share_set_info(char *desc, SRV_Q_NET_SHARE_SET_INFO *q_n, prs_
        if(!srv_io_srv_share_info("info  ", ps, depth, &q_n->info))
                return False;
 
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("ptr_parm_error", ps, depth, &q_n->ptr_parm_error))
+               return False;
+       if(q_n->ptr_parm_error!=0) {
+               if(!prs_uint32("parm_error", ps, depth, &q_n->parm_error))
+                       return False;
+       }
+
        return True;
 }
 
@@ -911,9 +1398,9 @@ BOOL srv_io_q_net_share_set_info(char *desc, SRV_Q_NET_SHARE_SET_INFO *q_n, prs_
  Reads or writes a structure.
 ********************************************************************/
 
-BOOL srv_io_r_net_share_set_info(char *desc, SRV_R_NET_SHARE_SET_INFO *q_n, prs_struct *ps, int depth)
+BOOL srv_io_r_net_share_set_info(char *desc, SRV_R_NET_SHARE_SET_INFO *r_n, prs_struct *ps, int depth)
 {
-       if (q_n == NULL)
+       if (r_n == NULL)
                return False;
 
        prs_debug(ps, depth, desc, "srv_io_r_net_share_set_info");
@@ -922,14 +1409,22 @@ BOOL srv_io_r_net_share_set_info(char *desc, SRV_R_NET_SHARE_SET_INFO *q_n, prs_
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("switch_value  ", ps, depth, &q_n->switch_value))
+       if(!prs_uint32("ptr_parm_error  ", ps, depth, &r_n->ptr_parm_error))
                return False;
-       if(!prs_werror("status", ps, depth, &q_n->status))
+
+       if(r_n->ptr_parm_error) {
+
+               if(!prs_uint32("parm_error  ", ps, depth, &r_n->parm_error))
+                       return False;
+       }
+
+       if(!prs_werror("status", ps, depth, &r_n->status))
                return False;
 
        return True;
 }      
 
+
 /*******************************************************************
  Reads or writes a structure.
 ********************************************************************/
@@ -962,6 +1457,9 @@ BOOL srv_io_q_net_share_add(char *desc, SRV_Q_NET_SHARE_ADD *q_n, prs_struct *ps
        if(!srv_io_srv_share_info("info  ", ps, depth, &q_n->info))
                return False;
 
+       if(!prs_align(ps))
+               return False;
+
        if(!prs_uint32("ptr_err_index", ps, depth, &q_n->ptr_err_index))
                return False;
        if (q_n->ptr_err_index)
@@ -994,9 +1492,9 @@ void init_srv_q_net_share_add(SRV_Q_NET_SHARE_ADD *q, char *srvname,
  Reads or writes a structure.
 ********************************************************************/
 
-BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *q_n, prs_struct *ps, int depth)
+BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *r_n, prs_struct *ps, int depth)
 {
-       if (q_n == NULL)
+       if (r_n == NULL)
                return False;
 
        prs_debug(ps, depth, desc, "srv_io_r_net_share_add");
@@ -1005,14 +1503,25 @@ BOOL srv_io_r_net_share_add(char *desc, SRV_R_NET_SHARE_ADD *q_n, prs_struct *ps
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("switch_value  ", ps, depth, &q_n->switch_value))
+       if(!prs_uint32("ptr_parm_error", ps, depth, &r_n->ptr_parm_error))
                return False;
-       if(!prs_werror("status", ps, depth, &q_n->status))
+
+       if(r_n->ptr_parm_error) {
+         
+               if(!prs_uint32("parm_error", ps, depth, &r_n->parm_error))
+                       return False;
+       }
+
+       if(!prs_werror("status", ps, depth, &r_n->status))
                return False;
 
        return True;
 }      
 
+/*******************************************************************
+ initialises a structure.
+********************************************************************/
+
 void init_srv_q_net_share_del(SRV_Q_NET_SHARE_DEL *del, const char *srvname,
                              const char *sharename)
 {
@@ -1889,8 +2398,8 @@ static BOOL srv_io_file_info3_str(char *desc, FILE_INFO_3_STR *sh1, prs_struct *
 ********************************************************************/
 
 void init_srv_file_info3(FILE_INFO_3 *fl3,
-                               uint32 id, uint32 perms, uint32 num_locks,
-                               char *path_name, char *user_name)
+                        uint32 id, uint32 perms, uint32 num_locks,
+                        char *path_name, char *user_name)
 {
        DEBUG(5,("init_srv_file_info3: %s %s\n", path_name, user_name));
 
@@ -2004,7 +2513,8 @@ static BOOL srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *
 ********************************************************************/
 
 void init_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n, 
-                             char *srv_name, char *qual_name, char *user_name,
+                             const char *srv_name, const char *qual_name, 
+                             const char *user_name,
                              uint32 file_level, SRV_FILE_INFO_CTR *ctr,
                              uint32 preferred_len,
                              ENUM_HND *hnd)
@@ -2295,7 +2805,7 @@ void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
        sv102->disc         = disc;
        sv102->hidden       = hidden;
        sv102->announce     = announce;
-       sv102->ann_delta    =ann_delta;
+       sv102->ann_delta    = ann_delta;
        sv102->licenses     = licenses;
        init_buf_unistr2(&sv102->uni_usr_path, &sv102->ptr_usr_path, usr_path);
 }
@@ -2559,7 +3069,7 @@ BOOL srv_io_r_net_srv_set_info(char *desc, SRV_R_NET_SRV_SET_INFO *r_n,
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("switch_value  ", ps, depth, &r_n->switch_value))
+       if(!prs_uint32("switch value ", ps, depth, &r_n->switch_value))
                return False;
 
        if(!prs_werror("status", ps, depth, &r_n->status))
@@ -2687,6 +3197,31 @@ BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *
        return True;
 }
 
+/*******************************************************************
+ initialises a structure.
+ ********************************************************************/
+
+BOOL init_srv_q_net_disk_enum(SRV_Q_NET_DISK_ENUM *q_n,
+                             const char *srv_name,
+                             uint32 preferred_len,
+                             ENUM_HND *enum_hnd
+       ) 
+{
+  
+
+       DEBUG(5,("init_srv_q_net_srv_disk_enum\n"));
+
+       init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
+
+       q_n->disk_enum_ctr.level = 0;
+       q_n->disk_enum_ctr.disk_info_ptr   = 0;
+  
+       q_n->preferred_len = preferred_len;
+       memcpy(&q_n->enum_hnd, enum_hnd, sizeof(*enum_hnd));
+
+       return True;
+}
+
 /*******************************************************************
  Reads or writes a structure.
  ********************************************************************/
@@ -2737,7 +3272,9 @@ BOOL srv_io_q_net_disk_enum(char *desc, SRV_Q_NET_DISK_ENUM *q_n, prs_struct *ps
 
 BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps, int depth)
 {
+
        int i;
+       uint32 entries_read, entries_read2, entries_read3;
 
        if (r_n == NULL)
                return False;
@@ -2745,23 +3282,36 @@ BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps
        prs_debug(ps, depth, desc, "srv_io_r_net_disk_enum");
        depth++;
 
+       entries_read = entries_read2 = entries_read3 = r_n->disk_enum_ctr.entries_read;
+
        if(!prs_align(ps))
                return False;
 
-       if(!prs_uint32("entries_read", ps, depth, &r_n->disk_enum_ctr.entries_read))
+       if(!prs_uint32("entries_read", ps, depth, &entries_read))
                return False;
        if(!prs_uint32("ptr_disk_info", ps, depth, &r_n->disk_enum_ctr.disk_info_ptr))
                return False;
 
        /*this may be max, unknown, actual?*/
 
-       if(!prs_uint32("max_elements", ps, depth, &r_n->disk_enum_ctr.entries_read))
+       if(!prs_uint32("max_elements", ps, depth, &entries_read2))
                return False;
        if(!prs_uint32("unknown", ps, depth, &r_n->disk_enum_ctr.unknown))
                return False;
-       if(!prs_uint32("actual_elements", ps, depth, &r_n->disk_enum_ctr.entries_read))
+       if(!prs_uint32("actual_elements", ps, depth, &entries_read3))
                return False;
 
+       r_n->disk_enum_ctr.entries_read = entries_read3;
+
+       if(UNMARSHALLING(ps)) {
+
+               DISK_INFO *dinfo;
+
+               if(!(dinfo = (DISK_INFO *)prs_alloc_mem(ps, sizeof(*dinfo) * entries_read3)))
+               return False;
+               r_n->disk_enum_ctr.disk_info = dinfo;
+       }
+
        for(i=0; i < r_n->disk_enum_ctr.entries_read; i++) {
 
                if(!prs_uint32("unknown", ps, depth, &r_n->disk_enum_ctr.disk_info[i].unknown))
@@ -2786,6 +3336,25 @@ BOOL srv_io_r_net_disk_enum(char *desc, SRV_R_NET_DISK_ENUM *r_n, prs_struct *ps
        return True;
 }
 
+/*******************************************************************
+ initialises a structure.
+ ********************************************************************/
+
+BOOL init_srv_q_net_name_validate(SRV_Q_NET_NAME_VALIDATE *q_n, const char *srv_name, const char *share_name, int type) 
+{
+       uint32 ptr_share_name;
+
+       DEBUG(5,("init_srv_q_net_name_validate\n"));
+  
+       init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
+       init_buf_unistr2(&q_n->uni_name,     &ptr_share_name,    share_name);
+
+       q_n->type  = type;
+       q_n->flags = 0;
+
+       return True;
+}
+
 /*******************************************************************
  Reads or writes a structure.
  ********************************************************************/