summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2003-08-15 17:52:55 +0000
committerGerald Carter <jerry@samba.org>2003-08-15 17:52:55 +0000
commit7139794cd0e68298e638929f35e7684a60fe5974 (patch)
tree2b40a989618bb9ece453fc995c645dfb1556af22
parent34ec734381246665fb20225dc2e03b06fd7fcc90 (diff)
downloadsamba-7139794cd0e68298e638929f35e7684a60fe5974.tar.gz
syncing up to 3.0.0rc1
-rw-r--r--packaging/SuSE/samba-3.0.0-msdfs.diff97
-rw-r--r--packaging/SuSE/samba-3.0.0-net_ads.diff140
-rw-r--r--packaging/SuSE/samba-3.0.0-pdb.diff11
-rw-r--r--packaging/SuSE/samba-3.0.0-python.diff44
-rw-r--r--packaging/SuSE/samba-3.0.0-vscan.diff80
-rw-r--r--packaging/SuSE/samba-vscan-0.3.1.tar.bz2bin51383 -> 0 bytes
-rwxr-xr-xpackaging/SuSE/samba-vscan-0.3.2b.tar.bz2bin69479 -> 0 bytes
-rw-r--r--source/Makefile.in149
-rw-r--r--source/aclocal.m4265
-rw-r--r--source/auth/auth.c6
-rw-r--r--source/auth/auth_domain.c4
-rw-r--r--source/auth/auth_ntlmssp.c1
-rw-r--r--source/auth/auth_sam.c12
-rw-r--r--source/auth/auth_util.c134
-rw-r--r--source/auth/auth_winbind.c2
-rw-r--r--source/client/client.c456
-rw-r--r--source/client/clitar.c2552
-rw-r--r--source/client/smbmnt.c4
-rw-r--r--source/client/smbmount.c2
-rw-r--r--source/client/smbspool.c2
-rw-r--r--source/client/tree.c6
-rw-r--r--source/configure.in527
-rw-r--r--source/dynconfig.c2
-rw-r--r--source/groupdb/mapping.c36
-rw-r--r--source/include/authdata.h2
-rw-r--r--source/include/byteorder.h2
-rw-r--r--source/include/charset.h6
-rw-r--r--source/include/client.h12
-rw-r--r--source/include/dynconfig.h2
-rw-r--r--source/include/idmap.h2
-rw-r--r--source/include/includes.h20
-rw-r--r--source/include/ntdomain.h20
-rw-r--r--source/include/ntioctl.h19
-rw-r--r--source/include/ntlmssp.h1
-rw-r--r--source/include/ntquotas.h2
-rw-r--r--source/include/popt_common.h1
-rw-r--r--source/include/rpc_dce.h8
-rw-r--r--source/include/rpc_ds.h75
-rw-r--r--source/include/rpc_lsa.h6
-rw-r--r--source/include/rpc_samr.h3
-rw-r--r--source/include/rpc_secdes.h20
-rwxr-xr-xsource/include/rpc_spoolss.h6
-rw-r--r--source/include/smb.h27
-rw-r--r--source/include/smb_macros.h6
-rw-r--r--source/include/smbldap.h3
-rw-r--r--source/include/spnego.h65
-rw-r--r--source/include/sysquotas.h16
-rw-r--r--source/include/version.h2
-rw-r--r--source/include/vfs.h12
-rw-r--r--source/include/vfs_macros.h3
-rw-r--r--source/lib/access.c3
-rw-r--r--source/lib/account_pol.c2
-rw-r--r--source/lib/charcnv.c120
-rw-r--r--source/lib/dummyroot.c33
-rw-r--r--source/lib/module.c2
-rw-r--r--source/lib/ms_fnmatch.c82
-rw-r--r--source/lib/popt_common.c56
-rw-r--r--source/lib/readline.c4
-rw-r--r--source/lib/replace.c18
-rw-r--r--source/lib/replace1.c42
-rw-r--r--source/lib/smbldap.c75
-rw-r--r--source/lib/snprintf.c6
-rw-r--r--source/lib/substitute.c4
-rw-r--r--source/lib/sysquotas.c234
-rw-r--r--source/lib/system.c159
-rw-r--r--source/lib/username.c4
-rw-r--r--source/lib/util.c17
-rw-r--r--source/lib/util_file.c4
-rw-r--r--source/lib/util_sid.c2
-rw-r--r--source/lib/util_sock.c184
-rw-r--r--source/lib/util_str.c77
-rw-r--r--source/lib/util_unistr.c76
-rw-r--r--source/lib/util_uuid.c2
-rw-r--r--source/libads/ads_status.c2
-rw-r--r--source/libads/authdata.c9
-rw-r--r--source/libads/kerberos_verify.c74
-rw-r--r--source/libads/krb5_setpw.c2
-rw-r--r--source/libads/ldap.c102
-rw-r--r--source/libads/ldap_printer.c2
-rw-r--r--source/libads/ldap_user.c2
-rw-r--r--source/libads/sasl.c19
-rw-r--r--source/libsmb/asn1.c6
-rw-r--r--source/libsmb/cliconnect.c132
-rw-r--r--source/libsmb/clientgen.c32
-rw-r--r--source/libsmb/clierror.c3
-rw-r--r--source/libsmb/clikrb5.c41
-rw-r--r--source/libsmb/clilist.c45
-rw-r--r--source/libsmb/cliprint.c17
-rw-r--r--source/libsmb/clirap.c10
-rw-r--r--source/libsmb/clirap2.c63
-rw-r--r--source/libsmb/clireadwrite.c2
-rw-r--r--source/libsmb/clisecdesc.c4
-rw-r--r--source/libsmb/clispnego.c11
-rw-r--r--source/libsmb/clitrans.c96
-rw-r--r--source/libsmb/errormap.c1
-rw-r--r--source/libsmb/namequery_dc.c16
-rw-r--r--source/libsmb/nmblib.c14
-rw-r--r--source/libsmb/ntlmssp.c75
-rw-r--r--source/libsmb/ntlmssp_parse.c5
-rw-r--r--source/libsmb/ntlmssp_sign.c24
-rw-r--r--source/libsmb/smb_signing.c760
-rw-r--r--source/libsmb/smbencrypt.c4
-rw-r--r--source/libsmb/spnego.c343
-rw-r--r--source/libsmb/trustdom_cache.c2
-rw-r--r--source/libsmb/trusts_util.c2
-rw-r--r--source/locking/locking.c10
-rw-r--r--source/modules/getdate.c2460
-rw-r--r--source/modules/getdate.h46
-rw-r--r--source/modules/getdate.y1115
-rw-r--r--source/modules/vfs_default_quota.c180
-rw-r--r--source/modules/vfs_readonly.c98
-rw-r--r--source/modules/vfs_recycle.c3
-rw-r--r--source/msdfs/msdfs.c75
-rw-r--r--source/nmbd/nmbd_processlogon.c3
-rw-r--r--source/nsswitch/wb_client.c74
-rw-r--r--source/nsswitch/wb_common.c2
-rw-r--r--source/nsswitch/wbinfo.c76
-rw-r--r--source/nsswitch/winbindd.c42
-rw-r--r--source/nsswitch/winbindd.h2
-rw-r--r--source/nsswitch/winbindd_acct.c78
-rw-r--r--source/nsswitch/winbindd_ads.c89
-rw-r--r--source/nsswitch/winbindd_cache.c16
-rw-r--r--source/nsswitch/winbindd_cm.c39
-rw-r--r--source/nsswitch/winbindd_group.c38
-rw-r--r--source/nsswitch/winbindd_misc.c30
-rw-r--r--source/nsswitch/winbindd_nss.h1
-rw-r--r--source/nsswitch/winbindd_pam.c67
-rw-r--r--source/nsswitch/winbindd_rpc.c4
-rw-r--r--source/nsswitch/winbindd_sid.c42
-rw-r--r--source/nsswitch/winbindd_user.c38
-rw-r--r--source/nsswitch/winbindd_util.c138
-rw-r--r--source/nsswitch/winbindd_wins.c4
-rw-r--r--source/nsswitch/wins.c48
-rw-r--r--source/param/loadparm.c859
-rw-r--r--source/passdb/passdb.c109
-rw-r--r--source/passdb/pdb_get_set.c9
-rw-r--r--source/passdb/pdb_ldap.c69
-rw-r--r--source/passdb/pdb_smbpasswd.c21
-rw-r--r--source/passdb/pdb_tdb.c67
-rw-r--r--source/passdb/secrets.c14
-rw-r--r--source/printing/notify.c8
-rw-r--r--source/printing/nt_printing.c25
-rw-r--r--source/printing/pcap.c4
-rw-r--r--source/python/py_common.c2
-rw-r--r--source/python/py_lsa.c58
-rw-r--r--source/python/py_ntsec.c39
-rw-r--r--source/python/py_smb.c65
-rw-r--r--source/python/py_winbind.c16
-rw-r--r--source/rpc_client/cli_ds.c68
-rw-r--r--source/rpc_client/cli_netlogon.c9
-rw-r--r--source/rpc_client/cli_pipe.c89
-rw-r--r--source/rpc_client/cli_spoolss.c6
-rw-r--r--source/rpc_client/cli_srvsvc.c2
-rw-r--r--source/rpc_parse/parse_ds.c190
-rw-r--r--source/rpc_parse/parse_echo.c8
-rw-r--r--source/rpc_parse/parse_lsa.c2
-rw-r--r--source/rpc_parse/parse_net.c2
-rw-r--r--source/rpc_parse/parse_prs.c20
-rw-r--r--source/rpc_parse/parse_reg.c2
-rw-r--r--source/rpc_parse/parse_samr.c3
-rw-r--r--source/rpc_parse/parse_spoolss.c10
-rw-r--r--source/rpc_server/srv_dfs.c18
-rw-r--r--source/rpc_server/srv_echo.c27
-rw-r--r--source/rpc_server/srv_lsa.c46
-rw-r--r--source/rpc_server/srv_lsa_ds.c91
-rw-r--r--source/rpc_server/srv_lsa_ds_nt.c127
-rw-r--r--source/rpc_server/srv_lsa_nt.c4
-rw-r--r--source/rpc_server/srv_netlog.c15
-rw-r--r--source/rpc_server/srv_netlog_nt.c2
-rw-r--r--source/rpc_server/srv_pipe.c216
-rw-r--r--source/rpc_server/srv_pipe_hnd.c2
-rw-r--r--source/rpc_server/srv_reg.c20
-rw-r--r--source/rpc_server/srv_reg_nt.c6
-rw-r--r--source/rpc_server/srv_samr.c19
-rw-r--r--source/rpc_server/srv_samr_nt.c58
-rwxr-xr-xsource/rpc_server/srv_spoolss.c13
-rw-r--r--source/rpc_server/srv_spoolss_nt.c52
-rw-r--r--source/rpc_server/srv_srvsvc.c18
-rw-r--r--source/rpc_server/srv_wkssvc.c17
-rw-r--r--source/rpcclient/cmd_ds.c22
-rw-r--r--source/rpcclient/cmd_netlogon.c2
-rw-r--r--source/rpcclient/cmd_samr.c2
-rw-r--r--source/rpcclient/cmd_spoolss.c26
-rw-r--r--source/rpcclient/rpcclient.c92
-rw-r--r--source/sam/idmap.c7
-rw-r--r--source/sam/idmap_ldap.c352
-rw-r--r--source/sam/idmap_tdb.c69
-rw-r--r--source/sam/idmap_util.c59
-rwxr-xr-xsource/script/installmodules.sh9
-rwxr-xr-xsource/script/linkmodules.sh12
-rw-r--r--source/smbd/blocking.c498
-rw-r--r--source/smbd/change_trust_pw.c2
-rw-r--r--source/smbd/chgpasswd.c27
-rw-r--r--source/smbd/close.c4
-rw-r--r--source/smbd/fileio.c22
-rw-r--r--source/smbd/ipc.c11
-rw-r--r--source/smbd/lanman.c112
-rw-r--r--source/smbd/mangle_hash.c7
-rw-r--r--source/smbd/negprot.c20
-rw-r--r--source/smbd/notify.c6
-rw-r--r--source/smbd/ntquotas.c2
-rw-r--r--source/smbd/nttrans.c178
-rw-r--r--source/smbd/open.c33
-rw-r--r--source/smbd/oplock.c14
-rw-r--r--source/smbd/password.c56
-rw-r--r--source/smbd/process.c21
-rw-r--r--source/smbd/reply.c162
-rw-r--r--source/smbd/sec_ctx.c2
-rw-r--r--source/smbd/service.c3
-rw-r--r--source/smbd/sesssetup.c91
-rw-r--r--source/smbd/statcache.c33
-rw-r--r--source/smbd/trans2.c76
-rw-r--r--source/smbd/uid.c2
-rw-r--r--source/smbd/utmp.c10
-rw-r--r--source/smbd/vfs-wrap.c66
-rw-r--r--source/smbd/vfs.c2
-rw-r--r--source/torture/cmd_vfs.c9
-rw-r--r--source/torture/locktest.c2
-rw-r--r--source/torture/locktest2.c4
-rw-r--r--source/torture/mangle_test.c2
-rw-r--r--source/torture/masktest.c2
-rw-r--r--source/torture/nsstest.c18
-rw-r--r--source/torture/torture.c8
-rw-r--r--source/utils/log2pcaphex.c297
-rw-r--r--source/utils/net.c32
-rw-r--r--source/utils/net_ads.c8
-rw-r--r--source/utils/net_ads_cldap.c28
-rw-r--r--source/utils/net_cache.c2
-rw-r--r--source/utils/net_groupmap.c17
-rw-r--r--source/utils/net_idmap.c9
-rw-r--r--source/utils/net_rpc.c24
-rw-r--r--source/utils/net_rpc_samsync.c50
-rw-r--r--source/utils/net_time.c4
-rw-r--r--source/utils/ntlm_auth.c779
-rw-r--r--source/utils/pdbedit.c22
-rw-r--r--source/utils/profiles.c2
-rw-r--r--source/utils/smbcacls.c3
-rw-r--r--source/utils/smbcontrol.c6
-rw-r--r--source/utils/smbcquotas.c3
-rw-r--r--source/utils/smbpasswd.c15
-rw-r--r--source/utils/status.c5
-rw-r--r--source/utils/testparm.c21
-rw-r--r--source/web/statuspage.c2
-rw-r--r--source/web/swat.c56
244 files changed, 13440 insertions, 5446 deletions
diff --git a/packaging/SuSE/samba-3.0.0-msdfs.diff b/packaging/SuSE/samba-3.0.0-msdfs.diff
deleted file mode 100644
index 1e688e64c4b..00000000000
--- a/packaging/SuSE/samba-3.0.0-msdfs.diff
+++ /dev/null
@@ -1,97 +0,0 @@
---- source/param/loadparm.c Wed Oct 9 21:17:05 2002
-+++ source/param/loadparm.c Mon Oct 14 16:33:08 2002
-@@ -386,6 +386,8 @@
- BOOL bInheritPerms;
- BOOL bInheritACLS;
- BOOL bMSDfsRoot;
-+ BOOL bMSDfsProxy;
-+ char *bMSDfsLinkName;
- BOOL bUseClientDriver;
- BOOL bDefaultDevmode;
- BOOL bNTAclSupport;
-@@ -508,6 +510,8 @@
- False, /* bInheritPerms */
- False, /* bInheritACLS */
- False, /* bMSDfsRoot */
-+ False, /* bMSDfsProxy */
-+ NULL, /* bMSDfsLinkName */
- False, /* bUseClientDriver */
- False, /* bDefaultDevmode */
- True, /* bNTAclSupport */
-@@ -1079,6 +1083,8 @@
-
-
- {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
-+ {"msdfs proxy", P_BOOL, P_LOCAL, &sDefault.bMSDfsProxy, NULL, NULL, FLAG_SHARE},
-+ {"msdfs link name", P_STRING, P_LOCAL, &sDefault.bMSDfsLinkName, NULL, NULL, FLAG_SHARE},
- {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"Winbind options", P_SEP, P_SEPARATOR},
-@@ -1730,6 +1736,8 @@
- FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
- FN_LOCAL_STRING(lp_driverlocation, szPrinterDriverLocation)
- FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
-+FN_LOCAL_BOOL(lp_msdfs_proxy, bMSDfsProxy)
-+FN_LOCAL_STRING(lp_msdfs_link_name, bMSDfsLinkName)
- FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
- FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
- FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
---- source/msdfs/msdfs.c Tue Jul 2 08:34:24 2002
-+++ source/msdfs/msdfs.c Mon Oct 14 16:49:57 2002
-@@ -600,12 +600,38 @@
- int reply_size = 0;
- char *pathnamep = pathname;
-
-+ struct connection_struct conns;
-+ struct connection_struct* conn = &conns;
-+ int snum;
-+ pstring conn_path;
-+ struct dfs_path dpi;
-+
-+ struct junction_map junction2;
-+ parse_dfs_path(pathname, &dpi);
-+ pstrcpy(junction2.service_name, dpi.servicename);
-+ snum = lp_servicenumber(junction2.service_name);
-+ create_conn_struct(conn, snum, conn_path);
-+
-+
- ZERO_STRUCT(junction);
-
- /* get the junction entry */
- if (!pathnamep)
- return -1;
-
-+ if (lp_msdfs_proxy(SNUM(conn))) {
-+ DEBUG(10,("running in proxy mode\n"));
-+ pstrcpy(pathnamep, "\\");
-+ pstrcat(pathnamep, dpi.hostname);
-+ pstrcat(pathnamep, "\\");
-+ pstrcat(pathnamep, dpi.servicename);
-+ pstrcat(pathnamep, "\\");
-+ pstrcat(pathnamep, (char *) lp_msdfs_link_name(SNUM(conn)));
-+ } else {
-+ DEBUG(10,("running in normal mode\n"));
-+ }
-+
-+
- /* Trim pathname sent by client so it begins with only one backslash.
- Two backslashes confuse some dfs clients
- */
-@@ -631,6 +657,17 @@
- }
- }
-
-+ if ( lp_msdfs_proxy(SNUM(conn)) ) {
-+ DEBUG(10,("running in proxy mode\n"));
-+ pstrcpy ( pathnamep, "\\" );
-+ pstrcat ( pathnamep, dpi.hostname);
-+ pstrcat ( pathnamep, "\\" );
-+ pstrcat ( pathnamep, dpi.servicename);
-+ } else {
-+ DEBUG(10,("running in normal mode\n"));
-+ }
-+
-+
- /* create the referral depeding on version */
- DEBUG(10,("max_referral_level :%d\n",max_referral_level));
- if(max_referral_level<2 || max_referral_level>3)
diff --git a/packaging/SuSE/samba-3.0.0-net_ads.diff b/packaging/SuSE/samba-3.0.0-net_ads.diff
deleted file mode 100644
index b1224c0cef1..00000000000
--- a/packaging/SuSE/samba-3.0.0-net_ads.diff
+++ /dev/null
@@ -1,140 +0,0 @@
-diff -Nur source/utils/net.c source/utils/net.c
---- source/utils/net.c Fri Sep 27 09:42:34 2002
-+++ source/utils/net.c Tue Oct 1 12:22:00 2002
-@@ -68,6 +68,7 @@
- int opt_port = 0;
- int opt_maxusers = -1;
- char *opt_comment = "";
-+char *opt_container = "cn=Users";
- int opt_flags = -1;
- int opt_jobid = 0;
- int opt_timeout = 0;
-@@ -459,6 +460,7 @@
- {"myname", 'n', POPT_ARG_STRING, &opt_requester_name},
- {"conf", 's', POPT_ARG_STRING, &servicesf},
- {"server", 'S', POPT_ARG_STRING, &opt_host},
-+ {"container", 'c', POPT_ARG_STRING, &opt_container},
- {"comment", 'C', POPT_ARG_STRING, &opt_comment},
- {"maxusers", 'M', POPT_ARG_INT, &opt_maxusers},
- {"flags", 'F', POPT_ARG_INT, &opt_flags},
-diff -Nur source/utils/net.h source/utils/net.h
---- source/utils/net.h Tue Jun 25 04:29:09 2002
-+++ source/utils/net.h Tue Oct 1 12:19:51 2002
-@@ -38,10 +38,8 @@
-
- extern int opt_maxusers;
- extern char *opt_comment;
-+extern char *opt_container;
- extern int opt_flags;
--
--extern char *opt_comment;
--
- extern char *opt_target_workgroup;
- extern int opt_long_list_entries;
- extern int opt_reboot;
-diff -Nur source/utils/net_ads.c source/utils/net_ads.c
---- source/utils/net_ads.c Tue Sep 17 14:15:52 2002
-+++ source/utils/net_ads.c Tue Oct 1 12:33:44 2002
-@@ -255,7 +255,7 @@
- goto done;
- }
-
-- status = ads_add_user_acct(ads, argv[0], opt_comment);
-+ status = ads_add_user_acct(ads, argv[0], opt_container, opt_comment);
-
- if (!ADS_ERR_OK(status)) {
- d_printf("Could not add user %s: %s\n", argv[0],
-@@ -431,7 +431,7 @@
- goto done;
- }
-
-- status = ads_add_group_acct(ads, argv[0], opt_comment);
-+ status = ads_add_group_acct(ads, argv[0], opt_container, opt_comment);
-
- if (ADS_ERR_OK(status)) {
- d_printf("Group %s added\n", argv[0]);
-diff -Nur source/utils/net_help.c source/utils/net_help.c
---- source/utils/net_help.c Tue Sep 24 20:10:30 2002
-+++ source/utils/net_help.c Tue Oct 1 13:01:50 2002
-@@ -69,14 +69,14 @@
- "\n\tDelete specified user\n");
- d_printf("\nnet [<method>] user INFO <name> [misc. options] [targets]"\
- "\n\tList the domain groups of the specified user\n");
-- d_printf("\nnet [<method>] user ADD <name> [password] "\
-+ d_printf("\nnet [<method>] user ADD <name> [password] [-c container] "\
- "[-F user flags] [misc. options]"\
- " [targets]\n\tAdd specified user\n");
-
- net_common_methods_usage(argc, argv);
- net_common_flags_usage(argc, argv);
-- d_printf(
-- "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
-+ d_printf("\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
-+ d_printf("\t-c or --container=<container>\tLDAP container, defaults to cn=Users (for add in ADS only)\n");
- return -1;
- }
-
-@@ -85,12 +85,12 @@
- "\n\tList user groups\n\n");
- d_printf("net [<method>] group DELETE <name> [misc. options] [targets]"\
- "\n\tDelete specified group\n");
-- d_printf("\nnet [<method>] group ADD <name> [-C comment]"\
-+ d_printf("\nnet [<method>] group ADD <name> [-C comment] [-c container]"\
- " [misc. options] [targets]\n\tCreate specified group\n");
- net_common_methods_usage(argc, argv);
- net_common_flags_usage(argc, argv);
-- d_printf(
-- "\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
-+ d_printf("\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
-+ d_printf("\t-c or --container=<container>\tLDAP container, defaults to cn=Users (for add in ADS only)\n");
- return -1;
- }
-
-diff -Nur source/libads/ldap_user.c source/libads/ldap_user.c
---- source/libads/ldap_user.c Wed Aug 7 12:33:22 2002
-+++ source/libads/ldap_user.c Tue Oct 1 12:46:08 2002
-@@ -38,7 +38,7 @@
- }
-
- ADS_STATUS ads_add_user_acct(ADS_STRUCT *ads, const char *user,
-- const char *fullname)
-+ const char *container, const char *fullname)
- {
- TALLOC_CTX *ctx;
- ADS_MODLIST mods;
-@@ -57,7 +60,7 @@
-
- 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,
-+ if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", name, container,
- ads->config.bind_path)))
- goto done;
- if (!(controlstr = talloc_asprintf(ctx, "%u", UF_NORMAL_ACCOUNT)))
-@@ -80,7 +83,7 @@
- }
-
- ADS_STATUS ads_add_group_acct(ADS_STRUCT *ads, const char *group,
-- const char *comment)
-+ const char *container, const char *comment)
- {
- TALLOC_CTX *ctx;
- ADS_MODLIST mods;
-@@ -93,7 +96,7 @@
-
- status = ADS_ERROR(LDAP_NO_MEMORY);
-
-- if (!(new_dn = talloc_asprintf(ctx, "cn=%s,cn=Users,%s", group,
-+ if (!(new_dn = talloc_asprintf(ctx, "cn=%s,%s,%s", group, container,
- ads->config.bind_path)))
- goto done;
- if (!(mods = ads_init_mods(ctx)))
-@@ -102,7 +105,7 @@
- ads_mod_str(ctx, &mods, "cn", group);
- ads_mod_strlist(ctx, &mods, "objectClass",objectClass);
- ads_mod_str(ctx, &mods, "name", group);
-- if (comment)
-+ if (comment && *comment)
- ads_mod_str(ctx, &mods, "description", comment);
- ads_mod_str(ctx, &mods, "sAMAccountName", group);
- status = ads_gen_add(ads, new_dn, mods);
diff --git a/packaging/SuSE/samba-3.0.0-pdb.diff b/packaging/SuSE/samba-3.0.0-pdb.diff
deleted file mode 100644
index 4f767c4ac45..00000000000
--- a/packaging/SuSE/samba-3.0.0-pdb.diff
+++ /dev/null
@@ -1,11 +0,0 @@
---- examples/pdb/Makefile Thu Sep 5 02:11:41 2002
-+++ examples/pdb/Makefile Thu Sep 5 02:11:59 2002
-@@ -8,7 +8,7 @@
- SAMBA_INCL = ../../source/include
- UBIQX_SRC = ../../source/ubiqx
- SMBWR_SRC = ../../source/smbwrapper
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g
-+CFLAGS = -I/usr/include/heimdal -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -Wall -g
- PDB_OBJS = pdb_test.so
-
- # Default target
diff --git a/packaging/SuSE/samba-3.0.0-python.diff b/packaging/SuSE/samba-3.0.0-python.diff
deleted file mode 100644
index 8c5931e4448..00000000000
--- a/packaging/SuSE/samba-3.0.0-python.diff
+++ /dev/null
@@ -1,44 +0,0 @@
---- source/python/py_common.c 2002-12-22 03:07:40.000000000 +0100
-+++ source/python/py_common.c 2002-11-29 11:50:22.000000000 +0100
-@@ -45,9 +45,6 @@
-
- void py_samba_init(void)
- {
-- extern pstring global_myname;
-- char *p;
--
- if (initialised)
- return;
-
-@@ -59,11 +56,7 @@
- /* Misc other stuff */
-
- load_interfaces();
--
-- fstrcpy(global_myname, myhostname());
-- p = strchr(global_myname, '.');
-- if (p)
-- *p = 0;
-+ init_names();
-
- initialised = True;
- }
---- source/python/py_smb.c 2002-11-27 03:54:20.000000000 +0100
-+++ source/python/py_smb.c 2002-11-29 11:50:22.000000000 +0100
-@@ -61,7 +61,6 @@
- static char *kwlist[] = { "called", "calling", NULL };
- char *calling_name = NULL, *called_name;
- struct nmb_name calling, called;
-- extern pstring global_myname;
- BOOL result;
-
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s", kwlist, &called_name,
-@@ -69,7 +68,7 @@
- return NULL;
-
- if (!calling_name)
-- calling_name = global_myname;
-+ calling_name = global_myname();
-
- make_nmb_name(&calling, calling_name, 0x00);
- make_nmb_name(&called, called_name, 0x20);
diff --git a/packaging/SuSE/samba-3.0.0-vscan.diff b/packaging/SuSE/samba-3.0.0-vscan.diff
deleted file mode 100644
index cb860e3ffb4..00000000000
--- a/packaging/SuSE/samba-3.0.0-vscan.diff
+++ /dev/null
@@ -1,80 +0,0 @@
---- examples/VFS/samba-vscan-0.3.1/fprot/Makefile 2002-11-26 15:20:17.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.1/fprot/Makefile 2002-12-19 13:26:19.000000000 +0100
-@@ -14,7 +14,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/heimdal
- VFS_OBJS = vscan-fprotd.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c vscan-fprotd.c vscan-fprotd_core.c vscan-fprotd.h vscan-fprotd_core.h
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-fprotd.lo vscan-fprotd_core.lo
---- examples/VFS/samba-vscan-0.3.1/include/vscan-global.h 2002-11-25 16:48:10.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.1/include/vscan-global.h 2002-12-19 13:26:34.000000000 +0100
-@@ -93,7 +93,7 @@
- */
-
- #ifndef SAMBA_VERSION_MAJOR
--# define SAMBA_VERSION_MAJOR 2
-+# define SAMBA_VERSION_MAJOR 3
- #endif
-
- #ifndef SAMBA_VERSION_MINOR
---- examples/VFS/samba-vscan-0.3.1/kaspersky/Makefile 2002-11-28 17:40:35.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.1/kaspersky/Makefile 2002-12-19 13:27:23.000000000 +0100
-@@ -23,9 +23,9 @@
- VFS_OBJS = vscan-kavp.so
-
- ifdef USE_DEBUG
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/heimdal
- else
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/heimdal
- endif
-
- ifndef USE_KAVPSHAREDLIB
---- examples/VFS/samba-vscan-0.3.1/mks/Makefile 2002-11-26 16:29:55.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.1/mks/Makefile 2002-12-19 13:27:53.000000000 +0100
-@@ -13,7 +13,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/heimdal
- VFS_OBJS = vscan-mksd.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c vscan-mksd.c vscan-mksd_core.c vscan-mksd.h vscan-mksd_core.h mks.h mks_c.c
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-mksd.lo vscan-mksd_core.lo mks_c.lo
---- examples/VFS/samba-vscan-0.3.1/openantivirus/Makefile 2002-11-27 19:24:03.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.1/openantivirus/Makefile 2002-12-19 13:28:10.000000000 +0100
-@@ -15,7 +15,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/heimdal
- VFS_OBJS = vscan-oav.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c vscan-oav.c vscan-oav_core.c vscan-oav.h vscan-oav_core.h
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-oav.lo vscan-oav_core.lo
---- examples/VFS/samba-vscan-0.3.1/sophos/Makefile 2002-11-27 19:24:03.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.1/sophos/Makefile 2002-12-19 13:29:20.000000000 +0100
-@@ -15,7 +15,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/heimdal
- VFS_OBJS = vscan-sophos.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c vscan-sophos.c vscan-sophos_core.c vscan-sophos.h vscan-sophos_core.h
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-sophos.lo vscan-sophos_core.lo
---- examples/VFS/samba-vscan-0.3.1/trend/Makefile 2002-11-27 19:24:03.000000000 +0100
-+++ examples/VFS/samba-vscan-0.3.1/trend/Makefile 2002-12-19 13:29:31.000000000 +0100
-@@ -15,7 +15,7 @@
- SMBWR_SRC = ../../../../source/smbwrapper
- SMBVS_INCL = ../include
- SMBVS_GLB = ../global
--CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
-+CFLAGS = -I$(SAMBA_SRC) -I$(SAMBA_INCL) -I$(UBIQX_SRC) -I$(SMBWR_SRC) -I$(SMBVS_INCL) -Wall -g -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/heimdal
- VFS_OBJS = vscan-trend.so
- SOURCES = $(SMBVS_GLB)/vscan-functions.c $(SMBVS_GLB)/vscan-message.c $(SMBVS_GLB)/vscan-quarantine.c vscan-trend.c vscan-trend_core.c vscan-trend.h vscan-trend_core.h
- OBJS = vscan-functions.lo vscan-message.lo vscan-quarantine.lo vscan-trend.lo vscan-trend_core.lo
diff --git a/packaging/SuSE/samba-vscan-0.3.1.tar.bz2 b/packaging/SuSE/samba-vscan-0.3.1.tar.bz2
deleted file mode 100644
index 56392793744..00000000000
--- a/packaging/SuSE/samba-vscan-0.3.1.tar.bz2
+++ /dev/null
Binary files differ
diff --git a/packaging/SuSE/samba-vscan-0.3.2b.tar.bz2 b/packaging/SuSE/samba-vscan-0.3.2b.tar.bz2
deleted file mode 100755
index 2680bed82f0..00000000000
--- a/packaging/SuSE/samba-vscan-0.3.2b.tar.bz2
+++ /dev/null
Binary files differ
diff --git a/source/Makefile.in b/source/Makefile.in
index 73ff436c6f5..97b61c93ec6 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -3,7 +3,7 @@
# Copyright Andrew Tridgell 1992-1998
# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
# Copyright Andrew Bartlett 2002
-# Copyright (C) 2003 Anthony Liguori <aliguor@us.ibm.com>
+# Copyright (C) 2003 Jim McDonough <aliguor@us.ibm.com>
# Copyright (C) 2002-2003 Jelmer Vernooij <jelmer@samba.org>
###########################################################################
@@ -32,7 +32,6 @@ AUTHLIBS=@AUTHLIBS@
ACLLIBS=@ACLLIBS@
PASSDBLIBS=@PASSDBLIBS@
IDMAP_LIBS=@IDMAP_LIBS@
-ADSLIBS=@ADSLIBS@
KRB5LIBS=@KRB5_LIBS@
LDAPLIBS=@LDAP_LIBS@
@@ -165,7 +164,7 @@ SMBLDAP_OBJ = @SMBLDAP@
LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \
lib/getsmbpass.o lib/interface.o lib/md4.o \
- lib/interfaces.o lib/pidfile.o lib/replace.o \
+ lib/interfaces.o lib/pidfile.o lib/replace.o lib/replace1.o \
lib/signal.o lib/system.o lib/sendfile.o lib/time.o \
lib/ufc.o lib/genrand.o lib/username.o \
lib/util_getent.o lib/util_pw.o lib/access.o lib/smbrun.o \
@@ -176,7 +175,7 @@ LIB_OBJ = lib/charcnv.o lib/debug.o lib/fault.o \
lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \
lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \
lib/ms_fnmatch.o lib/select.o lib/messages.o \
- lib/tallocmsg.o lib/dmallocmsg.o \
+ lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
lib/md5.o lib/hmacmd5.o lib/iconv.o lib/smbpasswd.o \
nsswitch/wb_client.o nsswitch/wb_common.o \
lib/pam_errors.o intl/lang_tdb.o lib/account_pol.o \
@@ -216,7 +215,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \
libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \
libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \
- libsmb/clistr.o libsmb/smb_signing.o \
+ libsmb/clistr.o \
libsmb/cliquota.o libsmb/clifsinfo.o \
libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \
@@ -243,6 +242,8 @@ RPC_SAMR_OBJ = rpc_server/srv_samr.o rpc_server/srv_samr_nt.o \
RPC_REG_OBJ = rpc_server/srv_reg.o rpc_server/srv_reg_nt.o
+RPC_LSA_DS_OBJ = rpc_server/srv_lsa_ds.o rpc_server/srv_lsa_ds_nt.o
+
RPC_SVC_OBJ = rpc_server/srv_srvsvc.o rpc_server/srv_srvsvc_nt.o
RPC_WKS_OBJ = rpc_server/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o
@@ -300,6 +301,8 @@ VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o
VFS_FAKE_PERMS_OBJ = modules/vfs_fake_perms.o
VFS_RECYCLE_OBJ = modules/vfs_recycle.o
VFS_NETATALK_OBJ = modules/vfs_netatalk.o
+VFS_DEFAULT_QUOTA_OBJ = modules/vfs_default_quota.o
+VFS_READONLY_OBJ = modules/vfs_readonly.o modules/getdate.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
@@ -389,24 +392,27 @@ SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
- $(POPT_LIB_OBJ) $(SMBLDAP_OBJ)
+ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o
SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
$(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ)
+ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) \
+ $(SECRETS_OBJ) $(LIBSAMBA_OBJ) lib/dummyroot.o libsmb/errormap.o
SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
$(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) \
- printing/notify.o printing/printing_db.o
+ $(SECRETS_OBJ) $(LIBSAMBA_OBJ) \
+ printing/notify.o printing/printing_db.o lib/dummyroot.o libsmb/errormap.o
SMBTREE_OBJ = utils/smbtree.o $(LOCKING_OBJ) $(PARAM_OBJ) \
$(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) \
- $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ)
+ $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ)
TESTPARM_OBJ = utils/testparm.o \
- $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ)
+ $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ) \
+ $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
$(LIB_OBJ)
@@ -414,11 +420,11 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
$(UBIQX_OBJ) $(LIB_OBJ) $(KRBCLIENT_OBJ) \
- $(SMBLDAP_OBJ)
+ $(SMBLDAP_OBJ) lib/dummyroot.o
PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \
- $(POPT_LIB_OBJ) $(SMBLDAP_OBJ)
+ $(POPT_LIB_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o
RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \
@@ -432,9 +438,9 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
$(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
- $(SMBLDAP_OBJ) $(DCUTIL_OBJ)
+ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o
-PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/snprintf.po
+PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/replace1.po lib/snprintf.po
SMBW_OBJ1 = smbwrapper/smbw.o \
smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \
@@ -460,7 +466,7 @@ LIBBIGBALLOFMUD_MAJOR = 0
LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
- $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ)
+ $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o
LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.po)
@@ -468,7 +474,7 @@ CLIENT_OBJ1 = client/client.o client/clitar.o
CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
$(LIB_OBJ) $(KRBCLIENT_OBJ) \
- $(READLINE_OBJ) $(POPT_LIB_OBJ)
+ $(READLINE_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ)
NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \
utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
@@ -480,10 +486,10 @@ NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
$(LIBMSRPC_OBJ) $(IDMAP_OBJ) \
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
- $(SMBLDAP_OBJ) $(DCUTIL_OBJ)
+ $(SMBLDAP_OBJ) $(DCUTIL_OBJ) lib/dummyroot.o lib/server_mutex.o
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
- $(LIB_OBJ) $(KRBCLIENT_OBJ)
+ $(LIB_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ)
MOUNT_OBJ = client/smbmount.o \
$(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
@@ -493,13 +499,13 @@ MNT_OBJ = client/smbmnt.o
UMOUNT_OBJ = client/smbumount.o
NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBNMB_OBJ) \
- $(LIB_OBJ) $(POPT_LIB_OBJ)
+ $(LIB_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/utable.o \
torture/denytest.o torture/mangle_test.o
SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \
- $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+ $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(SECRETS_OBJ)
MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ)
@@ -517,6 +523,8 @@ VFSTEST_OBJ = torture/cmd_vfs.o torture/vfstest.o $(SMBD_OBJ_BASE) $(READLINE_OB
SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_OBJ) $(UBIQX_OBJ) $(POPT_LIB_OBJ)
+LOG2PCAP_OBJ = utils/log2pcaphex.o
+
LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
@@ -557,9 +565,9 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(PASSDB_OBJ) $(GROUPDB_OBJ) $(MSDFS_OBJ) \
$(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \
$(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
- $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \
+ $(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) $(RPC_LSA_DS_OBJ) \
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
- $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ)
+ $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o
WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) \
$(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ)
@@ -601,21 +609,25 @@ WINBINDD_OBJ = \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
$(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \
$(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
- $(DCUTIL_OBJ) $(IDMAP_OBJ)
+ $(DCUTIL_OBJ) $(IDMAP_OBJ) lib/dummyroot.o
WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
$(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
-WINBIND_NSS_OBJ = nsswitch/wb_common.o @WINBIND_NSS_EXTRA_OBJS@
+WINBIND_NSS_OBJ = nsswitch/wb_common.o lib/replace1.o @WINBIND_NSS_EXTRA_OBJS@
-WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.po)
+WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.po) lib/snprintf.po
POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o $(TDBBASE_OBJ)
-NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ)
+NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \
+ libsmb/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \
+ libads/kerberos_verify.o passdb/secrets.o lib/server_mutex.o \
+ libads/authdata.o rpc_parse/parse_prs.o rpc_parse/parse_misc.o \
+ libsmb/doserr.o
######################################################################
# now the rules...
@@ -692,7 +704,6 @@ MAKEDIR = || exec false; \
# rebuild it's a bit hard.
dynconfig.o: dynconfig.c Makefile
- @$(MAKE) modules_clean
@echo Compiling $*.c
@$(CC) $(FLAGS) $(PATH_FLAGS) -c $< -o $@
@@ -727,12 +738,12 @@ bin/.dummy:
bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(ADSLIBS) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \
+ @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(KRB5LIBS) $(LDAPLIBS) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \
$(AUTHLIBS) $(ACLLIBS) $(PASSDBLIBS) $(LIBS) @POPTLIBS@
bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(ADSLIBS)
+ @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
bin/wrepld@EXEEXT@: $(WREPL_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -741,19 +752,19 @@ bin/wrepld@EXEEXT@: $(WREPL_OBJ) @BUILD_POPT@ bin/.dummy
bin/swat@EXEEXT@: $(SWAT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(DYNEXP) $(PRINTLIBS) \
- $(AUTHLIBS) $(LIBS) $(PASSDBLIBS) @POPTLIBS@ $(KRB5LIBS)
+ $(AUTHLIBS) $(LIBS) $(PASSDBLIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(ADSLIBS)
+ @$(CC) $(FLAGS) -o $@ $(PASSDBLIBS) $(RPCCLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(ADSLIBS)
+ @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
bin/net@EXEEXT@: $(NET_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(ADSLIBS) $(PASSDBLIBS)
+ @$(CC) $(FLAGS) -o $@ $(NET_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS) $(PASSDBLIBS)
bin/profiles@EXEEXT@: $(PROFILES_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -789,19 +800,22 @@ bin/testprns@EXEEXT@: $(TESTPRNS_OBJ) bin/.dummy
bin/smbstatus@EXEEXT@: $(STATUS_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
+ @POPTLIBS@
bin/smbcontrol@EXEEXT@: $(SMBCONTROL_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) -DUSING_SMBCONTROL $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@
+ @$(CC) -DUSING_SMBCONTROL $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(DYNEXP) \
+ $(LDFLAGS) $(LIBS) \
+ @POPTLIBS@
bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(PASSDBLIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(PASSDBLIBS) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -817,7 +831,7 @@ bin/nmblookup@EXEEXT@: $(NMBLOOKUP_OBJ) @BUILD_POPT@ bin/.dummy
bin/smbtorture@EXEEXT@: $(SMBTORTURE_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAPLIBS) $(SECRETS_OBJ)
bin/talloctort@EXEEXT@: $(TALLOCTORT_OBJ) bin/.dummy
@echo Linking $@
@@ -825,11 +839,11 @@ bin/talloctort@EXEEXT@: $(TALLOCTORT_OBJ) bin/.dummy
bin/masktest@EXEEXT@: $(MASKTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
+ @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS) $(SECRETS_OBJ)
bin/msgtest@EXEEXT@: $(MSGTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
+ @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/smbcacls@EXEEXT@: $(SMBCACLS_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -855,6 +869,10 @@ bin/smbiconv@EXEEXT@: $(SMBICONV_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SMBICONV_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@
+bin/log2pcap@EXEEXT@: $(LOG2PCAP_OBJ) @BUILD_POPT@ bin/.dummy
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(LOG2PCAP_OBJ) $(LDFLAGS) @POPTLIBS@ $(LIBS)
+
bin/locktest2@EXEEXT@: $(LOCKTEST2_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
@@ -873,7 +891,7 @@ bin/smbfilter@EXEEXT@: $(SMBFILTER_OBJ) bin/.dummy
bin/smbw_sample@EXEEXT@: $(SMBW_OBJ) utils/smbw_sample.o bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBW_OBJ) utils/smbw_sample.o $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBW_OBJ) utils/smbw_sample.o $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/smbsh@EXEEXT@: $(SMBSH_OBJ) bin/.dummy
@echo Linking $@
@@ -882,12 +900,14 @@ bin/smbsh@EXEEXT@: $(SMBSH_OBJ) bin/.dummy
bin/smbwrapper.@SHLIBEXT@: $(PICOBJS) bin/.dummy
@echo Linking shared library $@
@$(SHLD) $(LDSHFLAGS) -o $@ $(PICOBJS) $(LIBS) \
- @SONAMEFLAG@`basename $@` $(KRB5LIBS)
+ $(KRB5LIBS) $(LDAPLIBS) \
+ @SONAMEFLAG@`basename $@`
bin/libsmbclient.@SHLIBEXT@: $(LIBSMBCLIENT_PICOBJS)
@echo Linking libsmbclient shared library $@
@$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \
- $(KRB5LIBS) @SONAMEFLAG@`basename $@`.$(LIBSMBCLIENT_MAJOR)
+ $(KRB5LIBS) $(LDAPLIBS) \
+ @SONAMEFLAG@`basename $@`.$(LIBSMBCLIENT_MAJOR)
bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS)
@echo Linking libsmbclient non-shared library $@
@@ -897,7 +917,8 @@ bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS)
bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS)
@echo Linking bigballofmud shared library $@
@$(SHLD) $(LDSHFLAGS) -o $@ $(LIBBIGBALLOFMUD_PICOBJS) $(LIBS) \
- @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR) $(PASSDBLIBS) $(IDMAP_LIBS) $(ADSLIBS)
+ $(PASSDBLIBS) $(IDMAP_LIBS) $(KRB5LIBS) $(LDAPLIBS) \
+ @SONAMEFLAG@`basename $@`.$(LIBBIGBALLOFMUD_MAJOR)
ln -snf libbigballofmud.so bin/libbigballofmud.so.0
# It would be nice to build a static bigballofmud too, but when I try
@@ -937,6 +958,11 @@ bin/librpc_winreg.@SHLIBEXT@: $(RPC_REG_OBJ)
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_REG_OBJ) -lc \
@SONAMEFLAG@`basename $@`
+bin/librpc_lsa_ds.@SHLIBEXT@: $(RPC_LSA_DS_OBJ)
+ @echo "Linking $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_LSA_DS_OBJ) -lc \
+ @SONAMEFLAG@`basename $@`
+
bin/librpc_spoolss.@SHLIBEXT@: $(RPC_SPOOLSS_OBJ)
@echo "Linking $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_SPOOLSS_OBJ) -lc \
@@ -963,7 +989,8 @@ bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy
@WINBIND_WINS_NSS@: $(WINBIND_WINS_NSS_PICOBJS)
@echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_WINS_NSS_PICOBJS) -lc \
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_WINS_NSS_PICOBJS) \
+ $(KRBCLIENT_OBJ) $(LDAPLIBS) $(KRB5LIBS) -lc \
@SONAMEFLAG@`basename $@`
nsswitch/pam_winbind.@SHLIBEXT@: $(PAM_WINBIND_OBJ) bin/.dummy
@@ -983,7 +1010,7 @@ bin/domain.@SHLIBEXT@: $(AUTH_DOMAIN_OBJ:.o=.po)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_DOMAIN_OBJ:.o=.po) @SONAMEFLAG@`basename $@`
-bin/server.@SHLIBEXT@: $(AUTH_SERVER_OBJ:.o=.po)
+bin/smbserver.@SHLIBEXT@: $(AUTH_SERVER_OBJ:.o=.po)
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(AUTH_SERVER_OBJ:.o=.po) @SONAMEFLAG@`basename $@`
@@ -1054,6 +1081,16 @@ bin/fake_perms.@SHLIBEXT@: $(VFS_FAKE_PERMS_OBJ:.o=.po)
@$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_FAKE_PERMS_OBJ:.o=.po) \
@SONAMEFLAG@`basename $@`
+bin/default_quota.@SHLIBEXT@: $(VFS_DEFAULT_QUOTA_OBJ:.o=.po)
+ @echo "Building plugin $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_DEFAULT_QUOTA_OBJ:.o=.po) \
+ @SONAMEFLAG@`basename $@`
+
+bin/readonly.@SHLIBEXT@: $(VFS_READONLY_OBJ:.o=.po)
+ @echo "Building plugin $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(VFS_READONLY_OBJ:.o=.po) \
+ @SONAMEFLAG@`basename $@`
+
bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(LINK) -o $@ $(WBINFO_OBJ) $(LIBS) @POPTLIBS@
@@ -1062,7 +1099,7 @@ bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
$(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(LINK) -o $@ $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
- $(UBIQX_OBJ) $(LIBS) @POPTLIBS@
+ $(UBIQX_OBJ) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ)
@echo "Linking shared library $@"
@@ -1118,6 +1155,13 @@ installmodules: modules installdirs
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(IDMAPLIBDIR) $(IDMAP_MODULES)
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(CHARSETLIBDIR) $(CHARSET_MODULES)
@$(SHELL) $(srcdir)/script/installmodules.sh $(INSTALLPERMS) $(DESTDIR)$(BASEDIR) $(DESTDIR)$(AUTHLIBDIR) $(AUTH_MODULES)
+ @# These symlinks are required for the 'probing' of modules.
+ @# This mechanism should go at some point..
+ @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(PDBLIBDIR) ldapsam.@SHLIBEXT@ ldapsam_compat.@SHLIBEXT@
+ @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) rhosts.@SHLIBEXT@ hostsequiv.@SHLIBEXT@
+ @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) sam.@SHLIBEXT@ sam_ignoredomain.@SHLIBEXT@
+ @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) domain.@SHLIBEXT@ trustdomain.@SHLIBEXT@ ntdomain.@SHLIBEXT@
+ @$(SHELL) $(srcdir)/script/linkmodules.sh $(DESTDIR)$(AUTHLIBDIR) builtin.@SHLIBEXT@ guest.@SHLIBEXT@ fixed_challenge.@SHLIBEXT@ name_to_ntstatus.@SHLIBEXT@
installscripts: installdirs
@$(SHELL) $(srcdir)/script/installscripts.sh $(INSTALLPERMS) $(DESTDIR)$(BINDIR) $(SCRIPTS)
@@ -1138,7 +1182,7 @@ installclientlib: installdirs libsmbclient
PYTHON_OBJS = $(PARAM_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \
$(UBIQX_OBJ) $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(SECRETS_OBJ) $(KRBCLIENT_OBJ)
+ $(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) lib/dummyroot.o
PYTHON_PICOBJS = $(PYTHON_OBJS:.o=.po)
@@ -1149,7 +1193,7 @@ python_ext: $(PYTHON_PICOBJS)
fi
PYTHON_OBJS="$(PYTHON_PICOBJS)" \
PYTHON_CFLAGS="$(CFLAGS) $(CPPFLAGS) $(FLAGS)" \
- LIBS="$(LIBS) $(PASSDBLIBS) $(IDMAP_LIBS) $(KRB5LIBS)" \
+ LIBS="$(LIBS) $(PASSDBLIBS) $(IDMAP_LIBS) $(KRB5LIBS) $(LDAPLIBS)" \
$(PYTHON) python/setup.py build
python_install: $(PYTHON_PICOBJS)
@@ -1185,7 +1229,7 @@ showlayout:
@echo " mandir: $(MANDIR)"
-uninstall: uninstallman uninstallbin uninstallscripts
+uninstall: uninstallman uninstallbin uninstallscripts uninstallmodules
uninstallman:
@$(SHELL) $(srcdir)/script/uninstallman.sh $(DESTDIR)$(MANDIR) $(srcdir) $(man_langs)
@@ -1212,11 +1256,6 @@ clean: delheaders python_clean
$(TOPFILES) $(BIN_PROGS) $(SBIN_PROGS) $(MODULES) $(TORTURE_PROGS) \
$(LIBSMBCLIENT) $(EVERYTHING_PROGS) .headers.stamp
-# This is quite ugly actually.. But we need to make
-# sure the changes to include/config.h are used.
-modules_clean:
- @-rm -f auth/auth.o passdb/pdb_interface.o smbd/server.o lib/iconv.o smbd/vfs.o sam/idmap.o
-
# Making this target will just make sure that the prototype files
# exist, not necessarily that they are up to date. Since they're
# removed by "make clean" this will always be run when you do anything
diff --git a/source/aclocal.m4 b/source/aclocal.m4
index 21358e2a711..88f055f9ba0 100644
--- a/source/aclocal.m4
+++ b/source/aclocal.m4
@@ -71,6 +71,7 @@ AC_DEFUN(SMB_SUBSYSTEM,
AC_SUBST($1_STATIC)
AC_SUBST($1_MODULES)
AC_DEFINE_UNQUOTED([static_init_]translit([$1], [A-Z], [a-z]), [{$init_static_modules_]translit([$1], [A-Z], [a-z])[}], [Static init functions])
+ ifelse([$2], , :, [touch $2])
])
dnl AC_PROG_CC_FLAG(flag)
@@ -111,6 +112,113 @@ AC_DEFUN(AC_LIBTESTFUNC,
esac
])
+# AC_CHECK_LIB_EXT(LIBRARY, [EXT_LIBS], [FUNCTION],
+# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND],
+# [ADD-ACTION-IF-FOUND],[OTHER-LIBRARIES])
+# ------------------------------------------------------
+#
+# Use a cache variable name containing both the library and function name,
+# because the test really is for library $1 defining function $3, not
+# just for library $1. Separate tests with the same $1 and different $3s
+# may have different results.
+#
+# Note that using directly AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$3])
+# is asking for troubles, since AC_CHECK_LIB($lib, fun) would give
+# ac_cv_lib_$lib_fun, which is definitely not what was meant. Hence
+# the AS_LITERAL_IF indirection.
+#
+# FIXME: This macro is extremely suspicious. It DEFINEs unconditionnally,
+# whatever the FUNCTION, in addition to not being a *S macro. Note
+# that the cache does depend upon the function we are looking for.
+#
+# It is on purpose we used `ac_check_lib_ext_save_LIBS' and not just
+# `ac_save_LIBS': there are many macros which don't want to see `LIBS'
+# changed but still want to use AC_CHECK_LIB_EXT, so they save `LIBS'.
+# And ``ac_save_LIBS' is too tempting a name, so let's leave them some
+# freedom.
+AC_DEFUN([AC_CHECK_LIB_EXT],
+[
+AH_CHECK_LIB_EXT([$1])
+ac_check_lib_ext_save_LIBS=$LIBS
+LIBS="-l$1 $$2 $7 $LIBS"
+AS_LITERAL_IF([$1],
+ [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1])],
+ [AS_VAR_PUSHDEF([ac_Lib_ext], [ac_cv_lib_ext_$1''])])dnl
+
+m4_ifval([$3],
+ [
+ AH_CHECK_FUNC_EXT([$3])
+ AS_LITERAL_IF([$1],
+ [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1_$3])],
+ [AS_VAR_PUSHDEF([ac_Lib_func], [ac_cv_lib_ext_$1''_$3])])dnl
+ AC_CACHE_CHECK([for $3 in -l$1], ac_Lib_func,
+ [AC_TRY_LINK_FUNC($3,
+ [AS_VAR_SET(ac_Lib_func, yes);
+ AS_VAR_SET(ac_Lib_ext, yes)],
+ [AS_VAR_SET(ac_Lib_func, no);
+ AS_VAR_SET(ac_Lib_ext, no)])
+ ])
+ AS_IF([test AS_VAR_GET(ac_Lib_func) = yes],
+ [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$3))])dnl
+ AS_VAR_POPDEF([ac_Lib_func])dnl
+ ],[
+ AC_CACHE_CHECK([for -l$1], ac_Lib_ext,
+ [AC_TRY_LINK_FUNC([main],
+ [AS_VAR_SET(ac_Lib_ext, yes)],
+ [AS_VAR_SET(ac_Lib_ext, no)])
+ ])
+ ])
+LIBS=$ac_check_lib_ext_save_LIBS
+
+AS_IF([test AS_VAR_GET(ac_Lib_ext) = yes],
+ [m4_default([$4],
+ [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1))
+ case "$$2" in
+ *-l$1*)
+ ;;
+ *)
+ $2="$$2 -l$1"
+ ;;
+ esac])
+ [$6]
+ ],
+ [$5])dnl
+AS_VAR_POPDEF([ac_Lib_ext])dnl
+])# AC_CHECK_LIB_EXT
+
+# AH_CHECK_LIB_EXT(LIBNAME)
+# ---------------------
+m4_define([AH_CHECK_LIB_EXT],
+[AH_TEMPLATE(AS_TR_CPP(HAVE_LIB$1),
+ [Define to 1 if you have the `]$1[' library (-l]$1[).])])
+
+# AC_CHECK_FUNCS_EXT(FUNCTION, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+# -----------------------------------------------------------------
+dnl check for a function in a $LIBS and $OTHER_LIBS libraries variable.
+dnl AC_CHECK_FUNC_EXT(func,OTHER_LIBS,IF-TRUE,IF-FALSE)
+AC_DEFUN([AC_CHECK_FUNC_EXT],
+[
+ AH_CHECK_FUNC_EXT($1)
+ ac_check_func_ext_save_LIBS=$LIBS
+ LIBS="$2 $LIBS"
+ AS_VAR_PUSHDEF([ac_var], [ac_cv_func_ext_$1])dnl
+ AC_CACHE_CHECK([for $1], ac_var,
+ [AC_LINK_IFELSE([AC_LANG_FUNC_LINK_TRY([$1])],
+ [AS_VAR_SET(ac_var, yes)],
+ [AS_VAR_SET(ac_var, no)])])
+ LIBS=$ac_check_func_ext_save_LIBS
+ AS_IF([test AS_VAR_GET(ac_var) = yes],
+ [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1])) $3],
+ [$4])dnl
+AS_VAR_POPDEF([ac_var])dnl
+])# AC_CHECK_FUNC
+
+# AH_CHECK_FUNC_EXT(FUNCNAME)
+# ---------------------
+m4_define([AH_CHECK_FUNC_EXT],
+[AH_TEMPLATE(AS_TR_CPP(HAVE_$1),
+ [Define to 1 if you have the `]$1[' function.])])
+
dnl Define an AC_DEFINE with ifndef guard.
dnl AC_N_DEFINE(VARIABLE [, VALUE])
define(AC_N_DEFINE,
@@ -341,8 +449,6 @@ AC_ARG_WITH(mysql-prefix,[ --with-mysql-prefix=PFX Prefix where MYSQL is inst
mysql_prefix="$withval", mysql_prefix="")
AC_ARG_WITH(mysql-exec-prefix,[ --with-mysql-exec-prefix=PFX Exec prefix where MYSQL is installed (optional)],
mysql_exec_prefix="$withval", mysql_exec_prefix="")
-AC_ARG_ENABLE(mysqltest, [ --disable-mysqltest Do not try to compile and run a test MYSQL program],
- , enable_mysqltest=yes)
if test x$mysql_exec_prefix != x ; then
mysql_args="$mysql_args --exec-prefix=$mysql_exec_prefix"
@@ -359,143 +465,21 @@ AC_ARG_ENABLE(mysqltest, [ --disable-mysqltest Do not try to compile and
AC_REQUIRE([AC_CANONICAL_TARGET])
AC_PATH_PROG(MYSQL_CONFIG, mysql_config, no)
- min_mysql_version=ifelse([$1], ,0.11.0,$1)
- AC_MSG_CHECKING(for MYSQL - version >= $min_mysql_version)
+ AC_MSG_CHECKING(for MYSQL)
no_mysql=""
if test "$MYSQL_CONFIG" = "no" ; then
- no_mysql=yes
+ MYSQL_CFLAGS=""
+ MYSQL_LIBS=""
+ AC_MSG_RESULT(no)
+ ifelse([$2], , :, [$2])
else
MYSQL_CFLAGS=`$MYSQL_CONFIG $mysqlconf_args --cflags | sed -e "s/'//g"`
MYSQL_LIBS=`$MYSQL_CONFIG $mysqlconf_args --libs | sed -e "s/'//g"`
-
- mysql_major_version=`$MYSQL_CONFIG $mysql_args --version | \
- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
- mysql_minor_version=`$MYSQL_CONFIG $mysql_args --version | \
- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
- mysql_micro_version=`$MYSQL_CONFIG $mysql_config_args --version | \
- sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
- if test "x$enable_mysqltest" = "xyes" ; then
- ac_save_CFLAGS="$CFLAGS"
- ac_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $MYSQL_CFLAGS"
- LIBS="$LIBS $MYSQL_LIBS"
-dnl
-dnl Now check if the installed MYSQL is sufficiently new. (Also sanity
-dnl checks the results of mysql_config to some extent
-dnl
- rm -f conf.mysqltest
- AC_TRY_RUN([
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <mysql.h>
-
-char*
-my_strdup (char *str)
-{
- char *new_str;
-
- if (str)
- {
- new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
- strcpy (new_str, str);
- }
- else
- new_str = NULL;
-
- return new_str;
-}
-
-int main (int argc, char *argv[])
-{
-int major, minor, micro;
- char *tmp_version;
-
- /* This hangs on some systems (?)
- system ("touch conf.mysqltest");
- */
- { FILE *fp = fopen("conf.mysqltest", "a"); if ( fp ) fclose(fp); }
-
- /* HP/UX 9 (%@#!) writes to sscanf strings */
- tmp_version = my_strdup("$min_mysql_version");
- if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
- printf("%s, bad version string\n", "$min_mysql_version");
- exit(1);
- }
-
- if (($mysql_major_version > major) ||
- (($mysql_major_version == major) && ($mysql_minor_version > minor)) ||
- (($mysql_major_version == major) && ($mysql_minor_version == minor) && ($mysql_micro_version >= micro)))
- {
- return 0;
- }
- else
- {
- printf("\n*** 'mysql_config --version' returned %d.%d.%d, but the minimum version\n", $mysql_major_version, $mysql_minor_version, $mysql_micro_version);
- printf("*** of MYSQL required is %d.%d.%d. If mysql_config is correct, then it is\n", major, minor, micro);
- printf("*** best to upgrade to the required version.\n");
- printf("*** If mysql_config was wrong, set the environment variable MYSQL_CONFIG\n");
- printf("*** to point to the correct copy of mysql_config, and remove the file\n");
- printf("*** config.cache before re-running configure\n");
- return 1;
- }
-}
-
-],, no_mysql=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
- fi
- fi
- if test "x$no_mysql" = x ; then
- AC_MSG_RESULT(yes)
- ifelse([$2], , :, [$2])
- else
- AC_MSG_RESULT(no)
- if test "$MYSQL_CONFIG" = "no" ; then
- echo "*** The mysql_config script installed by MYSQL could not be found"
- echo "*** If MYSQL was installed in PREFIX, make sure PREFIX/bin is in"
- echo "*** your path, or set the MYSQL_CONFIG environment variable to the"
- echo "*** full path to mysql_config."
- else
- if test -f conf.mysqltest ; then
- :
- else
- echo "*** Could not run MYSQL test program, checking why..."
- CFLAGS="$CFLAGS $MYSQL_CFLAGS"
- LIBS="$LIBS $MYSQL_LIBS"
- AC_TRY_LINK([
-#include <stdio.h>
-#include <mysql.h>
-
-int main(int argc, char *argv[])
-{ return 0; }
-#undef main
-#define main K_and_R_C_main
-], [ return 0; ],
- [ echo "*** The test program compiled, but did not run. This usually means"
- echo "*** that the run-time linker is not finding MYSQL or finding the wrong"
- echo "*** version of MYSQL. If it is not finding MYSQL, you'll need to set your"
- echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
- echo "*** to the installed location Also, make sure you have run ldconfig if that"
- echo "*** is required on your system"
- echo "***"
- echo "*** If you have an old version installed, it is best to remove it, although"
- echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
- [ echo "*** The test program failed to compile or link. See the file config.log for the"
- echo "*** exact error that occured. This usually means MYSQL was incorrectly installed"
- echo "*** or that you have moved MYSQL since it was installed. In the latter case, you"
- echo "*** may want to edit the mysql_config script: $MYSQL_CONFIG" ])
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
- fi
- fi
- MYSQL_CFLAGS=""
- MYSQL_LIBS=""
- ifelse([$3], , :, [$3])
+ AC_MSG_RESULT(yes)
+ ifelse([$1], , :, [$1])
fi
AC_SUBST(MYSQL_CFLAGS)
AC_SUBST(MYSQL_LIBS)
- rm -f conf.mysqltest
])
dnl Removes -I/usr/include/? from given variable
@@ -626,6 +610,25 @@ AC_DEFUN(jm_ICONV,
fi
])
+AC_DEFUN(rjs_CHARSET
+[
+ dnl Find out if we can convert from $1 to UCS2-LE
+ AC_MSG_CHECKING(we can convert from $1 to UCS2-LE)
+ AC_TRY_RUN([
+#include <$jm_cv_include>
+main(){
+ iconv_t cd = iconv_open("$1", "UCS-2LE");
+ if (cd == 0 || cd == (iconv_t)-1) {
+ return -1;
+ }
+ return 0;
+}
+ ],ICONV_CHARSET=$1,ICONV_CHARSET="",])
+ if test x"$ICONV_CHARSET" != x; then
+ AC_MSG_RESULT($ICONV_CHARSET)
+ fi
+])
+
dnl CFLAGS_ADD_DIR(CFLAGS, $INCDIR)
dnl This function doesn't add -I/usr/include into CFLAGS
AC_DEFUN(CFLAGS_ADD_DIR,[
diff --git a/source/auth/auth.c b/source/auth/auth.c
index a2486acbd11..668bba0d641 100644
--- a/source/auth/auth.c
+++ b/source/auth/auth.c
@@ -131,7 +131,7 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by));
DEBUG(5, ("challenge is: \n"));
- dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
+ dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length);
SMB_ASSERT(auth_context->challenge.length == 8);
@@ -228,7 +228,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
auth_context->challenge_set_by));
DEBUG(10, ("challenge is: \n"));
- dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
+ dump_data(5, (const char *)auth_context->challenge.data, auth_context->challenge.length);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("user_info has passwords of length %d and %d\n",
@@ -512,7 +512,7 @@ NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[
return nt_status;
}
- (*auth_context)->challenge = data_blob(chal, 8);
+ (*auth_context)->challenge = data_blob_talloc((*auth_context)->mem_ctx, chal, 8);
(*auth_context)->challenge_set_by = "fixed";
return nt_status;
}
diff --git a/source/auth/auth_domain.c b/source/auth/auth_domain.c
index 56bd6b9acab..aacea261feb 100644
--- a/source/auth/auth_domain.c
+++ b/source/auth/auth_domain.c
@@ -69,7 +69,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
/* Attempt connection */
*retry = True;
result = cli_full_connection(cli, global_myname(), dc_name, &dc_ip, 0,
- "IPC$", "IPC", "", "", "", 0, retry);
+ "IPC$", "IPC", "", "", "", 0, Undefined, retry);
if (!NT_STATUS_IS_OK(result)) {
/* map to something more useful */
@@ -104,7 +104,7 @@ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
return NT_STATUS_NO_LOGON_SERVERS;
}
- snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as);
+ fstr_sprintf((*cli)->mach_acct, "%s$", setup_creds_as);
if (!(*cli)->mach_acct) {
release_server_mutex();
diff --git a/source/auth/auth_ntlmssp.c b/source/auth/auth_ntlmssp.c
index a381219d74e..3af0cbaada4 100644
--- a/source/auth/auth_ntlmssp.c
+++ b/source/auth/auth_ntlmssp.c
@@ -135,4 +135,3 @@ NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state,
{
return ntlmssp_server_update(auth_ntlmssp_state->ntlmssp_state, request, reply);
}
-
diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c
index 012696f46a9..fb66d53cd4f 100644
--- a/source/auth/auth_sam.c
+++ b/source/auth/auth_sam.c
@@ -44,12 +44,12 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response,
}
if (sec_blob->length != 8) {
- DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%d)\n", sec_blob->length));
+ DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", (unsigned long)sec_blob->length));
return False;
}
if (nt_response->length != 24) {
- DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response->length));
+ DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", (unsigned long)nt_response->length));
return False;
}
@@ -103,8 +103,8 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response,
/* We MUST have more than 16 bytes, or the stuff below will go
crazy. No known implementation sends less than the 24 bytes
for LMv2, let alone NTLMv2. */
- DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%d)\n",
- ntv2_response->length));
+ DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n",
+ (unsigned long)ntv2_response->length));
return False;
}
@@ -233,8 +233,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
if (auth_flags & AUTH_FLAG_LM_RESP) {
if (user_info->lm_resp.length != 24) {
- DEBUG(2,("sam_password_ok: invalid LanMan password length (%d) for user %s\n",
- user_info->nt_resp.length, pdb_get_username(sampass)));
+ DEBUG(2,("sam_password_ok: invalid LanMan password length (%lu) for user %s\n",
+ (unsigned long)user_info->nt_resp.length, pdb_get_username(sampass)));
}
if (!lp_lanman_auth()) {
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index 8e1b420b473..952aa8ba590 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -68,7 +68,7 @@ void auth_add_user_script(const char *domain, const char *username)
* user on the fly, do so.
*/
- if ( lp_adduser_script() )
+ if ( *lp_adduser_script() )
smb_create_user(domain, username, NULL);
else {
DEBUG(10,("auth_add_user_script: no 'add user script'. Asking winbindd\n"));
@@ -133,7 +133,7 @@ static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
*user_info = malloc(sizeof(**user_info));
if (!user_info) {
- DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info)));
+ DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
return NT_STATUS_NO_MEMORY;
}
@@ -216,8 +216,8 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
client_domain, smb_name, wksta_name));
/* don't allow "" as a domain, fixes a Win9X bug
- where it doens't supply a domain for logon script
- 'net use' commands.*/
+ where it doens't supply a domain for logon script
+ 'net use' commands. */
if ( *client_domain )
domain = client_domain;
@@ -227,7 +227,7 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
/* do what win2k does. Always map unknown domains to our own
and let the "passdb backend" handle unknown users. */
- if ( !is_trusted_domain(domain) )
+ if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) )
domain = get_default_sam_name();
/* we know that it is a trusted domain (and we are allowing them) or it is our domain */
@@ -393,7 +393,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
dump_data(100, plaintext_password.data, plaintext_password.length);
#endif
- SMBencrypt( (const uchar *)plaintext_password.data, (const uchar*)chal, local_lm_response);
+ SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response);
local_lm_blob = data_blob(local_lm_response, 24);
/* We can't do an NT hash here, as the password needs to be
@@ -489,9 +489,9 @@ void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n",
sid_to_string(sid_str, &token->user_sids[0]) ));
- DEBUGADDC(dbg_class, dbg_lev, ("contains %i SIDs\n", token->num_sids));
+ DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids));
for (i = 0; i < token->num_sids; i++)
- DEBUGADDC(dbg_class, dbg_lev, ("SID[%3i]: %s\n", i,
+ DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i,
sid_to_string(sid_str, &token->user_sids[i])));
}
@@ -646,43 +646,66 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
* of groups.
******************************************************************************/
-static NTSTATUS get_user_groups_from_local_sam(const char *username, uid_t uid, gid_t gid,
- int *n_groups, DOM_SID **groups, gid_t **unix_groups)
+static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid,
+ int *n_groups, DOM_SID **groups, gid_t **unix_groups)
{
- int n_unix_groups;
- int i;
+ int n_unix_groups;
+ int i;
*n_groups = 0;
*groups = NULL;
+
+ /* Try winbind first */
- n_unix_groups = groups_max();
- if ((*unix_groups = malloc( sizeof(gid_t) * n_unix_groups ) ) == NULL) {
- DEBUG(0, ("get_user_groups_from_local_sam: Out of memory allocating unix group list\n"));
- return NT_STATUS_NO_MEMORY;
+ if ( strchr(username, *lp_winbind_separator()) ) {
+ n_unix_groups = winbind_getgroups( username, unix_groups );
+
+ DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n", username,
+ n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
+
+ if ( n_unix_groups == -1 )
+ return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
}
-
- if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
- gid_t *groups_tmp;
- groups_tmp = Realloc(*unix_groups, sizeof(gid_t) * n_unix_groups);
- if (!groups_tmp) {
- SAFE_FREE(*unix_groups);
+ else {
+ /* fallback to getgrouplist() */
+
+ n_unix_groups = groups_max();
+
+ if ((*unix_groups = malloc( sizeof(gid_t) * n_unix_groups ) ) == NULL) {
+ DEBUG(0, ("get_user_groups: Out of memory allocating unix group list\n"));
return NT_STATUS_NO_MEMORY;
}
- *unix_groups = groups_tmp;
-
+
if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
- DEBUG(0, ("get_user_groups_from_local_sam: failed to get the unix group list\n"));
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
+
+ gid_t *groups_tmp;
+
+ groups_tmp = Realloc(*unix_groups, sizeof(gid_t) * n_unix_groups);
+
+ if (!groups_tmp) {
+ SAFE_FREE(*unix_groups);
+ return NT_STATUS_NO_MEMORY;
+ }
+ *unix_groups = groups_tmp;
+
+ if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
+ DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
+ SAFE_FREE(*unix_groups);
+ return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
+ }
}
}
debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
+ /* now setup the space for storing the SIDS */
+
if (n_unix_groups > 0) {
+
*groups = malloc(sizeof(DOM_SID) * n_unix_groups);
+
if (!*groups) {
- DEBUG(0, ("get_user_group_from_local_sam: malloc() failed for DOM_SID list!\n"));
+ DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n"));
SAFE_FREE(*unix_groups);
return NT_STATUS_NO_MEMORY;
}
@@ -692,7 +715,8 @@ static NTSTATUS get_user_groups_from_local_sam(const char *username, uid_t uid,
for (i = 0; i < *n_groups; i++) {
if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) {
- DEBUG(1, ("get_user_groups_from_local_sam: failed to convert gid %ld to a sid!\n", (long int)(*unix_groups)[i+1]));
+ DEBUG(1, ("get_user_groups: failed to convert gid %ld to a sid!\n",
+ (long int)(*unix_groups)[i+1]));
SAFE_FREE(*groups);
SAFE_FREE(*unix_groups);
return NT_STATUS_NO_SUCH_USER;
@@ -743,10 +767,9 @@ static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
BOOL is_guest;
uint32 rid;
- nt_status = get_user_groups_from_local_sam(pdb_get_username(sampass),
- uid, gid,
- &n_groupSIDs, &groupSIDs,
- &unix_groups);
+ nt_status = get_user_groups(pdb_get_username(sampass), uid, gid,
+ &n_groupSIDs, &groupSIDs, &unix_groups);
+
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(4,("get_user_groups_from_local_sam failed\n"));
free_server_info(server_info);
@@ -1068,11 +1091,11 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
/* Store the user group information in the server_info
returned to the caller. */
- nt_status = get_user_groups_from_local_sam((*server_info)->unix_name,
+ nt_status = get_user_groups((*server_info)->unix_name,
uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups);
- if ( !NT_STATUS_IS_OK(nt_status) )
- {
- DEBUG(4,("get_user_groups_from_local_sam failed\n"));
+
+ if ( !NT_STATUS_IS_OK(nt_status) ) {
+ DEBUG(4,("get_user_groups failed\n"));
return nt_status;
}
@@ -1080,9 +1103,9 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
(*server_info)->n_groups = n_lgroupSIDs;
/* Create a 'combined' list of all SIDs we might want in the SD */
- all_group_SIDs = malloc(sizeof(DOM_SID) *
- (n_lgroupSIDs + info3->num_groups2 +
- info3->num_other_sids));
+
+ all_group_SIDs = malloc(sizeof(DOM_SID) * (info3->num_groups2 +info3->num_other_sids));
+
if (!all_group_SIDs) {
DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
SAFE_FREE(lgroupSIDs);
@@ -1090,20 +1113,30 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
+#if 0 /* JERRY -- no such thing as local groups in current code */
/* Copy the 'local' sids */
memcpy(all_group_SIDs, lgroupSIDs, sizeof(DOM_SID) * n_lgroupSIDs);
SAFE_FREE(lgroupSIDs);
+#endif
/* and create (by appending rids) the 'domain' sids */
+
for (i = 0; i < info3->num_groups2; i++) {
- sid_copy(&all_group_SIDs[i+n_lgroupSIDs], &(info3->dom_sid.sid));
- if (!sid_append_rid(&all_group_SIDs[i+n_lgroupSIDs], info3->gids[i].g_rid)) {
+
+ sid_copy(&all_group_SIDs[i], &(info3->dom_sid.sid));
+
+ if (!sid_append_rid(&all_group_SIDs[i], info3->gids[i].g_rid)) {
+
nt_status = NT_STATUS_INVALID_PARAMETER;
+
DEBUG(3,("could not append additional group rid 0x%x\n",
info3->gids[i].g_rid));
+
SAFE_FREE(lgroupSIDs);
free_server_info(server_info);
+
return nt_status;
+
}
}
@@ -1113,19 +1146,20 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
*/
- for (i = 0; i < info3->num_other_sids; i++)
- sid_copy(&all_group_SIDs[
- n_lgroupSIDs + info3->num_groups2 + i],
+ for (i = 0; i < info3->num_other_sids; i++) {
+ sid_copy(&all_group_SIDs[info3->num_groups2 + i],
&info3->other_sids[i].sid);
+ }
/* Where are the 'global' sids... */
/* can the user be guest? if yes, where is it stored? */
- if (!NT_STATUS_IS_OK(
- nt_status = create_nt_user_token(
- &user_sid, &group_sid,
- n_lgroupSIDs + info3->num_groups2 + info3->num_other_sids,
- all_group_SIDs, False, &token))) {
+
+ nt_status = create_nt_user_token(&user_sid, &group_sid,
+ info3->num_groups2 + info3->num_other_sids,
+ all_group_SIDs, False, &token);
+
+ if ( !NT_STATUS_IS_OK(nt_status) ) {
DEBUG(4,("create_nt_user_token failed\n"));
SAFE_FREE(all_group_SIDs);
free_server_info(server_info);
diff --git a/source/auth/auth_winbind.c b/source/auth/auth_winbind.c
index aa8f345a5b9..cae7aadd0c7 100644
--- a/source/auth/auth_winbind.c
+++ b/source/auth/auth_winbind.c
@@ -36,7 +36,7 @@ static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response
if (!prs_init(&ps, len, mem_ctx, UNMARSHALL)) {
return NT_STATUS_NO_MEMORY;
}
- prs_copy_data_in(&ps, info3_ndr, len);
+ prs_copy_data_in(&ps, (char *)info3_ndr, len);
prs_set_offset(&ps,0);
if (!net_io_user_info3("", info3, &ps, 1, 3)) {
DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n"));
diff --git a/source/client/client.c b/source/client/client.c
index d9c3a7aa1b1..67fadd11a80 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -102,9 +102,10 @@ static double dir_total;
static struct cli_state *do_connect(const char *server, const char *share);
/****************************************************************************
-write to a local file with CR/LF->LF translation if appropriate. return the
-number taken from the buffer. This may not equal the number written.
+ Write to a local file with CR/LF->LF translation if appropriate. Return the
+ number taken from the buffer. This may not equal the number written.
****************************************************************************/
+
static int writefile(int f, char *b, int n)
{
int i;
@@ -129,9 +130,10 @@ static int writefile(int f, char *b, int n)
}
/****************************************************************************
- read from a file with LF->CR/LF translation if appropriate. return the
- number read. read approx n bytes.
+ Read from a file with LF->CR/LF translation if appropriate. Return the
+ number read. read approx n bytes.
****************************************************************************/
+
static int readfile(char *b, int n, XFILE *f)
{
int i;
@@ -156,10 +158,10 @@ static int readfile(char *b, int n, XFILE *f)
return(i);
}
-
/****************************************************************************
-send a message
+ Send a message.
****************************************************************************/
+
static void send_message(void)
{
int total_len = 0;
@@ -206,11 +208,10 @@ static void send_message(void)
}
}
-
-
/****************************************************************************
-check the space on a device
+ Check the space on a device.
****************************************************************************/
+
static int do_dskattr(void)
{
int total, bsize, avail;
@@ -227,8 +228,9 @@ static int do_dskattr(void)
}
/****************************************************************************
-show cd/pwd
+ Show cd/pwd.
****************************************************************************/
+
static int cmd_pwd(void)
{
d_printf("Current directory is %s",service);
@@ -236,10 +238,10 @@ static int cmd_pwd(void)
return 0;
}
-
/****************************************************************************
-change directory - inner section
+ Change directory - inner section.
****************************************************************************/
+
static int do_cd(char *newdir)
{
char *p = newdir;
@@ -276,8 +278,9 @@ static int do_cd(char *newdir)
}
/****************************************************************************
-change directory
+ Change directory.
****************************************************************************/
+
static int cmd_cd(void)
{
fstring buf;
@@ -291,13 +294,14 @@ static int cmd_cd(void)
return rc;
}
-
/*******************************************************************
- decide if a file should be operated on
- ********************************************************************/
+ Decide if a file should be operated on.
+********************************************************************/
+
static BOOL do_this_one(file_info *finfo)
{
- if (finfo->mode & aDIR) return(True);
+ if (finfo->mode & aDIR)
+ return(True);
if (*fileselection &&
!mask_match(finfo->name,fileselection,False)) {
@@ -319,8 +323,9 @@ static BOOL do_this_one(file_info *finfo)
}
/****************************************************************************
- display info about a file
- ****************************************************************************/
+ Display info about a file.
+****************************************************************************/
+
static void display_finfo(file_info *finfo)
{
if (do_this_one(finfo)) {
@@ -334,10 +339,10 @@ static void display_finfo(file_info *finfo)
}
}
-
/****************************************************************************
- accumulate size of a file
- ****************************************************************************/
+ Accumulate size of a file.
+****************************************************************************/
+
static void do_du(file_info *finfo)
{
if (do_this_one(finfo)) {
@@ -354,8 +359,8 @@ static long do_list_queue_end = 0;
static void (*do_list_fn)(file_info *);
/****************************************************************************
-functions for do_list_queue
- ****************************************************************************/
+ Functions for do_list_queue.
+****************************************************************************/
/*
* The do_list_queue is a NUL-separated list of strings stored in a
@@ -368,6 +373,7 @@ functions for do_list_queue
* Functions check to ensure that do_list_queue is non-NULL before
* accessing it.
*/
+
static void reset_do_list_queue(void)
{
SAFE_FREE(do_list_queue);
@@ -396,14 +402,11 @@ static void adjust_do_list_queue(void)
* If the starting point of the queue is more than half way through,
* move everything toward the beginning.
*/
- if (do_list_queue && (do_list_queue_start == do_list_queue_end))
- {
+ if (do_list_queue && (do_list_queue_start == do_list_queue_end)) {
DEBUG(4,("do_list_queue is empty\n"));
do_list_queue_start = do_list_queue_end = 0;
*do_list_queue = '\0';
- }
- else if (do_list_queue_start > (do_list_queue_size / 2))
- {
+ } else if (do_list_queue_start > (do_list_queue_size / 2)) {
DEBUG(4,("sliding do_list_queue backward\n"));
memmove(do_list_queue,
do_list_queue + do_list_queue_start,
@@ -411,15 +414,13 @@ static void adjust_do_list_queue(void)
do_list_queue_end -= do_list_queue_start;
do_list_queue_start = 0;
}
-
}
static void add_to_do_list_queue(const char* entry)
{
char *dlq;
long new_end = do_list_queue_end + ((long)strlen(entry)) + 1;
- while (new_end > do_list_queue_size)
- {
+ while (new_end > do_list_queue_size) {
do_list_queue_size *= 2;
DEBUG(4,("enlarging do_list_queue to %d\n",
(int)do_list_queue_size));
@@ -428,17 +429,15 @@ static void add_to_do_list_queue(const char* entry)
d_printf("failure enlarging do_list_queue to %d bytes\n",
(int)do_list_queue_size);
reset_do_list_queue();
- }
- else
- {
+ } else {
do_list_queue = dlq;
memset(do_list_queue + do_list_queue_size / 2,
0, do_list_queue_size / 2);
}
}
- if (do_list_queue)
- {
- pstrcpy(do_list_queue + do_list_queue_end, entry);
+ if (do_list_queue) {
+ safe_strcpy_base(do_list_queue + do_list_queue_end,
+ entry, do_list_queue, do_list_queue_size);
do_list_queue_end = new_end;
DEBUG(4,("added %s to do_list_queue (start=%d, end=%d)\n",
entry, (int)do_list_queue_start, (int)do_list_queue_end));
@@ -452,8 +451,7 @@ static char *do_list_queue_head(void)
static void remove_do_list_queue_head(void)
{
- if (do_list_queue_end > do_list_queue_start)
- {
+ if (do_list_queue_end > do_list_queue_start) {
do_list_queue_start += strlen(do_list_queue_head()) + 1;
adjust_do_list_queue();
DEBUG(4,("removed head of do_list_queue (start=%d, end=%d)\n",
@@ -467,8 +465,9 @@ static int do_list_queue_empty(void)
}
/****************************************************************************
-a helper for do_list
- ****************************************************************************/
+ A helper for do_list.
+****************************************************************************/
+
static void do_list_helper(file_info *f, const char *mask, void *state)
{
if (f->mode & aDIR) {
@@ -481,9 +480,15 @@ static void do_list_helper(file_info *f, const char *mask, void *state)
pstring mask2;
char *p;
+ if (!f->name[0]) {
+ d_printf("Empty dir name returned. Possible server misconfiguration.\n");
+ return;
+ }
+
pstrcpy(mask2, mask);
p = strrchr_m(mask2,'\\');
- if (!p) return;
+ if (!p)
+ return;
p[1] = 0;
pstrcat(mask2, f->name);
pstrcat(mask2,"\\*");
@@ -497,16 +502,15 @@ static void do_list_helper(file_info *f, const char *mask, void *state)
}
}
-
/****************************************************************************
-a wrapper around cli_list that adds recursion
- ****************************************************************************/
+ A wrapper around cli_list that adds recursion.
+****************************************************************************/
+
void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs)
{
static int in_do_list = 0;
- if (in_do_list && rec)
- {
+ if (in_do_list && rec) {
fprintf(stderr, "INTERNAL ERROR: do_list called recursively when the recursive flag is true\n");
exit(1);
}
@@ -517,13 +521,11 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
do_list_dirs = dirs;
do_list_fn = fn;
- if (rec)
- {
+ if (rec) {
init_do_list_queue();
add_to_do_list_queue(mask);
- while (! do_list_queue_empty())
- {
+ while (! do_list_queue_empty()) {
/*
* Need to copy head so that it doesn't become
* invalid inside the call to cli_list. This
@@ -535,30 +537,24 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
pstrcpy(head, do_list_queue_head());
cli_list(cli, head, attribute, do_list_helper, NULL);
remove_do_list_queue_head();
- if ((! do_list_queue_empty()) && (fn == display_finfo))
- {
+ if ((! do_list_queue_empty()) && (fn == display_finfo)) {
char* next_file = do_list_queue_head();
char* save_ch = 0;
if ((strlen(next_file) >= 2) &&
(next_file[strlen(next_file) - 1] == '*') &&
- (next_file[strlen(next_file) - 2] == '\\'))
- {
+ (next_file[strlen(next_file) - 2] == '\\')) {
save_ch = next_file +
strlen(next_file) - 2;
*save_ch = '\0';
}
d_printf("\n%s\n",next_file);
- if (save_ch)
- {
+ if (save_ch) {
*save_ch = '\\';
}
}
}
- }
- else
- {
- if (cli_list(cli, mask, attribute, do_list_helper, NULL) == -1)
- {
+ } else {
+ if (cli_list(cli, mask, attribute, do_list_helper, NULL) == -1) {
d_printf("%s listing %s\n", cli_errstr(cli), mask);
}
}
@@ -568,8 +564,9 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
}
/****************************************************************************
- get a directory listing
- ****************************************************************************/
+ Get a directory listing.
+****************************************************************************/
+
static int cmd_dir(void)
{
uint16 attribute = aDIR | aSYSTEM | aHIDDEN;
@@ -589,8 +586,7 @@ static int cmd_dir(void)
pstrcpy(mask,p);
else
pstrcat(mask,p);
- }
- else {
+ } else {
pstrcat(mask,"*");
}
@@ -603,10 +599,10 @@ static int cmd_dir(void)
return rc;
}
-
/****************************************************************************
- get a directory listing
- ****************************************************************************/
+ Get a directory listing.
+****************************************************************************/
+
static int cmd_du(void)
{
uint16 attribute = aDIR | aSYSTEM | aHIDDEN;
@@ -639,10 +635,10 @@ static int cmd_du(void)
return rc;
}
-
/****************************************************************************
- get a file from rname to lname
- ****************************************************************************/
+ Get a file from rname to lname
+****************************************************************************/
+
static int do_get(char *rname, char *lname, BOOL reget)
{
int handle = 0, fnum;
@@ -712,7 +708,8 @@ static int do_get(char *rname, char *lname, BOOL reget)
while (1) {
int n = cli_read(cli, fnum, data, nread + start, read_size);
- if (n <= 0) break;
+ if (n <= 0)
+ break;
if (writefile(handle,data, n) != n) {
d_printf("Error writing local file\n");
@@ -764,10 +761,10 @@ static int do_get(char *rname, char *lname, BOOL reget)
return rc;
}
-
/****************************************************************************
- get a file
- ****************************************************************************/
+ Get a file.
+****************************************************************************/
+
static int cmd_get(void)
{
pstring lname;
@@ -791,10 +788,10 @@ static int cmd_get(void)
return do_get(rname, lname, False);
}
-
/****************************************************************************
- do a mget operation on one file
- ****************************************************************************/
+ Do an mget operation on one file.
+****************************************************************************/
+
static void do_mget(file_info *finfo)
{
pstring rname;
@@ -817,7 +814,8 @@ static void do_mget(file_info *finfo)
slprintf(quest,sizeof(pstring)-1,
"Get file %s? ",finfo->name);
- if (prompt && !yesno(quest)) return;
+ if (prompt && !yesno(quest))
+ return;
if (!(finfo->mode & aDIR)) {
pstrcpy(rname,cur_dir);
@@ -857,10 +855,10 @@ static void do_mget(file_info *finfo)
pstrcpy(cur_dir,saved_curdir);
}
-
/****************************************************************************
-view the file using the pager
+ View the file using the pager.
****************************************************************************/
+
static int cmd_more(void)
{
fstring rname,lname,pager_cmd;
@@ -898,11 +896,10 @@ static int cmd_more(void)
return rc;
}
-
-
/****************************************************************************
-do a mget command
+ Do a mget command.
****************************************************************************/
+
static int cmd_mget(void)
{
uint16 attribute = aSYSTEM | aHIDDEN;
@@ -940,10 +937,10 @@ static int cmd_mget(void)
return 0;
}
-
/****************************************************************************
-make a directory of name "name"
+ Make a directory of name "name".
****************************************************************************/
+
static BOOL do_mkdir(char *name)
{
if (!cli_mkdir(cli, name)) {
@@ -956,8 +953,9 @@ static BOOL do_mkdir(char *name)
}
/****************************************************************************
-show 8.3 name of a file
+ Show 8.3 name of a file.
****************************************************************************/
+
static BOOL do_altname(char *name)
{
fstring altname;
@@ -971,10 +969,10 @@ static BOOL do_altname(char *name)
return(True);
}
-
/****************************************************************************
Exit client.
****************************************************************************/
+
static int cmd_quit(void)
{
cli_shutdown(cli);
@@ -983,10 +981,10 @@ static int cmd_quit(void)
return 0;
}
-
/****************************************************************************
- make a directory
- ****************************************************************************/
+ Make a directory.
+****************************************************************************/
+
static int cmd_mkdir(void)
{
pstring mask;
@@ -1025,10 +1023,10 @@ static int cmd_mkdir(void)
return 0;
}
-
/****************************************************************************
- show alt name
- ****************************************************************************/
+ Show alt name.
+****************************************************************************/
+
static int cmd_altname(void)
{
pstring name;
@@ -1048,10 +1046,10 @@ static int cmd_altname(void)
return 0;
}
-
/****************************************************************************
- put a single file
- ****************************************************************************/
+ Put a single file.
+****************************************************************************/
+
static int do_put(char *rname, char *lname, BOOL reput)
{
int fnum;
@@ -1105,7 +1103,6 @@ static int do_put(char *rname, char *lname, BOOL reput)
d_printf("Error opening local file %s\n",lname);
return 1;
}
-
DEBUG(1,("putting file %s as %s ",lname,
rname));
@@ -1177,11 +1174,10 @@ static int do_put(char *rname, char *lname, BOOL reput)
return rc;
}
-
-
/****************************************************************************
- put a file
- ****************************************************************************/
+ Put a file.
+****************************************************************************/
+
static int cmd_put(void)
{
pstring lname;
@@ -1220,7 +1216,7 @@ static int cmd_put(void)
}
/*************************************
- File list structure
+ File list structure.
*************************************/
static struct file_list {
@@ -1230,15 +1226,14 @@ static struct file_list {
} *file_list;
/****************************************************************************
- Free a file_list structure
+ Free a file_list structure.
****************************************************************************/
static void free_file_list (struct file_list * list)
{
struct file_list *tmp;
- while (list)
- {
+ while (list) {
tmp = list;
DLIST_REMOVE(list, list);
SAFE_FREE(tmp->file_path);
@@ -1247,9 +1242,10 @@ static void free_file_list (struct file_list * list)
}
/****************************************************************************
- seek in a directory/file list until you get something that doesn't start with
- the specified name
- ****************************************************************************/
+ Seek in a directory/file list until you get something that doesn't start with
+ the specified name.
+****************************************************************************/
+
static BOOL seek_list(struct file_list *list, char *name)
{
while (list) {
@@ -1264,8 +1260,9 @@ static BOOL seek_list(struct file_list *list, char *name)
}
/****************************************************************************
- set the file selection mask
- ****************************************************************************/
+ Set the file selection mask.
+****************************************************************************/
+
static int cmd_select(void)
{
pstrcpy(fileselection,"");
@@ -1278,6 +1275,7 @@ static int cmd_select(void)
Recursive file matching function act as find
match must be always set to True when calling this function
****************************************************************************/
+
static int file_find(struct file_list **list, const char *directory,
const char *expression, BOOL match)
{
@@ -1290,11 +1288,14 @@ static int file_find(struct file_list **list, const char *directory,
const char *dname;
dir = opendir(directory);
- if (!dir) return -1;
+ if (!dir)
+ return -1;
while ((dname = readdirname(dir))) {
- if (!strcmp("..", dname)) continue;
- if (!strcmp(".", dname)) continue;
+ if (!strcmp("..", dname))
+ continue;
+ if (!strcmp(".", dname))
+ continue;
if (asprintf(&path, "%s/%s", directory, dname) <= 0) {
continue;
@@ -1338,8 +1339,9 @@ static int file_find(struct file_list **list, const char *directory,
}
/****************************************************************************
- mput some files
- ****************************************************************************/
+ mput some files.
+****************************************************************************/
+
static int cmd_mput(void)
{
fstring buf;
@@ -1419,10 +1421,10 @@ static int cmd_mput(void)
return 0;
}
-
/****************************************************************************
- cancel a print job
- ****************************************************************************/
+ Cancel a print job.
+****************************************************************************/
+
static int do_cancel(int job)
{
if (cli_printjob_del(cli, job)) {
@@ -1434,10 +1436,10 @@ static int do_cancel(int job)
}
}
-
/****************************************************************************
- cancel a print job
- ****************************************************************************/
+ Cancel a print job.
+****************************************************************************/
+
static int cmd_cancel(void)
{
fstring buf;
@@ -1455,10 +1457,10 @@ static int cmd_cancel(void)
return 0;
}
-
/****************************************************************************
- print a file
- ****************************************************************************/
+ Print a file.
+****************************************************************************/
+
static int cmd_print(void)
{
pstring lname;
@@ -1483,18 +1485,19 @@ static int cmd_print(void)
return do_put(rname, lname, False);
}
-
/****************************************************************************
- show a print queue entry
+ Show a print queue entry.
****************************************************************************/
+
static void queue_fn(struct print_job_info *p)
{
d_printf("%-6d %-9d %s\n", (int)p->id, (int)p->size, p->name);
}
/****************************************************************************
- show a print queue
+ Show a print queue.
****************************************************************************/
+
static int cmd_queue(void)
{
cli_print_queue(cli, queue_fn);
@@ -1503,8 +1506,9 @@ static int cmd_queue(void)
}
/****************************************************************************
-delete some files
+ Delete some files.
****************************************************************************/
+
static void do_del(file_info *finfo)
{
pstring mask;
@@ -1521,8 +1525,9 @@ static void do_del(file_info *finfo)
}
/****************************************************************************
-delete some files
+ Delete some files.
****************************************************************************/
+
static int cmd_del(void)
{
pstring mask;
@@ -1547,6 +1552,7 @@ static int cmd_del(void)
/****************************************************************************
****************************************************************************/
+
static int cmd_open(void)
{
pstring mask;
@@ -1567,8 +1573,9 @@ static int cmd_open(void)
/****************************************************************************
-remove a directory
+ Remove a directory.
****************************************************************************/
+
static int cmd_rmdir(void)
{
pstring mask;
@@ -1733,8 +1740,9 @@ static int cmd_chown(void)
}
/****************************************************************************
-rename some files
+ Rename some file.
****************************************************************************/
+
static int cmd_rename(void)
{
pstring src,dest;
@@ -1760,10 +1768,10 @@ static int cmd_rename(void)
return 0;
}
-
/****************************************************************************
-toggle the prompt flag
+ Toggle the prompt flag.
****************************************************************************/
+
static int cmd_prompt(void)
{
prompt = !prompt;
@@ -1772,10 +1780,10 @@ static int cmd_prompt(void)
return 1;
}
-
/****************************************************************************
-set the newer than time
+ Set the newer than time.
****************************************************************************/
+
static int cmd_newer(void)
{
fstring buf;
@@ -1800,8 +1808,9 @@ static int cmd_newer(void)
}
/****************************************************************************
-set the archive level
+ Set the archive level.
****************************************************************************/
+
static int cmd_archive(void)
{
fstring buf;
@@ -1815,8 +1824,9 @@ static int cmd_archive(void)
}
/****************************************************************************
-toggle the lowercaseflag
+ Toggle the lowercaseflag.
****************************************************************************/
+
static int cmd_lowercase(void)
{
lowercase = !lowercase;
@@ -1825,12 +1835,10 @@ static int cmd_lowercase(void)
return 0;
}
-
-
-
/****************************************************************************
-toggle the recurse flag
+ Toggle the recurse flag.
****************************************************************************/
+
static int cmd_recurse(void)
{
recurse = !recurse;
@@ -1840,8 +1848,9 @@ static int cmd_recurse(void)
}
/****************************************************************************
-toggle the translate flag
+ Toggle the translate flag.
****************************************************************************/
+
static int cmd_translate(void)
{
translation = !translation;
@@ -1851,10 +1860,10 @@ static int cmd_translate(void)
return 0;
}
-
/****************************************************************************
-do a printmode command
+ Do a printmode command.
****************************************************************************/
+
static int cmd_printmode(void)
{
fstring buf;
@@ -1871,8 +1880,7 @@ static int cmd_printmode(void)
}
}
- switch(printmode)
- {
+ switch(printmode) {
case 0:
fstrcpy(mode,"text");
break;
@@ -1882,7 +1890,7 @@ static int cmd_printmode(void)
default:
slprintf(mode,sizeof(mode)-1,"%d",printmode);
break;
- }
+ }
DEBUG(2,("the printmode is now %s\n",mode));
@@ -1890,8 +1898,9 @@ static int cmd_printmode(void)
}
/****************************************************************************
- do the lcd command
+ Do the lcd command.
****************************************************************************/
+
static int cmd_lcd(void)
{
fstring buf;
@@ -1905,8 +1914,9 @@ static int cmd_lcd(void)
}
/****************************************************************************
- get a file restarting at end of local file
+ Get a file restarting at end of local file.
****************************************************************************/
+
static int cmd_reget(void)
{
pstring local_name;
@@ -1931,8 +1941,9 @@ static int cmd_reget(void)
}
/****************************************************************************
- put a file restarting at end of local file
+ Put a file restarting at end of local file.
****************************************************************************/
+
static int cmd_reput(void)
{
pstring local_name;
@@ -1965,10 +1976,10 @@ static int cmd_reput(void)
return do_put(remote_name, local_name, True);
}
-
/****************************************************************************
- list a share name
+ List a share name.
****************************************************************************/
+
static void browse_fn(const char *name, uint32 m,
const char *comment, void *state)
{
@@ -1994,10 +2005,10 @@ static void browse_fn(const char *name, uint32 m,
name,typestr,comment);
}
-
/****************************************************************************
-try and browse available connections on a host
+ Try and browse available connections on a host.
****************************************************************************/
+
static BOOL browse_host(BOOL sort)
{
int ret;
@@ -2012,8 +2023,9 @@ static BOOL browse_host(BOOL sort)
}
/****************************************************************************
-list a server name
+ List a server name.
****************************************************************************/
+
static void server_fn(const char *name, uint32 m,
const char *comment, void *state)
{
@@ -2021,11 +2033,13 @@ static void server_fn(const char *name, uint32 m,
}
/****************************************************************************
-try and browse available connections on a host
+ Try and browse available connections on a host.
****************************************************************************/
+
static BOOL list_servers(char *wk_grp)
{
- if (!cli->server_domain) return False;
+ if (!cli->server_domain)
+ return False;
d_printf("\n\tServer Comment\n");
d_printf("\t--------- -------\n");
@@ -2056,8 +2070,7 @@ static struct
int (*fn)(void);
const char *description;
char compl_args[2]; /* Completion argument info */
-} commands[] =
-{
+} commands[] = {
{"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
{"altname",cmd_altname,"<file> show alt name",{COMPL_NONE,COMPL_NONE}},
{"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}},
@@ -2111,11 +2124,11 @@ static struct
{NULL,NULL,NULL,{COMPL_NONE,COMPL_NONE}}
};
-
/*******************************************************************
- lookup a command string in the list of commands, including
- abbreviations
- ******************************************************************/
+ Lookup a command string in the list of commands, including
+ abbreviations.
+******************************************************************/
+
static int process_tok(fstring tok)
{
int i = 0, matches = 0;
@@ -2143,8 +2156,9 @@ static int process_tok(fstring tok)
}
/****************************************************************************
-help
+ Help.
****************************************************************************/
+
static int cmd_help(void)
{
int i=0,j;
@@ -2166,8 +2180,9 @@ static int cmd_help(void)
}
/****************************************************************************
-process a -c command string
+ Process a -c command string.
****************************************************************************/
+
static int process_command_string(char *cmd)
{
pstring line;
@@ -2192,7 +2207,8 @@ static int process_command_string(char *cmd)
line[1000] = '\0';
cmd += strlen(cmd);
} else {
- if (p - cmd > 999) p = cmd + 999;
+ if (p - cmd > 999)
+ p = cmd + 999;
strncpy(line, cmd, p - cmd);
line[p - cmd] = '\0';
cmd = p + 1;
@@ -2285,9 +2301,9 @@ static char **remote_completion(const char *text, int len)
if (i > 0) {
strncpy(info.dirmask, text, i+1);
info.dirmask[i+1] = 0;
- snprintf(dirmask, sizeof(dirmask), "%s%*s*", cur_dir, i-1, text);
+ pstr_sprintf(dirmask, "%s%*s*", cur_dir, i-1, text);
} else
- snprintf(dirmask, sizeof(dirmask), "%s*", cur_dir);
+ pstr_sprintf(dirmask, "%s*", cur_dir);
if (cli_list(cli, dirmask, aDIR | aSYSTEM | aHIDDEN, completion_remote_filter, &info) < 0)
goto cleanup;
@@ -2397,8 +2413,9 @@ cleanup:
}
/****************************************************************************
-make sure we swallow keepalives during idle time
+ Make sure we swallow keepalives during idle time.
****************************************************************************/
+
static void readline_callback(void)
{
fd_set fds;
@@ -2408,7 +2425,8 @@ static void readline_callback(void)
t = time(NULL);
- if (t - last_t < 5) return;
+ if (t - last_t < 5)
+ return;
last_t = t;
@@ -2436,10 +2454,10 @@ static void readline_callback(void)
cli_chkpath(cli, "\\");
}
-
/****************************************************************************
-process commands on stdin
+ Process commands on stdin.
****************************************************************************/
+
static void process_stdin(void)
{
const char *ptr;
@@ -2479,10 +2497,10 @@ static void process_stdin(void)
}
}
-
/*****************************************************
-return a connection to a server
+ Return a connection to a server.
*******************************************************/
+
static struct cli_state *do_connect(const char *server, const char *share)
{
struct cli_state *c;
@@ -2523,6 +2541,8 @@ static struct cli_state *do_connect(const char *server, const char *share)
c->protocol = max_protocol;
c->use_kerberos = use_kerberos;
+ cli_setup_signing_state(c, cmdline_auth_info.signing_state);
+
if (!cli_session_request(c, &calling, &called)) {
char *p;
@@ -2552,6 +2572,7 @@ static struct cli_state *do_connect(const char *server, const char *share)
char *pass = getpass("Password: ");
if (pass) {
pstrcpy(password, pass);
+ got_pass = 1;
}
}
@@ -2594,10 +2615,10 @@ static struct cli_state *do_connect(const char *server, const char *share)
return c;
}
-
/****************************************************************************
- process commands from the client
+ Process commands from the client.
****************************************************************************/
+
static int process(char *base_directory)
{
int rc = 0;
@@ -2620,8 +2641,9 @@ static int process(char *base_directory)
}
/****************************************************************************
-handle a -L query
+ Handle a -L query.
****************************************************************************/
+
static int do_host_query(char *query_host)
{
cli = do_connect(query_host, "IPC$");
@@ -2629,6 +2651,22 @@ static int do_host_query(char *query_host)
return 1;
browse_host(True);
+
+ if (port != 139) {
+
+ /* Workgroups simply don't make sense over anything
+ else but port 139... */
+
+ cli_shutdown(cli);
+ port = 139;
+ cli = do_connect(query_host, "IPC$");
+ }
+
+ if (cli == NULL) {
+ d_printf("NetBIOS over TCP disabled -- no workgroup available\n");
+ return 1;
+ }
+
list_servers(lp_workgroup());
cli_shutdown(cli);
@@ -2638,8 +2676,9 @@ static int do_host_query(char *query_host)
/****************************************************************************
-handle a tar operation
+ Handle a tar operation.
****************************************************************************/
+
static int do_tar_op(char *base_directory)
{
int ret;
@@ -2663,8 +2702,9 @@ static int do_tar_op(char *base_directory)
}
/****************************************************************************
-handle a message operation
+ Handle a message operation.
****************************************************************************/
+
static int do_message_op(void)
{
struct in_addr ip;
@@ -2707,6 +2747,7 @@ static int do_message_op(void)
* We don't actually do anything yet -- we just stash the name in a
* global variable and do the query when all options have been read.
**/
+
static void remember_query_host(const char *arg,
pstring query_host)
{
@@ -2721,12 +2762,13 @@ static void remember_query_host(const char *arg,
}
}
-
/****************************************************************************
main program
****************************************************************************/
+
int main(int argc,char *argv[])
{
+ extern BOOL AllowDebugChange;
fstring base_directory;
int opt;
pstring query_host;
@@ -2768,13 +2810,11 @@ static void remember_query_host(const char *arg,
*query_host = 0;
*base_directory = 0;
- setup_logging(argv[0],True);
+ /* set default debug level to 0 regardless of what smb.conf sets */
+ DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
+ dbf = x_stderr;
+ x_setbuf( x_stderr, NULL );
- if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
- fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n",
- argv[0], dyn_CONFIGFILE);
- }
-
pc = poptGetContext("smbclient", argc, (const char **) argv, long_options,
POPT_CONTEXT_KEEP_FIRST);
poptSetOtherOptionHelp(pc, "service <password>");
@@ -2790,7 +2830,8 @@ static void remember_query_host(const char *arg,
*/
name_type = 0x03;
pstrcpy(desthost,poptGetOptArg(pc));
- if( 0 == port ) port = 139;
+ if( 0 == port )
+ port = 139;
message = True;
break;
case 'I':
@@ -2816,9 +2857,25 @@ static void remember_query_host(const char *arg,
max_protocol = interpret_protocol(poptGetOptArg(pc), max_protocol);
break;
case 'T':
- if (!tar_parseargs(argc, argv, poptGetOptArg(pc), optind)) {
- poptPrintUsage(pc, stderr, 0);
- exit(1);
+ /* We must use old option processing for this. Find the
+ * position of the -T option in the raw argv[]. */
+ {
+ int i, optnum;
+ for (i = 1; i < argc; i++) {
+ if (strncmp("-T", argv[i],2)==0)
+ break;
+ }
+ i++;
+ if (!(optnum = tar_parseargs(argc, argv, poptGetOptArg(pc), i))) {
+ poptPrintUsage(pc, stderr, 0);
+ exit(1);
+ }
+ /* Now we must eat (optnum - i) options - they have
+ * been processed by tar_parseargs().
+ */
+ optnum -= i;
+ for (i = 0; i < optnum; i++)
+ poptGetOptArg(pc);
}
break;
case 'D':
@@ -2829,6 +2886,17 @@ static void remember_query_host(const char *arg,
poptGetArg(pc);
+ /*
+ * Don't load debug level from smb.conf. It should be
+ * set by cmdline arg or remain default (0)
+ */
+ AllowDebugChange = False;
+
+ if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
+ fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n",
+ argv[0], dyn_CONFIGFILE);
+ }
+
load_interfaces();
if(poptPeekArg(pc)) {
@@ -2843,7 +2911,7 @@ static void remember_query_host(const char *arg,
}
}
- if (poptPeekArg(pc)) {
+ if (poptPeekArg(pc) && !cmdline_auth_info.got_pass) {
cmdline_auth_info.got_pass = True;
pstrcpy(cmdline_auth_info.password,poptGetArg(pc));
}
diff --git a/source/client/clitar.c b/source/client/clitar.c
index 765bc2a6594..5e20c3e11bb 100644
--- a/source/client/clitar.c
+++ b/source/client/clitar.c
@@ -43,27 +43,23 @@ static int clipfind(char **aret, int ret, char *tok);
typedef struct file_info_struct file_info2;
-struct file_info_struct
-{
- SMB_BIG_UINT size;
- uint16 mode;
- uid_t uid;
- gid_t gid;
- /* These times are normally kept in GMT */
- time_t mtime;
- time_t atime;
- time_t ctime;
- char *name; /* This is dynamically allocate */
-
- file_info2 *next, *prev; /* Used in the stack ... */
-
+struct file_info_struct {
+ SMB_BIG_UINT size;
+ uint16 mode;
+ uid_t uid;
+ gid_t gid;
+ /* These times are normally kept in GMT */
+ time_t mtime;
+ time_t atime;
+ time_t ctime;
+ char *name; /* This is dynamically allocate */
+
+ file_info2 *next, *prev; /* Used in the stack ... */
};
-typedef struct
-{
- file_info2 *top;
- int items;
-
+typedef struct {
+ file_info2 *top;
+ int items;
} stack;
#define SEPARATORS " \t\n\r"
@@ -145,285 +141,284 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first);
/*******************************************************************
Create a string of size size+1 (for the null)
*******************************************************************/
+
static char *string_create_s(int size)
{
- char *tmp;
+ char *tmp;
- tmp = (char *)malloc(size+1);
+ tmp = (char *)malloc(size+1);
- if (tmp == NULL) {
-
- DEBUG(0, ("Out of memory in string_create_s\n"));
-
- }
-
- return(tmp);
+ if (tmp == NULL) {
+ DEBUG(0, ("Out of memory in string_create_s\n"));
+ }
+ return(tmp);
}
/****************************************************************************
Write a tar header to buffer
****************************************************************************/
+
static void writetarheader(int f, const char *aname, SMB_BIG_UINT size, time_t mtime,
const char *amode, unsigned char ftype)
{
- union hblock hb;
- int i, chk, l;
- char *jp;
+ union hblock hb;
+ int i, chk, l;
+ char *jp;
- DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname));
+ DEBUG(5, ("WriteTarHdr, Type = %c, Size= %.0f, Name = %s\n", ftype, (double)size, aname));
- memset(hb.dummy, 0, sizeof(hb.dummy));
+ memset(hb.dummy, 0, sizeof(hb.dummy));
- l=strlen(aname);
- if (l >= NAMSIZ - 1) {
- /* write a GNU tar style long header */
- char *b;
- b = (char *)malloc(l+TBLOCK+100);
- if (!b) {
- DEBUG(0,("out of memory\n"));
- exit(1);
- }
- writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L');
- memset(b, 0, l+TBLOCK+100);
- fixtarname(b, aname, l);
- i = strlen(b)+1;
- DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b)));
- dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
- SAFE_FREE(b);
- }
-
- /* use l + 1 to do the null too */
- fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1);
-
- if (lowercase)
- strlower_m(hb.dbuf.name);
-
- /* write out a "standard" tar format header */
-
- hb.dbuf.name[NAMSIZ-1]='\0';
- safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1);
- oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
- oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
- oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
- if (size > (SMB_BIG_UINT)077777777777LL) {
-
- /* This is a non-POSIX compatible extention to store files
- greater than 8GB. */
-
- memset(hb.dbuf.size, 0, 4);
- hb.dbuf.size[0]=128;
- for (i = 8, jp=(char*)&size; i; i--)
- hb.dbuf.size[i+3] = *(jp++);
- }
- oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime);
- memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum));
- memset(hb.dbuf.linkname, 0, NAMSIZ);
- hb.dbuf.linkflag=ftype;
+ l=strlen(aname);
+ if (l >= NAMSIZ - 1) {
+ /* write a GNU tar style long header */
+ char *b;
+ b = (char *)malloc(l+TBLOCK+100);
+ if (!b) {
+ DEBUG(0,("out of memory\n"));
+ exit(1);
+ }
+ writetarheader(f, "/./@LongLink", l+2, 0, " 0 \0", 'L');
+ memset(b, 0, l+TBLOCK+100);
+ fixtarname(b, aname, l);
+ i = strlen(b)+1;
+ DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b)));
+ dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
+ SAFE_FREE(b);
+ }
+
+ /* use l + 1 to do the null too */
+ fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1);
+
+ if (lowercase)
+ strlower_m(hb.dbuf.name);
+
+ /* write out a "standard" tar format header */
+
+ hb.dbuf.name[NAMSIZ-1]='\0';
+ safe_strcpy(hb.dbuf.mode, amode, sizeof(hb.dbuf.mode)-1);
+ oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.uid);
+ oct_it((SMB_BIG_UINT)0, 8, hb.dbuf.gid);
+ oct_it((SMB_BIG_UINT) size, 13, hb.dbuf.size);
+ if (size > (SMB_BIG_UINT)077777777777LL) {
+
+ /* This is a non-POSIX compatible extention to store files
+ greater than 8GB. */
+
+ memset(hb.dbuf.size, 0, 4);
+ hb.dbuf.size[0]=128;
+ for (i = 8, jp=(char*)&size; i; i--)
+ hb.dbuf.size[i+3] = *(jp++);
+ }
+ oct_it((SMB_BIG_UINT) mtime, 13, hb.dbuf.mtime);
+ memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum));
+ memset(hb.dbuf.linkname, 0, NAMSIZ);
+ hb.dbuf.linkflag=ftype;
- for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) chk+=(0xFF & *jp++);
+ for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;)
+ chk+=(0xFF & *jp++);
- oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
- hb.dbuf.chksum[6] = '\0';
+ oct_it((SMB_BIG_UINT) chk, 8, hb.dbuf.chksum);
+ hb.dbuf.chksum[6] = '\0';
- (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
+ (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
}
/****************************************************************************
Read a tar header into a hblock structure, and validate
***************************************************************************/
+
static long readtarheader(union hblock *hb, file_info2 *finfo, char *prefix)
{
- long chk, fchk;
- int i;
- char *jp;
-
- /*
- * read in a "standard" tar format header - we're not that interested
- * in that many fields, though
- */
-
- /* check the checksum */
- for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;) chk+=(0xFF & *jp++);
+ long chk, fchk;
+ int i;
+ char *jp;
- if (chk == 0)
- return chk;
-
- /* compensate for blanks in chksum header */
- for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;)
- chk-=(0xFF & *jp++);
+ /*
+ * read in a "standard" tar format header - we're not that interested
+ * in that many fields, though
+ */
- chk += ' ' * sizeof(hb->dbuf.chksum);
+ /* check the checksum */
+ for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;)
+ chk+=(0xFF & *jp++);
- fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum));
+ if (chk == 0)
+ return chk;
- DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n",
- chk, fchk, hb->dbuf.chksum));
+ /* compensate for blanks in chksum header */
+ for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;)
+ chk-=(0xFF & *jp++);
- if (fchk != chk)
- {
- DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk));
- dump_data(5, (char *)hb - TBLOCK, TBLOCK *3);
- return -1;
- }
+ chk += ' ' * sizeof(hb->dbuf.chksum);
- if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) {
+ fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum));
- DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name));
- return(-1);
+ DEBUG(5, ("checksum totals chk=%ld fchk=%ld chksum=%s\n",
+ chk, fchk, hb->dbuf.chksum));
- }
+ if (fchk != chk) {
+ DEBUG(0, ("checksums don't match %ld %ld\n", fchk, chk));
+ dump_data(5, (char *)hb - TBLOCK, TBLOCK *3);
+ return -1;
+ }
- safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3);
+ if ((finfo->name = string_create_s(strlen(prefix) + strlen(hb -> dbuf.name) + 3)) == NULL) {
+ DEBUG(0, ("Out of space creating file_info2 for %s\n", hb -> dbuf.name));
+ return(-1);
+ }
- /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
- unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
- strlen(hb->dbuf.name) + 1, True);
+ safe_strcpy(finfo->name, prefix, strlen(prefix) + strlen(hb -> dbuf.name) + 3);
+
+ /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
+ unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
+ strlen(hb->dbuf.name) + 1, True);
+
+ /* can't handle some links at present */
+ if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) {
+ if (hb->dbuf.linkflag == 0) {
+ DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
+ finfo->name));
+ } else {
+ if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */
+ /* Do nothing here at the moment. do_tarput will handle this
+ as long as the longlink gets back to it, as it has to advance
+ the buffer pointer, etc */
+ } else {
+ DEBUG(0, ("this tar file appears to contain some kind \
+of link other than a GNUtar Longlink - ignoring\n"));
+ return -2;
+ }
+ }
+ }
+
+ if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR) ||
+ (*(finfo->name+strlen(finfo->name)-1) == '\\')) {
+ finfo->mode=aDIR;
+ } else {
+ finfo->mode=0; /* we don't care about mode at the moment, we'll
+ * just make it a regular file */
+ }
- /* can't handle some links at present */
- if ((hb->dbuf.linkflag != '0') && (hb -> dbuf.linkflag != '5')) {
- if (hb->dbuf.linkflag == 0) {
- DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
- finfo->name));
- } else {
- if (hb -> dbuf.linkflag == 'L') { /* We have a longlink */
- /* Do nothing here at the moment. do_tarput will handle this
- as long as the longlink gets back to it, as it has to advance
- the buffer pointer, etc */
+ /*
+ * Bug fix by richard@sj.co.uk
+ *
+ * REC: restore times correctly (as does tar)
+ * We only get the modification time of the file; set the creation time
+ * from the mod. time, and the access time to current time
+ */
+ finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8);
+ finfo->atime = time(NULL);
+ finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
- } else {
- DEBUG(0, ("this tar file appears to contain some kind of link other than a GNUtar Longlink - ignoring\n"));
- return -2;
- }
- }
- }
-
- if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR)
- || (*(finfo->name+strlen(finfo->name)-1) == '\\'))
- {
- finfo->mode=aDIR;
- }
- else
- finfo->mode=0; /* we don't care about mode at the moment, we'll
- * just make it a regular file */
- /*
- * Bug fix by richard@sj.co.uk
- *
- * REC: restore times correctly (as does tar)
- * We only get the modification time of the file; set the creation time
- * from the mod. time, and the access time to current time
- */
- finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8);
- finfo->atime = time(NULL);
- finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
-
- return True;
+ return True;
}
/****************************************************************************
Write out the tar buffer to tape or wherever
****************************************************************************/
+
static int dotarbuf(int f, char *b, int n)
{
- int fail=1, writ=n;
-
- if (dry_run) {
- return writ;
- }
- /* This routine and the next one should be the only ones that do write()s */
- if (tp + n >= tbufsiz)
- {
- int diff;
-
- diff=tbufsiz-tp;
- memcpy(tarbuf + tp, b, diff);
- fail=fail && (1+write(f, tarbuf, tbufsiz));
- n-=diff;
- b+=diff;
- tp=0;
-
- while (n >= tbufsiz)
- {
- fail=fail && (1 + write(f, b, tbufsiz));
- n-=tbufsiz;
- b+=tbufsiz;
+ int fail=1, writ=n;
+
+ if (dry_run) {
+ return writ;
+ }
+ /* This routine and the next one should be the only ones that do write()s */
+ if (tp + n >= tbufsiz) {
+ int diff;
+
+ diff=tbufsiz-tp;
+ memcpy(tarbuf + tp, b, diff);
+ fail=fail && (1+write(f, tarbuf, tbufsiz));
+ n-=diff;
+ b+=diff;
+ tp=0;
+
+ while (n >= tbufsiz) {
+ fail=fail && (1 + write(f, b, tbufsiz));
+ n-=tbufsiz;
+ b+=tbufsiz;
+ }
}
- }
- if (n>0) {
- memcpy(tarbuf+tp, b, n);
- tp+=n;
- }
- return(fail ? writ : 0);
+ if (n>0) {
+ memcpy(tarbuf+tp, b, n);
+ tp+=n;
+ }
+
+ return(fail ? writ : 0);
}
/****************************************************************************
Write zeros to buffer / tape
****************************************************************************/
+
static void dozerobuf(int f, int n)
{
- /* short routine just to write out n zeros to buffer -
- * used to round files to nearest block
- * and to do tar EOFs */
+ /* short routine just to write out n zeros to buffer -
+ * used to round files to nearest block
+ * and to do tar EOFs */
- if (dry_run)
- return;
+ if (dry_run)
+ return;
- if (n+tp >= tbufsiz)
- {
- memset(tarbuf+tp, 0, tbufsiz-tp);
-
- write(f, tarbuf, tbufsiz);
- memset(tarbuf, 0, (tp+=n-tbufsiz));
- }
- else
- {
- memset(tarbuf+tp, 0, n);
- tp+=n;
- }
+ if (n+tp >= tbufsiz) {
+ memset(tarbuf+tp, 0, tbufsiz-tp);
+ write(f, tarbuf, tbufsiz);
+ memset(tarbuf, 0, (tp+=n-tbufsiz));
+ } else {
+ memset(tarbuf+tp, 0, n);
+ tp+=n;
+ }
}
/****************************************************************************
Malloc tape buffer
****************************************************************************/
+
static void initarbuf(void)
{
- /* initialize tar buffer */
- tbufsiz=blocksize*TBLOCK;
- tarbuf=malloc(tbufsiz); /* FIXME: We might not get the buffer */
+ /* initialize tar buffer */
+ tbufsiz=blocksize*TBLOCK;
+ tarbuf=malloc(tbufsiz); /* FIXME: We might not get the buffer */
- /* reset tar buffer pointer and tar file counter and total dumped */
- tp=0; ntarf=0; ttarf=0;
+ /* reset tar buffer pointer and tar file counter and total dumped */
+ tp=0; ntarf=0; ttarf=0;
}
/****************************************************************************
Write two zero blocks at end of file
****************************************************************************/
+
static void dotareof(int f)
{
- SMB_STRUCT_STAT stbuf;
- /* Two zero blocks at end of file, write out full buffer */
+ SMB_STRUCT_STAT stbuf;
+ /* Two zero blocks at end of file, write out full buffer */
- if (dry_run)
- return;
+ if (dry_run)
+ return;
- (void) dozerobuf(f, TBLOCK);
- (void) dozerobuf(f, TBLOCK);
+ (void) dozerobuf(f, TBLOCK);
+ (void) dozerobuf(f, TBLOCK);
- if (sys_fstat(f, &stbuf) == -1)
- {
- DEBUG(0, ("Couldn't stat file handle\n"));
- return;
- }
+ if (sys_fstat(f, &stbuf) == -1) {
+ DEBUG(0, ("Couldn't stat file handle\n"));
+ return;
+ }
- /* Could be a pipe, in which case S_ISREG should fail,
- * and we should write out at full size */
- if (tp > 0) write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz);
+ /* Could be a pipe, in which case S_ISREG should fail,
+ * and we should write out at full size */
+ if (tp > 0)
+ write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz);
}
/****************************************************************************
(Un)mangle DOS pathname, make nonabsolute
****************************************************************************/
+
static void fixtarname(char *tptr, const char *fp, int l)
{
/* add a '.' to start of file name, convert from ugly dos \'s in path
@@ -437,43 +432,43 @@ static void fixtarname(char *tptr, const char *fp, int l)
/****************************************************************************
Convert from decimal to octal string
****************************************************************************/
+
static void oct_it (SMB_BIG_UINT value, int ndgs, char *p)
{
- /* Converts long to octal string, pads with leading zeros */
+ /* Converts long to octal string, pads with leading zeros */
- /* skip final null, but do final space */
- --ndgs;
- p[--ndgs] = ' ';
+ /* skip final null, but do final space */
+ --ndgs;
+ p[--ndgs] = ' ';
- /* Loop does at least one digit */
- do {
- p[--ndgs] = '0' + (char) (value & 7);
- value >>= 3;
- }
- while (ndgs > 0 && value != 0);
+ /* Loop does at least one digit */
+ do {
+ p[--ndgs] = '0' + (char) (value & 7);
+ value >>= 3;
+ } while (ndgs > 0 && value != 0);
- /* Do leading zeros */
- while (ndgs > 0)
- p[--ndgs] = '0';
+ /* Do leading zeros */
+ while (ndgs > 0)
+ p[--ndgs] = '0';
}
/****************************************************************************
Convert from octal string to long
***************************************************************************/
+
static long unoct(char *p, int ndgs)
{
- long value=0;
- /* Converts octal string to long, ignoring any non-digit */
+ long value=0;
+ /* Converts octal string to long, ignoring any non-digit */
- while (--ndgs)
- {
- if (isdigit((int)*p))
- value = (value << 3) | (long) (*p - '0');
+ while (--ndgs) {
+ if (isdigit((int)*p))
+ value = (value << 3) | (long) (*p - '0');
- p++;
- }
+ p++;
+ }
- return value;
+ return value;
}
/****************************************************************************
@@ -481,90 +476,86 @@ Compare two strings in a slash insensitive way, allowing s1 to match s2
if s1 is an "initial" string (up to directory marker). Thus, if s2 is
a file in any subdirectory of s1, declare a match.
***************************************************************************/
+
static int strslashcmp(char *s1, char *s2)
{
- char *s1_0=s1;
+ char *s1_0=s1;
- while(*s1 && *s2 &&
- (*s1 == *s2
- || tolower(*s1) == tolower(*s2)
- || (*s1 == '\\' && *s2=='/')
- || (*s1 == '/' && *s2=='\\'))) {
- s1++; s2++;
- }
+ while(*s1 && *s2 && (*s1 == *s2 || tolower(*s1) == tolower(*s2) ||
+ (*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) {
+ s1++; s2++;
+ }
- /* if s1 has a trailing slash, it compared equal, so s1 is an "initial"
- string of s2.
- */
- if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\')) return 0;
+ /* if s1 has a trailing slash, it compared equal, so s1 is an "initial"
+ string of s2.
+ */
+ if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\'))
+ return 0;
- /* ignore trailing slash on s1 */
- if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0;
+ /* ignore trailing slash on s1 */
+ if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1))
+ return 0;
- /* check for s1 is an "initial" string of s2 */
- if ((*s2 == '/' || *s2 == '\\') && !*s1) return 0;
+ /* check for s1 is an "initial" string of s2 */
+ if ((*s2 == '/' || *s2 == '\\') && !*s1)
+ return 0;
- return *s1-*s2;
+ return *s1-*s2;
}
-
/****************************************************************************
Ensure a remote path exists (make if necessary)
***************************************************************************/
+
static BOOL ensurepath(char *fname)
{
- /* *must* be called with buffer ready malloc'ed */
- /* ensures path exists */
-
- char *partpath, *ffname;
- char *p=fname, *basehack;
-
- DEBUG(5, ( "Ensurepath called with: %s\n", fname));
+ /* *must* be called with buffer ready malloc'ed */
+ /* ensures path exists */
- partpath = string_create_s(strlen(fname));
- ffname = string_create_s(strlen(fname));
+ char *partpath, *ffname;
+ char *p=fname, *basehack;
- if ((partpath == NULL) || (ffname == NULL)){
+ DEBUG(5, ( "Ensurepath called with: %s\n", fname));
- DEBUG(0, ("Out of memory in ensurepath: %s\n", fname));
- return(False);
+ partpath = string_create_s(strlen(fname));
+ ffname = string_create_s(strlen(fname));
- }
+ if ((partpath == NULL) || (ffname == NULL)){
+ DEBUG(0, ("Out of memory in ensurepath: %s\n", fname));
+ return(False);
+ }
- *partpath = 0;
+ *partpath = 0;
- /* fname copied to ffname so can strtok */
+ /* fname copied to ffname so can strtok */
- safe_strcpy(ffname, fname, strlen(fname));
+ safe_strcpy(ffname, fname, strlen(fname));
- /* do a `basename' on ffname, so don't try and make file name directory */
- if ((basehack=strrchr_m(ffname, '\\')) == NULL)
- return True;
- else
- *basehack='\0';
+ /* do a `basename' on ffname, so don't try and make file name directory */
+ if ((basehack=strrchr_m(ffname, '\\')) == NULL)
+ return True;
+ else
+ *basehack='\0';
- p=strtok(ffname, "\\");
+ p=strtok(ffname, "\\");
- while (p)
- {
- safe_strcat(partpath, p, strlen(fname) + 1);
+ while (p) {
+ safe_strcat(partpath, p, strlen(fname) + 1);
- if (!cli_chkpath(cli, partpath)) {
- if (!cli_mkdir(cli, partpath))
- {
- DEBUG(0, ("Error mkdirhiering\n"));
- return False;
- }
- else
- DEBUG(3, ("mkdirhiering %s\n", partpath));
-
- }
+ if (!cli_chkpath(cli, partpath)) {
+ if (!cli_mkdir(cli, partpath)) {
+ DEBUG(0, ("Error mkdirhiering\n"));
+ return False;
+ } else {
+ DEBUG(3, ("mkdirhiering %s\n", partpath));
+ }
+ }
- safe_strcat(partpath, "\\", strlen(fname) + 1);
- p = strtok(NULL,"/\\");
- }
+ safe_strcat(partpath, "\\", strlen(fname) + 1);
+ p = strtok(NULL,"/\\");
+ }
- return True;
+ return True;
}
static int padit(char *buf, int bufsize, int padsize)
@@ -583,7 +574,6 @@ static int padit(char *buf, int bufsize, int padsize)
return berr;
}
-
static void do_setrattr(char *name, uint16 attr, int set)
{
uint16 oldattr;
@@ -601,268 +591,258 @@ static void do_setrattr(char *name, uint16 attr, int set)
}
}
-
/****************************************************************************
append one remote file to the tar file
***************************************************************************/
+
static void do_atar(char *rname,char *lname,file_info *finfo1)
{
- int fnum;
- SMB_BIG_UINT nread=0;
- char ftype;
- file_info2 finfo;
- BOOL close_done = False;
- BOOL shallitime=True;
- char data[65520];
- int read_size = 65520;
- int datalen=0;
-
- struct timeval tp_start;
- GetTimeOfDay(&tp_start);
-
- ftype = '0'; /* An ordinary file ... */
-
- if (finfo1) {
- finfo.size = finfo1 -> size;
- finfo.mode = finfo1 -> mode;
- finfo.uid = finfo1 -> uid;
- finfo.gid = finfo1 -> gid;
- finfo.mtime = finfo1 -> mtime;
- finfo.atime = finfo1 -> atime;
- finfo.ctime = finfo1 -> ctime;
- finfo.name = finfo1 -> name;
- }
- else {
- finfo.size = def_finfo.size;
- finfo.mode = def_finfo.mode;
- finfo.uid = def_finfo.uid;
- finfo.gid = def_finfo.gid;
- finfo.mtime = def_finfo.mtime;
- finfo.atime = def_finfo.atime;
- finfo.ctime = def_finfo.ctime;
- finfo.name = def_finfo.name;
- }
-
- if (dry_run)
- {
- DEBUG(3,("skipping file %s of size %12.0f bytes\n",
- finfo.name,
- (double)finfo.size));
- shallitime=0;
- ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
- ntarf++;
- return;
- }
-
- fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
-
- dos_clean_name(rname);
-
- if (fnum == -1) {
- DEBUG(0,("%s opening remote file %s (%s)\n",
- cli_errstr(cli),rname, cur_dir));
- return;
- }
-
- finfo.name = string_create_s(strlen(rname));
- if (finfo.name == NULL) {
- DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
- return;
- }
-
- safe_strcpy(finfo.name,rname, strlen(rname));
- if (!finfo1) {
- if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) {
- DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
- return;
- }
- finfo.ctime = finfo.mtime;
- }
-
- DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
-
- if (tar_inc && !(finfo.mode & aARCH))
- {
- DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name));
- shallitime=0;
- }
- else if (!tar_system && (finfo.mode & aSYSTEM))
- {
- DEBUG(4, ("skipping %s - system bit is set\n", finfo.name));
- shallitime=0;
- }
- else if (!tar_hidden && (finfo.mode & aHIDDEN))
- {
- DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name));
- shallitime=0;
- }
- else
- {
- DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
- finfo.name,
- (double)finfo.size,
- lname));
+ int fnum;
+ SMB_BIG_UINT nread=0;
+ char ftype;
+ file_info2 finfo;
+ BOOL close_done = False;
+ BOOL shallitime=True;
+ char data[65520];
+ int read_size = 65520;
+ int datalen=0;
+
+ struct timeval tp_start;
+
+ GetTimeOfDay(&tp_start);
+
+ ftype = '0'; /* An ordinary file ... */
+
+ if (finfo1) {
+ finfo.size = finfo1 -> size;
+ finfo.mode = finfo1 -> mode;
+ finfo.uid = finfo1 -> uid;
+ finfo.gid = finfo1 -> gid;
+ finfo.mtime = finfo1 -> mtime;
+ finfo.atime = finfo1 -> atime;
+ finfo.ctime = finfo1 -> ctime;
+ finfo.name = finfo1 -> name;
+ } else {
+ finfo.size = def_finfo.size;
+ finfo.mode = def_finfo.mode;
+ finfo.uid = def_finfo.uid;
+ finfo.gid = def_finfo.gid;
+ finfo.mtime = def_finfo.mtime;
+ finfo.atime = def_finfo.atime;
+ finfo.ctime = def_finfo.ctime;
+ finfo.name = def_finfo.name;
+ }
+
+ if (dry_run) {
+ DEBUG(3,("skipping file %s of size %12.0f bytes\n", finfo.name,
+ (double)finfo.size));
+ shallitime=0;
+ ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
+ ntarf++;
+ return;
+ }
+
+ fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
+
+ dos_clean_name(rname);
+
+ if (fnum == -1) {
+ DEBUG(0,("%s opening remote file %s (%s)\n",
+ cli_errstr(cli),rname, cur_dir));
+ return;
+ }
+
+ finfo.name = string_create_s(strlen(rname));
+ if (finfo.name == NULL) {
+ DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n"));
+ return;
+ }
+
+ safe_strcpy(finfo.name,rname, strlen(rname));
+ if (!finfo1) {
+ if (!cli_getattrE(cli, fnum, &finfo.mode, &finfo.size, NULL, &finfo.atime, &finfo.mtime)) {
+ DEBUG(0, ("getattrE: %s\n", cli_errstr(cli)));
+ return;
+ }
+ finfo.ctime = finfo.mtime;
+ }
+
+ DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
+
+ if (tar_inc && !(finfo.mode & aARCH)) {
+ DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name));
+ shallitime=0;
+ } else if (!tar_system && (finfo.mode & aSYSTEM)) {
+ DEBUG(4, ("skipping %s - system bit is set\n", finfo.name));
+ shallitime=0;
+ } else if (!tar_hidden && (finfo.mode & aHIDDEN)) {
+ DEBUG(4, ("skipping %s - hidden bit is set\n", finfo.name));
+ shallitime=0;
+ } else {
+ DEBUG(3,("getting file %s of size %.0f bytes as a tar file %s",
+ finfo.name, (double)finfo.size, lname));
- /* write a tar header, don't bother with mode - just set to 100644 */
- writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype);
+ /* write a tar header, don't bother with mode - just set to 100644 */
+ writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0", ftype);
- while (nread < finfo.size && !close_done) {
+ while (nread < finfo.size && !close_done) {
- DEBUG(3,("nread=%.0f\n",(double)nread));
+ DEBUG(3,("nread=%.0f\n",(double)nread));
- datalen = cli_read(cli, fnum, data, nread, read_size);
+ datalen = cli_read(cli, fnum, data, nread, read_size);
- if (datalen == -1) {
- DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
- break;
- }
+ if (datalen == -1) {
+ DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
+ break;
+ }
- nread += datalen;
-
- /* if file size has increased since we made file size query, truncate
- read so tar header for this file will be correct.
- */
-
- if (nread > finfo.size) {
- datalen -= nread - finfo.size;
- DEBUG(0,("File size change - truncating %s to %.0f bytes\n", finfo.name, (double)finfo.size));
- }
-
- /* add received bits of file to buffer - dotarbuf will
- * write out in 512 byte intervals */
- if (dotarbuf(tarhandle,data,datalen) != datalen) {
- DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
- break;
- }
+ nread += datalen;
+
+ /* if file size has increased since we made file size query, truncate
+ read so tar header for this file will be correct.
+ */
+
+ if (nread > finfo.size) {
+ datalen -= nread - finfo.size;
+ DEBUG(0,("File size change - truncating %s to %.0f bytes\n",
+ finfo.name, (double)finfo.size));
+ }
+
+ /* add received bits of file to buffer - dotarbuf will
+ * write out in 512 byte intervals */
+
+ if (dotarbuf(tarhandle,data,datalen) != datalen) {
+ DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
+ break;
+ }
- if (datalen == 0) {
- DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
- break;
- }
-
- datalen=0;
- }
-
- /* pad tar file with zero's if we couldn't get entire file */
- if (nread < finfo.size) {
- DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", (double)finfo.size, (int)nread));
- if (padit(data, sizeof(data), finfo.size - nread))
- DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
- }
-
- /* round tar file to nearest block */
- if (finfo.size % TBLOCK)
- dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
+ if (datalen == 0) {
+ DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
+ break;
+ }
+
+ datalen=0;
+ }
+
+ /* pad tar file with zero's if we couldn't get entire file */
+ if (nread < finfo.size) {
+ DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n",
+ (double)finfo.size, (int)nread));
+ if (padit(data, sizeof(data), finfo.size - nread))
+ DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
+ }
+
+ /* round tar file to nearest block */
+ if (finfo.size % TBLOCK)
+ dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
- ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
- ntarf++;
- }
+ ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
+ ntarf++;
+ }
- cli_close(cli, fnum);
+ cli_close(cli, fnum);
- if (shallitime)
- {
- struct timeval tp_end;
- int this_time;
+ if (shallitime) {
+ struct timeval tp_end;
+ int this_time;
- /* if shallitime is true then we didn't skip */
- if (tar_reset && !dry_run)
- (void) do_setrattr(finfo.name, aARCH, ATTRRESET);
+ /* if shallitime is true then we didn't skip */
+ if (tar_reset && !dry_run)
+ (void) do_setrattr(finfo.name, aARCH, ATTRRESET);
- GetTimeOfDay(&tp_end);
- this_time =
- (tp_end.tv_sec - tp_start.tv_sec)*1000 +
- (tp_end.tv_usec - tp_start.tv_usec)/1000;
- get_total_time_ms += this_time;
- get_total_size += finfo.size;
-
- if (tar_noisy)
- {
- DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
- (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
- finfo.name));
- }
+ GetTimeOfDay(&tp_end);
+ this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000;
+ get_total_time_ms += this_time;
+ get_total_size += finfo.size;
+
+ if (tar_noisy) {
+ DEBUG(0, ("%12.0f (%7.1f kb/s) %s\n",
+ (double)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
+ finfo.name));
+ }
- /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */
- DEBUG(3,("(%g kb/s) (average %g kb/s)\n",
- finfo.size / MAX(0.001, (1.024*this_time)),
- get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
- }
+ /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */
+ DEBUG(3,("(%g kb/s) (average %g kb/s)\n",
+ finfo.size / MAX(0.001, (1.024*this_time)),
+ get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
+ }
}
/****************************************************************************
Append single file to tar file (or not)
***************************************************************************/
+
static void do_tar(file_info *finfo)
{
- pstring rname;
+ pstring rname;
- if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
- return;
+ if (strequal(finfo->name,"..") || strequal(finfo->name,"."))
+ return;
- /* Is it on the exclude list ? */
- if (!tar_excl && clipn) {
- pstring exclaim;
+ /* Is it on the exclude list ? */
+ if (!tar_excl && clipn) {
+ pstring exclaim;
- DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
+ DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
- pstrcpy(exclaim, cur_dir);
- *(exclaim+strlen(exclaim)-1)='\0';
+ pstrcpy(exclaim, cur_dir);
+ *(exclaim+strlen(exclaim)-1)='\0';
- pstrcat(exclaim, "\\");
- pstrcat(exclaim, finfo->name);
+ pstrcat(exclaim, "\\");
+ pstrcat(exclaim, finfo->name);
- DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
+ DEBUG(5, ("...tar_re_search: %d\n", tar_re_search));
- if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) ||
+ if ((!tar_re_search && clipfind(cliplist, clipn, exclaim)) ||
#ifdef HAVE_REGEX_H
- (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) {
+ (tar_re_search && !regexec(preg, exclaim, 0, NULL, 0))) {
#else
- (tar_re_search && mask_match(exclaim, cliplist[0], True))) {
+ (tar_re_search && mask_match(exclaim, cliplist[0], True))) {
#endif
- DEBUG(3,("Skipping file %s\n", exclaim));
- return;
- }
- }
-
- if (finfo->mode & aDIR)
- {
- pstring saved_curdir;
- pstring mtar_mask;
-
- pstrcpy(saved_curdir, cur_dir);
-
- DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir), (int)strlen(cur_dir), (int)strlen(finfo->name), finfo->name, cur_dir));
-
- pstrcat(cur_dir,finfo->name);
- pstrcat(cur_dir,"\\");
-
- DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir));
-
- /* write a tar directory, don't bother with mode - just set it to
- * 40755 */
- writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5');
- if (tar_noisy) {
- DEBUG(0,(" directory %s\n", cur_dir));
- }
- ntarf++; /* Make sure we have a file on there */
- pstrcpy(mtar_mask,cur_dir);
- pstrcat(mtar_mask,"*");
- DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
- do_list(mtar_mask, attribute, do_tar, False, True);
- pstrcpy(cur_dir,saved_curdir);
- }
- else
- {
- pstrcpy(rname,cur_dir);
- pstrcat(rname,finfo->name);
- do_atar(rname,finfo->name,finfo);
- }
+ DEBUG(3,("Skipping file %s\n", exclaim));
+ return;
+ }
+ }
+
+ if (finfo->mode & aDIR) {
+ pstring saved_curdir;
+ pstring mtar_mask;
+
+ pstrcpy(saved_curdir, cur_dir);
+
+ DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, \
+strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n",
+ (int)sizeof(cur_dir), (int)strlen(cur_dir),
+ (int)strlen(finfo->name), finfo->name, cur_dir));
+
+ pstrcat(cur_dir,finfo->name);
+ pstrcat(cur_dir,"\\");
+
+ DEBUG(5, ("Writing a dir, Name = %s\n", cur_dir));
+
+ /* write a tar directory, don't bother with mode - just set it to
+ * 40755 */
+ writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0", '5');
+ if (tar_noisy) {
+ DEBUG(0,(" directory %s\n", cur_dir));
+ }
+ ntarf++; /* Make sure we have a file on there */
+ pstrcpy(mtar_mask,cur_dir);
+ pstrcat(mtar_mask,"*");
+ DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask));
+ do_list(mtar_mask, attribute, do_tar, False, True);
+ pstrcpy(cur_dir,saved_curdir);
+ } else {
+ pstrcpy(rname,cur_dir);
+ pstrcat(rname,finfo->name);
+ do_atar(rname,finfo->name,finfo);
+ }
}
/****************************************************************************
Convert from UNIX to DOS file names
***************************************************************************/
+
static void unfixtarname(char *tptr, char *fp, int l, BOOL first)
{
/* remove '.' from start of file name, convert from unix /'s to
@@ -886,79 +866,72 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first)
string_replace(tptr, '/', '\\');
}
-
/****************************************************************************
Move to the next block in the buffer, which may mean read in another set of
blocks. FIXME, we should allow more than one block to be skipped.
****************************************************************************/
+
static int next_block(char *ltarbuf, char **bufferp, int bufsiz)
{
- int bufread, total = 0;
-
- DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp));
- *bufferp += TBLOCK;
- total = TBLOCK;
-
- if (*bufferp >= (ltarbuf + bufsiz)) {
-
- DEBUG(5, ("Reading more data into ltarbuf ...\n"));
-
- /*
- * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>
- * Fixes bug where read can return short if coming from
- * a pipe.
- */
-
- bufread = read(tarhandle, ltarbuf, bufsiz);
- total = bufread;
-
- while (total < bufsiz) {
- if (bufread < 0) { /* An error, return false */
- return (total > 0 ? -2 : bufread);
- }
- if (bufread == 0) {
- if (total <= 0) {
- return -2;
- }
- break;
- }
- bufread = read(tarhandle, &ltarbuf[total], bufsiz - total);
- total += bufread;
- }
-
- DEBUG(5, ("Total bytes read ... %i\n", total));
-
- *bufferp = ltarbuf;
+ int bufread, total = 0;
+
+ DEBUG(5, ("Advancing to next block: %0lx\n", (unsigned long)*bufferp));
+ *bufferp += TBLOCK;
+ total = TBLOCK;
+
+ if (*bufferp >= (ltarbuf + bufsiz)) {
+
+ DEBUG(5, ("Reading more data into ltarbuf ...\n"));
+
+ /*
+ * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>
+ * Fixes bug where read can return short if coming from
+ * a pipe.
+ */
+
+ bufread = read(tarhandle, ltarbuf, bufsiz);
+ total = bufread;
+
+ while (total < bufsiz) {
+ if (bufread < 0) { /* An error, return false */
+ return (total > 0 ? -2 : bufread);
+ }
+ if (bufread == 0) {
+ if (total <= 0) {
+ return -2;
+ }
+ break;
+ }
+ bufread = read(tarhandle, &ltarbuf[total], bufsiz - total);
+ total += bufread;
+ }
- }
+ DEBUG(5, ("Total bytes read ... %i\n", total));
- return(total);
+ *bufferp = ltarbuf;
+ }
+ return(total);
}
/* Skip a file, even if it includes a long file name? */
static int skip_file(int skipsize)
{
- int dsize = skipsize;
-
- DEBUG(5, ("Skiping file. Size = %i\n", skipsize));
-
- /* FIXME, we should skip more than one block at a time */
-
- while (dsize > 0) {
+ int dsize = skipsize;
- if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
+ DEBUG(5, ("Skiping file. Size = %i\n", skipsize));
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
- return(False);
+ /* FIXME, we should skip more than one block at a time */
- }
-
- dsize -= TBLOCK;
-
- }
+ while (dsize > 0) {
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+ return(False);
+ }
+ dsize -= TBLOCK;
+ }
- return(True);
+ return(True);
}
/*************************************************************
@@ -969,103 +942,94 @@ static int skip_file(int skipsize)
static int get_file(file_info2 finfo)
{
- int fnum = -1, pos = 0, dsize = 0, bpos = 0;
- SMB_BIG_UINT rsize = 0;
-
- DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size));
-
- if (ensurepath(finfo.name) &&
- (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) {
- DEBUG(0, ("abandoning restore\n"));
- return(False);
- }
-
- /* read the blocks from the tar file and write to the remote file */
-
- rsize = finfo.size; /* This is how much to write */
-
- while (rsize > 0) {
+ int fnum = -1, pos = 0, dsize = 0, bpos = 0;
+ SMB_BIG_UINT rsize = 0;
- /* We can only write up to the end of the buffer */
+ DEBUG(5, ("get_file: file: %s, size %.0f\n", finfo.name, (double)finfo.size));
- dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */
- dsize = MIN(dsize, rsize); /* Should be only what is left */
- DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos));
-
- if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) {
- DEBUG(0, ("Error writing remote file\n"));
- return 0;
- }
-
- rsize -= dsize;
- pos += dsize;
-
- /* Now figure out how much to move in the buffer */
+ if (ensurepath(finfo.name) &&
+ (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) {
+ DEBUG(0, ("abandoning restore\n"));
+ return(False);
+ }
- /* FIXME, we should skip more than one block at a time */
+ /* read the blocks from the tar file and write to the remote file */
- /* First, skip any initial part of the part written that is left over */
- /* from the end of the first TBLOCK */
+ rsize = finfo.size; /* This is how much to write */
- if ((bpos) && ((bpos + dsize) >= TBLOCK)) {
+ while (rsize > 0) {
- dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */
- bpos = 0;
+ /* We can only write up to the end of the buffer */
+ dsize = MIN(tbufsiz - (buffer_p - tarbuf) - bpos, 65520); /* Calculate the size to write */
+ dsize = MIN(dsize, rsize); /* Should be only what is left */
+ DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos));
- if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
- return False;
+ if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) {
+ DEBUG(0, ("Error writing remote file\n"));
+ return 0;
+ }
- }
+ rsize -= dsize;
+ pos += dsize;
- }
+ /* Now figure out how much to move in the buffer */
- /*
- * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>.
- * If the file being extracted is an exact multiple of
- * TBLOCK bytes then we don't want to extract the next
- * block from the tarfile here, as it will be done in
- * the caller of get_file().
- */
+ /* FIXME, we should skip more than one block at a time */
- while (((rsize != 0) && (dsize >= TBLOCK)) ||
- ((rsize == 0) && (dsize > TBLOCK))) {
+ /* First, skip any initial part of the part written that is left over */
+ /* from the end of the first TBLOCK */
- if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
- return False;
- }
+ if ((bpos) && ((bpos + dsize) >= TBLOCK)) {
+ dsize -= (TBLOCK - bpos); /* Get rid of the end of the first block */
+ bpos = 0;
- dsize -= TBLOCK;
- }
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) { /* and skip the block */
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+ return False;
+ }
+ }
- bpos = dsize;
+ /*
+ * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>.
+ * If the file being extracted is an exact multiple of
+ * TBLOCK bytes then we don't want to extract the next
+ * block from the tarfile here, as it will be done in
+ * the caller of get_file().
+ */
- }
+ while (((rsize != 0) && (dsize >= TBLOCK)) ||
+ ((rsize == 0) && (dsize > TBLOCK))) {
- /* Now close the file ... */
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+ return False;
+ }
- if (!cli_close(cli, fnum)) {
- DEBUG(0, ("Error closing remote file\n"));
- return(False);
- }
+ dsize -= TBLOCK;
+ }
+ bpos = dsize;
+ }
- /* Now we update the creation date ... */
+ /* Now close the file ... */
- DEBUG(5, ("Updating creation date on %s\n", finfo.name));
+ if (!cli_close(cli, fnum)) {
+ DEBUG(0, ("Error closing remote file\n"));
+ return(False);
+ }
- if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) {
- if (tar_real_noisy) {
- DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
- /*return(False); */ /* Ignore, as Win95 does not allow changes */
- }
- }
+ /* Now we update the creation date ... */
+ DEBUG(5, ("Updating creation date on %s\n", finfo.name));
- ntarf++;
+ if (!cli_setatr(cli, finfo.name, finfo.mode, finfo.mtime)) {
+ if (tar_real_noisy) {
+ DEBUG(0, ("Could not set time on file: %s\n", finfo.name));
+ /*return(False); */ /* Ignore, as Win95 does not allow changes */
+ }
+ }
- DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size));
-
- return(True);
+ ntarf++;
+ DEBUG(0, ("restore tar file %s of size %.0f bytes\n", finfo.name, (double)finfo.size));
+ return(True);
}
/* Create a directory. We just ensure that the path exists and return as there
@@ -1073,214 +1037,167 @@ static int get_file(file_info2 finfo)
*/
static int get_dir(file_info2 finfo)
{
+ DEBUG(0, ("restore directory %s\n", finfo.name));
- DEBUG(0, ("restore directory %s\n", finfo.name));
-
- if (!ensurepath(finfo.name)) {
-
- DEBUG(0, ("Problems creating directory\n"));
- return(False);
-
- }
-
- ntarf++;
- return(True);
-
+ if (!ensurepath(finfo.name)) {
+ DEBUG(0, ("Problems creating directory\n"));
+ return(False);
+ }
+ ntarf++;
+ return(True);
}
+
/* Get a file with a long file name ... first file has file name, next file
has the data. We only want the long file name, as the loop in do_tarput
will deal with the rest.
*/
static char * get_longfilename(file_info2 finfo)
{
- int namesize = strlen(finfo.name) + strlen(cur_dir) + 2;
- char *longname = malloc(namesize);
- int offset = 0, left = finfo.size;
- BOOL first = True;
-
- DEBUG(5, ("Restoring a long file name: %s\n", finfo.name));
- DEBUG(5, ("Len = %.0f\n", (double)finfo.size));
-
- if (longname == NULL) {
-
- DEBUG(0, ("could not allocate buffer of size %d for longname\n",
- namesize));
- return(NULL);
- }
-
- /* First, add cur_dir to the long file name */
+ int namesize = strlen(finfo.name) + strlen(cur_dir) + 2;
+ char *longname = malloc(namesize);
+ int offset = 0, left = finfo.size;
+ BOOL first = True;
- if (strlen(cur_dir) > 0) {
- strncpy(longname, cur_dir, namesize);
- offset = strlen(cur_dir);
- }
+ DEBUG(5, ("Restoring a long file name: %s\n", finfo.name));
+ DEBUG(5, ("Len = %.0f\n", (double)finfo.size));
- /* Loop through the blocks picking up the name */
-
- while (left > 0) {
-
- if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
+ if (longname == NULL) {
+ DEBUG(0, ("could not allocate buffer of size %d for longname\n", namesize));
+ return(NULL);
+ }
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
- return(NULL);
+ /* First, add cur_dir to the long file name */
- }
+ if (strlen(cur_dir) > 0) {
+ strncpy(longname, cur_dir, namesize);
+ offset = strlen(cur_dir);
+ }
- unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--);
- DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p));
+ /* Loop through the blocks picking up the name */
- offset += TBLOCK;
- left -= TBLOCK;
+ while (left > 0) {
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+ return(NULL);
+ }
- }
+ unfixtarname(longname + offset, buffer_p, MIN(TBLOCK, finfo.size), first--);
+ DEBUG(5, ("UnfixedName: %s, buffer: %s\n", longname, buffer_p));
- return(longname);
+ offset += TBLOCK;
+ left -= TBLOCK;
+ }
+ return(longname);
}
static void do_tarput(void)
{
- file_info2 finfo;
- struct timeval tp_start;
- char *longfilename = NULL, linkflag;
- int skip = False;
-
- GetTimeOfDay(&tp_start);
-
- DEBUG(5, ("RJS do_tarput called ...\n"));
-
- buffer_p = tarbuf + tbufsiz; /* init this to force first read */
-
- /* Now read through those files ... */
-
- while (True) {
-
- /* Get us to the next block, or the first block first time around */
-
- if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
-
- DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
-
- return;
-
- }
-
- DEBUG(5, ("Reading the next header ...\n"));
-
- switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) {
-
- case -2: /* Hmm, not good, but not fatal */
- DEBUG(0, ("Skipping %s...\n", finfo.name));
- if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) &&
- !skip_file(finfo.size)) {
-
- DEBUG(0, ("Short file, bailing out...\n"));
- return;
-
- }
-
- break;
-
- case -1:
- DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
- return;
-
- case 0: /* chksum is zero - looks like an EOF */
- DEBUG(0, ("tar: restored %d files and directories\n", ntarf));
- return; /* Hmmm, bad here ... */
-
- default:
- /* No action */
-
- break;
-
- }
+ file_info2 finfo;
+ struct timeval tp_start;
+ char *longfilename = NULL, linkflag;
+ int skip = False;
+
+ GetTimeOfDay(&tp_start);
+ DEBUG(5, ("RJS do_tarput called ...\n"));
+
+ buffer_p = tarbuf + tbufsiz; /* init this to force first read */
+
+ /* Now read through those files ... */
+ while (True) {
+ /* Get us to the next block, or the first block first time around */
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <= 0) {
+ DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
+ return;
+ }
- /* Now, do we have a long file name? */
+ DEBUG(5, ("Reading the next header ...\n"));
- if (longfilename != NULL) {
+ switch (readtarheader((union hblock *) buffer_p, &finfo, cur_dir)) {
+ case -2: /* Hmm, not good, but not fatal */
+ DEBUG(0, ("Skipping %s...\n", finfo.name));
+ if ((next_block(tarbuf, &buffer_p, tbufsiz) <= 0) && !skip_file(finfo.size)) {
+ DEBUG(0, ("Short file, bailing out...\n"));
+ return;
+ }
+ break;
- SAFE_FREE(finfo.name); /* Free the space already allocated */
- finfo.name = longfilename;
- longfilename = NULL;
+ case -1:
+ DEBUG(0, ("abandoning restore, -1 from read tar header\n"));
+ return;
- }
+ case 0: /* chksum is zero - looks like an EOF */
+ DEBUG(0, ("tar: restored %d files and directories\n", ntarf));
+ return; /* Hmmm, bad here ... */
- /* Well, now we have a header, process the file ... */
+ default:
+ /* No action */
+ break;
+ }
- /* Should we skip the file? We have the long name as well here */
+ /* Now, do we have a long file name? */
+ if (longfilename != NULL) {
+ SAFE_FREE(finfo.name); /* Free the space already allocated */
+ finfo.name = longfilename;
+ longfilename = NULL;
+ }
- skip = clipn &&
- ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl)
+ /* Well, now we have a header, process the file ... */
+ /* Should we skip the file? We have the long name as well here */
+ skip = clipn && ((!tar_re_search && clipfind(cliplist, clipn, finfo.name) ^ tar_excl) ||
#ifdef HAVE_REGEX_H
- || (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0)));
+ (tar_re_search && !regexec(preg, finfo.name, 0, NULL, 0)));
#else
- || (tar_re_search && mask_match(finfo.name, cliplist[0], True)));
+ (tar_re_search && mask_match(finfo.name, cliplist[0], True)));
#endif
- DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name));
-
- if (skip) {
-
- skip_file(finfo.size);
- continue;
-
- }
-
- /* We only get this far if we should process the file */
- linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag;
-
- switch (linkflag) {
-
- case '0': /* Should use symbolic names--FIXME */
-
- /*
- * Skip to the next block first, so we can get the file, FIXME, should
- * be in get_file ...
- * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
- * Fixes bug where file size in tarfile is zero.
- */
-
- if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
- DEBUG(0, ("Short file, bailing out...\n"));
- return;
- }
- if (!get_file(finfo)) {
- DEBUG(0, ("Abandoning restore\n"));
- return;
-
- }
- break;
-
- case '5':
- if (!get_dir(finfo)) {
- DEBUG(0, ("Abandoning restore \n"));
- return;
- }
- break;
-
- case 'L':
- longfilename = get_longfilename(finfo);
- if (!longfilename) {
- DEBUG(0, ("abandoning restore\n"));
- return;
-
- }
- DEBUG(5, ("Long file name: %s\n", longfilename));
- break;
-
- default:
- skip_file(finfo.size); /* Don't handle these yet */
- break;
-
- }
-
- }
-
+ DEBUG(5, ("Skip = %i, cliplist=%s, file=%s\n", skip, (cliplist?cliplist[0]:NULL), finfo.name));
+ if (skip) {
+ skip_file(finfo.size);
+ continue;
+ }
+ /* We only get this far if we should process the file */
+ linkflag = ((union hblock *)buffer_p) -> dbuf.linkflag;
+ switch (linkflag) {
+ case '0': /* Should use symbolic names--FIXME */
+ /*
+ * Skip to the next block first, so we can get the file, FIXME, should
+ * be in get_file ...
+ * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
+ * Fixes bug where file size in tarfile is zero.
+ */
+ if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
+ DEBUG(0, ("Short file, bailing out...\n"));
+ return;
+ }
+ if (!get_file(finfo)) {
+ DEBUG(0, ("Abandoning restore\n"));
+ return;
+ }
+ break;
+ case '5':
+ if (!get_dir(finfo)) {
+ DEBUG(0, ("Abandoning restore \n"));
+ return;
+ }
+ break;
+ case 'L':
+ longfilename = get_longfilename(finfo);
+ if (!longfilename) {
+ DEBUG(0, ("abandoning restore\n"));
+ return;
+ }
+ DEBUG(5, ("Long file name: %s\n", longfilename));
+ break;
+
+ default:
+ skip_file(finfo.size); /* Don't handle these yet */
+ break;
+ }
+ }
}
-
/*
* samba interactive commands
*/
@@ -1288,577 +1205,594 @@ static void do_tarput(void)
/****************************************************************************
Blocksize command
***************************************************************************/
+
int cmd_block(void)
{
- fstring buf;
- int block;
-
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf)))
- {
- DEBUG(0, ("blocksize <n>\n"));
- return 1;
- }
-
- block=atoi(buf);
- if (block < 0 || block > 65535)
- {
- DEBUG(0, ("blocksize out of range"));
- return 1;
- }
-
- blocksize=block;
- DEBUG(2,("blocksize is now %d\n", blocksize));
-
- return 0;
+ fstring buf;
+ int block;
+
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ DEBUG(0, ("blocksize <n>\n"));
+ return 1;
+ }
+
+ block=atoi(buf);
+ if (block < 0 || block > 65535) {
+ DEBUG(0, ("blocksize out of range"));
+ return 1;
+ }
+
+ blocksize=block;
+ DEBUG(2,("blocksize is now %d\n", blocksize));
+
+ return 0;
}
/****************************************************************************
command to set incremental / reset mode
***************************************************************************/
+
int cmd_tarmode(void)
{
- fstring buf;
-
- while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- if (strequal(buf, "full"))
- tar_inc=False;
- else if (strequal(buf, "inc"))
- tar_inc=True;
- else if (strequal(buf, "reset"))
- tar_reset=True;
- else if (strequal(buf, "noreset"))
- tar_reset=False;
- else if (strequal(buf, "system"))
- tar_system=True;
- else if (strequal(buf, "nosystem"))
- tar_system=False;
- else if (strequal(buf, "hidden"))
- tar_hidden=True;
- else if (strequal(buf, "nohidden"))
- tar_hidden=False;
- else if (strequal(buf, "verbose") || strequal(buf, "noquiet"))
- tar_noisy=True;
- else if (strequal(buf, "quiet") || strequal(buf, "noverbose"))
- tar_noisy=False;
- else DEBUG(0, ("tarmode: unrecognised option %s\n", buf));
- }
-
- DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
- tar_inc ? "incremental" : "full",
- tar_system ? "system" : "nosystem",
- tar_hidden ? "hidden" : "nohidden",
- tar_reset ? "reset" : "noreset",
- tar_noisy ? "verbose" : "quiet"));
-
- return 0;
+ fstring buf;
+
+ while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ if (strequal(buf, "full"))
+ tar_inc=False;
+ else if (strequal(buf, "inc"))
+ tar_inc=True;
+ else if (strequal(buf, "reset"))
+ tar_reset=True;
+ else if (strequal(buf, "noreset"))
+ tar_reset=False;
+ else if (strequal(buf, "system"))
+ tar_system=True;
+ else if (strequal(buf, "nosystem"))
+ tar_system=False;
+ else if (strequal(buf, "hidden"))
+ tar_hidden=True;
+ else if (strequal(buf, "nohidden"))
+ tar_hidden=False;
+ else if (strequal(buf, "verbose") || strequal(buf, "noquiet"))
+ tar_noisy=True;
+ else if (strequal(buf, "quiet") || strequal(buf, "noverbose"))
+ tar_noisy=False;
+ else
+ DEBUG(0, ("tarmode: unrecognised option %s\n", buf));
+ }
+
+ DEBUG(0, ("tarmode is now %s, %s, %s, %s, %s\n",
+ tar_inc ? "incremental" : "full",
+ tar_system ? "system" : "nosystem",
+ tar_hidden ? "hidden" : "nohidden",
+ tar_reset ? "reset" : "noreset",
+ tar_noisy ? "verbose" : "quiet"));
+ return 0;
}
/****************************************************************************
Feeble attrib command
***************************************************************************/
+
int cmd_setmode(void)
{
- char *q;
- fstring buf;
- pstring fname;
- uint16 attra[2];
- int direct=1;
-
- attra[0] = attra[1] = 0;
-
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf)))
- {
- DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
- return 1;
- }
-
- pstrcpy(fname, cur_dir);
- pstrcat(fname, buf);
-
- while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
- q=buf;
-
- while(*q)
- switch (*q++) {
- case '+': direct=1;
- break;
- case '-': direct=0;
- break;
- case 'r': attra[direct]|=aRONLY;
- break;
- case 'h': attra[direct]|=aHIDDEN;
- break;
- case 's': attra[direct]|=aSYSTEM;
- break;
- case 'a': attra[direct]|=aARCH;
- break;
- default: DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
- return 1;
- }
- }
+ char *q;
+ fstring buf;
+ pstring fname;
+ uint16 attra[2];
+ int direct=1;
+
+ attra[0] = attra[1] = 0;
- if (attra[ATTRSET]==0 && attra[ATTRRESET]==0)
- {
- DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
- return 1;
- }
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
+ return 1;
+ }
+
+ pstrcpy(fname, cur_dir);
+ pstrcat(fname, buf);
+
+ while (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ q=buf;
+
+ while(*q) {
+ switch (*q++) {
+ case '+':
+ direct=1;
+ break;
+ case '-':
+ direct=0;
+ break;
+ case 'r':
+ attra[direct]|=aRONLY;
+ break;
+ case 'h':
+ attra[direct]|=aHIDDEN;
+ break;
+ case 's':
+ attra[direct]|=aSYSTEM;
+ break;
+ case 'a':
+ attra[direct]|=aARCH;
+ break;
+ default:
+ DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
+ return 1;
+ }
+ }
+ }
- DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET]));
- do_setrattr(fname, attra[ATTRSET], ATTRSET);
- do_setrattr(fname, attra[ATTRRESET], ATTRRESET);
+ if (attra[ATTRSET]==0 && attra[ATTRRESET]==0) {
+ DEBUG(0, ("setmode <filename> <[+|-]rsha>\n"));
+ return 1;
+ }
- return 0;
+ DEBUG(2, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET]));
+ do_setrattr(fname, attra[ATTRSET], ATTRSET);
+ do_setrattr(fname, attra[ATTRRESET], ATTRRESET);
+ return 0;
}
/****************************************************************************
Principal command for creating / extracting
***************************************************************************/
+
int cmd_tar(void)
{
- fstring buf;
- char **argl;
- int argcl;
-
- if (!next_token_nr(NULL,buf,NULL,sizeof(buf)))
- {
- DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
- return 1;
- }
-
- argl=toktocliplist(&argcl, NULL);
- if (!tar_parseargs(argcl, argl, buf, 0))
- return 1;
+ fstring buf;
+ char **argl;
+ int argcl;
- process_tar();
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ DEBUG(0,("tar <c|x>[IXbgan] <filename>\n"));
+ return 1;
+ }
- SAFE_FREE(argl);
+ argl=toktocliplist(&argcl, NULL);
+ if (!tar_parseargs(argcl, argl, buf, 0))
+ return 1;
- return 0;
+ process_tar();
+ SAFE_FREE(argl);
+ return 0;
}
/****************************************************************************
Command line (option) version
***************************************************************************/
+
int process_tar(void)
{
- initarbuf();
- switch(tar_type) {
- case 'x':
+ initarbuf();
+ switch(tar_type) {
+ case 'x':
#if 0
- do_tarput2();
+ do_tarput2();
#else
- do_tarput();
+ do_tarput();
#endif
- SAFE_FREE(tarbuf);
- close(tarhandle);
- break;
- case 'r':
- case 'c':
- if (clipn && tar_excl) {
- int i;
- pstring tarmac;
-
- for (i=0; i<clipn; i++) {
- DEBUG(5,("arg %d = %s\n", i, cliplist[i]));
-
- if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') {
- *(cliplist[i]+strlen(cliplist[i])-1)='\0';
- }
+ SAFE_FREE(tarbuf);
+ close(tarhandle);
+ break;
+ case 'r':
+ case 'c':
+ if (clipn && tar_excl) {
+ int i;
+ pstring tarmac;
+
+ for (i=0; i<clipn; i++) {
+ DEBUG(5,("arg %d = %s\n", i, cliplist[i]));
+
+ if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') {
+ *(cliplist[i]+strlen(cliplist[i])-1)='\0';
+ }
- if (strrchr_m(cliplist[i], '\\')) {
- pstring saved_dir;
+ if (strrchr_m(cliplist[i], '\\')) {
+ pstring saved_dir;
- pstrcpy(saved_dir, cur_dir);
+ pstrcpy(saved_dir, cur_dir);
- if (*cliplist[i]=='\\') {
- pstrcpy(tarmac, cliplist[i]);
- } else {
- pstrcpy(tarmac, cur_dir);
- pstrcat(tarmac, cliplist[i]);
- }
- pstrcpy(cur_dir, tarmac);
- *(strrchr_m(cur_dir, '\\')+1)='\0';
-
- DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
- do_list(tarmac,attribute,do_tar, False, True);
- pstrcpy(cur_dir,saved_dir);
- } else {
- pstrcpy(tarmac, cur_dir);
- pstrcat(tarmac, cliplist[i]);
- DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
- do_list(tarmac,attribute,do_tar, False, True);
- }
- }
- } else {
- pstring mask;
- pstrcpy(mask,cur_dir);
- DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
- pstrcat(mask,"\\*");
- do_list(mask,attribute,do_tar,False, True);
- }
+ if (*cliplist[i]=='\\') {
+ pstrcpy(tarmac, cliplist[i]);
+ } else {
+ pstrcpy(tarmac, cur_dir);
+ pstrcat(tarmac, cliplist[i]);
+ }
+ pstrcpy(cur_dir, tarmac);
+ *(strrchr_m(cur_dir, '\\')+1)='\0';
+
+ DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
+ do_list(tarmac,attribute,do_tar, False, True);
+ pstrcpy(cur_dir,saved_dir);
+ } else {
+ pstrcpy(tarmac, cur_dir);
+ pstrcat(tarmac, cliplist[i]);
+ DEBUG(5, ("process_tar, do_list with tarmac: %s\n", tarmac));
+ do_list(tarmac,attribute,do_tar, False, True);
+ }
+ }
+ } else {
+ pstring mask;
+ pstrcpy(mask,cur_dir);
+ DEBUG(5, ("process_tar, do_list with mask: %s\n", mask));
+ pstrcat(mask,"\\*");
+ do_list(mask,attribute,do_tar,False, True);
+ }
- if (ntarf) dotareof(tarhandle);
- close(tarhandle);
- SAFE_FREE(tarbuf);
+ if (ntarf)
+ dotareof(tarhandle);
+ close(tarhandle);
+ SAFE_FREE(tarbuf);
- DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
- DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
- break;
- }
-
- if (must_free_cliplist) {
- int i;
- for (i = 0; i < clipn; ++i) {
- SAFE_FREE(cliplist[i]);
- }
- SAFE_FREE(cliplist);
- cliplist = NULL;
- clipn = 0;
- must_free_cliplist = False;
- }
-
- return(0);
+ DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
+ DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
+ break;
+ }
+
+ if (must_free_cliplist) {
+ int i;
+ for (i = 0; i < clipn; ++i) {
+ SAFE_FREE(cliplist[i]);
+ }
+ SAFE_FREE(cliplist);
+ cliplist = NULL;
+ clipn = 0;
+ must_free_cliplist = False;
+ }
+ return(0);
}
/****************************************************************************
Find a token (filename) in a clip list
***************************************************************************/
+
static int clipfind(char **aret, int ret, char *tok)
{
- if (aret==NULL) return 0;
+ if (aret==NULL)
+ return 0;
- /* ignore leading slashes or dots in token */
- while(strchr_m("/\\.", *tok)) tok++;
+ /* ignore leading slashes or dots in token */
+ while(strchr_m("/\\.", *tok))
+ tok++;
- while(ret--) {
- char *pkey=*aret++;
+ while(ret--) {
+ char *pkey=*aret++;
- /* ignore leading slashes or dots in list */
- while(strchr_m("/\\.", *pkey)) pkey++;
+ /* ignore leading slashes or dots in list */
+ while(strchr_m("/\\.", *pkey))
+ pkey++;
- if (!strslashcmp(pkey, tok)) return 1;
- }
-
- return 0;
+ if (!strslashcmp(pkey, tok))
+ return 1;
+ }
+ return 0;
}
/****************************************************************************
Read list of files to include from the file and initialize cliplist
accordingly.
***************************************************************************/
+
static int read_inclusion_file(char *filename)
{
- XFILE *inclusion = NULL;
- char buf[MAXPATHLEN + 1];
- char *inclusion_buffer = NULL;
- int inclusion_buffer_size = 0;
- int inclusion_buffer_sofar = 0;
- char *p;
- char *tmpstr;
- int i;
- int error = 0;
-
- clipn = 0;
- buf[MAXPATHLEN] = '\0'; /* guarantee null-termination */
- if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) {
- /* XXX It would be better to include a reason for failure, but without
- * autoconf, it's hard to use strerror, sys_errlist, etc.
- */
- DEBUG(0,("Unable to open inclusion file %s\n", filename));
- return 0;
- }
-
- while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) {
- if (inclusion_buffer == NULL) {
- inclusion_buffer_size = 1024;
- if ((inclusion_buffer = malloc(inclusion_buffer_size)) == NULL) {
- DEBUG(0,("failure allocating buffer to read inclusion file\n"));
- error = 1;
- break;
- }
- }
+ XFILE *inclusion = NULL;
+ char buf[PATH_MAX + 1];
+ char *inclusion_buffer = NULL;
+ int inclusion_buffer_size = 0;
+ int inclusion_buffer_sofar = 0;
+ char *p;
+ char *tmpstr;
+ int i;
+ int error = 0;
+
+ clipn = 0;
+ buf[PATH_MAX] = '\0'; /* guarantee null-termination */
+ if ((inclusion = x_fopen(filename, O_RDONLY, 0)) == NULL) {
+ /* XXX It would be better to include a reason for failure, but without
+ * autoconf, it's hard to use strerror, sys_errlist, etc.
+ */
+ DEBUG(0,("Unable to open inclusion file %s\n", filename));
+ return 0;
+ }
+
+ while ((! error) && (x_fgets(buf, sizeof(buf)-1, inclusion))) {
+ if (inclusion_buffer == NULL) {
+ inclusion_buffer_size = 1024;
+ if ((inclusion_buffer = malloc(inclusion_buffer_size)) == NULL) {
+ DEBUG(0,("failure allocating buffer to read inclusion file\n"));
+ error = 1;
+ break;
+ }
+ }
- if (buf[strlen(buf)-1] == '\n') {
- buf[strlen(buf)-1] = '\0';
- }
+ if (buf[strlen(buf)-1] == '\n') {
+ buf[strlen(buf)-1] = '\0';
+ }
- if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
- char *ib;
- inclusion_buffer_size *= 2;
- ib = Realloc(inclusion_buffer,inclusion_buffer_size);
- if (! ib) {
- DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",
- inclusion_buffer_size));
- error = 1;
- break;
- }
- else inclusion_buffer = ib;
- }
+ if ((strlen(buf) + 1 + inclusion_buffer_sofar) >= inclusion_buffer_size) {
+ char *ib;
+ inclusion_buffer_size *= 2;
+ ib = Realloc(inclusion_buffer,inclusion_buffer_size);
+ if (! ib) {
+ DEBUG(0,("failure enlarging inclusion buffer to %d bytes\n",
+ inclusion_buffer_size));
+ error = 1;
+ break;
+ } else {
+ inclusion_buffer = ib;
+ }
+ }
- safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
- inclusion_buffer_sofar += strlen(buf) + 1;
- clipn++;
- }
- x_fclose(inclusion);
-
- if (! error) {
- /* Allocate an array of clipn + 1 char*'s for cliplist */
- cliplist = malloc((clipn + 1) * sizeof(char *));
- if (cliplist == NULL) {
- DEBUG(0,("failure allocating memory for cliplist\n"));
- error = 1;
- } else {
- cliplist[clipn] = NULL;
- p = inclusion_buffer;
- for (i = 0; (! error) && (i < clipn); i++) {
- /* set current item to NULL so array will be null-terminated even if
- * malloc fails below. */
- cliplist[i] = NULL;
- if ((tmpstr = (char *)malloc(strlen(p)+1)) == NULL) {
- DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i));
- error = 1;
- } else {
- unfixtarname(tmpstr, p, strlen(p) + 1, True);
- cliplist[i] = tmpstr;
- if ((p = strchr_m(p, '\000')) == NULL) {
- DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));
- abort();
- }
+ safe_strcpy(inclusion_buffer + inclusion_buffer_sofar, buf, inclusion_buffer_size - inclusion_buffer_sofar);
+ inclusion_buffer_sofar += strlen(buf) + 1;
+ clipn++;
+ }
+ x_fclose(inclusion);
+
+ if (! error) {
+ /* Allocate an array of clipn + 1 char*'s for cliplist */
+ cliplist = malloc((clipn + 1) * sizeof(char *));
+ if (cliplist == NULL) {
+ DEBUG(0,("failure allocating memory for cliplist\n"));
+ error = 1;
+ } else {
+ cliplist[clipn] = NULL;
+ p = inclusion_buffer;
+ for (i = 0; (! error) && (i < clipn); i++) {
+ /* set current item to NULL so array will be null-terminated even if
+ * malloc fails below. */
+ cliplist[i] = NULL;
+ if ((tmpstr = (char *)malloc(strlen(p)+1)) == NULL) {
+ DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", i));
+ error = 1;
+ } else {
+ unfixtarname(tmpstr, p, strlen(p) + 1, True);
+ cliplist[i] = tmpstr;
+ if ((p = strchr_m(p, '\000')) == NULL) {
+ DEBUG(0,("INTERNAL ERROR: inclusion_buffer is of unexpected contents.\n"));
+ abort();
+ }
+ }
+ ++p;
+ }
+ must_free_cliplist = True;
+ }
+ }
+
+ SAFE_FREE(inclusion_buffer);
+ if (error) {
+ if (cliplist) {
+ char **pp;
+ /* We know cliplist is always null-terminated */
+ for (pp = cliplist; *pp; ++pp) {
+ SAFE_FREE(*pp);
+ }
+ SAFE_FREE(cliplist);
+ cliplist = NULL;
+ must_free_cliplist = False;
+ }
+ return 0;
}
- ++p;
- }
- must_free_cliplist = True;
- }
- }
-
- SAFE_FREE(inclusion_buffer);
- if (error) {
- if (cliplist) {
- char **pp;
- /* We know cliplist is always null-terminated */
- for (pp = cliplist; *pp; ++pp) {
- SAFE_FREE(*pp);
- }
- SAFE_FREE(cliplist);
- cliplist = NULL;
- must_free_cliplist = False;
- }
- return 0;
- }
- /* cliplist and its elements are freed at the end of process_tar. */
- return 1;
+ /* cliplist and its elements are freed at the end of process_tar. */
+ return 1;
}
/****************************************************************************
Parse tar arguments. Sets tar_type, tar_excl, etc.
***************************************************************************/
-int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind)
+
+int tar_parseargs(int argc, char *argv[], const char *Optarg, int Optind)
{
- char tar_clipfl='\0';
-
- /* Reset back to defaults - could be from interactive version
- * reset mode and archive mode left as they are though
- */
- tar_type='\0';
- tar_excl=True;
- dry_run=False;
-
- while (*Optarg)
- switch(*Optarg++) {
- case 'c':
- tar_type='c';
- break;
- case 'x':
- if (tar_type=='c') {
- printf("Tar must be followed by only one of c or x.\n");
- return 0;
- }
- tar_type='x';
- break;
- case 'b':
- if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) {
- DEBUG(0,("Option b must be followed by valid blocksize\n"));
- return 0;
- } else {
- Optind++;
- }
- break;
- case 'g':
- tar_inc=True;
- break;
- case 'N':
- if (Optind>=argc) {
- DEBUG(0,("Option N must be followed by valid file name\n"));
- return 0;
- } else {
- SMB_STRUCT_STAT stbuf;
- extern time_t newer_than;
+ int newOptind = Optind;
+ char tar_clipfl='\0';
+
+ /* Reset back to defaults - could be from interactive version
+ * reset mode and archive mode left as they are though
+ */
+ tar_type='\0';
+ tar_excl=True;
+ dry_run=False;
+
+ while (*Optarg) {
+ switch(*Optarg++) {
+ case 'c':
+ tar_type='c';
+ break;
+ case 'x':
+ if (tar_type=='c') {
+ printf("Tar must be followed by only one of c or x.\n");
+ return 0;
+ }
+ tar_type='x';
+ break;
+ case 'b':
+ if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) {
+ DEBUG(0,("Option b must be followed by valid blocksize\n"));
+ return 0;
+ } else {
+ Optind++;
+ newOptind++;
+ }
+ break;
+ case 'g':
+ tar_inc=True;
+ break;
+ case 'N':
+ if (Optind>=argc) {
+ DEBUG(0,("Option N must be followed by valid file name\n"));
+ return 0;
+ } else {
+ SMB_STRUCT_STAT stbuf;
+ extern time_t newer_than;
- if (sys_stat(argv[Optind], &stbuf) == 0) {
- newer_than = stbuf.st_mtime;
- DEBUG(1,("Getting files newer than %s",
- asctime(LocalTime(&newer_than))));
- Optind++;
- } else {
- DEBUG(0,("Error setting newer-than time\n"));
- return 0;
+ if (sys_stat(argv[Optind], &stbuf) == 0) {
+ newer_than = stbuf.st_mtime;
+ DEBUG(1,("Getting files newer than %s",
+ asctime(LocalTime(&newer_than))));
+ newOptind++;
+ Optind++;
+ } else {
+ DEBUG(0,("Error setting newer-than time\n"));
+ return 0;
+ }
+ }
+ break;
+ case 'a':
+ tar_reset=True;
+ break;
+ case 'q':
+ tar_noisy=False;
+ break;
+ case 'I':
+ if (tar_clipfl) {
+ DEBUG(0,("Only one of I,X,F must be specified\n"));
+ return 0;
+ }
+ tar_clipfl='I';
+ break;
+ case 'X':
+ if (tar_clipfl) {
+ DEBUG(0,("Only one of I,X,F must be specified\n"));
+ return 0;
+ }
+ tar_clipfl='X';
+ break;
+ case 'F':
+ if (tar_clipfl) {
+ DEBUG(0,("Only one of I,X,F must be specified\n"));
+ return 0;
+ }
+ tar_clipfl='F';
+ break;
+ case 'r':
+ DEBUG(0, ("tar_re_search set\n"));
+ tar_re_search = True;
+ break;
+ case 'n':
+ if (tar_type == 'c') {
+ DEBUG(0, ("dry_run set\n"));
+ dry_run = True;
+ } else {
+ DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
+ return 0;
+ }
+ break;
+ default:
+ DEBUG(0,("Unknown tar option\n"));
+ return 0;
+ }
}
- }
- break;
- case 'a':
- tar_reset=True;
- break;
- case 'q':
- tar_noisy=False;
- break;
- case 'I':
- if (tar_clipfl) {
- DEBUG(0,("Only one of I,X,F must be specified\n"));
- return 0;
- }
- tar_clipfl='I';
- break;
- case 'X':
- if (tar_clipfl) {
- DEBUG(0,("Only one of I,X,F must be specified\n"));
- return 0;
- }
- tar_clipfl='X';
- break;
- case 'F':
- if (tar_clipfl) {
- DEBUG(0,("Only one of I,X,F must be specified\n"));
- return 0;
- }
- tar_clipfl='F';
- break;
- case 'r':
- DEBUG(0, ("tar_re_search set\n"));
- tar_re_search = True;
- break;
- case 'n':
- if (tar_type == 'c') {
- DEBUG(0, ("dry_run set\n"));
- dry_run = True;
- } else {
- DEBUG(0, ("n is only meaningful when creating a tar-file\n"));
- return 0;
- }
- break;
- default:
- DEBUG(0,("Unknown tar option\n"));
- return 0;
- }
-
- if (!tar_type) {
- printf("Option T must be followed by one of c or x.\n");
- return 0;
- }
-
- /* tar_excl is true if cliplist lists files to be included.
- * Both 'I' and 'F' mean include. */
- tar_excl=tar_clipfl!='X';
-
- if (tar_clipfl=='F') {
- if (argc-Optind-1 != 1) {
- DEBUG(0,("Option F must be followed by exactly one filename.\n"));
- return 0;
- }
- if (! read_inclusion_file(argv[Optind+1])) {
- return 0;
- }
- } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */
- char *tmpstr;
- char **tmplist;
- int clipcount;
-
- cliplist=argv+Optind+1;
- clipn=argc-Optind-1;
- clipcount = clipn;
-
- if ((tmplist=malloc(clipn*sizeof(char *))) == NULL) {
- DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n",
- clipn)
- );
- return 0;
- }
-
- for (clipcount = 0; clipcount < clipn; clipcount++) {
-
- DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount]));
-
- if ((tmpstr = (char *)malloc(strlen(cliplist[clipcount])+1)) == NULL) {
- DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n",
- clipcount)
- );
- return 0;
- }
- unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True);
- tmplist[clipcount] = tmpstr;
- DEBUG(5, ("Processed an item, %s\n", tmpstr));
-
- DEBUG(5, ("Cliplist is: %s\n", cliplist[0]));
- }
- cliplist = tmplist;
- must_free_cliplist = True;
- }
-
- if (Optind+1<argc && tar_re_search) { /* Doing regular expression seaches */
-#ifdef HAVE_REGEX_H
- int errcode;
- if ((preg = (regex_t *)malloc(65536)) == NULL) {
+ if (!tar_type) {
+ printf("Option T must be followed by one of c or x.\n");
+ return 0;
+ }
- DEBUG(0, ("Could not allocate buffer for regular expression search\n"));
- return;
+ /* tar_excl is true if cliplist lists files to be included.
+ * Both 'I' and 'F' mean include. */
+ tar_excl=tar_clipfl!='X';
- }
+ if (tar_clipfl=='F') {
+ if (argc-Optind-1 != 1) {
+ DEBUG(0,("Option F must be followed by exactly one filename.\n"));
+ return 0;
+ }
+ newOptind++;
+ Optind++;
+ if (! read_inclusion_file(argv[Optind])) {
+ return 0;
+ }
+ } else if (Optind+1<argc && !tar_re_search) { /* For backwards compatibility */
+ char *tmpstr;
+ char **tmplist;
+ int clipcount;
+
+ cliplist=argv+Optind+1;
+ clipn=argc-Optind-1;
+ clipcount = clipn;
+
+ if ((tmplist=malloc(clipn*sizeof(char *))) == NULL) {
+ DEBUG(0, ("Could not allocate space to process cliplist, count = %i\n", clipn));
+ return 0;
+ }
- if (errcode = regcomp(preg, argv[Optind + 1], REG_EXTENDED)) {
- char errstr[1024];
- size_t errlen;
+ for (clipcount = 0; clipcount < clipn; clipcount++) {
- errlen = regerror(errcode, preg, errstr, sizeof(errstr) - 1);
-
- DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv[Optind + 1], errstr));
- return;
+ DEBUG(5, ("Processing an item, %s\n", cliplist[clipcount]));
+
+ if ((tmpstr = (char *)malloc(strlen(cliplist[clipcount])+1)) == NULL) {
+ DEBUG(0, ("Could not allocate space for a cliplist item, # %i\n", clipcount));
+ return 0;
+ }
+
+ unfixtarname(tmpstr, cliplist[clipcount], strlen(cliplist[clipcount]) + 1, True);
+ tmplist[clipcount] = tmpstr;
+ DEBUG(5, ("Processed an item, %s\n", tmpstr));
+
+ DEBUG(5, ("Cliplist is: %s\n", cliplist[0]));
+ }
- }
+ cliplist = tmplist;
+ must_free_cliplist = True;
+
+ newOptind += clipn;
+ }
+
+ if (Optind+1<argc && tar_re_search) { /* Doing regular expression seaches */
+#ifdef HAVE_REGEX_H
+ int errcode;
+
+ if ((preg = (regex_t *)malloc(65536)) == NULL) {
+
+ DEBUG(0, ("Could not allocate buffer for regular expression search\n"));
+ return;
+ }
+
+ if (errcode = regcomp(preg, argv[Optind + 1], REG_EXTENDED)) {
+ char errstr[1024];
+ size_t errlen;
+
+ errlen = regerror(errcode, preg, errstr, sizeof(errstr) - 1);
+ DEBUG(0, ("Could not compile pattern buffer for re search: %s\n%s\n", argv[Optind + 1], errstr));
+ return;
+ }
#endif
- clipn=argc-Optind-1;
- cliplist=argv+Optind+1;
-
- }
-
- if (Optind>=argc || !strcmp(argv[Optind], "-")) {
- /* Sets tar handle to either 0 or 1, as appropriate */
- tarhandle=(tar_type=='c');
- /*
- * Make sure that dbf points to stderr if we are using stdout for
- * tar output
- */
- if (tarhandle == 1)
- dbf = x_stderr;
- } else {
- if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0))
- {
- if (!dry_run) {
- DEBUG(0,("Output is /dev/null, assuming dry_run\n"));
- dry_run = True;
+ clipn=argc-Optind-1;
+ cliplist=argv+Optind+1;
+ newOptind += clipn;
+ }
+
+ if (Optind>=argc || !strcmp(argv[Optind], "-")) {
+ /* Sets tar handle to either 0 or 1, as appropriate */
+ tarhandle=(tar_type=='c');
+ /*
+ * Make sure that dbf points to stderr if we are using stdout for
+ * tar output
+ */
+ if (tarhandle == 1) {
+ dbf = x_stderr;
+ }
+ if (!strcmp(argv[Optind], "-")) {
+ newOptind++;
+ }
+
+ } else {
+ if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0)) {
+ if (!dry_run) {
+ DEBUG(0,("Output is /dev/null, assuming dry_run\n"));
+ dry_run = True;
+ }
+ tarhandle=-1;
+ } else if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1)
+ || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0)) {
+ DEBUG(0,("Error opening local file %s - %s\n", argv[Optind], strerror(errno)));
+ return(0);
+ }
+ newOptind++;
}
- tarhandle=-1;
- } else
- if ((tar_type=='x' && (tarhandle = sys_open(argv[Optind], O_RDONLY, 0)) == -1)
- || (tar_type=='c' && (tarhandle=sys_creat(argv[Optind], 0644)) < 0))
- {
- DEBUG(0,("Error opening local file %s - %s\n",
- argv[Optind], strerror(errno)));
- return(0);
- }
- }
- return 1;
+ return newOptind;
}
diff --git a/source/client/smbmnt.c b/source/client/smbmnt.c
index ce406179cfd..0e36231bac7 100644
--- a/source/client/smbmnt.c
+++ b/source/client/smbmnt.c
@@ -94,9 +94,9 @@ parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
static char *
fullpath(const char *p)
{
- char path[MAXPATHLEN];
+ char path[PATH_MAX+1];
- if (strlen(p) > MAXPATHLEN-1) {
+ if (strlen(p) > PATH_MAX) {
return NULL;
}
diff --git a/source/client/smbmount.c b/source/client/smbmount.c
index 343d4f26757..156130758b1 100644
--- a/source/client/smbmount.c
+++ b/source/client/smbmount.c
@@ -428,7 +428,7 @@ static void send_fs_socket(char *the_service, char *mount_point, struct cli_stat
**/
static void init_mount(void)
{
- char mount_point[MAXPATHLEN+1];
+ char mount_point[PATH_MAX+1];
pstring tmp;
pstring svc2;
struct cli_state *c;
diff --git a/source/client/smbspool.c b/source/client/smbspool.c
index 68165792da3..5daefec5a55 100644
--- a/source/client/smbspool.c
+++ b/source/client/smbspool.c
@@ -282,7 +282,7 @@ smb_connect(const char *workgroup, /* I - Workgroup */
get_myname(myname);
nt_status = cli_full_connection(&c, myname, server, NULL, 0, share, "?????",
- username, workgroup, password, 0, NULL);
+ username, workgroup, password, 0, Undefined, NULL);
if (!NT_STATUS_IS_OK(nt_status)) {
fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status));
diff --git a/source/client/tree.c b/source/client/tree.c
index 3b90d15f652..97ad7742e31 100644
--- a/source/client/tree.c
+++ b/source/client/tree.c
@@ -69,7 +69,7 @@ static void tree_error_message(gchar *message) {
* workgroup type and return a path from there
*/
-static char path_string[1024];
+static pstring path_string;
char *get_path(GtkWidget *item)
{
@@ -112,7 +112,7 @@ char *get_path(GtkWidget *item)
* Now, build the path
*/
- snprintf(path_string, sizeof(path_string), "smb:/");
+ pstrcpy( path_string, "smb:/" );
for (j = i - 1; j >= 0; j--) {
@@ -151,7 +151,7 @@ static void cb_select_child (GtkWidget *root_tree, GtkWidget *child,
char dirbuf[512];
struct smbc_dirent *dirp;
struct stat st1;
- char path[1024], path1[1024];
+ pstring path, path1;
g_print ("select_child called for root tree %p, subtree %p, child %p\n",
root_tree, subtree, child);
diff --git a/source/configure.in b/source/configure.in
index 3469de2b592..6f38adfd92b 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -152,12 +152,10 @@ AC_SUBST(LIBSMBCLIENT)
AC_SUBST(PRINTLIBS)
AC_SUBST(AUTHLIBS)
AC_SUBST(ACLLIBS)
-AC_SUBST(ADSLIBS)
AC_SUBST(PASSDBLIBS)
AC_SUBST(IDMAP_LIBS)
AC_SUBST(KRB5_LIBS)
AC_SUBST(LDAP_LIBS)
-AC_SUBST(LDAP_OBJ)
AC_SUBST(SHLIB_PROGS)
AC_SUBST(SMBWRAPPER)
AC_SUBST(EXTRA_BIN_PROGS)
@@ -286,10 +284,10 @@ DYNEXP=
dnl Add modules that have to be built by default here
dnl These have to be built static:
-default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
+default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_reg rpc_lsa_ds rpc_wks rpc_net rpc_dfs rpc_srv rpc_spoolss auth_rhosts auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin"
dnl These are preferably build shared, and static if dlopen() is not available
-default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms"
+default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly"
if test "x$developer" = xyes; then
default_static_modules="$default_static_modules rpc_echo"
@@ -552,7 +550,7 @@ AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/
AC_CHECK_HEADERS(nss.h nss_common.h ns_api.h sys/security.h security/pam_appl.h security/pam_modules.h)
AC_CHECK_HEADERS(stropts.h poll.h)
AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h)
-AC_CHECK_HEADERS(sys/acl.h attr/xattr.h sys/cdefs.h glob.h)
+AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/cdefs.h glob.h)
# For experimental utmp support (lastlog on some BSD-like systems)
AC_CHECK_HEADERS(utmp.h utmpx.h lastlog.h)
@@ -843,7 +841,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 getgrouplist timegm)
+AC_CHECK_FUNCS(syslog vsyslog timegm)
AC_CHECK_FUNCS(setlocale nl_langinfo)
# setbuffer, shmget, shm_open are needed for smbtorture
AC_CHECK_FUNCS(setbuffer shmget shm_open backtrace_symbols)
@@ -867,6 +865,38 @@ AC_CHECK_FUNCS(pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64)
AC_CHECK_FUNCS(open64 _open64 __open64 creat64)
#
+#
+#
+case "$host_os" in
+ *linux*)
+ # glibc <= 2.3.2 has a broken getgrouplist
+ AC_TRY_RUN([
+#include <unistd.h>
+#include <sys/utsname.h>
+main() {
+ /* glibc up to 2.3 has a broken getgrouplist */
+#if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+ int libc_major = __GLIBC__;
+ int libc_minor = __GLIBC_MINOR__;
+
+ if (libc_major < 2)
+ exit(1);
+ if ((libc_major == 2) && (libc_minor <= 3))
+ exit(1);
+#endif
+ exit(0);
+}
+], [linux_getgrouplist_ok=yes], [linux_getgrouplist_ok=no])
+ if test x"$linux_getgrouplist_ok" = x"yes"; then
+ AC_DEFINE(HAVE_GETGROUPLIST, 1, [Have good getgrouplist])
+ fi
+ ;;
+ *)
+ AC_CHECK_FUNCS(getgrouplist)
+ ;;
+esac
+
+#
# stat64 family may need <sys/stat.h> on some systems, notably ReliantUNIX
#
@@ -946,6 +976,8 @@ AC_SEARCH_LIBS(getxattr, [attr])
AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr)
AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr)
AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr)
+AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove)
+AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef)
# Assume non-shared by default and override below
BLDSHARED="false"
@@ -1501,7 +1533,8 @@ AC_ARG_WITH(libiconv,
AC_MSG_ERROR(I won't take no for an answer)
else
if test "$withval" != "yes" ; then
- LOOK_DIRS="$withval $LOOK_DIRS"
+ ICONV_PATH_SPEC=yes
+ LOOK_DIRS="$withval"
fi
fi
])
@@ -1511,47 +1544,66 @@ for i in $LOOK_DIRS ; do
save_LIBS=$LIBS
save_LDFLAGS=$LDFLAGS
save_CPPFLAGS=$CPPFLAGS
- CPPFLAGS="-I$i/include"
- LDFLAGS="-L$i/lib"
+ CPPFLAGS="$CPPFLAGS -I$i/include"
+dnl This is here to handle -withval stuff for --with-libiconv
+ if test x"$ICONV_PATH_SPEC" = "xyes" ; then
+ LDFLAGS="-L$i/lib"
+ fi
LIBS=
export LDFLAGS LIBS CPPFLAGS
dnl Try to find iconv(3)
jm_ICONV($i)
- CPPFLAGS=$save_CPPFLAGS
if test "$ICONV_FOUND" = yes; then
- LDFLAGS=$save_LDFLAGS
LIB_ADD_DIR(LDFLAGS, "$i/lib")
CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
LIBS="$save_LIBS $LIBS"
ICONV_LOCATION=$i
export LDFLAGS LIBS CPPFLAGS
- break
- else
- LDFLAGS=$save_LDFLAGS
- LIBS=$save_LIBS
- export LDFLAGS LIBS CPPFLAGS
+dnl Now, check for a working iconv ... we want to do it here because
+dnl there might be a working iconv further down the list of LOOK_DIRS
+
+ ############
+ # check for iconv in libc
+ ic_save_LIBS="$LIBS"
+ if test x"$ICONV_PATH_SPEC" = "xyes" ; then
+ LIBS="$LIBS -L$ICONV_LOCATION/lib"
+ fi
+ AC_CACHE_CHECK([for working iconv],samba_cv_HAVE_NATIVE_ICONV,[
+ AC_TRY_RUN([
+#include <$jm_cv_include>
+main(){
+ iconv_t cd = iconv_open("ASCII", "UCS-2LE");
+ if (cd == 0 || cd == (iconv_t)-1) {
+ cd = iconv_open("CP850", "UCS-2LE");
+ if (cd == 0 || cd == (iconv_t)-1) {
+ cd = iconv_open("IBM850", "UCS-2LE"); /* Solaris has this */
+ if (cd == 0 || cd == (iconv_t)-1) {
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+ ],
+ samba_cv_HAVE_NATIVE_ICONV=yes,samba_cv_HAVE_NATIVE_ICONV=no,samba_cv_HAVE_NATIVE_ICONV=cross)])
+ LIBS="$ic_save_LIBS"
+ if test x"$samba_cv_HAVE_NATIVE_ICONV" = x"yes"; then
+ CPPFLAGS=$save_CPPFLAGS
+ CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
+ export CPPFLAGS
+ AC_DEFINE(HAVE_NATIVE_ICONV,1,[Whether to use native iconv])
+ break
+ fi
+dnl We didn't find a working iconv, so keep going
fi
+dnl We only need to clean these up here for the next pass through the loop
+ CPPFLAGS=$save_CPPFLAGS
+ LDFLAGS=$save_LDFLAGS
+ LIBS=$save_LIBS
+ export LDFLAGS LIBS CPPFLAGS
done
-############
-# check for iconv in libc
-ic_save_LIBS="$LIBS"
-LIBS="$LIBS -L$ICONV_LOCATION/lib"
-AC_CACHE_CHECK([for working iconv],samba_cv_HAVE_NATIVE_ICONV,[
-AC_TRY_RUN([
-#include <$jm_cv_include>
-main() {
- iconv_t cd = iconv_open("ASCII", "UCS-2LE");
- if (cd == 0 || cd == (iconv_t)-1) return -1;
- return 0;
-}
-],
-samba_cv_HAVE_NATIVE_ICONV=yes,samba_cv_HAVE_NATIVE_ICONV=no,samba_cv_HAVE_NATIVE_ICONV=cross)])
-if test x"$samba_cv_HAVE_NATIVE_ICONV" = x"yes"; then
- AC_DEFINE(HAVE_NATIVE_ICONV,1,[Whether to use native iconv])
-fi
-LIBS="$ic_save_LIBS"
if test x"$ICONV_FOUND" = x"no" -o x"$samba_cv_HAVE_NATIVE_ICONV" != x"yes" ; then
AC_MSG_WARN([Sufficient support for iconv function was not found.
@@ -2095,14 +2147,105 @@ AC_ARG_WITH(dfs,
AC_MSG_RESULT(no)
)
+########################################################
+# Compile with LDAP support?
+
+with_ldap_support=auto
+AC_MSG_CHECKING([for LDAP support])
+
+AC_ARG_WITH(ldap,
+[ --with-ldap LDAP support (default yes)],
+[ case "$withval" in
+ yes|no)
+ with_ldap_support=$withval
+ ;;
+ esac ])
+
+AC_MSG_RESULT($with_ldap_support)
+
+SMBLDAP=""
+AC_SUBST(SMBLDAP)
+if test x"$with_ldap_support" != x"no"; then
+
+ ##################################################################
+ # first test for ldap.h and lber.h
+ # (ldap.h is required for this test)
+ AC_CHECK_HEADERS(ldap.h lber.h)
+
+ if test x"$ac_cv_header_ldap_h" != x"yes"; then
+ if test x"$with_ldap_support" = x"yes"; then
+ AC_MSG_ERROR(ldap.h is needed for LDAP support)
+ else
+ AC_MSG_WARN(ldap.h is needed for LDAP support)
+ fi
+
+ with_ldap_support=no
+ fi
+fi
+
+if test x"$with_ldap_support" != x"no"; then
+ ac_save_LIBS=$LIBS
+
+ ##################################################################
+ # we might need the lber lib on some systems. To avoid link errors
+ # this test must be before the libldap test
+ AC_CHECK_LIB_EXT(lber, LDAP_LIBS, ber_scanf)
+
+ ########################################################
+ # now see if we can find the ldap libs in standard paths
+ AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init)
+
+ AC_CHECK_FUNC_EXT(ldap_domain2hostlist,$LDAP_LIBS)
+
+ ########################################################
+ # If we have LDAP, does it's rebind procedure take 2 or 3 arguments?
+ # Check found in pam_ldap 145.
+ AC_CHECK_FUNC_EXT(ldap_set_rebind_proc,$LDAP_LIBS)
+
+ LIBS="$LIBS $LDAP_LIBS"
+ AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, smb_ldap_cv_ldap_set_rebind_proc, [
+ AC_TRY_COMPILE([
+ #include <lber.h>
+ #include <ldap.h>],
+ [ldap_set_rebind_proc(0, 0, 0);],
+ [smb_ldap_cv_ldap_set_rebind_proc=3],
+ [smb_ldap_cv_ldap_set_rebind_proc=2]
+ )
+ ])
+
+ AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $smb_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc])
+
+ AC_CHECK_FUNC_EXT(ldap_initialize,$LDAP_LIBS)
+
+ if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then
+ AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])
+ default_static_modules="$default_static_modules pdb_ldap idmap_ldap";
+ SMBLDAP="lib/smbldap.o"
+ with_ldap_support=yes
+ AC_MSG_CHECKING(whether LDAP support is used)
+ AC_MSG_RESULT(yes)
+ else
+ if test x"$with_ldap_support" = x"yes"; then
+ AC_MSG_ERROR(libldap is needed for LDAP support)
+ else
+ AC_MSG_WARN(libldap is needed for LDAP support)
+ fi
+
+ LDAP_LIBS=""
+ with_ldap_support=no
+ fi
+ LIBS=$ac_save_LIBS
+fi
+
+
#################################################
# active directory support
with_ads_support=auto
-AC_MSG_CHECKING([whether to use Active Directory])
+AC_MSG_CHECKING([for Active Directory and krb5 support])
AC_ARG_WITH(ads,
-[ --with-ads Active Directory support (default yes)],
+[ --with-ads Active Directory support (default auto)],
[ case "$withval" in
yes|no)
with_ads_support="$withval"
@@ -2114,22 +2257,34 @@ AC_MSG_RESULT($with_ads_support)
FOUND_KRB5=no
KRB5_LIBS=""
+if test x"$with_ldap_support" != x"yes"; then
+ if test x"$with_ads_support" = x"yes"; then
+ AC_MSG_ERROR(Active Directory Support requires LDAP support)
+ elif test x"$with_ads_support" != x"no"; then
+ AC_MSG_WARN(Active Directory Support requires LDAP support)
+ fi
+ with_ads_support=no
+fi
+
if test x"$with_ads_support" != x"no"; then
# Do no harm to the values of CFLAGS and LIBS while testing for
# Kerberos support.
- ac_save_CFLAGS="$CFLAGS"
- ac_save_LIBS="$LIBS"
-
#################################################
# check for krb5-config from recent MIT and Heimdal kerberos 5
AC_PATH_PROG(KRB5_CONFIG, krb5-config)
AC_MSG_CHECKING(for working krb5-config)
if test -x "$KRB5_CONFIG"; then
- LIBS="$LIBS `$KRB5_CONFIG --libs`"
- CFLAGS="$CFLAGS `$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
- CPPFLAGS="$CPPFLAGS `$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
+ ac_save_CFLAGS=$CFLAGS
+ CFLAGS="";export CFLAGS
+ ac_save_LDFLAGS=$LDFLAGS
+ LDFLAGS="";export LDFLAGS
+ KRB5_LIBS="`$KRB5_CONFIG --libs gssapi`"
+ KRB5_CFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
+ KRB5_CPPFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
+ CFLAGS=$ac_save_CFLAGS;export CFLAGS
+ LDFLAGS=$ac_save_LDFLAGS;export LDFLAGS
FOUND_KRB5=yes
AC_MSG_RESULT(yes)
else
@@ -2144,18 +2299,21 @@ if test x"$with_ads_support" != x"no"; then
[ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)],
[ case "$withval" in
no)
- AC_MSG_RESULT(no)
+ AC_MSG_RESULT(no krb5-path given)
+ ;;
+ yes)
+ AC_MSG_RESULT(/usr)
+ FOUND_KRB5=yes
;;
*)
- AC_MSG_RESULT(yes)
- LIBS="$LIBS -lkrb5"
- CFLAGS="$CFLAGS -I$withval/include"
- CPPFLAGS="$CPPFLAGS -I$withval/include"
- LDFLAGS="$LDFLAGS -L$withval/lib"
+ AC_MSG_RESULT($withval)
+ KRB5_CFLAGS="-I$withval/include"
+ KRB5_CPPFLAGS="-I$withval/include"
+ KRB5_LDFLAGS="-L$withval/lib"
FOUND_KRB5=yes
;;
esac ],
- AC_MSG_RESULT(no)
+ AC_MSG_RESULT(no krb5-path given)
)
fi
@@ -2165,15 +2323,13 @@ if test x"$with_ads_support" != x"no"; then
AC_MSG_CHECKING(for /usr/include/heimdal)
if test -d /usr/include/heimdal; then
if test -f /usr/lib/heimdal/lib/libkrb5.a; then
- LIBS="$LIBS -lkrb5"
- CFLAGS="$CFLAGS -I/usr/include/heimdal"
- CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
- LDFLAGS="$LDFLAGS -L/usr/lib/heimdal/lib"
+ KRB5_CFLAGS="-I/usr/include/heimdal"
+ KRB5_CPPFLAGS="-I/usr/include/heimdal"
+ KRB5_LDFLAGS="-L/usr/lib/heimdal/lib"
AC_MSG_RESULT(yes)
else
- LIBS="$LIBS -lkrb5"
- CFLAGS="$CFLAGS -I/usr/include/heimdal"
- CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
+ KRB5_CFLAGS="-I/usr/include/heimdal"
+ KRB5_CPPFLAGS="-I/usr/include/heimdal"
AC_MSG_RESULT(yes)
fi
else
@@ -2186,16 +2342,25 @@ if test x"$with_ads_support" != x"no"; then
# see if this box has the RedHat location for kerberos
AC_MSG_CHECKING(for /usr/kerberos)
if test -d /usr/kerberos -a -f /usr/kerberos/lib/libkrb5.a; then
- LIBS="$LIBS -lkrb5"
- LDFLAGS="$LDFLAGS -L/usr/kerberos/lib"
- CFLAGS="$CFLAGS -I/usr/kerberos/include"
- CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include"
+ KRB5_LDFLAGS="-L/usr/kerberos/lib"
+ KRB5_CFLAGS="-I/usr/kerberos/include"
+ KRB5_CPPFLAGS="-I/usr/kerberos/include"
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
fi
fi
+ ac_save_CFLAGS=$CFLAGS
+ ac_save_CPPFLAGS=$CPPFLAGS
+ ac_save_LDFLAGS=$LDFLAGS
+
+ CFLAGS="$CFLAGS $KRB5_CFLAGS"
+ CPPFLAGS="$CPPFLAGS $KRB5_CPPFLAGS"
+ LDFLAGS="$LDFLAGS $KRB5_LDFLAGS"
+
+ KRB5_LIBS="$KRB5_LDFLAGS $KRB5_LIBS"
+
# now check for krb5.h. Some systems have the libraries without the headers!
# note that this check is done here to allow for different kerberos
# include paths
@@ -2215,24 +2380,17 @@ if test x"$with_ads_support" != x"no"; then
# Turn off AD support and restore CFLAGS and LIBS variables
with_ads_support="no"
-
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
-
- else
-
- # Get rid of case where $with_ads_support=auto
-
- with_ads_support="yes"
-
+
+ CFLAGS=$ac_save_CFLAGS
+ CPPFLAGS=$ac_save_CPPFLAGS
+ LDFLAGS=$ac_save_LDFLAGS
fi
fi
# Now we have determined whether we really want ADS support
-if test x"$with_ads_support" = x"yes"; then
-
- AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory support])
+if test x"$with_ads_support" != x"no"; then
+ ac_save_LIBS=$LIBS
# now check for gssapi headers. This is also done here to allow for
# different kerberos include paths
@@ -2240,77 +2398,46 @@ if test x"$with_ads_support" = x"yes"; then
##################################################################
# we might need the k5crypto and com_err libraries on some systems
- AC_CHECK_LIB(com_err, _et_list)
- AC_CHECK_LIB(k5crypto, krb5_encrypt_data)
+ AC_CHECK_LIB_EXT(com_err, KRB5_LIBS, _et_list)
+ AC_CHECK_LIB_EXT(k5crypto, KRB5_LIBS, krb5_encrypt_data)
# Heimdal checks.
- AC_CHECK_LIB(crypto, des_set_key)
- AC_CHECK_LIB(asn1, copy_Authenticator)
- AC_CHECK_LIB(roken, roken_getaddrinfo_hostspec)
+ AC_CHECK_LIB_EXT(crypto, KRB5_LIBS, des_set_key)
+ AC_CHECK_LIB_EXT(asn1, KRB5_LIBS, copy_Authenticator)
+ AC_CHECK_LIB_EXT(roken, KRB5_LIBS, roken_getaddrinfo_hostspec)
# Heimdal checks. On static Heimdal gssapi must be linked before krb5.
- AC_CHECK_LIB(gssapi, gss_display_status, [LIBS="$LIBS -lgssapi -lkrb5";
- AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])])
-
- AC_CHECK_LIB(krb5, krb5_set_real_time,
- [AC_DEFINE(HAVE_KRB5_SET_REAL_TIME,1,
- [Whether krb5_set_real_time is available])])
- AC_CHECK_LIB(krb5, krb5_set_default_in_tkt_etypes,
- [AC_DEFINE(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES,1,
- [Whether krb5_set_default_in_tkt_etypes, is available])])
- AC_CHECK_LIB(krb5, krb5_set_default_tgs_ktypes,
- [AC_DEFINE(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES,1,
- [Whether krb5_set_default_tgs_ktypes is available])])
-
- AC_CHECK_LIB(krb5, krb5_principal2salt,
- [AC_DEFINE(HAVE_KRB5_PRINCIPAL2SALT,1,
- [Whether krb5_principal2salt is available])])
- AC_CHECK_LIB(krb5, krb5_use_enctype,
- [AC_DEFINE(HAVE_KRB5_USE_ENCTYPE,1,
- [Whether krb5_use_enctype is available])])
- AC_CHECK_LIB(krb5, krb5_string_to_key,
- [AC_DEFINE(HAVE_KRB5_STRING_TO_KEY,1,
- [Whether krb5_string_to_key is available])])
- AC_CHECK_LIB(krb5, krb5_get_pw_salt,
- [AC_DEFINE(HAVE_KRB5_GET_PW_SALT,1,
- [Whether krb5_get_pw_salt is available])])
- AC_CHECK_LIB(krb5, krb5_string_to_key_salt,
- [AC_DEFINE(HAVE_KRB5_STRING_TO_KEY_SALT,1,
- [Whether krb5_string_to_key_salt is available])])
- AC_CHECK_LIB(krb5, krb5_auth_con_setkey,
- [AC_DEFINE(HAVE_KRB5_AUTH_CON_SETKEY,1,
- [Whether krb5_auth_con_setkey is available])])
- AC_CHECK_LIB(krb5, krb5_auth_con_setuseruserkey,
- [AC_DEFINE(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY,1,
- [Whether krb5_auth_con_setuseruserkey is available])])
- AC_CHECK_LIB(krb5, krb5_locate_kdc,
- [AC_DEFINE(HAVE_KRB5_LOCATE_KDC,1,
- [Whether krb5_locate_kdc is available])])
- AC_CHECK_LIB(krb5, krb5_get_permitted_enctypes,
- [AC_DEFINE(HAVE_KRB5_GET_PERMITTED_ENCTYPES,1,
- [Whether krb5_get_permitted_enctypes is available])])
- AC_CHECK_LIB(krb5, krb5_get_default_in_tkt_etypes,
- [AC_DEFINE(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES,1,
- [Whether krb5_get_default_in_tkt_etypes is available])])
- AC_CHECK_LIB(krb5, krb5_free_ktypes,
- [AC_DEFINE(HAVE_KRB5_FREE_KTYPES,1,
- [Whether krb5_free_ktypes is available])])
- AC_CHECK_LIB(krb5, krb5_principal_get_comp_string,
- [AC_DEFINE(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING,1,
- [Whether krb5_principal_get_comp_string is available])])
- AC_CACHE_CHECK([for the krb5_princ_component macro],
- samba_cv_HAVE_KRB5_PRINC_COMPONENT,[
- AC_TRY_LINK([#include <krb5.h>],
- [const krb5_data *pkdata; krb5_context context; krb5_principal principal; pkdata = krb5_princ_component(context, principal, 0);],
- samba_cv_HAVE_KRB5_PRINC_COMPONENT=yes,
- samba_cv_HAVE_KRB5_PRINC_COMPONENT=no)])
-
- if test x"$samba_cv_HAVE_KRB5_PRINC_COMPONENT" = x"yes"; then
- AC_DEFINE(HAVE_KRB5_PRINC_COMPONENT,1,
- [Whether krb5_princ_component is available])
- fi
+ AC_CHECK_LIB_EXT(gssapi, KRB5_LIBS, gss_display_status,[],[],
+ AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available]))
+ ########################################################
+ # now see if we can find the krb5 libs in standard paths
+ # or as specified above
+ AC_CHECK_LIB_EXT(krb5, KRB5_LIBS, krb5_mk_req_extended)
+ ########################################################
+ # now see if we can find the gssapi libs in standard paths
+ AC_CHECK_LIB_EXT(gssapi_krb5, KRB5_LIBS,gss_display_status,[],[],
+ AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available]))
+
+ AC_CHECK_FUNC_EXT(krb5_set_real_time, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_set_default_in_tkt_etypes, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_set_default_tgs_ktypes, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_principal2salt, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_use_enctype, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_string_to_key, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_get_pw_salt, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_string_to_key_salt, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_auth_con_setkey, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_auth_con_setuseruserkey, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_locate_kdc, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_get_permitted_enctypes, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_get_default_in_tkt_etypes, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_free_ktypes, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_principal_get_comp_string, $KRB5_LIBS)
+
+ LIBS="$LIBS $KRB5_LIBS"
+
AC_CACHE_CHECK([for addrtype in krb5_address],
samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS,[
AC_TRY_COMPILE([#include <krb5.h>],
@@ -2370,87 +2497,34 @@ if test x"$with_ads_support" = x"yes"; then
[Whether the ENCTYPE_ARCFOUR_HMAC_MD5 key type is available])
fi
- ########################################################
- # now see if we can find the krb5 libs in standard paths
- # or as specified above
- AC_CHECK_LIB(krb5, krb5_mk_req_extended, [KRB5_LIBS="$LIBS -lkrb5";
- KRB5_CFLAGS="$CFLAGS";
- AC_DEFINE(HAVE_KRB5,1,[Whether KRB5 is available])])
-
- ########################################################
- # now see if we can find the gssapi libs in standard paths
- AC_CHECK_LIB(gssapi_krb5, gss_display_status,
- [KRB5_LIBS="$KRB5_LIBS -lgssapi_krb5";
- AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])])
-
- CFLAGS="$ac_save_CFLAGS"
- LIBS="$ac_save_LIBS"
-fi
-
-########################################################
-# Compile with LDAP support?
-
-LDAP_OBJ=""
-with_ldap_support=yes
-AC_MSG_CHECKING([whether to use LDAP])
-
-AC_ARG_WITH(ldap,
-[ --with-ldap LDAP support (default yes)],
-[ case "$withval" in
- no)
- with_ldap_support=no
- ;;
- esac ])
-
-AC_MSG_RESULT($with_ldap_support)
+ AC_CACHE_CHECK([for the krb5_princ_component macro],
+ samba_cv_HAVE_KRB5_PRINC_COMPONENT,[
+ AC_TRY_LINK([#include <krb5.h>],
+ [const krb5_data *pkdata; krb5_context context; krb5_principal principal; pkdata = krb5_princ_component(context, principal, 0);],
+ samba_cv_HAVE_KRB5_PRINC_COMPONENT=yes,
+ samba_cv_HAVE_KRB5_PRINC_COMPONENT=no)])
-SMBLDAP=""
-if test x"$with_ldap_support" = x"yes"; then
- ac_save_LIBS="$LIBS"
- LIBS=""
+ if test x"$samba_cv_HAVE_KRB5_PRINC_COMPONENT" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_PRINC_COMPONENT,1,
+ [Whether krb5_princ_component is available])
+ fi
- ##################################################################
- # we might need the lber lib on some systems. To avoid link errors
- # this test must be before the libldap test
- AC_CHECK_LIB(lber, ber_scanf)
- ########################################################
- # now see if we can find the ldap libs in standard paths
- if test x$have_ldap != xyes; then
- AC_CHECK_LIB(ldap, ldap_init, [
- LIBS="$LIBS -lldap";
- AC_CHECK_LIB(ldap, ldap_domain2hostlist, [
- AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available])
- AC_CHECK_HEADERS([ldap.h lber.h],
- [default_static_modules="$default_static_modules pdb_ldap idmap_ldap";
- SMBLDAP="lib/smbldap.o"])
- ])
- ])
-
- ########################################################
- # If we have LDAP, does it's rebind procedure take 2 or 3 arguments?
- # Check found in pam_ldap 145.
- AC_CHECK_FUNCS(ldap_set_rebind_proc)
- AC_CACHE_CHECK(whether ldap_set_rebind_proc takes 3 arguments, pam_ldap_cv_ldap_set_rebind_proc, [
- AC_TRY_COMPILE([
- #include <lber.h>
- #include <ldap.h>], [ldap_set_rebind_proc(0, 0, 0);], [pam_ldap_cv_ldap_set_rebind_proc=3], [pam_ldap_cv_ldap_set_rebind_proc=2]) ])
- AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $pam_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc])
- AC_CHECK_FUNCS(ldap_initialize)
- fi
-
- AC_SUBST(SMBLDAP)
- LDAP_LIBS="$LIBS";
- LIBS="$ac_save_LIBS";
-else
- # Can't have ADS support without LDAP
+ if test x"$ac_cv_lib_ext_krb5_krb5_mk_req_extended" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5,1,[Whether to have KRB5 support])
+ AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory support])
+ AC_MSG_CHECKING(whether Active Directory and krb5 support is used)
+ AC_MSG_RESULT(yes)
+ else
if test x"$with_ads_support" = x"yes"; then
- AC_MSG_ERROR(Active directory support requires LDAP)
+ AC_MSG_ERROR(libkrb5 is needed for Active Directory support)
+ else
+ AC_MSG_WARN(libkrb5 is needed for Active Directory support)
fi
-fi
-
-if test x"$with_ads_support" = x"yes"; then
- ADSLIBS="$LDAP_LIBS $KRB5_LIBS"
+ KRB5_LIBS=""
+ with_ads_support=no
+ fi
+ LIBS="$ac_save_LIBS"
fi
########################################################
@@ -2476,7 +2550,7 @@ AC_ARG_WITH(expsam,
;;
mysql)
## pdb_mysql
- AM_PATH_MYSQL([0.11.0],[default_shared_modules="$default_shared_modules pdb_mysql"],[])
+ AM_PATH_MYSQL([default_shared_modules="$default_shared_modules pdb_mysql"],[])
CFLAGS="$CFLAGS $MYSQL_CFLAGS"
;;
no)
@@ -3656,7 +3730,7 @@ WINBIND_WINS_NSS="nsswitch/libnss_wins.$SHLIBEXT"
WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS
case "$host_os" in
- *linux*)
+ *linux*|*freebsd*)
WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o"
;;
*irix*)
@@ -3868,10 +3942,11 @@ SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o, "bin/ldapsam.$SHLIBEXT", PDB,
SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB)
SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB)
SMB_MODULE(pdb_guest, passdb/pdb_guest.o, "bin/guest.$SHLIBEXT", PDB)
-SMB_SUBSYSTEM(PDB)
+SMB_SUBSYSTEM(PDB,passdb/pdb_interface.c)
SMB_MODULE(rpc_lsa, \$(RPC_LSA_OBJ), "bin/librpc_lsarpc.$SHLIBEXT", RPC)
SMB_MODULE(rpc_reg, \$(RPC_REG_OBJ), "bin/librpc_winreg.$SHLIBEXT", RPC)
+SMB_MODULE(rpc_lsa_ds, \$(RPC_LSA_DS_OBJ), "bin/librpc_lsa_ds.$SHLIBEXT", RPC)
SMB_MODULE(rpc_wks, \$(RPC_WKS_OBJ), "bin/librpc_wkssvc.$SHLIBEXT", RPC)
SMB_MODULE(rpc_net, \$(RPC_NETLOG_OBJ), "bin/librpc_NETLOGON.$SHLIBEXT", RPC)
SMB_MODULE(rpc_dfs, \$(RPC_DFS_OBJ), "bin/librpc_netdfs.$SHLIBEXT", RPC)
@@ -3879,30 +3954,32 @@ SMB_MODULE(rpc_srv, \$(RPC_SVC_OBJ), "bin/librpc_srvsvc.$SHLIBEXT", RPC)
SMB_MODULE(rpc_spoolss, \$(RPC_SPOOLSS_OBJ), "bin/librpc_spoolss.$SHLIBEXT", RPC)
SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC)
SMB_MODULE(rpc_echo, \$(RPC_ECHO_OBJ), "bin/librpc_echo.$SHLIBEXT", RPC)
-SMB_SUBSYSTEM(RPC)
+SMB_SUBSYSTEM(RPC,smbd/server.c)
SMB_MODULE(idmap_ldap, sam/idmap_ldap.o, "bin/idmap_ldap.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_tdb, sam/idmap_tdb.o, "bin/idmap_tdb.$SHLIBEXT", IDMAP)
-SMB_SUBSYSTEM(IDMAP)
+SMB_SUBSYSTEM(IDMAP,sam/idmap.c)
SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET)
-SMB_SUBSYSTEM(CHARSET)
+SMB_SUBSYSTEM(CHARSET,lib/iconv.c)
SMB_MODULE(auth_rhosts, \$(AUTH_RHOSTS_OBJ), "bin/rhosts.$SHLIBEXT", AUTH)
SMB_MODULE(auth_sam, \$(AUTH_SAM_OBJ), "bin/sam.$SHLIBEXT", AUTH)
SMB_MODULE(auth_unix, \$(AUTH_UNIX_OBJ), "bin/unix.$SHLIBEXT", AUTH)
SMB_MODULE(auth_winbind, \$(AUTH_WINBIND_OBJ), "bin/winbind.$SHLIBEXT", AUTH)
-SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/server.$SHLIBEXT", AUTH)
+SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH)
SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH)
SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH)
-SMB_SUBSYSTEM(AUTH)
+SMB_SUBSYSTEM(AUTH,auth/auth.c)
SMB_MODULE(vfs_recycle, \$(VFS_RECYCLE_OBJ), "bin/recycle.$SHLIBEXT", VFS)
SMB_MODULE(vfs_audit, \$(VFS_AUDIT_OBJ), "bin/audit.$SHLIBEXT", VFS)
SMB_MODULE(vfs_extd_audit, \$(VFS_EXTD_AUDIT_OBJ), "bin/extd_audit.$SHLIBEXT", VFS)
SMB_MODULE(vfs_netatalk, \$(VFS_NETATALK_OBJ), "bin/netatalk.$SHLIBEXT", VFS)
SMB_MODULE(vfs_fake_perms, \$(VFS_FAKE_PERMS_OBJ), "bin/fake_perms.$SHLIBEXT", VFS)
-SMB_SUBSYSTEM(VFS)
+SMB_MODULE(vfs_default_quota, \$(VFS_DEFAULT_QUOTA_OBJ), "bin/default_quota.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS)
+SMB_SUBSYSTEM(VFS,smbd/vfs.c)
AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
@@ -3918,10 +3995,10 @@ fi
AC_MSG_RESULT([Using libraries:])
AC_MSG_RESULT([ LIBS = $LIBS])
-if test x"$with_ads_support" = x"yes"; then
+if test x"$with_ads_support" != x"no"; then
AC_MSG_RESULT([ KRB5_LIBS = $KRB5_LIBS])
fi
-if test x"$with_ldap_support" = x"yes"; then
+if test x"$with_ldap_support" != x"no"; then
AC_MSG_RESULT([ LDAP_LIBS = $LDAP_LIBS])
fi
diff --git a/source/dynconfig.c b/source/dynconfig.c
index 4577c3947c8..34c716926cc 100644
--- a/source/dynconfig.c
+++ b/source/dynconfig.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
- Copyright (C) 2003 by Anthony Liguori <aliguor@us.ibm.com>
+ Copyright (C) 2003 by Jim McDonough <jmcd@us.ibm.com>
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
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c
index 3d2af5d0ba6..58d04f0dde5 100644
--- a/source/groupdb/mapping.c
+++ b/source/groupdb/mapping.c
@@ -234,7 +234,7 @@ static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map)
TDB_DATA kbuf, dbuf;
pstring key;
fstring string_sid;
- int ret;
+ int ret = 0;
if(!init_group_mapping()) {
DEBUG(0,("failed to initialize group mapping"));
@@ -257,6 +257,11 @@ static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map)
&map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
SAFE_FREE(dbuf.dptr);
+
+ if ( ret == -1 ) {
+ DEBUG(3,("get_group_map_from_sid: tdb_unpack failure\n"));
+ return False;
+ }
sid_copy(&map->sid, &sid);
@@ -299,6 +304,11 @@ static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map)
SAFE_FREE(dbuf.dptr);
+ if ( ret == -1 ) {
+ DEBUG(3,("get_group_map_from_gid: tdb_unpack failure\n"));
+ return False;
+ }
+
if (gid==map->gid) {
SAFE_FREE(kbuf.dptr);
return True;
@@ -343,6 +353,11 @@ static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
&map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
SAFE_FREE(dbuf.dptr);
+
+ if ( ret == -1 ) {
+ DEBUG(3,("get_group_map_from_ntname: tdb_unpack failure\n"));
+ return False;
+ }
if (StrCaseCmp(name, map->nt_name)==0) {
SAFE_FREE(kbuf.dptr);
@@ -429,6 +444,11 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
SAFE_FREE(dbuf.dptr);
+ if ( ret == -1 ) {
+ DEBUG(3,("enum_group_mapping: tdb_unpack failure\n"));
+ continue;
+ }
+
/* list only the type or everything if UNKNOWN */
if (sid_name_use!=SID_NAME_UNKNOWN && sid_name_use!=map.sid_name_use) {
DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
@@ -509,9 +529,10 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map)
return False;
}
- DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%d\n",map->gid));
-
- if ( (grp=getgrgid(map->gid)) == NULL) {
+ DEBUG(10, ("get_domain_group_from_sid: SID is mapped to gid:%lu\n",(unsigned long)map->gid));
+
+ grp = getgrgid(map->gid)
+ if ( !grp ) {
DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n"));
return False;
}
@@ -553,9 +574,12 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map)
sid_peek_rid(&sid, &alias_rid);
map->gid=pdb_group_rid_to_gid(alias_rid);
-
- if ((grp=getgrgid(map->gid)) == NULL)
+
+ grp = getgrgid(map->gid);
+ if ( !grp ) {
+ DEBUG(3,("get_local_group_from_sid: No unix group for [%ul]\n", map->gid));
return False;
+ }
map->sid_name_use=SID_NAME_ALIAS;
diff --git a/source/include/authdata.h b/source/include/authdata.h
index 0798b72bdf9..9d80745fb06 100644
--- a/source/include/authdata.h
+++ b/source/include/authdata.h
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
Kerberos authorization data
- Copyright (C) Jim McDonough 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
This program is free software; you can redistribute it and/or modify
diff --git a/source/include/byteorder.h b/source/include/byteorder.h
index c262dd2d337..0eef5573066 100644
--- a/source/include/byteorder.h
+++ b/source/include/byteorder.h
@@ -105,7 +105,7 @@ it also defines lots of intermediate macros, just ignore those :-)
#define CAREFUL_ALIGNMENT 1
#endif
-#define CVAL(buf,pos) (((const unsigned char *)(buf))[pos])
+#define CVAL(buf,pos) ((unsigned)(((const unsigned char *)(buf))[pos]))
#define CVAL_NC(buf,pos) (((unsigned char *)(buf))[pos]) /* Non-const version of CVAL */
#define PVAL(buf,pos) (CVAL(buf,pos))
#define SCVAL(buf,pos,val) (CVAL_NC(buf,pos) = (val))
diff --git a/source/include/charset.h b/source/include/charset.h
index c56984ca7b2..f999a9cf720 100644
--- a/source/include/charset.h
+++ b/source/include/charset.h
@@ -24,9 +24,9 @@ typedef enum {CH_UCS2=0, CH_UNIX=1, CH_DISPLAY=2, CH_DOS=3, CH_UTF8=4} charset_t
#define NUM_CHARSETS 5
-/*
- * for each charset we have a function that pulls from that charset to
- * a ucs2 buffer, and a function that pushes to a ucs2 buffer
+/*
+ * for each charset we have a function that pushes from that charset to a ucs2
+ * buffer, and a function that pulls from ucs2 buffer to that charset.
* */
struct charset_functions {
diff --git a/source/include/client.h b/source/include/client.h
index fad2c099b96..598e6c0bda5 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -57,18 +57,6 @@ struct print_job_info
time_t t;
};
-typedef struct smb_sign_info {
- void (*sign_outgoing_message)(struct cli_state *cli);
- BOOL (*check_incoming_message)(struct cli_state *cli);
- void (*free_signing_context)(struct cli_state *cli);
- void *signing_context;
-
- BOOL negotiated_smb_signing;
- BOOL allow_smb_signing;
- BOOL doing_signing;
- BOOL mandatory_signing;
-} smb_sign_info;
-
struct cli_state {
int port;
int fd;
diff --git a/source/include/dynconfig.h b/source/include/dynconfig.h
index ce256f06130..a74d77e41f7 100644
--- a/source/include/dynconfig.h
+++ b/source/include/dynconfig.h
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
- Copyright (C) 2003 by Anthony Liguori <aliguor@us.ibm.com>
+ Copyright (C) 2003 by Jim McDonough <jmcd@us.ibm.com>
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
diff --git a/source/include/idmap.h b/source/include/idmap.h
index ae7e4e5101b..20b1015285e 100644
--- a/source/include/idmap.h
+++ b/source/include/idmap.h
@@ -5,7 +5,7 @@
Idmap headers
- Copyright (C) Anthony Liguori 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
Copyright (C) Simo Sorce 2003
This library is free software; you can redistribute it and/or
diff --git a/source/include/includes.h b/source/include/includes.h
index edaeda3abed..0179064a6ad 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -437,6 +437,10 @@
#include <com_err.h>
#endif
+#if HAVE_SYS_ATTRIBUTES_H
+#include <sys/attributes.h>
+#endif
+
#if HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#endif
@@ -835,6 +839,8 @@ extern int errno;
#include "nsswitch/winbind_client.h"
+#include "spnego.h"
+
/*
* Type for wide character dirent structure.
* Only d_name is defined by POSIX.
@@ -956,10 +962,6 @@ struct smb_ldap_privates;
#define SYNC_DNS 1
#endif
-#ifndef MAXPATHLEN
-#define MAXPATHLEN 256
-#endif
-
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
@@ -1232,6 +1234,14 @@ int snprintf(char *,size_t ,const char *, ...) PRINTF_ATTRIBUTE(3,4);
int asprintf(char **,const char *, ...) PRINTF_ATTRIBUTE(2,3);
#endif
+/* Fix prototype problem with non-C99 compliant snprintf implementations, esp
+ HPUX 11. Don't change the sense of this #if statement. Read the comments
+ in lib/snprint.c if you think you need to. See also bugzilla bug 174. */
+
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
+#define snprintf smb_snprintf
+#endif
+
void sys_adminlog(int priority, const char *format_str, ...) PRINTF_ATTRIBUTE(2,3);
int pstr_sprintf(pstring s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
@@ -1288,7 +1298,7 @@ krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt);
krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters);
krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes);
void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);
-BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]);
+BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote);
#endif /* HAVE_KRB5 */
/* TRUE and FALSE are part of the C99 standard and gcc, but
diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h
index b6ab4fd0c50..ccbc190c59d 100644
--- a/source/include/ntdomain.h
+++ b/source/include/ntdomain.h
@@ -165,10 +165,21 @@ struct dcinfo
};
+typedef struct pipe_rpc_fns {
+
+ struct pipe_rpc_fns *next, *prev;
+
+ /* RPC function table associated with the current rpc_bind (associated by context) */
+
+ struct api_struct *cmds;
+ int n_cmds;
+ uint32 context_id;
+
+} PIPE_RPC_FNS;
+
/*
* DCE/RPC-specific samba-internal-specific handling of data on
* NamedPipes.
- *
*/
typedef struct pipes_struct
@@ -180,7 +191,12 @@ typedef struct pipes_struct
fstring name;
fstring pipe_srv_name;
-
+
+ /* linked list of rpc dispatch tables associated
+ with the open rpc contexts */
+
+ PIPE_RPC_FNS *contexts;
+
RPC_HDR hdr; /* Incoming RPC header. */
RPC_HDR_REQ hdr_req; /* Incoming request header. */
diff --git a/source/include/ntioctl.h b/source/include/ntioctl.h
index 17791fde18f..9814c88e5e5 100644
--- a/source/include/ntioctl.h
+++ b/source/include/ntioctl.h
@@ -23,6 +23,8 @@
we only need the sparse flag
*/
+#ifndef _NTIOCTL_H
+#define _NTIOCTL_H
/* IOCTL information */
/* List of ioctl function codes that look to be of interest to remote clients like this. */
@@ -53,6 +55,8 @@
#define FSCTL_SIS_COPYFILE 0x00090100
#define FSCTL_SIS_LINK_FILES 0x0009C104
+#define FSCTL_GET_SHADOW_COPY_DATA 0x00144064 /* KJC -- Shadow Copy information */
+
#if 0
#define FSCTL_SECURITY_ID_CHECK
#define FSCTL_DISMOUNT_VOLUME
@@ -66,3 +70,18 @@
#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
#define IO_REPARSE_TAG_HSM 0xC0000004
#define IO_REPARSE_TAG_SIS 0x80000007
+
+
+/* For FSCTL_GET_SHADOW_COPY_DATA ...*/
+typedef char SHADOW_COPY_LABEL[25];
+
+typedef struct shadow_copy_data {
+ TALLOC_CTX *mem_ctx;
+ /* Total number of shadow volumes currently mounted */
+ uint32 num_volumes;
+ /* Concatenated list of labels */
+ SHADOW_COPY_LABEL *labels;
+} SHADOW_COPY_DATA;
+
+
+#endif /* _NTIOCTL_H */
diff --git a/source/include/ntlmssp.h b/source/include/ntlmssp.h
index 562e4853ccc..f1b1bc25e43 100644
--- a/source/include/ntlmssp.h
+++ b/source/include/ntlmssp.h
@@ -100,6 +100,7 @@ typedef struct ntlmssp_client_state
char *domain;
char *workstation;
char *password;
+ char *server_domain;
const char *(*get_global_myname)(void);
const char *(*get_domain)(void);
diff --git a/source/include/ntquotas.h b/source/include/ntquotas.h
index 1425e59bb84..dac1173770b 100644
--- a/source/include/ntquotas.h
+++ b/source/include/ntquotas.h
@@ -72,7 +72,7 @@ typedef struct _SMB_NTQUOTA_STRUCT {
SMB_BIG_UINT usedspace;
SMB_BIG_UINT softlim;
SMB_BIG_UINT hardlim;
- enum SMB_QUOTA_TYPE qflags;
+ uint32 qflags;
DOM_SID sid;
} SMB_NTQUOTA_STRUCT;
diff --git a/source/include/popt_common.h b/source/include/popt_common.h
index 57850bf6826..6db30fbc0ac 100644
--- a/source/include/popt_common.h
+++ b/source/include/popt_common.h
@@ -41,6 +41,7 @@ struct user_auth_info {
pstring password;
BOOL got_pass;
BOOL use_kerberos;
+ int signing_state;
};
extern struct user_auth_info cmdline_auth_info;
diff --git a/source/include/rpc_dce.h b/source/include/rpc_dce.h
index dc82f453685..2e4a418bb7d 100644
--- a/source/include/rpc_dce.h
+++ b/source/include/rpc_dce.h
@@ -78,8 +78,8 @@ enum netsec_direction
#define AUTH_PIPE_NETSEC 0x0008
/* Maximum PDU fragment size. */
-#define MAX_PDU_FRAG_LEN 0x1630
-/* #define MAX_PDU_FRAG_LEN 0x10b8 this is what w2k sets */
+/* #define MAX_PDU_FRAG_LEN 0x1630 this is what wnt sets */
+#define MAX_PDU_FRAG_LEN 0x10b8 /* this is what w2k sets */
/*
* Actual structure of a DCE UUID
@@ -136,8 +136,8 @@ typedef struct rpc_hdr_info
typedef struct rpc_hdr_req_info
{
uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
- uint16 context_id; /* 0 - presentation context identifier */
- uint16 opnum; /* opnum */
+ uint16 context_id; /* presentation context identifier */
+ uint16 opnum; /* opnum */
} RPC_HDR_REQ;
diff --git a/source/include/rpc_ds.h b/source/include/rpc_ds.h
index c01d10554ec..e2622be532c 100644
--- a/source/include/rpc_ds.h
+++ b/source/include/rpc_ds.h
@@ -27,15 +27,32 @@
/* Opcodes available on PIPE_LSARPC_DS */
#define DS_GETPRIMDOMINFO 0x00
+#define DS_NOP 0xFF /* no op -- placeholder */
+
+/* Opcodes available on PIPE_NETLOGON */
+
+#define DS_ENUM_DOM_TRUSTS 0x28
/* macros for RPC's */
+/* DSROLE_PRIMARY_DOMAIN_INFO_BASIC */
+
+/* flags */
+
#define DSROLE_PRIMARY_DS_RUNNING 0x00000001
#define DSROLE_PRIMARY_DS_MIXED_MODE 0x00000002
#define DSROLE_UPGRADE_IN_PROGRESS 0x00000004
#define DSROLE_PRIMARY_DOMAIN_GUID_PRESENT 0x01000000
+/* machine role */
+
+#define DSROLE_STANDALONE_SRV 2
+#define DSROLE_DOMAIN_MEMBER_SRV 3
+#define DSROLE_BDC 4
+#define DSROLE_PDC 5
+
+
typedef struct
{
uint16 machine_role;
@@ -50,10 +67,9 @@ typedef struct
GUID domain_guid;
UNISTR2 netbios_domain;
- /* these 2 might be reversed in order. I can't tell from
- my tests as both values are the same --jerry */
- UNISTR2 dns_domain;
- UNISTR2 forest_domain;
+
+ UNISTR2 dns_domain; /* our dns domain */
+ UNISTR2 forest_domain; /* root domain of the forest to which we belong */
} DSROLE_PRIMARY_DOMAIN_INFO_BASIC;
typedef struct
@@ -85,7 +101,58 @@ typedef struct
NTSTATUS status;
} DS_R_GETPRIMDOMINFO;
+typedef struct {
+ /* static portion of structure */
+ uint32 netbios_ptr;
+ uint32 dns_ptr;
+ uint32 flags;
+ uint32 parent_index;
+ uint32 trust_type;
+ uint32 trust_attributes;
+ uint32 sid_ptr;
+ GUID guid;
+
+ UNISTR2 netbios_domain;
+ UNISTR2 dns_domain;
+ DOM_SID2 sid;
+
+} DS_DOMAIN_TRUSTS;
+
+typedef struct {
+
+ uint32 ptr;
+ uint32 max_count;
+ DS_DOMAIN_TRUSTS *trusts;
+
+} DS_DOMAIN_TRUSTS_CTR;
+
+#define DS_DOMAIN_IN_FOREST 0x0001 /* domains in the forest to which
+ we belong; even different domain trees */
+#define DS_DOMAIN_DIRECT_OUTBOUND 0x0002 /* trusted domains */
+#define DS_DOMAIN_TREE_ROOT 0x0004 /* root of our forest; also available in
+ DsRoleGetPrimaryDomainInfo() */
+#define DS_DOMAIN_PRIMARY 0x0008 /* our domain */
+#define DS_DOMAIN_NATIVE_MODE 0x0010 /* native mode AD servers */
+#define DS_DOMAIN_DIRECT_INBOUND 0x0020 /* trusting domains */
+
+/* DS_Q_ENUM_DOM_TRUSTS - DsEnumerateDomainTrusts() request */
+typedef struct
+{
+ uint32 server_ptr;
+ UNISTR2 server;
+ uint32 flags;
+
+} DS_Q_ENUM_DOM_TRUSTS;
+
+/* DS_R_ENUM_DOM_TRUSTS - DsEnumerateDomainTrusts() response */
+typedef struct
+{
+ uint32 num_domains;
+ DS_DOMAIN_TRUSTS_CTR domains;
+
+ NTSTATUS status;
+} DS_R_ENUM_DOM_TRUSTS;
#endif /* _RPC_DS_H */
diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h
index 135fd76d6c9..fa49d76c885 100644
--- a/source/include/rpc_lsa.h
+++ b/source/include/rpc_lsa.h
@@ -27,6 +27,12 @@
/* Opcodes available on PIPE_LSARPC */
+#if 0 /* UNIMPLEMENTED */
+
+#define LSA_LOOKUPSIDS2 0x39
+
+#endif
+
#define LSA_CLOSE 0x00
#define LSA_DELETE 0x01
#define LSA_ENUM_PRIVS 0x02
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index 7d28a0f3a71..8ec274176a7 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -5,8 +5,7 @@
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Paul Ashton 1997-2000
Copyright (C) Jean François Micouleau 1998-2001
- Copyright (C) Anthony Liguori 2002
- Copyright (C) Jim McDonough 2002
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
This program is free software; you can redistribute it and/or modify
diff --git a/source/include/rpc_secdes.h b/source/include/rpc_secdes.h
index fb7060cde3b..5e718f8167d 100644
--- a/source/include/rpc_secdes.h
+++ b/source/include/rpc_secdes.h
@@ -305,12 +305,12 @@ typedef struct standard_mapping {
SA_RIGHT_FILE_EXECUTE)
-/* SAM Object specific access rights */
+/* SAM server specific access rights */
-#define SA_RIGHT_SAM_UNKNOWN_1 0x00000001
+#define SA_RIGHT_SAM_CONNECT_SERVER 0x00000001
#define SA_RIGHT_SAM_SHUTDOWN_SERVER 0x00000002
-#define SA_RIGHT_SAM_UNKNOWN_4 0x00000004
-#define SA_RIGHT_SAM_UNKNOWN_8 0x00000008
+#define SA_RIGHT_SAM_INITIALISE_SERVER 0x00000004
+#define SA_RIGHT_SAM_CREATE_DOMAIN 0x00000008
#define SA_RIGHT_SAM_ENUM_DOMAINS 0x00000010
#define SA_RIGHT_SAM_OPEN_DOMAIN 0x00000020
@@ -326,14 +326,14 @@ typedef struct standard_mapping {
#define GENERIC_RIGHTS_SAM_WRITE \
(STANDARD_RIGHTS_WRITE_ACCESS | \
- SA_RIGHT_SAM_UNKNOWN_8 | \
- SA_RIGHT_SAM_UNKNOWN_4 | \
+ SA_RIGHT_SAM_CREATE_DOMAIN | \
+ SA_RIGHT_SAM_INITIALISE_SERVER | \
SA_RIGHT_SAM_SHUTDOWN_SERVER)
#define GENERIC_RIGHTS_SAM_EXECUTE \
(STANDARD_RIGHTS_EXECUTE_ACCESS | \
SA_RIGHT_SAM_OPEN_DOMAIN | \
- SA_RIGHT_SAM_UNKNOWN_1)
+ SA_RIGHT_SAM_CONNECT_SERVER)
/* Domain Object specific access rights */
@@ -388,8 +388,8 @@ typedef struct standard_mapping {
#define SA_RIGHT_USER_CHANGE_PASSWORD 0x00000040
#define SA_RIGHT_USER_SET_PASSWORD 0x00000080
#define SA_RIGHT_USER_GET_GROUPS 0x00000100
-#define SA_RIGHT_USER_UNKNOWN_200 0x00000200
-#define SA_RIGHT_USER_UNKNOWN_400 0x00000400
+#define SA_RIGHT_USER_READ_GROUP_MEM 0x00000200
+#define SA_RIGHT_USER_CHANGE_GROUP_MEM 0x00000400
#define SA_RIGHT_USER_ALL_ACCESS 0x000007FF
@@ -399,7 +399,7 @@ typedef struct standard_mapping {
#define GENERIC_RIGHTS_USER_READ \
(STANDARD_RIGHTS_READ_ACCESS | \
- SA_RIGHT_USER_UNKNOWN_200 | \
+ SA_RIGHT_USER_READ_GROUP_MEM | \
SA_RIGHT_USER_GET_GROUPS | \
SA_RIGHT_USER_ACCT_FLAGS_EXPIRY | \
SA_RIGHT_USER_GET_LOGONINFO | \
diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h
index c2e3d92787c..f96b4fa96ab 100755
--- a/source/include/rpc_spoolss.h
+++ b/source/include/rpc_spoolss.h
@@ -1302,6 +1302,12 @@ typedef struct s_port_info_2
}
PORT_INFO_2;
+/* Port Type bits */
+#define PORT_TYPE_WRITE 0x0001
+#define PORT_TYPE_READ 0x0002
+#define PORT_TYPE_REDIRECTED 0x0004
+#define PORT_TYPE_NET_ATTACHED 0x0008
+
typedef struct spool_q_enumports
{
uint32 name_ptr;
diff --git a/source/include/smb.h b/source/include/smb.h
index d2714e78bc8..2cafd1b9b1e 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -42,6 +42,7 @@
#define SMB_PORT2 139
#define SMB_PORTS "445 139"
+#define Undefined (-1)
#define False (0)
#define True (1)
#define Auto (2)
@@ -79,9 +80,7 @@ typedef int BOOL;
#define READ_TIMEOUT 1
#define READ_EOF 2
#define READ_ERROR 3
-
-/* This error code can go into the client smb_rw_error. */
-#define WRITE_ERROR 4
+#define WRITE_ERROR 4 /* This error code can go into the client smb_rw_error. */
#define READ_BAD_SIG 5
#define DIR_STRUCT_SIZE 43
@@ -391,6 +390,7 @@ typedef struct files_struct
SMB_OFF_T pos;
SMB_BIG_UINT size;
SMB_BIG_UINT initial_allocation_size; /* Faked up initial allocation on disk. */
+ SMB_BIG_UINT position_information;
mode_t mode;
uint16 vuid;
write_bmpx_struct *wbmpx_ptr;
@@ -707,13 +707,14 @@ struct bitmap {
unsigned int n;
};
-#define FLAG_BASIC 0x0001 /* fundamental options */
+/* The following flags are used in SWAT */
+#define FLAG_BASIC 0x0001 /* Display only in BASIC view */
#define FLAG_SHARE 0x0002 /* file sharing options */
#define FLAG_PRINT 0x0004 /* printing options */
#define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
#define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
-#define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
-#define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
+#define FLAG_ADVANCED 0x0020 /* Parameters that will be visible in advanced view */
+#define FLAG_DEVELOPER 0x0040 /* No longer used */
#define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
#define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
#define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
@@ -1630,4 +1631,18 @@ struct ip_service {
unsigned port;
};
+/* Used by the SMB signing functions. */
+
+typedef struct smb_sign_info {
+ void (*sign_outgoing_message)(char *outbuf, struct smb_sign_info *si);
+ BOOL (*check_incoming_message)(char *inbuf, struct smb_sign_info *si);
+ void (*free_signing_context)(struct smb_sign_info *si);
+ void *signing_context;
+
+ BOOL negotiated_smb_signing;
+ BOOL allow_smb_signing;
+ BOOL doing_signing;
+ BOOL mandatory_signing;
+} smb_sign_info;
+
#endif /* _SMB_H */
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index 21ccdf295c4..178fd9c3580 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -77,6 +77,12 @@
#define OPEN_CONN(conn) ((conn) && (conn)->open)
#define IS_IPC(conn) ((conn) && (conn)->ipc)
#define IS_PRINT(conn) ((conn) && (conn)->printer)
+#define FSP_BELONGS_CONN(fsp,conn) do {\
+ extern struct current_user current_user;\
+ if (!((fsp) && (conn) && ((conn)==(fsp)->conn) && (current_user.vuid==(fsp)->vuid))) \
+ return(ERROR_DOS(ERRDOS,ERRbadfid));\
+ } while(0)
+
#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid)
#define CHECK_FSP(fsp,conn) do {\
diff --git a/source/include/smbldap.h b/source/include/smbldap.h
index 589d01aa6dd..826fc3c55a1 100644
--- a/source/include/smbldap.h
+++ b/source/include/smbldap.h
@@ -132,6 +132,9 @@ struct smbldap_state {
char *bind_secret;
unsigned int num_failures;
+
+ time_t last_use;
+ smb_event_id_t event_id;
};
#endif /* HAVE_LDAP */
diff --git a/source/include/spnego.h b/source/include/spnego.h
new file mode 100644
index 00000000000..b6492ee3c8a
--- /dev/null
+++ b/source/include/spnego.h
@@ -0,0 +1,65 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ RFC2478 Compliant SPNEGO implementation
+
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef SAMBA_SPNEGO_H
+#define SAMBA_SPNEGO_H
+
+#define SPNEGO_DELEG_FLAG 0x01
+#define SPNEGO_MUTUAL_FLAG 0x02
+#define SPNEGO_REPLAY_FLAG 0x04
+#define SPNEGO_SEQUENCE_FLAG 0x08
+#define SPNEGO_ANON_FLAG 0x10
+#define SPNEGO_CONF_FLAG 0x20
+#define SPNEGO_INTEG_FLAG 0x40
+#define SPNEGO_REQ_FLAG 0x80
+
+#define SPNEGO_NEG_TOKEN_INIT 0
+#define SPNEGO_NEG_TOKEN_TARG 1
+
+typedef enum _spnego_negResult {
+ SPNEGO_ACCEPT_COMPLETED = 0,
+ SPNEGO_ACCEPT_INCOMPLETE = 1,
+ SPNEGO_REJECT = 2
+} negResult_t;
+
+typedef struct spnego_negTokenInit {
+ const char **mechTypes;
+ int reqFlags;
+ DATA_BLOB mechToken;
+ DATA_BLOB mechListMIC;
+} negTokenInit_t;
+
+typedef struct spnego_negTokenTarg {
+ uint8 negResult;
+ const char *supportedMech;
+ DATA_BLOB responseToken;
+ DATA_BLOB mechListMIC;
+} negTokenTarg_t;
+
+typedef struct spnego_spnego {
+ int type;
+ negTokenInit_t negTokenInit;
+ negTokenTarg_t negTokenTarg;
+} SPNEGO_DATA;
+
+#endif
diff --git a/source/include/sysquotas.h b/source/include/sysquotas.h
index cfdac0609aa..b803e6277ab 100644
--- a/source/include/sysquotas.h
+++ b/source/include/sysquotas.h
@@ -189,6 +189,22 @@
#define SMB_QUOTAS_NO_LIMIT ((SMB_BIG_UINT)(0))
#define SMB_QUOTAS_NO_SPACE ((SMB_BIG_UINT)(1))
+#define SMB_QUOTAS_SET_NO_LIMIT(dp) \
+{\
+ (dp)->softlimit = SMB_QUOTAS_NO_LIMIT;\
+ (dp)->hardlimit = SMB_QUOTAS_NO_LIMIT;\
+ (dp)->isoftlimit = SMB_QUOTAS_NO_LIMIT;\
+ (dp)->ihardlimit = SMB_QUOTAS_NO_LIMIT;\
+}
+
+#define SMB_QUOTAS_SET_NO_SPACE(dp) \
+{\
+ (dp)->softlimit = SMB_QUOTAS_NO_SPACE;\
+ (dp)->hardlimit = SMB_QUOTAS_NO_SPACE;\
+ (dp)->isoftlimit = SMB_QUOTAS_NO_SPACE;\
+ (dp)->ihardlimit = SMB_QUOTAS_NO_SPACE;\
+}
+
typedef struct _SMB_DISK_QUOTA {
enum SMB_QUOTA_TYPE qtype;
SMB_BIG_UINT bsize;
diff --git a/source/include/version.h b/source/include/version.h
index 5e2d47e1ded..68bc140dafb 100644
--- a/source/include/version.h
+++ b/source/include/version.h
@@ -1 +1 @@
-#define VERSION "3.0.0beta3"
+#define VERSION "3.0.0rc1"
diff --git a/source/include/vfs.h b/source/include/vfs.h
index 924d7063217..dd489702aa9 100644
--- a/source/include/vfs.h
+++ b/source/include/vfs.h
@@ -50,8 +50,8 @@
/* Changed to version 6 for the new module system, fixed cascading and quota functions. --metze */
/* Changed to version 7 to include the get_nt_acl info parameter. JRA. */
/* Changed to version 8 includes EA calls. JRA. */
-
-#define SMB_VFS_INTERFACE_VERSION 8
+/* Changed to version 9 to include the get_shadow_data call. --metze */
+#define SMB_VFS_INTERFACE_VERSION 9
/* to bug old modules witch are trying to compile with the old functions */
@@ -91,6 +91,8 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_DISK_FREE,
SMB_VFS_OP_GET_QUOTA,
SMB_VFS_OP_SET_QUOTA,
+ SMB_VFS_OP_GET_SHADOW_COPY_DATA,
+
/* Directory operations */
@@ -196,6 +198,7 @@ struct vfs_ops {
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
int (*get_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
int (*set_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
+ int (*get_shadow_copy_data)(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels);
/* Directory operations */
@@ -293,6 +296,7 @@ struct vfs_ops {
struct vfs_handle_struct *disk_free;
struct vfs_handle_struct *get_quota;
struct vfs_handle_struct *set_quota;
+ struct vfs_handle_struct *get_shadow_copy_data;
/* Directory operations */
@@ -379,6 +383,7 @@ struct vfs_ops {
struct vfs_handle_struct *setxattr;
struct vfs_handle_struct *lsetxattr;
struct vfs_handle_struct *fsetxattr;
+
} handles;
};
@@ -466,6 +471,9 @@ typedef struct vfs_handle_struct {
} \
}
+/* Check whether module-specific data handle was already allocated or not */
+#define SMB_VFS_HANDLE_TEST_DATA(handle) ( !(handle) || !(handle)->data ? False : True )
+
#define SMB_VFS_OP(x) ((void *) x)
diff --git a/source/include/vfs_macros.h b/source/include/vfs_macros.h
index fdbc1516e31..c4f63c352e4 100644
--- a/source/include/vfs_macros.h
+++ b/source/include/vfs_macros.h
@@ -33,6 +33,7 @@
#define SMB_VFS_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs.ops.disk_free((conn)->vfs.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
#define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.get_quota((conn)->vfs.handles.get_quota, (conn), (qtype), (id), (qt)))
#define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.set_quota((conn)->vfs.handles.set_quota, (conn), (qtype), (id), (qt)))
+#define SMB_VFS_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs.ops.get_shadow_copy_data((fsp)->conn->vfs.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
/* Directory operations */
#define SMB_VFS_OPENDIR(conn, fname) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname)))
@@ -128,6 +129,7 @@
#define SMB_VFS_OPAQUE_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs_opaque.ops.disk_free((conn)->vfs_opaque.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
#define SMB_VFS_OPAQUE_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.get_quota((conn)->vfs_opaque.handles.get_quota, (conn), (qtype), (id), (qt)))
#define SMB_VFS_OPAQUE_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.set_quota((conn)->vfs_opaque.handles.set_quota, (conn), (qtype), (id), (qt)))
+#define SMB_VFS_OPAQUE_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs_opaque.ops.get_shadow_copy_data((fsp)->conn->vfs_opaque.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
/* Directory operations */
#define SMB_VFS_OPAQUE_OPENDIR(conn, fname) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname)))
@@ -223,6 +225,7 @@
#define SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize, dfree ,dsize) ((handle)->vfs_next.ops.disk_free((handle)->vfs_next.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
#define SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.get_quota((handle)->vfs_next.handles.get_quota, (conn), (qtype), (id), (qt)))
#define SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.set_quota((handle)->vfs_next.handles.set_quota, (conn), (qtype), (id), (qt)))
+#define SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data ,labels) ((handle)->vfs_next.ops.get_shadow_copy_data((handle)->vfs_next.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
/* Directory operations */
#define SMB_VFS_NEXT_OPENDIR(handle, conn, fname) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname)))
diff --git a/source/lib/access.c b/source/lib/access.c
index c30b3c33cc2..a874c8b1e20 100644
--- a/source/lib/access.c
+++ b/source/lib/access.c
@@ -281,13 +281,12 @@ static BOOL only_ipaddrs_in_list(const char** list)
}
if (!is_ipaddress(*list)) {
- char *p;
/*
* if we failed, make sure that it was not because the token
* was a network/netmask pair. Only network/netmask pairs
* have a '/' in them
*/
- if ((p=strchr_m(*list, '/')) == NULL) {
+ if ((strchr_m(*list, '/')) == NULL) {
only_ip = False;
DEBUG(3,("only_ipaddrs_in_list: list has non-ip address (%s)\n", *list));
break;
diff --git a/source/lib/account_pol.c b/source/lib/account_pol.c
index e8b382c7ab9..dc131985a1a 100644
--- a/source/lib/account_pol.c
+++ b/source/lib/account_pol.c
@@ -53,7 +53,7 @@ BOOL init_account_policy(void)
account_policy_set(AP_MIN_PASSWORD_LEN, MINPASSWDLENGTH); /* 5 chars minimum */
account_policy_set(AP_PASSWORD_HISTORY, 0); /* don't keep any old password */
account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, 0); /* don't force user to logon */
- account_policy_set(AP_MAX_PASSWORD_AGE, MAX_PASSWORD_AGE); /* 21 days */
+ account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)-1); /* don't expire */
account_policy_set(AP_MIN_PASSWORD_AGE, 0); /* 0 days */
account_policy_set(AP_LOCK_ACCOUNT_DURATION, 0); /* lockout for 0 minutes */
account_policy_set(AP_RESET_COUNT_TIME, 0); /* reset immediatly */
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index 4e9c2c15923..ca5e378970c 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -190,8 +190,8 @@ size_t convert_string(charset_t from, charset_t to,
break;
case E2BIG:
reason="No more room";
- DEBUG(0, ("convert_string: Required %d, available %d\n",
- srclen, destlen));
+ DEBUG(0, ("convert_string: Required %lu, available %lu\n",
+ (unsigned long)srclen, (unsigned long)destlen));
/* we are not sure we need srclen bytes,
may be more, may be less.
We only know we need more than destlen
@@ -319,8 +319,7 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
size_t size;
smb_ucs2_t *buffer;
- size = convert_string_allocate(CH_UNIX, CH_UCS2, src, srclen,
- (void **) &buffer);
+ size = push_ucs2_allocate(&buffer, src);
if (size == -1) {
smb_panic("failed to create UCS2 buffer");
}
@@ -334,6 +333,33 @@ size_t unix_strupper(const char *src, size_t srclen, char *dest, size_t destlen)
return size;
}
+/**
+ strdup() a unix string to upper case.
+**/
+
+char *strdup_upper(const char *s)
+{
+ size_t size;
+ smb_ucs2_t *buffer;
+ char *out_buffer;
+
+ size = push_ucs2_allocate(&buffer, s);
+ if (size == -1) {
+ return NULL;
+ }
+
+ strupper_w(buffer);
+
+ size = pull_ucs2_allocate(&out_buffer, buffer);
+ SAFE_FREE(buffer);
+
+ if (size == -1) {
+ return NULL;
+ }
+
+ return out_buffer;
+}
+
size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
{
size_t size;
@@ -353,6 +379,32 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
return size;
}
+/**
+ strdup() a unix string to lower case.
+**/
+
+char *strdup_lower(const char *s)
+{
+ size_t size;
+ smb_ucs2_t *buffer;
+ char *out_buffer;
+
+ size = push_ucs2_allocate(&buffer, s);
+ if (size == -1) {
+ return NULL;
+ }
+
+ strlower_w(buffer);
+
+ size = pull_ucs2_allocate(&out_buffer, buffer);
+ SAFE_FREE(buffer);
+
+ if (size == -1) {
+ return NULL;
+ }
+
+ return out_buffer;
+}
static size_t ucs2_align(const void *base_ptr, const void *p, int flags)
{
@@ -480,18 +532,11 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_
{
size_t len=0;
size_t src_len = strlen(src);
- pstring tmpbuf;
/* treat a pstring as "unlimited" length */
if (dest_len == (size_t)-1)
dest_len = sizeof(pstring);
- if (flags & STR_UPPER) {
- pstrcpy(tmpbuf, src);
- strupper_m(tmpbuf);
- src = tmpbuf;
- }
-
if (flags & STR_TERMINATE)
src_len++;
@@ -506,6 +551,18 @@ size_t push_ucs2(const void *base_ptr, void *dest, const char *src, size_t dest_
dest_len &= ~1;
len += convert_string(CH_UNIX, CH_UCS2, src, src_len, dest, dest_len);
+
+ if (flags & STR_UPPER) {
+ smb_ucs2_t *dest_ucs2 = dest;
+ size_t i;
+ for (i = 0; i < (dest_len / 2) && dest_ucs2[i]; i++) {
+ smb_ucs2_t v = toupper_w(dest_ucs2[i]);
+ if (v != dest_ucs2[i]) {
+ dest_ucs2[i] = v;
+ }
+ }
+ }
+
return len;
}
@@ -809,44 +866,3 @@ size_t align_string(const void *base_ptr, const char *p, int flags)
return 0;
}
-/**
- Convert from unix to ucs2 charset and return the
- allocated and converted string or NULL if an error occurred.
- You must provide a zero terminated string.
- The returning string will be zero terminated.
-**/
-
-smb_ucs2_t *acnv_uxu2(const char *src)
-{
- size_t slen;
- size_t dlen;
- void *dest;
-
- slen = strlen(src) + 1;
- dlen = convert_string_allocate(CH_UNIX, CH_UCS2, src, slen, &dest);
- if (dlen == (size_t)-1)
- return NULL;
- else
- return dest;
-}
-
-/**
- Convert from dos to ucs2 charset and return the
- allocated and converted string or NULL if an error occurred.
- You must provide a zero terminated string.
- The returning string will be zero terminated.
-**/
-
-smb_ucs2_t *acnv_dosu2(const char *src)
-{
- size_t slen;
- size_t dlen;
- void *dest;
-
- slen = strlen(src) + 1;
- dlen = convert_string_allocate(CH_DOS, CH_UCS2, src, slen, &dest);
- if (dlen == (size_t)-1)
- return NULL;
- else
- return dest;
-}
diff --git a/source/lib/dummyroot.c b/source/lib/dummyroot.c
new file mode 100644
index 00000000000..c8465cb791a
--- /dev/null
+++ b/source/lib/dummyroot.c
@@ -0,0 +1,33 @@
+/*
+ Unix SMB/CIFS implementation.
+ RPC pipe client
+
+ Copyright (C) Tim Potter 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Stupid dummy functions required due to the horrible dependency mess
+ in Samba. */
+
+void become_root(void)
+{
+ return;
+}
+
+void unbecome_root(void)
+{
+ return;
+}
diff --git a/source/lib/module.c b/source/lib/module.c
index ac4fe57a2c8..d860cba8195 100644
--- a/source/lib/module.c
+++ b/source/lib/module.c
@@ -41,7 +41,7 @@ NTSTATUS smb_load_module(const char *module_name)
return NT_STATUS_UNSUCCESSFUL;
}
- init = sys_dlsym(handle, "init_module");
+ init = (init_module_function *)sys_dlsym(handle, "init_module");
/* we must check sys_dlerror() to determine if it worked, because
sys_dlsym() can validly return NULL */
diff --git a/source/lib/ms_fnmatch.c b/source/lib/ms_fnmatch.c
index 106efa5bbcf..24232c3b523 100644
--- a/source/lib/ms_fnmatch.c
+++ b/source/lib/ms_fnmatch.c
@@ -35,7 +35,8 @@
of the protocol. This is not yet perfect, but its a lot
better than what we had */
static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern,
- const smb_ucs2_t *string)
+ const smb_ucs2_t *string,
+ BOOL case_sensitive)
{
const smb_ucs2_t *p = pattern, *n = string;
smb_ucs2_t c;
@@ -61,8 +62,8 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern,
case UCS2_CHAR('>'):
if (! *n) goto next;
if (n[0] == UCS2_CHAR('.')) {
- if (! n[1] && ms_fnmatch_lanman_core(p, n+1) == 0) goto match;
- if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
+ if (! n[1] && ms_fnmatch_lanman_core(p, n+1, case_sensitive) == 0) goto match;
+ if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
goto nomatch;
}
n++;
@@ -72,13 +73,13 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern,
if (! *n) goto next;
if (! *p) goto match;
for (; *n; n++) {
- if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
+ if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
}
break;
case UCS2_CHAR('<'):
for (; *n; n++) {
- if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
+ if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
if (*n == UCS2_CHAR('.') &&
!strchr_w(n+1,UCS2_CHAR('.'))) {
n++;
@@ -88,13 +89,17 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern,
break;
case UCS2_CHAR('"'):
- if (*n == 0 && ms_fnmatch_lanman_core(p, n) == 0) goto match;
+ if (*n == 0 && ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
if (*n != UCS2_CHAR('.')) goto nomatch;
n++;
break;
default:
- if (c != *n) goto nomatch;
+ if (case_sensitive) {
+ if (c != *n) goto nomatch;
+ } else {
+ if (tolower_w(c) != tolower_w(*n)) goto nomatch;
+ }
n++;
}
}
@@ -108,7 +113,7 @@ static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern,
return -1;
next:
- if (ms_fnmatch_lanman_core(p, n) == 0) goto match;
+ if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
goto nomatch;
match:
@@ -118,7 +123,8 @@ next:
return 0;
}
-static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *string)
+static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern,
+ const smb_ucs2_t *string, BOOL case_sensitive)
{
if (!strpbrk_wa(pattern, "?*<>\"")) {
smb_ucs2_t s[] = {UCS2_CHAR('.'), 0};
@@ -129,11 +135,11 @@ static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *strin
if (strcmp_wa(string,"..") == 0 || strcmp_wa(string,".") == 0) {
smb_ucs2_t dot[] = {UCS2_CHAR('.'), 0};
smb_ucs2_t dotdot[] = {UCS2_CHAR('.'), UCS2_CHAR('.'), 0};
- return ms_fnmatch_lanman_core(pattern, dotdot) &&
- ms_fnmatch_lanman_core(pattern, dot);
+ return ms_fnmatch_lanman_core(pattern, dotdot, case_sensitive) &&
+ ms_fnmatch_lanman_core(pattern, dot, case_sensitive);
}
- return ms_fnmatch_lanman_core(pattern, string);
+ return ms_fnmatch_lanman_core(pattern, string, case_sensitive);
}
@@ -145,13 +151,14 @@ static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, const smb_ucs2_t *strin
Returns 0 on match, -1 on fail.
*/
-static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int protocol)
+static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string,
+ int protocol, BOOL case_sensitive)
{
const smb_ucs2_t *p = pattern, *n = string;
smb_ucs2_t c;
if (protocol <= PROTOCOL_LANMAN2) {
- return ms_fnmatch_lanman1(pattern, string);
+ return ms_fnmatch_lanman1(pattern, string, case_sensitive);
}
while ((c = *p++)) {
@@ -163,23 +170,23 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int
case UCS2_CHAR('>'):
if (n[0] == UCS2_CHAR('.')) {
- if (! n[1] && ms_fnmatch_w(p, n+1, protocol) == 0) return 0;
- if (ms_fnmatch_w(p, n, protocol) == 0) return 0;
+ if (! n[1] && ms_fnmatch_w(p, n+1, protocol, case_sensitive) == 0) return 0;
+ if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
return -1;
}
- if (! *n) return ms_fnmatch_w(p, n, protocol);
+ if (! *n) return ms_fnmatch_w(p, n, protocol, case_sensitive);
n++;
break;
case UCS2_CHAR('*'):
for (; *n; n++) {
- if (ms_fnmatch_w(p, n, protocol) == 0) return 0;
+ if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
}
break;
case UCS2_CHAR('<'):
for (; *n; n++) {
- if (ms_fnmatch_w(p, n, protocol) == 0) return 0;
+ if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
if (*n == UCS2_CHAR('.') && !strchr_wa(n+1,'.')) {
n++;
break;
@@ -188,13 +195,17 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int
break;
case UCS2_CHAR('"'):
- if (*n == 0 && ms_fnmatch_w(p, n, protocol) == 0) return 0;
+ if (*n == 0 && ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
if (*n != UCS2_CHAR('.')) return -1;
n++;
break;
default:
- if (c != *n) return -1;
+ if (case_sensitive) {
+ if (c != *n) return -1;
+ } else {
+ if (tolower_w(c) != tolower_w(*n)) return -1;
+ }
n++;
}
}
@@ -204,22 +215,35 @@ static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, int
return -1;
}
-
-int ms_fnmatch(const char *pattern, const char *string, int protocol)
+int ms_fnmatch(const char *pattern, const char *string, int protocol,
+ BOOL case_senstive)
{
- wpstring p, s;
+ wpstring buffer_pattern, buffer_string;
int ret;
+ size_t size;
+
+ size = push_ucs2(NULL, buffer_pattern, pattern, sizeof(buffer_pattern), STR_TERMINATE);
+ if (size == (size_t)-1) {
+ return -1;
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ }
+
+ size = push_ucs2(NULL, buffer_string, string, sizeof(buffer_string), STR_TERMINATE);
+ if (size == (size_t)-1) {
+ return -1;
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ }
- pstrcpy_wa(p, pattern);
- pstrcpy_wa(s, string);
+ ret = ms_fnmatch_w(buffer_pattern, buffer_string, protocol, case_senstive);
+ DEBUG(10,("ms_fnmatch(%s,%s) -> %d\n", pattern, string, ret));
- ret = ms_fnmatch_w(p, s, protocol);
-/* DEBUG(0,("ms_fnmatch(%s,%s) -> %d\n", pattern, string, ret)); */
return ret;
}
/* a generic fnmatch function - uses for non-CIFS pattern matching */
int gen_fnmatch(const char *pattern, const char *string)
{
- return ms_fnmatch(pattern, string, PROTOCOL_NT1);
+ return ms_fnmatch(pattern, string, PROTOCOL_NT1, True);
}
diff --git a/source/lib/popt_common.c b/source/lib/popt_common.c
index b8e77b2d9ec..95a9a58b34f 100644
--- a/source/lib/popt_common.c
+++ b/source/lib/popt_common.c
@@ -119,6 +119,7 @@ struct poptOption popt_common_connection[] = {
{ "netbiosname", 'n', POPT_ARG_STRING, NULL, 'n', "Primary netbios name", "NETBIOSNAME" },
{ "workgroup", 'W', POPT_ARG_STRING, NULL, 'W', "Set the workgroup name", "WORKGROUP" },
{ "scope", 'i', POPT_ARG_STRING, NULL, 'i', "Use this Netbios scope", "SCOPE" },
+
POPT_TABLEEND
};
@@ -258,19 +259,22 @@ static void get_credentials_file(const char *file, struct user_auth_info *info)
* -A,--authentication-file
* -k,--use-kerberos
* -N,--no-pass
+ * -S,--signing
+ * -P --machine-pass
*/
static void popt_common_credentials_callback(poptContext con,
- enum poptCallbackReason reason,
- const struct poptOption *opt,
- const char *arg, const void *data)
+ enum poptCallbackReason reason,
+ const struct poptOption *opt,
+ const char *arg, const void *data)
{
char *p;
if (reason == POPT_CALLBACK_REASON_PRE) {
cmdline_auth_info.use_kerberos = False;
cmdline_auth_info.got_pass = False;
+ cmdline_auth_info.signing_state = Undefined;
pstrcpy(cmdline_auth_info.username, "GUEST");
if (getenv("LOGNAME"))pstrcpy(cmdline_auth_info.username,getenv("LOGNAME"));
@@ -327,6 +331,50 @@ static void popt_common_credentials_callback(poptContext con,
cmdline_auth_info.got_pass = True;
#endif
break;
+
+ case 'S':
+ {
+ cmdline_auth_info.signing_state = -1;
+ if (strequal(arg, "off") || strequal(arg, "no") || strequal(arg, "false"))
+ cmdline_auth_info.signing_state = False;
+ else if (strequal(arg, "on") || strequal(arg, "yes") || strequal(arg, "true") ||
+ strequal(arg, "auto") )
+ cmdline_auth_info.signing_state = True;
+ else if (strequal(arg, "force") || strequal(arg, "required") || strequal(arg, "forced"))
+ cmdline_auth_info.signing_state = Required;
+ else {
+ fprintf(stderr, "Unknown signing option %s\n", arg );
+ exit(1);
+ }
+ }
+ break;
+ case 'P':
+ {
+ char *opt_password = NULL;
+ /* it is very useful to be able to make ads queries as the
+ machine account for testing purposes and for domain leave */
+
+ if (!secrets_init()) {
+ d_printf("ERROR: Unable to open secrets database\n");
+ exit(1);
+ }
+
+ opt_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
+
+ if (!opt_password) {
+ d_printf("ERROR: Unable to fetch machine password\n");
+ exit(1);
+ }
+ pstr_sprintf(cmdline_auth_info.username, "%s$",
+ global_myname());
+ pstrcpy(cmdline_auth_info.password,opt_password);
+ SAFE_FREE(opt_password);
+
+ /* machine accounts only work with kerberos */
+ cmdline_auth_info.use_kerberos = True;
+ cmdline_auth_info.got_pass = True;
+ }
+ break;
}
}
@@ -338,5 +386,7 @@ struct poptOption popt_common_credentials[] = {
{ "no-pass", 'N', POPT_ARG_NONE, &cmdline_auth_info.got_pass, 0, "Don't ask for a password" },
{ "kerberos", 'k', POPT_ARG_NONE, &cmdline_auth_info.use_kerberos, 'k', "Use kerberos (active directory) authentication" },
{ "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
+ { "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" },
+ {"machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" },
POPT_TABLEEND
};
diff --git a/source/lib/readline.c b/source/lib/readline.c
index ceb02ef749c..78b99fd7fb0 100644
--- a/source/lib/readline.c
+++ b/source/lib/readline.c
@@ -51,7 +51,7 @@
****************************************************************************/
static char *smb_readline_replacement(char *prompt, void (*callback)(void),
- char **(completion_fn)(char *text, int start, int end))
+ char **(completion_fn)(const char *text, int start, int end))
{
fd_set fds;
static pstring line;
@@ -83,7 +83,7 @@ static char *smb_readline_replacement(char *prompt, void (*callback)(void),
****************************************************************************/
char *smb_readline(char *prompt, void (*callback)(void),
- char **(completion_fn)(char *text, int start, int end))
+ char **(completion_fn)(const char *text, int start, int end))
{
#if HAVE_LIBREADLINE
if (isatty(x_fileno(x_stdin))) {
diff --git a/source/lib/replace.c b/source/lib/replace.c
index 0c62ec9bfa5..cd48b8d160f 100644
--- a/source/lib/replace.c
+++ b/source/lib/replace.c
@@ -447,21 +447,3 @@ char *rep_inet_ntoa(struct in_addr ip)
return t;
}
#endif
-
-#ifndef HAVE_SETENV
- int setenv(const char *name, const char *value, int overwrite)
-{
- char *p = NULL;
- int ret = -1;
-
- asprintf(&p, "%s=%s", name, value);
-
- if (overwrite || getenv(name)) {
- if (p) ret = putenv(p);
- } else {
- ret = 0;
- }
-
- return ret;
-}
-#endif
diff --git a/source/lib/replace1.c b/source/lib/replace1.c
new file mode 100644
index 00000000000..e1be56eb128
--- /dev/null
+++ b/source/lib/replace1.c
@@ -0,0 +1,42 @@
+/*
+ Unix SMB/CIFS implementation.
+ replacement routines for broken systems
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+ void replace1_dummy(void);
+ void replace1_dummy(void) {}
+
+#ifndef HAVE_SETENV
+ int setenv(const char *name, const char *value, int overwrite)
+{
+ char *p = NULL;
+ int ret = -1;
+
+ asprintf(&p, "%s=%s", name, value);
+
+ if (overwrite || getenv(name)) {
+ if (p) ret = putenv(p);
+ } else {
+ ret = 0;
+ }
+
+ return ret;
+}
+#endif
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index 39c1990decb..1ce03491da1 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -5,7 +5,7 @@
Copyright (C) Gerald Carter 2001-2003
Copyright (C) Shahms King 2001
Copyright (C) Andrew Bartlett 2002-2003
- Copyright (C) Stefan (metze) Metzmacher 2002
+ Copyright (C) Stefan (metze) Metzmacher 2002-2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -35,6 +35,8 @@
#define SMBLDAP_DONT_PING_TIME 10 /* ping only all 10 seconds */
#define SMBLDAP_NUM_RETRIES 8 /* retry only 8 times */
+#define SMBLDAP_IDLE_TIME 150 /* After 2.5 minutes disconnect */
+
/* attributes used by Samba 2.2 */
@@ -925,6 +927,8 @@ int smbldap_search(struct smbldap_state *ldap_state,
smbldap_close(ldap_state);
}
+ ldap_state->last_use = time(NULL);
+
SAFE_FREE(utf8_filter);
return rc;
}
@@ -954,6 +958,8 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
smbldap_close(ldap_state);
}
+ ldap_state->last_use = time(NULL);
+
SAFE_FREE(utf8_dn);
return rc;
}
@@ -983,6 +989,8 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
smbldap_close(ldap_state);
}
+ ldap_state->last_use = time(NULL);
+
SAFE_FREE(utf8_dn);
return rc;
}
@@ -1012,6 +1020,8 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
smbldap_close(ldap_state);
}
+ ldap_state->last_use = time(NULL);
+
SAFE_FREE(utf8_dn);
return rc;
}
@@ -1041,6 +1051,8 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state,
smbldap_close(ldap_state);
}
+ ldap_state->last_use = time(NULL);
+
return rc;
}
@@ -1071,6 +1083,24 @@ int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter,
return rc;
}
+static void smbldap_idle_fn(void **data, time_t *interval, time_t now)
+{
+ struct smbldap_state *state = (struct smbldap_state *)(*data);
+
+ if (state->ldap_struct == NULL) {
+ DEBUG(10,("ldap connection not connected...\n"));
+ return;
+ }
+
+ if ((state->last_use+SMBLDAP_IDLE_TIME) > now) {
+ DEBUG(10,("ldap connection not idle...\n"));
+ return;
+ }
+
+ DEBUG(7,("ldap connection idle...closing connection\n"));
+ smbldap_close(state);
+}
+
/**********************************************************************
Housekeeping
*********************************************************************/
@@ -1086,6 +1116,8 @@ void smbldap_free_struct(struct smbldap_state **ldap_state)
SAFE_FREE((*ldap_state)->bind_dn);
SAFE_FREE((*ldap_state)->bind_secret);
+ smb_unregister_idle_event((*ldap_state)->event_id);
+
*ldap_state = NULL;
/* No need to free any further, as it is talloc()ed */
@@ -1109,6 +1141,16 @@ NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_
} else {
(*smbldap_state)->uri = "ldap://localhost";
}
+
+ (*smbldap_state)->event_id =
+ smb_register_idle_event(smbldap_idle_fn, (void *)(*smbldap_state),
+ SMBLDAP_IDLE_TIME);
+
+ if ((*smbldap_state)->event_id == SMB_EVENT_ID_INVALID) {
+ DEBUG(0,("Failed to register LDAP idle event!\n"));
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
return NT_STATUS_OK;
}
@@ -1130,6 +1172,9 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
LDAPMessage *result = NULL;
int num_result;
char **attr_list;
+ uid_t u_low, u_high;
+ gid_t g_low, g_high;
+ uint32 rid_low, rid_high;
slprintf (filter, sizeof (filter) - 1, "(&(%s=%s)(objectclass=%s))",
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
@@ -1155,7 +1200,7 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
DEBUG(3,("Adding new domain\n"));
ldap_op = LDAP_MOD_ADD;
- snprintf(dn, sizeof(dn), "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
+ pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
domain_name, lp_ldap_suffix());
/* Free original search */
@@ -1175,6 +1220,30 @@ static NTSTATUS add_new_domain_info(struct smbldap_state *ldap_state,
smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_ALGORITHMIC_RID_BASE),
algorithmic_rid_base_string);
smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
+
+ /* add the sambaNext[User|Group]Rid attributes if the idmap ranges are set.
+ TODO: fix all the places where the line between idmap and normal operations
+ needed by smbd gets fuzzy --jerry 2003-08-11 */
+
+ if ( lp_idmap_uid(&u_low, &u_high) && lp_idmap_gid(&g_low, &g_high)
+ && get_free_rid_range(&rid_low, &rid_high) )
+ {
+ fstring rid_str;
+
+ fstr_sprintf( rid_str, "%i", rid_high|USER_RID_TYPE );
+ DEBUG(10,("setting next available user rid [%s]\n", rid_str));
+ smbldap_set_mod(&mods, LDAP_MOD_ADD,
+ get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
+ rid_str);
+
+ fstr_sprintf( rid_str, "%i", rid_high|GROUP_RID_TYPE );
+ DEBUG(10,("setting next available group rid [%s]\n", rid_str));
+ smbldap_set_mod(&mods, LDAP_MOD_ADD,
+ get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
+ rid_str);
+
+ }
+
switch(ldap_op)
{
@@ -1220,7 +1289,7 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
char **attr_list;
int count;
- snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
LDAP_OBJ_DOMINFO,
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
domain_name);
diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c
index 9b9ceb60cac..a2f9f592db3 100644
--- a/source/lib/snprintf.c
+++ b/source/lib/snprintf.c
@@ -823,12 +823,10 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
*
* The logic for these two is that we need our own definition if the
* OS *either* has no definition of *sprintf, or if it does have one
- * that doesn't work properly according to the autoconf test. Perhaps
- * these should really be smb_snprintf to avoid conflicts with buggy
- * linkers? -- mbp
+ * that doesn't work properly according to the autoconf test.
*/
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
- int snprintf(char *str,size_t count,const char *fmt,...)
+int smb_snprintf(char *str,size_t count,const char *fmt,...)
{
size_t ret;
va_list ap;
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index ac2cf687c49..c0d0096806a 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -58,8 +58,8 @@ void set_local_machine_name(const char* local_name, BOOL perm)
fstrcpy(tmp_local_machine,local_name);
trim_string(tmp_local_machine," "," ");
- strlower_m(tmp_local_machine);
alpha_strcpy(local_machine,tmp_local_machine,SAFE_NETBIOS_CHARS,sizeof(local_machine)-1);
+ strlower_m(local_machine);
}
/**
@@ -80,8 +80,8 @@ void set_remote_machine_name(const char* remote_name, BOOL perm)
fstrcpy(tmp_remote_machine,remote_name);
trim_string(tmp_remote_machine," "," ");
- strlower_m(tmp_remote_machine);
alpha_strcpy(remote_machine,tmp_remote_machine,SAFE_NETBIOS_CHARS,sizeof(remote_machine)-1);
+ strlower_m(remote_machine);
}
const char* get_remote_machine_name(void)
diff --git a/source/lib/sysquotas.c b/source/lib/sysquotas.c
index efc9e65b9de..617f624daea 100644
--- a/source/lib/sysquotas.c
+++ b/source/lib/sysquotas.c
@@ -48,12 +48,6 @@ static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
switch (qtype) {
case SMB_USER_QUOTA_TYPE:
- /* we use id.uid == 0 for default quotas */
- if (id.uid == 0) {
- ret = 0;
- break;
- }
-
if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))) {
return ret;
}
@@ -88,13 +82,19 @@ static int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
qflags |= QUOTAS_DENY_DISK;
}
- /* get the default quotas stored in the root's (uid =0) record */
- if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, 0, (CADDR_T)&D))) {
- return ret;
+ ret = 0;
+ break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_FS_QUOTA_TYPE:
+ id.gid = getgid();
+
+ if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) {
+ qflags |= QUOTAS_DENY_DISK;
}
ret = 0;
break;
+#endif /* HAVE_GROUP_QUOTA */
default:
errno = ENOSYS;
return -1;
@@ -122,6 +122,7 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
{
int ret = -1;
uint32 qflags = 0;
+ uint32 oldqflags = 0;
struct SYS_DQBLK D;
SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
@@ -146,10 +147,7 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
switch (qtype) {
case SMB_USER_QUOTA_TYPE:
- /* we use id.uid == 0 for default quotas */
- if (id.uid>0) {
- ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D);
- }
+ ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D);
break;
#ifdef HAVE_GROUP_QUOTA
case SMB_GROUP_QUOTA_TYPE:
@@ -160,7 +158,7 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
/* this stuff didn't work as it should:
* switching on/off quota via quotactl()
* didn't work!
- * So we only set the default limits
+ * So we just return 0
* --metze
*
* On HPUX we didn't have the mount path,
@@ -168,9 +166,9 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
*
*/
#if 0
- uid = getuid();
+ id.uid = getuid();
- ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, uid, (CADDR_T)&D);
+ ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D);
if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
if (ret == 0) {
@@ -197,14 +195,79 @@ static int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
}
DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
- ret,errno,strerror(errno),uid,bdev));
+ ret,errno,strerror(errno),id.uid,bdev));
+#else
+ id.uid = getuid();
+
+ if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D))==0) {
+ oldqflags |= QUOTAS_DENY_DISK;
+ }
+
+ if (oldqflags == qflags) {
+ ret = 0;
+ } else {
+ ret = -1;
+ }
#endif
-
- /* we use uid == 0 for default quotas */
- ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, 0, (CADDR_T)&D);
-
break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_FS_QUOTA_TYPE:
+ /* this stuff didn't work as it should:
+ * switching on/off quota via quotactl()
+ * didn't work!
+ * So we just return 0
+ * --metze
+ *
+ * On HPUX we didn't have the mount path,
+ * we need to fix sys_path_to_bdev()
+ *
+ */
+#if 0
+ id.gid = getgid();
+
+ ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (CADDR_T)&D);
+
+ if ((qflags&QUOTAS_DENY_DISK)||(qflags&QUOTAS_ENABLED)) {
+ if (ret == 0) {
+ char *quota_file = NULL;
+
+ asprintf(&quota_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION);
+ if (quota_file == NULL) {
+ DEBUG(0,("asprintf() failed!\n"));
+ errno = ENOMEM;
+ return -1;
+ }
+
+ ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), bdev, -1,(CADDR_T)quota_file);
+ } else {
+ ret = 0;
+ }
+ } else {
+ if (ret != 0) {
+ /* turn off */
+ ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), bdev, -1, (CADDR_T)0);
+ } else {
+ ret = 0;
+ }
+ }
+
+ DEBUG(0,("vfs_fs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
+ ret,errno,strerror(errno),id.gid,bdev));
+#else
+ id.gid = getgid();
+
+ if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (CADDR_T)&D))==0) {
+ oldqflags |= QUOTAS_DENY_DISK;
+ }
+ if (oldqflags == qflags) {
+ ret = 0;
+ } else {
+ ret = -1;
+ }
+#endif
+ break;
+#endif /* HAVE_GROUP_QUOTA */
default:
errno = ENOSYS;
return -1;
@@ -383,7 +446,7 @@ static int sys_path_to_bdev(const char *path, char **mntpath, char **bdev, char
****************************************************************************/
static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
{
- int ret;
+ int ret = -1;
uint32 qflags = 0;
SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
struct fs_disk_quota D;
@@ -399,11 +462,6 @@ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
switch (qtype) {
case SMB_USER_QUOTA_TYPE:
- /* we use id.uid == 0 for default quotas */
- if (id.uid == 0) {
- ret = 0;
- break;
- }
if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (CADDR_T)&D)))
return ret;
break;
@@ -413,10 +471,8 @@ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
return ret;
break;
#endif /* HAVE_GROUP_QUOTA */
- case SMB_USER_FS_QUOTA_TYPE:
- /* TODO: get quota status from quotactl() ... */
- if ((ret = quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F)))
- return ret;
+ case SMB_USER_FS_QUOTA_TYPE:
+ quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F);
if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
qflags |= QUOTAS_DENY_DISK;
@@ -425,11 +481,24 @@ static int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
qflags |= QUOTAS_ENABLED;
}
- /* we use uid == 0 for default quotas */
- if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, 0, (CADDR_T)&D)))
- return ret;
+ ret = 0;
break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_FS_QUOTA_TYPE:
+ quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F);
+
+ if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
+ qflags |= QUOTAS_DENY_DISK;
+ }
+ else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
+ qflags |= QUOTAS_ENABLED;
+ }
+
+ ret = 0;
+
+ break;
+#endif /* HAVE_GROUP_QUOTA */
default:
errno = ENOSYS;
return -1;
@@ -481,11 +550,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
switch (qtype) {
case SMB_USER_QUOTA_TYPE:
- /* we use uid == 0 for default quotas */
- if (id.uid>0) {
- D.d_fieldmask |= FS_DQ_LIMIT_MASK;
- ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D);
- }
+ D.d_fieldmask |= FS_DQ_LIMIT_MASK;
+ ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (CADDR_T)&D);
break;
#ifdef HAVE_GROUP_QUOTA
case SMB_GROUP_QUOTA_TYPE:
@@ -494,7 +560,6 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
break;
#endif /* HAVE_GROUP_QUOTA */
case SMB_USER_FS_QUOTA_TYPE:
- /* TODO */
quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (CADDR_T)&F);
if (qflags & QUOTAS_DENY_DISK) {
@@ -505,6 +570,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
if (q_on != 0) {
ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on);
+ } else {
+ ret = 0;
}
} else if (qflags & QUOTAS_ENABLED) {
@@ -513,6 +580,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
if (q_off != 0) {
ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off);
+ } else {
+ ret = 0;
}
if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
@@ -520,6 +589,8 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
if (q_on != 0) {
ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (CADDR_T)&q_on);
+ } else {
+ ret = 0;
}
} else {
#if 0
@@ -533,14 +604,71 @@ static int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_
if (q_off !=0) {
ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (CADDR_T)&q_off);
+ } else {
+ ret = 0;
}
+#else
+ ret = -1;
#endif
}
+
+ break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_FS_QUOTA_TYPE:
+ quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (CADDR_T)&F);
- /* we use uid == 0 for default quotas */
- D.d_fieldmask |= FS_DQ_LIMIT_MASK;
- ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, 0, (CADDR_T)&D);
+ if (qflags & QUOTAS_DENY_DISK) {
+ if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
+ q_on |= XFS_QUOTA_UDQ_ENFD;
+ if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
+ q_on |= XFS_QUOTA_UDQ_ACCT;
+
+ if (q_on != 0) {
+ ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on);
+ } else {
+ ret = 0;
+ }
+
+ } else if (qflags & QUOTAS_ENABLED) {
+ if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
+ q_off |= XFS_QUOTA_UDQ_ENFD;
+
+ if (q_off != 0) {
+ ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off);
+ } else {
+ ret = 0;
+ }
+
+ if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
+ q_on |= XFS_QUOTA_UDQ_ACCT;
+
+ if (q_on != 0) {
+ ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (CADDR_T)&q_on);
+ } else {
+ ret = 0;
+ }
+ } else {
+#if 0
+ /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
+ * only swittching off XFS_QUOTA_UDQ_ACCT work
+ */
+ if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
+ q_off |= XFS_QUOTA_UDQ_ENFD;
+ if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
+ q_off |= XFS_QUOTA_UDQ_ACCT;
+
+ if (q_off !=0) {
+ ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (CADDR_T)&q_off);
+ } else {
+ ret = 0;
+ }
+#else
+ ret = -1;
+#endif
+ }
+
break;
+#endif /* HAVE_GROUP_QUOTA */
default:
errno = ENOSYS;
return -1;
@@ -783,12 +911,17 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
}
if ((ret=sys_path_to_bdev(path,&mntpath,&bdev,&fs))!=0) {
+ DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path));
return ret;
}
for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].get_quota);i++) {
if (strcmp(fs,sys_quota_backends[i].name)==0) {
ret = sys_quota_backends[i].get_quota(mntpath, bdev, qtype, id, dp);
+ if (ret!=0) {
+ DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
+ fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret));
+ }
ready = True;
break;
}
@@ -796,7 +929,11 @@ int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
if (!ready) {
/* use the default vfs quota functions */
- ret = sys_get_vfs_quota(mntpath, bdev, qtype, id, dp);
+ ret=sys_get_vfs_quota(mntpath, bdev, qtype, id, dp);
+ if (ret!=0) {
+ DEBUG(10,("sys_get_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
+ "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret));
+ }
}
SAFE_FREE(mntpath);
@@ -831,12 +968,17 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
}
if ((ret=sys_path_to_bdev(path,&mntpath,&bdev,&fs))!=0) {
+ DEBUG(0,("sys_path_to_bdev() failed for path [%s]!\n",path));
return ret;
}
for (i=0;(fs && sys_quota_backends[i].name && sys_quota_backends[i].set_quota);i++) {
if (strcmp(fs,sys_quota_backends[i].name)==0) {
ret = sys_quota_backends[i].set_quota(mntpath, bdev, qtype, id, dp);
+ if (ret!=0) {
+ DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
+ fs,mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret));
+ }
ready = True;
break;
}
@@ -845,6 +987,10 @@ int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DI
if (!ready) {
/* use the default vfs quota functions */
ret=sys_set_vfs_quota(mntpath, bdev, qtype, id, dp);
+ if (ret!=0) {
+ DEBUG(10,("sys_set_%s_quota() failed for mntpath[%s] bdev[%s] qtype[%d] id[%d] ret[%d].\n",
+ "vfs",mntpath,bdev,qtype,(qtype==SMB_GROUP_QUOTA_TYPE?id.gid:id.uid),ret));
+ }
}
SAFE_FREE(mntpath);
diff --git a/source/lib/system.c b/source/lib/system.c
index a7024c852df..b020a203730 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -1263,6 +1263,16 @@ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t si
{
#if defined(HAVE_GETXATTR)
return getxattr(path, name, value, size);
+#elif defined(HAVE_ATTR_GET)
+ int retval, flags = 0;
+ int valuelength = (int)size;
+ char *attrname = strchr(name,'.') +1;
+
+ if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
+
+ retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
+
+ return retval ? retval : valuelength;
#else
errno = ENOSYS;
return -1;
@@ -1273,6 +1283,16 @@ ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t s
{
#if defined(HAVE_LGETXATTR)
return lgetxattr(path, name, value, size);
+#elif defined(HAVE_ATTR_GET)
+ int retval, flags = ATTR_DONTFOLLOW;
+ int valuelength = (int)size;
+ char *attrname = strchr(name,'.') +1;
+
+ if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
+
+ retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
+
+ return retval ? retval : valuelength;
#else
errno = ENOSYS;
return -1;
@@ -1283,16 +1303,96 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
{
#if defined(HAVE_FGETXATTR)
return fgetxattr(filedes, name, value, size);
+#elif defined(HAVE_ATTR_GETF)
+ int retval, flags = 0;
+ int valuelength = (int)size;
+ char *attrname = strchr(name,'.') +1;
+
+ if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
+
+ retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
+
+ return retval ? retval : valuelength;
#else
errno = ENOSYS;
return -1;
#endif
}
+#if defined(HAVE_ATTR_LIST)
+static char attr_buffer[ATTR_MAX_VALUELEN];
+
+static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
+{
+ int retval = 0, index;
+ attrlist_cursor_t *cursor = 0;
+ int total_size = 0;
+ attrlist_t * al = (attrlist_t *)attr_buffer;
+ attrlist_ent_t *ae;
+ size_t ent_size, left = size;
+ char *bp = list;
+
+ while (True) {
+ if (filedes)
+ retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
+ else
+ retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
+ if (retval) break;
+ for (index = 0; index < al->al_count; index++) {
+ ae = ATTR_ENTRY(attr_buffer, index);
+ ent_size = strlen(ae->a_name) + sizeof("user.");
+ if (left >= ent_size) {
+ strncpy(bp, "user.", sizeof("user."));
+ strncat(bp, ae->a_name, ent_size - sizeof("user."));
+ bp += ent_size;
+ left -= ent_size;
+ } else if (size) {
+ errno = ERANGE;
+ retval = -1;
+ break;
+ }
+ total_size += ent_size;
+ }
+ if (al->al_more == 0) break;
+ }
+ if (retval == 0) {
+ flags |= ATTR_ROOT;
+ cursor = 0;
+ while (True) {
+ if (filedes)
+ retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
+ else
+ retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
+ if (retval) break;
+ for (index = 0; index < al->al_count; index++) {
+ ae = ATTR_ENTRY(attr_buffer, index);
+ ent_size = strlen(ae->a_name) + sizeof("system.");
+ if (left >= ent_size) {
+ strncpy(bp, "system.", sizeof("system."));
+ strncat(bp, ae->a_name, ent_size - sizeof("system."));
+ bp += ent_size;
+ left -= ent_size;
+ } else if (size) {
+ errno = ERANGE;
+ retval = -1;
+ break;
+ }
+ total_size += ent_size;
+ }
+ if (al->al_more == 0) break;
+ }
+ }
+ return (ssize_t)(retval ? retval : total_size);
+}
+
+#endif
+
ssize_t sys_listxattr (const char *path, char *list, size_t size)
{
#if defined(HAVE_LISTXATTR)
return listxattr(path, list, size);
+#elif defined(HAVE_ATTR_LIST)
+ return irix_attr_list(path, 0, list, size, 0);
#else
errno = ENOSYS;
return -1;
@@ -1301,8 +1401,10 @@ ssize_t sys_listxattr (const char *path, char *list, size_t size)
ssize_t sys_llistxattr (const char *path, char *list, size_t size)
{
-#if defined(HAVE_GETXATTR)
+#if defined(HAVE_LLISTXATTR)
return llistxattr(path, list, size);
+#elif defined(HAVE_ATTR_LIST)
+ return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
#else
errno = ENOSYS;
return -1;
@@ -1313,6 +1415,8 @@ ssize_t sys_flistxattr (int filedes, char *list, size_t size)
{
#if defined(HAVE_FLISTXATTR)
return flistxattr(filedes, list, size);
+#elif defined(HAVE_ATTR_LISTF)
+ return irix_attr_list(NULL, filedes, list, size, 0);
#else
errno = ENOSYS;
return -1;
@@ -1323,6 +1427,13 @@ int sys_removexattr (const char *path, const char *name)
{
#if defined(HAVE_REMOVEXATTR)
return removexattr(path, name);
+#elif defined(HAVE_ATTR_REMOVE)
+ int flags = 0;
+ char *attrname = strchr(name,'.') +1;
+
+ if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
+
+ return attr_remove(path, attrname, flags);
#else
errno = ENOSYS;
return -1;
@@ -1333,6 +1444,13 @@ int sys_lremovexattr (const char *path, const char *name)
{
#if defined(HAVE_LREMOVEXATTR)
return lremovexattr(path, name);
+#elif defined(HAVE_ATTR_REMOVE)
+ int flags = ATTR_DONTFOLLOW;
+ char *attrname = strchr(name,'.') +1;
+
+ if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
+
+ return attr_remove(path, attrname, flags);
#else
errno = ENOSYS;
return -1;
@@ -1343,16 +1461,37 @@ int sys_fremovexattr (int filedes, const char *name)
{
#if defined(HAVE_FREMOVEXATTR)
return fremovexattr(filedes, name);
+#elif defined(HAVE_ATTR_REMOVEF)
+ int flags = 0;
+ char *attrname = strchr(name,'.') +1;
+
+ if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
+
+ return attr_removef(filedes, attrname, flags);
#else
errno = ENOSYS;
return -1;
#endif
}
+#if !defined(HAVE_SETXATTR)
+#define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
+#define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
+#endif
+
int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
{
#if defined(HAVE_SETXATTR)
return setxattr(path, name, value, size, flags);
+#elif defined(HAVE_ATTR_SET)
+ int myflags = 0;
+ char *attrname = strchr(name,'.') +1;
+
+ if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
+ if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
+ if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
+
+ return attr_set(path, attrname, (const char *)value, size, myflags);
#else
errno = ENOSYS;
return -1;
@@ -1363,6 +1502,15 @@ int sys_lsetxattr (const char *path, const char *name, const void *value, size_t
{
#if defined(HAVE_LSETXATTR)
return lsetxattr(path, name, value, size, flags);
+#elif defined(HAVE_ATTR_SET)
+ int myflags = ATTR_DONTFOLLOW;
+ char *attrname = strchr(name,'.') +1;
+
+ if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
+ if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
+ if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
+
+ return attr_set(path, attrname, (const char *)value, size, myflags);
#else
errno = ENOSYS;
return -1;
@@ -1373,6 +1521,15 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size
{
#if defined(HAVE_FSETXATTR)
return fsetxattr(filedes, name, value, size, flags);
+#elif defined(HAVE_ATTR_SETF)
+ int myflags = 0;
+ char *attrname = strchr(name,'.') +1;
+
+ if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
+ if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
+ if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
+
+ return attr_setf(filedes, attrname, (const char *)value, size, myflags);
#else
errno = ENOSYS;
return -1;
diff --git a/source/lib/username.c b/source/lib/username.c
index 98b8f33aae3..6321d470212 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -386,7 +386,7 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL
if ( DEBUGLEVEL >= 10 ) {
DEBUG(10,("user_in_winbind_group_list: using groups -- "));
for ( i=0; i<num_groups; i++ )
- DEBUGADD(10,("%d ", groups[i]));
+ DEBUGADD(10,("%lu ", (unsigned long)groups[i]));
DEBUGADD(10,("\n"));
}
@@ -593,7 +593,7 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_gr
will return domain local groups; while NT4 or mixed mode 2k DCs
will not */
- if ( winbind_lookup_name(NULL, *list, &g_sid, &name_type)
+ if ( winbind_lookup_name(domain, groupname, &g_sid, &name_type)
&& ( name_type==SID_NAME_DOM_GRP ||
(strequal(lp_workgroup(), domain) && name_type==SID_NAME_ALIAS) ) )
{
diff --git a/source/lib/util.c b/source/lib/util.c
index a7c939fe5a0..5f4fae9baa2 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -4,7 +4,7 @@
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 2001-2002
Copyright (C) Simo Sorce 2001
- Copyright (C) Anthony Liguori 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
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
@@ -311,7 +311,7 @@ BOOL in_group(gid_t group, gid_t current_gid, int ngroups, const gid_t *groups)
static const char *Atoic(const char *p, int *n, const char *c)
{
- if (!isdigit((const int)*p)) {
+ if (!isdigit((int)*p)) {
DEBUG(5, ("Atoic: malformed number\n"));
return NULL;
}
@@ -2247,7 +2247,7 @@ char *pid_path(const char *name)
char *lib_path(const char *name)
{
static pstring fname;
- snprintf(fname, sizeof(fname), "%s/%s", dyn_LIBDIR, name);
+ fstr_sprintf(fname, "%s/%s", dyn_LIBDIR, name);
return fname;
}
@@ -2335,21 +2335,12 @@ BOOL ms_has_wild_w(const smb_ucs2_t *s)
BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
{
- fstring p2, s2;
-
if (strcmp(string,"..") == 0)
string = ".";
if (strcmp(pattern,".") == 0)
return False;
- if (is_case_sensitive)
- return ms_fnmatch(pattern, string, Protocol) == 0;
-
- fstrcpy(p2, pattern);
- fstrcpy(s2, string);
- strlower_m(p2);
- strlower_m(s2);
- return ms_fnmatch(p2, s2, Protocol) == 0;
+ return ms_fnmatch(pattern, string, Protocol, is_case_sensitive) == 0;
}
/*********************************************************
diff --git a/source/lib/util_file.c b/source/lib/util_file.c
index 02acbd4d7e1..638a6ca3429 100644
--- a/source/lib/util_file.c
+++ b/source/lib/util_file.c
@@ -455,8 +455,8 @@ void *map_file(char *fname, size_t size)
p = file_load(fname, &s2);
if (!p) return NULL;
if (s2 != size) {
- DEBUG(1,("incorrect size for %s - got %d expected %d\n",
- fname, s2, size));
+ DEBUG(1,("incorrect size for %s - got %lu expected %lu\n",
+ fname, (unsigned long)s2, (unsigned long)size));
if (p) free(p);
return NULL;
}
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index 00f14d7d26b..fbb393770d5 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -93,7 +93,7 @@ static const struct {
{SID_NAME_UNKNOWN, "UNKNOWN"},
{SID_NAME_COMPUTER, "Computer"},
- {0, NULL}
+ {(enum SID_NAME_USE)0, NULL}
};
const char *sid_type_lookup(uint32 sid_type)
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index 1bd4c3a96be..b8b84717084 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -289,7 +289,7 @@ ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,un
}
/****************************************************************************
- read data from the client, reading exactly N bytes.
+ Read data from the client, reading exactly N bytes.
****************************************************************************/
ssize_t read_data(int fd,char *buffer,size_t N)
@@ -397,7 +397,7 @@ static ssize_t write_socket_data(int fd,char *buffer,size_t N)
}
/****************************************************************************
-write to a socket
+ Write to a socket.
****************************************************************************/
ssize_t write_socket(int fd,char *buf,size_t len)
@@ -416,7 +416,7 @@ ssize_t write_socket(int fd,char *buf,size_t len)
}
/****************************************************************************
-send a keepalive packet (rfc1002)
+ Send a keepalive packet (rfc1002).
****************************************************************************/
BOOL send_keepalive(int client)
@@ -431,11 +431,11 @@ BOOL send_keepalive(int client)
/****************************************************************************
-read 4 bytes of a smb packet and return the smb length of the packet
-store the result in the buffer
-This version of the function will return a length of zero on receiving
-a keepalive packet.
-timeout is in milliseconds.
+ Read 4 bytes of a smb packet and return the smb length of the packet.
+ Store the result in the buffer.
+ This version of the function will return a length of zero on receiving
+ a keepalive packet.
+ Timeout is in milliseconds.
****************************************************************************/
static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
@@ -466,10 +466,10 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int
}
/****************************************************************************
-read 4 bytes of a smb packet and return the smb length of the packet
-store the result in the buffer. This version of the function will
-never return a session keepalive (length of zero).
-timeout is in milliseconds.
+ Read 4 bytes of a smb packet and return the smb length of the packet.
+ Store the result in the buffer. This version of the function will
+ never return a session keepalive (length of zero).
+ Timeout is in milliseconds.
****************************************************************************/
ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
@@ -493,11 +493,10 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
}
/****************************************************************************
- read an smb from a fd. Note that the buffer *MUST* be of size
- BUFFER_SIZE+SAFETY_MARGIN.
- The timeout is in milliseconds.
- This function will return on a
- receipt of a session keepalive packet.
+ Read an smb from a fd. Note that the buffer *MUST* be of size
+ BUFFER_SIZE+SAFETY_MARGIN.
+ The timeout is in milliseconds.
+ This function will return on receipt of a session keepalive packet.
****************************************************************************/
BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
@@ -553,11 +552,19 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
}
}
+ /* Check the incoming SMB signature. */
+ if (!srv_check_sign_mac(buffer)) {
+ DEBUG(0, ("receive_smb: SMB Signature verification failed on incoming packet!\n"));
+ if (smb_read_error == 0)
+ smb_read_error = READ_BAD_SIG;
+ return False;
+ };
+
return(True);
}
/****************************************************************************
- send an smb to a fd
+ Send an smb to a fd.
****************************************************************************/
BOOL send_smb(int fd,char *buffer)
@@ -565,6 +572,10 @@ BOOL send_smb(int fd,char *buffer)
size_t len;
size_t nwritten=0;
ssize_t ret;
+
+ /* Sign the outgoing packet if required. */
+ srv_calculate_sign_mac(buffer);
+
len = smb_len(buffer) + 4;
while (nwritten < len) {
@@ -647,80 +658,86 @@ int open_socket_in( int type, int port, int dlevel, uint32 socket_addr, BOOL reb
}
/****************************************************************************
- create an outgoing socket. timeout is in milliseconds.
- **************************************************************************/
+ Create an outgoing socket. timeout is in milliseconds.
+**************************************************************************/
int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
{
- struct sockaddr_in sock_out;
- int res,ret;
- int connect_loop = 10;
- int increment = 10;
+ struct sockaddr_in sock_out;
+ int res,ret;
+ int connect_loop = 10;
+ int increment = 10;
- /* create a socket to write to */
- res = socket(PF_INET, type, 0);
- if (res == -1)
- { DEBUG(0,("socket error\n")); return -1; }
+ /* create a socket to write to */
+ res = socket(PF_INET, type, 0);
+ if (res == -1) {
+ DEBUG(0,("socket error\n"));
+ return -1;
+ }
- if (type != SOCK_STREAM) return(res);
+ if (type != SOCK_STREAM)
+ return(res);
- memset((char *)&sock_out,'\0',sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)addr);
+ memset((char *)&sock_out,'\0',sizeof(sock_out));
+ putip((char *)&sock_out.sin_addr,(char *)addr);
- sock_out.sin_port = htons( port );
- sock_out.sin_family = PF_INET;
+ sock_out.sin_port = htons( port );
+ sock_out.sin_family = PF_INET;
- /* set it non-blocking */
- set_blocking(res,False);
+ /* set it non-blocking */
+ set_blocking(res,False);
- DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
+ DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
- /* and connect it to the destination */
-connect_again:
- ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
-
- /* Some systems return EAGAIN when they mean EINPROGRESS */
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN) && (connect_loop < timeout) ) {
- msleep(connect_loop);
- connect_loop += increment;
- if (increment < 250) {
- /* After 8 rounds we end up at a max of 255 msec */
- increment *= 1.5;
- }
- goto connect_again;
- }
-
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN)) {
- DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
- close(res);
- return -1;
- }
+ /* and connect it to the destination */
+ connect_again:
+
+ ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
+
+ /* Some systems return EAGAIN when they mean EINPROGRESS */
+ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
+ errno == EAGAIN) && (connect_loop < timeout) ) {
+ msleep(connect_loop);
+ connect_loop += increment;
+ if (increment < 250) {
+ /* After 8 rounds we end up at a max of 255 msec */
+ increment *= 1.5;
+ }
+ goto connect_again;
+ }
+
+ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
+ errno == EAGAIN)) {
+ DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
+ close(res);
+ return -1;
+ }
#ifdef EISCONN
- if (ret < 0 && errno == EISCONN) {
- errno = 0;
- ret = 0;
- }
+
+ if (ret < 0 && errno == EISCONN) {
+ errno = 0;
+ ret = 0;
+ }
#endif
- if (ret < 0) {
- DEBUG(2,("error connecting to %s:%d (%s)\n",
- inet_ntoa(*addr),port,strerror(errno)));
- close(res);
- return -1;
- }
+ if (ret < 0) {
+ DEBUG(2,("error connecting to %s:%d (%s)\n",
+ inet_ntoa(*addr),port,strerror(errno)));
+ close(res);
+ return -1;
+ }
- /* set it blocking again */
- set_blocking(res,True);
+ /* set it blocking again */
+ set_blocking(res,True);
- return res;
+ return res;
}
-/*
- open a connected UDP socket to host on port
-*/
+/****************************************************************************
+ Open a connected UDP socket to host on port
+**************************************************************************/
+
int open_udp_socket(const char *host, int port)
{
int type = SOCK_DGRAM;
@@ -783,9 +800,10 @@ struct in_addr *client_inaddr(struct sockaddr *sa)
}
/*******************************************************************
- matchname - determine if host name matches IP address. Used to
- confirm a hostname lookup to prevent spoof attacks
- ******************************************************************/
+ Matchname - determine if host name matches IP address. Used to
+ confirm a hostname lookup to prevent spoof attacks.
+******************************************************************/
+
static BOOL matchname(char *remotehost,struct in_addr addr)
{
struct hostent *hp;
@@ -828,10 +846,10 @@ static BOOL matchname(char *remotehost,struct in_addr addr)
return False;
}
-
/*******************************************************************
- return the DNS name of the remote end of a socket
- ******************************************************************/
+ Return the DNS name of the remote end of a socket.
+******************************************************************/
+
char *get_socket_name(int fd, BOOL force_lookup)
{
static pstring name_buf;
@@ -881,8 +899,9 @@ char *get_socket_name(int fd, BOOL force_lookup)
}
/*******************************************************************
- return the IP addr of the remote end of a socket as a string
+ Return the IP addr of the remote end of a socket as a string.
******************************************************************/
+
char *get_socket_addr(int fd)
{
struct sockaddr sa;
@@ -906,7 +925,6 @@ char *get_socket_addr(int fd)
return addr_buf;
}
-
/*******************************************************************
Create protected unix domain socket.
@@ -968,7 +986,7 @@ int create_pipe_sock(const char *socket_dir,
goto out_umask;
}
- snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name);
+ pstr_sprintf(path, "%s/%s", socket_dir, socket_name);
unlink(path);
memset(&sunaddr, 0, sizeof(sunaddr));
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 96fbc3f1247..eb1c70d4129 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -37,7 +37,7 @@
**/
BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
{
- const char *s;
+ char *s;
char *pbuf;
BOOL quoted;
size_t len=1;
@@ -45,7 +45,7 @@ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
if (!ptr)
return(False);
- s = *ptr;
+ s = (char *)*ptr;
/* default to simple separators */
if (!sep)
@@ -88,7 +88,7 @@ BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
{
BOOL ret;
if (!ptr)
- ptr = (const char **)&last_ptr;
+ ptr = &last_ptr;
ret = next_token(ptr, buff, sep, bufsize);
last_ptr = *ptr;
@@ -109,7 +109,7 @@ void set_first_token(char *ptr)
char **toktocliplist(int *ctok, const char *sep)
{
- char *s=last_ptr;
+ char *s=(char *)last_ptr;
int ictok=0;
char **ret, **iret;
@@ -132,7 +132,7 @@ char **toktocliplist(int *ctok, const char *sep)
} while(*s);
*ctok=ictok;
- s=last_ptr;
+ s=(char *)last_ptr;
if (!(ret=iret=malloc(ictok*sizeof(char *))))
return NULL;
@@ -181,7 +181,9 @@ int StrCaseCmp(const char *s, const char *t)
{
const char * ps, * pt;
- pstring buf1, buf2;
+ size_t size;
+ smb_ucs2_t *buffer_s, *buffer_t;
+ int ret;
for (ps = s, pt = t; ; ps++, pt++) {
char us, ut;
@@ -206,16 +208,25 @@ int StrCaseCmp(const char *s, const char *t)
return +1;
}
- /* TODO: Don't do this with a fixed-length buffer. This could
- * still be much more efficient. */
- /* TODO: Hardcode a char-by-char comparison for UTF-8, which
- * can be much faster. */
- /* TODO: Test case for this! */
-
- unix_strupper(ps, strlen(ps)+1, buf1, sizeof(buf1));
- unix_strupper(pt, strlen(pt)+1, buf2, sizeof(buf2));
-
- return strcmp(buf1, buf2);
+ size = push_ucs2_allocate(&buffer_s, s);
+ if (size == (size_t)-1) {
+ return strcmp(s, t);
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ }
+
+ size = push_ucs2_allocate(&buffer_t, t);
+ if (size == (size_t)-1) {
+ SAFE_FREE(buffer_s);
+ return strcmp(s, t);
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ }
+
+ ret = strcasecmp_w(buffer_s, buffer_t);
+ SAFE_FREE(buffer_s);
+ SAFE_FREE(buffer_t);
+ return ret;
}
@@ -351,7 +362,7 @@ BOOL strisnormal(const char *s)
NOTE: oldc and newc must be 7 bit characters
**/
-void string_replace(char *s,char oldc,char newc)
+void string_replace(pstring s,char oldc,char newc)
{
push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
@@ -1156,21 +1167,6 @@ void strlower_m(char *s)
}
/**
- Duplicate convert a string to lower case.
-**/
-
-char *strdup_lower(const char *s)
-{
- char *t = strdup(s);
- if (t == NULL) {
- DEBUG(0, ("strdup_lower: Out of memory!\n"));
- return NULL;
- }
- strlower_m(t);
- return t;
-}
-
-/**
Convert a string to upper case.
**/
@@ -1195,21 +1191,6 @@ void strupper_m(char *s)
}
/**
- Convert a string to upper case.
-**/
-
-char *strdup_upper(const char *s)
-{
- char *t = strdup(s);
- if (t == NULL) {
- DEBUG(0, ("strdup_upper: Out of memory!\n"));
- return NULL;
- }
- strupper_m(t);
- return t;
-}
-
-/**
Return a RFC2254 binary string representation of a buffer.
Used in LDAP filters.
Caller must free.
@@ -1575,7 +1556,7 @@ int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
- DEBUG(0,("ipstr_list_parse: malloc failed for %d entries\n", count));
+ DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
return 0;
}
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index ae000fba023..fd51f3c57d9 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -759,82 +759,6 @@ smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins)
return NULL;
}
-/*******************************************************************
-copy a string with max len
-********************************************************************/
-
-smb_ucs2_t *strncpy_wa(smb_ucs2_t *dest, const char *src, const size_t max)
-{
- smb_ucs2_t *ucs2_src;
-
- if (!dest || !src) return NULL;
- if (!(ucs2_src = acnv_uxu2(src)))
- return NULL;
-
- strncpy_w(dest, ucs2_src, max);
- SAFE_FREE(ucs2_src);
- return dest;
-}
-
-/*******************************************************************
-convert and duplicate an ascii string
-********************************************************************/
-smb_ucs2_t *strdup_wa(const char *src)
-{
- return strndup_wa(src, 0);
-}
-
-/* if len == 0 then duplicate the whole string */
-smb_ucs2_t *strndup_wa(const char *src, size_t len)
-{
- smb_ucs2_t *dest, *s;
-
- s = acnv_dosu2(src);
- if (!len) len = strlen_w(s);
- dest = (smb_ucs2_t *)malloc((len + 1) * sizeof(smb_ucs2_t));
- if (!dest) {
- DEBUG(0,("strdup_w: out of memory!\n"));
- SAFE_FREE(s);
- return NULL;
- }
-
- memcpy(dest, src, len * sizeof(smb_ucs2_t));
- dest[len] = 0;
-
- SAFE_FREE(s);
- return dest;
-}
-
-/*******************************************************************
-append a string of len bytes and add a terminator
-********************************************************************/
-
-smb_ucs2_t *strncat_wa(smb_ucs2_t *dest, const char *src, const size_t max)
-{
- smb_ucs2_t *ucs2_src;
-
- if (!dest || !src) return NULL;
- if (!(ucs2_src = acnv_uxu2(src)))
- return NULL;
-
- strncat_w(dest, ucs2_src, max);
- SAFE_FREE(ucs2_src);
- return dest;
-}
-
-smb_ucs2_t *strcat_wa(smb_ucs2_t *dest, const char *src)
-{
- smb_ucs2_t *ucs2_src;
-
- if (!dest || !src) return NULL;
- if (!(ucs2_src = acnv_uxu2(src)))
- return NULL;
-
- strcat_w(dest, ucs2_src);
- SAFE_FREE(ucs2_src);
- return dest;
-}
-
BOOL trim_string_wa(smb_ucs2_t *s, const char *front,
const char *back)
{
diff --git a/source/lib/util_uuid.c b/source/lib/util_uuid.c
index 83553ec28ec..56f0ecd85b9 100644
--- a/source/lib/util_uuid.c
+++ b/source/lib/util_uuid.c
@@ -2,7 +2,7 @@
* Unix SMB/CIFS implementation.
* UUID server routines
* Copyright (C) Theodore Ts'o 1996, 1997,
- * Copyright (C) Jim McDonough 2002.
+ * 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
diff --git a/source/libads/ads_status.c b/source/libads/ads_status.c
index 80fdb99eac0..b8f7788bd7a 100644
--- a/source/libads/ads_status.c
+++ b/source/libads/ads_status.c
@@ -87,7 +87,7 @@ NTSTATUS ads_ntstatus(ADS_STATUS status)
*/
const char *ads_errstr(ADS_STATUS status)
{
- int msg_ctx;
+ OM_uint32 msg_ctx;
static char *ret;
SAFE_FREE(ret);
diff --git a/source/libads/authdata.c b/source/libads/authdata.c
index c554a02e90e..29170af377e 100644
--- a/source/libads/authdata.c
+++ b/source/libads/authdata.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
kerberos authorization data (PAC) utility library
- Copyright (C) Jim McDonough 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
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
@@ -39,6 +39,7 @@ static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data)
asn1_end_tag(&data);
asn1_end_tag(&data);
asn1_end_tag(&data);
+ asn1_free(&data);
return pac_contents;
}
@@ -422,7 +423,7 @@ static BOOL pac_io_pac_signature_data(const char *desc,
if (!prs_uint32("type", ps, depth, &data->type))
return False;
if (UNMARSHALLING(ps)) {
- data->signature = prs_alloc_mem(ps, siglen);
+ data->signature = (unsigned char *)prs_alloc_mem(ps, siglen);
if (!data->signature) {
DEBUG(3, ("No memory available\n"));
return False;
@@ -600,9 +601,11 @@ PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx)
DEBUG(5,("dump_pac_data\n"));
prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL);
- prs_copy_data_in(&ps, pac_data_blob.data, pac_data_blob.length);
+ prs_copy_data_in(&ps, (char *)pac_data_blob.data, pac_data_blob.length);
prs_set_offset(&ps, 0);
+ data_blob_free(&pac_data_blob);
+
pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA));
pac_io_pac_data("pac data", pac_data, &ps, 0);
diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c
index 25b7f9d948b..3343194203f 100644
--- a/source/libads/kerberos_verify.c
+++ b/source/libads/kerberos_verify.c
@@ -28,7 +28,7 @@
verify an incoming ticket and parse out the principal name and
authorization_data if available
*/
-NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
+NTSTATUS ads_verify_ticket(const char *realm, const DATA_BLOB *ticket,
char **principal, DATA_BLOB *auth_data,
DATA_BLOB *ap_rep,
uint8 session_key[16])
@@ -60,13 +60,13 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
ZERO_STRUCTP(ap_rep);
if (!secrets_init()) {
- DEBUG(1,("secrets_init failed\n"));
+ DEBUG(1,("ads_verify_ticket: secrets_init failed\n"));
return NT_STATUS_LOGON_FAILURE;
}
password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
if (!password_s) {
- DEBUG(1,("failed to fetch machine password\n"));
+ DEBUG(1,("ads_verify_ticket: failed to fetch machine password\n"));
return NT_STATUS_LOGON_FAILURE;
}
@@ -75,13 +75,13 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
ret = krb5_init_context(&context);
if (ret) {
- DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_verify_ticket: krb5_init_context failed (%s)\n", error_message(ret)));
return NT_STATUS_LOGON_FAILURE;
}
- ret = krb5_set_default_realm(context, ads->auth.realm);
+ ret = krb5_set_default_realm(context, realm);
if (ret) {
- DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_verify_ticket: krb5_set_default_realm failed (%s)\n", error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
goto out;
}
@@ -92,7 +92,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
ret = krb5_auth_con_init(context, &auth_context);
if (ret) {
- DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_verify_ticket: krb5_auth_con_init failed (%s)\n", error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
goto out;
}
@@ -102,66 +102,83 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm());
ret = krb5_parse_name(context, host_princ_s, &host_princ);
if (ret) {
- DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret)));
+ DEBUG(1,("ads_verify_ticket: krb5_parse_name(%s) failed (%s)\n",
+ host_princ_s, error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
goto out;
}
/*
- * JRA. We must set the rcache and the allowed addresses in the auth_context
- * here. This will prevent replay attacks and ensure the client has got a key from
- * the correct IP address.
+ * JRA. We must set the rcache here. This will prevent replay attacks.
*/
ret = krb5_get_server_rcache(context, krb5_princ_component(context, host_princ, 0), &rcache);
if (ret) {
- DEBUG(1,("krb5_get_server_rcache failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_verify_ticket: krb5_get_server_rcache failed (%s)\n", error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
goto out;
}
ret = krb5_auth_con_setrcache(context, auth_context, rcache);
if (ret) {
- DEBUG(1,("krb5_auth_con_setrcache failed (%s)\n", error_message(ret)));
+ DEBUG(1,("ads_verify_ticket: krb5_auth_con_setrcache failed (%s)\n", error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
goto out;
}
- /* Now we need to add the addresses.... JRA. */
+ /* CIFS doesn't use addresses in tickets. This would breat NAT. JRA */
- if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
- sret = NT_STATUS_NO_MEMORY;
- goto out;
- }
-
if ((ret = get_kerberos_allowed_etypes(context, &enctypes))) {
- DEBUG(1,("krb5_get_permitted_enctypes failed (%s)\n",
+ DEBUG(1,("ads_verify_ticket: krb5_get_permitted_enctypes failed (%s)\n",
error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
goto out;
}
- /* we need to setup a auth context with each possible encoding type in turn */
+ /* Lock a mutex surrounding the replay as there is no locking in the MIT krb5
+ * code surrounding the replay cache... */
+
+ if (!grab_server_mutex("replay cache mutex")) {
+ DEBUG(1,("ads_verify_ticket: unable to protect replay cache with mutex.\n"));
+ sret = NT_STATUS_LOGON_FAILURE;
+ goto out;
+ }
+
+ /* We need to setup a auth context with each possible encoding type in turn. */
for (i=0;enctypes[i];i++) {
+ if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
+ sret = NT_STATUS_NO_MEMORY;
+ goto out;
+ }
+
if (create_kerberos_key_from_string(context, host_princ, &password, key, enctypes[i])) {
continue;
}
krb5_auth_con_setuseruserkey(context, auth_context, key);
+ krb5_free_keyblock(context, key);
+
packet.length = ticket->length;
packet.data = (krb5_pointer)ticket->data;
if (!(ret = krb5_rd_req(context, &auth_context, &packet,
NULL, keytab, NULL, &tkt))) {
- free_kerberos_etypes(context, enctypes);
+ DEBUG(10,("ads_verify_ticket: enc type [%u] decrypted message !\n",
+ (unsigned int)enctypes[i] ));
auth_ok = True;
break;
}
+
+ DEBUG((ret != KRB5_BAD_ENCTYPE) ? 3 : 10,
+ ("ads_verify_ticket: enc type [%u] failed to decrypt with error %s\n",
+ (unsigned int)enctypes[i], error_message(ret)));
}
+ release_server_mutex();
+
if (!auth_ok) {
- DEBUG(3,("krb5_rd_req with auth failed (%s)\n",
+ DEBUG(3,("ads_verify_ticket: krb5_rd_req with auth failed (%s)\n",
error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
goto out;
@@ -169,7 +186,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
ret = krb5_mk_rep(context, auth_context, &packet);
if (ret) {
- DEBUG(3,("Failed to generate mutual authentication reply (%s)\n",
+ DEBUG(3,("ads_verify_ticket: Failed to generate mutual authentication reply (%s)\n",
error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
goto out;
@@ -178,7 +195,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
*ap_rep = data_blob(packet.data, packet.length);
free(packet.data);
- get_krb5_smb_session_key(context, auth_context, session_key);
+ get_krb5_smb_session_key(context, auth_context, session_key, True);
#ifdef DEBUG_PASSWORD
DEBUG(10,("SMB session key (from ticket) follows:\n"));
dump_data(10, session_key, 16);
@@ -205,7 +222,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
if ((ret = krb5_unparse_name(context, get_principal_from_tkt(tkt),
principal))) {
- DEBUG(3,("krb5_unparse_name failed (%s)\n",
+ DEBUG(3,("ads_verify_ticket: krb5_unparse_name failed (%s)\n",
error_message(ret)));
sret = NT_STATUS_LOGON_FAILURE;
goto out;
@@ -221,8 +238,11 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
if (!NT_STATUS_IS_OK(sret))
data_blob_free(ap_rep);
- SAFE_FREE(host_princ_s);
+ krb5_free_principal(context, host_princ);
+ krb5_free_ticket(context, tkt);
+ free_kerberos_etypes(context, enctypes);
SAFE_FREE(password_s);
+ SAFE_FREE(host_princ_s);
if (auth_context)
krb5_auth_con_free(context, auth_context);
diff --git a/source/libads/krb5_setpw.c b/source/libads/krb5_setpw.c
index 80ef6cdf01c..d1da118bb87 100644
--- a/source/libads/krb5_setpw.c
+++ b/source/libads/krb5_setpw.c
@@ -143,7 +143,7 @@ static krb5_error_code build_kpasswd_request(uint16 pversion,
else
return EINVAL;
- encoded_setpw.data = setpw.data;
+ encoded_setpw.data = (char *)setpw.data;
encoded_setpw.length = setpw.length;
ret = krb5_mk_priv(context, auth_context,
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index 92f7f7645ac..5a12288b167 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -3,7 +3,7 @@
ads (active directory) utility library
Copyright (C) Andrew Tridgell 2001
Copyright (C) Remus Koos 2001
- Copyright (C) Jim McDonough 2002
+ 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
@@ -106,26 +106,39 @@ static BOOL ads_find_dc(ADS_STRUCT *ads)
struct ip_service *ip_list;
pstring realm;
BOOL got_realm = False;
+ BOOL use_own_domain = False;
+
+ /* if the realm and workgroup are both empty, assume they are ours */
/* realm */
c_realm = ads->server.realm;
- if (!c_realm || !*c_realm) {
- c_realm = lp_realm();
+
+ if ( !c_realm || !*c_realm ) {
+ /* special case where no realm and no workgroup means our own */
+ if ( !ads->server.workgroup || !*ads->server.workgroup ) {
+ use_own_domain = True;
+ c_realm = lp_realm();
+ }
}
- if ( c_realm )
+
+ if (c_realm && *c_realm)
got_realm = True;
-
-
+
again:
/* we need to try once with the realm name and fallback to the
netbios domain name if we fail (if netbios has not been disabled */
if ( !got_realm && !lp_disable_netbios() ) {
c_realm = ads->server.workgroup;
- if (!c_realm || !*c_realm)
- c_realm = lp_workgroup();
- if (!c_realm)
+ if (!c_realm || !*c_realm) {
+ if ( use_own_domain )
+ c_realm = lp_workgroup();
+ }
+
+ if ( !c_realm || !*c_realm ) {
+ DEBUG(0,("ads_find_dc: no realm or workgroup! Don't know what to do\n"));
return False;
+ }
}
pstrcpy( realm, c_realm );
@@ -1875,77 +1888,6 @@ ADS_STATUS ads_server_info(ADS_STRUCT *ads)
return ADS_SUCCESS;
}
-
-/**
- * find the list of trusted domains
- * @param ads connection to ads server
- * @param mem_ctx TALLOC_CTX for allocating results
- * @param num_trusts pointer to number of trusts
- * @param names pointer to trusted domain name list
- * @param sids pointer to list of sids of trusted domains
- * @return the count of SIDs pulled
- **/
-ADS_STATUS ads_trusted_domains(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
- int *num_trusts,
- char ***names,
- char ***alt_names,
- DOM_SID **sids)
-{
- const char *attrs[] = {"name", "flatname", "securityIdentifier",
- "trustDirection", NULL};
- ADS_STATUS status;
- void *res, *msg;
- int count, i;
-
- *num_trusts = 0;
-
- status = ads_search(ads, &res, "(objectcategory=trustedDomain)", attrs);
- if (!ADS_ERR_OK(status)) return status;
-
- count = ads_count_replies(ads, res);
- if (count == 0) {
- ads_msgfree(ads, res);
- return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
- }
-
- (*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)) {
- 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++;
- }
- }
-
- ads_msgfree(ads, res);
-
- *num_trusts = i;
-
- return ADS_SUCCESS;
-}
-
/**
* find the domain sid for our domain
* @param ads connection to ads server
diff --git a/source/libads/ldap_printer.c b/source/libads/ldap_printer.c
index b650a5eb38b..1448074ea02 100644
--- a/source/libads/ldap_printer.c
+++ b/source/libads/ldap_printer.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
ads (active directory) printer utility library
- Copyright (C) Jim McDonough 2002
+ 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
diff --git a/source/libads/ldap_user.c b/source/libads/ldap_user.c
index e70249dd784..56a0d8013b2 100644
--- a/source/libads/ldap_user.c
+++ b/source/libads/ldap_user.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
ads (active directory) utility library
- Copyright (C) Jim McDonough 2002
+ 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
diff --git a/source/libads/sasl.c b/source/libads/sasl.c
index 598208b17f8..0320bb0cfc5 100644
--- a/source/libads/sasl.c
+++ b/source/libads/sasl.c
@@ -60,7 +60,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
msg1 = gen_negTokenTarg(mechs, blob);
data_blob_free(&blob);
- cred.bv_val = msg1.data;
+ cred.bv_val = (char *)msg1.data;
cred.bv_len = msg1.length;
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
@@ -106,7 +106,7 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
data_blob_free(&blob);
/* now send the auth packet and we should be done */
- cred.bv_val = auth.data;
+ cred.bv_val = (char *)auth.data;
cred.bv_len = auth.length;
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
@@ -124,16 +124,17 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip
{
DATA_BLOB blob;
struct berval cred, *scred;
+ unsigned char sk[16];
int rc;
- blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset);
+ blob = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, sk);
if (!blob.data) {
return ADS_ERROR(LDAP_OPERATIONS_ERROR);
}
/* now send the auth packet and we should be done */
- cred.bv_val = blob.data;
+ cred.bv_val = (char *)blob.data;
cred.bv_len = blob.length;
rc = ldap_sasl_bind_s(ads->ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
@@ -226,7 +227,7 @@ failed:
*/
static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
{
- int minor_status;
+ OM_uint32 minor_status;
gss_name_t serv_name;
gss_buffer_desc input_name;
gss_ctx_id_t context_handle;
@@ -327,7 +328,7 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
gss_release_name(&minor_status, &serv_name);
gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token,
- &conf_state,NULL);
+ (int *)&conf_state,NULL);
if (gss_rc) {
status = ADS_ERROR_GSS(gss_rc, minor_status);
goto failed;
@@ -352,13 +353,13 @@ static 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->config.bind_path)+4, "dn:%s", ads->config.bind_path);
- p += strlen(p);
+ snprintf((char *)p, strlen(ads->config.bind_path)+4, "dn:%s", ads->config.bind_path);
+ p += strlen((const char *)p);
output_token.length = PTR_DIFF(p, output_token.value);
gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
- &output_token, &conf_state,
+ &output_token, (int *)&conf_state,
&input_token);
if (gss_rc) {
status = ADS_ERROR_GSS(gss_rc, minor_status);
diff --git a/source/libsmb/asn1.c b/source/libsmb/asn1.c
index 09d4fbb6c9a..576491dd3bc 100644
--- a/source/libsmb/asn1.c
+++ b/source/libsmb/asn1.c
@@ -322,9 +322,9 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID)
asn1_read_uint8(data, &b);
oid[0] = 0;
- snprintf(el, sizeof(el), "%u", b/40);
+ fstr_sprintf(el, "%u", b/40);
pstrcat(oid, el);
- snprintf(el, sizeof(el), " %u", b%40);
+ fstr_sprintf(el, " %u", b%40);
pstrcat(oid, el);
while (asn1_tag_remaining(data) > 0) {
@@ -333,7 +333,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID)
asn1_read_uint8(data, &b);
v = (v<<7) | (b&0x7f);
} while (!data->has_error && b & 0x80);
- snprintf(el, sizeof(el), " %u", v);
+ fstr_sprintf(el, " %u", v);
pstrcat(oid, el);
}
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 0dcc9e28459..010aa4d1bb4 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -131,55 +131,6 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli)
}
/****************************************************************************
- Do a NT1 guest session setup.
-****************************************************************************/
-
-static BOOL cli_session_setup_guest(struct cli_state *cli)
-{
- char *p;
- uint32 capabilities = cli_session_setup_capabilities(cli);
-
- set_message(cli->outbuf,13,0,True);
- SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
- cli_setup_packet(cli);
-
- SCVAL(cli->outbuf,smb_vwv0,0xFF);
- SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
- 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,0);
- SSVAL(cli->outbuf,smb_vwv8,0);
- SIVAL(cli->outbuf,smb_vwv11,capabilities);
- p = smb_buf(cli->outbuf);
- p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */
- p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */
- p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
- p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
- cli_setup_bcc(cli, p);
-
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
-
- show_msg(cli->inbuf);
-
- if (cli_is_error(cli))
- return False;
-
- cli->vuid = SVAL(cli->inbuf,smb_uid);
-
- p = smb_buf(cli->inbuf);
- p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE);
- p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE);
- p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE);
-
- fstrcpy(cli->user_name, "");
-
- return True;
-}
-
-/****************************************************************************
Do a NT1 plaintext session setup.
****************************************************************************/
@@ -190,7 +141,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
char *p;
fstring lanman;
- snprintf( lanman, sizeof(lanman), "Samba %s", VERSION );
+ fstr_sprintf( lanman, "Samba %s", VERSION );
set_message(cli->outbuf,13,0,True);
SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
@@ -267,8 +218,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
BOOL ret = False;
char *p;
- if (passlen != 24) {
- if (lp_client_ntlmv2_auth()) {
+ if (passlen == 0) {
+ /* do nothing - guest login */
+ } else if (passlen != 24) {
+ if ((cli->capabilities & CAP_EXTENDED_SECURITY) && lp_client_ntlmv2_auth()) {
DATA_BLOB server_chal;
DATA_BLOB names_blob;
server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
@@ -472,6 +425,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
/****************************************************************************
Use in-memory credentials cache
****************************************************************************/
+
static void use_in_memory_ccache(void) {
setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
}
@@ -483,18 +437,23 @@ static void use_in_memory_ccache(void) {
static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
{
DATA_BLOB blob2, negTokenTarg;
-
+ unsigned char session_key_krb5[16];
+ DATA_BLOB null_blob = data_blob(NULL, 0);
+
DEBUG(2,("Doing kerberos session setup\n"));
/* generate the encapsulated kerberos5 ticket */
- negTokenTarg = spnego_gen_negTokenTarg(principal, 0);
+ negTokenTarg = spnego_gen_negTokenTarg(principal, 0, session_key_krb5);
- if (!negTokenTarg.data) return False;
+ if (!negTokenTarg.data)
+ return False;
#if 0
file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
#endif
+ cli_simple_set_signing(cli, session_key_krb5, null_blob);
+
blob2 = cli_session_setup_blob(cli, negTokenTarg);
/* we don't need this blob for kerberos */
@@ -551,7 +510,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
blob_in, &blob_out);
data_blob_free(&blob_in);
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DATA_BLOB null = data_blob(NULL, 0);
+ DATA_BLOB null_blob = data_blob(NULL, 0);
if (turn == 1) {
/* and wrap it in a SPNEGO wrapper */
msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
@@ -562,7 +521,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
cli_simple_set_signing(cli,
ntlmssp_state->session_key.data,
- null);
+ null_blob);
/* now send that blob on its way */
if (!cli_session_setup_blob_send(cli, msg1)) {
@@ -604,6 +563,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
} while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
if (NT_STATUS_IS_OK(nt_status)) {
+ fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
set_cli_session_key(cli, ntlmssp_state->session_key);
}
@@ -630,7 +590,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user,
BOOL got_kerberos_mechanism = False;
DATA_BLOB blob;
- DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length));
+ DEBUG(2,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
/* the server might not even do spnego */
if (cli->secblob.length <= 16) {
@@ -671,7 +631,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user,
* and do not store results */
if (got_kerberos_mechanism && cli->use_kerberos) {
- if (*pass) {
+ if (pass && *pass) {
int ret;
use_in_memory_ccache();
@@ -744,12 +704,6 @@ BOOL cli_session_setup(struct cli_state *cli,
return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup);
}
- /* if no user is supplied then we have to do an anonymous connection.
- passwords are ignored */
-
- if (!user || !*user)
- return cli_session_setup_guest(cli);
-
/* if the server is share level then send a plaintext null
password at this point. The password is sent in the tree
connect */
@@ -757,6 +711,17 @@ BOOL cli_session_setup(struct cli_state *cli,
if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
return cli_session_setup_plaintext(cli, user, "", workgroup);
+ /* if no user is supplied then we have to do an anonymous connection.
+ passwords are ignored */
+
+ if (!user || !*user) {
+ user = "";
+ pass = NULL;
+ ntpass = NULL;
+ passlen = 0;
+ ntpasslen = 0;
+ }
+
/* if the server doesn't support encryption then we have to use
plaintext. The second password is ignored */
@@ -989,6 +954,11 @@ BOOL cli_negprot(struct cli_state *cli)
cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
+ if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
+ DEBUG(1,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
+ return False;
+ }
+
if (cli->protocol >= PROTOCOL_NT1) {
/* NT protocol */
cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
@@ -1013,22 +983,27 @@ BOOL cli_negprot(struct cli_state *cli)
smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN);
}
- if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) {
- /* Fail if signing is mandatory and we don't want to support it. */
- if (!lp_client_signing()) {
+ /*
+ * As signing is slow we only turn it on if either the client or
+ * the server require it. JRA.
+ */
+
+ if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
+ /* Fail if server says signing is mandatory and we don't want to support it. */
+ if (!cli->sign_info.allow_smb_signing) {
DEBUG(1,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
return False;
}
cli->sign_info.negotiated_smb_signing = True;
- }
-
- if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) && cli->sign_info.allow_smb_signing)
+ cli->sign_info.mandatory_signing = True;
+ } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
+ /* Fail if client says signing is mandatory and the server doesn't support it. */
+ if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
+ DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
+ return False;
+ }
cli->sign_info.negotiated_smb_signing = True;
-
- /* Fail if signing is mandatory and the server doesn't support it. */
- if (cli->sign_info.mandatory_signing && !(cli->sign_info.negotiated_smb_signing)) {
- DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
- return False;
+ cli->sign_info.mandatory_signing = True;
}
} else if (cli->protocol >= PROTOCOL_LANMAN1) {
@@ -1248,6 +1223,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
const char *service, const char *service_type,
const char *user, const char *domain,
const char *password, int flags,
+ int signing_state,
BOOL *retry)
{
struct ntuser_creds creds;
@@ -1310,6 +1286,8 @@ again:
return NT_STATUS_UNSUCCESSFUL;
}
+ cli_setup_signing_state(cli, signing_state);
+
if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
cli->use_spnego = False;
else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
@@ -1480,7 +1458,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC",
user_info->username, lp_workgroup(), user_info->password,
- CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, NULL);
+ CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, Undefined, NULL);
if (NT_STATUS_IS_OK(nt_status)) {
return cli;
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index cd9edb1cc93..5838f301c49 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -157,6 +157,10 @@ BOOL cli_send_smb(struct cli_state *cli)
}
nwritten += ret;
}
+ /* Increment the mid so we can tell between responses. */
+ cli->mid++;
+ if (!cli->mid)
+ cli->mid++;
return True;
}
@@ -209,6 +213,27 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr)
}
/****************************************************************************
+ Set the signing state (used from the command line).
+****************************************************************************/
+
+void cli_setup_signing_state(struct cli_state *cli, int signing_state)
+{
+ if (signing_state == Undefined)
+ return;
+
+ if (signing_state == False) {
+ cli->sign_info.allow_smb_signing = False;
+ cli->sign_info.mandatory_signing = False;
+ return;
+ }
+
+ cli->sign_info.allow_smb_signing = True;
+
+ if (signing_state == Required)
+ cli->sign_info.mandatory_signing = True;
+}
+
+/****************************************************************************
Initialise a client structure.
****************************************************************************/
@@ -314,7 +339,9 @@ void cli_nt_session_close(struct cli_state *cli)
ntlmssp_client_end(&cli->ntlmssp_pipe_state);
}
- cli_close(cli, cli->nt_pipe_fnum);
+ if (cli->nt_pipe_fnum != 0)
+ cli_close(cli, cli->nt_pipe_fnum);
+
cli->nt_pipe_fnum = 0;
cli->pipe_idx = -1;
}
@@ -337,6 +364,9 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli)
void cli_close_connection(struct cli_state *cli)
{
+ if ( !cli )
+ return;
+
cli_nt_session_close(cli);
cli_nt_netlogon_netsec_session_close(cli);
diff --git a/source/libsmb/clierror.c b/source/libsmb/clierror.c
index 656671823c4..c27e1955e20 100644
--- a/source/libsmb/clierror.c
+++ b/source/libsmb/clierror.c
@@ -371,6 +371,9 @@ BOOL cli_is_error(struct cli_state *cli)
{
uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0;
+ if (cli->fd == -1 && cli->smb_rw_error != 0)
+ return True;
+
if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
/* Return error is error bits are set */
rcls = IVAL(cli->inbuf, smb_rcls);
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
index ba8ba11368a..1fccc04a013 100644
--- a/source/libsmb/clikrb5.c
+++ b/source/libsmb/clikrb5.c
@@ -74,7 +74,7 @@
{
pkaddr->addrtype = ADDRTYPE_INET;
pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr);
- pkaddr->contents = (char *)&(((struct sockaddr_in *)paddr)->sin_addr);
+ pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr);
}
#else
__ERROR__XX__UNKNOWN_ADDRTYPE
@@ -97,7 +97,9 @@
return ret;
}
krb5_use_enctype(context, &eblock, enctype);
- return krb5_string_to_key(context, &eblock, key, password, &salt);
+ ret = krb5_string_to_key(context, &eblock, key, password, &salt);
+ SAFE_FREE(salt.data);
+ return ret;
}
#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT)
int create_kerberos_key_from_string(krb5_context context,
@@ -305,7 +307,7 @@ cleanup_princ:
/*
get a kerberos5 ticket for the given service
*/
-DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset)
+DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16])
{
krb5_error_code retval;
krb5_data packet;
@@ -345,13 +347,15 @@ DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset)
}
if ((retval = ads_krb5_mk_req(context,
- &auth_context,
- 0,
- principal,
- ccdef, &packet))) {
+ &auth_context,
+ AP_OPTS_USE_SUBKEY,
+ principal,
+ ccdef, &packet))) {
goto failed;
}
+ get_krb5_smb_session_key(context, auth_context, session_key_krb5, False);
+
ret = data_blob(packet.data, packet.length);
/* Hmm, heimdal dooesn't have this - what's the correct call? */
/* krb5_free_data_contents(context, &packet); */
@@ -365,26 +369,29 @@ failed:
return data_blob(NULL, 0);
}
- BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16])
+ BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote)
{
-#ifdef ENCTYPE_ARCFOUR_HMAC
krb5_keyblock *skey;
-#endif
+ krb5_error_code err;
BOOL ret = False;
memset(session_key, 0, 16);
-#ifdef ENCTYPE_ARCFOUR_HMAC
- if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) {
- if (KRB5_KEY_TYPE(skey) ==
- ENCTYPE_ARCFOUR_HMAC
- && KRB5_KEY_LENGTH(skey) == 16) {
+ if (remote)
+ err = krb5_auth_con_getremotesubkey(context, auth_context, &skey);
+ else
+ err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey);
+ if (err == 0 && skey != NULL) {
+ DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey)));
+ if (KRB5_KEY_LENGTH(skey) == 16) {
memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey));
+ dump_data_pw("KRB5 Session Key:\n", session_key, 16);
ret = True;
}
krb5_free_keyblock(context, skey);
+ } else {
+ DEBUG(10, ("KRB5 error getting session key %d\n", err));
}
-#endif /* ENCTYPE_ARCFOUR_HMAC */
return ret;
}
@@ -403,7 +410,7 @@ failed:
#else /* HAVE_KRB5 */
/* this saves a few linking headaches */
-DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset)
+DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16])
{
DEBUG(0,("NO KERBEROS SUPPORT\n"));
return data_blob(NULL, 0);
diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c
index 5bd1283ab7b..7822987ada8 100644
--- a/source/libsmb/clilist.c
+++ b/source/libsmb/clilist.c
@@ -101,13 +101,20 @@ static int interpret_long_filename(struct cli_state *cli,
cheap to calculate, I suppose, as
no DST tables will be needed */
- finfo->ctime = interpret_long_date(p); p += 8;
- finfo->atime = interpret_long_date(p); p += 8;
- finfo->mtime = interpret_long_date(p); p += 8; p += 8;
- finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8;
+ finfo->ctime = interpret_long_date(p);
+ p += 8;
+ finfo->atime = interpret_long_date(p);
+ p += 8;
+ finfo->mtime = interpret_long_date(p);
+ p += 8;
+ p += 8;
+ finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0);
+ p += 8;
p += 8; /* alloc size */
- finfo->mode = CVAL(p,0); p += 4;
- namelen = IVAL(p,0); p += 4;
+ finfo->mode = CVAL(p,0);
+ p += 4;
+ namelen = IVAL(p,0);
+ p += 4;
p += 4; /* EA size */
slen = SVAL(p, 0);
p += 2;
@@ -138,7 +145,11 @@ static int interpret_long_filename(struct cli_state *cli,
int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
void (*fn)(file_info *, const char *, void *), void *state)
{
+#if 0
+ int max_matches = 1366; /* Match W2k - was 512. */
+#else
int max_matches = 512;
+#endif
int info_level;
char *p, *p2;
pstring mask;
@@ -200,7 +211,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
&setup, 1, 0, /* setup, length, max */
param, param_len, 10, /* param, length, max */
NULL, 0,
- cli->max_xmit /* data, length, max */
+#if 0
+ /* w2k value. */
+ MIN(16384,cli->max_xmit) /* data, length, max. */
+#else
+ cli->max_xmit /* data, length, max. */
+#endif
)) {
break;
}
@@ -214,7 +230,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
uint8 eclass;
uint32 ecode;
cli_dos_error(cli, &eclass, &ecode);
- if (eclass != ERRSRV || ecode != ERRerror) break;
+ if (eclass != ERRSRV || ecode != ERRerror)
+ break;
msleep(100);
continue;
}
@@ -222,7 +239,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
if (cli_is_error(cli) || !rdata || !rparam)
break;
- if (total_received == -1) total_received = 0;
+ if (total_received == -1)
+ total_received = 0;
/* parse out some important return info */
p = rparam;
@@ -245,8 +263,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
/* we might need the lastname for continuations */
if (ff_lastname > 0) {
- switch(info_level)
- {
+ switch(info_level) {
case 260:
clistr_pull(cli, mask, p+ff_lastname,
sizeof(mask),
@@ -270,8 +287,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
if (!tdl) {
DEBUG(0,("cli_list_new: Failed to expand dirlist\n"));
break;
+ } else {
+ dirlist = tdl;
}
- else dirlist = tdl;
/* put in a length for the last entry, to ensure we can chain entries
into the next packet */
@@ -291,7 +309,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
DEBUG(3,("received %d entries (eos=%d)\n",
ff_searchcount,ff_eos));
- if (ff_searchcount > 0) loop_count = 0;
+ if (ff_searchcount > 0)
+ loop_count = 0;
First = False;
}
diff --git a/source/libsmb/cliprint.c b/source/libsmb/cliprint.c
index bfa33bc5146..2fb0e59acac 100644
--- a/source/libsmb/cliprint.c
+++ b/source/libsmb/cliprint.c
@@ -55,7 +55,7 @@ int cli_print_queue(struct cli_state *cli,
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt, rprcnt;
+ unsigned int rdrcnt, rprcnt;
pstring param;
int result_code=0;
int i = -1;
@@ -65,16 +65,16 @@ int cli_print_queue(struct cli_state *cli,
p = param;
SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */
p += 2;
- pstrcpy(p,"zWrLeh"); /* parameter description? */
+ pstrcpy_base(p,"zWrLeh", param); /* parameter description? */
p = skip_string(p,1);
- pstrcpy(p,"WWzWWDDzz"); /* returned data format */
+ pstrcpy_base(p,"WWzWWDDzz", param); /* returned data format */
p = skip_string(p,1);
- pstrcpy(p,cli->share); /* name of queue */
+ pstrcpy_base(p,cli->share, param); /* name of queue */
p = skip_string(p,1);
SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */
SSVAL(p,2,1000); /* size of bytes of returned data buffer */
p += 4;
- pstrcpy(p,""); /* subformat */
+ pstrcpy_base(p,"", param); /* subformat */
p = skip_string(p,1);
DEBUG(4,("doing cli_print_queue for %s\n", cli->share));
@@ -125,7 +125,8 @@ int cli_printjob_del(struct cli_state *cli, int job)
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt, ret = -1;
+ unsigned int rdrcnt,rprcnt;
+ int ret = -1;
pstring param;
memset(param,'\0',sizeof(param));
@@ -133,9 +134,9 @@ int cli_printjob_del(struct cli_state *cli, int job)
p = param;
SSVAL(p,0,81); /* DosPrintJobDel() */
p += 2;
- pstrcpy(p,"W");
+ pstrcpy_base(p,"W", param);
p = skip_string(p,1);
- pstrcpy(p,"");
+ pstrcpy_base(p,"", param);
p = skip_string(p,1);
SSVAL(p,0,job);
p += 2;
diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c
index a307ac6ccf8..79ad38fc8c3 100644
--- a/source/libsmb/clirap.c
+++ b/source/libsmb/clirap.c
@@ -76,7 +76,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
pstring param;
memset(param, 0, sizeof(param));
@@ -137,7 +137,7 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
pstring param;
int count = -1;
@@ -211,7 +211,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
{
char *rparam = NULL;
char *rdata = NULL;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
char *p;
pstring param;
int uLevel = 1;
@@ -256,7 +256,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
const char *cmnt = comment_offset?(rdata+comment_offset):"";
pstring s1, s2;
- if (comment_offset < 0 || comment_offset > rdrcnt) continue;
+ if (comment_offset < 0 || comment_offset > (int)rdrcnt) continue;
stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
@@ -290,7 +290,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
unsigned int param_len = 0;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
pstring dos_new_password;
if (strlen(user) >= sizeof(fstring)-1) {
diff --git a/source/libsmb/clirap2.c b/source/libsmb/clirap2.c
index 669b33860da..12a3d63aff3 100644
--- a/source/libsmb/clirap2.c
+++ b/source/libsmb/clirap2.c
@@ -153,7 +153,8 @@ int cli_NetGroupDelete(struct cli_state *cli, const char *group_name )
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt, res;
+ unsigned int rdrcnt,rprcnt;
+ int res;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetGroupDel_REQ) /* parm string */
+1 /* no ret string */
@@ -204,7 +205,8 @@ int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo )
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt,res;
+ unsigned int rdrcnt,rprcnt;
+ int res;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetGroupAdd_REQ) /* req string */
+sizeof(RAP_GROUP_INFO_L1) /* return string */
@@ -272,7 +274,7 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char
char *p;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
int res = -1;
@@ -332,7 +334,8 @@ int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const ch
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt,res;
+ unsigned int rdrcnt,rprcnt;
+ int res;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetGroupDelUser_REQ) /* parm string */
+1 /* no ret string */
@@ -390,7 +393,8 @@ int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const ch
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt,res;
+ unsigned int rdrcnt,rprcnt;
+ int res;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetGroupAddUser_REQ) /* parm string */
+1 /* no ret string */
@@ -446,7 +450,7 @@ int cli_NetGroupGetUsers(struct cli_state * cli, const char *group_name, void (*
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
int res = -1;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetGroupGetUsers_REQ)/* parm string */
@@ -501,7 +505,7 @@ int cli_NetUserGetGroups(struct cli_state * cli, const char *user_name, void (*f
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
int res = -1;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetUserGetGroups_REQ)/* parm string */
@@ -560,7 +564,8 @@ int cli_NetUserDelete(struct cli_state *cli, const char * user_name )
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt, res;
+ unsigned int rdrcnt,rprcnt;
+ int res;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetGroupDel_REQ) /* parm string */
+1 /* no ret string */
@@ -614,7 +619,8 @@ int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo )
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt,res;
+ unsigned int rdrcnt,rprcnt;
+ int res;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetUserAdd2_REQ) /* req string */
+sizeof(RAP_USER_INFO_L1) /* data string */
@@ -702,7 +708,7 @@ int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char
char *p;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
int res = -1;
@@ -770,7 +776,7 @@ int cli_NetFileClose(struct cli_state *cli, uint32 file_id )
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
char param[WORDSIZE /* api number */
+sizeof(RAP_WFileClose2_REQ) /* req string */
+1 /* no ret string */
@@ -816,7 +822,8 @@ int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const c
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt, res;
+ unsigned int rdrcnt,rprcnt;
+ int res;
char param[WORDSIZE /* api number */
+sizeof(RAP_WFileGetInfo2_REQ) /* req string */
+sizeof(RAP_FILE_INFO_L3) /* return string */
@@ -893,7 +900,7 @@ int cli_NetFileEnum(struct cli_state *cli, char * user, char * base_path, void (
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
char param[WORDSIZE /* api number */
+sizeof(RAP_WFileEnum2_REQ) /* req string */
+sizeof(RAP_FILE_INFO_L3) /* return string */
@@ -965,7 +972,8 @@ int cli_NetShareAdd(struct cli_state *cli, RAP_SHARE_INFO_2 * sinfo )
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt,res;
+ unsigned int rdrcnt,rprcnt;
+ int res;
char param[WORDSIZE /* api number */
+sizeof(RAP_WShareAdd_REQ) /* req string */
+sizeof(RAP_SHARE_INFO_L2) /* return string */
@@ -1035,7 +1043,8 @@ int cli_NetShareDelete(struct cli_state *cli, const char * share_name )
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt, res;
+ unsigned int rdrcnt,rprcnt;
+ int res;
char param[WORDSIZE /* api number */
+sizeof(RAP_WShareDel_REQ) /* req string */
+1 /* no ret string */
@@ -1097,7 +1106,7 @@ BOOL cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name)
{
char *rparam = NULL;
char *rdata = NULL;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
char *p;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetServerEnum2_REQ) /* req string */
@@ -1177,7 +1186,7 @@ BOOL cli_get_server_domain(struct cli_state *cli)
{
char *rparam = NULL;
char *rdata = NULL;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
char *p;
char param[WORDSIZE /* api number */
+sizeof(RAP_WWkstaGetInfo_REQ) /* req string */
@@ -1242,7 +1251,7 @@ BOOL cli_get_server_type(struct cli_state *cli, uint32 *pstype)
{
char *rparam = NULL;
char *rdata = NULL;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
char *p;
char param[WORDSIZE /* api number */
+sizeof(RAP_WserverGetInfo_REQ) /* req string */
@@ -1309,7 +1318,7 @@ BOOL cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 sty
{
char *rparam = NULL;
char *rdata = NULL;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
char *p;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetServerEnum2_REQ) /* req string */
@@ -1378,7 +1387,7 @@ BOOL cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation)
char *rparam = NULL;
char *rdata = NULL;
char *p;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
char param[WORDSIZE /* api number */
+sizeof(RAP_NetWkstaUserLogoff_REQ) /* req string */
+sizeof(RAP_USER_LOGOFF_INFO_L1) /* return string */
@@ -1436,7 +1445,7 @@ int cli_NetPrintQEnum(struct cli_state *cli,
char *p;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
int res = -1;
@@ -1540,7 +1549,7 @@ int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer,
char *p;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
int res = -1;
@@ -1639,7 +1648,7 @@ int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const ch
char *p;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
int res = -1;
@@ -1708,7 +1717,7 @@ int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16,
char *p;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
int res = -1;
memset(param, '\0', sizeof(param));
@@ -1784,7 +1793,7 @@ int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void (
char *p;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
int res = -1;
@@ -1858,7 +1867,7 @@ int cli_NetSessionDel(struct cli_state *cli, const char *workstation)
char *p;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
int res;
memset(param, '\0', sizeof(param));
@@ -1903,7 +1912,7 @@ int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, void (*f
char *p;
char *rparam = NULL;
char *rdata = NULL;
- int rprcnt, rdrcnt;
+ unsigned int rprcnt, rdrcnt;
int res = -1;
memset(param, '\0', sizeof(param));
diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c
index 0715aa7f1a5..8eac7d07d8b 100644
--- a/source/libsmb/clireadwrite.c
+++ b/source/libsmb/clireadwrite.c
@@ -326,7 +326,7 @@ ssize_t cli_write(struct cli_state *cli,
int issued = 0;
int received = 0;
int mpx = MAX(cli->max_mux-1, 1);
- int block = (cli->max_xmit - (smb_size+32)) & ~1023;
+ int block = cli->max_xmit - (smb_size+32);
int blocks = (size + (block-1)) / block;
while (received < blocks) {
diff --git a/source/libsmb/clisecdesc.c b/source/libsmb/clisecdesc.c
index d86a9022a69..548cd6ec187 100644
--- a/source/libsmb/clisecdesc.c
+++ b/source/libsmb/clisecdesc.c
@@ -28,7 +28,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
{
char param[8];
char *rparam=NULL, *rdata=NULL;
- int rparam_count=0, rdata_count=0;
+ unsigned int rparam_count=0, rdata_count=0;
prs_struct pd;
SEC_DESC *psd = NULL;
@@ -78,7 +78,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd)
{
char param[8];
char *rparam=NULL, *rdata=NULL;
- int rparam_count=0, rdata_count=0;
+ unsigned int rparam_count=0, rdata_count=0;
uint32 sec_info = 0;
TALLOC_CTX *mem_ctx;
prs_struct pd;
diff --git a/source/libsmb/clispnego.c b/source/libsmb/clispnego.c
index bb48f579151..63076a1a1ce 100644
--- a/source/libsmb/clispnego.c
+++ b/source/libsmb/clispnego.c
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
simple kerberos5/SPNEGO routines
Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jim McDonough 2002
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
Copyright (C) Luke Howard 2003
This program is free software; you can redistribute it and/or modify
@@ -323,13 +323,16 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY
kerberos session setup
*/
-DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset)
+DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsigned char session_key_krb5[16])
{
DATA_BLOB tkt, tkt_wrapped, targ;
const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL};
- /* get a kerberos ticket for the service */
- tkt = cli_krb5_get_ticket(principal, time_offset);
+ /* get a kerberos ticket for the service and extract the session key */
+ tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5);
+
+ if (tkt.data == NULL)
+ return tkt;
/* wrap that up in a nice GSS-API wrapping */
tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ);
diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c
index 3d3cd427d76..e6771ac6885 100644
--- a/source/libsmb/clitrans.c
+++ b/source/libsmb/clitrans.c
@@ -40,6 +40,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
char *outdata,*outparam;
char *p;
int pipe_name_len=0;
+ uint16 mid;
this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));
@@ -49,6 +50,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
SCVAL(cli->outbuf,smb_com,trans);
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
+ mid = cli->mid;
if (pipe_name) {
pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE);
@@ -84,13 +86,19 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
cli_setup_bcc(cli, outdata+this_ldata);
show_msg(cli->outbuf);
- if (!cli_send_smb(cli))
+
+ cli_signing_trans_start(cli);
+ if (!cli_send_smb(cli)) {
+ cli_signing_trans_stop(cli);
return False;
+ }
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
- if (!cli_receive_smb(cli) || cli_is_error(cli))
+ if (!cli_receive_smb(cli) || cli_is_error(cli)) {
+ cli_signing_trans_stop(cli);
return(False);
+ }
tot_data = this_ldata;
tot_param = this_lparam;
@@ -122,9 +130,15 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
memcpy(outdata,data+tot_data,this_ldata);
cli_setup_bcc(cli, outdata+this_ldata);
+ /* Ensure this packet has the same MID as
+ * the primary. Important in signing. JRA. */
+ cli->mid = mid;
+
show_msg(cli->outbuf);
- if (!cli_send_smb(cli))
+ if (!cli_send_smb(cli)) {
+ cli_signing_trans_stop(cli);
return False;
+ }
tot_data += this_ldata;
tot_param += this_lparam;
@@ -151,8 +165,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
*data_len = *param_len = 0;
- if (!cli_receive_smb(cli))
+ if (!cli_receive_smb(cli)) {
+ cli_signing_trans_stop(cli);
return False;
+ }
show_msg(cli->inbuf);
@@ -161,6 +177,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
DEBUG(0,("Expected %s response, got command 0x%02x\n",
trans==SMBtrans?"SMBtrans":"SMBtrans2",
CVAL(cli->inbuf,smb_com)));
+ cli_signing_trans_stop(cli);
return(False);
}
@@ -171,8 +188,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
*/
status = cli_nt_error(cli);
- if (NT_STATUS_IS_ERR(status))
+ if (NT_STATUS_IS_ERR(status)) {
+ cli_signing_trans_stop(cli);
return False;
+ }
/* parse out the lengths */
total_data = SVAL(cli->inbuf,smb_tdrcnt);
@@ -183,6 +202,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
tdata = Realloc(*data,total_data);
if (!tdata) {
DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n"));
+ cli_signing_trans_stop(cli);
return False;
}
else
@@ -193,6 +213,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
tparam = Realloc(*param,total_param);
if (!tparam) {
DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n"));
+ cli_signing_trans_stop(cli);
return False;
}
else
@@ -206,6 +227,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
if (this_data + *data_len > total_data ||
this_param + *param_len > total_param) {
DEBUG(1,("Data overflow in cli_receive_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
@@ -214,6 +236,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
this_param + *param_len < this_param ||
this_param + *param_len < *param_len) {
DEBUG(1,("Data overflow in cli_receive_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
@@ -226,6 +249,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
data_offset_out + this_data < data_offset_out ||
data_offset_out + this_data < this_data) {
DEBUG(1,("Data overflow in cli_receive_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
if (data_offset_in > cli->bufsize ||
@@ -233,6 +257,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
data_offset_in + this_data < data_offset_in ||
data_offset_in + this_data < this_data) {
DEBUG(1,("Data overflow in cli_receive_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
@@ -247,6 +272,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
param_offset_out + this_param < param_offset_out ||
param_offset_out + this_param < this_param) {
DEBUG(1,("Param overflow in cli_receive_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
if (param_offset_in > cli->bufsize ||
@@ -254,6 +280,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
param_offset_in + this_param < param_offset_in ||
param_offset_in + this_param < this_param) {
DEBUG(1,("Param overflow in cli_receive_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
@@ -265,8 +292,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
if (total_data <= *data_len && total_param <= *param_len)
break;
- if (!cli_receive_smb(cli))
- return False;
+ if (!cli_receive_smb(cli)) {
+ cli_signing_trans_stop(cli);
+ return False;
+ }
show_msg(cli->inbuf);
@@ -275,9 +304,11 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
DEBUG(0,("Expected %s response, got command 0x%02x\n",
trans==SMBtrans?"SMBtrans":"SMBtrans2",
CVAL(cli->inbuf,smb_com)));
+ cli_signing_trans_stop(cli);
return(False);
}
if (NT_STATUS_IS_ERR(cli_nt_error(cli))) {
+ cli_signing_trans_stop(cli);
return(False);
}
@@ -292,6 +323,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
}
+ cli_signing_trans_stop(cli);
return(True);
}
@@ -309,6 +341,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
unsigned int i;
unsigned int this_ldata,this_lparam;
unsigned int tot_data=0,tot_param=0;
+ uint16 mid;
char *outdata,*outparam;
this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
@@ -319,6 +352,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
SCVAL(cli->outbuf,smb_com,SMBnttrans);
SSVAL(cli->outbuf,smb_tid, cli->cnum);
cli_setup_packet(cli);
+ mid = cli->mid;
outparam = smb_buf(cli->outbuf)+3;
outdata = outparam+this_lparam;
@@ -347,13 +381,18 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
cli_setup_bcc(cli, outdata+this_ldata);
show_msg(cli->outbuf);
- if (!cli_send_smb(cli))
+ cli_signing_trans_start(cli);
+ if (!cli_send_smb(cli)) {
+ cli_signing_trans_stop(cli);
return False;
+ }
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
- if (!cli_receive_smb(cli) || cli_is_error(cli))
+ if (!cli_receive_smb(cli) || cli_is_error(cli)) {
+ cli_signing_trans_stop(cli);
return(False);
+ }
tot_data = this_ldata;
tot_param = this_lparam;
@@ -384,9 +423,16 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
memcpy(outdata,data+tot_data,this_ldata);
cli_setup_bcc(cli, outdata+this_ldata);
+ /* Ensure this packet has the same MID as
+ * the primary. Important in signing. JRA. */
+ cli->mid = mid;
+
show_msg(cli->outbuf);
- if (!cli_send_smb(cli))
+
+ if (!cli_send_smb(cli)) {
+ cli_signing_trans_stop(cli);
return False;
+ }
tot_data += this_ldata;
tot_param += this_lparam;
@@ -396,8 +442,6 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
return(True);
}
-
-
/****************************************************************************
receive a SMB nttrans response allocating the necessary memory
****************************************************************************/
@@ -416,8 +460,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
*data_len = *param_len = 0;
- if (!cli_receive_smb(cli))
+ if (!cli_receive_smb(cli)) {
+ cli_signing_trans_stop(cli);
return False;
+ }
show_msg(cli->inbuf);
@@ -425,6 +471,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
if (CVAL(cli->inbuf,smb_com) != SMBnttrans) {
DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n",
CVAL(cli->inbuf,smb_com)));
+ cli_signing_trans_stop(cli);
return(False);
}
@@ -435,8 +482,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
*/
if (cli_is_dos_error(cli)) {
cli_dos_error(cli, &eclass, &ecode);
- if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
+ if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
+ cli_signing_trans_stop(cli);
return(False);
+ }
}
/* parse out the lengths */
@@ -448,6 +497,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
tdata = Realloc(*data,total_data);
if (!tdata) {
DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data));
+ cli_signing_trans_stop(cli);
return False;
} else {
*data = tdata;
@@ -458,6 +508,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
tparam = Realloc(*param,total_param);
if (!tparam) {
DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param));
+ cli_signing_trans_stop(cli);
return False;
} else {
*param = tparam;
@@ -471,6 +522,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
if (this_data + *data_len > total_data ||
this_param + *param_len > total_param) {
DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
@@ -479,6 +531,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
this_param + *param_len < this_param ||
this_param + *param_len < *param_len) {
DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
@@ -491,6 +544,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
data_offset_out + this_data < data_offset_out ||
data_offset_out + this_data < this_data) {
DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
if (data_offset_in > cli->bufsize ||
@@ -498,6 +552,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
data_offset_in + this_data < data_offset_in ||
data_offset_in + this_data < this_data) {
DEBUG(1,("Data overflow in cli_receive_nt_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
@@ -513,6 +568,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
param_offset_out + this_param < param_offset_out ||
param_offset_out + this_param < this_param) {
DEBUG(1,("Param overflow in cli_receive_nt_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
if (param_offset_in > cli->bufsize ||
@@ -520,6 +576,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
param_offset_in + this_param < param_offset_in ||
param_offset_in + this_param < this_param) {
DEBUG(1,("Param overflow in cli_receive_nt_trans\n"));
+ cli_signing_trans_stop(cli);
return False;
}
@@ -532,8 +589,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
if (total_data <= *data_len && total_param <= *param_len)
break;
- if (!cli_receive_smb(cli))
+ if (!cli_receive_smb(cli)) {
+ cli_signing_trans_stop(cli);
return False;
+ }
show_msg(cli->inbuf);
@@ -541,13 +600,15 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
if (CVAL(cli->inbuf,smb_com) != SMBnttrans) {
DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n",
CVAL(cli->inbuf,smb_com)));
+ cli_signing_trans_stop(cli);
return(False);
}
if (cli_is_dos_error(cli)) {
cli_dos_error(cli, &eclass, &ecode);
- if(cli->nt_pipe_fnum == 0 ||
- !(eclass == ERRDOS && ecode == ERRmoredata))
+ if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
+ cli_signing_trans_stop(cli);
return(False);
+ }
}
/* parse out the total lengths again - they can shrink! */
if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data)
@@ -559,5 +620,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
break;
}
+ cli_signing_trans_stop(cli);
return(True);
}
diff --git a/source/libsmb/errormap.c b/source/libsmb/errormap.c
index 8ee5ee3d31e..3d99e3d5e52 100644
--- a/source/libsmb/errormap.c
+++ b/source/libsmb/errormap.c
@@ -1498,6 +1498,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = {
{ ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
{ EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES },
{ ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL },
+ { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY },
#ifdef EDQUOT
{ EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL },
#endif
diff --git a/source/libsmb/namequery_dc.c b/source/libsmb/namequery_dc.c
index c9d45a7acc1..a596f00ddb9 100644
--- a/source/libsmb/namequery_dc.c
+++ b/source/libsmb/namequery_dc.c
@@ -161,18 +161,28 @@ BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
{
struct in_addr dc_ip;
BOOL ret;
+ BOOL our_domain = False;
zero_ip(&dc_ip);
ret = False;
- if (lp_security() == SEC_ADS)
+
+ if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), domain) )
+ our_domain = True;
+
+ /* always try to obey what the admin specified in smb.conf.
+ If it is not our domain, assume that domain names with periods
+ in them are realm names */
+
+ if ( (our_domain && lp_security()==SEC_ADS) || strchr_m(domain, '.') ) {
ret = ads_dc_name(domain, &dc_ip, srv_name);
-
+ }
+
if (!ret) {
/* fall back on rpc methods if the ADS methods fail */
ret = rpc_dc_name(domain, srv_name, &dc_ip);
}
-
+
*ip_out = dc_ip;
return ret;
diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c
index 157a2bb43cb..6ee05f01045 100644
--- a/source/libsmb/nmblib.c
+++ b/source/libsmb/nmblib.c
@@ -1129,12 +1129,14 @@ char *dns_to_netbios_name(char *dns_name)
/****************************************************************************
-interpret the weird netbios "name". Return the name type
+interpret the weird netbios "name" into a unix fstring. Return the name type
****************************************************************************/
-static int name_interpret(char *in,char *out)
+static int name_interpret(char *in, fstring name)
{
int ret;
int len = (*in++) / 2;
+ fstring out_string;
+ char *out = out_string;
*out=0;
@@ -1150,8 +1152,8 @@ static int name_interpret(char *in,char *out)
in += 2;
out++;
}
- *out = 0;
ret = out[-1];
+ out[-1] = 0;
#ifdef NETBIOS_SCOPE
/* Handle any scope names */
@@ -1165,6 +1167,8 @@ static int name_interpret(char *in,char *out)
in += len;
}
#endif
+ pull_ascii(name, out_string, sizeof(fstring), sizeof(out_string), STR_TERMINATE);
+
return(ret);
}
@@ -1245,9 +1249,9 @@ static char *name_ptr(char *buf,int ofs)
}
/****************************************************************************
-extract a netbios name from a buf
+extract a netbios name from a buf (into a unix string) return name type
****************************************************************************/
-int name_extract(char *buf,int ofs,char *name)
+int name_extract(char *buf,int ofs, fstring name)
{
char *p = name_ptr(buf,ofs);
int d = PTR_DIFF(p,buf+ofs);
diff --git a/source/libsmb/ntlmssp.c b/source/libsmb/ntlmssp.c
index 66dc6e08eb8..e4d4acd29b0 100644
--- a/source/libsmb/ntlmssp.c
+++ b/source/libsmb/ntlmssp.c
@@ -23,6 +23,12 @@
#include "includes.h"
+#if 0
+/* we currently do not know how to get the right session key for this, so
+ we cannot enable it by default... :-( */
+#define USE_NTLM2 1
+#endif
+
/**
* Print out the NTLMSSP flags for debugging
* @param neg_flags The flags from the packet
@@ -140,7 +146,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
&cliname,
&domname)) {
DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
- dump_data(2, request.data, request.length);
+ dump_data(2, (const char *)request.data, request.length);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -172,6 +178,9 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
target_name = ntlmssp_target_name(ntlmssp_state,
neg_flags, &chal_flags);
+ if (target_name == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
+
/* This should be a 'netbios domain -> DNS domain' mapping */
dnsdomname[0] = '\0';
get_mydomname(dnsdomname);
@@ -273,14 +282,14 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
&sess_key,
&neg_flags)) {
DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
- dump_data(2, request.data, request.length);
+ dump_data(2, (const char *)request.data, request.length);
return NT_STATUS_INVALID_PARAMETER;
}
data_blob_free(&sess_key);
- DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%d len2=%d\n",
- ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, ntlmssp_state->lm_resp.length, ntlmssp_state->nt_resp.length));
+ DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
+ ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
#if 0
file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
@@ -412,6 +421,10 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat
if (ntlmssp_state->use_ntlmv2) {
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
}
+
+#ifdef USE_NTLM2
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+#endif
/* generate the ntlmssp negotiate packet */
msrpc_gen(next_request, "CddAA",
@@ -463,7 +476,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
&server_domain_blob,
&chal_flags)) {
DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
- dump_data(2, reply.data, reply.length);
+ dump_data(2, (const char *)reply.data, reply.length);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -525,17 +538,22 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
&unkn1, &unkn2,
&struct_blob)) {
DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
- dump_data(2, reply.data, reply.length);
+ dump_data(2, (const char *)reply.data, reply.length);
return NT_STATUS_INVALID_PARAMETER;
}
+ ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx,
+ server_domain);
+
SAFE_FREE(server_domain);
if (challenge_blob.length != 8) {
data_blob_free(&struct_blob);
return NT_STATUS_INVALID_PARAMETER;
}
- if (ntlmssp_state->use_ntlmv2) {
+ if (!ntlmssp_state->password) {
+ /* do nothing - blobs are zero length */
+ } else if (ntlmssp_state->use_ntlmv2) {
if (!struct_blob.length) {
/* be lazy, match win2k - we can't do NTLMv2 without it */
@@ -554,7 +572,34 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
data_blob_free(&struct_blob);
return NT_STATUS_NO_MEMORY;
}
+#ifdef USE_NTLM2
+ } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
+ struct MD5Context md5_session_nonce_ctx;
+ uchar nt_hash[16];
+ uchar session_nonce[16];
+ E_md4hash(ntlmssp_state->password, nt_hash);
+
+ generate_random_buffer(lm_response.data, 8, False);
+ memset(lm_response.data+8, 0, 16);
+
+ MD5Init(&md5_session_nonce_ctx);
+ MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
+ MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
+ MD5Final(session_nonce, &md5_session_nonce_ctx);
+
+ nt_response = data_blob(NULL, 24);
+ SMBNTencrypt(ntlmssp_state->password,
+ challenge_blob.data,
+ nt_response.data);
+
+ /* This is *NOT* the correct session key algorithm - just
+ fill in the bytes with something... */
+ session_key = data_blob(NULL, 16);
+ SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+#endif
} else {
+
+
uchar lm_hash[16];
uchar nt_hash[16];
E_deshash(ntlmssp_state->password, lm_hash);
@@ -565,15 +610,15 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st
lm_response = data_blob(NULL, 24);
SMBencrypt(ntlmssp_state->password,challenge_blob.data,
lm_response.data);
- }
+ }
nt_response = data_blob(NULL, 24);
SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
nt_response.data);
-
+
session_key = data_blob(NULL, 16);
if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
- && lp_client_lanman_auth()) {
+ && lp_client_lanman_auth()) {
SMBsesskeygen_lmv1(lm_hash, lm_response.data,
session_key.data);
} else {
@@ -706,9 +751,13 @@ NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *u
NTSTATUS ntlmssp_set_password(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *password)
{
- ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password);
- if (!ntlmssp_state->password) {
- return NT_STATUS_NO_MEMORY;
+ if (!password) {
+ ntlmssp_state->password = NULL;
+ } else {
+ ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password);
+ if (!ntlmssp_state->password) {
+ return NT_STATUS_NO_MEMORY;
+ }
}
return NT_STATUS_OK;
}
diff --git a/source/libsmb/ntlmssp_parse.c b/source/libsmb/ntlmssp_parse.c
index f53afcdcd01..60cb4ab04ae 100644
--- a/source/libsmb/ntlmssp_parse.c
+++ b/source/libsmb/ntlmssp_parse.c
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
simple kerberos5/SPNEGO routines
Copyright (C) Andrew Tridgell 2001
- Copyright (C) Jim McDonough 2002
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
Copyright (C) Andrew Bartlett 2002-2003
This program is free software; you can redistribute it and/or modify
@@ -153,7 +153,8 @@ BOOL msrpc_gen(DATA_BLOB *blob,
SSVAL(blob->data, head_ofs, n); head_ofs += 2;
SSVAL(blob->data, head_ofs, n); head_ofs += 2;
SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4;
- memcpy(blob->data+data_ofs, b, n);
+ if (n && b) /* don't follow null pointers... */
+ memcpy(blob->data+data_ofs, b, n);
data_ofs += n;
break;
case 'd':
diff --git a/source/libsmb/ntlmssp_sign.c b/source/libsmb/ntlmssp_sign.c
index ecaef808c9b..ff2f97c2e88 100644
--- a/source/libsmb/ntlmssp_sign.c
+++ b/source/libsmb/ntlmssp_sign.c
@@ -91,8 +91,8 @@ static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16],
MD5Init(&ctx3);
MD5Update(&ctx3, session_key.data, session_key.length);
- MD5Update(&ctx3, constant, strlen(constant));
- MD5Final(digest, &ctx3);
+ MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant));
+ MD5Final((unsigned char *)digest, &ctx3);
calc_hash(hash, digest, 16);
}
@@ -113,8 +113,8 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat
uchar digest[16];
SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
- hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx);
- hmac_md5_update(seq_num, 4, &ctx);
+ hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx);
+ hmac_md5_update((const unsigned char *)seq_num, 4, &ctx);
hmac_md5_update(data, length, &ctx);
hmac_md5_final(digest, &ctx);
@@ -132,7 +132,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat
}
} else {
uint32 crc;
- crc = crc32_calc_buffer(data, length);
+ crc = crc32_calc_buffer((const char *)data, length);
if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
return NT_STATUS_NO_MEMORY;
}
@@ -183,10 +183,10 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
if (memcmp(sig->data+sig->length - 8, local_sig.data+local_sig.length - 8, 8) != 0) {
DEBUG(5, ("BAD SIG: wanted signature of\n"));
- dump_data(5, local_sig.data, local_sig.length);
+ dump_data(5, (const char *)local_sig.data, local_sig.length);
DEBUG(5, ("BAD SIG: got signature of\n"));
- dump_data(5, sig->data, sig->length);
+ dump_data(5, (const char *)(sig->data), sig->length);
DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n"));
return NT_STATUS_ACCESS_DENIED;
@@ -216,8 +216,8 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
uchar digest[16];
SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num);
- hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx);
- hmac_md5_update(seq_num, 4, &ctx);
+ hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx);
+ hmac_md5_update((const unsigned char *)seq_num, 4, &ctx);
hmac_md5_update(data, length, &ctx);
hmac_md5_final(digest, &ctx);
@@ -236,7 +236,7 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data+4, sig->length-4);
} else {
uint32 crc;
- crc = crc32_calc_buffer(data, length);
+ crc = crc32_calc_buffer((const char *)data, length);
if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) {
return NT_STATUS_NO_MEMORY;
}
@@ -335,7 +335,7 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state)
DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n"));
- calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 8);
+ calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 8);
dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
sizeof(ntlmssp_state->ntlmssp_hash));
} else {
@@ -347,7 +347,7 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state)
DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n"));
- calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 16);
+ calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 16);
dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash,
sizeof(ntlmssp_state->ntlmssp_hash));
}
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
index df17362f083..08ff655a3f8 100644
--- a/source/libsmb/smb_signing.c
+++ b/source/libsmb/smb_signing.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
SMB Signing Code
- Copyright (C) Jeremy Allison 2002.
+ Copyright (C) Jeremy Allison 2003.
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
This program is free software; you can redistribute it and/or modify
@@ -25,17 +25,26 @@
struct outstanding_packet_lookup {
uint16 mid;
uint32 reply_seq_num;
+ BOOL deferred_packet;
struct outstanding_packet_lookup *prev, *next;
};
+/* Store the data for an ongoing trans/trans2/nttrans operation. */
+struct trans_info_context {
+ uint16 mid;
+ uint32 send_seq_num;
+ uint32 reply_seq_num;
+};
+
struct smb_basic_signing_context {
DATA_BLOB mac_key;
uint32 send_seq_num;
+ struct trans_info_context *trans_info;
struct outstanding_packet_lookup *outstanding_packet_list;
};
static void store_sequence_for_reply(struct outstanding_packet_lookup **list,
- uint16 mid, uint32 reply_seq_num)
+ uint16 mid, uint32 reply_seq_num, BOOL deferred_pkt)
{
struct outstanding_packet_lookup *t;
struct outstanding_packet_lookup *tmp;
@@ -46,22 +55,47 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list,
DLIST_ADD_END(*list, t, tmp);
t->mid = mid;
t->reply_seq_num = reply_seq_num;
+ t->deferred_packet = deferred_pkt;
+
+ DEBUG(10,("store_sequence_for_reply: stored %sseq = %u mid = %u\n",
+ deferred_pkt ? "deferred " : "",
+ (unsigned int)reply_seq_num, (unsigned int)mid ));
}
static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
- uint16 mid, uint32 *reply_seq_num)
+ uint16 mid, uint32 *reply_seq_num, BOOL *def)
{
struct outstanding_packet_lookup *t;
for (t = *list; t; t = t->next) {
if (t->mid == mid) {
*reply_seq_num = t->reply_seq_num;
+ if (def)
+ *def = t->deferred_packet;
+ DEBUG(10,("get_sequence_for_reply: found %sseq = %u mid = %u\n",
+ (t->deferred_packet) ? "deferred " : "",
+ (unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
DLIST_REMOVE(*list, t);
+ SAFE_FREE(t);
+ return True;
+ }
+ }
+ return False;
+}
+
+/***********************************************************
+ A reply is pending if there is a non-deferred packet on the queue.
+************************************************************/
+
+static BOOL is_reply_pending(struct outstanding_packet_lookup *list)
+{
+ for (; list; list = list->next) {
+ if (!list->deferred_packet) {
+ DEBUG(10,("is_reply_pending: True.\n"));
return True;
}
}
- DEBUG(0, ("Unexpected incoming packet, it's MID (%u) does not match"
- " a MID in our outstanding list!\n", mid));
+ DEBUG(10,("is_reply_pending: False.\n"));
return False;
}
@@ -81,7 +115,7 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli)
}
if (cli->sign_info.free_signing_context)
- cli->sign_info.free_signing_context(cli);
+ cli->sign_info.free_signing_context(&cli->sign_info);
/* These calls are INCOMPATIBLE with SMB signing */
cli->readbraw_supported = False;
@@ -94,42 +128,108 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli)
SMB signing - Common code for 'real' implementations
************************************************************/
-static BOOL cli_set_smb_signing_real_common(struct cli_state *cli)
+static BOOL set_smb_signing_real_common(struct smb_sign_info *si)
{
- if (cli->sign_info.mandatory_signing) {
+ if (si->mandatory_signing) {
DEBUG(5, ("Mandatory SMB signing enabled!\n"));
- cli->sign_info.doing_signing = True;
}
+ si->doing_signing = True;
DEBUG(5, ("SMB signing enabled!\n"));
return True;
}
-static void cli_mark_packet_signed(struct cli_state *cli)
+static void mark_packet_signed(char *outbuf)
{
uint16 flags2;
- flags2 = SVAL(cli->outbuf,smb_flg2);
+ flags2 = SVAL(outbuf,smb_flg2);
flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
- SSVAL(cli->outbuf,smb_flg2, flags2);
+ SSVAL(outbuf,smb_flg2, flags2);
}
-static BOOL cli_signing_good(struct cli_state *cli, BOOL good)
+/***********************************************************
+ SMB signing - NULL implementation - calculate a MAC to send.
+************************************************************/
+
+static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
{
- DEBUG(10, ("got SMB signature of\n"));
- dump_data(10,&cli->inbuf[smb_ss_field] , 8);
+ /* we can't zero out the sig, as we might be trying to send a
+ session request - which is NBT-level, not SMB level and doesn't
+ have the field */
+ return;
+}
- if (good && !cli->sign_info.doing_signing) {
- cli->sign_info.doing_signing = True;
+/***********************************************************
+ SMB signing - NULL implementation - check a MAC sent by server.
+************************************************************/
+
+static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si)
+{
+ return True;
+}
+
+/***********************************************************
+ SMB signing - NULL implementation - free signing context
+************************************************************/
+
+static void null_free_signing_context(struct smb_sign_info *si)
+{
+ return;
+}
+
+/**
+ SMB signing - NULL implementation - setup the MAC key.
+
+ @note Used as an initialisation only - it will not correctly
+ shut down a real signing mechanism
+*/
+
+static BOOL null_set_signing(struct smb_sign_info *si)
+{
+ si->signing_context = NULL;
+
+ si->sign_outgoing_message = null_sign_outgoing_message;
+ si->check_incoming_message = null_check_incoming_message;
+ si->free_signing_context = null_free_signing_context;
+
+ return True;
+}
+
+/**
+ * Free the signing context
+ */
+
+static void free_signing_context(struct smb_sign_info *si)
+{
+ if (si->free_signing_context) {
+ si->free_signing_context(si);
+ si->signing_context = NULL;
+ }
+
+ null_set_signing(si);
+}
+
+
+static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq)
+{
+ if (good && !si->doing_signing) {
+ si->doing_signing = True;
}
if (!good) {
- if (cli->sign_info.doing_signing) {
- DEBUG(1, ("SMB signature check failed!\n"));
+ if (si->doing_signing) {
+ struct smb_basic_signing_context *data = si->signing_context;
+
+ /* W2K sends a bad first signature but the sign engine is on.... JRA. */
+ if (data->send_seq_num > 1)
+ DEBUG(1, ("signing_good: SMB signature check failed on seq %u!\n",
+ (unsigned int)seq ));
+
return False;
} else {
- DEBUG(3, ("Server did not sign reply correctly\n"));
- cli_free_signing_context(cli);
+ DEBUG(3, ("signing_good: Peer did not sign reply correctly\n"));
+ free_signing_context(si);
return False;
}
}
@@ -155,13 +255,15 @@ static void simple_packet_signature(struct smb_basic_signing_context *data,
* We do this here, to avoid modifying the packet.
*/
+ DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number ));
+
SIVAL(sequence_buf, 0, seq_number);
SIVAL(sequence_buf, 4, 0);
/* Calculate the 16 byte MAC - but don't alter the data in the
incoming packet.
- This makes for a bit for fussing about, but it's not too bad.
+ This makes for a bit of fussing about, but it's not too bad.
*/
MD5Init(&md5_ctx);
@@ -185,76 +287,126 @@ static void simple_packet_signature(struct smb_basic_signing_context *data,
/***********************************************************
- SMB signing - Simple implementation - send the MAC.
+ SMB signing - Client implementation - send the MAC.
************************************************************/
-static void cli_simple_sign_outgoing_message(struct cli_state *cli)
+static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
{
unsigned char calc_md5_mac[16];
- struct smb_basic_signing_context *data = cli->sign_info.signing_context;
+ struct smb_basic_signing_context *data = si->signing_context;
+ uint32 send_seq_num;
+
+ if (!si->doing_signing)
+ return;
+
+ /* JRA Paranioa test - we should be able to get rid of this... */
+ if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
+ DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n",
+ smb_len(outbuf) ));
+ abort();
+ }
/* mark the packet as signed - BEFORE we sign it...*/
- cli_mark_packet_signed(cli);
+ mark_packet_signed(outbuf);
- simple_packet_signature(data, cli->outbuf, data->send_seq_num,
- calc_md5_mac);
+ if (data->trans_info)
+ send_seq_num = data->trans_info->send_seq_num;
+ else
+ send_seq_num = data->send_seq_num;
- DEBUG(10, ("sent SMB signature of\n"));
- dump_data(10, calc_md5_mac, 8);
+ simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_num, calc_md5_mac);
- memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8);
+ DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n"));
+ dump_data(10, (const char *)calc_md5_mac, 8);
+
+ memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
/* cli->outbuf[smb_ss_field+2]=0;
Uncomment this to test if the remote server actually verifies signatures...*/
+ if (data->trans_info)
+ return;
+
data->send_seq_num++;
store_sequence_for_reply(&data->outstanding_packet_list,
- cli->mid,
- data->send_seq_num);
+ SVAL(outbuf,smb_mid),
+ data->send_seq_num, False);
data->send_seq_num++;
}
/***********************************************************
- SMB signing - Simple implementation - check a MAC sent by server.
+ SMB signing - Client implementation - check a MAC sent by server.
************************************************************/
-static BOOL cli_simple_check_incoming_message(struct cli_state *cli)
+static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si)
{
BOOL good;
uint32 reply_seq_number;
+ uint32 saved_seq;
unsigned char calc_md5_mac[16];
unsigned char *server_sent_mac;
- struct smb_basic_signing_context *data = cli->sign_info.signing_context;
+ struct smb_basic_signing_context *data = si->signing_context;
+
+ if (!si->doing_signing)
+ return True;
- if (!get_sequence_for_reply(&data->outstanding_packet_list,
- SVAL(cli->inbuf, smb_mid),
- &reply_seq_number)) {
+ if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
+ DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
return False;
}
- simple_packet_signature(data, cli->inbuf, reply_seq_number, calc_md5_mac);
+ if (data->trans_info) {
+ reply_seq_number = data->trans_info->reply_seq_num;
+ } else if (!get_sequence_for_reply(&data->outstanding_packet_list,
+ SVAL(inbuf, smb_mid),
+ &reply_seq_number, NULL)) {
+ DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n",
+ (unsigned int) SVAL(inbuf, smb_mid) ));
+ return False;
+ }
+
+ saved_seq = reply_seq_number;
+ simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
- server_sent_mac = &cli->inbuf[smb_ss_field];
+ server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
if (!good) {
- DEBUG(5, ("BAD SIG: wanted SMB signature of\n"));
- dump_data(5, calc_md5_mac, 8);
+ DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n"));
+ dump_data(5, (const char *)calc_md5_mac, 8);
- DEBUG(5, ("BAD SIG: got SMB signature of\n"));
- dump_data(5, server_sent_mac, 8);
+ DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n"));
+ dump_data(5, (const char *)server_sent_mac, 8);
+#if 1 /* JRATEST */
+ {
+ int i;
+ reply_seq_number -= 5;
+ for (i = 0; i < 10; i++, reply_seq_number++) {
+ simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
+ if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
+ DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n",
+ reply_seq_number ));
+ break;
+ }
+ }
+ }
+#endif /* JRATEST */
+
+ } else {
+ DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number));
+ dump_data(10, (const char *)server_sent_mac, 8);
}
- return cli_signing_good(cli, good);
+ return signing_good(inbuf, si, good, saved_seq);
}
/***********************************************************
SMB signing - Simple implementation - free signing context
************************************************************/
-static void cli_simple_free_signing_context(struct cli_state *cli)
+static void simple_free_signing_context(struct smb_sign_info *si)
{
- struct smb_basic_signing_context *data = cli->sign_info.signing_context;
+ struct smb_basic_signing_context *data = si->signing_context;
struct outstanding_packet_lookup *list = data->outstanding_packet_list;
while (list) {
@@ -264,7 +416,11 @@ static void cli_simple_free_signing_context(struct cli_state *cli)
}
data_blob_free(&data->mac_key);
- SAFE_FREE(cli->sign_info.signing_context);
+
+ if (data->trans_info)
+ SAFE_FREE(data->trans_info);
+
+ SAFE_FREE(si->signing_context);
return;
}
@@ -284,18 +440,29 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[
return False;
}
- if (!cli_set_smb_signing_real_common(cli)) {
+ if (!set_smb_signing_real_common(&cli->sign_info)) {
return False;
}
data = smb_xmalloc(sizeof(*data));
+ memset(data, '\0', sizeof(*data));
cli->sign_info.signing_context = data;
data->mac_key = data_blob(NULL, response.length + 16);
memcpy(&data->mac_key.data[0], user_session_key, 16);
- memcpy(&data->mac_key.data[16],response.data, response.length);
+
+ DEBUG(10, ("cli_simple_set_signing: user_session_key\n"));
+ dump_data(10, (const char *)user_session_key, 16);
+
+ if (response.length) {
+ memcpy(&data->mac_key.data[16],response.data, response.length);
+ DEBUG(10, ("cli_simple_set_signing: response_data\n"));
+ dump_data(10, (const char *)response.data, response.length);
+ } else {
+ DEBUG(10, ("cli_simple_set_signing: NULL response_data\n"));
+ }
/* Initialise the sequence number */
data->send_seq_num = 0;
@@ -303,73 +470,68 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[
/* Initialise the list of outstanding packets */
data->outstanding_packet_list = NULL;
- cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message;
- cli->sign_info.check_incoming_message = cli_simple_check_incoming_message;
- cli->sign_info.free_signing_context = cli_simple_free_signing_context;
+ cli->sign_info.sign_outgoing_message = client_sign_outgoing_message;
+ cli->sign_info.check_incoming_message = client_check_incoming_message;
+ cli->sign_info.free_signing_context = simple_free_signing_context;
return True;
}
/***********************************************************
- SMB signing - NULL implementation - calculate a MAC to send.
+ Tell client code we are in a multiple trans reply state.
************************************************************/
-static void cli_null_sign_outgoing_message(struct cli_state *cli)
+void cli_signing_trans_start(struct cli_state *cli)
{
- /* we can't zero out the sig, as we might be trying to send a
- session request - which is NBT-level, not SMB level and doesn't
- have the field */
- return;
-}
+ struct smb_basic_signing_context *data = cli->sign_info.signing_context;
-/***********************************************************
- SMB signing - NULL implementation - check a MAC sent by server.
-************************************************************/
+ if (!cli->sign_info.doing_signing || !data)
+ return;
-static BOOL cli_null_check_incoming_message(struct cli_state *cli)
-{
- return True;
+ data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
+ ZERO_STRUCTP(data->trans_info);
+
+ data->trans_info->send_seq_num = data->send_seq_num;
+ data->trans_info->mid = SVAL(cli->outbuf,smb_mid);
+ data->trans_info->reply_seq_num = data->send_seq_num+1;
+
+ DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
+data->send_seq_num = %u\n",
+ (unsigned int)data->trans_info->mid,
+ (unsigned int)data->trans_info->reply_seq_num,
+ (unsigned int)data->trans_info->send_seq_num,
+ (unsigned int)data->send_seq_num ));
}
/***********************************************************
- SMB signing - NULL implementation - free signing context
+ Tell client code we are out of a multiple trans reply state.
************************************************************/
-static void cli_null_free_signing_context(struct cli_state *cli)
+void cli_signing_trans_stop(struct cli_state *cli)
{
- return;
-}
+ struct smb_basic_signing_context *data = cli->sign_info.signing_context;
-/**
- SMB signing - NULL implementation - setup the MAC key.
+ if (!cli->sign_info.doing_signing || !data)
+ return;
- @note Used as an initialisation only - it will not correctly
- shut down a real signing mechanism
-*/
+ SAFE_FREE(data->trans_info);
+ data->trans_info = NULL;
-BOOL cli_null_set_signing(struct cli_state *cli)
-{
- cli->sign_info.signing_context = NULL;
-
- cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message;
- cli->sign_info.check_incoming_message = cli_null_check_incoming_message;
- cli->sign_info.free_signing_context = cli_null_free_signing_context;
-
- return True;
+ data->send_seq_num += 2;
}
/***********************************************************
SMB signing - TEMP implementation - calculate a MAC to send.
************************************************************/
-static void cli_temp_sign_outgoing_message(struct cli_state *cli)
+static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
{
/* mark the packet as signed - BEFORE we sign it...*/
- cli_mark_packet_signed(cli);
+ mark_packet_signed(outbuf);
/* I wonder what BSRSPYL stands for - but this is what MS
actually sends! */
- memcpy(&cli->outbuf[smb_ss_field], "BSRSPYL ", 8);
+ memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8);
return;
}
@@ -377,7 +539,7 @@ static void cli_temp_sign_outgoing_message(struct cli_state *cli)
SMB signing - TEMP implementation - check a MAC sent by server.
************************************************************/
-static BOOL cli_temp_check_incoming_message(struct cli_state *cli)
+static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si)
{
return True;
}
@@ -386,7 +548,7 @@ static BOOL cli_temp_check_incoming_message(struct cli_state *cli)
SMB signing - TEMP implementation - free signing context
************************************************************/
-static void cli_temp_free_signing_context(struct cli_state *cli)
+static void temp_free_signing_context(struct smb_sign_info *si)
{
return;
}
@@ -395,6 +557,15 @@ static void cli_temp_free_signing_context(struct cli_state *cli)
SMB signing - NULL implementation - setup the MAC key.
************************************************************/
+BOOL cli_null_set_signing(struct cli_state *cli)
+{
+ return null_set_signing(&cli->sign_info);
+}
+
+/***********************************************************
+ SMB signing - temp implementation - setup the MAC key.
+************************************************************/
+
BOOL cli_temp_set_signing(struct cli_state *cli)
{
if (!cli_set_smb_signing_common(cli)) {
@@ -403,23 +574,16 @@ BOOL cli_temp_set_signing(struct cli_state *cli)
cli->sign_info.signing_context = NULL;
- cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message;
- cli->sign_info.check_incoming_message = cli_temp_check_incoming_message;
- cli->sign_info.free_signing_context = cli_temp_free_signing_context;
+ cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message;
+ cli->sign_info.check_incoming_message = temp_check_incoming_message;
+ cli->sign_info.free_signing_context = temp_free_signing_context;
return True;
}
-/**
- * Free the signing context
- */
-
-void cli_free_signing_context(struct cli_state *cli)
+void cli_free_signing_context(struct cli_state *cli)
{
- if (cli->sign_info.free_signing_context)
- cli->sign_info.free_signing_context(cli);
-
- cli_null_set_signing(cli);
+ free_signing_context(&cli->sign_info);
}
/**
@@ -428,33 +592,403 @@ void cli_free_signing_context(struct cli_state *cli)
void cli_calculate_sign_mac(struct cli_state *cli)
{
- cli->sign_info.sign_outgoing_message(cli);
+ cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info);
}
/**
* Check a packet with the current mechanism
* @return False if we had an established signing connection
- * which had a back checksum, True otherwise
+ * which had a bad checksum, True otherwise.
*/
BOOL cli_check_sign_mac(struct cli_state *cli)
{
+ if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) {
+ free_signing_context(&cli->sign_info);
+ return False;
+ }
+ return True;
+}
+
+/***********************************************************
+ SMB signing - Server implementation - send the MAC.
+************************************************************/
+
+static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si)
+{
+ unsigned char calc_md5_mac[16];
+ struct smb_basic_signing_context *data = si->signing_context;
+ uint32 send_seq_number = data->send_seq_num;
+ BOOL was_deferred_packet = False;
+ uint16 mid;
+
+ if (!si->doing_signing) {
+ return;
+ }
+
+ /* JRA Paranioa test - we should be able to get rid of this... */
+ if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) {
+ DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n",
+ smb_len(outbuf) ));
+ abort();
+ }
+
+ /* mark the packet as signed - BEFORE we sign it...*/
+ mark_packet_signed(outbuf);
+
+ mid = SVAL(outbuf, smb_mid);
+
+ /* See if this is a reply for a deferred packet. */
+ get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number, &was_deferred_packet);
+
+ if (data->trans_info && (data->trans_info->mid == mid)) {
+ /* This is a reply in a trans stream. Use the sequence
+ * number associated with the stream mid. */
+ send_seq_number = data->trans_info->send_seq_num;
+ }
+
+ simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac);
+
+ DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number));
+ dump_data(10, (const char *)calc_md5_mac, 8);
+
+ memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8);
+
+/* cli->outbuf[smb_ss_field+2]=0;
+ Uncomment this to test if the remote server actually verifies signatures...*/
+
+ if (!was_deferred_packet) {
+ if (!data->trans_info) {
+ /* Always increment if not in a trans stream. */
+ data->send_seq_num++;
+ } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) {
+ /* Increment if this is the first reply in a trans stream or a
+ * packet that doesn't belong to this stream (different mid). */
+ data->send_seq_num++;
+ }
+ }
+}
+
+/***********************************************************
+ Is an incoming packet an oplock break reply ?
+************************************************************/
+
+static BOOL is_oplock_break(char *inbuf)
+{
+ if (CVAL(inbuf,smb_com) != SMBlockingX)
+ return False;
+
+ if (!(CVAL(inbuf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE))
+ return False;
+
+ DEBUG(10,("is_oplock_break: Packet is oplock break\n"));
+ return True;
+}
+
+/***********************************************************
+ SMB signing - Server implementation - check a MAC sent by server.
+************************************************************/
+
+static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si)
+{
BOOL good;
+ struct smb_basic_signing_context *data = si->signing_context;
+ uint32 reply_seq_number = data->send_seq_num;
+ uint32 saved_seq;
+ unsigned char calc_md5_mac[16];
+ unsigned char *server_sent_mac;
+ uint mid;
+
+ if (!si->doing_signing)
+ return True;
+
+ if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
+ DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf)));
+ return False;
+ }
+
+ mid = SVAL(inbuf, smb_mid);
- if (smb_len(cli->inbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf)));
- good = False;
+ /* Is this part of a trans stream ? */
+ if (data->trans_info && (data->trans_info->mid == mid)) {
+ /* If so we don't increment the sequence. */
+ reply_seq_number = data->trans_info->reply_seq_num;
} else {
- good = cli->sign_info.check_incoming_message(cli);
+ /* We always increment the sequence number. */
+ data->send_seq_num++;
+
+ /* If we get an asynchronous oplock break reply and there
+ * isn't a reply pending we need to re-sync the sequence
+ * number.
+ */
+ if (is_oplock_break(inbuf) && !is_reply_pending(data->outstanding_packet_list))
+ data->send_seq_num++;
}
+ saved_seq = reply_seq_number;
+ simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
+
+ server_sent_mac = (unsigned char *)&inbuf[smb_ss_field];
+ good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
+
if (!good) {
- if (cli->sign_info.doing_signing) {
- return False;
- } else {
- cli_free_signing_context(cli);
+
+ DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
+ (unsigned int)saved_seq));
+ dump_data(5, (const char *)calc_md5_mac, 8);
+
+ DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
+ (unsigned int)saved_seq));
+ dump_data(5, (const char *)server_sent_mac, 8);
+
+#if 1 /* JRATEST */
+ {
+ int i;
+ reply_seq_number -= 5;
+ for (i = 0; i < 10; i++, reply_seq_number++) {
+ simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac);
+ if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) {
+ DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n",
+ reply_seq_number ));
+ break;
+ }
+ }
}
+#endif /* JRATEST */
+
+ } else {
+ DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num));
+ dump_data(10, (const char *)server_sent_mac, 8);
}
+ return signing_good(inbuf, si, good, saved_seq);
+}
- return True;
+/***********************************************************
+ SMB signing - server API's.
+************************************************************/
+
+static struct smb_sign_info srv_sign_info = {
+ null_sign_outgoing_message,
+ null_check_incoming_message,
+ null_free_signing_context,
+ NULL,
+ False,
+ False,
+ False,
+ False
+};
+
+/***********************************************************
+ Turn signing off or on for oplock break code.
+************************************************************/
+
+BOOL srv_oplock_set_signing(BOOL onoff)
+{
+ BOOL ret = srv_sign_info.doing_signing;
+ srv_sign_info.doing_signing = onoff;
+ return ret;
+}
+
+/***********************************************************
+ Called to validate an incoming packet from the client.
+************************************************************/
+
+BOOL srv_check_sign_mac(char *inbuf)
+{
+ /* Check if it's a session keepalive. */
+ if(CVAL(inbuf,0) == SMBkeepalive)
+ return True;
+
+ return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info);
+}
+
+/***********************************************************
+ Called to sign an outgoing packet to the client.
+************************************************************/
+
+void srv_calculate_sign_mac(char *outbuf)
+{
+ /* Check if it's a session keepalive. */
+ /* JRA Paranioa test - do we ever generate these in the server ? */
+ if(CVAL(outbuf,0) == SMBkeepalive)
+ return;
+
+ srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
+}
+
+/***********************************************************
+ Called by server to defer an outgoing packet.
+************************************************************/
+
+void srv_defer_sign_response(uint16 mid, BOOL deferred_packet)
+{
+ struct smb_basic_signing_context *data;
+
+ if (!srv_sign_info.doing_signing)
+ return;
+
+ data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
+
+ if (!data)
+ return;
+
+ store_sequence_for_reply(&data->outstanding_packet_list,
+ mid, data->send_seq_num, deferred_packet);
+ data->send_seq_num++;
+}
+
+/***********************************************************
+ Called to remove sequence records when a deferred packet is
+ cancelled by mid. This should never find one....
+************************************************************/
+
+void srv_cancel_sign_response(uint16 mid)
+{
+ struct smb_basic_signing_context *data;
+ uint32 dummy_seq;
+
+ if (!srv_sign_info.doing_signing)
+ return;
+
+ data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
+
+ if (!data)
+ return;
+
+ DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid ));
+
+ while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq,NULL))
+ ;
+}
+
+/***********************************************************
+ Called by server negprot when signing has been negotiated.
+************************************************************/
+
+void srv_set_signing_negotiated(void)
+{
+ srv_sign_info.allow_smb_signing = True;
+ srv_sign_info.negotiated_smb_signing = True;
+ if (lp_server_signing() == Required)
+ srv_sign_info.mandatory_signing = True;
+
+ srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message;
+ srv_sign_info.check_incoming_message = temp_check_incoming_message;
+ srv_sign_info.free_signing_context = temp_free_signing_context;
+}
+
+/***********************************************************
+ Returns whether signing is active. We can't use sendfile or raw
+ reads/writes if it is.
+************************************************************/
+
+BOOL srv_is_signing_active(void)
+{
+ return srv_sign_info.doing_signing;
+}
+
+/***********************************************************
+ Tell server code we are in a multiple trans reply state.
+************************************************************/
+
+void srv_signing_trans_start(uint16 mid)
+{
+ struct smb_basic_signing_context *data;
+
+ if (!srv_sign_info.doing_signing)
+ return;
+
+ data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
+ if (!data)
+ return;
+
+ data->trans_info = smb_xmalloc(sizeof(struct trans_info_context));
+ ZERO_STRUCTP(data->trans_info);
+
+ data->trans_info->reply_seq_num = data->send_seq_num-1;
+ data->trans_info->mid = mid;
+ data->trans_info->send_seq_num = data->send_seq_num;
+
+ DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \
+data->send_seq_num = %u\n",
+ (unsigned int)mid,
+ (unsigned int)data->trans_info->reply_seq_num,
+ (unsigned int)data->trans_info->send_seq_num,
+ (unsigned int)data->send_seq_num ));
+}
+
+/***********************************************************
+ Tell server code we are out of a multiple trans reply state.
+************************************************************/
+
+void srv_signing_trans_stop(void)
+{
+ struct smb_basic_signing_context *data;
+
+ if (!srv_sign_info.doing_signing)
+ return;
+
+ data = (struct smb_basic_signing_context *)srv_sign_info.signing_context;
+ if (!data || !data->trans_info)
+ return;
+
+ DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \
+data->send_seq_num = %u\n",
+ (unsigned int)data->trans_info->mid,
+ (unsigned int)data->trans_info->reply_seq_num,
+ (unsigned int)data->trans_info->send_seq_num,
+ (unsigned int)data->send_seq_num ));
+
+ SAFE_FREE(data->trans_info);
+ data->trans_info = NULL;
+}
+
+/***********************************************************
+ Turn on signing from this packet onwards.
+************************************************************/
+
+void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response)
+{
+ struct smb_basic_signing_context *data;
+
+ if (!user_session_key)
+ return;
+
+ if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) {
+ DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n",
+ (unsigned int)srv_sign_info.negotiated_smb_signing,
+ (unsigned int)srv_sign_info.mandatory_signing ));
+ return;
+ }
+
+ /* Once we've turned on, ignore any more sessionsetups. */
+ if (srv_sign_info.doing_signing) {
+ return;
+ }
+
+ if (srv_sign_info.free_signing_context)
+ srv_sign_info.free_signing_context(&srv_sign_info);
+
+ srv_sign_info.doing_signing = True;
+
+ data = smb_xmalloc(sizeof(*data));
+ memset(data, '\0', sizeof(*data));
+
+ srv_sign_info.signing_context = data;
+
+ data->mac_key = data_blob(NULL, response.length + 16);
+
+ memcpy(&data->mac_key.data[0], user_session_key, 16);
+ if (response.length)
+ memcpy(&data->mac_key.data[16],response.data, response.length);
+
+ /* Initialise the sequence number */
+ data->send_seq_num = 0;
+
+ /* Initialise the list of outstanding packets */
+ data->outstanding_packet_list = NULL;
+
+ srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message;
+ srv_sign_info.check_incoming_message = srv_check_incoming_message;
+ srv_sign_info.free_signing_context = simple_free_signing_context;
}
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index 7a1a2d7d189..ec31bb5dbaa 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -81,7 +81,7 @@ void E_deshash(const char *passwd, uchar p16[16])
push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE);
/* Only the fisrt 14 chars are considered, password need not be null terminated. */
- E_P16(dospwd, p16);
+ E_P16((const unsigned char *)dospwd, p16);
ZERO_STRUCT(dospwd);
}
@@ -247,7 +247,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
return True;
}
-/* Does the md5 encryption from the NT hash for NTLMv2. */
+/* Does the md5 encryption from the Key Response for NTLMv2. */
void SMBOWFencrypt_ntv2(const uchar kr[16],
const DATA_BLOB *srv_chal,
const DATA_BLOB *cli_chal,
diff --git a/source/libsmb/spnego.c b/source/libsmb/spnego.c
new file mode 100644
index 00000000000..50caf7b4c0e
--- /dev/null
+++ b/source/libsmb/spnego.c
@@ -0,0 +1,343 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ RFC2478 Compliant SPNEGO implementation
+
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_AUTH
+
+static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
+{
+ ZERO_STRUCTP(token);
+
+ asn1_start_tag(asn1, ASN1_CONTEXT(0));
+ asn1_start_tag(asn1, ASN1_SEQUENCE(0));
+
+ while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
+ int i;
+
+ switch (asn1->data[asn1->ofs]) {
+ /* Read mechTypes */
+ case ASN1_CONTEXT(0):
+ asn1_start_tag(asn1, ASN1_CONTEXT(0));
+ asn1_start_tag(asn1, ASN1_SEQUENCE(0));
+
+ token->mechTypes = malloc(sizeof(*token->mechTypes));
+ for (i = 0; !asn1->has_error &&
+ 0 < asn1_tag_remaining(asn1); i++) {
+ token->mechTypes =
+ realloc(token->mechTypes, (i + 2) *
+ sizeof(*token->mechTypes));
+ asn1_read_OID(asn1, token->mechTypes + i);
+ }
+ token->mechTypes[i] = NULL;
+
+ asn1_end_tag(asn1);
+ asn1_end_tag(asn1);
+ break;
+ /* Read reqFlags */
+ case ASN1_CONTEXT(1):
+ asn1_start_tag(asn1, ASN1_CONTEXT(1));
+ asn1_read_Integer(asn1, &token->reqFlags);
+ token->reqFlags |= SPNEGO_REQ_FLAG;
+ asn1_end_tag(asn1);
+ break;
+ /* Read mechToken */
+ case ASN1_CONTEXT(2):
+ asn1_start_tag(asn1, ASN1_CONTEXT(2));
+ asn1_read_OctetString(asn1, &token->mechToken);
+ asn1_end_tag(asn1);
+ break;
+ /* Read mecListMIC */
+ case ASN1_CONTEXT(3):
+ asn1_start_tag(asn1, ASN1_CONTEXT(3));
+ if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) {
+ asn1_read_OctetString(asn1,
+ &token->mechListMIC);
+ } else {
+ /* RFC 2478 says we have an Octet String here,
+ but W2k sends something different... */
+ char *mechListMIC;
+ asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+ asn1_push_tag(asn1, ASN1_CONTEXT(0));
+ asn1_read_GeneralString(asn1, &mechListMIC);
+ asn1_pop_tag(asn1);
+ asn1_pop_tag(asn1);
+
+ token->mechListMIC =
+ data_blob(mechListMIC, strlen(mechListMIC));
+ SAFE_FREE(mechListMIC);
+ }
+ asn1_end_tag(asn1);
+ break;
+ default:
+ asn1->has_error = True;
+ break;
+ }
+ }
+
+ asn1_end_tag(asn1);
+ asn1_end_tag(asn1);
+
+ return !asn1->has_error;
+}
+
+static BOOL write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token)
+{
+ asn1_push_tag(asn1, ASN1_CONTEXT(0));
+ asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+
+ /* Write mechTypes */
+ if (token->mechTypes && *token->mechTypes) {
+ int i;
+
+ asn1_push_tag(asn1, ASN1_CONTEXT(0));
+ asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+ for (i = 0; token->mechTypes[i]; i++) {
+ asn1_write_OID(asn1, token->mechTypes[i]);
+ }
+ asn1_pop_tag(asn1);
+ asn1_pop_tag(asn1);
+ }
+
+ /* write reqFlags */
+ if (token->reqFlags & SPNEGO_REQ_FLAG) {
+ int flags = token->reqFlags & ~SPNEGO_REQ_FLAG;
+
+ asn1_push_tag(asn1, ASN1_CONTEXT(1));
+ asn1_write_Integer(asn1, flags);
+ asn1_pop_tag(asn1);
+ }
+
+ /* write mechToken */
+ if (token->mechToken.data) {
+ asn1_push_tag(asn1, ASN1_CONTEXT(2));
+ asn1_write_OctetString(asn1, token->mechToken.data,
+ token->mechToken.length);
+ asn1_pop_tag(asn1);
+ }
+
+ /* write mechListMIC */
+ if (token->mechListMIC.data) {
+ asn1_push_tag(asn1, ASN1_CONTEXT(3));
+#if 0
+ /* This is what RFC 2478 says ... */
+ asn1_write_OctetString(asn1, token->mechListMIC.data,
+ token->mechListMIC.length);
+#else
+ /* ... but unfortunately this is what Windows
+ sends/expects */
+ asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+ asn1_push_tag(asn1, ASN1_CONTEXT(0));
+ asn1_push_tag(asn1, ASN1_GENERAL_STRING);
+ asn1_write(asn1, token->mechListMIC.data,
+ token->mechListMIC.length);
+ asn1_pop_tag(asn1);
+ asn1_pop_tag(asn1);
+ asn1_pop_tag(asn1);
+#endif
+ asn1_pop_tag(asn1);
+ }
+
+ asn1_pop_tag(asn1);
+ asn1_pop_tag(asn1);
+
+ return !asn1->has_error;
+}
+
+static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token)
+{
+ ZERO_STRUCTP(token);
+
+ asn1_start_tag(asn1, ASN1_CONTEXT(1));
+ asn1_start_tag(asn1, ASN1_SEQUENCE(0));
+
+ while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) {
+ switch (asn1->data[asn1->ofs]) {
+ case ASN1_CONTEXT(0):
+ asn1_start_tag(asn1, ASN1_CONTEXT(0));
+ asn1_start_tag(asn1, ASN1_ENUMERATED);
+ asn1_read_uint8(asn1, &token->negResult);
+ asn1_end_tag(asn1);
+ asn1_end_tag(asn1);
+ break;
+ case ASN1_CONTEXT(1):
+ asn1_start_tag(asn1, ASN1_CONTEXT(1));
+ asn1_read_OID(asn1, &token->supportedMech);
+ asn1_end_tag(asn1);
+ break;
+ case ASN1_CONTEXT(2):
+ asn1_start_tag(asn1, ASN1_CONTEXT(2));
+ asn1_read_OctetString(asn1, &token->responseToken);
+ asn1_end_tag(asn1);
+ break;
+ case ASN1_CONTEXT(3):
+ asn1_start_tag(asn1, ASN1_CONTEXT(3));
+ asn1_read_OctetString(asn1, &token->mechListMIC);
+ asn1_end_tag(asn1);
+ break;
+ default:
+ asn1->has_error = True;
+ break;
+ }
+ }
+
+ asn1_end_tag(asn1);
+ asn1_end_tag(asn1);
+
+ return !asn1->has_error;
+}
+
+static BOOL write_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token)
+{
+ asn1_push_tag(asn1, ASN1_CONTEXT(1));
+ asn1_push_tag(asn1, ASN1_SEQUENCE(0));
+
+ asn1_push_tag(asn1, ASN1_CONTEXT(0));
+ asn1_write_enumerated(asn1, token->negResult);
+ asn1_pop_tag(asn1);
+
+ if (token->supportedMech) {
+ asn1_push_tag(asn1, ASN1_CONTEXT(1));
+ asn1_write_OID(asn1, token->supportedMech);
+ asn1_pop_tag(asn1);
+ }
+
+ if (token->responseToken.data) {
+ asn1_push_tag(asn1, ASN1_CONTEXT(2));
+ asn1_write_OctetString(asn1, token->responseToken.data,
+ token->responseToken.length);
+ asn1_pop_tag(asn1);
+ }
+
+ if (token->mechListMIC.data) {
+ asn1_push_tag(asn1, ASN1_CONTEXT(3));
+ asn1_write_OctetString(asn1, token->mechListMIC.data,
+ token->mechListMIC.length);
+ asn1_pop_tag(asn1);
+ }
+
+ asn1_pop_tag(asn1);
+ asn1_pop_tag(asn1);
+
+ return !asn1->has_error;
+}
+
+ssize_t read_spnego_data(DATA_BLOB data, SPNEGO_DATA *token)
+{
+ ASN1_DATA asn1;
+ ssize_t ret = -1;
+
+ ZERO_STRUCTP(token);
+ ZERO_STRUCT(asn1);
+ asn1_load(&asn1, data);
+
+ switch (asn1.data[asn1.ofs]) {
+ case ASN1_APPLICATION(0):
+ asn1_start_tag(&asn1, ASN1_APPLICATION(0));
+ asn1_check_OID(&asn1, OID_SPNEGO);
+ if (read_negTokenInit(&asn1, &token->negTokenInit)) {
+ token->type = SPNEGO_NEG_TOKEN_INIT;
+ }
+ asn1_end_tag(&asn1);
+ break;
+ case ASN1_CONTEXT(1):
+ if (read_negTokenTarg(&asn1, &token->negTokenTarg)) {
+ token->type = SPNEGO_NEG_TOKEN_TARG;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!asn1.has_error) ret = asn1.ofs;
+ asn1_free(&asn1);
+
+ return ret;
+}
+
+ssize_t write_spnego_data(DATA_BLOB *blob, SPNEGO_DATA *spnego)
+{
+ ASN1_DATA asn1;
+ ssize_t ret = -1;
+
+ ZERO_STRUCT(asn1);
+
+ switch (spnego->type) {
+ case SPNEGO_NEG_TOKEN_INIT:
+ asn1_push_tag(&asn1, ASN1_APPLICATION(0));
+ asn1_write_OID(&asn1, OID_SPNEGO);
+ write_negTokenInit(&asn1, &spnego->negTokenInit);
+ asn1_pop_tag(&asn1);
+ break;
+ case SPNEGO_NEG_TOKEN_TARG:
+ write_negTokenTarg(&asn1, &spnego->negTokenTarg);
+ break;
+ default:
+ asn1.has_error = True;
+ break;
+ }
+
+ if (!asn1.has_error) {
+ *blob = data_blob(asn1.data, asn1.length);
+ ret = asn1.ofs;
+ }
+ asn1_free(&asn1);
+
+ return ret;
+}
+
+BOOL free_spnego_data(SPNEGO_DATA *spnego)
+{
+ BOOL ret = True;
+
+ if (!spnego) goto out;
+
+ switch(spnego->type) {
+ case SPNEGO_NEG_TOKEN_INIT:
+ if (spnego->negTokenInit.mechTypes) {
+ int i;
+ for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) {
+ free(spnego->negTokenInit.mechTypes[i]);
+ }
+ free(spnego->negTokenInit.mechTypes);
+ }
+ data_blob_free(&spnego->negTokenInit.mechToken);
+ data_blob_free(&spnego->negTokenInit.mechListMIC);
+ break;
+ case SPNEGO_NEG_TOKEN_TARG:
+ if (spnego->negTokenTarg.supportedMech) {
+ free(spnego->negTokenTarg.supportedMech);
+ }
+ data_blob_free(&spnego->negTokenTarg.responseToken);
+ data_blob_free(&spnego->negTokenTarg.mechListMIC);
+ break;
+ default:
+ ret = False;
+ break;
+ }
+ ZERO_STRUCTP(spnego);
+out:
+ return ret;
+}
+
diff --git a/source/libsmb/trustdom_cache.c b/source/libsmb/trustdom_cache.c
index 83781250880..0128d080062 100644
--- a/source/libsmb/trustdom_cache.c
+++ b/source/libsmb/trustdom_cache.c
@@ -223,7 +223,7 @@ BOOL trustdom_cache_store_timestamp( uint32 t, time_t timeout )
if (!gencache_init())
return False;
- snprintf(value, sizeof(value), "%d", t );
+ fstr_sprintf(value, "%d", t );
if (!gencache_set(TDOMTSKEY, value, timeout)) {
DEBUG(5, ("failed to set timestamp for trustdom_cache\n"));
diff --git a/source/libsmb/trusts_util.c b/source/libsmb/trusts_util.c
index 77e63709aac..610f4b3c031 100644
--- a/source/libsmb/trusts_util.c
+++ b/source/libsmb/trusts_util.c
@@ -154,7 +154,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
/* setup the anonymous connection */
result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
- "", "", "", 0, &retry);
+ "", "", "", 0, Undefined, &retry);
if ( !NT_STATUS_IS_OK(result) )
goto done;
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 1a5757f8173..4475f1446f9 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -125,7 +125,11 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
*/
if (!set_posix_lock(fsp, offset, count, lock_type)) {
- status = NT_STATUS_LOCK_NOT_GRANTED;
+ if (errno == EACCES || errno == EAGAIN)
+ status = NT_STATUS_FILE_LOCK_CONFLICT;
+ else
+ status = map_nt_error_from_unix(errno);
+
/*
* We failed to map - we must now remove the brl
* lock entry.
@@ -380,8 +384,8 @@ char *share_mode_str(int num, share_mode_entry *e)
static pstring share_str;
slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: \
-pid = %u, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
- num, e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
+pid = %lu, share_mode = 0x%x, desired_access = 0x%x, port = 0x%x, type= 0x%x, file_id = %lu, dev = 0x%x, inode = %.0f",
+ num, (unsigned long)e->pid, e->share_mode, (unsigned int)e->desired_access, e->op_port, e->op_type, e->share_file_id,
(unsigned int)e->dev, (double)e->inode );
return share_str;
diff --git a/source/modules/getdate.c b/source/modules/getdate.c
new file mode 100644
index 00000000000..491c51294e9
--- /dev/null
+++ b/source/modules/getdate.c
@@ -0,0 +1,2460 @@
+/* A Bison parser, made by GNU Bison 1.875a. */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ 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, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, when this file is copied by Bison into a
+ Bison output file, you may use that output file without restriction.
+ This special exception was added by the Free Software Foundation
+ in version 1.24 of Bison. */
+
+/* Written by Richard Stallman by simplifying the original so called
+ ``semantic'' parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ tAGO = 258,
+ tDST = 259,
+ tDAY = 260,
+ tDAY_UNIT = 261,
+ tDAYZONE = 262,
+ tHOUR_UNIT = 263,
+ tLOCAL_ZONE = 264,
+ tMERIDIAN = 265,
+ tMINUTE_UNIT = 266,
+ tMONTH = 267,
+ tMONTH_UNIT = 268,
+ tSEC_UNIT = 269,
+ tYEAR_UNIT = 270,
+ tZONE = 271,
+ tSNUMBER = 272,
+ tUNUMBER = 273
+ };
+#endif
+#define tAGO 258
+#define tDST 259
+#define tDAY 260
+#define tDAY_UNIT 261
+#define tDAYZONE 262
+#define tHOUR_UNIT 263
+#define tLOCAL_ZONE 264
+#define tMERIDIAN 265
+#define tMINUTE_UNIT 266
+#define tMONTH 267
+#define tMONTH_UNIT 268
+#define tSEC_UNIT 269
+#define tYEAR_UNIT 270
+#define tZONE 271
+#define tSNUMBER 272
+#define tUNUMBER 273
+
+
+
+
+/* Copy the first part of user declarations. */
+#line 1 "getdate.y"
+
+/* Parse a string into an internal time stamp.
+ Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+
+ 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, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Originally written by Steven M. Bellovin <smb@research.att.com> while
+ at the University of North Carolina at Chapel Hill. Later tweaked by
+ a couple of people on Usenet. Completely overhauled by Rich $alz
+ <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
+
+ Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
+ the right thing about local DST. Unlike previous versions, this
+ version is reentrant. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# endif
+#endif
+
+/* Since the code of getdate.y is not included in the Emacs executable
+ itself, there is no need to #define static in this file. Even if
+ the code were included in the Emacs executable, it probably
+ wouldn't do any harm to #undef it here; this will only cause
+ problems if we try to write to a static variable, which I don't
+ think this code needs to do. */
+#ifdef emacs
+# undef static
+#endif
+
+#include <ctype.h>
+
+#if HAVE_STDLIB_H
+# include <stdlib.h> /* for `free'; used by Bison 1.27 */
+#endif
+
+#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
+# define IN_CTYPE_DOMAIN(c) 1
+#else
+# define IN_CTYPE_DOMAIN(c) isascii (c)
+#endif
+
+#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
+#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
+#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
+#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
+
+/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
+ - Its arg may be any int or unsigned int; it need not be an unsigned char.
+ - It's guaranteed to evaluate its argument exactly once.
+ - It's typically faster.
+ POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
+ ISDIGIT_LOCALE unless it's important to use the locale's definition
+ of `digit' even when the host does not conform to POSIX. */
+#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
+
+#if STDC_HEADERS || HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
+# define __attribute__(x)
+#endif
+
+#ifndef ATTRIBUTE_UNUSED
+# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif
+
+#define EPOCH_YEAR 1970
+#define TM_YEAR_BASE 1900
+
+#define HOUR(x) ((x) * 60)
+
+/* An integer value, and the number of digits in its textual
+ representation. */
+typedef struct
+{
+ int value;
+ int digits;
+} textint;
+
+/* An entry in the lexical lookup table. */
+typedef struct
+{
+ char const *name;
+ int type;
+ int value;
+} table;
+
+/* Meridian: am, pm, or 24-hour style. */
+enum { MERam, MERpm, MER24 };
+
+/* Information passed to and from the parser. */
+typedef struct
+{
+ /* The input string remaining to be parsed. */
+ const char *input;
+
+ /* N, if this is the Nth Tuesday. */
+ int day_ordinal;
+
+ /* Day of week; Sunday is 0. */
+ int day_number;
+
+ /* tm_isdst flag for the local zone. */
+ int local_isdst;
+
+ /* Time zone, in minutes east of UTC. */
+ int time_zone;
+
+ /* Style used for time. */
+ int meridian;
+
+ /* Gregorian year, month, day, hour, minutes, and seconds. */
+ textint year;
+ int month;
+ int day;
+ int hour;
+ int minutes;
+ int seconds;
+
+ /* Relative year, month, day, hour, minutes, and seconds. */
+ int rel_year;
+ int rel_month;
+ int rel_day;
+ int rel_hour;
+ int rel_minutes;
+ int rel_seconds;
+
+ /* Counts of nonterminals of various flavors parsed so far. */
+ int dates_seen;
+ int days_seen;
+ int local_zones_seen;
+ int rels_seen;
+ int times_seen;
+ int zones_seen;
+
+ /* Table of local time zone abbrevations, terminated by a null entry. */
+ table local_time_zone_table[3];
+} parser_control;
+
+#define PC (* (parser_control *) parm)
+#define YYLEX_PARAM parm
+#define YYPARSE_PARAM parm
+
+static int yyerror ();
+static int yylex ();
+
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 172 "getdate.y"
+typedef union YYSTYPE {
+ int intval;
+ textint textintval;
+} YYSTYPE;
+/* Line 191 of yacc.c. */
+#line 281 "getdate.c"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 214 of yacc.c. */
+#line 293 "getdate.c"
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# if YYSTACK_USE_ALLOCA
+# define YYSTACK_ALLOC alloca
+# else
+# ifndef YYSTACK_USE_ALLOCA
+# if defined (alloca) || defined (_ALLOCA_H)
+# define YYSTACK_ALLOC alloca
+# else
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+# else
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+# define YYSTACK_ALLOC malloc
+# define YYSTACK_FREE free
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+ && (! defined (__cplusplus) \
+ || (YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ short yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ register YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (0)
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+ typedef signed char yysigned_char;
+#else
+ typedef short yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 2
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 52
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 22
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 12
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 54
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 64
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 273
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 20, 2, 2, 21, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 19, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned char yyprhs[] =
+{
+ 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
+ 19, 21, 24, 29, 34, 41, 48, 50, 53, 55,
+ 57, 60, 62, 65, 68, 72, 78, 82, 86, 89,
+ 94, 97, 101, 104, 106, 109, 112, 114, 117, 120,
+ 122, 125, 128, 130, 133, 136, 138, 141, 144, 146,
+ 149, 152, 154, 156, 157
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+ 23, 0, -1, -1, 23, 24, -1, 25, -1, 26,
+ -1, 27, -1, 29, -1, 28, -1, 30, -1, 32,
+ -1, 18, 10, -1, 18, 19, 18, 33, -1, 18,
+ 19, 18, 17, -1, 18, 19, 18, 19, 18, 33,
+ -1, 18, 19, 18, 19, 18, 17, -1, 9, -1,
+ 9, 4, -1, 16, -1, 7, -1, 16, 4, -1,
+ 5, -1, 5, 20, -1, 18, 5, -1, 18, 21,
+ 18, -1, 18, 21, 18, 21, 18, -1, 18, 17,
+ 17, -1, 18, 12, 17, -1, 12, 18, -1, 12,
+ 18, 20, 18, -1, 18, 12, -1, 18, 12, 18,
+ -1, 31, 3, -1, 31, -1, 18, 15, -1, 17,
+ 15, -1, 15, -1, 18, 13, -1, 17, 13, -1,
+ 13, -1, 18, 6, -1, 17, 6, -1, 6, -1,
+ 18, 8, -1, 17, 8, -1, 8, -1, 18, 11,
+ -1, 17, 11, -1, 11, -1, 18, 14, -1, 17,
+ 14, -1, 14, -1, 18, -1, -1, 10, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short yyrline[] =
+{
+ 0, 188, 188, 190, 194, 196, 198, 200, 202, 204,
+ 206, 210, 217, 224, 232, 239, 251, 253, 258, 260,
+ 262, 267, 272, 277, 285, 290, 310, 317, 325, 330,
+ 336, 341, 350, 359, 363, 365, 367, 369, 371, 373,
+ 375, 377, 379, 381, 383, 385, 387, 389, 391, 393,
+ 395, 397, 402, 439, 440
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE
+/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
+ "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
+ "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER",
+ "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time",
+ "local_zone", "zone", "day", "date", "rel", "relunit", "number",
+ "o_merid", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const unsigned short yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 58,
+ 44, 47
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 22, 23, 23, 24, 24, 24, 24, 24, 24,
+ 24, 25, 25, 25, 25, 25, 26, 26, 27, 27,
+ 27, 28, 28, 28, 29, 29, 29, 29, 29, 29,
+ 29, 29, 30, 30, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 32, 33, 33
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 4, 6, 6, 1, 2, 1, 1,
+ 2, 1, 2, 2, 3, 5, 3, 3, 2, 4,
+ 2, 3, 2, 1, 2, 2, 1, 2, 2, 1,
+ 2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
+ 2, 1, 1, 0, 1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const unsigned char yydefact[] =
+{
+ 2, 0, 1, 21, 42, 19, 45, 16, 48, 0,
+ 39, 51, 36, 18, 0, 52, 3, 4, 5, 6,
+ 8, 7, 9, 33, 10, 22, 17, 28, 20, 41,
+ 44, 47, 38, 50, 35, 23, 40, 43, 11, 46,
+ 30, 37, 49, 34, 0, 0, 0, 32, 0, 27,
+ 31, 26, 53, 24, 29, 54, 13, 0, 12, 0,
+ 53, 25, 15, 14
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yysigned_char yydefgoto[] =
+{
+ -1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 58
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -17
+static const yysigned_char yypact[] =
+{
+ -17, 0, -17, 1, -17, -17, -17, 19, -17, -14,
+ -17, -17, -17, 32, 26, 14, -17, -17, -17, -17,
+ -17, -17, -17, 27, -17, -17, -17, 22, -17, -17,
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -16, -17, -17, -17, 29, 25, 30, -17, 31, -17,
+ -17, -17, 28, 23, -17, -17, -17, 33, -17, 34,
+ -7, -17, -17, -17
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yysigned_char yypgoto[] =
+{
+ -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
+ -17, -10
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -1
+static const unsigned char yytable[] =
+{
+ 2, 49, 50, 55, 27, 3, 4, 5, 6, 7,
+ 62, 8, 9, 10, 11, 12, 13, 14, 15, 35,
+ 36, 25, 37, 26, 38, 39, 40, 41, 42, 43,
+ 47, 44, 29, 45, 30, 46, 28, 31, 55, 32,
+ 33, 34, 48, 52, 59, 56, 51, 57, 53, 54,
+ 63, 60, 61
+};
+
+static const unsigned char yycheck[] =
+{
+ 0, 17, 18, 10, 18, 5, 6, 7, 8, 9,
+ 17, 11, 12, 13, 14, 15, 16, 17, 18, 5,
+ 6, 20, 8, 4, 10, 11, 12, 13, 14, 15,
+ 3, 17, 6, 19, 8, 21, 4, 11, 10, 13,
+ 14, 15, 20, 18, 21, 17, 17, 19, 18, 18,
+ 60, 18, 18
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 23, 0, 5, 6, 7, 8, 9, 11, 12,
+ 13, 14, 15, 16, 17, 18, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 20, 4, 18, 4, 6,
+ 8, 11, 13, 14, 15, 5, 6, 8, 10, 11,
+ 12, 13, 14, 15, 17, 19, 21, 3, 20, 17,
+ 18, 17, 18, 18, 18, 10, 17, 19, 33, 21,
+ 18, 18, 17, 33
+};
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# if defined (__STDC__) || defined (__cplusplus)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# endif
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrlab1
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK; \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror ("syntax error: cannot back up");\
+ YYERROR; \
+ } \
+while (0)
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+/* YYLLOC_DEFAULT -- Compute the default location (before the actions
+ are run). */
+
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ Current.first_line = Rhs[1].first_line; \
+ Current.first_column = Rhs[1].first_column; \
+ Current.last_line = Rhs[N].last_line; \
+ Current.last_column = Rhs[N].last_column;
+#endif
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval)
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (0)
+
+# define YYDSYMPRINT(Args) \
+do { \
+ if (yydebug) \
+ yysymprint Args; \
+} while (0)
+
+# define YYDSYMPRINTF(Title, Token, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yysymprint (stderr, \
+ Token, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (cinluded). |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short *bottom, short *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ short *bottom;
+ short *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (/* Nothing. */; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+ int yyrule;
+#endif
+{
+ int yyi;
+ unsigned int yylineno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
+ yyrule - 1, yylineno);
+ /* Print the symbols being reduced, and their result. */
+ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+ YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
+ YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (Rule); \
+} while (0)
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YYDSYMPRINT(Args)
+# define YYDSYMPRINTF(Title, Token, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#if YYMAXDEPTH == 0
+# undef YYMAXDEPTH
+#endif
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined (__GLIBC__) && defined (_STRING_H)
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+static YYSIZE_T
+# if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+# else
+yystrlen (yystr)
+ const char *yystr;
+# endif
+{
+ register const char *yys = yystr;
+
+ while (*yys++ != '\0')
+ continue;
+
+ return yys - yystr - 1;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+# if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+# else
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+# endif
+{
+ register char *yyd = yydest;
+ register const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ if (yytype < YYNTOKENS)
+ {
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+# ifdef YYPRINT
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+ }
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+ YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yytype, yyvaluep)
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ /* Pacify ``unused variable'' warnings. */
+ (void) yyvaluep;
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+ /* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+ register int yystate;
+ register int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken = 0;
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ short yyssa[YYINITDEPTH];
+ short *yyss = yyssa;
+ register short *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ register YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK (yyvsp--, yyssp--)
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* When reducing, the number of symbols on the RHS of the reduced
+ rule. */
+ int yylen;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. so pushing a state here evens the stacks.
+ */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ short *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow ("parser stack overflow",
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyoverflowlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyoverflowlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ short *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyoverflowlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state. */
+/* Read a lookahead token if we need one and don't already have one. */
+/* yyresume: */
+
+ /* First try to decide what to do without reference to lookahead token. */
+
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Shift the lookahead token. */
+ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
+
+ /* Discard the token being shifted unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ *++yyvsp = yylval;
+
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 4:
+#line 195 "getdate.y"
+ { PC.times_seen++; }
+ break;
+
+ case 5:
+#line 197 "getdate.y"
+ { PC.local_zones_seen++; }
+ break;
+
+ case 6:
+#line 199 "getdate.y"
+ { PC.zones_seen++; }
+ break;
+
+ case 7:
+#line 201 "getdate.y"
+ { PC.dates_seen++; }
+ break;
+
+ case 8:
+#line 203 "getdate.y"
+ { PC.days_seen++; }
+ break;
+
+ case 9:
+#line 205 "getdate.y"
+ { PC.rels_seen++; }
+ break;
+
+ case 11:
+#line 211 "getdate.y"
+ {
+ PC.hour = yyvsp[-1].textintval.value;
+ PC.minutes = 0;
+ PC.seconds = 0;
+ PC.meridian = yyvsp[0].intval;
+ }
+ break;
+
+ case 12:
+#line 218 "getdate.y"
+ {
+ PC.hour = yyvsp[-3].textintval.value;
+ PC.minutes = yyvsp[-1].textintval.value;
+ PC.seconds = 0;
+ PC.meridian = yyvsp[0].intval;
+ }
+ break;
+
+ case 13:
+#line 225 "getdate.y"
+ {
+ PC.hour = yyvsp[-3].textintval.value;
+ PC.minutes = yyvsp[-1].textintval.value;
+ PC.meridian = MER24;
+ PC.zones_seen++;
+ PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
+ }
+ break;
+
+ case 14:
+#line 233 "getdate.y"
+ {
+ PC.hour = yyvsp[-5].textintval.value;
+ PC.minutes = yyvsp[-3].textintval.value;
+ PC.seconds = yyvsp[-1].textintval.value;
+ PC.meridian = yyvsp[0].intval;
+ }
+ break;
+
+ case 15:
+#line 240 "getdate.y"
+ {
+ PC.hour = yyvsp[-5].textintval.value;
+ PC.minutes = yyvsp[-3].textintval.value;
+ PC.seconds = yyvsp[-1].textintval.value;
+ PC.meridian = MER24;
+ PC.zones_seen++;
+ PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
+ }
+ break;
+
+ case 16:
+#line 252 "getdate.y"
+ { PC.local_isdst = yyvsp[0].intval; }
+ break;
+
+ case 17:
+#line 254 "getdate.y"
+ { PC.local_isdst = yyvsp[-1].intval < 0 ? 1 : yyvsp[-1].intval + 1; }
+ break;
+
+ case 18:
+#line 259 "getdate.y"
+ { PC.time_zone = yyvsp[0].intval; }
+ break;
+
+ case 19:
+#line 261 "getdate.y"
+ { PC.time_zone = yyvsp[0].intval + 60; }
+ break;
+
+ case 20:
+#line 263 "getdate.y"
+ { PC.time_zone = yyvsp[-1].intval + 60; }
+ break;
+
+ case 21:
+#line 268 "getdate.y"
+ {
+ PC.day_ordinal = 1;
+ PC.day_number = yyvsp[0].intval;
+ }
+ break;
+
+ case 22:
+#line 273 "getdate.y"
+ {
+ PC.day_ordinal = 1;
+ PC.day_number = yyvsp[-1].intval;
+ }
+ break;
+
+ case 23:
+#line 278 "getdate.y"
+ {
+ PC.day_ordinal = yyvsp[-1].textintval.value;
+ PC.day_number = yyvsp[0].intval;
+ }
+ break;
+
+ case 24:
+#line 286 "getdate.y"
+ {
+ PC.month = yyvsp[-2].textintval.value;
+ PC.day = yyvsp[0].textintval.value;
+ }
+ break;
+
+ case 25:
+#line 291 "getdate.y"
+ {
+ /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
+ otherwise as MM/DD/YY.
+ The goal in recognizing YYYY/MM/DD is solely to support legacy
+ machine-generated dates like those in an RCS log listing. If
+ you want portability, use the ISO 8601 format. */
+ if (4 <= yyvsp[-4].textintval.digits)
+ {
+ PC.year = yyvsp[-4].textintval;
+ PC.month = yyvsp[-2].textintval.value;
+ PC.day = yyvsp[0].textintval.value;
+ }
+ else
+ {
+ PC.month = yyvsp[-4].textintval.value;
+ PC.day = yyvsp[-2].textintval.value;
+ PC.year = yyvsp[0].textintval;
+ }
+ }
+ break;
+
+ case 26:
+#line 311 "getdate.y"
+ {
+ /* ISO 8601 format. YYYY-MM-DD. */
+ PC.year = yyvsp[-2].textintval;
+ PC.month = -yyvsp[-1].textintval.value;
+ PC.day = -yyvsp[0].textintval.value;
+ }
+ break;
+
+ case 27:
+#line 318 "getdate.y"
+ {
+ /* e.g. 17-JUN-1992. */
+ PC.day = yyvsp[-2].textintval.value;
+ PC.month = yyvsp[-1].intval;
+ PC.year.value = -yyvsp[0].textintval.value;
+ PC.year.digits = yyvsp[0].textintval.digits;
+ }
+ break;
+
+ case 28:
+#line 326 "getdate.y"
+ {
+ PC.month = yyvsp[-1].intval;
+ PC.day = yyvsp[0].textintval.value;
+ }
+ break;
+
+ case 29:
+#line 331 "getdate.y"
+ {
+ PC.month = yyvsp[-3].intval;
+ PC.day = yyvsp[-2].textintval.value;
+ PC.year = yyvsp[0].textintval;
+ }
+ break;
+
+ case 30:
+#line 337 "getdate.y"
+ {
+ PC.day = yyvsp[-1].textintval.value;
+ PC.month = yyvsp[0].intval;
+ }
+ break;
+
+ case 31:
+#line 342 "getdate.y"
+ {
+ PC.day = yyvsp[-2].textintval.value;
+ PC.month = yyvsp[-1].intval;
+ PC.year = yyvsp[0].textintval;
+ }
+ break;
+
+ case 32:
+#line 351 "getdate.y"
+ {
+ PC.rel_seconds = -PC.rel_seconds;
+ PC.rel_minutes = -PC.rel_minutes;
+ PC.rel_hour = -PC.rel_hour;
+ PC.rel_day = -PC.rel_day;
+ PC.rel_month = -PC.rel_month;
+ PC.rel_year = -PC.rel_year;
+ }
+ break;
+
+ case 34:
+#line 364 "getdate.y"
+ { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 35:
+#line 366 "getdate.y"
+ { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 36:
+#line 368 "getdate.y"
+ { PC.rel_year += yyvsp[0].intval; }
+ break;
+
+ case 37:
+#line 370 "getdate.y"
+ { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 38:
+#line 372 "getdate.y"
+ { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 39:
+#line 374 "getdate.y"
+ { PC.rel_month += yyvsp[0].intval; }
+ break;
+
+ case 40:
+#line 376 "getdate.y"
+ { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 41:
+#line 378 "getdate.y"
+ { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 42:
+#line 380 "getdate.y"
+ { PC.rel_day += yyvsp[0].intval; }
+ break;
+
+ case 43:
+#line 382 "getdate.y"
+ { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 44:
+#line 384 "getdate.y"
+ { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 45:
+#line 386 "getdate.y"
+ { PC.rel_hour += yyvsp[0].intval; }
+ break;
+
+ case 46:
+#line 388 "getdate.y"
+ { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 47:
+#line 390 "getdate.y"
+ { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 48:
+#line 392 "getdate.y"
+ { PC.rel_minutes += yyvsp[0].intval; }
+ break;
+
+ case 49:
+#line 394 "getdate.y"
+ { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 50:
+#line 396 "getdate.y"
+ { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
+ break;
+
+ case 51:
+#line 398 "getdate.y"
+ { PC.rel_seconds += yyvsp[0].intval; }
+ break;
+
+ case 52:
+#line 403 "getdate.y"
+ {
+ if (PC.dates_seen
+ && ! PC.rels_seen && (PC.times_seen || 2 < yyvsp[0].textintval.digits))
+ PC.year = yyvsp[0].textintval;
+ else
+ {
+ if (4 < yyvsp[0].textintval.digits)
+ {
+ PC.dates_seen++;
+ PC.day = yyvsp[0].textintval.value % 100;
+ PC.month = (yyvsp[0].textintval.value / 100) % 100;
+ PC.year.value = yyvsp[0].textintval.value / 10000;
+ PC.year.digits = yyvsp[0].textintval.digits - 4;
+ }
+ else
+ {
+ PC.times_seen++;
+ if (yyvsp[0].textintval.digits <= 2)
+ {
+ PC.hour = yyvsp[0].textintval.value;
+ PC.minutes = 0;
+ }
+ else
+ {
+ PC.hour = yyvsp[0].textintval.value / 100;
+ PC.minutes = yyvsp[0].textintval.value % 100;
+ }
+ PC.seconds = 0;
+ PC.meridian = MER24;
+ }
+ }
+ }
+ break;
+
+ case 53:
+#line 439 "getdate.y"
+ { yyval.intval = MER24; }
+ break;
+
+ case 54:
+#line 441 "getdate.y"
+ { yyval.intval = yyvsp[0].intval; }
+ break;
+
+
+ }
+
+/* Line 999 of yacc.c. */
+#line 1593 "getdate.c"
+
+ yyvsp -= yylen;
+ yyssp -= yylen;
+
+
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if YYERROR_VERBOSE
+ yyn = yypact[yystate];
+
+ if (YYPACT_NINF < yyn && yyn < YYLAST)
+ {
+ YYSIZE_T yysize = 0;
+ int yytype = YYTRANSLATE (yychar);
+ char *yymsg;
+ int yyx, yycount;
+
+ yycount = 0;
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ yysize += yystrlen (yytname[yyx]) + 15, yycount++;
+ yysize += yystrlen ("syntax error, unexpected ") + 1;
+ yysize += yystrlen (yytname[yytype]);
+ yymsg = (char *) YYSTACK_ALLOC (yysize);
+ if (yymsg != 0)
+ {
+ char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
+ yyp = yystpcpy (yyp, yytname[yytype]);
+
+ if (yycount < 5)
+ {
+ yycount = 0;
+ for (yyx = yyn < 0 ? -yyn : 0;
+ yyx < (int) (sizeof (yytname) / sizeof (char *));
+ yyx++)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ const char *yyq = ! yycount ? ", expecting " : " or ";
+ yyp = yystpcpy (yyp, yyq);
+ yyp = yystpcpy (yyp, yytname[yyx]);
+ yycount++;
+ }
+ }
+ yyerror (yymsg);
+ YYSTACK_FREE (yymsg);
+ }
+ else
+ yyerror ("syntax error; also virtual memory exhausted");
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror ("syntax error");
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ {
+ /* Pop the error token. */
+ YYPOPSTACK;
+ /* Pop the rest of the stack. */
+ while (yyss < yyssp)
+ {
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[*yyssp], yyvsp);
+ YYPOPSTACK;
+ }
+ YYABORT;
+ }
+
+ YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
+ yydestruct (yytoken, &yylval);
+ yychar = YYEMPTY;
+
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*----------------------------------------------------.
+| yyerrlab1 -- error raised explicitly by an action. |
+`----------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
+ yydestruct (yystos[yystate], yyvsp);
+ yyvsp--;
+ yystate = *--yyssp;
+
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ YYDPRINTF ((stderr, "Shifting error token, "));
+
+ *++yyvsp = yylval;
+
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*----------------------------------------------.
+| yyoverflowlab -- parser overflow comes here. |
+`----------------------------------------------*/
+yyoverflowlab:
+ yyerror ("parser stack overflow");
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+ return yyresult;
+}
+
+
+#line 444 "getdate.y"
+
+
+/* Include this file down here because bison inserts code above which
+ may define-away `const'. We want the prototype for get_date to have
+ the same signature as the function definition. */
+#include "modules/getdate.h"
+
+#ifndef gmtime
+struct tm *gmtime ();
+#endif
+#ifndef localtime
+struct tm *localtime ();
+#endif
+#ifndef mktime
+time_t mktime ();
+#endif
+
+static table const meridian_table[] =
+{
+ { "AM", tMERIDIAN, MERam },
+ { "A.M.", tMERIDIAN, MERam },
+ { "PM", tMERIDIAN, MERpm },
+ { "P.M.", tMERIDIAN, MERpm },
+ { 0, 0, 0 }
+};
+
+static table const dst_table[] =
+{
+ { "DST", tDST, 0 }
+};
+
+static table const month_and_day_table[] =
+{
+ { "JANUARY", tMONTH, 1 },
+ { "FEBRUARY", tMONTH, 2 },
+ { "MARCH", tMONTH, 3 },
+ { "APRIL", tMONTH, 4 },
+ { "MAY", tMONTH, 5 },
+ { "JUNE", tMONTH, 6 },
+ { "JULY", tMONTH, 7 },
+ { "AUGUST", tMONTH, 8 },
+ { "SEPTEMBER",tMONTH, 9 },
+ { "SEPT", tMONTH, 9 },
+ { "OCTOBER", tMONTH, 10 },
+ { "NOVEMBER", tMONTH, 11 },
+ { "DECEMBER", tMONTH, 12 },
+ { "SUNDAY", tDAY, 0 },
+ { "MONDAY", tDAY, 1 },
+ { "TUESDAY", tDAY, 2 },
+ { "TUES", tDAY, 2 },
+ { "WEDNESDAY",tDAY, 3 },
+ { "WEDNES", tDAY, 3 },
+ { "THURSDAY", tDAY, 4 },
+ { "THUR", tDAY, 4 },
+ { "THURS", tDAY, 4 },
+ { "FRIDAY", tDAY, 5 },
+ { "SATURDAY", tDAY, 6 },
+ { 0, 0, 0 }
+};
+
+static table const time_units_table[] =
+{
+ { "YEAR", tYEAR_UNIT, 1 },
+ { "MONTH", tMONTH_UNIT, 1 },
+ { "FORTNIGHT",tDAY_UNIT, 14 },
+ { "WEEK", tDAY_UNIT, 7 },
+ { "DAY", tDAY_UNIT, 1 },
+ { "HOUR", tHOUR_UNIT, 1 },
+ { "MINUTE", tMINUTE_UNIT, 1 },
+ { "MIN", tMINUTE_UNIT, 1 },
+ { "SECOND", tSEC_UNIT, 1 },
+ { "SEC", tSEC_UNIT, 1 },
+ { 0, 0, 0 }
+};
+
+/* Assorted relative-time words. */
+static table const relative_time_table[] =
+{
+ { "TOMORROW", tMINUTE_UNIT, 24 * 60 },
+ { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) },
+ { "TODAY", tMINUTE_UNIT, 0 },
+ { "NOW", tMINUTE_UNIT, 0 },
+ { "LAST", tUNUMBER, -1 },
+ { "THIS", tUNUMBER, 0 },
+ { "NEXT", tUNUMBER, 1 },
+ { "FIRST", tUNUMBER, 1 },
+/*{ "SECOND", tUNUMBER, 2 }, */
+ { "THIRD", tUNUMBER, 3 },
+ { "FOURTH", tUNUMBER, 4 },
+ { "FIFTH", tUNUMBER, 5 },
+ { "SIXTH", tUNUMBER, 6 },
+ { "SEVENTH", tUNUMBER, 7 },
+ { "EIGHTH", tUNUMBER, 8 },
+ { "NINTH", tUNUMBER, 9 },
+ { "TENTH", tUNUMBER, 10 },
+ { "ELEVENTH", tUNUMBER, 11 },
+ { "TWELFTH", tUNUMBER, 12 },
+ { "AGO", tAGO, 1 },
+ { 0, 0, 0 }
+};
+
+/* The time zone table. This table is necessarily incomplete, as time
+ zone abbreviations are ambiguous; e.g. Australians interpret "EST"
+ as Eastern time in Australia, not as US Eastern Standard Time.
+ You cannot rely on getdate to handle arbitrary time zone
+ abbreviations; use numeric abbreviations like `-0500' instead. */
+static table const time_zone_table[] =
+{
+ { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
+ { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
+ { "UTC", tZONE, HOUR ( 0) },
+ { "WET", tZONE, HOUR ( 0) }, /* Western European */
+ { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
+ { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
+ { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
+ { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
+ { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
+ { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
+ { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
+ { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
+ { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
+ { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
+ { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
+ { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
+ { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
+ { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
+ { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
+ { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
+ { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
+ { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
+ { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
+ { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
+ { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
+ { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
+ { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
+ { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
+ { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
+ { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
+ { "CET", tZONE, HOUR ( 1) }, /* Central European */
+ { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
+ { "MET", tZONE, HOUR ( 1) }, /* Middle European */
+ { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
+ { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
+ { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
+ { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
+ { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
+ { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
+ { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
+ { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
+ { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
+ { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
+ { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
+ { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
+ { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
+ { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
+ { "GST", tZONE, HOUR (10) }, /* Guam Standard */
+ { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
+ { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
+ { 0, 0, 0 }
+};
+
+/* Military time zone table. */
+static table const military_table[] =
+{
+ { "A", tZONE, -HOUR ( 1) },
+ { "B", tZONE, -HOUR ( 2) },
+ { "C", tZONE, -HOUR ( 3) },
+ { "D", tZONE, -HOUR ( 4) },
+ { "E", tZONE, -HOUR ( 5) },
+ { "F", tZONE, -HOUR ( 6) },
+ { "G", tZONE, -HOUR ( 7) },
+ { "H", tZONE, -HOUR ( 8) },
+ { "I", tZONE, -HOUR ( 9) },
+ { "K", tZONE, -HOUR (10) },
+ { "L", tZONE, -HOUR (11) },
+ { "M", tZONE, -HOUR (12) },
+ { "N", tZONE, HOUR ( 1) },
+ { "O", tZONE, HOUR ( 2) },
+ { "P", tZONE, HOUR ( 3) },
+ { "Q", tZONE, HOUR ( 4) },
+ { "R", tZONE, HOUR ( 5) },
+ { "S", tZONE, HOUR ( 6) },
+ { "T", tZONE, HOUR ( 7) },
+ { "U", tZONE, HOUR ( 8) },
+ { "V", tZONE, HOUR ( 9) },
+ { "W", tZONE, HOUR (10) },
+ { "X", tZONE, HOUR (11) },
+ { "Y", tZONE, HOUR (12) },
+ { "Z", tZONE, HOUR ( 0) },
+ { 0, 0, 0 }
+};
+
+
+
+static int
+to_hour (int hours, int meridian)
+{
+ switch (meridian)
+ {
+ case MER24:
+ return 0 <= hours && hours < 24 ? hours : -1;
+ case MERam:
+ return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
+ case MERpm:
+ return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
+ default:
+ abort ();
+ }
+ /* NOTREACHED */
+ return 0;
+}
+
+static int
+to_year (textint textyear)
+{
+ int year = textyear.value;
+
+ if (year < 0)
+ year = -year;
+
+ /* XPG4 suggests that years 00-68 map to 2000-2068, and
+ years 69-99 map to 1969-1999. */
+ if (textyear.digits == 2)
+ year += year < 69 ? 2000 : 1900;
+
+ return year;
+}
+
+static table const *
+lookup_zone (parser_control const *pc, char const *name)
+{
+ table const *tp;
+
+ /* Try local zone abbreviations first; they're more likely to be right. */
+ for (tp = pc->local_time_zone_table; tp->name; tp++)
+ if (strcmp (name, tp->name) == 0)
+ return tp;
+
+ for (tp = time_zone_table; tp->name; tp++)
+ if (strcmp (name, tp->name) == 0)
+ return tp;
+
+ return 0;
+}
+
+#if ! HAVE_TM_GMTOFF
+/* Yield the difference between *A and *B,
+ measured in seconds, ignoring leap seconds.
+ The body of this function is taken directly from the GNU C Library;
+ see src/strftime.c. */
+static int
+tm_diff (struct tm const *a, struct tm const *b)
+{
+ /* Compute intervening leap days correctly even if year is negative.
+ Take care to avoid int overflow in leap day calculations,
+ but it's OK to assume that A and B are close to each other. */
+ int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
+ int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+ int a100 = a4 / 25 - (a4 % 25 < 0);
+ int b100 = b4 / 25 - (b4 % 25 < 0);
+ int a400 = a100 >> 2;
+ int b400 = b100 >> 2;
+ int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+ int years = a->tm_year - b->tm_year;
+ int days = (365 * years + intervening_leap_days
+ + (a->tm_yday - b->tm_yday));
+ return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+ + (a->tm_min - b->tm_min))
+ + (a->tm_sec - b->tm_sec));
+}
+#endif /* ! HAVE_TM_GMTOFF */
+
+static table const *
+lookup_word (parser_control const *pc, char *word)
+{
+ char *p;
+ char *q;
+ size_t wordlen;
+ table const *tp;
+ int i;
+ int abbrev;
+
+ /* Make it uppercase. */
+ for (p = word; *p; p++)
+ if (ISLOWER ((unsigned char) *p))
+ *p = toupper ((unsigned char) *p);
+
+ for (tp = meridian_table; tp->name; tp++)
+ if (strcmp (word, tp->name) == 0)
+ return tp;
+
+ /* See if we have an abbreviation for a month. */
+ wordlen = strlen (word);
+ abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
+
+ for (tp = month_and_day_table; tp->name; tp++)
+ if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
+ return tp;
+
+ if ((tp = lookup_zone (pc, word)))
+ return tp;
+
+ if (strcmp (word, dst_table[0].name) == 0)
+ return dst_table;
+
+ for (tp = time_units_table; tp->name; tp++)
+ if (strcmp (word, tp->name) == 0)
+ return tp;
+
+ /* Strip off any plural and try the units table again. */
+ if (word[wordlen - 1] == 'S')
+ {
+ word[wordlen - 1] = '\0';
+ for (tp = time_units_table; tp->name; tp++)
+ if (strcmp (word, tp->name) == 0)
+ return tp;
+ word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
+ }
+
+ for (tp = relative_time_table; tp->name; tp++)
+ if (strcmp (word, tp->name) == 0)
+ return tp;
+
+ /* Military time zones. */
+ if (wordlen == 1)
+ for (tp = military_table; tp->name; tp++)
+ if (word[0] == tp->name[0])
+ return tp;
+
+ /* Drop out any periods and try the time zone table again. */
+ for (i = 0, p = q = word; (*p = *q); q++)
+ if (*q == '.')
+ i = 1;
+ else
+ p++;
+ if (i && (tp = lookup_zone (pc, word)))
+ return tp;
+
+ return 0;
+}
+
+static int
+yylex (YYSTYPE *lvalp, parser_control *pc)
+{
+ unsigned char c;
+ int count;
+
+ for (;;)
+ {
+ while (c = *pc->input, ISSPACE (c))
+ pc->input++;
+
+ if (ISDIGIT (c) || c == '-' || c == '+')
+ {
+ char const *p;
+ int sign;
+ int value;
+ if (c == '-' || c == '+')
+ {
+ sign = c == '-' ? -1 : 1;
+ c = *++pc->input;
+ if (! ISDIGIT (c))
+ /* skip the '-' sign */
+ continue;
+ }
+ else
+ sign = 0;
+ p = pc->input;
+ value = 0;
+ do
+ {
+ value = 10 * value + c - '0';
+ c = *++p;
+ }
+ while (ISDIGIT (c));
+ lvalp->textintval.value = sign < 0 ? -value : value;
+ lvalp->textintval.digits = p - pc->input;
+ pc->input = p;
+ return sign ? tSNUMBER : tUNUMBER;
+ }
+
+ if (ISALPHA (c))
+ {
+ char buff[20];
+ char *p = buff;
+ table const *tp;
+
+ do
+ {
+ if (p < buff + sizeof buff - 1)
+ *p++ = c;
+ c = *++pc->input;
+ }
+ while (ISALPHA (c) || c == '.');
+
+ *p = '\0';
+ tp = lookup_word (pc, buff);
+ if (! tp)
+ return '?';
+ lvalp->intval = tp->value;
+ return tp->type;
+ }
+
+ if (c != '(')
+ return *pc->input++;
+ count = 0;
+ do
+ {
+ c = *pc->input++;
+ if (c == '\0')
+ return c;
+ if (c == '(')
+ count++;
+ else if (c == ')')
+ count--;
+ }
+ while (count > 0);
+ }
+}
+
+/* Do nothing if the parser reports an error. */
+static int
+yyerror (char *s ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Parse a date/time string P. Return the corresponding time_t value,
+ or (time_t) -1 if there is an error. P can be an incomplete or
+ relative time specification; if so, use *NOW as the basis for the
+ returned time. */
+time_t
+get_date (const char *p, const time_t *now)
+{
+ time_t Start = now ? *now : time (0);
+ struct tm *tmp = localtime (&Start);
+ struct tm tm;
+ struct tm tm0;
+ parser_control pc;
+
+ if (! tmp)
+ return -1;
+
+ pc.input = p;
+ pc.year.value = tmp->tm_year + TM_YEAR_BASE;
+ pc.year.digits = 4;
+ pc.month = tmp->tm_mon + 1;
+ pc.day = tmp->tm_mday;
+ pc.hour = tmp->tm_hour;
+ pc.minutes = tmp->tm_min;
+ pc.seconds = tmp->tm_sec;
+ tm.tm_isdst = tmp->tm_isdst;
+
+ pc.meridian = MER24;
+ pc.rel_seconds = 0;
+ pc.rel_minutes = 0;
+ pc.rel_hour = 0;
+ pc.rel_day = 0;
+ pc.rel_month = 0;
+ pc.rel_year = 0;
+ pc.dates_seen = 0;
+ pc.days_seen = 0;
+ pc.rels_seen = 0;
+ pc.times_seen = 0;
+ pc.local_zones_seen = 0;
+ pc.zones_seen = 0;
+
+#if HAVE_STRUCT_TM_TM_ZONE
+ pc.local_time_zone_table[0].name = tmp->tm_zone;
+ pc.local_time_zone_table[0].type = tLOCAL_ZONE;
+ pc.local_time_zone_table[0].value = tmp->tm_isdst;
+ pc.local_time_zone_table[1].name = 0;
+
+ /* Probe the names used in the next three calendar quarters, looking
+ for a tm_isdst different from the one we already have. */
+ {
+ int quarter;
+ for (quarter = 1; quarter <= 3; quarter++)
+ {
+ time_t probe = Start + quarter * (90 * 24 * 60 * 60);
+ struct tm *probe_tm = localtime (&probe);
+ if (probe_tm && probe_tm->tm_zone
+ && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
+ {
+ {
+ pc.local_time_zone_table[1].name = probe_tm->tm_zone;
+ pc.local_time_zone_table[1].type = tLOCAL_ZONE;
+ pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
+ pc.local_time_zone_table[2].name = 0;
+ }
+ break;
+ }
+ }
+ }
+#else
+#if HAVE_TZNAME
+ {
+# ifndef tzname
+ extern char *tzname[];
+# endif
+ int i;
+ for (i = 0; i < 2; i++)
+ {
+ pc.local_time_zone_table[i].name = tzname[i];
+ pc.local_time_zone_table[i].type = tLOCAL_ZONE;
+ pc.local_time_zone_table[i].value = i;
+ }
+ pc.local_time_zone_table[i].name = 0;
+ }
+#else
+ pc.local_time_zone_table[0].name = 0;
+#endif
+#endif
+
+ if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
+ && ! strcmp (pc.local_time_zone_table[0].name,
+ pc.local_time_zone_table[1].name))
+ {
+ /* This locale uses the same abbrevation for standard and
+ daylight times. So if we see that abbreviation, we don't
+ know whether it's daylight time. */
+ pc.local_time_zone_table[0].value = -1;
+ pc.local_time_zone_table[1].name = 0;
+ }
+
+ if (yyparse (&pc) != 0
+ || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
+ || 1 < (pc.local_zones_seen + pc.zones_seen)
+ || (pc.local_zones_seen && 1 < pc.local_isdst))
+ return -1;
+
+ tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
+ tm.tm_mon = pc.month - 1 + pc.rel_month;
+ tm.tm_mday = pc.day + pc.rel_day;
+ if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
+ {
+ tm.tm_hour = to_hour (pc.hour, pc.meridian);
+ if (tm.tm_hour < 0)
+ return -1;
+ tm.tm_min = pc.minutes;
+ tm.tm_sec = pc.seconds;
+ }
+ else
+ {
+ tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+ }
+
+ /* Let mktime deduce tm_isdst if we have an absolute time stamp,
+ or if the relative time stamp mentions days, months, or years. */
+ if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
+ | pc.rel_month | pc.rel_year)
+ tm.tm_isdst = -1;
+
+ /* But if the input explicitly specifies local time with or without
+ DST, give mktime that information. */
+ if (pc.local_zones_seen)
+ tm.tm_isdst = pc.local_isdst;
+
+ tm0 = tm;
+
+ Start = mktime (&tm);
+
+ if (Start == (time_t) -1)
+ {
+
+ /* Guard against falsely reporting errors near the time_t boundaries
+ when parsing times in other time zones. For example, if the min
+ time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
+ of UTC, then the min localtime value is 1970-01-01 08:00:00; if
+ we apply mktime to 1970-01-01 00:00:00 we will get an error, so
+ we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
+ zone by 24 hours to compensate. This algorithm assumes that
+ there is no DST transition within a day of the time_t boundaries. */
+ if (pc.zones_seen)
+ {
+ tm = tm0;
+ if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
+ {
+ tm.tm_mday++;
+ pc.time_zone += 24 * 60;
+ }
+ else
+ {
+ tm.tm_mday--;
+ pc.time_zone -= 24 * 60;
+ }
+ Start = mktime (&tm);
+ }
+
+ if (Start == (time_t) -1)
+ return Start;
+ }
+
+ if (pc.days_seen && ! pc.dates_seen)
+ {
+ tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
+ + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
+ tm.tm_isdst = -1;
+ Start = mktime (&tm);
+ if (Start == (time_t) -1)
+ return Start;
+ }
+
+ if (pc.zones_seen)
+ {
+ int delta = pc.time_zone * 60;
+#ifdef HAVE_TM_GMTOFF
+ delta -= tm.tm_gmtoff;
+#else
+ struct tm *gmt = gmtime (&Start);
+ if (! gmt)
+ return -1;
+ delta -= tm_diff (&tm, gmt);
+#endif
+ if ((Start < Start - delta) != (delta < 0))
+ return -1; /* time_t overflow */
+ Start -= delta;
+ }
+
+ /* Add relative hours, minutes, and seconds. Ignore leap seconds;
+ i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
+ leap second. Typically this is not what the user wants, but it's
+ too hard to do it the other way, because the time zone indicator
+ must be applied before relative times, and if mktime is applied
+ again the time zone will be lost. */
+ {
+ time_t t0 = Start;
+ long d1 = 60 * 60 * (long) pc.rel_hour;
+ time_t t1 = t0 + d1;
+ long d2 = 60 * (long) pc.rel_minutes;
+ time_t t2 = t1 + d2;
+ int d3 = pc.rel_seconds;
+ time_t t3 = t2 + d3;
+ if ((d1 / (60 * 60) ^ pc.rel_hour)
+ | (d2 / 60 ^ pc.rel_minutes)
+ | ((t0 + d1 < t0) ^ (d1 < 0))
+ | ((t1 + d2 < t1) ^ (d2 < 0))
+ | ((t2 + d3 < t2) ^ (d3 < 0)))
+ return -1;
+ Start = t3;
+ }
+
+ return Start;
+}
+
+#if TEST
+
+#include <stdio.h>
+
+int
+main (int ac, char **av)
+{
+ char buff[BUFSIZ];
+ time_t d;
+
+ printf ("Enter date, or blank line to exit.\n\t> ");
+ fflush (stdout);
+
+ buff[BUFSIZ - 1] = 0;
+ while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
+ {
+ d = get_date (buff, 0);
+ if (d == (time_t) -1)
+ printf ("Bad format - couldn't convert.\n");
+ else
+ printf ("%s", ctime (&d));
+ printf ("\t> ");
+ fflush (stdout);
+ }
+ return 0;
+}
+#endif /* defined TEST */
+
+
diff --git a/source/modules/getdate.h b/source/modules/getdate.h
new file mode 100644
index 00000000000..674c474f115
--- /dev/null
+++ b/source/modules/getdate.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
+
+ 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, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef PARAMS
+# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
+# define PARAMS(Args) Args
+# else
+# define PARAMS(Args) ()
+# endif
+#endif
+
+#ifdef vms
+# include <types.h>
+# include <time.h>
+#else
+# include <sys/types.h>
+# if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+# else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+# endif
+#endif /* defined (vms) */
+
+time_t get_date PARAMS ((const char *p, const time_t *now));
diff --git a/source/modules/getdate.y b/source/modules/getdate.y
new file mode 100644
index 00000000000..aab37f4d235
--- /dev/null
+++ b/source/modules/getdate.y
@@ -0,0 +1,1115 @@
+%{
+/* Parse a string into an internal time stamp.
+ Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+
+ 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, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Originally written by Steven M. Bellovin <smb@research.att.com> while
+ at the University of North Carolina at Chapel Hill. Later tweaked by
+ a couple of people on Usenet. Completely overhauled by Rich $alz
+ <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
+
+ Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
+ the right thing about local DST. Unlike previous versions, this
+ version is reentrant. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+# ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+# endif
+#endif
+
+/* Since the code of getdate.y is not included in the Emacs executable
+ itself, there is no need to #define static in this file. Even if
+ the code were included in the Emacs executable, it probably
+ wouldn't do any harm to #undef it here; this will only cause
+ problems if we try to write to a static variable, which I don't
+ think this code needs to do. */
+#ifdef emacs
+# undef static
+#endif
+
+#include <ctype.h>
+
+#if HAVE_STDLIB_H
+# include <stdlib.h> /* for `free'; used by Bison 1.27 */
+#endif
+
+#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
+# define IN_CTYPE_DOMAIN(c) 1
+#else
+# define IN_CTYPE_DOMAIN(c) isascii (c)
+#endif
+
+#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
+#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
+#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
+#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
+
+/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
+ - Its arg may be any int or unsigned int; it need not be an unsigned char.
+ - It's guaranteed to evaluate its argument exactly once.
+ - It's typically faster.
+ POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
+ ISDIGIT_LOCALE unless it's important to use the locale's definition
+ of `digit' even when the host does not conform to POSIX. */
+#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
+
+#if STDC_HEADERS || HAVE_STRING_H
+# include <string.h>
+#endif
+
+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
+# define __attribute__(x)
+#endif
+
+#ifndef ATTRIBUTE_UNUSED
+# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
+#endif
+
+#define EPOCH_YEAR 1970
+#define TM_YEAR_BASE 1900
+
+#define HOUR(x) ((x) * 60)
+
+/* An integer value, and the number of digits in its textual
+ representation. */
+typedef struct
+{
+ int value;
+ int digits;
+} textint;
+
+/* An entry in the lexical lookup table. */
+typedef struct
+{
+ char const *name;
+ int type;
+ int value;
+} table;
+
+/* Meridian: am, pm, or 24-hour style. */
+enum { MERam, MERpm, MER24 };
+
+/* Information passed to and from the parser. */
+typedef struct
+{
+ /* The input string remaining to be parsed. */
+ const char *input;
+
+ /* N, if this is the Nth Tuesday. */
+ int day_ordinal;
+
+ /* Day of week; Sunday is 0. */
+ int day_number;
+
+ /* tm_isdst flag for the local zone. */
+ int local_isdst;
+
+ /* Time zone, in minutes east of UTC. */
+ int time_zone;
+
+ /* Style used for time. */
+ int meridian;
+
+ /* Gregorian year, month, day, hour, minutes, and seconds. */
+ textint year;
+ int month;
+ int day;
+ int hour;
+ int minutes;
+ int seconds;
+
+ /* Relative year, month, day, hour, minutes, and seconds. */
+ int rel_year;
+ int rel_month;
+ int rel_day;
+ int rel_hour;
+ int rel_minutes;
+ int rel_seconds;
+
+ /* Counts of nonterminals of various flavors parsed so far. */
+ int dates_seen;
+ int days_seen;
+ int local_zones_seen;
+ int rels_seen;
+ int times_seen;
+ int zones_seen;
+
+ /* Table of local time zone abbrevations, terminated by a null entry. */
+ table local_time_zone_table[3];
+} parser_control;
+
+#define PC (* (parser_control *) parm)
+#define YYLEX_PARAM parm
+#define YYPARSE_PARAM parm
+
+static int yyerror ();
+static int yylex ();
+
+%}
+
+/* We want a reentrant parser. */
+%pure_parser
+
+/* This grammar has 13 shift/reduce conflicts. */
+%expect 13
+
+%union
+{
+ int intval;
+ textint textintval;
+}
+
+%token tAGO tDST
+
+%token <intval> tDAY tDAY_UNIT tDAYZONE tHOUR_UNIT tLOCAL_ZONE tMERIDIAN
+%token <intval> tMINUTE_UNIT tMONTH tMONTH_UNIT tSEC_UNIT tYEAR_UNIT tZONE
+
+%token <textintval> tSNUMBER tUNUMBER
+
+%type <intval> o_merid
+
+%%
+
+spec:
+ /* empty */
+ | spec item
+ ;
+
+item:
+ time
+ { PC.times_seen++; }
+ | local_zone
+ { PC.local_zones_seen++; }
+ | zone
+ { PC.zones_seen++; }
+ | date
+ { PC.dates_seen++; }
+ | day
+ { PC.days_seen++; }
+ | rel
+ { PC.rels_seen++; }
+ | number
+ ;
+
+time:
+ tUNUMBER tMERIDIAN
+ {
+ PC.hour = $1.value;
+ PC.minutes = 0;
+ PC.seconds = 0;
+ PC.meridian = $2;
+ }
+ | tUNUMBER ':' tUNUMBER o_merid
+ {
+ PC.hour = $1.value;
+ PC.minutes = $3.value;
+ PC.seconds = 0;
+ PC.meridian = $4;
+ }
+ | tUNUMBER ':' tUNUMBER tSNUMBER
+ {
+ PC.hour = $1.value;
+ PC.minutes = $3.value;
+ PC.meridian = MER24;
+ PC.zones_seen++;
+ PC.time_zone = $4.value % 100 + ($4.value / 100) * 60;
+ }
+ | tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid
+ {
+ PC.hour = $1.value;
+ PC.minutes = $3.value;
+ PC.seconds = $5.value;
+ PC.meridian = $6;
+ }
+ | tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER
+ {
+ PC.hour = $1.value;
+ PC.minutes = $3.value;
+ PC.seconds = $5.value;
+ PC.meridian = MER24;
+ PC.zones_seen++;
+ PC.time_zone = $6.value % 100 + ($6.value / 100) * 60;
+ }
+ ;
+
+local_zone:
+ tLOCAL_ZONE
+ { PC.local_isdst = $1; }
+ | tLOCAL_ZONE tDST
+ { PC.local_isdst = $1 < 0 ? 1 : $1 + 1; }
+ ;
+
+zone:
+ tZONE
+ { PC.time_zone = $1; }
+ | tDAYZONE
+ { PC.time_zone = $1 + 60; }
+ | tZONE tDST
+ { PC.time_zone = $1 + 60; }
+ ;
+
+day:
+ tDAY
+ {
+ PC.day_ordinal = 1;
+ PC.day_number = $1;
+ }
+ | tDAY ','
+ {
+ PC.day_ordinal = 1;
+ PC.day_number = $1;
+ }
+ | tUNUMBER tDAY
+ {
+ PC.day_ordinal = $1.value;
+ PC.day_number = $2;
+ }
+ ;
+
+date:
+ tUNUMBER '/' tUNUMBER
+ {
+ PC.month = $1.value;
+ PC.day = $3.value;
+ }
+ | tUNUMBER '/' tUNUMBER '/' tUNUMBER
+ {
+ /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
+ otherwise as MM/DD/YY.
+ The goal in recognizing YYYY/MM/DD is solely to support legacy
+ machine-generated dates like those in an RCS log listing. If
+ you want portability, use the ISO 8601 format. */
+ if (4 <= $1.digits)
+ {
+ PC.year = $1;
+ PC.month = $3.value;
+ PC.day = $5.value;
+ }
+ else
+ {
+ PC.month = $1.value;
+ PC.day = $3.value;
+ PC.year = $5;
+ }
+ }
+ | tUNUMBER tSNUMBER tSNUMBER
+ {
+ /* ISO 8601 format. YYYY-MM-DD. */
+ PC.year = $1;
+ PC.month = -$2.value;
+ PC.day = -$3.value;
+ }
+ | tUNUMBER tMONTH tSNUMBER
+ {
+ /* e.g. 17-JUN-1992. */
+ PC.day = $1.value;
+ PC.month = $2;
+ PC.year.value = -$3.value;
+ PC.year.digits = $3.digits;
+ }
+ | tMONTH tUNUMBER
+ {
+ PC.month = $1;
+ PC.day = $2.value;
+ }
+ | tMONTH tUNUMBER ',' tUNUMBER
+ {
+ PC.month = $1;
+ PC.day = $2.value;
+ PC.year = $4;
+ }
+ | tUNUMBER tMONTH
+ {
+ PC.day = $1.value;
+ PC.month = $2;
+ }
+ | tUNUMBER tMONTH tUNUMBER
+ {
+ PC.day = $1.value;
+ PC.month = $2;
+ PC.year = $3;
+ }
+ ;
+
+rel:
+ relunit tAGO
+ {
+ PC.rel_seconds = -PC.rel_seconds;
+ PC.rel_minutes = -PC.rel_minutes;
+ PC.rel_hour = -PC.rel_hour;
+ PC.rel_day = -PC.rel_day;
+ PC.rel_month = -PC.rel_month;
+ PC.rel_year = -PC.rel_year;
+ }
+ | relunit
+ ;
+
+relunit:
+ tUNUMBER tYEAR_UNIT
+ { PC.rel_year += $1.value * $2; }
+ | tSNUMBER tYEAR_UNIT
+ { PC.rel_year += $1.value * $2; }
+ | tYEAR_UNIT
+ { PC.rel_year += $1; }
+ | tUNUMBER tMONTH_UNIT
+ { PC.rel_month += $1.value * $2; }
+ | tSNUMBER tMONTH_UNIT
+ { PC.rel_month += $1.value * $2; }
+ | tMONTH_UNIT
+ { PC.rel_month += $1; }
+ | tUNUMBER tDAY_UNIT
+ { PC.rel_day += $1.value * $2; }
+ | tSNUMBER tDAY_UNIT
+ { PC.rel_day += $1.value * $2; }
+ | tDAY_UNIT
+ { PC.rel_day += $1; }
+ | tUNUMBER tHOUR_UNIT
+ { PC.rel_hour += $1.value * $2; }
+ | tSNUMBER tHOUR_UNIT
+ { PC.rel_hour += $1.value * $2; }
+ | tHOUR_UNIT
+ { PC.rel_hour += $1; }
+ | tUNUMBER tMINUTE_UNIT
+ { PC.rel_minutes += $1.value * $2; }
+ | tSNUMBER tMINUTE_UNIT
+ { PC.rel_minutes += $1.value * $2; }
+ | tMINUTE_UNIT
+ { PC.rel_minutes += $1; }
+ | tUNUMBER tSEC_UNIT
+ { PC.rel_seconds += $1.value * $2; }
+ | tSNUMBER tSEC_UNIT
+ { PC.rel_seconds += $1.value * $2; }
+ | tSEC_UNIT
+ { PC.rel_seconds += $1; }
+ ;
+
+number:
+ tUNUMBER
+ {
+ if (PC.dates_seen
+ && ! PC.rels_seen && (PC.times_seen || 2 < $1.digits))
+ PC.year = $1;
+ else
+ {
+ if (4 < $1.digits)
+ {
+ PC.dates_seen++;
+ PC.day = $1.value % 100;
+ PC.month = ($1.value / 100) % 100;
+ PC.year.value = $1.value / 10000;
+ PC.year.digits = $1.digits - 4;
+ }
+ else
+ {
+ PC.times_seen++;
+ if ($1.digits <= 2)
+ {
+ PC.hour = $1.value;
+ PC.minutes = 0;
+ }
+ else
+ {
+ PC.hour = $1.value / 100;
+ PC.minutes = $1.value % 100;
+ }
+ PC.seconds = 0;
+ PC.meridian = MER24;
+ }
+ }
+ }
+ ;
+
+o_merid:
+ /* empty */
+ { $$ = MER24; }
+ | tMERIDIAN
+ { $$ = $1; }
+ ;
+
+%%
+
+/* Include this file down here because bison inserts code above which
+ may define-away `const'. We want the prototype for get_date to have
+ the same signature as the function definition. */
+#include "modules/getdate.h"
+
+#ifndef gmtime
+struct tm *gmtime ();
+#endif
+#ifndef localtime
+struct tm *localtime ();
+#endif
+#ifndef mktime
+time_t mktime ();
+#endif
+
+static table const meridian_table[] =
+{
+ { "AM", tMERIDIAN, MERam },
+ { "A.M.", tMERIDIAN, MERam },
+ { "PM", tMERIDIAN, MERpm },
+ { "P.M.", tMERIDIAN, MERpm },
+ { 0, 0, 0 }
+};
+
+static table const dst_table[] =
+{
+ { "DST", tDST, 0 }
+};
+
+static table const month_and_day_table[] =
+{
+ { "JANUARY", tMONTH, 1 },
+ { "FEBRUARY", tMONTH, 2 },
+ { "MARCH", tMONTH, 3 },
+ { "APRIL", tMONTH, 4 },
+ { "MAY", tMONTH, 5 },
+ { "JUNE", tMONTH, 6 },
+ { "JULY", tMONTH, 7 },
+ { "AUGUST", tMONTH, 8 },
+ { "SEPTEMBER",tMONTH, 9 },
+ { "SEPT", tMONTH, 9 },
+ { "OCTOBER", tMONTH, 10 },
+ { "NOVEMBER", tMONTH, 11 },
+ { "DECEMBER", tMONTH, 12 },
+ { "SUNDAY", tDAY, 0 },
+ { "MONDAY", tDAY, 1 },
+ { "TUESDAY", tDAY, 2 },
+ { "TUES", tDAY, 2 },
+ { "WEDNESDAY",tDAY, 3 },
+ { "WEDNES", tDAY, 3 },
+ { "THURSDAY", tDAY, 4 },
+ { "THUR", tDAY, 4 },
+ { "THURS", tDAY, 4 },
+ { "FRIDAY", tDAY, 5 },
+ { "SATURDAY", tDAY, 6 },
+ { 0, 0, 0 }
+};
+
+static table const time_units_table[] =
+{
+ { "YEAR", tYEAR_UNIT, 1 },
+ { "MONTH", tMONTH_UNIT, 1 },
+ { "FORTNIGHT",tDAY_UNIT, 14 },
+ { "WEEK", tDAY_UNIT, 7 },
+ { "DAY", tDAY_UNIT, 1 },
+ { "HOUR", tHOUR_UNIT, 1 },
+ { "MINUTE", tMINUTE_UNIT, 1 },
+ { "MIN", tMINUTE_UNIT, 1 },
+ { "SECOND", tSEC_UNIT, 1 },
+ { "SEC", tSEC_UNIT, 1 },
+ { 0, 0, 0 }
+};
+
+/* Assorted relative-time words. */
+static table const relative_time_table[] =
+{
+ { "TOMORROW", tMINUTE_UNIT, 24 * 60 },
+ { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) },
+ { "TODAY", tMINUTE_UNIT, 0 },
+ { "NOW", tMINUTE_UNIT, 0 },
+ { "LAST", tUNUMBER, -1 },
+ { "THIS", tUNUMBER, 0 },
+ { "NEXT", tUNUMBER, 1 },
+ { "FIRST", tUNUMBER, 1 },
+/*{ "SECOND", tUNUMBER, 2 }, */
+ { "THIRD", tUNUMBER, 3 },
+ { "FOURTH", tUNUMBER, 4 },
+ { "FIFTH", tUNUMBER, 5 },
+ { "SIXTH", tUNUMBER, 6 },
+ { "SEVENTH", tUNUMBER, 7 },
+ { "EIGHTH", tUNUMBER, 8 },
+ { "NINTH", tUNUMBER, 9 },
+ { "TENTH", tUNUMBER, 10 },
+ { "ELEVENTH", tUNUMBER, 11 },
+ { "TWELFTH", tUNUMBER, 12 },
+ { "AGO", tAGO, 1 },
+ { 0, 0, 0 }
+};
+
+/* The time zone table. This table is necessarily incomplete, as time
+ zone abbreviations are ambiguous; e.g. Australians interpret "EST"
+ as Eastern time in Australia, not as US Eastern Standard Time.
+ You cannot rely on getdate to handle arbitrary time zone
+ abbreviations; use numeric abbreviations like `-0500' instead. */
+static table const time_zone_table[] =
+{
+ { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
+ { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
+ { "UTC", tZONE, HOUR ( 0) },
+ { "WET", tZONE, HOUR ( 0) }, /* Western European */
+ { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
+ { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
+ { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
+ { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
+ { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
+ { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
+ { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
+ { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
+ { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
+ { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
+ { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
+ { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
+ { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
+ { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
+ { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
+ { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
+ { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
+ { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
+ { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
+ { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
+ { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
+ { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
+ { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
+ { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
+ { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
+ { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
+ { "CET", tZONE, HOUR ( 1) }, /* Central European */
+ { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
+ { "MET", tZONE, HOUR ( 1) }, /* Middle European */
+ { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
+ { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
+ { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
+ { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
+ { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
+ { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
+ { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
+ { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
+ { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
+ { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
+ { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
+ { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
+ { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
+ { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
+ { "GST", tZONE, HOUR (10) }, /* Guam Standard */
+ { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
+ { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
+ { 0, 0, 0 }
+};
+
+/* Military time zone table. */
+static table const military_table[] =
+{
+ { "A", tZONE, -HOUR ( 1) },
+ { "B", tZONE, -HOUR ( 2) },
+ { "C", tZONE, -HOUR ( 3) },
+ { "D", tZONE, -HOUR ( 4) },
+ { "E", tZONE, -HOUR ( 5) },
+ { "F", tZONE, -HOUR ( 6) },
+ { "G", tZONE, -HOUR ( 7) },
+ { "H", tZONE, -HOUR ( 8) },
+ { "I", tZONE, -HOUR ( 9) },
+ { "K", tZONE, -HOUR (10) },
+ { "L", tZONE, -HOUR (11) },
+ { "M", tZONE, -HOUR (12) },
+ { "N", tZONE, HOUR ( 1) },
+ { "O", tZONE, HOUR ( 2) },
+ { "P", tZONE, HOUR ( 3) },
+ { "Q", tZONE, HOUR ( 4) },
+ { "R", tZONE, HOUR ( 5) },
+ { "S", tZONE, HOUR ( 6) },
+ { "T", tZONE, HOUR ( 7) },
+ { "U", tZONE, HOUR ( 8) },
+ { "V", tZONE, HOUR ( 9) },
+ { "W", tZONE, HOUR (10) },
+ { "X", tZONE, HOUR (11) },
+ { "Y", tZONE, HOUR (12) },
+ { "Z", tZONE, HOUR ( 0) },
+ { 0, 0, 0 }
+};
+
+
+
+static int
+to_hour (int hours, int meridian)
+{
+ switch (meridian)
+ {
+ case MER24:
+ return 0 <= hours && hours < 24 ? hours : -1;
+ case MERam:
+ return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
+ case MERpm:
+ return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
+ default:
+ abort ();
+ }
+ /* NOTREACHED */
+ return 0;
+}
+
+static int
+to_year (textint textyear)
+{
+ int year = textyear.value;
+
+ if (year < 0)
+ year = -year;
+
+ /* XPG4 suggests that years 00-68 map to 2000-2068, and
+ years 69-99 map to 1969-1999. */
+ if (textyear.digits == 2)
+ year += year < 69 ? 2000 : 1900;
+
+ return year;
+}
+
+static table const *
+lookup_zone (parser_control const *pc, char const *name)
+{
+ table const *tp;
+
+ /* Try local zone abbreviations first; they're more likely to be right. */
+ for (tp = pc->local_time_zone_table; tp->name; tp++)
+ if (strcmp (name, tp->name) == 0)
+ return tp;
+
+ for (tp = time_zone_table; tp->name; tp++)
+ if (strcmp (name, tp->name) == 0)
+ return tp;
+
+ return 0;
+}
+
+#if ! HAVE_TM_GMTOFF
+/* Yield the difference between *A and *B,
+ measured in seconds, ignoring leap seconds.
+ The body of this function is taken directly from the GNU C Library;
+ see src/strftime.c. */
+static int
+tm_diff (struct tm const *a, struct tm const *b)
+{
+ /* Compute intervening leap days correctly even if year is negative.
+ Take care to avoid int overflow in leap day calculations,
+ but it's OK to assume that A and B are close to each other. */
+ int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
+ int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
+ int a100 = a4 / 25 - (a4 % 25 < 0);
+ int b100 = b4 / 25 - (b4 % 25 < 0);
+ int a400 = a100 >> 2;
+ int b400 = b100 >> 2;
+ int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+ int years = a->tm_year - b->tm_year;
+ int days = (365 * years + intervening_leap_days
+ + (a->tm_yday - b->tm_yday));
+ return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+ + (a->tm_min - b->tm_min))
+ + (a->tm_sec - b->tm_sec));
+}
+#endif /* ! HAVE_TM_GMTOFF */
+
+static table const *
+lookup_word (parser_control const *pc, char *word)
+{
+ char *p;
+ char *q;
+ size_t wordlen;
+ table const *tp;
+ int i;
+ int abbrev;
+
+ /* Make it uppercase. */
+ for (p = word; *p; p++)
+ if (ISLOWER ((unsigned char) *p))
+ *p = toupper ((unsigned char) *p);
+
+ for (tp = meridian_table; tp->name; tp++)
+ if (strcmp (word, tp->name) == 0)
+ return tp;
+
+ /* See if we have an abbreviation for a month. */
+ wordlen = strlen (word);
+ abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
+
+ for (tp = month_and_day_table; tp->name; tp++)
+ if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
+ return tp;
+
+ if ((tp = lookup_zone (pc, word)))
+ return tp;
+
+ if (strcmp (word, dst_table[0].name) == 0)
+ return dst_table;
+
+ for (tp = time_units_table; tp->name; tp++)
+ if (strcmp (word, tp->name) == 0)
+ return tp;
+
+ /* Strip off any plural and try the units table again. */
+ if (word[wordlen - 1] == 'S')
+ {
+ word[wordlen - 1] = '\0';
+ for (tp = time_units_table; tp->name; tp++)
+ if (strcmp (word, tp->name) == 0)
+ return tp;
+ word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
+ }
+
+ for (tp = relative_time_table; tp->name; tp++)
+ if (strcmp (word, tp->name) == 0)
+ return tp;
+
+ /* Military time zones. */
+ if (wordlen == 1)
+ for (tp = military_table; tp->name; tp++)
+ if (word[0] == tp->name[0])
+ return tp;
+
+ /* Drop out any periods and try the time zone table again. */
+ for (i = 0, p = q = word; (*p = *q); q++)
+ if (*q == '.')
+ i = 1;
+ else
+ p++;
+ if (i && (tp = lookup_zone (pc, word)))
+ return tp;
+
+ return 0;
+}
+
+static int
+yylex (YYSTYPE *lvalp, parser_control *pc)
+{
+ unsigned char c;
+ int count;
+
+ for (;;)
+ {
+ while (c = *pc->input, ISSPACE (c))
+ pc->input++;
+
+ if (ISDIGIT (c) || c == '-' || c == '+')
+ {
+ char const *p;
+ int sign;
+ int value;
+ if (c == '-' || c == '+')
+ {
+ sign = c == '-' ? -1 : 1;
+ c = *++pc->input;
+ if (! ISDIGIT (c))
+ /* skip the '-' sign */
+ continue;
+ }
+ else
+ sign = 0;
+ p = pc->input;
+ value = 0;
+ do
+ {
+ value = 10 * value + c - '0';
+ c = *++p;
+ }
+ while (ISDIGIT (c));
+ lvalp->textintval.value = sign < 0 ? -value : value;
+ lvalp->textintval.digits = p - pc->input;
+ pc->input = p;
+ return sign ? tSNUMBER : tUNUMBER;
+ }
+
+ if (ISALPHA (c))
+ {
+ char buff[20];
+ char *p = buff;
+ table const *tp;
+
+ do
+ {
+ if (p < buff + sizeof buff - 1)
+ *p++ = c;
+ c = *++pc->input;
+ }
+ while (ISALPHA (c) || c == '.');
+
+ *p = '\0';
+ tp = lookup_word (pc, buff);
+ if (! tp)
+ return '?';
+ lvalp->intval = tp->value;
+ return tp->type;
+ }
+
+ if (c != '(')
+ return *pc->input++;
+ count = 0;
+ do
+ {
+ c = *pc->input++;
+ if (c == '\0')
+ return c;
+ if (c == '(')
+ count++;
+ else if (c == ')')
+ count--;
+ }
+ while (count > 0);
+ }
+}
+
+/* Do nothing if the parser reports an error. */
+static int
+yyerror (char *s ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+/* Parse a date/time string P. Return the corresponding time_t value,
+ or (time_t) -1 if there is an error. P can be an incomplete or
+ relative time specification; if so, use *NOW as the basis for the
+ returned time. */
+time_t
+get_date (const char *p, const time_t *now)
+{
+ time_t Start = now ? *now : time (0);
+ struct tm *tmp = localtime (&Start);
+ struct tm tm;
+ struct tm tm0;
+ parser_control pc;
+
+ if (! tmp)
+ return -1;
+
+ pc.input = p;
+ pc.year.value = tmp->tm_year + TM_YEAR_BASE;
+ pc.year.digits = 4;
+ pc.month = tmp->tm_mon + 1;
+ pc.day = tmp->tm_mday;
+ pc.hour = tmp->tm_hour;
+ pc.minutes = tmp->tm_min;
+ pc.seconds = tmp->tm_sec;
+ tm.tm_isdst = tmp->tm_isdst;
+
+ pc.meridian = MER24;
+ pc.rel_seconds = 0;
+ pc.rel_minutes = 0;
+ pc.rel_hour = 0;
+ pc.rel_day = 0;
+ pc.rel_month = 0;
+ pc.rel_year = 0;
+ pc.dates_seen = 0;
+ pc.days_seen = 0;
+ pc.rels_seen = 0;
+ pc.times_seen = 0;
+ pc.local_zones_seen = 0;
+ pc.zones_seen = 0;
+
+#if HAVE_STRUCT_TM_TM_ZONE
+ pc.local_time_zone_table[0].name = tmp->tm_zone;
+ pc.local_time_zone_table[0].type = tLOCAL_ZONE;
+ pc.local_time_zone_table[0].value = tmp->tm_isdst;
+ pc.local_time_zone_table[1].name = 0;
+
+ /* Probe the names used in the next three calendar quarters, looking
+ for a tm_isdst different from the one we already have. */
+ {
+ int quarter;
+ for (quarter = 1; quarter <= 3; quarter++)
+ {
+ time_t probe = Start + quarter * (90 * 24 * 60 * 60);
+ struct tm *probe_tm = localtime (&probe);
+ if (probe_tm && probe_tm->tm_zone
+ && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
+ {
+ {
+ pc.local_time_zone_table[1].name = probe_tm->tm_zone;
+ pc.local_time_zone_table[1].type = tLOCAL_ZONE;
+ pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
+ pc.local_time_zone_table[2].name = 0;
+ }
+ break;
+ }
+ }
+ }
+#else
+#if HAVE_TZNAME
+ {
+# ifndef tzname
+ extern char *tzname[];
+# endif
+ int i;
+ for (i = 0; i < 2; i++)
+ {
+ pc.local_time_zone_table[i].name = tzname[i];
+ pc.local_time_zone_table[i].type = tLOCAL_ZONE;
+ pc.local_time_zone_table[i].value = i;
+ }
+ pc.local_time_zone_table[i].name = 0;
+ }
+#else
+ pc.local_time_zone_table[0].name = 0;
+#endif
+#endif
+
+ if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
+ && ! strcmp (pc.local_time_zone_table[0].name,
+ pc.local_time_zone_table[1].name))
+ {
+ /* This locale uses the same abbrevation for standard and
+ daylight times. So if we see that abbreviation, we don't
+ know whether it's daylight time. */
+ pc.local_time_zone_table[0].value = -1;
+ pc.local_time_zone_table[1].name = 0;
+ }
+
+ if (yyparse (&pc) != 0
+ || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
+ || 1 < (pc.local_zones_seen + pc.zones_seen)
+ || (pc.local_zones_seen && 1 < pc.local_isdst))
+ return -1;
+
+ tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
+ tm.tm_mon = pc.month - 1 + pc.rel_month;
+ tm.tm_mday = pc.day + pc.rel_day;
+ if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
+ {
+ tm.tm_hour = to_hour (pc.hour, pc.meridian);
+ if (tm.tm_hour < 0)
+ return -1;
+ tm.tm_min = pc.minutes;
+ tm.tm_sec = pc.seconds;
+ }
+ else
+ {
+ tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+ }
+
+ /* Let mktime deduce tm_isdst if we have an absolute time stamp,
+ or if the relative time stamp mentions days, months, or years. */
+ if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
+ | pc.rel_month | pc.rel_year)
+ tm.tm_isdst = -1;
+
+ /* But if the input explicitly specifies local time with or without
+ DST, give mktime that information. */
+ if (pc.local_zones_seen)
+ tm.tm_isdst = pc.local_isdst;
+
+ tm0 = tm;
+
+ Start = mktime (&tm);
+
+ if (Start == (time_t) -1)
+ {
+
+ /* Guard against falsely reporting errors near the time_t boundaries
+ when parsing times in other time zones. For example, if the min
+ time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
+ of UTC, then the min localtime value is 1970-01-01 08:00:00; if
+ we apply mktime to 1970-01-01 00:00:00 we will get an error, so
+ we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
+ zone by 24 hours to compensate. This algorithm assumes that
+ there is no DST transition within a day of the time_t boundaries. */
+ if (pc.zones_seen)
+ {
+ tm = tm0;
+ if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
+ {
+ tm.tm_mday++;
+ pc.time_zone += 24 * 60;
+ }
+ else
+ {
+ tm.tm_mday--;
+ pc.time_zone -= 24 * 60;
+ }
+ Start = mktime (&tm);
+ }
+
+ if (Start == (time_t) -1)
+ return Start;
+ }
+
+ if (pc.days_seen && ! pc.dates_seen)
+ {
+ tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
+ + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
+ tm.tm_isdst = -1;
+ Start = mktime (&tm);
+ if (Start == (time_t) -1)
+ return Start;
+ }
+
+ if (pc.zones_seen)
+ {
+ int delta = pc.time_zone * 60;
+#ifdef HAVE_TM_GMTOFF
+ delta -= tm.tm_gmtoff;
+#else
+ struct tm *gmt = gmtime (&Start);
+ if (! gmt)
+ return -1;
+ delta -= tm_diff (&tm, gmt);
+#endif
+ if ((Start < Start - delta) != (delta < 0))
+ return -1; /* time_t overflow */
+ Start -= delta;
+ }
+
+ /* Add relative hours, minutes, and seconds. Ignore leap seconds;
+ i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
+ leap second. Typically this is not what the user wants, but it's
+ too hard to do it the other way, because the time zone indicator
+ must be applied before relative times, and if mktime is applied
+ again the time zone will be lost. */
+ {
+ time_t t0 = Start;
+ long d1 = 60 * 60 * (long) pc.rel_hour;
+ time_t t1 = t0 + d1;
+ long d2 = 60 * (long) pc.rel_minutes;
+ time_t t2 = t1 + d2;
+ int d3 = pc.rel_seconds;
+ time_t t3 = t2 + d3;
+ if ((d1 / (60 * 60) ^ pc.rel_hour)
+ | (d2 / 60 ^ pc.rel_minutes)
+ | ((t0 + d1 < t0) ^ (d1 < 0))
+ | ((t1 + d2 < t1) ^ (d2 < 0))
+ | ((t2 + d3 < t2) ^ (d3 < 0)))
+ return -1;
+ Start = t3;
+ }
+
+ return Start;
+}
+
+#if TEST
+
+#include <stdio.h>
+
+int
+main (int ac, char **av)
+{
+ char buff[BUFSIZ];
+ time_t d;
+
+ printf ("Enter date, or blank line to exit.\n\t> ");
+ fflush (stdout);
+
+ buff[BUFSIZ - 1] = 0;
+ while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
+ {
+ d = get_date (buff, 0);
+ if (d == (time_t) -1)
+ printf ("Bad format - couldn't convert.\n");
+ else
+ printf ("%s", ctime (&d));
+ printf ("\t> ");
+ fflush (stdout);
+ }
+ return 0;
+}
+#endif /* defined TEST */
diff --git a/source/modules/vfs_default_quota.c b/source/modules/vfs_default_quota.c
new file mode 100644
index 00000000000..1294a515333
--- /dev/null
+++ b/source/modules/vfs_default_quota.c
@@ -0,0 +1,180 @@
+/*
+ * Store default Quotas in a specified quota record
+ *
+ * Copyright (C) Stefan (metze) Metzmacher 2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+#define DEFAULT_QUOTA_NAME "default_quota"
+
+#define DEFAULT_QUOTA_UID_DEFAULT 0
+#define DEFAULT_QUOTA_UID_NOLIMIT_DEFAULT True
+#define DEFAULT_QUOTA_GID_DEFAULT 0
+#define DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT True
+
+#define DEFAULT_QUOTA_UID(handle) \
+ (uid_t)lp_parm_int(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"uid",DEFAULT_QUOTA_UID_DEFAULT)
+
+#define DEFAULT_QUOTA_UID_NOLIMIT(handle) \
+ lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"uid nolimit",DEFAULT_QUOTA_UID_NOLIMIT_DEFAULT)
+
+#define DEFAULT_QUOTA_GID(handle) \
+ (gid_t)lp_parm_int(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid",DEFAULT_QUOTA_GID_DEFAULT)
+
+#define DEFAULT_QUOTA_GID_NOLIMIT(handle) \
+ lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid nolimit",DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT)
+
+static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
+{
+ int ret = -1;
+
+ if ((ret=SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, dq))!=0) {
+ return ret;
+ }
+
+ switch (qtype) {
+ case SMB_USER_QUOTA_TYPE:
+ /* we use id.uid == 0 for default quotas */
+ if ((id.uid==DEFAULT_QUOTA_UID(handle)) &&
+ DEFAULT_QUOTA_UID_NOLIMIT(handle)) {
+ SMB_QUOTAS_SET_NO_LIMIT(dq);
+ }
+ break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_QUOTA_TYPE:
+ /* we use id.gid == 0 for default quotas */
+ if ((id.gid==DEFAULT_QUOTA_GID(handle)) &&
+ DEFAULT_QUOTA_GID_NOLIMIT(handle)) {
+ SMB_QUOTAS_SET_NO_LIMIT(dq);
+ }
+ break;
+#endif /* HAVE_GROUP_QUOTA */
+ case SMB_USER_FS_QUOTA_TYPE:
+ {
+ unid_t qid;
+ uint32 qflags = dq->qflags;
+ qid.uid = DEFAULT_QUOTA_UID(handle);
+ SMB_VFS_NEXT_GET_QUOTA(handle, conn, SMB_USER_QUOTA_TYPE, qid, dq);
+ dq->qflags = qflags;
+ }
+ break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_FS_QUOTA_TYPE:
+ {
+ unid_t qid;
+ uint32 qflags = dq->qflags;
+ qid.gid = DEFAULT_QUOTA_GID(handle);
+ SMB_VFS_NEXT_GET_QUOTA(handle, conn, SMB_GROUP_QUOTA_TYPE, qid, dq);
+ dq->qflags = qflags;
+ }
+ break;
+#endif /* HAVE_GROUP_QUOTA */
+ default:
+ errno = ENOSYS;
+ return -1;
+ break;
+ }
+
+ return ret;
+}
+
+static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
+{
+ int ret = -1;
+
+ switch (qtype) {
+ case SMB_USER_QUOTA_TYPE:
+ /* we use id.uid == 0 for default quotas */
+ if ((id.uid==DEFAULT_QUOTA_UID(handle)) &&
+ DEFAULT_QUOTA_UID_NOLIMIT(handle)) {
+ return -1;
+ }
+ break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_QUOTA_TYPE:
+ /* we use id.gid == 0 for default quotas */
+ if ((id.gid==DEFAULT_QUOTA_GID(handle)) &&
+ DEFAULT_QUOTA_GID_NOLIMIT(handle)) {
+ return -1;
+ }
+ break;
+#endif /* HAVE_GROUP_QUOTA */
+ case SMB_USER_FS_QUOTA_TYPE:
+ break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_FS_QUOTA_TYPE:
+ break;
+#endif /* HAVE_GROUP_QUOTA */
+ default:
+ errno = ENOSYS;
+ return -1;
+ break;
+ }
+
+ if ((ret=SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, dq))!=0) {
+ return ret;
+ }
+
+ switch (qtype) {
+ case SMB_USER_QUOTA_TYPE:
+ break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_QUOTA_TYPE:
+ break;
+#endif /* HAVE_GROUP_QUOTA */
+ case SMB_USER_FS_QUOTA_TYPE:
+ {
+ unid_t qid;
+ qid.uid = DEFAULT_QUOTA_UID(handle);
+ ret = SMB_VFS_NEXT_SET_QUOTA(handle, conn, SMB_USER_QUOTA_TYPE, qid, dq);
+ }
+ break;
+#ifdef HAVE_GROUP_QUOTA
+ case SMB_GROUP_FS_QUOTA_TYPE:
+ {
+ unid_t qid;
+ qid.gid = DEFAULT_QUOTA_GID(handle);
+ ret = SMB_VFS_NEXT_SET_QUOTA(handle, conn, SMB_GROUP_QUOTA_TYPE, qid, dq);
+ }
+ break;
+#endif /* HAVE_GROUP_QUOTA */
+ default:
+ errno = ENOSYS;
+ return -1;
+ break;
+ }
+
+ return ret;
+}
+
+/* VFS operations structure */
+
+static vfs_op_tuple default_quota_ops[] = {
+ {SMB_VFS_OP(default_quota_get_quota), SMB_VFS_OP_GET_QUOTA, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(default_quota_set_quota), SMB_VFS_OP_SET_QUOTA, SMB_VFS_LAYER_TRANSPARENT},
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_default_quota_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, DEFAULT_QUOTA_NAME, default_quota_ops);
+}
diff --git a/source/modules/vfs_readonly.c b/source/modules/vfs_readonly.c
new file mode 100644
index 00000000000..5959ce900cd
--- /dev/null
+++ b/source/modules/vfs_readonly.c
@@ -0,0 +1,98 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ VFS module to perform read-only limitation based on a time period
+ Copyright (C) Alexander Bokovoy 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ This work was sponsored by Optifacio Software Services, Inc.
+*/
+
+#include "includes.h"
+#include "getdate.h"
+
+/*
+ This module performs a read-only limitation for specified share
+ (or all of them if it is loaded in a [global] section) based on period
+ definition in smb.conf. You can stack this module multiple times under
+ different names to get multiple limit intervals.
+
+ The module uses get_date() function from coreutils' date utility to parse
+ specified dates according to date(1) rules. Look into info page for date(1)
+ to understand the syntax.
+
+ The module accepts one parameter:
+
+ readonly: period = "begin date","end date"
+
+ where "begin date" and "end date" are mandatory and should comply with date(1)
+ syntax for date strings.
+
+ Example:
+
+ readonly: period = "today 14:00","today 15:00"
+
+ Default:
+
+ readonly: period = "today 0:0:0","tomorrow 0:0:0"
+
+ The default covers whole day thus making the share readonly
+
+ */
+
+#define MODULE_NAME "readonly"
+static int readonly_connect(vfs_handle_struct *handle,
+ connection_struct *conn,
+ const char *service,
+ const char *user)
+{
+ const char *period_def[] = {"today 0:0:0", "tomorrow 0:0:0"};
+
+ const char **period = lp_parm_string_list(SNUM(handle->conn),
+ (handle->param ? handle->param : MODULE_NAME),
+ "period", period_def);
+
+ if (period && period[0] && period[1]) {
+ time_t current_time = time(NULL);
+ time_t begin_period = get_date(period[0], &current_time);
+ time_t end_period = get_date(period[1], &current_time);
+
+ if ((current_time >= begin_period) && (current_time <= end_period)) {
+ conn->read_only = True;
+ }
+
+ return SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
+
+ } else {
+
+ return 1;
+
+ }
+}
+
+
+/* VFS operations structure */
+
+static vfs_op_tuple readonly_op_tuples[] = {
+ /* Disk operations */
+ {SMB_VFS_OP(readonly_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS init_module(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE_NAME, readonly_op_tuples);
+}
diff --git a/source/modules/vfs_recycle.c b/source/modules/vfs_recycle.c
index e725daedba4..c0b331b8621 100644
--- a/source/modules/vfs_recycle.c
+++ b/source/modules/vfs_recycle.c
@@ -455,7 +455,8 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
/* rename file we move to recycle bin */
i = 1;
while (recycle_file_exist(handle, final_name)) {
- snprintf(final_name, PATH_MAX -1, "%s/Copy #%d of %s", temp_name, i++, base);
+ SAFE_FREE(final_name);
+ asprintf(&final_name, "%s/Copy #%d of %s", temp_name, i++, base);
}
DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name));
diff --git a/source/msdfs/msdfs.c b/source/msdfs/msdfs.c
index ce6e64d9157..57408b9106a 100644
--- a/source/msdfs/msdfs.c
+++ b/source/msdfs/msdfs.c
@@ -87,8 +87,16 @@ static BOOL create_conn_struct( connection_struct *conn, int snum, char *path)
conn->connectpath = path;
pstring_sub(conn->connectpath , "%S", lp_servicename(snum));
+ /* needed for smbd_vfs_init() */
+
+ if ( (conn->mem_ctx=talloc_init("connection_struct")) == NULL ) {
+ DEBUG(0,("talloc_init(connection_struct) failed!\n"));
+ return False;
+ }
+
if (!smbd_vfs_init(conn)) {
DEBUG(0,("create_conn_struct: smbd_vfs_init failed.\n"));
+ talloc_destroy( conn->mem_ctx );
return False;
}
return True;
@@ -339,6 +347,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn,
struct connection_struct* conn = &conns;
pstring conn_path;
int snum;
+ BOOL ret = False;
BOOL self_referral = False;
@@ -381,16 +390,15 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn,
if (!lp_msdfs_root(SNUM(conn))) {
DEBUG(3,("get_referred_path: .%s. in dfs path %s is not a dfs root.\n",
dp.servicename, pathname));
- return False;
+ goto out;
}
if (*lp_msdfs_proxy(snum) != '\0') {
struct referral* ref;
jn->referral_count = 1;
- if ((ref = (struct referral*) malloc(sizeof(struct referral)))
- == NULL) {
+ if ((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) {
DEBUG(0, ("malloc failed for referral\n"));
- return False;
+ goto out;
}
pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum));
@@ -401,7 +409,8 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn,
jn->referral_list = ref;
if (consumedcntp)
*consumedcntp = strlen(pathname);
- return True;
+ ret = True;
+ goto out;
}
/* If not remote & not a self referral, return False */
@@ -410,7 +419,7 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn,
self_referralp, consumedcntp)) {
if (!*self_referralp) {
DEBUG(3,("get_referred_path: No valid referrals for path %s\n", pathname));
- return False;
+ goto out;
}
}
@@ -418,10 +427,9 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn,
if (*self_referralp) {
struct referral* ref;
jn->referral_count = 1;
- if((ref = (struct referral*) malloc(sizeof(struct referral)))
- == NULL) {
+ if((ref = (struct referral*) malloc(sizeof(struct referral))) == NULL) {
DEBUG(0,("malloc failed for referral\n"));
- return False;
+ goto out;
}
pstrcpy(ref->alternate_path,pathname);
@@ -431,8 +439,12 @@ BOOL get_referred_path(char *pathname, struct junction_map* jn,
if (consumedcntp)
*consumedcntp = strlen(pathname);
}
-
- return True;
+
+ ret = True;
+out:
+ talloc_destroy( conn->mem_ctx );
+
+ return ret;
}
static int setup_ver2_dfs_referral(char* pathname, char** ppdata,
@@ -758,6 +770,7 @@ BOOL create_msdfs_link(struct junction_map* jn, BOOL exists)
connection_struct *conn = &conns;
int i=0;
BOOL insert_comma = False;
+ BOOL ret = False;
if(!junction_to_local_path(jn, path, sizeof(path), conn))
return False;
@@ -786,14 +799,20 @@ BOOL create_msdfs_link(struct junction_map* jn, BOOL exists)
if(exists)
if(SMB_VFS_UNLINK(conn,path)!=0)
- return False;
+ goto out;
if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {
DEBUG(1,("create_msdfs_link: symlink failed %s -> %s\nError: %s\n",
path, msdfs_link, strerror(errno)));
- return False;
+ goto out;
}
- return True;
+
+
+ ret = True;
+
+out:
+ talloc_destroy( conn->mem_ctx );
+ return ret;
}
BOOL remove_msdfs_link(struct junction_map* jn)
@@ -801,14 +820,16 @@ BOOL remove_msdfs_link(struct junction_map* jn)
pstring path;
connection_struct conns;
connection_struct *conn = &conns;
+ BOOL ret = False;
- if(!junction_to_local_path(jn, path, sizeof(path), conn))
- return False;
-
- if(SMB_VFS_UNLINK(conn, path)!=0)
- return False;
-
- return True;
+ if( junction_to_local_path(jn, path, sizeof(path), conn) ) {
+ if( SMB_VFS_UNLINK(conn, path) == 0 )
+ ret = True;
+
+ talloc_destroy( conn->mem_ctx );
+ }
+
+ return ret;
}
static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
@@ -821,6 +842,7 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
connection_struct conns;
connection_struct *conn = &conns;
struct referral *ref = NULL;
+ BOOL ret = False;
pstrcpy(connect_path,lp_pathname(snum));
@@ -846,7 +868,7 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
= (struct referral*) malloc(sizeof(struct referral));
if (jn[cnt].referral_list == NULL) {
DEBUG(0, ("Malloc failed!\n"));
- return False;
+ goto out;
}
ref->proximity = 0;
@@ -854,7 +876,8 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
if (*lp_msdfs_proxy(snum) != '\0') {
pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum));
*jn_count = ++cnt;
- return True;
+ ret = True;
+ goto out;
}
slprintf(ref->alternate_path, sizeof(pstring)-1,
@@ -864,7 +887,7 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
/* Now enumerate all dfs links */
dirp = SMB_VFS_OPENDIR(conn, connect_path);
if(!dirp)
- return False;
+ goto out;
while((dname = vfs_readdirname(conn, dirp)) != NULL) {
pstring pathreal;
@@ -883,7 +906,9 @@ static BOOL form_junctions(int snum, struct junction_map* jn, int* jn_count)
SMB_VFS_CLOSEDIR(conn,dirp);
*jn_count = cnt;
- return True;
+out:
+ talloc_destroy(conn->mem_ctx);
+ return ret;
}
int enum_msdfs_links(struct junction_map* jn)
diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c
index 42edcc871fa..bc3540af70e 100644
--- a/source/nmbd/nmbd_processlogon.c
+++ b/source/nmbd/nmbd_processlogon.c
@@ -4,8 +4,7 @@
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
+ 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
diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c
index 7c5a8dd0546..0c6644e9d00 100644
--- a/source/nsswitch/wb_client.c
+++ b/source/nsswitch/wb_client.c
@@ -264,6 +264,80 @@ static int wb_getgroups(const char *user, gid_t **groups)
return -1;
}
+/* Call winbindd to initialise group membership. This is necessary for
+ some systems (i.e RH5.2) that do not have an initgroups function as part
+ of the nss extension. In RH5.2 this is implemented using getgrent()
+ which can be amazingly inefficient as well as having problems with
+ username case. */
+
+int winbind_initgroups(char *user, gid_t gid)
+{
+ gid_t *tgr, *groups = NULL;
+ int result;
+
+ /* Call normal initgroups if we are a local user */
+
+ if (!strchr(user, *lp_winbind_separator())) {
+ return initgroups(user, gid);
+ }
+
+ result = wb_getgroups(user, &groups);
+
+ DEBUG(10,("winbind_getgroups: %s: result = %s\n", user,
+ result == -1 ? "FAIL" : "SUCCESS"));
+
+ if (result != -1) {
+ int ngroups = result, i;
+ BOOL is_member = False;
+
+ /* Check to see if the passed gid is already in the list */
+
+ for (i = 0; i < ngroups; i++) {
+ if (groups[i] == gid) {
+ is_member = True;
+ }
+ }
+
+ /* Add group to list if necessary */
+
+ if (!is_member) {
+ tgr = (gid_t *)Realloc(groups, sizeof(gid_t) * ngroups + 1);
+
+ if (!tgr) {
+ errno = ENOMEM;
+ result = -1;
+ goto done;
+ }
+ else groups = tgr;
+
+ groups[ngroups] = gid;
+ ngroups++;
+ }
+
+ /* Set the groups */
+
+ if (sys_setgroups(ngroups, groups) == -1) {
+ errno = EPERM;
+ result = -1;
+ goto done;
+ }
+
+ } else {
+
+ /* The call failed. Set errno to something so we don't get
+ a bogus value from the last failed system call. */
+
+ errno = EIO;
+ }
+
+ /* Free response data if necessary */
+
+ done:
+ SAFE_FREE(groups);
+
+ return result;
+}
+
/* Return a list of groups the user is a member of. This function is
useful for large systems where inverting the group database would be too
time consuming. If size is zero, list is not modified and the total
diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c
index acaf0ed17c9..79553e9e4fa 100644
--- a/source/nsswitch/wb_common.c
+++ b/source/nsswitch/wb_common.c
@@ -239,6 +239,8 @@ int winbind_open_pipe_sock(void)
}
}
+ SAFE_FREE(response.extra_data);
+
return winbindd_fd;
#else
return -1;
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index f5337993704..0018e99f60f 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -3,7 +3,7 @@
Winbind status program.
- Copyright (C) Tim Potter 2000-2002
+ Copyright (C) Tim Potter 2000-2003
Copyright (C) Andrew Bartlett 2002
This program is free software; you can redistribute it and/or modify
@@ -219,15 +219,20 @@ static BOOL wbinfo_list_domains(void)
/* show sequence numbers */
-static BOOL wbinfo_show_sequence(void)
+static BOOL wbinfo_show_sequence(const char *domain)
{
+ struct winbindd_request request;
struct winbindd_response response;
ZERO_STRUCT(response);
+ ZERO_STRUCT(request);
+
+ if ( domain )
+ fstrcpy( request.domain_name, domain );
/* Send request */
- if (winbindd_request(WINBINDD_SHOW_SEQUENCE, NULL, &response) !=
+ if (winbindd_request(WINBINDD_SHOW_SEQUENCE, &request, &response) !=
NSS_STATUS_SUCCESS)
return False;
@@ -481,9 +486,18 @@ static BOOL wbinfo_auth_crap(char *username)
parse_wbinfo_domain_user(username, name_domain, name_user);
- fstrcpy(request.data.auth_crap.user, name_user);
+ if (push_utf8_fstring(request.data.auth_crap.user, name_user) == -1) {
+ d_printf("unable to create utf8 string for '%s'\n",
+ name_user);
+ return False;
+ }
- fstrcpy(request.data.auth_crap.domain, name_domain);
+ if (push_utf8_fstring(request.data.auth_crap.domain,
+ name_domain) == -1) {
+ d_printf("unable to create utf8 string for '%s'\n",
+ name_domain);
+ return False;
+ }
generate_random_buffer(request.data.auth_crap.chal, 8, False);
@@ -682,17 +696,27 @@ static BOOL wbinfo_remove_user_from_group(char *string)
/* Print domain users */
-static BOOL print_domain_users(void)
+static BOOL print_domain_users(const char *domain)
{
+ struct winbindd_request request;
struct winbindd_response response;
const char *extra_data;
fstring name;
/* Send request to winbind daemon */
+ ZERO_STRUCT(request);
ZERO_STRUCT(response);
+
+ if (domain) {
+ /* '.' is the special sign for our own domwin */
+ if ( strequal(domain, ".") )
+ fstrcpy( request.domain_name, lp_workgroup() );
+ else
+ fstrcpy( request.domain_name, domain );
+ }
- if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response) !=
+ if (winbindd_request(WINBINDD_LIST_USERS, &request, &response) !=
NSS_STATUS_SUCCESS)
return False;
@@ -713,15 +737,24 @@ static BOOL print_domain_users(void)
/* Print domain groups */
-static BOOL print_domain_groups(void)
+static BOOL print_domain_groups(const char *domain)
{
+ struct winbindd_request request;
struct winbindd_response response;
const char *extra_data;
fstring name;
+ ZERO_STRUCT(request);
ZERO_STRUCT(response);
- if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response) !=
+ if (domain) {
+ if ( strequal(domain, ".") )
+ fstrcpy( request.domain_name, lp_workgroup() );
+ else
+ fstrcpy( request.domain_name, domain );
+ }
+
+ if (winbindd_request(WINBINDD_LIST_GROUPS, &request, &response) !=
NSS_STATUS_SUCCESS)
return False;
@@ -845,6 +878,7 @@ static BOOL wbinfo_ping(void)
enum {
OPT_SET_AUTH_USER = 1000,
OPT_GET_AUTH_USER,
+ OPT_DOMAIN_NAME,
OPT_SEQUENCE
};
@@ -854,8 +888,8 @@ int main(int argc, char **argv)
poptContext pc;
static char *string_arg;
+ static char *opt_domain_name;
static int int_arg;
- BOOL got_command = False;
int result = 1;
struct poptOption long_options[] = {
@@ -864,8 +898,8 @@ int main(int argc, char **argv)
/* longName, shortName, argInfo, argPtr, value, descrip,
argDesc */
- { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users"},
- { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g', "Lists all domain groups" },
+ { "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users", "domain"},
+ { "domain-groups", 'g', POPT_ARG_NONE, 0, 'g', "Lists all domain groups", "domain" },
{ "WINS-by-name", 'N', POPT_ARG_STRING, &string_arg, 'N', "Converts NetBIOS name to IP", "NETBIOS-NAME" },
{ "WINS-by-ip", 'I', POPT_ARG_STRING, &string_arg, 'I', "Converts IP address to NetBIOS name", "IP" },
{ "name-to-sid", 'n', POPT_ARG_STRING, &string_arg, 'n', "Converts name to sid", "NAME" },
@@ -888,6 +922,7 @@ int main(int argc, char **argv)
{ "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
{ "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
{ "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" },
+ { "domain", 0, POPT_ARG_STRING, &opt_domain_name, OPT_DOMAIN_NAME, "Define to the domain to restrict operatio", "domain" },
POPT_COMMON_VERSION
POPT_TABLEEND
};
@@ -917,11 +952,7 @@ int main(int argc, char **argv)
}
while((opt = poptGetNextOpt(pc)) != -1) {
- if (got_command) {
- d_fprintf(stderr, "No more than one command may be specified at once.\n");
- exit(1);
- }
- got_command = True;
+ /* get the generic configuration parameters like --domain */
}
poptFreeContext(pc);
@@ -932,13 +963,13 @@ int main(int argc, char **argv)
while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case 'u':
- if (!print_domain_users()) {
+ if (!print_domain_users(opt_domain_name)) {
d_printf("Error looking up domain users\n");
goto done;
}
break;
case 'g':
- if (!print_domain_groups()) {
+ if (!print_domain_groups(opt_domain_name)) {
d_printf("Error looking up domain groups\n");
goto done;
}
@@ -1007,7 +1038,7 @@ int main(int argc, char **argv)
}
break;
case OPT_SEQUENCE:
- if (!wbinfo_show_sequence()) {
+ if (!wbinfo_show_sequence(opt_domain_name)) {
d_printf("Could not show sequence numbers\n");
goto done;
}
@@ -1074,7 +1105,7 @@ int main(int argc, char **argv)
goto done;
}
break;
- case 'P':
+ case 'p':
if (!wbinfo_ping()) {
d_printf("could not ping winbindd!\n");
goto done;
@@ -1086,6 +1117,9 @@ int main(int argc, char **argv)
case OPT_GET_AUTH_USER:
wbinfo_get_auth_user();
break;
+ /* generic configuration options */
+ case OPT_DOMAIN_NAME:
+ break;
default:
d_fprintf(stderr, "Invalid option\n");
poptPrintHelp(pc, stderr, 0);
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index 0860d701d86..313161f5fa8 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -27,20 +27,6 @@
BOOL opt_nocache = False;
BOOL opt_dual_daemon = True;
-/*****************************************************************************
- stubb functions
-****************************************************************************/
-
-void become_root( void )
-{
- return;
-}
-
-void unbecome_root( void )
-{
- return;
-}
-
/* Reload configuration */
static BOOL reload_services_file(BOOL test)
@@ -131,8 +117,8 @@ static void winbindd_status(void)
if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
DEBUG(2, ("\tclient list:\n"));
for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
- DEBUG(2, ("\t\tpid %d, sock %d, rbl %d, wbl %d\n",
- tmp->pid, tmp->sock, tmp->read_buf_len,
+ DEBUG(2, ("\t\tpid %lu, sock %d, rbl %d, wbl %d\n",
+ (unsigned long)tmp->pid, tmp->sock, tmp->read_buf_len,
tmp->write_buf_len));
}
}
@@ -172,7 +158,7 @@ static void terminate(void)
idmap_close();
/* Remove socket file */
- snprintf(path, sizeof(path), "%s/%s",
+ pstr_sprintf(path, "%s/%s",
WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
unlink(path);
exit(0);
@@ -471,8 +457,8 @@ void winbind_client_read(struct winbindd_cli_state *state)
/* Read failed, kill client */
if (n == -1 || n == 0) {
- DEBUG(5,("read failed on sock %d, pid %d: %s\n",
- state->sock, state->pid,
+ DEBUG(5,("read failed on sock %d, pid %lu: %s\n",
+ state->sock, (unsigned long)state->pid,
(n == -1) ? strerror(errno) : "EOF"));
state->finished = True;
@@ -519,8 +505,8 @@ static void client_write(struct winbindd_cli_state *state)
if (num_written == -1 || num_written == 0) {
- DEBUG(3,("write failed on sock %d, pid %d: %s\n",
- state->sock, state->pid,
+ DEBUG(3,("write failed on sock %d, pid %lu: %s\n",
+ state->sock, (unsigned long)state->pid,
(num_written == -1) ? strerror(errno) : "EOF"));
state->finished = True;
@@ -584,9 +570,15 @@ static void process_loop(void)
message_dispatch();
- /* rescan the trusted domains list. This must be done
+#if 0
+ /* not needed any more since we use a single RPC to
+ get transitive trusts --jerry
+
+ rescan the trusted domains list. This must be done
regularly to cope with transitive trusts */
+
rescan_trusted_domains(False);
+#endif
/* Free up temporary memory */
@@ -726,8 +718,8 @@ static void process_loop(void)
if (state->read_buf_len >= sizeof(uint32)
&& *(uint32 *) &state->request != sizeof(state->request)) {
- DEBUG(0,("process_loop: Invalid request size from pid %d: %d bytes sent, should be %d\n",
- state->request.pid, *(uint32 *) &state->request, sizeof(state->request)));
+ DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %d\n",
+ (unsigned long)state->request.pid, *(uint32 *) &state->request, sizeof(state->request)));
remove_client(state);
break;
@@ -838,7 +830,7 @@ int main(int argc, char **argv)
exit(1);
}
- snprintf(logfile, sizeof(logfile), "%s/log.winbindd", dyn_LOGFILEBASE);
+ pstr_sprintf(logfile, "%s/log.winbindd", dyn_LOGFILEBASE);
lp_set_logfile(logfile);
setup_logging("winbindd", log_stdout);
reopen_logs();
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index 2acb89b24bb..677afa1849f 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/nsswitch/winbindd.h
@@ -4,7 +4,7 @@
Winbind daemon for ntdom nss module
Copyright (C) Tim Potter 2000
- Copyright (C) Anthony Liguori 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/source/nsswitch/winbindd_acct.c b/source/nsswitch/winbindd_acct.c
index a1cd1d5f19a..0c06df7fdd4 100644
--- a/source/nsswitch/winbindd_acct.c
+++ b/source/nsswitch/winbindd_acct.c
@@ -70,18 +70,13 @@ static BOOL winbindd_accountdb_init(void)
if ( account_tdb )
return True;
-
- /* Nope. Try to open it */
- if (!(account_tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0,
- TDB_DEFAULT, O_RDWR | O_CREAT, 0600)))
- {
- /* last chance -- maybe idmap has already opened it */
- if ( !(account_tdb = idmap_tdb_handle()) ) {
+ /* winbindd_idmap.tdb should always be opened by the idmap_init()
+ code first */
- DEBUG(0, ("winbindd_idmap_init: Unable to open idmap database\n"));
- return False;
- }
+ if ( !(account_tdb = idmap_tdb_handle()) ) {
+ DEBUG(0, ("winbindd_accountdb_init: Unable to retreive handle for database\n"));
+ return False;
}
/* yeah! */
@@ -136,8 +131,8 @@ static WINBINDD_PW* string2passwd( char *string )
/* last minute sanity checks */
if ( pw.pw_uid==0 || pw.pw_gid==0 ) {
- DEBUG(0,("string2passwd: Failure! uid==%d, gid==%d\n",
- pw.pw_uid, pw.pw_gid));
+ DEBUG(0,("string2passwd: Failure! uid==%lu, gid==%lu\n",
+ (unsigned long)pw.pw_uid, (unsigned long)pw.pw_gid));
return NULL;
}
@@ -161,17 +156,17 @@ static char* passwd2string( const WINBINDD_PW *pw )
DEBUG(10,("passwd2string: converting passwd struct for %s\n",
pw->pw_name));
- ret = snprintf( string, sizeof(string), "%s:%s:%d:%d:%s:%s:%s",
+ ret = pstr_sprintf( string, "%s:%s:%lu:%lu:%s:%s:%s",
pw->pw_name,
pw->pw_passwd ? pw->pw_passwd : "x",
- pw->pw_uid,
- pw->pw_gid,
+ (unsigned long)pw->pw_uid,
+ (unsigned long)pw->pw_gid,
pw->pw_gecos,
pw->pw_dir,
pw->pw_shell );
if ( ret < 0 ) {
- DEBUG(0,("passwd2string: snprintf() failed!\n"));
+ DEBUG(0,("passwd2string: pstr_sprintf() failed!\n"));
return NULL;
}
@@ -247,7 +242,7 @@ static WINBINDD_GR* string2group( char *string )
/* last minute sanity checks */
if ( grp.gr_gid == 0 ) {
- DEBUG(0,("string2group: Failure! gid==%d\n", grp.gr_gid));
+ DEBUG(0,("string2group: Failure! gid==%lu\n", (unsigned long)grp.gr_gid));
SAFE_FREE( gr_members );
return NULL;
}
@@ -303,16 +298,16 @@ static char* group2string( const WINBINDD_GR *grp )
fstrcpy( gr_mem_str, "" );
}
- ret = snprintf( string, sizeof(string)-1, "%s:%s:%d:%s",
+ ret = pstr_sprintf( string, "%s:%s:%lu:%s",
grp->gr_name,
grp->gr_passwd ? grp->gr_passwd : "*",
- grp->gr_gid,
+ (unsigned long)grp->gr_gid,
gr_mem_str );
SAFE_FREE( gr_mem_str );
if ( ret < 0 ) {
- DEBUG(0,("group2string: snprintf() failed!\n"));
+ DEBUG(0,("group2string: pstr_sprintf() failed!\n"));
return NULL;
}
@@ -326,7 +321,7 @@ static char* acct_userkey_byname( const char *name )
{
static fstring key;
- snprintf( key, sizeof(key), "%s/NAME/%s", WBKEY_PASSWD, name );
+ fstr_sprintf( key, "%s/NAME/%s", WBKEY_PASSWD, name );
return key;
}
@@ -338,7 +333,7 @@ static char* acct_userkey_byuid( uid_t uid )
{
static fstring key;
- snprintf( key, sizeof(key), "%s/UID/%d", WBKEY_PASSWD, uid );
+ fstr_sprintf( key, "%s/UID/%lu", WBKEY_PASSWD, (unsigned long)uid );
return key;
}
@@ -350,7 +345,7 @@ static char* acct_groupkey_byname( const char *name )
{
static fstring key;
- snprintf( key, sizeof(key), "%s/NAME/%s", WBKEY_GROUP, name );
+ fstr_sprintf( key, "%s/NAME/%s", WBKEY_GROUP, name );
return key;
}
@@ -362,7 +357,7 @@ static char* acct_groupkey_bygid( gid_t gid )
{
static fstring key;
- snprintf( key, sizeof(key), "%s/GID/%d", WBKEY_GROUP, gid );
+ fstr_sprintf( key, "%s/GID/%lu", WBKEY_GROUP, (unsigned long)gid );
return key;
}
@@ -415,7 +410,7 @@ WINBINDD_PW* wb_getpwuid( const uid_t uid )
data = tdb_fetch_bystring( account_tdb, acct_userkey_byuid(uid) );
if ( !data.dptr ) {
- DEBUG(4,("wb_getpwuid: failed to locate uid == %d\n", uid));
+ DEBUG(4,("wb_getpwuid: failed to locate uid == %lu\n", (unsigned long)uid));
return NULL;
}
keystr = acct_userkey_byname( data.dptr );
@@ -431,8 +426,8 @@ WINBINDD_PW* wb_getpwuid( const uid_t uid )
SAFE_FREE( data.dptr );
}
- DEBUG(5,("wb_getpwuid: %s user (uid == %d)\n",
- (pw ? "Found" : "Did not find"), uid ));
+ DEBUG(5,("wb_getpwuid: %s user (uid == %lu)\n",
+ (pw ? "Found" : "Did not find"), (unsigned long)uid ));
return pw;
}
@@ -544,7 +539,8 @@ WINBINDD_GR* wb_getgrgid( gid_t gid )
data = tdb_fetch_bystring( account_tdb, acct_groupkey_bygid(gid) );
if ( !data.dptr ) {
- DEBUG(4,("wb_getgrgid: failed to locate gid == %d\n", gid));
+ DEBUG(4,("wb_getgrgid: failed to locate gid == %lu\n",
+ (unsigned long)gid));
return NULL;
}
keystr = acct_groupkey_byname( data.dptr );
@@ -560,8 +556,8 @@ WINBINDD_GR* wb_getgrgid( gid_t gid )
SAFE_FREE( data.dptr );
}
- DEBUG(5,("wb_getgrgid: %s group (gid == %d)\n",
- (grp ? "Found" : "Did not find"), gid ));
+ DEBUG(5,("wb_getgrgid: %s group (gid == %lu)\n",
+ (grp ? "Found" : "Did not find"), (unsigned long)gid ));
return grp;
}
@@ -697,7 +693,7 @@ static int cleangroups_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA
fstring key;
char *name = (char*)state;
- snprintf( key, sizeof(key), "%s/NAME", WBKEY_GROUP );
+ fstr_sprintf( key, "%s/NAME", WBKEY_GROUP );
len = strlen(key);
/* if this is a group entry then, check the members */
@@ -776,7 +772,7 @@ static int isprimarygroup_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf,
fstring key;
struct _check_primary_grp *check = (struct _check_primary_grp*)params;
- snprintf( key, sizeof(key), "%s/NAME", WBKEY_PASSWD );
+ fstr_sprintf( key, "%s/NAME", WBKEY_PASSWD );
len = strlen(key);
/* if this is a group entry then, check the members */
@@ -875,8 +871,8 @@ enum winbindd_result winbindd_create_user(struct winbindd_cli_state *state)
user = state->request.data.acct_mgt.username;
group = state->request.data.acct_mgt.groupname;
- DEBUG(3, ("[%5d]: create_user: user=>(%s), group=>(%s)\n",
- state->pid, user, group));
+ DEBUG(3, ("[%5lu]: create_user: user=>(%s), group=>(%s)\n",
+ (unsigned long)state->pid, user, group));
if ( !*group )
group = lp_template_primary_group();
@@ -965,7 +961,7 @@ enum winbindd_result winbindd_create_group(struct winbindd_cli_state *state)
state->request.data.acct_mgt.groupname[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
group = state->request.data.acct_mgt.groupname;
- DEBUG(3, ("[%5d]: create_group: (%s)\n", state->pid, group));
+ DEBUG(3, ("[%5lu]: create_group: (%s)\n", (unsigned long)state->pid, group));
/* get a new uid */
@@ -1025,7 +1021,7 @@ enum winbindd_result winbindd_add_user_to_group(struct winbindd_cli_state *state
group = state->request.data.acct_mgt.groupname;
user = state->request.data.acct_mgt.username;
- DEBUG(3, ("[%5d]: add_user_to_group: add %s to %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: add_user_to_group: add %s to %s\n", (unsigned long)state->pid,
user, group));
/* make sure it is a valid user */
@@ -1073,7 +1069,7 @@ enum winbindd_result winbindd_remove_user_from_group(struct winbindd_cli_state *
group = state->request.data.acct_mgt.groupname;
user = state->request.data.acct_mgt.username;
- DEBUG(3, ("[%5d]: remove_user_to_group: delete %s from %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: remove_user_to_group: delete %s from %s\n", (unsigned long)state->pid,
user, group));
/* don't worry about checking the username since we're removing it anyways */
@@ -1116,8 +1112,8 @@ enum winbindd_result winbindd_set_user_primary_group(struct winbindd_cli_state *
group = state->request.data.acct_mgt.groupname;
user = state->request.data.acct_mgt.username;
- DEBUG(3, ("[%5d]: set_user_primary_grou:p group %s for user %s\n", state->pid,
- group, user));
+ DEBUG(3, ("[%5lu]: set_user_primary_group: group %s for user %s\n",
+ (unsigned long)state->pid, group, user));
/* make sure it is a valid user */
@@ -1158,7 +1154,7 @@ enum winbindd_result winbindd_delete_user(struct winbindd_cli_state *state)
state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.username)-1]='\0';
user = state->request.data.acct_mgt.username;
- DEBUG(3, ("[%5d]: delete_user: %s\n", state->pid, user));
+ DEBUG(3, ("[%5lu]: delete_user: %s\n", (unsigned long)state->pid, user));
/* make sure it is a valid user */
@@ -1189,7 +1185,7 @@ enum winbindd_result winbindd_delete_group(struct winbindd_cli_state *state)
state->request.data.acct_mgt.username[sizeof(state->request.data.acct_mgt.groupname)-1]='\0';
group = state->request.data.acct_mgt.groupname;
- DEBUG(3, ("[%5d]: delete_group: %s\n", state->pid, group));
+ DEBUG(3, ("[%5lu]: delete_group: %s\n", (unsigned long)state->pid, group));
/* make sure it is a valid group */
diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c
index 462dd21531b..9041401e52c 100644
--- a/source/nsswitch/winbindd_ads.c
+++ b/source/nsswitch/winbindd_ads.c
@@ -377,8 +377,10 @@ static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
rc = ads_search_retry(ads, &res, ldap_exp, attrs);
SAFE_FREE(ldap_exp);
SAFE_FREE(escaped_dn);
+ if ( !res )
+ goto failed;
- if (!ADS_ERR_OK(rc)) {
+ if (!res || !ADS_ERR_OK(rc)) {
goto failed;
}
@@ -801,24 +803,91 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
char ***alt_names,
DOM_SID **dom_sids)
{
- ADS_STRUCT *ads;
- ADS_STATUS rc;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DS_DOMAIN_TRUSTS *domains = NULL;
+ int count = 0;
+ int i;
+ struct cli_state *cli = NULL;
+ /* i think we only need our forest and downlevel trusted domains */
+ uint32 flags = DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND;
DEBUG(3,("ads: trusted_domains\n"));
*num_domains = 0;
- *names = NULL;
+ *alt_names = NULL;
+ *names = NULL;
+ *dom_sids = NULL;
+
+ if ( !NT_STATUS_IS_OK(result = cm_fresh_connection(domain->name, PI_NETLOGON, &cli)) ) {
+ DEBUG(5, ("trusted_domains: Could not open a connection to %s for PIPE_NETLOGON (%s)\n",
+ domain->name, nt_errstr(result)));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if ( NT_STATUS_IS_OK(result) )
+ result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, flags, &domains, (unsigned int *)&count );
+
+ if ( NT_STATUS_IS_OK(result) && count) {
+
+ /* Allocate memory for trusted domain names and sids */
- ads = ads_cached_connection(domain);
+ if ( !(*names = (char **)talloc(mem_ctx, sizeof(char *) * count)) ) {
+ DEBUG(0, ("trusted_domains: out of memory\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
- if (!ads) {
- domain->last_status = NT_STATUS_SERVER_DISABLED;
- return NT_STATUS_UNSUCCESSFUL;
+ if ( !(*alt_names = (char **)talloc(mem_ctx, sizeof(char *) * count)) ) {
+ DEBUG(0, ("trusted_domains: out of memory\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ if ( !(*dom_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * count)) ) {
+ DEBUG(0, ("trusted_domains: out of memory\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ /* Copy across names and sids */
+
+ for (i = 0; i < count; i++) {
+ fstring tmp;
+ fstring tmp2;
+
+ (*names)[i] = NULL;
+ (*alt_names)[i] = NULL;
+ ZERO_STRUCT( (*dom_sids)[i] );
+
+ if ( domains[i].netbios_ptr ) {
+ unistr2_to_ascii(tmp, &domains[i].netbios_domain, sizeof(tmp) - 1);
+ (*names)[i] = talloc_strdup(mem_ctx, tmp);
+ }
+
+ if ( domains[i].dns_ptr ) {
+ unistr2_to_ascii(tmp2, &domains[i].dns_domain, sizeof(tmp2) - 1);
+ (*alt_names)[i] = talloc_strdup(mem_ctx, tmp2);
+ }
+
+ /* sometimes we will get back a NULL SID from this call */
+
+ if ( domains[i].sid_ptr )
+ sid_copy(&(*dom_sids)[i], &domains[i].sid.sid);
+ }
+
+ *num_domains = count;
}
- rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, alt_names, dom_sids);
+done:
- return ads_ntstatus(rc);
+ SAFE_FREE( domains );
+
+ /* remove connection; This is a special case to the \NETLOGON pipe */
+
+ if ( cli )
+ cli_shutdown( cli );
+
+ return result;
}
/* find the domain sid for a domain */
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index 2da2a9e641d..bc6967dee1c 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -106,7 +106,7 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
case SEC_ADS: {
extern struct winbindd_methods ads_methods;
/* always obey the lp_security parameter for our domain */
- if ( strequal(lp_realm(), domain->alt_name) ) {
+ if ( strequal(lp_realm(), domain->alt_name) || strequal(lp_workgroup(), domain->name) ) {
domain->backend = &ads_methods;
break;
}
@@ -256,7 +256,7 @@ static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
return NT_STATUS_UNSUCCESSFUL;
}
- snprintf( key, sizeof(key), "SEQNUM/%s", domain->name );
+ fstr_sprintf( key, "SEQNUM/%s", domain->name );
data = tdb_fetch_bystring( wcache->tdb, key );
if ( !data.dptr || data.dsize!=8 ) {
@@ -295,7 +295,7 @@ static NTSTATUS store_cache_seqnum( struct winbindd_domain *domain )
return NT_STATUS_UNSUCCESSFUL;
}
- snprintf( key_str, sizeof(key_str), "SEQNUM/%s", domain->name );
+ fstr_sprintf( key_str, "SEQNUM/%s", domain->name );
key.dptr = key_str;
key.dsize = strlen(key_str)+1;
@@ -328,6 +328,8 @@ static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
time_t t = time(NULL);
unsigned cache_time = lp_winbind_cache_time();
+ get_cache( domain );
+
/* trying to reconnect is expensive, don't do it too often */
if (domain->sequence_number == DOM_SEQUENCE_NONE) {
cache_time *= 8;
@@ -430,7 +432,7 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
}
centry = smb_xmalloc(sizeof(*centry));
- centry->data = data.dptr;
+ centry->data = (unsigned char *)data.dptr;
centry->len = data.dsize;
centry->ofs = 0;
@@ -574,7 +576,7 @@ static void centry_end(struct cache_entry *centry, const char *format, ...)
key.dptr = kstr;
key.dsize = strlen(kstr);
- data.dptr = centry->data;
+ data.dptr = (char *)centry->data;
data.dsize = centry->ofs;
tdb_store(wcache->tdb, key, data, TDB_REPLACE);
@@ -922,7 +924,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
centry = wcache_fetch(cache, domain, "NS/%s/%s", domain->name, uname);
if (!centry)
goto do_query;
- *type = centry_uint32(centry);
+ *type = (enum SID_NAME_USE)centry_uint32(centry);
sid2 = centry_sid(centry, mem_ctx);
if (!sid2) {
ZERO_STRUCTP(sid);
@@ -986,7 +988,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
if (!centry)
goto do_query;
if (NT_STATUS_IS_OK(centry->status)) {
- *type = centry_uint32(centry);
+ *type = (enum SID_NAME_USE)centry_uint32(centry);
*name = centry_string(centry, mem_ctx);
}
status = centry->status;
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index 7f351677783..f07117b5ab8 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -152,7 +152,8 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
result = cli_full_connection(&new_conn->cli, global_myname(), new_conn->controller,
&dc_ip, 0, "IPC$", "IPC", ipc_username, ipc_domain,
- ipc_password, CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, &retry);
+ ipc_password, CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK,
+ Undefined, &retry);
secrets_named_mutex_release(new_conn->controller);
@@ -169,6 +170,11 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
return result;
}
+ /* set the domain if empty; needed for schannel connections */
+ if ( !*new_conn->cli->domain )
+ fstrcpy( new_conn->cli->domain, domain );
+
+
if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) {
result = NT_STATUS_PIPE_NOT_AVAILABLE;
/*
@@ -188,6 +194,25 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
return NT_STATUS_OK;
}
+/************************************************************************
+ Wrapper around statuc cm_open_connection to retreive a freshly
+ setup cli_state struct
+************************************************************************/
+
+NTSTATUS cm_fresh_connection(const char *domain, const int pipe_index,
+ struct cli_state **cli)
+{
+ NTSTATUS result;
+ struct winbindd_cm_conn conn;
+
+ result = cm_open_connection( domain, pipe_index, &conn );
+
+ if ( NT_STATUS_IS_OK(result) )
+ *cli = conn.cli;
+
+ return result;
+}
+
/* Return true if a connection is still alive */
static BOOL connection_ok(struct winbindd_cm_conn *conn)
@@ -320,13 +345,11 @@ BOOL cm_check_for_native_mode_win2k( const char *domain )
done:
-#if 0
- /*
- * I don't think we need to shutdown here ? JRA.
- */
+ /* close the connection; no other cals use this pipe and it is called only
+ on reestablishing the domain list --jerry */
+
if ( conn.cli )
cli_shutdown( conn.cli );
-#endif
return ret;
}
@@ -488,14 +511,14 @@ NTSTATUS cm_get_netlogon_cli(const char *domain,
if (!NT_STATUS_IS_OK(result))
return result;
- snprintf(lock_name, sizeof(lock_name), "NETLOGON\\%s", conn->controller);
+ fstr_sprintf(lock_name, "NETLOGON\\%s", conn->controller);
if (!(got_mutex = secrets_named_mutex(lock_name, WINBIND_SERVER_MUTEX_WAIT_TIME))) {
DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller));
}
if ( sec_channel_type == SEC_CHAN_DOMAIN )
- snprintf(conn->cli->mach_acct, sizeof(conn->cli->mach_acct) - 1, "%s$", lp_workgroup());
+ fstr_sprintf(conn->cli->mach_acct, "%s$", lp_workgroup());
result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd);
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index d67d48d5066..fba427536c8 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -232,7 +232,7 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';
- DEBUG(3, ("[%5d]: getgrnam %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: getgrnam %s\n", (unsigned long)state->pid,
state->request.data.groupname));
/* Parse domain and groupname */
@@ -334,8 +334,8 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
int gr_mem_len;
char *gr_mem;
- DEBUG(3, ("[%5d]: getgrgid %d\n", state->pid,
- state->request.data.gid));
+ DEBUG(3, ("[%5lu]: getgrgid %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.gid));
/* Bug out if the gid isn't in the winbind range */
@@ -360,8 +360,8 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
/* Get rid from gid */
if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&group_sid, state->request.data.gid))) {
- DEBUG(1, ("could not convert gid %d to rid\n",
- state->request.data.gid));
+ DEBUG(1, ("could not convert gid %lu to rid\n",
+ (unsigned long)state->request.data.gid));
return WINBINDD_ERROR;
}
@@ -416,7 +416,7 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
- DEBUG(3, ("[%5d]: setgrent\n", state->pid));
+ DEBUG(3, ("[%5lu]: setgrent\n", (unsigned long)state->pid));
/* Check user has enabled this */
@@ -469,7 +469,7 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5d]: endgrent\n", state->pid));
+ DEBUG(3, ("[%5lu]: endgrent\n", (unsigned long)state->pid));
free_getent_state(state->getgrent_state);
state->getgrent_state = NULL;
@@ -605,7 +605,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
int num_groups, group_list_ndx = 0, i, gr_mem_list_len = 0;
char *new_extra_data, *gr_mem_list = NULL;
- DEBUG(3, ("[%5d]: getgrent\n", state->pid));
+ DEBUG(3, ("[%5lu]: getgrent\n", (unsigned long)state->pid));
/* Check user has enabled this */
@@ -691,7 +691,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
goto tryagain;
}
- DEBUG(10, ("got gid %d for group %x\n", group_gid,
+ DEBUG(10, ("got gid %lu for group %x\n", (unsigned long)group_gid,
name_list[ent->sam_entry_index].rid));
/* Fill in group entry */
@@ -821,17 +821,29 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
{
uint32 total_entries = 0;
struct winbindd_domain *domain;
+ const char *which_domain;
char *extra_data = NULL;
char *ted = NULL;
unsigned int extra_data_len = 0, i;
- DEBUG(3, ("[%5d]: list groups\n", state->pid));
+ DEBUG(3, ("[%5lu]: list groups\n", (unsigned long)state->pid));
+ /* Ensure null termination */
+ state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
+ which_domain = state->request.domain_name;
+
/* Enumerate over trusted domains */
for (domain = domain_list(); domain; domain = domain->next) {
struct getent_state groups;
+ /* if we have a domain name restricting the request and this
+ one in the list doesn't match, then just bypass the remainder
+ of the loop */
+
+ if ( *which_domain && !strequal(which_domain, domain->name) )
+ continue;
+
ZERO_STRUCT(groups);
/* Get list of sam groups */
@@ -915,7 +927,7 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.data.username[sizeof(state->request.data.username)-1]='\0';
- DEBUG(3, ("[%5d]: getgroups %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: getgroups %s\n", (unsigned long)state->pid,
state->request.data.username));
if (!(mem_ctx = talloc_init("winbindd_getgroups(%s)",
@@ -1009,9 +1021,9 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
/* We've jumped through a lot of hoops to get here */
DEBUG(10, ("winbindd_getgroups: mapped other sid %s to "
- "gid %d\n", sid_string_static(
+ "gid %lu\n", sid_string_static(
&info3->other_sids[i].sid),
- gid_list[num_gids]));
+ (unsigned long)gid_list[num_gids]));
num_gids++;
}
diff --git a/source/nsswitch/winbindd_misc.c b/source/nsswitch/winbindd_misc.c
index 8d7cdc47317..d2d50c52ac5 100644
--- a/source/nsswitch/winbindd_misc.c
+++ b/source/nsswitch/winbindd_misc.c
@@ -35,7 +35,7 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
int num_retries = 0;
struct cli_state *cli;
uint32 sec_channel_type;
- DEBUG(3, ("[%5d]: check machine account\n", state->pid));
+ DEBUG(3, ("[%5lu]: check machine account\n", (unsigned long)state->pid));
/* Get trust account password */
@@ -95,7 +95,7 @@ enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
int total_entries = 0, extra_data_len = 0;
char *ted, *extra_data = NULL;
- DEBUG(3, ("[%5d]: list trusted domains\n", state->pid));
+ DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid));
/* We need to refresh the trusted domain list as the domains may
have changed since we last looked. There may be a sequence
@@ -148,8 +148,13 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
char *extra_data = NULL;
+ const char *which_domain;
- DEBUG(3, ("[%5d]: show sequence\n", state->pid));
+ DEBUG(3, ("[%5lu]: show sequence\n", (unsigned long)state->pid));
+
+ /* Ensure null termination */
+ state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
+ which_domain = state->request.domain_name;
extra_data = strdup("");
@@ -158,6 +163,13 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state)
for (domain = domain_list(); domain; domain = domain->next) {
char *s;
+ /* if we have a domain name restricting the request and this
+ one in the list doesn't match, then just bypass the remainder
+ of the loop */
+
+ if ( *which_domain && !strequal(which_domain, domain->name) )
+ continue;
+
domain->methods->sequence_number(domain, &domain->sequence_number);
if (DOM_SEQUENCE_NONE == (unsigned)domain->sequence_number) {
@@ -181,7 +193,7 @@ enum winbindd_result winbindd_show_sequence(struct winbindd_cli_state *state)
enum winbindd_result winbindd_ping(struct winbindd_cli_state
*state)
{
- DEBUG(3, ("[%5d]: ping\n", state->pid));
+ DEBUG(3, ("[%5lu]: ping\n", (unsigned long)state->pid));
return WINBINDD_OK;
}
@@ -191,7 +203,7 @@ enum winbindd_result winbindd_ping(struct winbindd_cli_state
enum winbindd_result winbindd_info(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5d]: request misc info\n", state->pid));
+ DEBUG(3, ("[%5lu]: request misc info\n", (unsigned long)state->pid));
state->response.data.info.winbind_separator = *lp_winbind_separator();
fstrcpy(state->response.data.info.samba_version, VERSION);
@@ -204,7 +216,7 @@ enum winbindd_result winbindd_info(struct winbindd_cli_state *state)
enum winbindd_result winbindd_interface_version(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5d]: request interface version\n", state->pid));
+ DEBUG(3, ("[%5lu]: request interface version\n", (unsigned long)state->pid));
state->response.data.interface_version = WINBIND_INTERFACE_VERSION;
@@ -216,7 +228,7 @@ enum winbindd_result winbindd_interface_version(struct winbindd_cli_state *state
enum winbindd_result winbindd_domain_name(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5d]: request domain name\n", state->pid));
+ DEBUG(3, ("[%5lu]: request domain name\n", (unsigned long)state->pid));
fstrcpy(state->response.data.domain_name, lp_workgroup());
@@ -228,7 +240,7 @@ enum winbindd_result winbindd_domain_name(struct winbindd_cli_state *state)
enum winbindd_result winbindd_netbios_name(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5d]: request netbios name\n", state->pid));
+ DEBUG(3, ("[%5lu]: request netbios name\n", (unsigned long)state->pid));
fstrcpy(state->response.data.netbios_name, global_myname());
@@ -240,7 +252,7 @@ enum winbindd_result winbindd_netbios_name(struct winbindd_cli_state *state)
enum winbindd_result winbindd_priv_pipe_dir(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5d]: request location of privileged pipe\n", state->pid));
+ DEBUG(3, ("[%5lu]: request location of privileged pipe\n", (unsigned long)state->pid));
state->response.extra_data = strdup(get_winbind_priv_pipe_dir());
if (!state->response.extra_data)
diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h
index c4407bbe31c..41fecd2816c 100644
--- a/source/nsswitch/winbindd_nss.h
+++ b/source/nsswitch/winbindd_nss.h
@@ -157,6 +157,7 @@ struct winbindd_request {
enum winbindd_cmd cmd; /* Winbindd command to execute */
pid_t pid; /* pid of calling process */
uint32 flags; /* flags relavant to a given request */
+ fstring domain_name; /* name of domain for which the request applies */
union {
fstring winsreq; /* WINS request */
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index 8df0f621c0f..a89c7ca065e 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -53,55 +53,6 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-/*******************************************************************
- wrapper around retreiving the trsut account password
-*******************************************************************/
-
-static BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
- time_t *pass_last_set_time, uint32 *channel)
-{
- DOM_SID sid;
- char *pwd;
-
- /* if we are a DC and this is not our domain, then lookup an account
- for the domain trust */
-
- if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() )
- {
- if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
- pass_last_set_time) )
- {
- DEBUG(0, ("get_trust_pw: could not fetch trust account "
- "password for trusted domain %s\n", domain));
- return False;
- }
-
- *channel = SEC_CHAN_DOMAIN;
- E_md4hash(pwd, ret_pwd);
- SAFE_FREE(pwd);
-
- return True;
- }
- else /* just get the account for our domain (covers
- ROLE_DOMAIN_MEMBER as well */
- {
- /* get the machine trust account for our domain */
-
- if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd,
- pass_last_set_time, channel) )
- {
- DEBUG(0, ("get_trust_pw: could not fetch trust account "
- "password for my domain %s\n", domain));
- return False;
- }
-
- return True;
- }
-
- /* Failure */
- return False;
-}
-
/**********************************************************************
Authenticate a user with a clear test password
**********************************************************************/
@@ -131,7 +82,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
/* 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,
+ DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)state->pid,
state->request.data.auth.user));
if (!(mem_ctx = talloc_init("winbind pam auth for %s", state->request.data.auth.user))) {
@@ -275,10 +226,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
}
/* 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';
+ state->request.data.auth_crap.user[sizeof(state->request.data.auth_crap.user)-1]=0;
+ state->request.data.auth_crap.domain[sizeof(state->request.data.auth_crap.domain)-1]=0;
if (!(mem_ctx = talloc_init("winbind pam auth crap for (utf8) %s", state->request.data.auth_crap.user))) {
DEBUG(0, ("winbindd_pam_auth_crap: could not talloc_init()!\n"));
@@ -288,12 +237,16 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
if (pull_utf8_talloc(mem_ctx, &user, state->request.data.auth_crap.user) == (size_t)-1) {
DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
if (*state->request.data.auth_crap.domain) {
char *dom = NULL;
if (pull_utf8_talloc(mem_ctx, &dom, state->request.data.auth_crap.domain) == (size_t)-1) {
DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
domain = dom;
} else if (lp_winbind_use_default_domain()) {
@@ -305,7 +258,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
goto done;
}
- DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid,
domain, user));
if ( !get_trust_pw(domain, trust_passwd, &last_change_time, &sec_channel_type) ) {
@@ -317,6 +270,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
char *wrk = NULL;
if (pull_utf8_talloc(mem_ctx, &wrk, state->request.data.auth_crap.workstation) == (size_t)-1) {
DEBUG(0, ("winbindd_pam_auth_crap: pull_utf8_talloc failed!\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
}
workstation = wrk;
} else {
@@ -436,7 +391,7 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
fstring domain, user;
CLI_POLICY_HND *hnd;
- DEBUG(3, ("[%5d]: pam chauthtok %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid,
state->request.data.chauthtok.user));
/* Setup crap */
diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c
index 33339d7ca03..8bd2c665113 100644
--- a/source/nsswitch/winbindd_rpc.c
+++ b/source/nsswitch/winbindd_rpc.c
@@ -295,7 +295,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
if (NT_STATUS_IS_OK(result)) {
sid_copy(sid, &sids[0]);
- *type = types[0];
+ *type = (enum SID_NAME_USE)types[0];
}
return result;
@@ -331,7 +331,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
hnd && hnd->cli && hnd->cli->fd == -1);
if (NT_STATUS_IS_OK(result)) {
- *type = types[0];
+ *type = (enum SID_NAME_USE)types[0];
*name = names[0];
DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
diff --git a/source/nsswitch/winbindd_sid.c b/source/nsswitch/winbindd_sid.c
index 676beae3aaf..ac1ee115554 100644
--- a/source/nsswitch/winbindd_sid.c
+++ b/source/nsswitch/winbindd_sid.c
@@ -39,7 +39,7 @@ enum winbindd_result winbindd_lookupsid(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
- DEBUG(3, ("[%5d]: lookupsid %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: lookupsid %s\n", (unsigned long)state->pid,
state->request.data.sid));
/* Lookup sid from PDC using lsa_lookup_sids() */
@@ -90,7 +90,7 @@ enum winbindd_result winbindd_lookupname(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0';
- DEBUG(3, ("[%5d]: lookupname %s%s%s\n", state->pid,
+ DEBUG(3, ("[%5lu]: lookupname %s%s%s\n", (unsigned long)state->pid,
state->request.data.name.dom_name,
lp_winbind_separator(),
state->request.data.name.name));
@@ -127,7 +127,7 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
- DEBUG(3, ("[%5d]: sid to uid %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,
state->request.data.sid));
/* Split sid into domain sid and user rid */
@@ -159,7 +159,7 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.data.sid[sizeof(state->request.data.sid)-1]='\0';
- DEBUG(3, ("[%5d]: sid to gid %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid,
state->request.data.sid));
if (!string_to_sid(&sid, state->request.data.sid)) {
@@ -185,20 +185,25 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- /* Bug out if the uid isn't in the winbind range */
-
+#if 0 /* JERRY */
+ /* we cannot do this check this anymore since a domain member of
+ a Samba domain may share unix accounts via NIS or LDAP. In this
+ case the uid/gid will be out of winbindd's range but still might
+ be resolved to a SID via an ldap idmap backend */
+
if ((state->request.data.uid < server_state.uid_low ) ||
(state->request.data.uid > server_state.uid_high)) {
return WINBINDD_ERROR;
}
+#endif
- DEBUG(3, ("[%5d]: uid to sid %d\n", state->pid,
- state->request.data.uid));
+ DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.uid));
/* Lookup rid for this uid */
if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&sid, state->request.data.uid))) {
- DEBUG(1, ("Could not convert uid %d to rid\n",
- state->request.data.uid));
+ DEBUG(1, ("Could not convert uid %lu to rid\n",
+ (unsigned long)state->request.data.uid));
return WINBINDD_ERROR;
}
@@ -214,20 +219,25 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
- /* Bug out if the gid isn't in the winbind range */
-
+#if 0 /* JERRY */
+ /* we cannot do this check this anymore since a domain member of
+ a Samba domain may share unix accounts via NIS or LDAP. In this
+ case the uid/gid will be out of winbindd's range but still might
+ be resolved to a SID via an ldap idmap backend */
+
if ((state->request.data.gid < server_state.gid_low) ||
(state->request.data.gid > server_state.gid_high)) {
return WINBINDD_ERROR;
}
+#endif
- DEBUG(3, ("[%5d]: gid to sid %d\n", state->pid,
- state->request.data.gid));
+ DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.gid));
/* Lookup sid for this uid */
if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&sid, state->request.data.gid))) {
- DEBUG(1, ("Could not convert gid %d to sid\n",
- state->request.data.gid));
+ DEBUG(1, ("Could not convert gid %lu to sid\n",
+ (unsigned long)state->request.data.gid));
return WINBINDD_ERROR;
}
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
index c49c41687b9..eab88c842ea 100644
--- a/source/nsswitch/winbindd_user.c
+++ b/source/nsswitch/winbindd_user.c
@@ -108,7 +108,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.data.username[sizeof(state->request.data.username)-1]='\0';
- DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: getpwnam %s\n", (unsigned long)state->pid,
state->request.data.username));
/* Parse domain and username */
@@ -131,7 +131,7 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
/* should we deal with users for our domain? */
if ( lp_winbind_trusted_domains_only() && strequal(name_domain, lp_workgroup())) {
- DEBUG(7,("winbindd_getpenam: My domain -- rejecting getpwnam() for %s\\%s.\n",
+ DEBUG(7,("winbindd_getpwnam: My domain -- rejecting getpwnam() for %s\\%s.\n",
name_domain, name_user));
return WINBINDD_ERROR;
}
@@ -209,8 +209,8 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
(state->request.data.uid > server_state.uid_high))
return WINBINDD_ERROR;
- DEBUG(3, ("[%5d]: getpwuid %d\n", state->pid,
- state->request.data.uid));
+ DEBUG(3, ("[%5lu]: getpwuid %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.uid));
/* always try local tdb first */
@@ -222,8 +222,8 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
/* Get rid from uid */
if (!NT_STATUS_IS_OK(idmap_uid_to_sid(&user_sid, state->request.data.uid))) {
- DEBUG(1, ("could not convert uid %d to SID\n",
- state->request.data.uid));
+ DEBUG(1, ("could not convert uid %lu to SID\n",
+ (unsigned long)state->request.data.uid));
return WINBINDD_ERROR;
}
@@ -246,8 +246,8 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
/* Get some user info */
- if (!(mem_ctx = talloc_init("winbind_getpwuid(%d)",
- state->request.data.uid))) {
+ if (!(mem_ctx = talloc_init("winbind_getpwuid(%lu)",
+ (unsigned long)state->request.data.uid))) {
DEBUG(1, ("out of memory\n"));
return WINBINDD_ERROR;
@@ -295,7 +295,7 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
- DEBUG(3, ("[%5d]: setpwent\n", state->pid));
+ DEBUG(3, ("[%5lu]: setpwent\n", (unsigned long)state->pid));
/* Check user has enabled this */
@@ -359,7 +359,7 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
enum winbindd_result winbindd_endpwent(struct winbindd_cli_state *state)
{
- DEBUG(3, ("[%5d]: endpwent\n", state->pid));
+ DEBUG(3, ("[%5lu]: endpwent\n", (unsigned long)state->pid));
free_getent_state(state->getpwent_state);
state->getpwent_state = NULL;
@@ -474,7 +474,7 @@ enum winbindd_result winbindd_getpwent(struct winbindd_cli_state *state)
struct winbindd_pw *user_list;
int num_users, user_list_ndx = 0, i;
- DEBUG(3, ("[%5d]: getpwent\n", state->pid));
+ DEBUG(3, ("[%5lu]: getpwent\n", (unsigned long)state->pid));
/* Check user has enabled this */
@@ -575,24 +575,36 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
{
struct winbindd_domain *domain;
WINBIND_USERINFO *info;
+ const char *which_domain;
uint32 num_entries = 0, total_entries = 0;
char *ted, *extra_data = NULL;
int extra_data_len = 0;
TALLOC_CTX *mem_ctx;
enum winbindd_result rv = WINBINDD_ERROR;
- DEBUG(3, ("[%5d]: list users\n", state->pid));
+ DEBUG(3, ("[%5lu]: list users\n", (unsigned long)state->pid));
if (!(mem_ctx = talloc_init("winbindd_list_users")))
return WINBINDD_ERROR;
+ /* Ensure null termination */
+ state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
+ which_domain = state->request.domain_name;
+
/* Enumerate over trusted domains */
for (domain = domain_list(); domain; domain = domain->next) {
NTSTATUS status;
struct winbindd_methods *methods;
unsigned int i;
-
+
+ /* if we have a domain name restricting the request and this
+ one in the list doesn't match, then just bypass the remainder
+ of the loop */
+
+ if ( *which_domain && !strequal(which_domain, domain->name) )
+ continue;
+
methods = domain->methods;
/* Query display info */
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 6177c46aefd..95dff847693 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -80,6 +80,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
DOM_SID *sid)
{
struct winbindd_domain *domain;
+ char *contact_name;
/* We can't call domain_list() as this function is called from
init_domain_list() and we'll get stuck in a loop. */
@@ -111,7 +112,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
fstrcpy(domain->name, alt_name);
fstrcpy(domain->alt_name, domain_name);
} else {
- fstrcpy(domain->name, domain_name);
+ fstrcpy(domain->name, domain_name);
if (alt_name) {
fstrcpy(domain->alt_name, alt_name);
}
@@ -125,10 +126,12 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
sid_copy(&domain->sid, sid);
}
- /* see if this is a native mode win2k domain */
+ /* see if this is a native mode win2k domain (use realm name if possible) */
- domain->native_mode = cm_check_for_native_mode_win2k( domain_name );
- DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain_name,
+ contact_name = *domain->alt_name ? domain->alt_name : domain->name;
+ domain->native_mode = cm_check_for_native_mode_win2k( contact_name );
+
+ DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", contact_name,
domain->native_mode ? "native" : "mixed (or NT4)" ));
/* Link to domain list */
@@ -145,50 +148,67 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
/*
rescan our domains looking for new trusted domains
*/
-void rescan_trusted_domains(BOOL force)
+void add_trusted_domains( struct winbindd_domain *domain )
{
- struct winbindd_domain *domain;
TALLOC_CTX *mem_ctx;
- static time_t last_scan;
- time_t t = time(NULL);
+ NTSTATUS result;
+ time_t t;
+ char **names;
+ char **alt_names;
+ int num_domains = 0;
+ DOM_SID *dom_sids, null_sid;
+ int i;
+ struct winbindd_domain *new_domain;
/* trusted domains might be disabled */
if (!lp_allow_trusted_domains()) {
return;
}
- /* Only rescan every few minutes but force if necessary */
-
- if (((unsigned)(t - last_scan) < WINBINDD_RESCAN_FREQ) && !force)
- return;
-
- last_scan = t;
-
DEBUG(1, ("scanning trusted domain list\n"));
if (!(mem_ctx = talloc_init("init_domain_list")))
return;
+
+ ZERO_STRUCTP(&null_sid);
- 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;
- }
+ t = time(NULL);
+
+ /* ask the DC what domains it trusts */
+
+ result = domain->methods->trusted_domains(domain, mem_ctx, (unsigned int *)&num_domains,
+ &names, &alt_names, &dom_sids);
+
+ if ( NT_STATUS_IS_OK(result) ) {
- /* Add each domain to the trusted domain list. Each domain inherits
- the access methods of its parent */
+ /* Add each domain to the trusted domain list */
+
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]);
+ domain->methods, &dom_sids[i]);
+
+ /* if the SID was empty, we better set it now */
+
+ if ( sid_equal(&dom_sids[i], &null_sid) ) {
+
+ new_domain = find_domain_from_name(names[i]);
+
+ /* this should never happen */
+ if ( !new_domain ) {
+ DEBUG(0,("rescan_trust_domains: can't find the domain I just added! [%s]\n",
+ names[i]));
+ break;
+ }
+
+ /* call the cache method; which will operate on the winbindd_domain \
+ passed in and choose either rpc or ads as appropriate */
+
+ result = domain->methods->domain_sid( new_domain, &new_domain->sid );
+
+ if ( NT_STATUS_IS_OK(result) )
+ sid_copy( &dom_sids[i], &new_domain->sid );
+ }
/* store trusted domain in the cache */
trustdom_cache_store(names[i], alt_names ? alt_names[i] : NULL,
@@ -209,7 +229,9 @@ BOOL init_domain_list(void)
free_domain_list();
/* Add ourselves as the first entry */
- domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL);
+
+ domain = add_trusted_domain( lp_workgroup(), NULL, &cache_methods, NULL);
+
if (!secrets_fetch_domain_sid(domain->name, &domain->sid)) {
DEBUG(1, ("Could not fetch sid for our domain %s\n",
domain->name));
@@ -220,7 +242,7 @@ BOOL init_domain_list(void)
cache_methods.alternate_name(domain);
/* do an initial scan for trusted domains */
- rescan_trusted_domains(True);
+ add_trusted_domains(domain);
return True;
}
@@ -782,3 +804,53 @@ BOOL winbindd_upgrade_idmap(void)
return idmap_convert(idmap_name);
}
+
+/*******************************************************************
+ wrapper around retrieving the trust account password
+*******************************************************************/
+
+BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
+ time_t *pass_last_set_time, uint32 *channel)
+{
+ DOM_SID sid;
+ char *pwd;
+
+ /* if we are a DC and this is not our domain, then lookup an account
+ for the domain trust */
+
+ if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() )
+ {
+ if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
+ pass_last_set_time) )
+ {
+ DEBUG(0, ("get_trust_pw: could not fetch trust account "
+ "password for trusted domain %s\n", domain));
+ return False;
+ }
+
+ *channel = SEC_CHAN_DOMAIN;
+ E_md4hash(pwd, ret_pwd);
+ SAFE_FREE(pwd);
+
+ return True;
+ }
+ else /* just get the account for our domain (covers
+ ROLE_DOMAIN_MEMBER as well */
+ {
+ /* get the machine trust account for our domain */
+
+ if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd,
+ pass_last_set_time, channel) )
+ {
+ DEBUG(0, ("get_trust_pw: could not fetch trust account "
+ "password for my domain %s\n", domain));
+ return False;
+ }
+
+ return True;
+ }
+
+ /* Failure */
+ return False;
+}
+
diff --git a/source/nsswitch/winbindd_wins.c b/source/nsswitch/winbindd_wins.c
index 66903e250da..49bee2dc9f7 100644
--- a/source/nsswitch/winbindd_wins.c
+++ b/source/nsswitch/winbindd_wins.c
@@ -137,7 +137,7 @@ enum winbindd_result winbindd_wins_byip(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
- DEBUG(3, ("[%5d]: wins_byip %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: wins_byip %s\n", (unsigned long)state->pid,
state->request.data.winsreq));
*response = '\0';
@@ -184,7 +184,7 @@ enum winbindd_result winbindd_wins_byname(struct winbindd_cli_state *state)
/* Ensure null termination */
state->request.data.winsreq[sizeof(state->request.data.winsreq)-1]='\0';
- DEBUG(3, ("[%5d]: wins_byname %s\n", state->pid,
+ DEBUG(3, ("[%5lu]: wins_byname %s\n", (unsigned long)state->pid,
state->request.data.winsreq));
*response = '\0';
diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c
index 62493ef0a9e..87dac60192e 100644
--- a/source/nsswitch/wins.c
+++ b/source/nsswitch/wins.c
@@ -86,29 +86,6 @@ static void nss_wins_init(void)
load_interfaces();
}
-static struct node_status *lookup_byaddr_backend(char *addr, int *count)
-{
- int fd;
- struct in_addr ip;
- struct nmb_name nname;
- struct node_status *status;
-
- if (!initialised) {
- nss_wins_init();
- }
-
- fd = wins_lookup_open_socket_in();
- if (fd == -1)
- return NULL;
-
- make_nmb_name(&nname, "*", 0);
- ip = *interpret_addr2(addr);
- status = node_status_query(fd,&nname,ip, count);
-
- close(fd);
- return status;
-}
-
static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
int fd = -1;
@@ -149,8 +126,31 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
return ret;
}
-
#ifdef HAVE_NS_API_H
+
+static struct node_status *lookup_byaddr_backend(char *addr, int *count)
+{
+ int fd;
+ struct in_addr ip;
+ struct nmb_name nname;
+ struct node_status *status;
+
+ if (!initialised) {
+ nss_wins_init();
+ }
+
+ fd = wins_lookup_open_socket_in();
+ if (fd == -1)
+ return NULL;
+
+ make_nmb_name(&nname, "*", 0);
+ ip = *interpret_addr2(addr);
+ status = node_status_query(fd,&nname,ip, count);
+
+ close(fd);
+ return status;
+}
+
/* IRIX version */
int init(void)
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index dd429fa6889..70efa8042b0 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -8,7 +8,7 @@
Copyright (C) Simo Sorce 2001
Copyright (C) Alexander Bokovoy 2002
Copyright (C) Stefan (metze) Metzmacher 2002
- Copyright (C) Anthony Liguori 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
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
@@ -292,6 +292,7 @@ typedef struct
int restrict_anonymous;
int name_cache_timeout;
int client_signing;
+ int server_signing;
param_opt_struct *param_opt;
}
global;
@@ -693,15 +694,18 @@ static const struct enum_list enum_smb_signing_vals[] = {
{False, "False"},
{False, "0"},
{False, "Off"},
+ {False, "disabled"},
{True, "Yes"},
{True, "True"},
{True, "1"},
{True, "On"},
- {Required, "Required"},
- {Required, "Mandatory"},
- {Required, "Force"},
- {Required, "Forced"},
- {Required, "Enforced"},
+ {True, "enabled"},
+ {Auto, "auto"},
+ {Required, "required"},
+ {Required, "mandatory"},
+ {Required, "force"},
+ {Required, "forced"},
+ {Required, "enforced"},
{-1, NULL}
};
@@ -736,426 +740,431 @@ static const struct enum_list enum_map_to_guest[] = {
/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
*
- * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
- * is implied in current control logic. This may change at some later time. A
- * flag value of 0 means - show as development option only.
- *
* The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
* screen in SWAT. This is used to exclude parameters as well as to squash all
* parameters that have been duplicated by pseudonyms.
+ *
+ * NOTE: To display a parameter in BASIC view set FLAG_BASIC
+ * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
+ * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
+ * respective views.
*/
+
static struct parm_struct parm_table[] = {
- {"Base Options", P_SEP, P_SEPARATOR},
-
- {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
- {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
- {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
- {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
-
- {"Security Options", P_SEP, P_SEPARATOR},
-
- {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
- {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
- {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
-
- {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT},
- {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
- {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
- {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
- {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
- {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
- {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
-
- {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
- {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
- {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
- {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
- {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_SHARE},
- {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
- {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
-
- {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
- {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
-
- {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
- {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
- {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
- {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
- {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
- {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
-
- {"Logging Options", P_SEP, P_SEPARATOR},
-
- {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
- {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_DEVELOPER},
- {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_DEVELOPER},
- {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_DEVELOPER},
- {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_DEVELOPER},
-
- {"Protocol Options", P_SEP, P_SEPARATOR},
-
- {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
- {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
- {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
- {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
- {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_DEVELOPER},
- {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
- {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
- {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED},
-
- {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
- {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
- {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
- {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_DEVELOPER},
-
- {"Tuning Options", P_SEP, P_SEPARATOR},
-
- {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_DEVELOPER},
- {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_DEVELOPER},
- {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_DEVELOPER},
- {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_DEVELOPER},
-
- {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
- {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_DEVELOPER},
- {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
- {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
- {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_DEVELOPER},
- {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
- {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_DEVELOPER},
-
- {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_DEVELOPER},
- {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE},
- {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
- {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
- {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
- {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_SHARE},
- {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"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, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"Printing Options", P_SEP, P_SEPARATOR},
-
- {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_PRINT},
- {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
- {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
- {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
- {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
- {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
- {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
- {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
- {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
- {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
- {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
- {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
- {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
- {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
- {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
- {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
-
- {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
- {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
- {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT},
- {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_PRINT},
-
- {"Filename Handling", P_SEP, P_SEPARATOR},
- {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
- {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE},
- {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"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 special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, 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 },
- {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
- {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_DEVELOPER},
-
- {"Domain Options", P_SEP, P_SEPARATOR},
-
- {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
-
- {"Logon Options", P_SEP, P_SEPARATOR},
-
- {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"Browse Options", P_SEP, P_SEPARATOR},
-
- {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
- {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
- {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
- {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
- {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
-
- {"WINS Options", P_SEP, P_SEPARATOR},
-
- {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
- {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
+ {"Base Options", P_SEP, P_SEPARATOR},
+
+ {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED},
+ {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED},
+ {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED},
+ {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
+ {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
+#ifdef WITH_ADS
+ {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
+#endif
+ {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
+ {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
+ {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
+ {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
+ {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
+ {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
+
+ {"Security Options", P_SEP, P_SEPARATOR},
+
+ {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
+ {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
+ {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
+ {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
+ {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
+ {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
+ {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
+ {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED},
+ {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
+ {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
+ {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
+ {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
+ {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
+ {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
+ {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
+ {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
+ {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
+ {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
+ {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
+ {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
+ {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
+ {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
+
+ {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
+ {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
+ {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
+ {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
+ {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
+ {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
+ {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
+ {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
+ {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
+ {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
+ {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
+ {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
+ {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
+ {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
+
+ {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
+ {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
+
+ {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT},
+ {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
+
+ {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
+ {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
+ {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
+ {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
+
+ {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
+ {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
+ {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+ {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
+
+ {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
+
+ {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
+ {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
+ {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
+
+ {"Logging Options", P_SEP, P_SEPARATOR},
+
+ {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
+ {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
+ {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
+ {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
+ {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
+
+ {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
+ {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
+ {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
+ {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
+ {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
+ {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
+
+ {"Protocol Options", P_SEP, P_SEPARATOR},
+
+ {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
+ {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
+ {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
+ {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
+ {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
+ {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_ADVANCED},
+ {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED},
+ {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
+ {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
+ {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
+
+ {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
+ {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
+ {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
+
+ {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
+ {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
+ {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
+ {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
+
+ {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
+ {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
+ {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
+ {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
+ {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
+ {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
+ {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
+ {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
+ {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
+ {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
+
+ {"Tuning Options", P_SEP, P_SEPARATOR},
+
+ {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_ADVANCED},
+ {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
+ {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
+ {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
+ {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED},
+
+ {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
+ {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
+ {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
+ {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
+ {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
+ {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_ADVANCED},
+
+ {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
+ {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
+ {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
+ {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+
+ {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
+
+ {"Printing Options", P_SEP, P_SEPARATOR},
+
+ {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
+ {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
+ {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+ {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
+
+ {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
+ {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
+ {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
+ {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
+ {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
+
+ {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
+ {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+ {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
+
+ {"Filename Handling", P_SEP, P_SEPARATOR},
+ {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED},
+ {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
+ {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
+
+ {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED},
+ {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
+ {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE},
+ {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
+ {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
+ {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
+ {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
+
+ {"Domain Options", P_SEP, P_SEPARATOR},
+
+ {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
+
+ {"Logon Options", P_SEP, P_SEPARATOR},
+
+ {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
+ {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
+ {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
+ {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
+ {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
+ {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
+ {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
+ {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
+ {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
+ {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
+
+ {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
+ {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
+ {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
+ {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
+ {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
+
+ {"Browse Options", P_SEP, P_SEPARATOR},
+
+ {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
+ {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
+ {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
+ {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
+ {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
+ {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
+ {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
+ {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
+ {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
+ {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
+
+ {"WINS Options", P_SEP, P_SEPARATOR},
+
+ {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
+ {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
+
+ {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
+ {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
+ {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
+ {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
+
+ {"Locking Options", P_SEP, P_SEPARATOR},
+
+ {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
+ {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
+ {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
+
+ {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
+ {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+
+ {"Ldap Options", P_SEP, P_SEPARATOR},
- {"Locking Options", P_SEP, P_SEPARATOR},
-
- {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
- {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
- {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
- {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
- {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
-
- {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_GLOBAL},
- {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
-
- {"Ldap Options", P_SEP, P_SEPARATOR},
-
#ifdef WITH_LDAP_SAMCONFIG
- {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
- {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
+ {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, FLAG_ADVANCED},
+ {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, FLAG_ADVANCED},
#endif
- {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"Miscellaneous Options", P_SEP, P_SEPARATOR},
- {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
- {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED},
+ {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED},
+ {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED},
+ {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED},
+ {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, handle_ldap_sub_suffix, NULL, FLAG_ADVANCED},
+ {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED},
+ {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
+ {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
+ {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
+ {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED},
+ {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
+
+ {"Miscellaneous Options", P_SEP, P_SEPARATOR},
+ {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
+ {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
+ {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
+
+ {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
+ {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
+ {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
+ {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
{"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
- {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
#ifdef WITH_UTMP
- {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
+ {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
+ {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
+ {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
#endif
-
- {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
- {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
- {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
-
- {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
- {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
- {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
- {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE},
- {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
- {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
- {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE},
- {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
- {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
- {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
- {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
- {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE},
- {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE},
- {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE},
- {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE},
- {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
-
- {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
- {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"VFS module options", P_SEP, P_SEPARATOR},
-
- {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_SHARE},
- {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_SHARE | FLAG_HIDE},
-
- {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
- {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
- {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {"Winbind options", P_SEP, P_SEPARATOR},
-
- {"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_DEPRECATED},
- {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
- {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER },
- {"template primary group", P_STRING, P_GLOBAL, &Globals.szTemplatePrimaryGroup, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind enable local accounts", P_BOOL, P_GLOBAL, &Globals.bWinbindEnableLocalAccounts, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
- {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
-
- {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
+ {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
+ {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
+ {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
+ {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED},
+ {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
+ {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
+ {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
+ {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
+ {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
+ {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
+ {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
+ {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
+ {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
+
+ {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
+ {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
+ {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
+
+ {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
+ {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
+ {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, FLAG_ADVANCED},
+ {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+
+ {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
+ {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED},
+
+ {"VFS module options", P_SEP, P_SEPARATOR},
+
+ {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
+
+
+ {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
+ {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
+
+ {"Winbind options", P_SEP, P_SEPARATOR},
+
+ {"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_DEPRECATED},
+ {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED},
+ {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED},
+ {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED},
+ {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED},
+ {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED},
+ {"template primary group", P_STRING, P_GLOBAL, &Globals.szTemplatePrimaryGroup, NULL, NULL, FLAG_ADVANCED},
+ {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
+ {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
+ {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
+ {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
+ {"winbind enable local accounts", P_BOOL, P_GLOBAL, &Globals.bWinbindEnableLocalAccounts, NULL, NULL, FLAG_ADVANCED},
+ {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
+ {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
+ {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
+ {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
+
+ {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
/***************************************************************************
@@ -1419,12 +1428,13 @@ static void init_globals(void)
Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
-
+ Globals.bClientNTLMv2Auth = True; /* Client should use NTLMv2 if available. */
+
Globals.map_to_guest = 0; /* By Default, "Never" */
Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */
Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
Globals.enhanced_browsing = True;
- Globals.iLockSpinCount = 3; /* Try 2 times. */
+ Globals.iLockSpinCount = 3; /* Try 3 times. */
Globals.iLockSpinTime = 10; /* usec. */
#ifdef MMAP_BLACKLIST
Globals.bUseMmap = False;
@@ -1506,6 +1516,9 @@ static void init_globals(void)
Globals.bUseSpnego = True;
Globals.bClientUseSpnego = True;
+ Globals.client_signing = Auto;
+ Globals.server_signing = False;
+
string_set(&Globals.smb_ports, SMB_PORTS);
}
@@ -1860,7 +1873,7 @@ FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
-FN_LOCAL_BOOL(lp_use_sendfile, bUseSendfile)
+FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
@@ -1885,7 +1898,8 @@ FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
-FN_GLOBAL_BOOL(lp_client_signing, &Globals.client_signing)
+FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
+FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
/* local prototypes */
@@ -4286,3 +4300,12 @@ int lp_maxprintjobs(int snum)
return maxjobs;
}
+
+/*******************************************************************
+ Ensure we don't use sendfile if server smb signing is active.
+********************************************************************/
+
+BOOL lp_use_sendfile(int snum)
+{
+ return (_lp_use_sendfile(snum) && !srv_is_signing_active());
+}
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index 9a99e07d828..34a5f7e32aa 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -758,13 +758,25 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
if (fallback_pdb_rid_is_user(rid)) {
uid_t uid;
+ struct passwd *pw = NULL;
DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
uid = fallback_pdb_user_rid_to_uid(rid);
- slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
-
- return False; /* Indicates that this user was 'not mapped' */
+ pw = sys_getpwuid( uid );
+
+ DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
+ pw ? "succeeded" : "failed" ));
+
+ if ( !pw )
+ fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
+ else
+ fstrcpy( name, pw->pw_name );
+
+ DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
+ (unsigned int)rid ));
+
+ return ( pw != NULL );
} else {
gid_t gid;
struct group *gr;
@@ -779,16 +791,15 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
DEBUG(5,("local_lookup_sid: looking up gid %u %s\n", (unsigned int)gid,
gr ? "succeeded" : "failed" ));
- if(!gr) {
- slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
- return False; /* Indicates that this group was 'not mapped' */
- }
-
- fstrcpy( name, gr->gr_name);
+ if( !gr )
+ fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
+ else
+ fstrcpy( name, gr->gr_name);
DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
(unsigned int)rid ));
- return True;
+
+ return ( gr != NULL );
}
}
@@ -1056,7 +1067,7 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
unix_pw = sys_getpwuid( uid );
if ( !unix_pw ) {
- DEBUG(4,("local_uid_to_sid: host has know idea of uid %d\n", uid));
+ DEBUG(4,("local_uid_to_sid: host has know idea of uid %lu\n", (unsigned long)uid));
return NULL;
}
@@ -1072,8 +1083,8 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
if ( ret )
sid_copy( psid, pdb_get_user_sid(sampw) );
else {
- DEBUG(4,("local_uid_to_sid: User %s [uid == %d] has no samba account\n",
- unix_pw->pw_name, uid));
+ DEBUG(4,("local_uid_to_sid: User %s [uid == %lu] has no samba account\n",
+ unix_pw->pw_name, (unsigned long)uid));
if ( !lp_enable_rid_algorithm() )
return NULL;
@@ -1156,11 +1167,18 @@ BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_
DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
{
GROUP_MAP group;
+ BOOL ret;
/* we don't need to disable winbindd since the gid is stored in
the GROUP_MAP object */
+
+ /* done as root since ldap backend requires root to open a connection */
- if ( !pdb_getgrgid( &group, gid ) ) {
+ become_root();
+ ret = pdb_getgrgid( &group, gid );
+ unbecome_root();
+
+ if ( !ret ) {
/* fallback to rid mapping if enabled */
@@ -1289,6 +1307,7 @@ BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
BOOL ret = True;
uid_t uid = -1;
gid_t gid = -1;
+ struct passwd *pw = NULL;
if(sampass == NULL || buf == NULL) {
DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n"));
@@ -1296,7 +1315,7 @@ BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
/* unpack the buffer into variables */
- len = tdb_unpack (buf, buflen, TDB_FORMAT_STRING,
+ len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING,
&logon_time,
&logoff_time,
&kickoff_time,
@@ -1344,6 +1363,12 @@ BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
pdb_set_nt_username(sampass, nt_username, PDB_SET);
pdb_set_fullname(sampass, fullname, PDB_SET);
+
+ if ( (pw=Get_Pwnam(username)) != NULL ) {
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ }
+
if (homedir) {
pdb_set_homedir(sampass, homedir, PDB_SET);
}
@@ -1633,7 +1658,7 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_
}
/* now for the real call to tdb_pack() */
- buflen = tdb_pack(*buf, len, TDB_FORMAT_STRING,
+ buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING,
logon_time,
logoff_time,
kickoff_time,
@@ -1667,8 +1692,8 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_
/* check to make sure we got it correct */
if (buflen != len) {
- DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%d) != len (%d) in tdb_pack operations!\n",
- buflen, len));
+ DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
+ (unsigned long)buflen, (unsigned long)len));
/* error */
SAFE_FREE (*buf);
return (-1);
@@ -1676,3 +1701,51 @@ uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_
return (buflen);
}
+
+
+/**********************************************************************
+**********************************************************************/
+
+static BOOL get_free_ugid_range(uint32 *low, uint32 *high)
+{
+ uid_t u_low, u_high;
+ gid_t g_low, g_high;
+
+ if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
+ return False;
+ }
+
+ *low = (u_low < g_low) ? u_low : g_low;
+ *high = (u_high < g_high) ? u_high : g_high;
+
+ return True;
+}
+
+/******************************************************************
+ Get the the non-algorithmic RID range if idmap range are defined
+******************************************************************/
+
+BOOL get_free_rid_range(uint32 *low, uint32 *high)
+{
+ uint32 id_low, id_high;
+
+ if (!lp_enable_rid_algorithm()) {
+ *low = BASE_RID;
+ *high = (uint32)-1;
+ }
+
+ if (!get_free_ugid_range(&id_low, &id_high)) {
+ return False;
+ }
+
+ *low = fallback_pdb_uid_to_user_rid(id_low);
+ if (fallback_pdb_user_rid_to_uid((uint32)-1) < id_high) {
+ *high = (uint32)-1;
+ } else {
+ *high = fallback_pdb_uid_to_user_rid(id_high);
+ }
+
+ return True;
+}
+
+
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
index ba07a4e01c8..15054585512 100644
--- a/source/passdb/pdb_get_set.c
+++ b/source/passdb/pdb_get_set.c
@@ -1027,9 +1027,18 @@ BOOL pdb_set_backend_private_data (SAM_ACCOUNT *sampass, void *private_data,
if (!sampass)
return False;
+#if 0
+ /* With this check backend_private_data_free_fn is *never* set
+ as the methods are never set anywhere. What is this
+ supposed to do ????
+
+ Volker
+ */
+
/* does this backend 'own' this SAM_ACCOUNT? */
if (my_methods != sampass->private.backend_private_methods)
return False;
+#endif
if (sampass->private.backend_private_data && sampass->private.backend_private_data_free_fn) {
sampass->private.backend_private_data_free_fn(&sampass->private.backend_private_data);
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 84ac6c576a8..66c4133c4a9 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -104,7 +104,7 @@ struct ldapsam_privates {
static void private_data_free_fn(void **result)
{
- ldap_memfree(*result);
+ ldap_msgfree(*result);
*result = NULL;
}
@@ -161,10 +161,10 @@ static const char* get_objclass_filter( int schema_ver )
switch( schema_ver )
{
case SCHEMAVER_SAMBAACCOUNT:
- snprintf( objclass_filter, sizeof(objclass_filter)-1, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
+ fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBAACCOUNT );
break;
case SCHEMAVER_SAMBASAMACCOUNT:
- snprintf( objclass_filter, sizeof(objclass_filter)-1, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
+ fstr_sprintf( objclass_filter, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
break;
default:
DEBUG(0,("pdb_ldapsam: get_objclass_filter(): Invalid schema version specified!\n"));
@@ -192,7 +192,7 @@ static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state,
* in the filter expression, replace %u with the real name
* so in ldap filter, %u MUST exist :-)
*/
- snprintf(filter, sizeof(filter)-1, "(&%s%s)", lp_ldap_filter(),
+ pstr_sprintf(filter, "(&%s%s)", lp_ldap_filter(),
get_objclass_filter(ldap_state->schema_ver));
/*
@@ -217,7 +217,7 @@ static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
pstring filter;
int rc;
- snprintf(filter, sizeof(filter)-1, "(&(rid=%i)%s)", rid,
+ pstr_sprintf(filter, "(&(rid=%i)%s)", rid,
get_objclass_filter(ldap_state->schema_ver));
rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
@@ -236,7 +236,7 @@ static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
int rc;
fstring sid_string;
- snprintf(filter, sizeof(filter)-1, "(&(%s=%s)%s)",
+ pstr_sprintf(filter, "(&(%s=%s)%s)",
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
sid_to_string(sid_string, sid),
get_objclass_filter(ldap_state->schema_ver));
@@ -419,8 +419,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
uint32 hours_len;
uint8 hours[MAX_HOURS_LEN];
pstring temp;
+ struct passwd *pw = NULL;
uid_t uid = -1;
- gid_t gid = getegid();
+ gid_t gid = -1;
/*
* do a little initialization
@@ -455,6 +456,14 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
DEBUG(2, ("Entry found for user: %s\n", username));
+ /* I'm not going to fail here, since there are checks
+ higher up the cal stack to do this --jerry */
+
+ if ( (pw=Get_Pwnam(username)) != NULL ) {
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ }
+
pstrcpy(nt_username, username);
pstrcpy(domain, ldap_state->domain_name);
@@ -956,7 +965,7 @@ static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
pstring filter;
char **attr_list;
- snprintf( filter, sizeof(filter)-1, "(&%s%s)", lp_ldap_filter(),
+ pstr_sprintf( filter, "(&%s%s)", lp_ldap_filter(),
get_objclass_filter(ldap_state->schema_ver));
all_string_sub(filter, "%u", "*", sizeof(pstring));
@@ -1377,6 +1386,7 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
element_is_changed)) {
DEBUG(0, ("ldapsam_update_sam_account: init_ldap_from_sam failed!\n"));
+ ldap_memfree(dn);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -1384,11 +1394,13 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
DEBUG(4,("mods is empty: nothing to update for user: %s\n",
pdb_get_username(newpwd)));
ldap_mods_free(mods, True);
+ ldap_memfree(dn);
return NT_STATUS_OK;
}
ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,LDAP_MOD_REPLACE, element_is_changed);
ldap_mods_free(mods,True);
+ ldap_memfree(dn);
if (!NT_STATUS_IS_OK(ret)) {
char *ld_error = NULL;
@@ -1516,7 +1528,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
/* There might be a SID for this account already - say an idmap entry */
- snprintf(filter, sizeof(filter)-1, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
+ pstr_sprintf(filter, "(&(%s=%s)(|(objectClass=%s)(objectClass=%s)))",
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
sid_to_string(sid_string, sid),
LDAP_OBJ_IDMAP_ENTRY,
@@ -1682,7 +1694,7 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE)));
return False;
}
- map->sid_name_use = (uint32)atol(temp);
+ map->sid_name_use = (enum SID_NAME_USE)atol(temp);
if ((map->sid_name_use < SID_NAME_USER) ||
(map->sid_name_use > SID_NAME_UNKNOWN)) {
@@ -1698,7 +1710,7 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp))
{
DEBUG(0, ("Attributes cn not found either "
- "for gidNumber(%i)\n",map->gid));
+ "for gidNumber(%lu)\n",(unsigned long)map->gid));
return False;
}
}
@@ -1734,7 +1746,7 @@ static BOOL init_ldap_from_group(LDAP *ldap_struct,
sid_to_string(tmp, &map->sid);
smbldap_make_mod(ldap_struct, existing, mods,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID), tmp);
- snprintf(tmp, sizeof(tmp)-1, "%i", map->sid_name_use);
+ pstr_sprintf(tmp, "%i", map->sid_name_use);
smbldap_make_mod(ldap_struct, existing, mods,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp);
@@ -1805,7 +1817,7 @@ static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
{
pstring filter;
- snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
LDAP_OBJ_GROUPMAP,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_SID),
sid_string_static(&sid));
@@ -1821,10 +1833,10 @@ static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
{
pstring filter;
- snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%d))",
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
LDAP_OBJ_GROUPMAP,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
- gid);
+ (unsigned long)gid);
return ldapsam_getgroup(methods, filter, map);
}
@@ -1842,7 +1854,7 @@ static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
return NT_STATUS_NO_MEMORY;
}
- snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
+ pstr_sprintf(filter, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))",
LDAP_OBJ_GROUPMAP,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), escape_name,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_CN), escape_name);
@@ -1861,10 +1873,10 @@ static int ldapsam_search_one_group_by_gid(struct ldapsam_privates *ldap_state,
{
pstring filter;
- snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%i))",
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
LDAP_OBJ_POSIXGROUP,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER),
- gid);
+ (unsigned long)gid);
return ldapsam_search_one_group(ldap_state, filter, result);
}
@@ -1891,7 +1903,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
map->gid))) {
- DEBUG(0, ("Group %i already exists in LDAP\n", map->gid));
+ DEBUG(0, ("Group %ld already exists in LDAP\n", (unsigned long)map->gid));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -1909,8 +1921,8 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
}
if (count > 1) {
- DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
- map->gid));
+ DEBUG(2, ("Group %lu must exist exactly once in LDAP\n",
+ (unsigned long)map->gid));
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -1944,13 +1956,13 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
char *ld_error = NULL;
ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
- DEBUG(0, ("failed to add group %i error: %s (%s)\n", map->gid,
+ DEBUG(0, ("failed to add group %lu error: %s (%s)\n", (unsigned long)map->gid,
ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
SAFE_FREE(ld_error);
return NT_STATUS_UNSUCCESSFUL;
}
- DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
+ DEBUG(2, ("successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
return NT_STATUS_OK;
}
@@ -2005,12 +2017,12 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
char *ld_error = NULL;
ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
- DEBUG(0, ("failed to modify group %i error: %s (%s)\n", map->gid,
+ DEBUG(0, ("failed to modify group %lu error: %s (%s)\n", (unsigned long)map->gid,
ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
SAFE_FREE(ld_error);
}
- DEBUG(2, ("successfully modified group %i in LDAP\n", map->gid));
+ DEBUG(2, ("successfully modified group %lu in LDAP\n", (unsigned long)map->gid));
return NT_STATUS_OK;
}
@@ -2029,7 +2041,7 @@ static NTSTATUS ldapsam_delete_group_mapping_entry(struct pdb_methods *methods,
sid_to_string(sidstring, &sid);
- snprintf(filter, sizeof(filter)-1, "(&(objectClass=%s)(%s=%s))",
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
LDAP_OBJ_GROUPMAP, LDAP_ATTRIBUTE_SID, sidstring);
rc = ldapsam_search_one_group(ldap_state, filter, &result);
@@ -2057,7 +2069,7 @@ static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
int rc;
char **attr_list;
- snprintf( filter, sizeof(filter)-1, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
+ pstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
attr_list = get_attr_list( groupmap_attr_list );
rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
LDAP_SCOPE_SUBTREE, filter,
@@ -2125,7 +2137,6 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
GROUP_MAP map;
GROUP_MAP *mapt;
int entries = 0;
- NTSTATUS nt_status;
*num_entries = 0;
*rmap = NULL;
@@ -2135,7 +2146,7 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
return NT_STATUS_ACCESS_DENIED;
}
- while (NT_STATUS_IS_OK(nt_status = ldapsam_getsamgrent(methods, &map))) {
+ while (NT_STATUS_IS_OK(ldapsam_getsamgrent(methods, &map))) {
if (sid_name_use != SID_NAME_UNKNOWN &&
sid_name_use != map.sid_name_use) {
DEBUG(11,("enum_group_mapping: group %s is not of the requested type\n", map.nt_name));
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index 055e8e71bac..8171b65adcc 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -179,8 +179,25 @@ static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int
DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile));
if((fp = sys_fopen(pfile, open_mode)) == NULL) {
- DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) ));
- return NULL;
+
+ /*
+ * If smbpasswd file doesn't exist, then create new one. This helps to avoid
+ * confusing error msg when adding user account first time.
+ */
+ if (errno == ENOENT) {
+ if ((fp = sys_fopen(pfile, "a+")) != NULL) {
+ DEBUG(0, ("startsmbfilepwent_internal: file %s did not exist. File successfully created.\n", pfile));
+
+ } else {
+ DEBUG(0, ("startsmbfilepwent_internal: file %s did not exist. Couldn't create new one. Error was: %s",
+ pfile, strerror(errno)));
+ return NULL;
+ }
+
+ } else {
+ DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was: %s\n", pfile, strerror(errno)));
+ return NULL;
+ }
}
if (!pw_file_lock(fileno(fp), lock_type, 5, lock_depth)) {
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index 1078a5bd265..c9a84f3242c 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -133,7 +133,7 @@ static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *
}
/* unpack the buffer */
- if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
+ if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
return nt_status;
@@ -180,6 +180,24 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT
/* open the accounts TDB */
if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
+
+ if (errno == ENOENT) {
+ /*
+ * TDB file doesn't exist, so try to create new one. This is useful to avoid
+ * confusing error msg when adding user account first time
+ */
+ if (!(pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_CREAT, 0600))) {
+ DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) did not exist. File successfully created.\n",
+ tdb_state->tdbsam_location));
+ } else {
+ DEBUG(0, ("pdb_getsampwnam: TDB passwd (%s) does not exist. Couldn't create new one. Error was: %s\n",
+ tdb_state->tdbsam_location, strerror(errno)));
+ }
+
+ /* requested user isn't there anyway */
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ return nt_status;
+ }
DEBUG(0, ("pdb_getsampwnam: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
return nt_status;
}
@@ -195,7 +213,7 @@ static NTSTATUS tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT
}
/* unpack the buffer */
- if (!init_sam_from_buffer(user, data.dptr, data.dsize)) {
+ if (!init_sam_from_buffer(user, (unsigned char *)data.dptr, data.dsize)) {
DEBUG(0,("pdb_getsampwent: Bad SAM_ACCOUNT entry returned from TDB!\n"));
SAFE_FREE(data.dptr);
tdb_close(pwd_tdb);
@@ -372,7 +390,7 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd,
ret = False;
goto done;
}
- data.dptr = buf;
+ data.dptr = (char *)buf;
fstrcpy(name, pdb_get_username(newpwd));
strlower_m(name);
@@ -419,49 +437,6 @@ done:
return (ret);
}
-#if 0
-/***************************************************************************
- Allocates a new RID and returns it to the caller as a domain sid
-
- NOTE: Use carefullt, do not waste RIDs they are a limited resource!
- - SSS
- ***************************************************************************/
-
-static NTSTATUS tdbsam_get_next_sid (struct pdb_methods *my_methods, DOM_SID *sid)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_CONTEXT *pwd_tdb;
- uint32 rid;
-
- if (sid == NULL) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
- if (!pwd_tdb)
- {
- DEBUG(0, ("tdbsam_get_next_sid: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- rid = BASE_RID;
- if (tdb_change_uint32_atomic(pwd_tdb, "RID_COUNTER", &rid, 1)) {
-
- sid_copy(sid, get_global_sam_sid());
- if (!sid_append_rid(sid, rid)) {
- goto done;
- }
-
- ret = NT_STATUS_OK;
- }
-
-done:
- tdb_close (pwd_tdb);
- return ret;
-}
-#endif
-
/***************************************************************************
Modifies an existing SAM_ACCOUNT
****************************************************************************/
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index bad8e96865c..2c99631e130 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -58,7 +58,7 @@ void *secrets_fetch(const char *key, size_t *size)
secrets_init();
if (!tdb)
return NULL;
- kbuf.dptr = key;
+ kbuf.dptr = (char *)key;
kbuf.dsize = strlen(key);
dbuf = tdb_fetch(tdb, kbuf);
if (size)
@@ -74,9 +74,9 @@ BOOL secrets_store(const char *key, const void *data, size_t size)
secrets_init();
if (!tdb)
return False;
- kbuf.dptr = key;
+ kbuf.dptr = (char *)key;
kbuf.dsize = strlen(key);
- dbuf.dptr = data;
+ dbuf.dptr = (char *)data;
dbuf.dsize = size;
return tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) == 0;
}
@@ -90,7 +90,7 @@ BOOL secrets_delete(const char *key)
secrets_init();
if (!tdb)
return False;
- kbuf.dptr = key;
+ kbuf.dptr = (char *)key;
kbuf.dsize = strlen(key);
return tdb_delete(tdb, kbuf) == 0;
}
@@ -195,11 +195,11 @@ const char *trust_keystr(const char *domain)
*
* @return stored password's key
**/
-char *trustdom_keystr(const char *domain)
+static char *trustdom_keystr(const char *domain)
{
- static char* keystr;
+ static pstring keystr;
- asprintf(&keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain);
+ pstr_sprintf(keystr, "%s/%s", SECRETS_DOMTRUST_ACCT_PASS, domain);
strupper_m(keystr);
return keystr;
diff --git a/source/printing/notify.c b/source/printing/notify.c
index 479d883134b..e2146d50189 100644
--- a/source/printing/notify.c
+++ b/source/printing/notify.c
@@ -164,8 +164,8 @@ static void print_notify_send_messages_to_printer(const char *printer, unsigned
}
}
- DEBUG(5, ("print_notify_send_messages_to_printer: sending %d print notify message%s to printer %s\n",
- msg_count, msg_count != 1 ? "s" : "", printer));
+ DEBUG(5, ("print_notify_send_messages_to_printer: sending %lu print notify message%s to printer %s\n",
+ (unsigned long)msg_count, msg_count != 1 ? "s" : "", printer));
/*
* Get the list of PID's to send to.
@@ -272,8 +272,8 @@ in notify_queue\n", msg->type, msg->field, msg->printer));
/* allocate a new msg structure and copy the fields */
if ( !(pnqueue->msg = (SPOOLSS_NOTIFY_MSG*)talloc(send_ctx, sizeof(SPOOLSS_NOTIFY_MSG))) ) {
- DEBUG(0,("send_spoolss_notify2_msg: talloc() of size [%d] failed!\n",
- sizeof(SPOOLSS_NOTIFY_MSG)));
+ DEBUG(0,("send_spoolss_notify2_msg: talloc() of size [%lu] failed!\n",
+ (unsigned long)sizeof(SPOOLSS_NOTIFY_MSG)));
return;
}
copy_notify2_msg(pnqueue->msg, msg);
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index 5e6e95ff7e2..9ac5d2b7449 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -204,13 +204,19 @@ struct table_node {
int version;
};
+#define SPL_ARCH_WIN40 "WIN40"
+#define SPL_ARCH_W32X86 "W32X86"
+#define SPL_ARCH_W32MIPS "W32MIPS"
+#define SPL_ARCH_W32ALPHA "W32ALPHA"
+#define SPL_ARCH_W32PPC "W32PPC"
+
static const struct table_node archi_table[]= {
- {"Windows 4.0", "WIN40", 0 },
- {"Windows NT x86", "W32X86", 2 },
- {"Windows NT R4000", "W32MIPS", 2 },
- {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
- {"Windows NT PowerPC", "W32PPC", 2 },
+ {"Windows 4.0", SPL_ARCH_WIN40, 0 },
+ {"Windows NT x86", SPL_ARCH_W32X86, 2 },
+ {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
+ {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
+ {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
{NULL, "", -1 }
};
@@ -1755,6 +1761,11 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
ZERO_STRUCT(driver);
architecture = get_short_archi(arch);
+
+ /* Windows 4.0 (i.e. win9x) should always use a version of 0 */
+
+ if ( strcmp( arch, SPL_ARCH_WIN40 ) == 0 )
+ version = 0;
DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
@@ -2919,7 +2930,7 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const cha
return WERR_NOMEM;
regval_ctr_addvalue( &p2->data.keys[key_index].values, value,
- type, data, real_len );
+ type, (const char *)data, real_len );
DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
key, value, type, real_len ));
@@ -3012,7 +3023,7 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
/* add the new value */
- regval_ctr_addvalue( &printer_data->keys[key_index].values, valuename, type, data_p, size );
+ regval_ctr_addvalue( &printer_data->keys[key_index].values, valuename, type, (const char *)data_p, size );
SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
diff --git a/source/printing/pcap.c b/source/printing/pcap.c
index 1bdbf4a789e..a5fb53a320d 100644
--- a/source/printing/pcap.c
+++ b/source/printing/pcap.c
@@ -208,7 +208,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
/* probably a good printer ??? */
free (line);
SAFE_FREE(pName);
- fclose(pfile);
+ x_fclose(pfile);
return(True);
}
@@ -222,7 +222,7 @@ static BOOL ScanQconfig(char *psz,char *pszPrintername)
/* it's a good virtual printer */
free (line);
SAFE_FREE(pName);
- fclose(pfile);
+ x_fclose(pfile);
return(True);
}
break;
diff --git a/source/python/py_common.c b/source/python/py_common.c
index ea092d93703..02d22bbdab5 100644
--- a/source/python/py_common.c
+++ b/source/python/py_common.c
@@ -223,7 +223,7 @@ struct cli_state *open_pipe_creds(char *server, PyObject *creds,
result = cli_full_connection(
&cli, NULL, server, NULL, 0, "IPC$", "IPC",
- username, domain, password, 0, NULL);
+ username, domain, password, 0, Undefined, NULL);
if (!NT_STATUS_IS_OK(result)) {
*errstr = strdup("error connecting to IPC$ pipe");
diff --git a/source/python/py_lsa.c b/source/python/py_lsa.c
index c063dcba81f..07191be8682 100644
--- a/source/python/py_lsa.c
+++ b/source/python/py_lsa.c
@@ -104,8 +104,7 @@ done:
if (cli)
cli_shutdown(cli);
- if (mem_ctx)
- talloc_destroy(mem_ctx);
+ talloc_destroy(mem_ctx);
}
return result;
@@ -141,12 +140,13 @@ static PyObject *lsa_close(PyObject *self, PyObject *args, PyObject *kw)
static PyObject *lsa_lookup_names(PyObject *self, PyObject *args)
{
- PyObject *py_names, *result;
+ PyObject *py_names, *result = NULL;
NTSTATUS ntstatus;
lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self;
int num_names, i;
const char **names;
DOM_SID *sids;
+ TALLOC_CTX *mem_ctx = NULL;
uint32 *name_types;
if (!PyArg_ParseTuple(args, "O", &py_names))
@@ -157,18 +157,22 @@ static PyObject *lsa_lookup_names(PyObject *self, PyObject *args)
return NULL;
}
+ if (!(mem_ctx = talloc_init("lsa_lookup_names"))) {
+ PyErr_SetString(lsa_error, "unable to init talloc context\n");
+ goto done;
+ }
+
if (PyList_Check(py_names)) {
/* Convert list to char ** array */
num_names = PyList_Size(py_names);
- names = (const char **)talloc(
- hnd->mem_ctx, num_names * sizeof(char *));
+ names = (const char **)talloc(mem_ctx, num_names * sizeof(char *));
for (i = 0; i < num_names; i++) {
PyObject *obj = PyList_GetItem(py_names, i);
- names[i] = talloc_strdup(hnd->mem_ctx, PyString_AsString(obj));
+ names[i] = talloc_strdup(mem_ctx, PyString_AsString(obj));
}
} else {
@@ -176,17 +180,17 @@ static PyObject *lsa_lookup_names(PyObject *self, PyObject *args)
/* Just a single element */
num_names = 1;
- names = (const char **)talloc(hnd->mem_ctx, sizeof(char *));
+ names = (const char **)talloc(mem_ctx, sizeof(char *));
names[0] = PyString_AsString(py_names);
}
- ntstatus = cli_lsa_lookup_names(hnd->cli, hnd->mem_ctx, &hnd->pol,
+ ntstatus = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol,
num_names, names, &sids, &name_types);
if (!NT_STATUS_IS_OK(ntstatus) && NT_STATUS_V(ntstatus) != 0x107) {
PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
- return NULL;
+ goto done;
}
result = PyList_New(num_names);
@@ -196,10 +200,13 @@ static PyObject *lsa_lookup_names(PyObject *self, PyObject *args)
py_from_SID(&sid_obj, &sids[i]);
- obj = Py_BuildValue("(Oi)", sid_obj, name_types[i]);
+ obj = Py_BuildValue("(Ni)", sid_obj, name_types[i]);
PyList_SetItem(result, i, obj);
}
+
+ done:
+ talloc_destroy(mem_ctx);
return result;
}
@@ -207,12 +214,13 @@ static PyObject *lsa_lookup_names(PyObject *self, PyObject *args)
static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args,
PyObject *kw)
{
- PyObject *py_sids, *result;
+ PyObject *py_sids, *result = NULL;
NTSTATUS ntstatus;
int num_sids, i;
char **domains, **names;
uint32 *types;
lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self;
+ TALLOC_CTX *mem_ctx = NULL;
DOM_SID *sids;
if (!PyArg_ParseTuple(args, "O", &py_sids))
@@ -223,12 +231,17 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args,
return NULL;
}
+ if (!(mem_ctx = talloc_init("lsa_lookup_sids"))) {
+ PyErr_SetString(lsa_error, "unable to init talloc context\n");
+ goto done;
+ }
+
if (PyList_Check(py_sids)) {
/* Convert dictionary to char ** array */
num_sids = PyList_Size(py_sids);
- sids = (DOM_SID *)talloc(hnd->mem_ctx, num_sids * sizeof(DOM_SID));
+ sids = (DOM_SID *)talloc(mem_ctx, num_sids * sizeof(DOM_SID));
memset(sids, 0, num_sids * sizeof(DOM_SID));
@@ -237,7 +250,7 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args,
if (!string_to_sid(&sids[i], PyString_AsString(obj))) {
PyErr_SetString(PyExc_ValueError, "string_to_sid failed");
- return NULL;
+ goto done;
}
}
@@ -246,21 +259,21 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args,
/* Just a single element */
num_sids = 1;
- sids = (DOM_SID *)talloc(hnd->mem_ctx, sizeof(DOM_SID));
+ sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID));
if (!string_to_sid(&sids[0], PyString_AsString(py_sids))) {
PyErr_SetString(PyExc_ValueError, "string_to_sid failed");
- return NULL;
+ goto done;
}
}
- ntstatus = cli_lsa_lookup_sids(hnd->cli, hnd->mem_ctx, &hnd->pol,
+ ntstatus = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
num_sids, sids, &domains, &names,
&types);
if (!NT_STATUS_IS_OK(ntstatus)) {
PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus));
- return NULL;
+ goto done;
}
result = PyList_New(num_sids);
@@ -274,7 +287,10 @@ static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args,
PyList_SetItem(result, i, obj);
}
-
+
+ done:
+ talloc_destroy(mem_ctx);
+
return result;
}
@@ -391,7 +407,7 @@ static PyMethodDef lsa_methods[] = {
"\n"
"Example:\n"
"\n"
-">>> spoolss.setup_logging(interactive = 1)" },
+">>> lsa.setup_logging(interactive = 1)" },
{ "get_debuglevel", (PyCFunction)get_debuglevel,
METH_VARARGS,
@@ -399,7 +415,7 @@ static PyMethodDef lsa_methods[] = {
"\n"
"Example:\n"
"\n"
-">>> spoolss.get_debuglevel()\n"
+">>> lsa.get_debuglevel()\n"
"0" },
{ "set_debuglevel", (PyCFunction)set_debuglevel,
@@ -408,7 +424,7 @@ static PyMethodDef lsa_methods[] = {
"\n"
"Example:\n"
"\n"
-">>> spoolss.set_debuglevel(10)" },
+">>> lsa.set_debuglevel(10)" },
{ NULL }
};
diff --git a/source/python/py_ntsec.c b/source/python/py_ntsec.c
index 47524d8e190..3d408e0bda2 100644
--- a/source/python/py_ntsec.c
+++ b/source/python/py_ntsec.c
@@ -58,14 +58,14 @@ BOOL py_from_ACE(PyObject **dict, SEC_ACE *ace)
return True;
}
- *dict = PyDict_New();
-
- PyDict_SetItemString(*dict, "type", PyInt_FromLong(ace->type));
- PyDict_SetItemString(*dict, "flags", PyInt_FromLong(ace->flags));
- PyDict_SetItemString(*dict, "mask", PyInt_FromLong(ace->info.mask));
+ *dict = Py_BuildValue("{sisisi}", "type", ace->type,
+ "flags", ace->flags,
+ "mask", ace->info.mask);
- if (py_from_SID(&obj, &ace->trustee))
+ if (py_from_SID(&obj, &ace->trustee)) {
PyDict_SetItemString(*dict, "trustee", obj);
+ Py_DECREF(obj);
+ }
return True;
}
@@ -125,10 +125,6 @@ BOOL py_from_ACL(PyObject **dict, SEC_ACL *acl)
return True;
}
- *dict = PyDict_New();
-
- PyDict_SetItemString(*dict, "revision", PyInt_FromLong(acl->revision));
-
ace_list = PyList_New(acl->num_aces);
for (i = 0; i < acl->num_aces; i++) {
@@ -138,7 +134,8 @@ BOOL py_from_ACL(PyObject **dict, SEC_ACL *acl)
PyList_SetItem(ace_list, i, obj);
}
- PyDict_SetItemString(*dict, "ace_list", ace_list);
+ *dict = Py_BuildValue("{sisN}", "revision", acl->revision,
+ "ace_list", ace_list);
return True;
}
@@ -181,19 +178,29 @@ BOOL py_from_SECDESC(PyObject **dict, SEC_DESC *sd)
*dict = PyDict_New();
- PyDict_SetItemString(*dict, "revision", PyInt_FromLong(sd->revision));
+ obj = PyInt_FromLong(sd->revision);
+ PyDict_SetItemString(*dict, "revision", obj);
+ Py_DECREF(obj);
- if (py_from_SID(&obj, sd->owner_sid))
+ if (py_from_SID(&obj, sd->owner_sid)) {
PyDict_SetItemString(*dict, "owner_sid", obj);
+ Py_DECREF(obj);
+ }
- if (py_from_SID(&obj, sd->grp_sid))
+ if (py_from_SID(&obj, sd->grp_sid)) {
PyDict_SetItemString(*dict, "group_sid", obj);
+ Py_DECREF(obj);
+ }
- if (py_from_ACL(&obj, sd->dacl))
+ if (py_from_ACL(&obj, sd->dacl)) {
PyDict_SetItemString(*dict, "dacl", obj);
+ Py_DECREF(obj);
+ }
- if (py_from_ACL(&obj, sd->sacl))
+ if (py_from_ACL(&obj, sd->sacl)) {
PyDict_SetItemString(*dict, "sacl", obj);
+ Py_DECREF(obj);
+ }
return True;
}
diff --git a/source/python/py_smb.c b/source/python/py_smb.c
index d37b73cceb7..e5e65061965 100644
--- a/source/python/py_smb.c
+++ b/source/python/py_smb.c
@@ -221,10 +221,10 @@ static PyObject *py_smb_query_secdesc(PyObject *self, PyObject *args,
{
cli_state_object *cli = (cli_state_object *)self;
static char *kwlist[] = { "fnum", NULL };
- PyObject *result;
+ PyObject *result = NULL;
SEC_DESC *secdesc = NULL;
int fnum;
- TALLOC_CTX *mem_ctx;
+ TALLOC_CTX *mem_ctx = NULL;
/* Parse parameters */
@@ -238,7 +238,7 @@ static PyObject *py_smb_query_secdesc(PyObject *self, PyObject *args,
if (cli_is_error(cli->cli)) {
PyErr_SetString(PyExc_RuntimeError, "query_secdesc failed");
- return NULL;
+ goto done;
}
if (!secdesc) {
@@ -251,7 +251,6 @@ static PyObject *py_smb_query_secdesc(PyObject *self, PyObject *args,
PyErr_SetString(
PyExc_TypeError,
"Invalid security descriptor returned");
- result = NULL;
goto done;
}
@@ -267,11 +266,12 @@ static PyObject *py_smb_set_secdesc(PyObject *self, PyObject *args,
{
cli_state_object *cli = (cli_state_object *)self;
static char *kwlist[] = { "fnum", "security_descriptor", NULL };
+ PyObject *result = NULL;
PyObject *py_secdesc;
SEC_DESC *secdesc;
- TALLOC_CTX *mem_ctx = talloc_init("py_smb_set_secdesc");
+ TALLOC_CTX *mem_ctx = NULL;
int fnum;
- BOOL result;
+ BOOL err;
/* Parse parameters */
@@ -279,20 +279,26 @@ static PyObject *py_smb_set_secdesc(PyObject *self, PyObject *args,
args, kw, "iO", kwlist, &fnum, &py_secdesc))
return NULL;
+ mem_ctx = talloc_init("py_smb_set_secdesc");
+
if (!py_to_SECDESC(&secdesc, py_secdesc, mem_ctx)) {
PyErr_SetString(PyExc_TypeError,
"Invalid security descriptor");
- return NULL;
+ goto done;
}
- result = cli_set_secdesc(cli->cli, fnum, secdesc);
+ err = cli_set_secdesc(cli->cli, fnum, secdesc);
if (cli_is_error(cli->cli)) {
PyErr_SetString(PyExc_RuntimeError, "set_secdesc failed");
- return NULL;
+ goto done;
}
- return PyInt_FromLong(result);
+ result = PyInt_FromLong(err);
+ done:
+ talloc_destroy(mem_ctx);
+
+ return result;
}
static PyMethodDef smb_hnd_methods[] = {
@@ -342,11 +348,48 @@ static PyMethodDef smb_methods[] = {
{ "connect", (PyCFunction)py_smb_connect, METH_VARARGS | METH_KEYWORDS,
"Connect to a host" },
+ /* Other stuff - this should really go into a samba config module
+ but for the moment let's leave it here. */
+
+ { "setup_logging", (PyCFunction)py_setup_logging,
+ METH_VARARGS | METH_KEYWORDS,
+ "Set up debug logging.\n"
+"\n"
+"Initialises Samba's debug logging system. One argument is expected which\n"
+"is a boolean specifying whether debugging is interactive and sent to stdout\n"
+"or logged to a file.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> smb.setup_logging(interactive = 1)" },
+
+ { "get_debuglevel", (PyCFunction)get_debuglevel,
+ METH_VARARGS,
+ "Set the current debug level.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> smb.get_debuglevel()\n"
+"0" },
+
+ { "set_debuglevel", (PyCFunction)set_debuglevel,
+ METH_VARARGS,
+ "Get the current debug level.\n"
+"\n"
+"Example:\n"
+"\n"
+">>> smb.set_debuglevel(10)" },
+
{ NULL }
};
static void py_cli_state_dealloc(PyObject* self)
{
+ cli_state_object *cli = (cli_state_object *)self;
+
+ if (cli->cli)
+ cli_shutdown(cli->cli);
+
PyObject_Del(self);
}
@@ -395,5 +438,5 @@ void initsmb(void)
py_samba_init();
setup_logging("smb", True);
- DEBUGLEVEL = 10;
+ DEBUGLEVEL = 3;
}
diff --git a/source/python/py_winbind.c b/source/python/py_winbind.c
index db66be2321a..130f78d7e12 100644
--- a/source/python/py_winbind.c
+++ b/source/python/py_winbind.c
@@ -259,14 +259,14 @@ static PyObject *py_config_dict(void)
PyDict_SetItemString(result, "template_shell",
PyString_FromString(lp_template_shell()));
- /* Winbind uid/gid range */
+ /* idmap uid/gid range */
- if (lp_winbind_uid(&ulow, &uhi)) {
+ if (lp_idmap_uid(&ulow, &uhi)) {
PyDict_SetItemString(result, "uid_low", PyInt_FromLong(ulow));
PyDict_SetItemString(result, "uid_high", PyInt_FromLong(uhi));
}
- if (lp_winbind_gid(&glow, &ghi)) {
+ if (lp_idmap_gid(&glow, &ghi)) {
PyDict_SetItemString(result, "gid_low", PyInt_FromLong(glow));
PyDict_SetItemString(result, "gid_high", PyInt_FromLong(ghi));
}
@@ -427,7 +427,10 @@ static PyObject *py_auth_crap(PyObject *self, PyObject *args, PyObject *kw)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- fstrcpy(request.data.auth_crap.user, username);
+ if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
+ PyErr_SetString(winbind_error, "unable to create utf8 string");
+ return NULL;
+ }
generate_random_buffer(request.data.auth_crap.chal, 8, False);
@@ -473,7 +476,10 @@ static PyObject *py_auth_smbd(PyObject *self, PyObject *args, PyObject *kw)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- fstrcpy(request.data.smbd_auth_crap.user, username);
+ if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
+ PyErr_SetString("unable to create utf8 string");
+ return NULL;
+ }
generate_random_buffer(request.data.smbd_auth_crap.chal, 8, False);
diff --git a/source/rpc_client/cli_ds.c b/source/rpc_client/cli_ds.c
index f0edeca0003..a7a093328c9 100644
--- a/source/rpc_client/cli_ds.c
+++ b/source/rpc_client/cli_ds.c
@@ -22,6 +22,10 @@
/* implementations of client side DsXXX() functions */
+/********************************************************************
+ Get information about the server and directory services
+********************************************************************/
+
NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
uint16 level, DS_DOMINFO_CTR *ctr)
{
@@ -40,7 +44,7 @@ NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
q.level = level;
- if (!ds_io_q_getprimdominfo("", &q, &qbuf, 0)
+ if (!ds_io_q_getprimdominfo("", &qbuf, 0, &q)
|| !rpc_api_pipe_req(cli, DS_GETPRIMDOMINFO, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
@@ -48,7 +52,7 @@ NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Unmarshall response */
- if (!ds_io_r_getprimdominfo("", &r, &rbuf, 0)) {
+ if (!ds_io_r_getprimdominfo("", &rbuf, 0, &r)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -71,3 +75,63 @@ done:
return result;
}
+
+/********************************************************************
+ Enumerate trusted domains in an AD forest
+********************************************************************/
+
+NTSTATUS cli_ds_enum_domain_trusts(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ const char *server, uint32 flags,
+ DS_DOMAIN_TRUSTS **trusts, uint32 *num_domains)
+{
+ prs_struct qbuf, rbuf;
+ DS_Q_ENUM_DOM_TRUSTS q;
+ DS_R_ENUM_DOM_TRUSTS r;
+ NTSTATUS result;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ init_q_ds_enum_domain_trusts( &q, server, flags );
+
+ if (!ds_io_q_enum_domain_trusts("", &qbuf, 0, &q)
+ || !rpc_api_pipe_req(cli, DS_ENUM_DOM_TRUSTS, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!ds_io_r_enum_domain_trusts("", &rbuf, 0, &r)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ result = r.status;
+
+ if ( NT_STATUS_IS_OK(result) ) {
+ int i;
+
+ *num_domains = r.num_domains;
+ *trusts = (DS_DOMAIN_TRUSTS*)smb_xmalloc(r.num_domains*sizeof(DS_DOMAIN_TRUSTS));
+
+ memcpy( *trusts, r.domains.trusts, r.num_domains*sizeof(DS_DOMAIN_TRUSTS) );
+ for ( i=0; i<r.num_domains; i++ ) {
+ copy_unistr2( &(*trusts)[i].netbios_domain, &r.domains.trusts[i].netbios_domain );
+ copy_unistr2( &(*trusts)[i].dns_domain, &r.domains.trusts[i].dns_domain );
+ }
+ }
+
+done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
+
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index 831101ed81e..2de830e558e 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -332,8 +332,7 @@ NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
/****************************************************************************
-Generate the next creds to use. Yuck - this is a cut&paste from another
-file. They should be combined at some stage. )-:
+Generate the next creds to use.
****************************************************************************/
static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
@@ -515,7 +514,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
0, /* param_ctrl */
0xdead, 0xbeef, /* LUID? */
username, cli->clnt_name_slash,
- cli->sess_key, lm_owf_user_pwd,
+ (const char *)cli->sess_key, lm_owf_user_pwd,
nt_owf_user_pwd);
break;
@@ -708,9 +707,9 @@ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx,
credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
/* store the parameters */
- init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->sess_key,
+ init_q_srv_pwset(&q_s, cli->srv_name_slash, (const char *)cli->sess_key,
mach_acct, sec_chan_type, machine_name,
- &new_clnt_cred, (char *)hashed_mach_pwd);
+ &new_clnt_cred, hashed_mach_pwd);
/* turn parameters into data stream */
if(!net_io_q_srv_pwset("", &q_s, &qbuf, 0)) {
diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c
index d6307ddb46e..13a78414556 100644
--- a/source/rpc_client/cli_pipe.c
+++ b/source/rpc_client/cli_pipe.c
@@ -5,6 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
* Copyright (C) Paul Ashton 1998.
* Copyright (C) Jeremy Allison 1999.
+ * Copyright (C) Andrew Bartlett 2003.
*
* 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
@@ -263,7 +264,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len);
/* save the reply away, for use a little later */
- prs_copy_data_out(ntlmssp_verf.data, &auth_verf, auth_len);
+ prs_copy_data_out((char *)ntlmssp_verf.data, &auth_verf, auth_len);
return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state,
@@ -286,7 +287,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
return False;
}
sig = data_blob(NULL, auth_len);
- prs_copy_data_out(sig.data, &auth_verf, auth_len);
+ prs_copy_data_out((char *)sig.data, &auth_verf, auth_len);
}
/*
@@ -305,12 +306,12 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
return False;
}
nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state,
- reply_data, data_len,
+ (unsigned char *)reply_data, data_len,
&sig);
}
else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) {
nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state,
- reply_data, data_len,
+ (const unsigned char *)reply_data, data_len,
&sig);
}
@@ -637,7 +638,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
RPC_HDR_AUTH hdr_auth;
int auth_len = 0;
int auth_type, auth_level;
- size_t saved_hdr_offset;
+ size_t saved_hdr_offset = 0;
prs_struct auth_info;
prs_init(&auth_info, RPC_HDR_AUTH_LEN, /* we will need at least this much */
@@ -683,21 +684,22 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
/* Auth len in the rpc header doesn't include auth_header. */
auth_len = request.length;
- prs_copy_data_in(&auth_info, request.data, request.length);
+ prs_copy_data_in(&auth_info, (char *)request.data, request.length);
DEBUG(5, ("NTLMSSP Negotiate:\n"));
- dump_data(5, request.data, request.length);
+ dump_data(5, (const char *)request.data, request.length);
data_blob_free(&request);
- }
- else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
+ } else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) {
RPC_AUTH_NETSEC_NEG netsec_neg;
/* Use lp_workgroup() if domain not specified */
- if (!domain || !domain[0])
+ if (!domain || !domain[0]) {
+ DEBUG(10,("create_rpc_bind_req: no domain; assuming my own\n"));
domain = lp_workgroup();
+ }
init_rpc_auth_netsec_neg(&netsec_neg, domain, my_name);
@@ -715,7 +717,8 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
/* Auth len in the rpc header doesn't include auth_header. */
auth_len = prs_offset(&auth_info) - saved_hdr_offset;
}
- /* create the request RPC_HDR */
+
+ /* Create the request RPC_HDR */
init_rpc_hdr(&hdr, RPC_BIND, 0x3, rpc_call_id,
RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info),
auth_len);
@@ -748,6 +751,7 @@ static NTSTATUS create_rpc_bind_req(struct cli_state *cli, prs_struct *rpc_out,
return NT_STATUS_NO_MEMORY;
}
}
+ prs_mem_free(&auth_info);
return NT_STATUS_OK;
}
@@ -807,7 +811,7 @@ static NTSTATUS create_rpc_bind_resp(struct cli_state *cli,
* Append the auth data to the outgoing buffer.
*/
- if(!prs_copy_data_in(rpc_out, ntlmssp_reply.data, ntlmssp_reply.length)) {
+ if(!prs_copy_data_in(rpc_out, (char *)ntlmssp_reply.data, ntlmssp_reply.length)) {
DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
data_blob_free(&ntlmssp_reply);
return NT_STATUS_NO_MEMORY;
@@ -1013,7 +1017,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
/* write auth footer onto the packet */
real_auth_len = sign_blob.length;
- prs_copy_data_in(&sec_blob, sign_blob.data, sign_blob.length);
+ prs_copy_data_in(&sec_blob, (char *)sign_blob.data, sign_blob.length);
data_blob_free(&sign_blob);
}
@@ -1021,11 +1025,6 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 };
size_t parse_offset_marker;
- if ((cli->auth_info.seq_num & 1) != 0) {
- DEBUG(0,("SCHANNEL ERROR: seq_num must be even in client (seq_num=%d)\n",
- cli->auth_info.seq_num));
- }
-
DEBUG(10,("SCHANNEL seq_num=%d\n", cli->auth_info.seq_num));
init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes,
@@ -1573,9 +1572,6 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
}
}
- /* doing schannel, not per-user auth */
- cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL;
-
if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) {
DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
cli_close(cli, cli->nt_pipe_fnum);
@@ -1586,6 +1582,57 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
}
+NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan,
+ const uchar trust_password[16])
+{
+ NTSTATUS result;
+ uint32 neg_flags = 0x000701ff;
+ cli->pipe_auth_flags = 0;
+
+ if (lp_client_schannel() == False) {
+ return NT_STATUS_OK;
+ }
+
+ if (!cli_nt_session_open(cli, PI_NETLOGON)) {
+ DEBUG(0, ("Could not initialise %s\n",
+ get_pipe_name_from_index(PI_NETLOGON)));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (lp_client_schannel() != False)
+ neg_flags |= NETLOGON_NEG_SCHANNEL;
+
+ neg_flags |= NETLOGON_NEG_SCHANNEL;
+
+ result = cli_nt_setup_creds(cli, sec_chan, trust_password,
+ &neg_flags, 2);
+
+ if (!(neg_flags & NETLOGON_NEG_SCHANNEL)
+ && lp_client_schannel() == True) {
+ DEBUG(1, ("Could not negotiate SCHANNEL with the DC!\n"));
+ result = NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!NT_STATUS_IS_OK(result)) {
+ ZERO_STRUCT(cli->auth_info.sess_key);
+ ZERO_STRUCT(cli->sess_key);
+ cli->pipe_auth_flags = 0;
+ cli_nt_session_close(cli);
+ return result;
+ }
+
+ memcpy(cli->auth_info.sess_key, cli->sess_key,
+ sizeof(cli->auth_info.sess_key));
+
+ cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
+ cli->nt_pipe_fnum = 0;
+
+ /* doing schannel, not per-user auth */
+ cli->pipe_auth_flags = AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN | AUTH_PIPE_SEAL;
+
+ return NT_STATUS_OK;
+}
+
const char *cli_pipe_get_name(struct cli_state *cli)
{
return cli->pipe_name;
diff --git a/source/rpc_client/cli_spoolss.c b/source/rpc_client/cli_spoolss.c
index 63926204978..f983f63cd72 100644
--- a/source/rpc_client/cli_spoolss.c
+++ b/source/rpc_client/cli_spoolss.c
@@ -2027,7 +2027,7 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Initialise input parameters */
make_spoolss_q_setprinterdata(
- &q, hnd, value->valuename, value->type, value->data_p, value->size);
+ &q, hnd, value->valuename, value->type, (char *)value->data_p, value->size);
/* Marshall data and send request */
@@ -2072,7 +2072,7 @@ WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Initialise input parameters */
make_spoolss_q_setprinterdataex(
- &q, hnd, keyname, value->valuename, value->type, value->data_p,
+ &q, hnd, keyname, value->valuename, value->type, (char *)value->data_p,
value->size);
/* Marshall data and send request */
@@ -2215,7 +2215,7 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1,
STR_TERMINATE);
- regval_ctr_addvalue(ctr, name, v->type, v->data, v->data_len);
+ regval_ctr_addvalue(ctr, name, v->type, (const char *)v->data, v->data_len);
}
done:
diff --git a/source/rpc_client/cli_srvsvc.c b/source/rpc_client/cli_srvsvc.c
index 6cd18f2e43d..27349b72957 100644
--- a/source/rpc_client/cli_srvsvc.c
+++ b/source/rpc_client/cli_srvsvc.c
@@ -4,7 +4,7 @@
Copyright (C) Andrew Tridgell 1994-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Tim Potter 2001
- Copyright (C) Jim McDonough 2002
+ 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
diff --git a/source/rpc_parse/parse_ds.c b/source/rpc_parse/parse_ds.c
index ab076318317..f954806036b 100644
--- a/source/rpc_parse/parse_ds.c
+++ b/source/rpc_parse/parse_ds.c
@@ -1,7 +1,8 @@
/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
- * Copyright (C) Gerald Carter 2002
+
+ * Copyright (C) Gerald Carter 2002-2003
*
* 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
@@ -20,6 +21,9 @@
#include "includes.h"
+/************************************************************************
+************************************************************************/
+
static BOOL ds_io_dominfobasic( const char *desc, prs_struct *ps, int depth, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **basic)
{
DSROLE_PRIMARY_DOMAIN_INFO_BASIC *p = *basic;
@@ -68,7 +72,10 @@ static BOOL ds_io_dominfobasic( const char *desc, prs_struct *ps, int depth, DSR
}
-BOOL ds_io_q_getprimdominfo( const char *desc, DS_Q_GETPRIMDOMINFO *q_u, prs_struct *ps, int depth)
+/************************************************************************
+************************************************************************/
+
+BOOL ds_io_q_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_Q_GETPRIMDOMINFO *q_u)
{
prs_debug(ps, depth, desc, "ds_io_q_getprimdominfo");
depth++;
@@ -82,7 +89,10 @@ BOOL ds_io_q_getprimdominfo( const char *desc, DS_Q_GETPRIMDOMINFO *q_u, prs_str
return True;
}
-BOOL ds_io_r_getprimdominfo( const char *desc, DS_R_GETPRIMDOMINFO *r_u, prs_struct *ps, int depth)
+/************************************************************************
+************************************************************************/
+
+BOOL ds_io_r_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_R_GETPRIMDOMINFO *r_u)
{
prs_debug(ps, depth, desc, "ds_io_r_getprimdominfo");
depth++;
@@ -120,3 +130,177 @@ BOOL ds_io_r_getprimdominfo( const char *desc, DS_R_GETPRIMDOMINFO *r_u, prs_str
return True;
}
+
+/************************************************************************
+ initialize a DS_ENUM_DOM_TRUSTS structure
+************************************************************************/
+
+BOOL init_q_ds_enum_domain_trusts( DS_Q_ENUM_DOM_TRUSTS *q, const char *server,
+ uint32 flags )
+{
+ int len;
+
+ q->flags = flags;
+
+ if ( server && *server )
+ q->server_ptr = 1;
+ else
+ q->server_ptr = 0;
+
+ len = q->server_ptr ? strlen(server)+1 : 0;
+
+ init_unistr2( &q->server, server, len );
+
+ return True;
+}
+
+/************************************************************************
+************************************************************************/
+
+static BOOL ds_io_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_DOMAIN_TRUSTS *trust)
+{
+ prs_debug(ps, depth, desc, "ds_io_dom_trusts_ctr");
+ depth++;
+
+ if ( !prs_uint32( "netbios_ptr", ps, depth, &trust->netbios_ptr ) )
+ return False;
+
+ if ( !prs_uint32( "dns_ptr", ps, depth, &trust->dns_ptr ) )
+ return False;
+
+ if ( !prs_uint32( "flags", ps, depth, &trust->flags ) )
+ return False;
+
+ if ( !prs_uint32( "parent_index", ps, depth, &trust->parent_index ) )
+ return False;
+
+ if ( !prs_uint32( "trust_type", ps, depth, &trust->trust_type ) )
+ return False;
+
+ if ( !prs_uint32( "trust_attributes", ps, depth, &trust->trust_attributes ) )
+ return False;
+
+ if ( !prs_uint32( "sid_ptr", ps, depth, &trust->sid_ptr ) )
+ return False;
+
+ if ( !prs_uint8s(False, "guid", ps, depth, trust->guid.info, GUID_SIZE) )
+ return False;
+
+ return True;
+}
+
+/************************************************************************
+************************************************************************/
+
+static BOOL ds_io_dom_trusts_ctr( const char *desc, prs_struct *ps, int depth, DS_DOMAIN_TRUSTS_CTR *ctr)
+{
+ int i;
+
+ prs_debug(ps, depth, desc, "ds_io_dom_trusts_ctr");
+ depth++;
+
+ if ( !prs_uint32( "ptr", ps, depth, &ctr->ptr ) )
+ return False;
+
+ if ( !prs_uint32( "max_count", ps, depth, &ctr->max_count ) )
+ return False;
+
+ /* are we done? */
+
+ if ( ctr->max_count == 0 )
+ return True;
+
+ /* allocate the domain trusts array are parse it */
+
+ ctr->trusts = (DS_DOMAIN_TRUSTS*)talloc(ps->mem_ctx, sizeof(DS_DOMAIN_TRUSTS)*ctr->max_count);
+
+ if ( !ctr->trusts )
+ return False;
+
+ /* this stinks; the static portion o fthe structure is read here and then
+ we need another loop to read the UNISTR2's and SID's */
+
+ for ( i=0; i<ctr->max_count;i++ ) {
+ if ( !ds_io_domain_trusts("domain_trusts", ps, depth, &ctr->trusts[i] ) )
+ return False;
+ }
+
+ for ( i=0; i<ctr->max_count; i++ ) {
+
+ if ( !smb_io_unistr2("netbios_domain", &ctr->trusts[i].netbios_domain, ctr->trusts[i].netbios_ptr, ps, depth) )
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !smb_io_unistr2("dns_domain", &ctr->trusts[i].dns_domain, ctr->trusts[i].dns_ptr, ps, depth) )
+ return False;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( ctr->trusts[i].sid_ptr ) {
+ if ( !smb_io_dom_sid2("sid", &ctr->trusts[i].sid, ps, depth ) )
+ return False;
+ }
+ }
+
+ return True;
+}
+
+/************************************************************************
+ initialize a DS_ENUM_DOM_TRUSTS request
+************************************************************************/
+
+BOOL ds_io_q_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_Q_ENUM_DOM_TRUSTS *q_u)
+{
+ prs_debug(ps, depth, desc, "ds_io_q_enum_domain_trusts");
+ depth++;
+
+ if ( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32( "server_ptr", ps, depth, &q_u->server_ptr ) )
+ return False;
+
+ if ( !smb_io_unistr2("server", &q_u->server, q_u->server_ptr, ps, depth) )
+ return False;
+
+ if ( !prs_align(ps) )
+ return False;
+
+ if ( !prs_uint32( "flags", ps, depth, &q_u->flags ) )
+ return False;
+
+ return True;
+}
+
+/************************************************************************
+************************************************************************/
+
+BOOL ds_io_r_enum_domain_trusts( const char *desc, prs_struct *ps, int depth, DS_R_ENUM_DOM_TRUSTS *r_u)
+{
+ prs_debug(ps, depth, desc, "ds_io_r_enum_domain_trusts");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !prs_uint32( "num_domains", ps, depth, &r_u->num_domains ) )
+ return False;
+
+ if ( r_u->num_domains ) {
+ if ( !ds_io_dom_trusts_ctr("domains", ps, depth, &r_u->domains ) )
+ return False;
+ }
+
+ if(!prs_align(ps))
+ return False;
+
+ if ( !prs_ntstatus("status", ps, depth, &r_u->status ) )
+ return False;
+
+ return True;
+}
+
+
diff --git a/source/rpc_parse/parse_echo.c b/source/rpc_parse/parse_echo.c
index 67f9ad772ee..4b1ff1f4d54 100644
--- a/source/rpc_parse/parse_echo.c
+++ b/source/rpc_parse/parse_echo.c
@@ -73,7 +73,7 @@ BOOL echo_io_q_echo_data(const char *desc, ECHO_Q_ECHO_DATA *q_d,
return False;
}
- if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size))
+ if (!prs_uint8s(False, "data", ps, depth, (unsigned char *)q_d->data, q_d->size))
return False;
return True;
@@ -92,7 +92,7 @@ BOOL echo_io_r_echo_data(const char *desc, ECHO_R_ECHO_DATA *q_d,
return False;
}
- if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size))
+ if (!prs_uint8s(False, "data", ps, depth, (unsigned char *)q_d->data, q_d->size))
return False;
return True;
@@ -120,7 +120,7 @@ BOOL echo_io_q_sink_data(const char *desc, ECHO_Q_SINK_DATA *q_d,
return False;
}
- if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size))
+ if (!prs_uint8s(False, "data", ps, depth, (unsigned char *)q_d->data, q_d->size))
return False;
return True;
@@ -159,7 +159,7 @@ BOOL echo_io_r_source_data(const char *desc, ECHO_R_SOURCE_DATA *q_d,
return False;
}
- if (!prs_uint8s(False, "data", ps, depth, q_d->data, q_d->size))
+ if (!prs_uint8s(False, "data", ps, depth, (unsigned char *)q_d->data, q_d->size))
return False;
return True;
diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c
index f620845d3b3..07b0da7e9c2 100644
--- a/source/rpc_parse/parse_lsa.c
+++ b/source/rpc_parse/parse_lsa.c
@@ -5,7 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Andrew Bartlett 2002,
- * Copyright (C) Jim McDonough 2002.
+ * 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
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index 804da707ded..252e690723a 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -801,7 +801,7 @@ void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s,
DEBUG(5,("init_q_srv_pwset\n"));
/* Process the new password. */
- cred_hash3( nt_cypher, hashed_mach_pwd, sess_key, 1);
+ cred_hash3( nt_cypher, hashed_mach_pwd, (const unsigned char *)sess_key, 1);
init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index efd4914c66b..81a95730778 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -1402,7 +1402,7 @@ static void netsec_digest(struct netsec_auth_struct *a,
if (auth_flags & AUTH_PIPE_SEAL) {
MD5Update(&ctx3, verf->data8, sizeof(verf->data8));
}
- MD5Update(&ctx3, data, data_len);
+ MD5Update(&ctx3, (const unsigned char *)data, data_len);
MD5Final(whole_packet_digest, &ctx3);
dump_data_pw("whole_packet_digest:\n", whole_packet_digest, sizeof(whole_packet_digest));
@@ -1429,7 +1429,7 @@ static void netsec_get_sealing_key(struct netsec_auth_struct *a,
dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
- /* MD5 of sess_kf0 and the high bytes of the sequence number */
+ /* MD5 of sess_kf0 and 4 zero bytes */
hmac_md5(sess_kf0, zeros, 0x4, digest2);
dump_data_pw("digest2:\n", digest2, sizeof(digest2));
@@ -1473,7 +1473,7 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
{
uchar digest_final[16];
- DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%d\n", a->seq_num, data_len));
+ DEBUG(10,("SCHANNEL: netsec_encode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
RSIVAL(verf->seq_num, 0, a->seq_num);
@@ -1506,9 +1506,9 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
dump_data_pw("verf->data8_enc:\n", verf->data8, sizeof(verf->data8));
/* encode the packet payload */
- dump_data_pw("data:\n", data, data_len);
- netsechash(sealing_key, data, data_len);
- dump_data_pw("data_enc:\n", data, data_len);
+ dump_data_pw("data:\n", (const unsigned char *)data, data_len);
+ netsechash(sealing_key, (unsigned char *)data, data_len);
+ dump_data_pw("data_enc:\n", (const unsigned char *)data, data_len);
}
/* encode the sequence number (key based on packet digest) */
@@ -1544,7 +1544,7 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
break;
}
- DEBUG(10,("SCHANNEL: netsec_decode seq_num=%d data_len=%d\n", a->seq_num, data_len));
+ DEBUG(10,("SCHANNEL: netsec_decode seq_num=%d data_len=%lu\n", a->seq_num, (unsigned long)data_len));
dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
dump_data_pw("seq_num:\n", seq_num, sizeof(seq_num));
@@ -1578,9 +1578,9 @@ BOOL netsec_decode(struct netsec_auth_struct *a, int auth_flags,
sizeof(verf->data8));
/* extract the packet payload */
- dump_data_pw("data :\n", data, data_len);
- netsechash(sealing_key, data, data_len);
- dump_data_pw("datadec:\n", data, data_len);
+ dump_data_pw("data :\n", (const unsigned char *)data, data_len);
+ netsechash(sealing_key, (unsigned char *)data, data_len);
+ dump_data_pw("datadec:\n", (const unsigned char *)data, data_len);
}
/* digest includes 'data' after unsealing */
diff --git a/source/rpc_parse/parse_reg.c b/source/rpc_parse/parse_reg.c
index b4d20bf2baa..bbf6e6a8e3d 100644
--- a/source/rpc_parse/parse_reg.c
+++ b/source/rpc_parse/parse_reg.c
@@ -40,7 +40,7 @@ static uint32 reg_init_buffer2( BUFFER2 *buf2, REGISTRY_VALUE *val )
return 0;
real_size = regval_size(val);
- init_buffer2( buf2, (char*)regval_data_p(val), real_size );
+ init_buffer2( buf2, (unsigned char*)regval_data_p(val), real_size );
return real_size;
}
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index 45c81deb899..fce31952256 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -7,8 +7,7 @@
* Copyright (C) Elrond 2000,
* Copyright (C) Jeremy Allison 2001,
* Copyright (C) Jean François Micouleau 1998-2001,
- * Copyright (C) Anthony Liguori 2002,
- * Copyright (C) Jim McDonough 2002.
+ * 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
diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c
index 1a380c64d55..7ca9bccab46 100644
--- a/source/rpc_parse/parse_spoolss.c
+++ b/source/rpc_parse/parse_spoolss.c
@@ -1368,7 +1368,7 @@ BOOL spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u,
return False;
if (UNMARSHALLING(ps) && r_u->size) {
- r_u->data = prs_alloc_mem(ps, r_u->size);
+ r_u->data = (unsigned char *)prs_alloc_mem(ps, r_u->size);
if(!r_u->data)
return False;
}
@@ -6178,7 +6178,7 @@ BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, const POLICY_HND
init_unistr2(&q_u->value, value, strlen(value)+1);
q_u->max_len = q_u->real_len = data_size;
- q_u->data = data;
+ q_u->data = (unsigned char *)data;
return True;
}
@@ -6195,7 +6195,7 @@ BOOL make_spoolss_q_setprinterdataex(SPOOL_Q_SETPRINTERDATAEX *q_u, const POLICY
init_unistr2(&q_u->key, key, strlen(key)+1);
q_u->max_len = q_u->real_len = data_size;
- q_u->data = data;
+ q_u->data = (unsigned char *)data;
return True;
}
@@ -6990,7 +6990,7 @@ BOOL spoolss_io_r_getprinterdataex(const char *desc, SPOOL_R_GETPRINTERDATAEX *r
return False;
if (UNMARSHALLING(ps) && r_u->size) {
- r_u->data = prs_alloc_mem(ps, r_u->size);
+ r_u->data = (unsigned char *)prs_alloc_mem(ps, r_u->size);
if(!r_u->data)
return False;
}
@@ -7689,7 +7689,7 @@ BOOL make_spoolss_q_writeprinter(SPOOL_Q_WRITEPRINTER *q_u,
{
memcpy(&q_u->handle, handle, sizeof(POLICY_HND));
q_u->buffer_size = q_u->buffer_size2 = data_size;
- q_u->buffer = data;
+ q_u->buffer = (unsigned char *)data;
return True;
}
diff --git a/source/rpc_server/srv_dfs.c b/source/rpc_server/srv_dfs.c
index 75a24174ea3..6c35917e618 100644
--- a/source/rpc_server/srv_dfs.c
+++ b/source/rpc_server/srv_dfs.c
@@ -5,7 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Shirish Kalele 2000,
* Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Anthony Liguori 2003.
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
*
* 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
@@ -157,17 +157,23 @@ static BOOL api_dfs_enum(pipes_struct *p)
/*******************************************************************
\pipe\netdfs commands
********************************************************************/
-
-NTSTATUS rpc_dfs_init(void)
+static struct api_struct api_netdfs_cmds[] =
{
- struct api_struct api_netdfs_cmds[] =
- {
{"DFS_EXIST", DFS_EXIST, api_dfs_exist },
{"DFS_ADD", DFS_ADD, api_dfs_add },
{"DFS_REMOVE", DFS_REMOVE, api_dfs_remove },
{"DFS_GET_INFO", DFS_GET_INFO, api_dfs_get_info },
{"DFS_ENUM", DFS_ENUM, api_dfs_enum }
- };
+};
+
+void netdfs_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_netdfs_cmds;
+ *n_fns = sizeof(api_netdfs_cmds) / sizeof(struct api_struct);
+}
+
+NTSTATUS rpc_dfs_init(void)
+{
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "netdfs", "netdfs", api_netdfs_cmds,
sizeof(api_netdfs_cmds) / sizeof(struct api_struct));
}
diff --git a/source/rpc_server/srv_echo.c b/source/rpc_server/srv_echo.c
index 166b6e939d2..c6cfde07c15 100644
--- a/source/rpc_server/srv_echo.c
+++ b/source/rpc_server/srv_echo.c
@@ -120,18 +120,31 @@ static BOOL api_sink_data(pipes_struct *p)
\pipe\rpcecho commands
********************************************************************/
-NTSTATUS rpc_echo_init(void)
+struct api_struct api_echo_cmds[] = {
+ {"ADD_ONE", ECHO_ADD_ONE, api_add_one },
+ {"ECHO_DATA", ECHO_DATA, api_echo_data },
+ {"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data },
+ {"SINK_DATA", ECHO_SINK_DATA, api_sink_data },
+};
+
+
+void echo_get_pipe_fns( struct api_struct **fns, int *n_fns )
{
- struct api_struct api_echo_cmds[] = {
- {"ADD_ONE", ECHO_ADD_ONE, api_add_one },
- {"ECHO_DATA", ECHO_DATA, api_echo_data },
- {"SOURCE_DATA", ECHO_SOURCE_DATA, api_source_data },
- {"SINK_DATA", ECHO_SINK_DATA, api_sink_data },
- };
+ *fns = api_echo_cmds;
+ *n_fns = sizeof(api_echo_cmds) / sizeof(struct api_struct);
+}
+NTSTATUS rpc_echo_init(void)
+{
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION,
"rpcecho", "rpcecho", api_echo_cmds,
sizeof(api_echo_cmds) / sizeof(struct api_struct));
}
+#else /* DEVELOPER */
+
+NTSTATUS rpc_echo_init(void)
+{
+ return NT_STATUS_OK;
+}
#endif /* DEVELOPER */
diff --git a/source/rpc_server/srv_lsa.c b/source/rpc_server/srv_lsa.c
index 679cfb73bba..138fb1d7ef9 100644
--- a/source/rpc_server/srv_lsa.c
+++ b/source/rpc_server/srv_lsa.c
@@ -5,8 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Jim McDonough 2002,
- * Copyright (C) Anthony Liguori 2003.
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002-2003.
*
* 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
@@ -645,9 +644,8 @@ static BOOL api_lsa_query_info2(pipes_struct *p)
/***************************************************************************
\PIPE\ntlsa commands
***************************************************************************/
-NTSTATUS rpc_lsa_init(void)
-{
-static const struct api_struct api_lsa_cmds[] =
+
+static struct api_struct api_lsa_cmds[] =
{
{ "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
{ "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
@@ -672,17 +670,33 @@ static const struct api_struct api_lsa_cmds[] =
ADS DC capabilities */
{ "LSA_QUERYINFO2" , LSA_QUERYINFO2 , api_lsa_query_info2 }
};
-/*
- * NOTE: Certain calls can not be enabled if we aren't an ADS DC. Make sure
- * these calls are always last and that you decrement by the amount of calls
- * to disable.
- */
- int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct);
- if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) {
- funcs -= 1;
- }
+static int count_fns(void)
+{
+ int funcs = sizeof(api_lsa_cmds) / sizeof(struct api_struct);
+
+ /*
+ * NOTE: Certain calls can not be enabled if we aren't an ADS DC. Make sure
+ * these calls are always last and that you decrement by the amount of calls
+ * to disable.
+ */
+ if (!(SEC_ADS == lp_security() && ROLE_DOMAIN_PDC == lp_server_role())) {
+ funcs -= 1;
+ }
+
+ return funcs;
+}
+void lsa_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_lsa_cmds;
+ *n_fns = count_fns();
+}
+
+
+NTSTATUS rpc_lsa_init(void)
+{
+ int funcs = count_fns();
- return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds,
- funcs);
+ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsarpc", "lsass", api_lsa_cmds,
+ funcs);
}
diff --git a/source/rpc_server/srv_lsa_ds.c b/source/rpc_server/srv_lsa_ds.c
new file mode 100644
index 00000000000..5996935b220
--- /dev/null
+++ b/source/rpc_server/srv_lsa_ds.c
@@ -0,0 +1,91 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * RPC Pipe client / server routines
+ * Copyright (C) Gerald Carter 2003
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This is the interface for the registry functions. */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+/*******************************************************************
+ api_reg_open_entry
+ ********************************************************************/
+
+static BOOL api_dsrole_get_primary_dominfo(pipes_struct *p)
+{
+ DS_Q_GETPRIMDOMINFO q_u;
+ DS_R_GETPRIMDOMINFO r_u;
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the request */
+ if ( !ds_io_q_getprimdominfo("", data, 0, &q_u) )
+ return False;
+
+ /* construct reply. */
+ r_u.status = _dsrole_get_primary_dominfo( p, &q_u, &r_u );
+
+ if ( !ds_io_r_getprimdominfo("", rdata, 0, &r_u) )
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ stub functions for unimplemented RPC
+*******************************************************************/
+
+static BOOL api_dsrole_stub( pipes_struct *p )
+{
+ DEBUG(0,("api_dsrole_stub: Hmmm....didn't know this RPC existsed?!??!\n"));
+
+ return False;
+}
+
+
+/*******************************************************************
+ array of \PIPE\lsass (new windows 2000 UUID) operations
+********************************************************************/
+static struct api_struct api_lsa_ds_cmds[] = {
+ { "DS_NOP", DS_NOP, api_dsrole_stub }
+
+#if 0 /* disabled due to breakage with viewing domain users and groups
+ on a Samba PDC from win2k clients --jerry CIFS 2003 */
+ { "DS_GETPRIMDOMINFO", DS_GETPRIMDOMINFO, api_dsrole_get_primary_dominfo }
+#endif
+
+};
+
+void lsa_ds_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_lsa_ds_cmds;
+ *n_fns = sizeof(api_lsa_ds_cmds) / sizeof(struct api_struct);
+}
+
+
+NTSTATUS rpc_lsa_ds_init(void)
+{
+ return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "lsa_ds", "lsa_ds", api_lsa_ds_cmds,
+ sizeof(api_lsa_ds_cmds) / sizeof(struct api_struct));
+}
diff --git a/source/rpc_server/srv_lsa_ds_nt.c b/source/rpc_server/srv_lsa_ds_nt.c
new file mode 100644
index 00000000000..37540a9668c
--- /dev/null
+++ b/source/rpc_server/srv_lsa_ds_nt.c
@@ -0,0 +1,127 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * 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 2001.
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Implementation of registry functions. */
+
+#include "includes.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_SRV
+
+/********************************************************************
+ Fill in a DS_DOMINFO_CTR structure
+ ********************************************************************/
+
+static NTSTATUS fill_dsrole_dominfo_basic(TALLOC_CTX *ctx, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **info)
+{
+ DSROLE_PRIMARY_DOMAIN_INFO_BASIC *basic;
+ const char *netbios_domain;
+ fstring dnsdomain;
+
+ DEBUG(10,("fill_dsrole_dominfo_basic: enter\n"));
+
+ if ( !(basic = talloc_zero(ctx, sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC))) ) {
+ DEBUG(0,("fill_dsrole_dominfo_basic: FATAL error! talloc_xero() failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ switch ( lp_server_role() ) {
+ case ROLE_STANDALONE:
+ basic->machine_role = DSROLE_STANDALONE_SRV;
+ break;
+ case ROLE_DOMAIN_MEMBER:
+ basic->machine_role = DSROLE_DOMAIN_MEMBER_SRV;
+ break;
+ case ROLE_DOMAIN_BDC:
+ basic->machine_role = DSROLE_BDC;
+ basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
+ if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
+ basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
+ get_mydomname(dnsdomain);
+ strlower_m(dnsdomain);
+ break;
+ case ROLE_DOMAIN_PDC:
+ basic->machine_role = DSROLE_PDC;
+ basic->flags = DSROLE_PRIMARY_DS_RUNNING|DSROLE_PRIMARY_DS_MIXED_MODE;
+ if ( secrets_fetch_domain_guid( lp_workgroup(), &basic->domain_guid ) )
+ basic->flags |= DSROLE_PRIMARY_DOMAIN_GUID_PRESENT;
+ get_mydomname(dnsdomain);
+ strlower_m(dnsdomain);
+ break;
+ }
+
+ basic->unknown = 0x6173; /* seen on the wire; maybe padding */
+
+ /* always set netbios name */
+
+ basic->netbios_ptr = 1;
+ netbios_domain = get_global_sam_name();
+ init_unistr2( &basic->netbios_domain, netbios_domain, strlen(netbios_domain) );
+
+ basic->dnsname_ptr = 1;
+ init_unistr2( &basic->dns_domain, dnsdomain, strlen(dnsdomain) );
+ basic->forestname_ptr = 1;
+ init_unistr2( &basic->forest_domain, dnsdomain, strlen(dnsdomain) );
+
+
+ /* fill in some additional fields if we are a member of an AD domain */
+
+ if ( lp_security() == SEC_ADS ) {
+ /* TODO */
+ ;;
+ }
+
+ *info = basic;
+
+ return NT_STATUS_OK;
+}
+
+/********************************************************************
+ Implement the DsroleGetPrimaryDomainInfo() call
+ ********************************************************************/
+
+NTSTATUS _dsrole_get_primary_dominfo(pipes_struct *p, DS_Q_GETPRIMDOMINFO *q_u, DS_R_GETPRIMDOMINFO *r_u)
+{
+ NTSTATUS result = NT_STATUS_OK;
+ uint32 level = q_u->level;
+
+ switch ( level ) {
+
+ case DsRolePrimaryDomainInfoBasic:
+ r_u->level = DsRolePrimaryDomainInfoBasic;
+ r_u->ptr = 1;
+ result = fill_dsrole_dominfo_basic( p->mem_ctx, &r_u->info.basic );
+ break;
+
+ default:
+ DEBUG(0,("_dsrole_get_primary_dominfo: Unsupported info level [%d]!\n",
+ level));
+ result = NT_STATUS_INVALID_LEVEL;
+ }
+
+ return result;
+}
+
+
+
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index ca3021a8762..330dd727efd 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -6,7 +6,7 @@
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Jeremy Allison 2001,
* Copyright (C) Rafal Szczesniak 2002,
- * Copyright (C) Jim McDonough 2002.
+ * 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
@@ -502,7 +502,7 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E
if (!(info->access & POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
- nt_status = secrets_get_trusted_domains(p->mem_ctx, &enum_context, max_num_domains, &num_domains, &trust_doms);
+ nt_status = secrets_get_trusted_domains(p->mem_ctx, (int *)&enum_context, max_num_domains, (int *)&num_domains, &trust_doms);
if (!NT_STATUS_IS_OK(nt_status) &&
!NT_STATUS_EQUAL(nt_status, STATUS_MORE_ENTRIES) &&
diff --git a/source/rpc_server/srv_netlog.c b/source/rpc_server/srv_netlog.c
index 0cd40731774..9c10d86379d 100644
--- a/source/rpc_server/srv_netlog.c
+++ b/source/rpc_server/srv_netlog.c
@@ -5,7 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Jeremy Allison 1998-2001,
- * Copyright (C) Anthony Liguori 2003.
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
*
* 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
@@ -320,10 +320,7 @@ static BOOL api_net_logon_ctrl(pipes_struct *p)
/*******************************************************************
array of \PIPE\NETLOGON operations
********************************************************************/
-
-NTSTATUS rpc_net_init(void)
-{
- static struct api_struct api_net_cmds [] =
+static struct api_struct api_net_cmds [] =
{
{ "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
{ "NET_AUTH" , NET_AUTH , api_net_auth },
@@ -336,6 +333,14 @@ NTSTATUS rpc_net_init(void)
{ "NET_LOGON_CTRL" , NET_LOGON_CTRL , api_net_logon_ctrl }
};
+void netlog_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_net_cmds;
+ *n_fns = sizeof(api_net_cmds) / sizeof(struct api_struct);
+}
+
+NTSTATUS rpc_net_init(void)
+{
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "NETLOGON", "lsass", api_net_cmds,
sizeof(api_net_cmds) / sizeof(struct api_struct));
}
diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c
index c4a87d2e26d..602cd7d2d50 100644
--- a/source/rpc_server/srv_netlog_nt.c
+++ b/source/rpc_server/srv_netlog_nt.c
@@ -5,7 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Jeremy Allison 1998-2001.
- * Copyirht (C) Andrew Bartlett 2001.
+ * Copyright (C) Andrew Bartlett 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
diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c
index 9a63ebc7a3a..d1fb587d748 100644
--- a/source/rpc_server/srv_pipe.c
+++ b/source/rpc_server/srv_pipe.c
@@ -5,7 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
* Copyright (C) Paul Ashton 1997-1998,
* Copyright (C) Jeremy Allison 1999,
- * Copyright (C) Anthony Liguori 2003.
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
*
* 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
@@ -277,11 +277,6 @@ BOOL create_next_pdu(pipes_struct *p)
prs_init(&rverf, 0, p->mem_ctx, MARSHALL);
prs_init(&rauth, 0, p->mem_ctx, MARSHALL);
- if ((p->netsec_auth.seq_num & 1) == 0) {
- DEBUG(0,("SCHANNEL ERROR: seq_num must be odd in server! (seq_num=%d)\n",
- p->netsec_auth.seq_num));
- }
-
init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, nullbytes, nullbytes);
netsec_encode(&p->netsec_auth,
@@ -718,26 +713,19 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status)
Used to reject unknown binds from Win2k.
*******************************************************************/
-BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract,
- RPC_IFACE* transfer)
+BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract,
+ RPC_IFACE* transfer, uint32 context_id)
{
extern struct pipe_id_info pipe_names[];
+ char *pipe_name = p->name;
int i=0;
fstring pname;
+
fstrcpy(pname,"\\PIPE\\");
fstrcat(pname,pipe_name);
DEBUG(3,("check_bind_req for %s\n", pname));
-#ifndef SUPPORT_NEW_LSARPC_UUID
-
- /* check for the first pipe matching the name */
-
- for ( i=0; pipe_names[i].client_pipe; i++ ) {
- if ( strequal(pipe_names[i].client_pipe, pname) )
- break;
- }
-#else
/* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */
for ( i=0; pipe_names[i].client_pipe; i++ )
@@ -748,29 +736,34 @@ BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract,
&& (transfer->version == pipe_names[i].trans_syntax.version)
&& (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) == 0) )
{
+ struct api_struct *fns = NULL;
+ int n_fns = 0;
+ PIPE_RPC_FNS *context_fns;
+
+ if ( !(context_fns = malloc(sizeof(PIPE_RPC_FNS))) ) {
+ DEBUG(0,("check_bind_req: malloc() failed!\n"));
+ return False;
+ }
+
+ /* save the RPC function table associated with this bind */
+
+ get_pipe_fns(i, &fns, &n_fns);
+
+ context_fns->cmds = fns;
+ context_fns->n_cmds = n_fns;
+ context_fns->context_id = context_id;
+
+ /* add to the list of open contexts */
+
+ DLIST_ADD( p->contexts, context_fns );
+
break;
}
}
-#endif
if(pipe_names[i].client_pipe == NULL)
return False;
-#ifndef SUPPORT_NEW_LSARPC_UUID
- /* check the abstract interface */
- if ( (abstract->version != pipe_names[i].abstr_syntax.version)
- || (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(RPC_UUID)) != 0) )
- {
- return False;
- }
-
- /* check the transfer interface */
- if ( (transfer->version != pipe_names[i].trans_syntax.version)
- || (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) != 0) )
- {
- return False;
- }
-#endif
return True;
}
@@ -866,7 +859,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
}
if (i == rpc_lookup_size) {
- if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) {
+ if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) {
DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
p->name ));
if(!setup_bind_nak(p))
@@ -883,10 +876,10 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
}
}
- if (i == rpc_lookup_size) {
- DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
- return False;
- }
+ if (i == rpc_lookup_size) {
+ DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name));
+ return False;
+ }
}
/* decode the bind request */
@@ -1033,7 +1026,8 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
unknown to NT4)
Needed when adding entries to a DACL from NT5 - SK */
- if(check_bind_req(p->name, &hdr_rb.abstract, &hdr_rb.transfer)) {
+ if(check_bind_req(p, &hdr_rb.abstract, &hdr_rb.transfer, hdr_rb.context_id ))
+ {
init_rpc_hdr_ba(&hdr_ba,
MAX_PDU_FRAG_LEN,
MAX_PDU_FRAG_LEN,
@@ -1232,10 +1226,10 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
sizeof(p->ntlmssp_hash));
dump_data_pw("Incoming RPC PDU (NTLMSSP sealed)\n",
- data, data_len);
+ (const unsigned char *)data, data_len);
NTLMSSPcalc_p(p, (uchar*)data, data_len);
dump_data_pw("Incoming RPC PDU (NTLMSSP unsealed)\n",
- data, data_len);
+ (const unsigned char *)data, data_len);
crc32 = crc32_calc_buffer(data, data_len);
}
@@ -1397,6 +1391,48 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p
}
/****************************************************************************
+ Find the set of RPC functions associated with this context_id
+****************************************************************************/
+
+static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id )
+{
+ PIPE_RPC_FNS *fns = NULL;
+ PIPE_RPC_FNS *tmp = NULL;
+
+ if ( !list ) {
+ DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n"));
+ return NULL;
+ }
+
+ for (tmp=list; tmp; tmp=tmp->next ) {
+ if ( tmp->context_id == context_id )
+ break;
+ }
+
+ fns = tmp;
+
+ return fns;
+}
+
+/****************************************************************************
+ memory cleanup
+****************************************************************************/
+
+void free_pipe_rpc_context( PIPE_RPC_FNS *list )
+{
+ PIPE_RPC_FNS *tmp = list;
+ PIPE_RPC_FNS *tmp2;
+
+ while (tmp) {
+ tmp2 = tmp->next;
+ SAFE_FREE(tmp);
+ tmp = tmp2;
+ }
+
+ return;
+}
+
+/****************************************************************************
Find the correct RPC function to call for this request.
If the pipe is authenticated then become the correct UNIX user
before doing the call.
@@ -1404,9 +1440,9 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p
BOOL api_pipe_request(pipes_struct *p)
{
- int i = 0;
BOOL ret = False;
-
+ PIPE_RPC_FNS *pipe_fns;
+
if (p->ntlmssp_auth_validated) {
if(!become_authenticated_pipe_user(p)) {
@@ -1416,36 +1452,19 @@ BOOL api_pipe_request(pipes_struct *p)
}
DEBUG(5, ("Requested \\PIPE\\%s\n", p->name));
-
- for (i = 0; i < rpc_lookup_size; i++) {
- if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
- DEBUG(3,("Doing \\PIPE\\%s\n",
- rpc_lookup[i].pipe.clnt));
- set_current_rpc_talloc(p->mem_ctx);
- ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt,
- rpc_lookup[i].cmds,
- rpc_lookup[i].n_cmds);
- set_current_rpc_talloc(NULL);
- break;
- }
+
+ /* get the set of RPC functions for this context */
+
+ pipe_fns = find_pipe_fns_by_context(p->contexts, p->hdr_req.context_id);
+
+ if ( pipe_fns ) {
+ set_current_rpc_talloc(p->mem_ctx);
+ ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds);
+ set_current_rpc_talloc(NULL);
}
-
-
- if (i == rpc_lookup_size) {
- smb_probe_module("rpc", p->name);
-
- for (i = 0; i < rpc_lookup_size; i++) {
- if (strequal(rpc_lookup[i].pipe.clnt, p->name)) {
- DEBUG(3,("Doing \\PIPE\\%s\n",
- rpc_lookup[i].pipe.clnt));
- set_current_rpc_talloc(p->mem_ctx);
- ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt,
- rpc_lookup[i].cmds,
- rpc_lookup[i].n_cmds);
- set_current_rpc_talloc(NULL);
- break;
- }
- }
+ else {
+ DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n",
+ p->hdr_req.context_id, p->name));
}
if(p->ntlmssp_auth_validated)
@@ -1534,3 +1553,56 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name,
return True;
}
+
+/*******************************************************************
+*******************************************************************/
+
+void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns )
+{
+ struct api_struct *cmds = NULL;
+ int n_cmds = 0;
+
+ switch ( idx ) {
+ case PI_LSARPC:
+ lsa_get_pipe_fns( &cmds, &n_cmds );
+ break;
+ case PI_LSARPC_DS:
+ lsa_ds_get_pipe_fns( &cmds, &n_cmds );
+ break;
+ case PI_SAMR:
+ samr_get_pipe_fns( &cmds, &n_cmds );
+ break;
+ case PI_NETLOGON:
+ netlog_get_pipe_fns( &cmds, &n_cmds );
+ break;
+ case PI_SRVSVC:
+ srvsvc_get_pipe_fns( &cmds, &n_cmds );
+ break;
+ case PI_WKSSVC:
+ wkssvc_get_pipe_fns( &cmds, &n_cmds );
+ break;
+ case PI_WINREG:
+ reg_get_pipe_fns( &cmds, &n_cmds );
+ break;
+ case PI_SPOOLSS:
+ spoolss_get_pipe_fns( &cmds, &n_cmds );
+ break;
+ case PI_NETDFS:
+ netdfs_get_pipe_fns( &cmds, &n_cmds );
+ break;
+#ifdef DEVELOPER
+ case PI_ECHO:
+ echo_get_pipe_fns( &cmds, &n_cmds );
+ break;
+#endif
+ default:
+ DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx));
+ }
+
+ *fns = cmds;
+ *n_fns = n_cmds;
+
+ return;
+}
+
+
diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index 125f6037710..55def976732 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/rpc_server/srv_pipe_hnd.c
@@ -1106,6 +1106,8 @@ static BOOL close_internal_rpc_pipe_hnd(void *np_conn)
if (p->mem_ctx)
talloc_destroy(p->mem_ctx);
+
+ free_pipe_rpc_context( p->contexts );
/* Free the handles database. */
close_policy_by_pipe(p);
diff --git a/source/rpc_server/srv_reg.c b/source/rpc_server/srv_reg.c
index 43bb1ad86a1..b780be0aff3 100644
--- a/source/rpc_server/srv_reg.c
+++ b/source/rpc_server/srv_reg.c
@@ -7,7 +7,7 @@
* Copyright (C) Marc Jacobsen 2000,
* Copyright (C) Jeremy Allison 2001,
* Copyright (C) Gerald Carter 2002,
- * Copyright (C) Anthony Liguori 2003.
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
*
* 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
@@ -367,16 +367,12 @@ static BOOL api_reg_save_key(pipes_struct *p)
return True;
}
-
-
/*******************************************************************
array of \PIPE\reg operations
********************************************************************/
-NTSTATUS rpc_reg_init(void)
+static struct api_struct api_reg_cmds[] =
{
- static struct api_struct api_reg_cmds[] =
- {
{ "REG_CLOSE" , REG_CLOSE , api_reg_close },
{ "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
{ "REG_OPEN_HKCR" , REG_OPEN_HKCR , api_reg_open_hkcr },
@@ -390,7 +386,17 @@ NTSTATUS rpc_reg_init(void)
{ "REG_ABORT_SHUTDOWN" , REG_ABORT_SHUTDOWN , api_reg_abort_shutdown },
{ "REG_UNKNOWN_1A" , REG_UNKNOWN_1A , api_reg_unknown_1a },
{ "REG_SAVE_KEY" , REG_SAVE_KEY , api_reg_save_key }
- };
+};
+
+void reg_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_reg_cmds;
+ *n_fns = sizeof(api_reg_cmds) / sizeof(struct api_struct);
+}
+
+NTSTATUS rpc_reg_init(void)
+{
+
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "winreg", "winreg", api_reg_cmds,
sizeof(api_reg_cmds) / sizeof(struct api_struct));
}
diff --git a/source/rpc_server/srv_reg_nt.c b/source/rpc_server/srv_reg_nt.c
index 5632544909a..a4e3638be60 100644
--- a/source/rpc_server/srv_reg_nt.c
+++ b/source/rpc_server/srv_reg_nt.c
@@ -596,11 +596,11 @@ NTSTATUS _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u
/* security check */
alpha_strcpy (chkmsg, message, NULL, sizeof(message));
/* timeout */
- snprintf(timeout, sizeof(timeout), "%d", q_u->timeout);
+ fstr_sprintf(timeout, "%d", q_u->timeout);
/* reboot */
- snprintf(r, sizeof(r), (q_u->reboot) ? SHUTDOWN_R_STRING : "");
+ fstr_sprintf(r, (q_u->reboot) ? SHUTDOWN_R_STRING : "");
/* force */
- snprintf(f, sizeof(f), (q_u->force) ? SHUTDOWN_F_STRING : "");
+ fstr_sprintf(f, (q_u->force) ? SHUTDOWN_F_STRING : "");
pstrcpy(shutdown_script, lp_shutdown_script());
diff --git a/source/rpc_server/srv_samr.c b/source/rpc_server/srv_samr.c
index 9250b023d3b..d9624bdff02 100644
--- a/source/rpc_server/srv_samr.c
+++ b/source/rpc_server/srv_samr.c
@@ -6,8 +6,7 @@
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Marc Jacobsen 1999,
* Copyright (C) Jean François Micouleau 1998-2001,
- * Copyright (C) Anthony Liguori 2002-2003,
- * Copyright (C) Jim McDonough 2002.
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002-2003.
*
* Split into interface and implementation modules by,
*
@@ -1443,10 +1442,8 @@ static BOOL api_samr_set_dom_info(pipes_struct *p)
array of \PIPE\samr operations
********************************************************************/
-NTSTATUS rpc_samr_init(void)
+static struct api_struct api_samr_cmds [] =
{
- static struct api_struct api_samr_cmds [] =
- {
{"SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
{"SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
{"SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
@@ -1500,7 +1497,17 @@ NTSTATUS rpc_samr_init(void)
{"SAMR_UNKNOWN_2E" , SAMR_UNKNOWN_2E , api_samr_unknown_2e },
{"SAMR_SET_DOMAIN_INFO" , SAMR_SET_DOMAIN_INFO , api_samr_set_dom_info },
{"SAMR_CONNECT4" , SAMR_CONNECT4 , api_samr_connect4 }
- };
+};
+
+void samr_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_samr_cmds;
+ *n_fns = sizeof(api_samr_cmds) / sizeof(struct api_struct);
+}
+
+
+NTSTATUS rpc_samr_init(void)
+{
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "samr", "lsass", api_samr_cmds,
sizeof(api_samr_cmds) / sizeof(struct api_struct));
}
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index 9324fd4765a..a338b5eb4d8 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -7,8 +7,7 @@
* Copyright (C) Marc Jacobsen 1999,
* Copyright (C) Jeremy Allison 2001-2002,
* Copyright (C) Jean François Micouleau 1998-2001,
- * Copyright (C) Anthony Liguori 2002,
- * Copyright (C) Jim McDonough 2002.
+ * 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
@@ -914,7 +913,6 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
} else if (sid_equal(sid, get_global_sam_sid()) && !lp_hide_local_users()) {
struct sys_grent *glist;
struct sys_grent *grp;
- struct passwd *pw;
gid_t winbind_gid_low, winbind_gid_high;
BOOL winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
@@ -953,7 +951,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
/* Don't return user private groups... */
- if ((pw = Get_Pwnam(smap.nt_name)) != 0) {
+ if (Get_Pwnam(smap.nt_name) != 0) {
DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
continue;
}
@@ -1014,8 +1012,13 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO
*p_num_entries = 0;
+ /* access checks for the users were performed higher up. become/unbecome_root()
+ needed for some passdb backends to enumerate groups */
+
+ become_root();
pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
-
+ unbecome_root();
+
num_entries=group_entries-start_idx;
/* limit the number of entries */
@@ -1517,17 +1520,17 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
{
- fstring user_name;
- fstring wks;
+ fstring user_name;
+ fstring wks;
- DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
+ DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
- r_u->status = NT_STATUS_OK;
+ r_u->status = NT_STATUS_OK;
- rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
- rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
+ rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
+ rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
- DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
+ DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
/*
* Pass the user through the NT -> unix user mapping
@@ -1541,14 +1544,14 @@ NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_
* is case insensitive.
*/
- r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
- q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
+ r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
+ q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
- init_samr_r_chgpasswd_user(r_u, r_u->status);
+ init_samr_r_chgpasswd_user(r_u, r_u->status);
- DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
+ DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
- return r_u->status;
+ return r_u->status;
}
/*******************************************************************
@@ -2141,7 +2144,7 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
num_users, num_groups, num_aliases);
break;
case 0x03:
- account_policy_get(AP_TIME_TO_LOGOUT, (int *)&u_logout);
+ account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
unix_to_nt_time_abs(&nt_logout, u_logout);
init_unk_info3(&ctr->info.inf3, nt_logout);
@@ -2259,7 +2262,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
* now have some sainity-checking to match.
*/
- DEBUG(10,("checking account %s at pos %d for $ termination\n",account, strlen(account)-1));
+ DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
/*
* we used to have code here that made sure the acb_info flags
@@ -2370,6 +2373,7 @@ NTSTATUS _api_samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_
NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
{
struct samr_info *info = NULL;
+ uint32 des_access = q_u->access_mask;
/* Access check */
@@ -2387,6 +2391,13 @@ NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CO
if ((info = get_samr_info_by_sid(NULL)) == NULL)
return NT_STATUS_NO_MEMORY;
+ /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
+ was observed from a win98 client trying to enumerate users (when configured
+ user level access control on shares) --jerry */
+
+ se_map_generic( &des_access, &sam_generic_mapping );
+ info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
+
info->status = q_u->unknown_0;
/* get a (unique) handle. open a policy on it. */
@@ -2511,7 +2522,9 @@ NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_
if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) {
+ if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
+ SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
+ {
return r_u->status;
}
@@ -2761,8 +2774,9 @@ static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
grp = getgrgid(gid);
if (grp == NULL) {
- DEBUG(2,("Could not find primary group %d for "
- "user %s\n", gid, pdb_get_username(sampass)));
+ DEBUG(2,("Could not find primary group %lu for "
+ "user %s\n", (unsigned long)gid,
+ pdb_get_username(sampass)));
return False;
}
diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c
index 3e9ed9e39f9..a903ae90298 100755
--- a/source/rpc_server/srv_spoolss.c
+++ b/source/rpc_server/srv_spoolss.c
@@ -6,7 +6,7 @@
* Copyright (C) Jean François Micouleau 1998-2000,
* Copyright (C) Jeremy Allison 2001,
* Copyright (C) Gerald Carter 2001-2002,
- * Copyright (C) Anthony Liguori 2003.
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
*
* 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
@@ -1580,8 +1580,6 @@ static BOOL api_spoolss_replycloseprinter(pipes_struct *p)
\pipe\spoolss commands
********************************************************************/
-NTSTATUS rpc_spoolss_init(void)
-{
struct api_struct api_spoolss_cmds[] =
{
{"SPOOLSS_OPENPRINTER", SPOOLSS_OPENPRINTER, api_spoolss_open_printer },
@@ -1640,6 +1638,15 @@ NTSTATUS rpc_spoolss_init(void)
{"SPOOLSS_REPLYCLOSEPRINTER", SPOOLSS_REPLYCLOSEPRINTER, api_spoolss_replycloseprinter }
#endif
};
+
+void spoolss_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_spoolss_cmds;
+ *n_fns = sizeof(api_spoolss_cmds) / sizeof(struct api_struct);
+}
+
+NTSTATUS rpc_spoolss_init(void)
+{
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "spoolss", "spoolss", api_spoolss_cmds,
sizeof(api_spoolss_cmds) / sizeof(struct api_struct));
}
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 2d316051af2..725672da69d 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -387,7 +387,6 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
char *cmd = lp_deleteprinter_cmd();
pstring command;
int ret;
- int i;
/* Printer->dev.handlename equals portname equals sharename */
slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd,
@@ -406,7 +405,7 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
/* go ahead and re-read the services immediately */
reload_services( False );
- if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) < 0 )
+ if ( lp_servicenumber( Printer->dev.handlename ) < 0 )
return WERR_ACCESS_DENIED;
}
@@ -478,7 +477,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
fstring sname;
BOOL found=False;
- DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename)));
+ DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
ZERO_STRUCT(Printer->dev.printerservername);
@@ -497,7 +496,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
aprinter=handlename;
}
- DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
+ DEBUGADD(5,("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter)));
/*
* The original code allowed smbd to store a printer name that
@@ -563,7 +562,7 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
new_printer->notify.option=NULL;
- if ( !(new_printer->ctx = talloc_init("Printer Entry [0x%x]", (uint32)hnd)) ) {
+ if ( !(new_printer->ctx = talloc_init("Printer Entry [%p]", hnd)) ) {
DEBUG(0,("open_printer_hnd: talloc_init() failed!\n"));
close_printer_handle(p, hnd);
return False;
@@ -957,7 +956,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
SPOOL_NOTIFY_INFO_DATA *data;
uint32 data_len = 0;
uint32 id;
- int i, event_index;
+ int i;
/* Is there notification on this handle? */
@@ -980,8 +979,6 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
data = talloc( mem_ctx, msg_group->num_msgs*sizeof(SPOOL_NOTIFY_INFO_DATA) );
ZERO_STRUCTP(data);
- event_index = 0;
-
/* build the array of change notifications */
sending_msg_count = 0;
@@ -1176,7 +1173,7 @@ static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, siz
msg_count = IVAL(buf, 0);
msg_ptr = buf + 4;
- DEBUG(5, ("receive_notify2_message_list: got %d messages in list\n", msg_count));
+ DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
if (msg_count == 0) {
DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
@@ -2393,9 +2390,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
- fstring string;
-
- fstrcpy(string, string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
+ const char *string="C:\\PRINTERS";
*type = 0x1;
*needed = 2*(strlen(string)+1);
if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
@@ -2411,7 +2406,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
}
if (!StrCaseCmp(value, "Architecture")) {
- pstring string="Windows NT x86";
+ const char *string="Windows NT x86";
*type = 0x1;
*needed = 2*(strlen(string)+1);
if((*data = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
@@ -3755,7 +3750,6 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
int n_services=lp_numservices();
int i;
- uint32 id;
SPOOL_NOTIFY_OPTION *option;
SPOOL_NOTIFY_OPTION_TYPE *option_type;
@@ -3765,7 +3759,6 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
return WERR_BADFID;
option=Printer->notify.option;
- id=1;
info->version=2;
info->data=NULL;
info->count=0;
@@ -5135,7 +5128,7 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c
else
pstrcpy( line, v );
- DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
+ DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
/* add one extra unit16 for the second terminating NULL */
@@ -6194,12 +6187,9 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
int snum;
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
- WERROR result;
DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
- result = WERR_OK;
-
if (!Printer)
return WERR_BADFID;
@@ -7102,7 +7092,6 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name)
init_unistr(&port->port_name, name);
init_unistr(&port->monitor_name, "Local Monitor");
init_unistr(&port->description, "Local Port");
-#define PORT_TYPE_WRITE 1
port->port_type=PORT_TYPE_WRITE;
port->reserved=0x0;
}
@@ -7725,7 +7714,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
NT_PRINTER_INFO_LEVEL *printer = NULL;
- uint32 param_index;
uint32 biggest_valuesize;
uint32 biggest_datasize;
uint32 data_len;
@@ -7774,7 +7762,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
{
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
- param_index = 0;
biggest_valuesize = 0;
biggest_datasize = 0;
@@ -7912,6 +7899,11 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
return WERR_BADFID;
}
+ if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) {
+ DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
+ return WERR_INVALID_PARAM;
+ }
+
if (!get_printer_snum(p,handle, &snum))
return WERR_BADFID;
@@ -8698,7 +8690,7 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u,
/* Is the handle to a printer or to the server? */
if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) {
- DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n"));
+ DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
status = WERR_INVALID_PARAM;
goto done;
}
@@ -8780,10 +8772,15 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u,
SetPrinterData if key is "PrinterDriverData" */
if (!Printer) {
- DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+ DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
return WERR_BADFID;
}
+ if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) {
+ DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
+ return WERR_INVALID_PARAM;
+ }
+
if ( !get_printer_snum(p,handle, &snum) )
return WERR_BADFID;
@@ -9092,8 +9089,8 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
{
if ( (enum_values=talloc(p->mem_ctx, num_entries*sizeof(PRINTER_ENUM_VALUES))) == NULL )
{
- DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%d] bytes!\n",
- num_entries*sizeof(PRINTER_ENUM_VALUES)));
+ DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
+ (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
result = WERR_NOMEM;
goto done;
}
@@ -9178,12 +9175,11 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
{
pstring path;
pstring long_archi;
- const char *short_archi;
PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
- if (!(short_archi = get_short_archi(long_archi)))
+ if (!get_short_archi(long_archi))
return WERR_INVALID_ENVIRONMENT;
if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
diff --git a/source/rpc_server/srv_srvsvc.c b/source/rpc_server/srv_srvsvc.c
index deba1224210..9d85088e568 100644
--- a/source/rpc_server/srv_srvsvc.c
+++ b/source/rpc_server/srv_srvsvc.c
@@ -5,7 +5,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Jeremy Allison 2001,
- * Copyright (C) Anthony Liguori 2003.
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
*
* 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
@@ -526,10 +526,8 @@ static BOOL api_srv_net_file_set_secdesc(pipes_struct *p)
\PIPE\srvsvc commands
********************************************************************/
-NTSTATUS rpc_srv_init(void)
+static struct api_struct api_srv_cmds[] =
{
- static const struct api_struct api_srv_cmds[] =
- {
{ "SRV_NET_CONN_ENUM" , SRV_NET_CONN_ENUM , api_srv_net_conn_enum },
{ "SRV_NET_SESS_ENUM" , SRV_NET_SESS_ENUM , api_srv_net_sess_enum },
{ "SRV_NET_SHARE_ENUM_ALL" , SRV_NET_SHARE_ENUM_ALL , api_srv_net_share_enum_all },
@@ -547,7 +545,17 @@ NTSTATUS rpc_srv_init(void)
{ "SRV_NET_NAME_VALIDATE" , SRV_NET_NAME_VALIDATE , api_srv_net_name_validate },
{ "SRV_NET_FILE_QUERY_SECDESC", SRV_NET_FILE_QUERY_SECDESC, api_srv_net_file_query_secdesc },
{ "SRV_NET_FILE_SET_SECDESC" , SRV_NET_FILE_SET_SECDESC , api_srv_net_file_set_secdesc }
- };
+};
+
+void srvsvc_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_srv_cmds;
+ *n_fns = sizeof(api_srv_cmds) / sizeof(struct api_struct);
+}
+
+
+NTSTATUS rpc_srv_init(void)
+{
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "srvsvc", "ntsvcs", api_srv_cmds,
sizeof(api_srv_cmds) / sizeof(struct api_struct));
}
diff --git a/source/rpc_server/srv_wkssvc.c b/source/rpc_server/srv_wkssvc.c
index 8efa29fd0bc..b5c1af34d9d 100644
--- a/source/rpc_server/srv_wkssvc.c
+++ b/source/rpc_server/srv_wkssvc.c
@@ -4,7 +4,7 @@
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997,
- * Copyright (C) Anthony Liguori 2003.
+ * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003.
*
* 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
@@ -60,12 +60,19 @@ static BOOL api_wks_query_info(pipes_struct *p)
\PIPE\wkssvc commands
********************************************************************/
-NTSTATUS rpc_wks_init(void)
+static struct api_struct api_wks_cmds[] =
{
- static struct api_struct api_wks_cmds[] =
- {
{ "WKS_Q_QUERY_INFO", WKS_QUERY_INFO, api_wks_query_info }
- };
+};
+
+void wkssvc_get_pipe_fns( struct api_struct **fns, int *n_fns )
+{
+ *fns = api_wks_cmds;
+ *n_fns = sizeof(api_wks_cmds) / sizeof(struct api_struct);
+}
+
+NTSTATUS rpc_wks_init(void)
+{
return rpc_pipe_register_commands(SMB_RPC_INTERFACE_VERSION, "wkssvc", "ntsvcs", api_wks_cmds,
sizeof(api_wks_cmds) / sizeof(struct api_struct));
}
diff --git a/source/rpcclient/cmd_ds.c b/source/rpcclient/cmd_ds.c
index 4c2f52e2915..b01236d9a58 100644
--- a/source/rpcclient/cmd_ds.c
+++ b/source/rpcclient/cmd_ds.c
@@ -47,13 +47,33 @@ static NTSTATUS cmd_ds_dsrole_getprimarydominfo(struct cli_state *cli,
return result;
}
+static NTSTATUS cmd_ds_enum_domain_trusts(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ NTSTATUS result;
+ uint32 flags = 0x1;
+ DS_DOMAIN_TRUSTS *trusts = NULL;
+ unsigned int num_domains = 0;
+
+ result = cli_ds_enum_domain_trusts( cli, mem_ctx, cli->desthost, flags,
+ &trusts, &num_domains );
+
+ printf( "%d domains returned\n", num_domains );
+
+ SAFE_FREE( trusts );
+
+ return result;
+}
+
/* List of commands exported by this module */
struct cmd_set ds_commands[] = {
{ "LSARPC-DS" },
- { "dsroledominfo", RPC_RTYPE_NTSTATUS, cmd_ds_dsrole_getprimarydominfo, NULL, PI_LSARPC_DS, "Get Primary Domain Information", "" },
+ { "dsroledominfo", RPC_RTYPE_NTSTATUS, cmd_ds_dsrole_getprimarydominfo, NULL, PI_LSARPC_DS, "Get Primary Domain Information", "" },
+ { "dsenumdomtrusts", RPC_RTYPE_NTSTATUS, cmd_ds_enum_domain_trusts, NULL, PI_NETLOGON, "Enumerate all trusted domains in an AD forest", "" },
{ NULL }
};
diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c
index 0ec78a06734..e7d5f7f1185 100644
--- a/source/rpcclient/cmd_netlogon.c
+++ b/source/rpcclient/cmd_netlogon.c
@@ -308,6 +308,8 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type);
+ clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
+
if (!NT_STATUS_IS_OK(result))
goto done;
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index 40d01d0f5a2..722d66621a6 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -125,7 +125,7 @@ static const char *display_time(NTTIME nttime)
mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60;
secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60);
- snprintf(string, sizeof(string)-1, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
+ fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
return (string);
}
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index b2fa802e9a3..d2e62ac3a3d 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -395,7 +395,31 @@ static void display_port_info_2(PORT_INFO_2 *i2)
rpcstr_pull(buffer, i2->description.buffer, sizeof(buffer), -1, STR_TERMINATE);
printf("\tDescription:\t[%s]\n", buffer);
- printf("\tPort Type:\t[%d]\n", i2->port_type);
+ printf("\tPort Type:\t" );
+ if ( i2->port_type ) {
+ int comma = 0; /* hack */
+ printf( "[" );
+ if ( i2->port_type & PORT_TYPE_READ ) {
+ printf( "Read" );
+ comma = 1;
+ }
+ if ( i2->port_type & PORT_TYPE_WRITE ) {
+ printf( "%sWrite", comma ? ", " : "" );
+ comma = 1;
+ }
+ /* These two have slightly different interpretations
+ on 95/98/ME but I'm disregarding that for now */
+ if ( i2->port_type & PORT_TYPE_REDIRECTED ) {
+ printf( "%sRedirected", comma ? ", " : "" );
+ comma = 1;
+ }
+ if ( i2->port_type & PORT_TYPE_NET_ATTACHED ) {
+ printf( "%sNet-Attached", comma ? ", " : "" );
+ }
+ printf( "]\n" );
+ } else {
+ printf( "[Unset]\n" );
+ }
printf("\tReserved:\t[%d]\n", i2->reserved);
printf("\n");
}
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index af021962f5d..6efa9874a06 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -37,25 +37,10 @@ static struct cmd_list {
struct cmd_set *cmd_set;
} *cmd_list;
-/*****************************************************************************
- stubb functions
-****************************************************************************/
-
-void become_root( void )
-{
- return;
-}
-
-void unbecome_root( void )
-{
- return;
-}
-
-
/****************************************************************************
handle completion of commands for readline
****************************************************************************/
-static char **completion_fn(char *text, int start, int end)
+static char **completion_fn(const char *text, int start, int end)
{
#define MAX_COMPLETIONS 100
char **matches;
@@ -370,66 +355,64 @@ static NTSTATUS cmd_none(struct cli_state *cli, TALLOC_CTX *mem_ctx,
static NTSTATUS cmd_schannel(struct cli_state *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
{
+ NTSTATUS ret;
uchar trust_password[16];
uint32 sec_channel_type;
- uint32 neg_flags = 0x000001ff;
- NTSTATUS result;
static uchar zeros[16];
+ if (argc == 2) {
+ strhex_to_str((char *)cli->auth_info.sess_key,
+ strlen(argv[1]),
+ argv[1]);
+ memcpy(cli->sess_key, cli->auth_info.sess_key, sizeof(cli->sess_key));
+
+ cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
+ cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
+ cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
+
+ return NT_STATUS_OK;
+ }
+
/* Cleanup */
- if ((memcmp(cli->auth_info.sess_key, zeros, sizeof(cli->auth_info.sess_key)) != 0)
- && (cli->saved_netlogon_pipe_fnum != 0)) {
+ if ((memcmp(cli->auth_info.sess_key, zeros, sizeof(cli->auth_info.sess_key)) != 0)) {
if (cli->pipe_auth_flags == (AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL)) {
+ /* already in this mode nothing to do */
return NT_STATUS_OK;
} else {
- /* still have session, just need to use it again */
+ /* schannel is setup, just need to use it again */
cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
if (cli->nt_pipe_fnum != 0)
cli_nt_session_close(cli);
+ return NT_STATUS_OK;
}
}
if (cli->nt_pipe_fnum != 0)
cli_nt_session_close(cli);
- cli->pipe_auth_flags = 0;
-
+ cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
+ cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
+ cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
+
if (!secrets_fetch_trust_account_password(lp_workgroup(),
trust_password,
NULL, &sec_channel_type)) {
return NT_STATUS_UNSUCCESSFUL;
}
-
- if (!cli_nt_session_open(cli, PI_NETLOGON)) {
- DEBUG(0, ("Could not initialise %s\n",
- get_pipe_name_from_index(PI_NETLOGON)));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- neg_flags |= NETLOGON_NEG_SCHANNEL;
- result = cli_nt_setup_creds(cli, sec_channel_type, trust_password,
- &neg_flags, 2);
-
- if (!NT_STATUS_IS_OK(result)) {
- ZERO_STRUCT(cli->auth_info.sess_key);
- cli->pipe_auth_flags = 0;
- return result;
+ ret = cli_nt_setup_netsec(cli, sec_channel_type, trust_password);
+ if (NT_STATUS_IS_OK(ret)) {
+ char *hex_session_key;
+ hex_encode(cli->auth_info.sess_key,
+ sizeof(cli->auth_info.sess_key),
+ &hex_session_key);
+ printf("Got Session key: %s\n", hex_session_key);
+ SAFE_FREE(hex_session_key);
}
-
- memcpy(cli->auth_info.sess_key, cli->sess_key,
- sizeof(cli->auth_info.sess_key));
-
- cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
-
- cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
- cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
- cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
-
- return NT_STATUS_OK;
+ return ret;
}
/* Built in rpcclient commands */
@@ -536,7 +519,9 @@ static NTSTATUS do_cmd(struct cli_state *cli,
}
}
- if ((cmd_entry->pipe_idx == PI_NETLOGON) && !(cli->pipe_auth_flags & AUTH_PIPE_NETSEC)) {
+ /* some of the DsXXX commands use the netlogon pipe */
+
+ if (lp_client_schannel() && (cmd_entry->pipe_idx == PI_NETLOGON) && !(cli->pipe_auth_flags & AUTH_PIPE_NETSEC)) {
uint32 neg_flags = 0x000001ff;
uint32 sec_channel_type;
@@ -740,8 +725,11 @@ out_free:
nt_status = cli_full_connection(&cli, global_myname(), server,
opt_ipaddr ? &server_ip : NULL, 0,
"IPC$", "IPC",
- cmdline_auth_info.username, lp_workgroup(),
- cmdline_auth_info.password, 0, NULL);
+ cmdline_auth_info.username,
+ lp_workgroup(),
+ cmdline_auth_info.password,
+ cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
+ cmdline_auth_info.signing_state,NULL);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status)));
diff --git a/source/sam/idmap.c b/source/sam/idmap.c
index 7a8f270e15a..4d8b768c2fa 100644
--- a/source/sam/idmap.c
+++ b/source/sam/idmap.c
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
ID Mapping
Copyright (C) Tim Potter 2000
- Copyright (C) Anthony Liguori <aliguor@us.ibm.com> 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
Copyright (C) Simo Sorce 2003
Copyright (C) Jeremy Allison 2003.
@@ -153,10 +153,11 @@ NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
struct idmap_methods *map = remote_map;
DOM_SID tmp_sid;
- DEBUG(10, ("idmap_set_mapping: Set %s to %s %d\n",
+ DEBUG(10, ("idmap_set_mapping: Set %s to %s %lu\n",
sid_string_static(sid),
((id_type & ID_TYPEMASK) == ID_USERID) ? "UID" : "GID",
- ((id_type & ID_TYPEMASK) == ID_USERID) ? id.uid : id.gid));
+ ((id_type & ID_TYPEMASK) == ID_USERID) ? (unsigned long)id.uid :
+ (unsigned long)id.gid));
if ( (NT_STATUS_IS_OK(cache_map->
get_sid_from_id(&tmp_sid, id,
diff --git a/source/sam/idmap_ldap.c b/source/sam/idmap_ldap.c
index 9a1ee039d0c..61226417186 100644
--- a/source/sam/idmap_ldap.c
+++ b/source/sam/idmap_ldap.c
@@ -4,7 +4,7 @@
idmap LDAP backend
Copyright (C) Tim Potter 2000
- Copyright (C) Anthony Liguori 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
Copyright (C) Simo Sorce 2003
Copyright (C) Gerald Carter 2003
@@ -41,12 +41,6 @@
struct ldap_idmap_state {
struct smbldap_state *smbldap_state;
TALLOC_CTX *mem_ctx;
-
- uint32 low_allocated_user_rid;
- uint32 high_allocated_user_rid;
- uint32 low_allocated_group_rid;
- uint32 high_allocated_group_rid;
-
};
#define LDAP_MAX_ALLOC_ID 128 /* number tries while allocating
@@ -203,11 +197,7 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid,
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
old_rid_string))
{
-
- *rid = (uint32)atol(old_rid_string);
-
- } else {
- *rid = state->low_allocated_user_rid;
+ *rid = (uint32)atol(old_rid_string);
}
break;
case GROUP_RID_TYPE:
@@ -216,8 +206,6 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid,
old_rid_string))
{
*rid = (uint32)atol(old_rid_string);
- } else {
- *rid = state->low_allocated_group_rid;
}
break;
}
@@ -231,10 +219,6 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid,
switch (rid_type) {
case USER_RID_TYPE:
- if (next_rid > state->high_allocated_user_rid) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* Try to make the modification atomically by enforcing the
old value in the delete mod. */
smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods,
@@ -243,10 +227,6 @@ static NTSTATUS ldap_next_rid(struct ldap_idmap_state *state, uint32 *rid,
break;
case GROUP_RID_TYPE:
- if (next_rid > state->high_allocated_group_rid) {
- return NT_STATUS_UNSUCCESSFUL;
- }
-
/* Try to make the modification atomically by enforcing the
old value in the delete mod. */
smbldap_make_mod(state->smbldap_state->ldap_struct, entry, &mods,
@@ -361,7 +341,7 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER ) :
get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
- snprintf(filter, sizeof(filter)-1, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
+ pstr_sprintf(filter, "(objectClass=%s)", LDAP_OBJ_IDPOOL);
attr_list = get_attr_list( idpool_attr_list );
@@ -400,20 +380,23 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
if (id_type & ID_USERID) {
id->uid = strtoul(id_str, NULL, 10);
if (id->uid > huid ) {
- DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %d!\n", huid));
+ DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n",
+ (unsigned long)huid));
goto out;
}
}
else {
id->gid = strtoul(id_str, NULL, 10);
if (id->gid > hgid ) {
- DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %d!\n", hgid));
+ DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n",
+ (unsigned long)hgid));
goto out;
}
}
- snprintf(new_id_str, sizeof(new_id_str), "%u",
- ((id_type & ID_USERID) ? id->uid : id->gid) + 1);
+ pstr_sprintf(new_id_str, "%lu",
+ ((id_type & ID_USERID) ? (unsigned long)id->uid :
+ (unsigned long)id->gid) + 1);
smbldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str );
smbldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str );
@@ -458,27 +441,38 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
if ( id_type & ID_USERID ) {
type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
obj_class = LDAP_OBJ_SAMBASAMACCOUNT;
- snprintf(id_str, sizeof(id_str), "%u", id.uid );
+ fstr_sprintf(id_str, "%lu", (unsigned long)id.uid );
pstrcpy( suffix, lp_ldap_suffix());
}
else {
type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
obj_class = LDAP_OBJ_GROUPMAP;
- snprintf(id_str, sizeof(id_str), "%u", id.gid );
+ fstr_sprintf(id_str, "%lu", (unsigned long)id.gid );
pstrcpy( suffix, lp_ldap_group_suffix() );
}
+
+ DEBUG(5,("ldap_get_sid_from_id: Searching \"%s\"\n", filter ));
attr_list = get_attr_list( sidmap_attr_list );
- snprintf(filter, sizeof(filter), "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
+ pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
LDAP_OBJ_IDMAP_ENTRY, obj_class, type, id_str);
rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
filter, attr_list, 0, &result);
- if (rc != LDAP_SUCCESS)
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
+ ldap_err2string(rc) ));
goto out;
-
+ }
+
count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
+
+ if (count > 1) {
+ DEBUG(0,("ldap_get_sid_from_id: mapping returned [%d] entries!\n",
+ count));
+ goto out;
+ }
/* fall back to looking up an idmap entry if we didn't find and
actual user or group */
@@ -487,24 +481,30 @@ static NTSTATUS ldap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
ldap_msgfree(result);
result = NULL;
- snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%u))",
- LDAP_OBJ_IDMAP_ENTRY, type, ((id_type & ID_USERID) ? id.uid : id.gid));
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%lu))",
+ LDAP_OBJ_IDMAP_ENTRY, type,
+ ((id_type & ID_USERID) ? (unsigned long)id.uid :
+ (unsigned long)id.gid));
pstrcpy( suffix, lp_ldap_idmap_suffix() );
rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
filter, attr_list, 0, &result);
- if (rc != LDAP_SUCCESS)
- goto out;
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(3,("ldap_get_isd_from_id: Failure looking up entry (%s)\n",
+ ldap_err2string(rc) ));
+ goto out;
+ }
count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
- }
-
- if (count != 1) {
- DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %u\n",
- type, ((id_type & ID_USERID) ? id.uid : id.gid)));
- goto out;
+
+ if (count != 1) {
+ DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n",
+ type, ((id_type & ID_USERID) ? (unsigned long)id.uid :
+ (unsigned long)id.gid)));
+ goto out;
+ }
}
entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
@@ -538,117 +538,146 @@ static NTSTATUS ldap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *si
pstring id_str;
const char *suffix;
const char *type;
- const char *obj_class;
- const char *posix_obj_class;
int rc;
int count;
char **attr_list;
char *dn = NULL;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- /* first try getting the mapping from a samba user or group */
-
sid_to_string(sid_str, sid);
- if ( *id_type & ID_USERID ) {
- type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER );
- obj_class = LDAP_OBJ_SAMBASAMACCOUNT;
- posix_obj_class = LDAP_OBJ_POSIXACCOUNT;
- suffix = lp_ldap_suffix();
- snprintf(filter, sizeof(filter),
- "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))",
- obj_class, posix_obj_class, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ),
- sid_str);
- }
- else {
+
+ DEBUG(8,("ldap_get_id_from_sid: %s (%s)\n", sid_str,
+ (*id_type & ID_GROUPID ? "group" : "user") ));
+
+ /* ahhh.... ok. We have to check users and groups in places other
+ than idmap (hint: we're a domain member of a Samba domain) */
+
+ if ( *id_type & ID_GROUPID ) {
+
type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER );
- obj_class = LDAP_OBJ_GROUPMAP;
- posix_obj_class = LDAP_OBJ_POSIXGROUP;
suffix = lp_ldap_group_suffix();
- snprintf(filter, sizeof(filter),
- "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
- obj_class, LDAP_OBJ_IDMAP_ENTRY,
+ pstr_sprintf(filter, "(&(|(objectClass=%s)(objectClass=%s))(%s=%s))",
+ LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
+ get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ),
+ sid_str);
+
+ }
+ else {
+
+ type = get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER );
+ suffix = lp_ldap_suffix();
+ pstr_sprintf(filter, "(&(|(&(objectClass=%s)(objectClass=%s))(objectClass=%s))(%s=%s))",
+ LDAP_OBJ_SAMBASAMACCOUNT, LDAP_OBJ_POSIXACCOUNT, LDAP_OBJ_IDMAP_ENTRY,
get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID ),
sid_str);
+
}
-
+
+ DEBUG(10,("ldap_get_id_from_sid: Searching for \"%s\"\n", filter));
+
+ /* do the search and check for errors */
+
attr_list = get_attr_list( sidmap_attr_list );
rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
- filter, attr_list, 0, &result);
-
- if (rc != LDAP_SUCCESS)
+ filter, attr_list, 0, &result);
+
+ if ( rc != LDAP_SUCCESS ) {
+ DEBUG(3,("ldap_get_id_from_sid: Failure looking up group mapping (%s)\n",
+ ldap_err2string(rc) ));
goto out;
+ }
count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
-
- /* fall back to looking up an idmap entry if we didn't find anything under the idmap
- user or group suffix */
- if (count == 0) {
- ldap_msgfree(result);
-
- snprintf(filter, sizeof(filter), "(&(objectClass=%s)(%s=%s))",
- LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str);
+ if ( count > 1 ) {
+ DEBUG(3,("ldap_get_id_from_sid: search \"%s\" returned [%d] entries. Bailing...\n",
+ filter, count));
+ goto out;
+ }
+
+ /* see if we need to do a search here */
+
+ if ( count == 0 ) {
+
+ if ( result ) {
+ ldap_msgfree(result);
+ result = NULL;
+ }
+
+ /* look in idmap suffix */
suffix = lp_ldap_idmap_suffix();
+ pstr_sprintf(filter, "(&(objectClass=%s)(%s=%s))",
+ LDAP_OBJ_IDMAP_ENTRY, LDAP_ATTRIBUTE_SID, sid_str);
rc = smbldap_search(ldap_state.smbldap_state, suffix, LDAP_SCOPE_SUBTREE,
filter, attr_list, 0, &result);
- if (rc != LDAP_SUCCESS)
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(3,("ldap_get_id_from_sid: Failure looking up idmap entry (%s)\n",
+ ldap_err2string(rc) ));
goto out;
+ }
+ /* check for the number of entries returned */
+
count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result);
- }
- if ( count > 1 ) {
- DEBUG(0, ("ldap_get_id_from_sid: search %s returned more than on entry!\n",
- filter));
- goto out;
- }
-
- /* we might have an existing entry to work with so pull out the requested information */
-
- if ( count ) {
- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
-
- dn = ldap_get_dn(ldap_state.smbldap_state->ldap_struct, result);
- DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn, type));
-
- if ( smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, type, id_str) )
- {
- if ( (*id_type & ID_USERID) )
- id->uid = strtoul(id_str, NULL, 10);
- else
- id->gid = strtoul(id_str, NULL, 10);
-
- ret = NT_STATUS_OK;
+ if ( count > 1 ) {
+ DEBUG(0, ("ldap_get_id_from_sid: (2nd) search %s returned [%d] entries!\n",
+ filter, count));
goto out;
}
- }
- if (!(*id_type & ID_QUERY_ONLY)) {
- /* if entry == NULL, and we are asked to - allocate a new id */
- int i;
+
+ /* try to allocate a new id if we still haven't found one */
+
+ if ( (count==0) && !(*id_type & ID_QUERY_ONLY) ) {
+ int i;
+
+ DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n"));
- for (i = 0; i < LDAP_MAX_ALLOC_ID; i++)
- {
- ret = ldap_allocate_id(id, *id_type);
- if ( NT_STATUS_IS_OK(ret) )
- break;
- }
+ for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) {
+ ret = ldap_allocate_id(id, *id_type);
+ if ( NT_STATUS_IS_OK(ret) )
+ break;
+ }
- if ( !NT_STATUS_IS_OK(ret) ) {
- DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
+ if ( !NT_STATUS_IS_OK(ret) ) {
+ DEBUG(0,("ldap_allocate_id: cannot acquire id lock!\n"));
+ goto out;
+ }
+
+ DEBUG(10,("ldap_get_id_from_sid: Allocated new %cid [%ul]\n",
+ (*id_type & ID_GROUPID ? 'g' : 'u'), (uint32)id->uid ));
+
+ ret = ldap_set_mapping(sid, *id, *id_type);
+
+ /* all done */
+
goto out;
}
-
- ret = ldap_set_mapping(sid, *id, *id_type);
- } else {
- /* no match, and not adding one */
- ret = NT_STATUS_UNSUCCESSFUL;
}
+ DEBUG(10,("ldap_get_id_from_sid: success\n"));
+
+ entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result);
+
+ dn = ldap_get_dn(ldap_state.smbldap_state->ldap_struct, result);
+
+ DEBUG(10, ("Found mapping entry at dn=%s, looking for %s\n", dn, type));
+
+ if ( smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, type, id_str) )
+ {
+ if ( (*id_type & ID_USERID) )
+ id->uid = strtoul(id_str, NULL, 10);
+ else
+ id->gid = strtoul(id_str, NULL, 10);
+
+ ret = NT_STATUS_OK;
+ goto out;
+ }
+
out:
free_attr_list( attr_list );
if (result)
@@ -670,7 +699,7 @@ static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id,
int id_type, const char *ldap_dn,
LDAPMessage *entry)
{
- char *dn = NULL;
+ pstring dn;
pstring id_str;
fstring type;
LDAPMod **mods = NULL;
@@ -685,24 +714,20 @@ static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id,
if (ldap_dn) {
DEBUG(10, ("Adding new IDMAP mapping on DN: %s", ldap_dn));
ldap_op = LDAP_MOD_REPLACE;
- dn = strdup(ldap_dn);
+ pstrcpy( dn, ldap_dn );
} else {
ldap_op = LDAP_MOD_ADD;
- asprintf(&dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID),
+ pstr_sprintf(dn, "%s=%s,%s", get_attr_key2string( sidmap_attr_list, LDAP_ATTR_SID),
sid_string, lp_ldap_idmap_suffix());
}
- if (!dn) {
- DEBUG(0, ("ldap_set_mapping_internals: out of memory allocating DN!\n"));
- return NT_STATUS_NO_MEMORY;
- }
-
if ( id_type & ID_USERID )
fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_UIDNUMBER ) );
else
fstrcpy( type, get_attr_key2string( sidmap_attr_list, LDAP_ATTR_GIDNUMBER ) );
- snprintf(id_str, sizeof(id_str), "%u", ((id_type & ID_USERID) ? id.uid : id.gid));
+ pstr_sprintf(id_str, "%lu", ((id_type & ID_USERID) ? (unsigned long)id.uid :
+ (unsigned long)id.gid));
if (entry)
values = ldap_get_values(ldap_state.smbldap_state->ldap_struct, entry, "objectClass");
@@ -754,15 +779,16 @@ static NTSTATUS ldap_set_mapping_internals(const DOM_SID *sid, unid_t id,
char *ld_error = NULL;
ldap_get_option(ldap_state.smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
- DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %u [%s]\n",
+ DEBUG(0,("ldap_set_mapping_internals: Failed to %s mapping from %s to %lu [%s]\n",
(ldap_op == LDAP_MOD_ADD) ? "add" : "replace",
- sid_string, (unsigned int)((id_type & ID_USERID) ? id.uid : id.gid), type));
+ sid_string, (unsigned long)((id_type & ID_USERID) ? id.uid : id.gid), type));
DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));
return NT_STATUS_UNSUCCESSFUL;
}
- DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %d [%s]\n",
- sid_string, ((id_type & ID_USERID) ? id.uid : id.gid), type));
+ DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to %lu [%s]\n",
+ sid_string, ((id_type & ID_USERID) ? (unsigned long)id.uid :
+ (unsigned long)id.gid), type));
return NT_STATUS_OK;
}
@@ -794,18 +820,18 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
suffix = lp_ldap_suffix();
type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_UIDNUMBER );
posix_obj_class = LDAP_OBJ_POSIXACCOUNT;
- snprintf(id_str, sizeof(id_str), "%u", id.uid );
+ fstr_sprintf(id_str, "%lu", (unsigned long)id.uid );
}
else {
obj_class = LDAP_OBJ_GROUPMAP;
suffix = lp_ldap_group_suffix();
type = get_attr_key2string( idpool_attr_list, LDAP_ATTR_GIDNUMBER );
posix_obj_class = LDAP_OBJ_POSIXGROUP;
- snprintf(id_str, sizeof(id_str), "%u", id.gid );
+ fstr_sprintf(id_str, "%lu", (unsigned long)id.gid );
}
sid_to_string(sid_str, sid);
- snprintf(filter, sizeof(filter),
+ pstr_sprintf(filter,
"(|"
"(&(|(objectClass=%s)(|(objectClass=%s)(objectClass=%s)))(%s=%s))"
"(&(objectClass=%s)(%s=%s))"
@@ -859,10 +885,13 @@ out:
return ret;
}
-/*****************************************************************************
- Initialise idmap database.
-*****************************************************************************/
-static NTSTATUS ldap_idmap_init( char *params )
+
+
+/**********************************************************************
+ Verify the sambaUnixIdPool entry in the directiry.
+**********************************************************************/
+
+static NTSTATUS verify_idpool( void )
{
fstring filter;
int rc;
@@ -870,24 +899,8 @@ static NTSTATUS ldap_idmap_init( char *params )
LDAPMessage *result = NULL;
LDAPMod **mods = NULL;
int count;
- NTSTATUS nt_status;
-
- ldap_state.mem_ctx = talloc_init("idmap_ldap");
- if (!ldap_state.mem_ctx) {
- return NT_STATUS_NO_MEMORY;
- }
-
- /* assume location is the only parameter */
- if (!NT_STATUS_IS_OK(nt_status =
- smbldap_init(ldap_state.mem_ctx, params,
- &ldap_state.smbldap_state))) {
- talloc_destroy(ldap_state.mem_ctx);
- return nt_status;
- }
-
- /* see if the idmap suffix and sub entries exists */
- snprintf( filter, sizeof(filter), "(objectclass=%s)", LDAP_OBJ_IDPOOL );
+ fstr_sprintf( filter, "(objectclass=%s)", LDAP_OBJ_IDPOOL );
attr_list = get_attr_list( idpool_attr_list );
rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(),
@@ -914,8 +927,8 @@ static NTSTATUS ldap_idmap_init( char *params )
return NT_STATUS_UNSUCCESSFUL;
}
- snprintf( uid_str, sizeof(uid_str), "%d", luid );
- snprintf( gid_str, sizeof(gid_str), "%d", lgid );
+ fstr_sprintf( uid_str, "%lu", (unsigned long)luid );
+ fstr_sprintf( gid_str, "%lu", (unsigned long)lgid );
smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDPOOL );
smbldap_set_mod( &mods, LDAP_MOD_ADD,
@@ -925,7 +938,36 @@ static NTSTATUS ldap_idmap_init( char *params )
rc = smbldap_modify(ldap_state.smbldap_state, lp_ldap_idmap_suffix(), mods);
}
+
+ return ( rc==LDAP_SUCCESS ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL );
+}
+
+/*****************************************************************************
+ Initialise idmap database.
+*****************************************************************************/
+static NTSTATUS ldap_idmap_init( char *params )
+{
+ NTSTATUS nt_status;
+
+ ldap_state.mem_ctx = talloc_init("idmap_ldap");
+ if (!ldap_state.mem_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* assume location is the only parameter */
+ if (!NT_STATUS_IS_OK(nt_status =
+ smbldap_init(ldap_state.mem_ctx, params,
+ &ldap_state.smbldap_state))) {
+ talloc_destroy(ldap_state.mem_ctx);
+ return nt_status;
+ }
+
+ /* see if the idmap suffix and sub entries exists */
+ nt_status = verify_idpool();
+ if ( !NT_STATUS_IS_OK(nt_status) )
+ return nt_status;
+
return NT_STATUS_OK;
}
diff --git a/source/sam/idmap_tdb.c b/source/sam/idmap_tdb.c
index 7f8dce1f1a1..8ab8ec84770 100644
--- a/source/sam/idmap_tdb.c
+++ b/source/sam/idmap_tdb.c
@@ -4,7 +4,7 @@
idmap TDB backend
Copyright (C) Tim Potter 2000
- Copyright (C) Anthony Liguori 2003
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
Copyright (C) Simo Sorce 2003
This program is free software; you can redistribute it and/or modify
@@ -46,20 +46,6 @@ static struct idmap_state {
} idmap_state;
/**********************************************************************
- Return the TDB_CONTEXT* for winbindd_idmap. I **really** feel
- dirty doing this, but not so dirty that I want to create another
- tdb
-***********************************************************************/
-
-TDB_CONTEXT *idmap_tdb_handle( void )
-{
- if ( idmap_tdb )
- return idmap_tdb;
-
- return NULL;
-}
-
-/**********************************************************************
allocate a new RID; We don't care if is a user or group
**********************************************************************/
@@ -75,7 +61,7 @@ static NTSTATUS db_allocate_rid(uint32 *rid, int rid_type)
/* cannot fail since idmap is only called winbindd */
- idmap_get_free_rid_range( &lowrid, &highrid );
+ get_free_rid_range( &lowrid, &highrid );
tmp_rid = lowrid;
@@ -116,12 +102,13 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type)
/* check it is in the range */
if (hwm > idmap_state.uid_high) {
- DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %u)\n", idmap_state.uid_high));
+ DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n",
+ (unsigned long)idmap_state.uid_high));
return NT_STATUS_UNSUCCESSFUL;
}
/* fetch a new id and increment it */
- ret = tdb_change_uint32_atomic(idmap_tdb, HWM_USER, &hwm, 1);
+ ret = tdb_change_uint32_atomic(idmap_tdb, HWM_USER, (unsigned int *)&hwm, 1);
if (!ret) {
DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!"));
return NT_STATUS_UNSUCCESSFUL;
@@ -129,7 +116,8 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type)
/* recheck it is in the range */
if (hwm > idmap_state.uid_high) {
- DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %u)\n", idmap_state.uid_high));
+ DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n",
+ (unsigned long)idmap_state.uid_high));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -144,12 +132,13 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type)
/* check it is in the range */
if (hwm > idmap_state.gid_high) {
- DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %u)\n", idmap_state.gid_high));
+ DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n",
+ (unsigned long)idmap_state.gid_high));
return NT_STATUS_UNSUCCESSFUL;
}
/* fetch a new id and increment it */
- ret = tdb_change_uint32_atomic(idmap_tdb, HWM_GROUP, &hwm, 1);
+ ret = tdb_change_uint32_atomic(idmap_tdb, HWM_GROUP, (unsigned int *)&hwm, 1);
if (!ret) {
DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!"));
@@ -158,7 +147,8 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type)
/* recheck it is in the range */
if (hwm > idmap_state.gid_high) {
- DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %u)\n", idmap_state.gid_high));
+ DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n",
+ (unsigned long)idmap_state.gid_high));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -185,10 +175,10 @@ static NTSTATUS internal_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
switch (id_type & ID_TYPEMASK) {
case ID_USERID:
- slprintf(keystr, sizeof(keystr), "UID %d", id.uid);
+ slprintf(keystr, sizeof(keystr), "UID %lu", (unsigned long)id.uid);
break;
case ID_GROUPID:
- slprintf(keystr, sizeof(keystr), "GID %d", id.gid);
+ slprintf(keystr, sizeof(keystr), "GID %lu", (unsigned long)id.gid);
break;
default:
return NT_STATUS_UNSUCCESSFUL;
@@ -374,9 +364,11 @@ static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
/* Store the UID side */
/* Store new id */
if (*id_type & ID_USERID) {
- slprintf(ugid_str, sizeof(ugid_str), "UID %d", (*id).uid);
+ slprintf(ugid_str, sizeof(ugid_str), "UID %lu",
+ (unsigned long)((*id).uid));
} else {
- slprintf(ugid_str, sizeof(ugid_str), "GID %d", (*id).gid);
+ slprintf(ugid_str, sizeof(ugid_str), "GID %lu",
+ (unsigned long)((*id).gid));
}
ugid_data.dptr = ugid_str;
@@ -430,9 +422,9 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
ksid.dsize = strlen(ksidstr) + 1;
if (id_type & ID_USERID) {
- slprintf(kidstr, sizeof(kidstr), "UID %d", id.uid);
+ slprintf(kidstr, sizeof(kidstr), "UID %lu", (unsigned long)id.uid);
} else if (id_type & ID_GROUPID) {
- slprintf(kidstr, sizeof(kidstr), "GID %d", id.gid);
+ slprintf(kidstr, sizeof(kidstr), "GID %lu", (unsigned long)id.gid);
} else {
return NT_STATUS_INVALID_PARAMETER;
}
@@ -644,6 +636,27 @@ static void db_idmap_status(void)
/* Display complete mapping of users and groups to rids */
}
+/**********************************************************************
+ Return the TDB_CONTEXT* for winbindd_idmap. I **really** feel
+ dirty doing this, but not so dirty that I want to create another
+ tdb
+***********************************************************************/
+
+TDB_CONTEXT *idmap_tdb_handle( void )
+{
+ if ( idmap_tdb )
+ return idmap_tdb;
+
+ /* go ahead an open it; db_idmap_init() doesn't use any params
+ right now */
+
+ db_idmap_init( NULL );
+ if ( idmap_tdb )
+ return idmap_tdb;
+
+ return NULL;
+}
+
static struct idmap_methods db_methods = {
db_idmap_init,
diff --git a/source/sam/idmap_util.c b/source/sam/idmap_util.c
index f767cc898c7..f28e11cde74 100644
--- a/source/sam/idmap_util.c
+++ b/source/sam/idmap_util.c
@@ -22,50 +22,7 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_IDMAP
-/**********************************************************************
-**********************************************************************/
-
-BOOL idmap_get_free_ugid_range(uint32 *low, uint32 *high)
-{
- uid_t u_low, u_high;
- gid_t g_low, g_high;
-
- if (!lp_idmap_uid(&u_low, &u_high) || !lp_idmap_gid(&g_low, &g_high)) {
- return False;
- }
-
- *low = (u_low < g_low) ? u_low : g_low;
- *high = (u_high < g_high) ? u_high : g_high;
-
- return True;
-}
-
-/******************************************************************
- Get the the non-algorithmic RID range if idmap range are defined
-******************************************************************/
-
-BOOL idmap_get_free_rid_range(uint32 *low, uint32 *high)
-{
- uint32 id_low, id_high;
-
- if (!lp_enable_rid_algorithm()) {
- *low = BASE_RID;
- *high = (uint32)-1;
- }
-
- if (!idmap_get_free_ugid_range(&id_low, &id_high)) {
- return False;
- }
-
- *low = fallback_pdb_uid_to_user_rid(id_low);
- if (fallback_pdb_user_rid_to_uid((uint32)-1) < id_high) {
- *high = (uint32)-1;
- } else {
- *high = fallback_pdb_uid_to_user_rid(id_high);
- }
-
- return True;
-}
+#if 0 /* NOT USED */
/**********************************************************************
Get the free RID base if idmap is configured, otherwise return 0
@@ -137,6 +94,8 @@ BOOL idmap_check_sid_is_in_free_range(const DOM_SID *sid)
return True;
}
+#endif /* NOT USED */
+
/*****************************************************************
Returns SID pointer.
*****************************************************************/
@@ -146,7 +105,7 @@ NTSTATUS idmap_uid_to_sid(DOM_SID *sid, uid_t uid)
unid_t id;
int flags;
- DEBUG(10,("idmap_uid_to_sid: uid = [%d]\n", uid));
+ DEBUG(10,("idmap_uid_to_sid: uid = [%lu]\n", (unsigned long)uid));
flags = ID_USERID;
id.uid = uid;
@@ -164,7 +123,7 @@ NTSTATUS idmap_gid_to_sid(DOM_SID *sid, gid_t gid)
unid_t id;
int flags;
- DEBUG(10,("idmap_gid_to_sid: gid = [%d]\n", gid));
+ DEBUG(10,("idmap_gid_to_sid: gid = [%lu]\n", (unsigned long)gid));
flags = ID_GROUPID;
#if 0 /* JERRY */
@@ -192,10 +151,10 @@ NTSTATUS idmap_sid_to_uid(const DOM_SID *sid, uid_t *uid, uint32 flags)
flags |= ID_USERID;
- ret = idmap_get_id_from_sid(&id, &flags, sid);
+ ret = idmap_get_id_from_sid(&id, (int *)&flags, sid);
if ( NT_STATUS_IS_OK(ret) ) {
- DEBUG(10,("idmap_sid_to_uid: uid = [%d]\n", id.uid));
+ DEBUG(10,("idmap_sid_to_uid: uid = [%lu]\n", (unsigned long)id.uid));
*uid = id.uid;
}
@@ -221,11 +180,11 @@ NTSTATUS idmap_sid_to_gid(const DOM_SID *sid, gid_t *gid, uint32 flags)
flags |= ID_GROUPID;
- ret = idmap_get_id_from_sid(&id, &flags, sid);
+ ret = idmap_get_id_from_sid(&id, (int *)&flags, sid);
if ( NT_STATUS_IS_OK(ret) )
{
- DEBUG(10,("idmap_sid_to_gid: gid = [%d]\n", id.gid));
+ DEBUG(10,("idmap_sid_to_gid: gid = [%lu]\n", (unsigned long)id.gid));
*gid = id.gid;
}
diff --git a/source/script/installmodules.sh b/source/script/installmodules.sh
index ec5691992dd..c80da763688 100755
--- a/source/script/installmodules.sh
+++ b/source/script/installmodules.sh
@@ -24,13 +24,4 @@ for p in $*; do
chmod $INSTALLPERMS $LIBDIR/$p2
done
-
-cat << EOF
-======================================================================
-The modules are installed. You may uninstall the modules using the
-command "make uninstallmodules" or "make uninstall" to uninstall
-binaries, man pages, shell scripts and modules.
-======================================================================
-EOF
-
exit 0
diff --git a/source/script/linkmodules.sh b/source/script/linkmodules.sh
new file mode 100755
index 00000000000..16a04cc064b
--- /dev/null
+++ b/source/script/linkmodules.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+cd "$1"
+test -f "$2" || exit 0
+
+for I in $3 $4 $5 $6 $7 $8
+do
+ echo "Linking $I to $2"
+ ln -s $2 $I
+done
+
+exit 0
diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c
index 2802fbb1512..8fa2a6494e3 100644
--- a/source/smbd/blocking.c
+++ b/source/smbd/blocking.c
@@ -28,16 +28,16 @@ extern char *OutBuffer;
*****************************************************************************/
typedef struct {
- ubi_slNode msg_next;
- int com_type;
- files_struct *fsp;
- time_t expire_time;
- int lock_num;
- SMB_BIG_UINT offset;
- SMB_BIG_UINT count;
- uint16 lock_pid;
- char *inbuf;
- int length;
+ ubi_slNode msg_next;
+ int com_type;
+ files_struct *fsp;
+ time_t expire_time;
+ int lock_num;
+ SMB_BIG_UINT offset;
+ SMB_BIG_UINT count;
+ uint16 lock_pid;
+ char *inbuf;
+ int length;
} blocking_lock_record;
static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_queue, 0};
@@ -48,8 +48,8 @@ static ubi_slList blocking_lock_queue = { NULL, (ubi_slNodePtr)&blocking_lock_qu
static void free_blocking_lock_record(blocking_lock_record *blr)
{
- SAFE_FREE(blr->inbuf);
- SAFE_FREE(blr);
+ SAFE_FREE(blr->inbuf);
+ SAFE_FREE(blr);
}
/****************************************************************************
@@ -58,17 +58,17 @@ static void free_blocking_lock_record(blocking_lock_record *blr)
static files_struct *get_fsp_from_pkt(char *inbuf)
{
- switch(CVAL(inbuf,smb_com)) {
- case SMBlock:
- case SMBlockread:
- return file_fsp(inbuf,smb_vwv0);
- case SMBlockingX:
- return file_fsp(inbuf,smb_vwv2);
- default:
- DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n"));
- exit_server("PANIC - unknown type on blocking lock queue");
- }
- return NULL; /* Keep compiler happy. */
+ switch(CVAL(inbuf,smb_com)) {
+ case SMBlock:
+ case SMBlockread:
+ return file_fsp(inbuf,smb_vwv0);
+ case SMBlockingX:
+ return file_fsp(inbuf,smb_vwv2);
+ default:
+ DEBUG(0,("get_fsp_from_pkt: PANIC - unknown type on blocking lock queue - exiting.!\n"));
+ exit_server("PANIC - unknown type on blocking lock queue");
+ }
+ return NULL; /* Keep compiler happy. */
}
/****************************************************************************
@@ -77,7 +77,7 @@ static files_struct *get_fsp_from_pkt(char *inbuf)
static BOOL in_chained_smb(void)
{
- return (chain_size != 0);
+ return (chain_size != 0);
}
static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len);
@@ -89,66 +89,68 @@ static void received_unlock_msg(int msg_type, pid_t src, void *buf, size_t len);
BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout,
int lock_num, uint16 lock_pid, SMB_BIG_UINT offset, SMB_BIG_UINT count)
{
- static BOOL set_lock_msg;
- blocking_lock_record *blr;
- NTSTATUS status;
-
- if(in_chained_smb() ) {
- DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
- return False;
- }
-
- /*
- * Now queue an entry on the blocking lock queue. We setup
- * the expiration time here.
- */
-
- if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) {
- DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
- return False;
- }
-
- if((blr->inbuf = (char *)malloc(length)) == NULL) {
- DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" ));
- SAFE_FREE(blr);
- return False;
- }
-
- blr->com_type = CVAL(inbuf,smb_com);
- blr->fsp = get_fsp_from_pkt(inbuf);
- blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout;
- blr->lock_num = lock_num;
- blr->lock_pid = lock_pid;
- blr->offset = offset;
- blr->count = count;
- memcpy(blr->inbuf, inbuf, length);
- blr->length = length;
-
- /* Add a pending lock record for this. */
- status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
- lock_pid, sys_getpid(), blr->fsp->conn->cnum,
- offset, count,
- PENDING_LOCK);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
- free_blocking_lock_record(blr);
- return False;
- }
+ static BOOL set_lock_msg;
+ blocking_lock_record *blr;
+ NTSTATUS status;
+
+ if(in_chained_smb() ) {
+ DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
+ return False;
+ }
+
+ /*
+ * Now queue an entry on the blocking lock queue. We setup
+ * the expiration time here.
+ */
- ubi_slAddTail(&blocking_lock_queue, blr);
+ if((blr = (blocking_lock_record *)malloc(sizeof(blocking_lock_record))) == NULL) {
+ DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
+ return False;
+ }
+
+ if((blr->inbuf = (char *)malloc(length)) == NULL) {
+ DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" ));
+ SAFE_FREE(blr);
+ return False;
+ }
- /* Ensure we'll receive messages when this is unlocked. */
- if (!set_lock_msg) {
- message_register(MSG_SMB_UNLOCK, received_unlock_msg);
- set_lock_msg = True;
- }
+ blr->com_type = CVAL(inbuf,smb_com);
+ blr->fsp = get_fsp_from_pkt(inbuf);
+ blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout;
+ blr->lock_num = lock_num;
+ blr->lock_pid = lock_pid;
+ blr->offset = offset;
+ blr->count = count;
+ memcpy(blr->inbuf, inbuf, length);
+ blr->length = length;
+
+ /* Add a pending lock record for this. */
+ status = brl_lock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
+ lock_pid, sys_getpid(), blr->fsp->conn->cnum,
+ offset, count, PENDING_LOCK);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
+ free_blocking_lock_record(blr);
+ return False;
+ }
+
+ ubi_slAddTail(&blocking_lock_queue, blr);
+
+ /* Ensure we'll receive messages when this is unlocked. */
+ if (!set_lock_msg) {
+ message_register(MSG_SMB_UNLOCK, received_unlock_msg);
+ set_lock_msg = True;
+ }
- DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \
+ DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \
for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout,
- blr->fsp->fnum, blr->fsp->fsp_name ));
+ blr->fsp->fnum, blr->fsp->fsp_name ));
- return True;
+ /* Push the MID of this packet on the signing queue. */
+ srv_defer_sign_response(SVAL(inbuf,smb_mid), True);
+
+ return True;
}
/****************************************************************************
@@ -170,27 +172,27 @@ static void send_blocking_reply(char *outbuf, int outsize)
static void reply_lockingX_success(blocking_lock_record *blr)
{
- char *outbuf = OutBuffer;
- int bufsize = BUFFER_SIZE;
- char *inbuf = blr->inbuf;
- int outsize = 0;
+ char *outbuf = OutBuffer;
+ int bufsize = BUFFER_SIZE;
+ char *inbuf = blr->inbuf;
+ int outsize = 0;
- construct_reply_common(inbuf, outbuf);
- set_message(outbuf,2,0,True);
+ construct_reply_common(inbuf, outbuf);
+ set_message(outbuf,2,0,True);
- /*
- * As this message is a lockingX call we must handle
- * any following chained message correctly.
- * This is normally handled in construct_reply(),
- * but as that calls switch_message, we can't use
- * that here and must set up the chain info manually.
- */
+ /*
+ * As this message is a lockingX call we must handle
+ * any following chained message correctly.
+ * This is normally handled in construct_reply(),
+ * but as that calls switch_message, we can't use
+ * that here and must set up the chain info manually.
+ */
- outsize = chain_reply(inbuf,outbuf,blr->length,bufsize);
+ outsize = chain_reply(inbuf,outbuf,blr->length,bufsize);
- outsize += chain_size;
+ outsize += chain_size;
- send_blocking_reply(outbuf,outsize);
+ send_blocking_reply(outbuf,outsize);
}
/****************************************************************************
@@ -492,18 +494,18 @@ Waiting....\n",
static BOOL blocking_lock_record_process(blocking_lock_record *blr)
{
- switch(blr->com_type) {
- case SMBlock:
- return process_lock(blr);
- case SMBlockread:
- return process_lockread(blr);
- case SMBlockingX:
- return process_lockingX(blr);
- default:
- DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n"));
- exit_server("PANIC - unknown type on blocking lock queue");
- }
- return False; /* Keep compiler happy. */
+ switch(blr->com_type) {
+ case SMBlock:
+ return process_lock(blr);
+ case SMBlockread:
+ return process_lockread(blr);
+ case SMBlockingX:
+ return process_lockingX(blr);
+ default:
+ DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n"));
+ exit_server("PANIC - unknown type on blocking lock queue");
+ }
+ return False; /* Keep compiler happy. */
}
/****************************************************************************
@@ -512,27 +514,27 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr)
void remove_pending_lock_requests_by_fid(files_struct *fsp)
{
- blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
- blocking_lock_record *prev = NULL;
+ blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
+ blocking_lock_record *prev = NULL;
- while(blr != NULL) {
- if(blr->fsp->fnum == fsp->fnum) {
+ while(blr != NULL) {
+ if(blr->fsp->fnum == fsp->fnum) {
- DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \
+ DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \
file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
- brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
- blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
+ brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
+ blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- continue;
- }
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ continue;
+ }
- prev = blr;
- blr = (blocking_lock_record *)ubi_slNext(blr);
- }
+ prev = blr;
+ blr = (blocking_lock_record *)ubi_slNext(blr);
+ }
}
/****************************************************************************
@@ -541,28 +543,28 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
void remove_pending_lock_requests_by_mid(int mid)
{
- blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
- blocking_lock_record *prev = NULL;
+ blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
+ blocking_lock_record *prev = NULL;
- while(blr != NULL) {
- if(SVAL(blr->inbuf,smb_mid) == mid) {
- files_struct *fsp = blr->fsp;
+ while(blr != NULL) {
+ if(SVAL(blr->inbuf,smb_mid) == mid) {
+ files_struct *fsp = blr->fsp;
- DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \
+ DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \
file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
- blocking_lock_reply_error(blr,NT_STATUS_CANCELLED);
- brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
- blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- continue;
- }
-
- prev = blr;
- blr = (blocking_lock_record *)ubi_slNext(blr);
- }
+ blocking_lock_reply_error(blr,NT_STATUS_CANCELLED);
+ brl_unlock(blr->fsp->dev, blr->fsp->inode, blr->fsp->fnum,
+ blr->lock_pid, sys_getpid(), blr->fsp->conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ continue;
+ }
+
+ prev = blr;
+ blr = (blocking_lock_record *)ubi_slNext(blr);
+ }
}
/****************************************************************************
@@ -611,112 +613,112 @@ unsigned blocking_locks_timeout(unsigned default_timeout)
void process_blocking_lock_queue(time_t t)
{
- blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
- blocking_lock_record *prev = NULL;
-
- if(blr == NULL)
- return;
-
- /*
- * Go through the queue and see if we can get any of the locks.
- */
-
- while(blr != NULL) {
- connection_struct *conn = NULL;
- uint16 vuid;
- files_struct *fsp = NULL;
-
- /*
- * Ensure we don't have any old chain_fsp values
- * sitting around....
- */
- chain_size = 0;
- file_chain_reset();
- fsp = blr->fsp;
-
- conn = conn_find(SVAL(blr->inbuf,smb_tid));
- vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
- SVAL(blr->inbuf,smb_uid);
-
- DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
- fsp->fnum, fsp->fsp_name ));
-
- if((blr->expire_time != -1) && (blr->expire_time <= t)) {
- /*
- * Lock expired - throw away all previously
- * obtained locks and return lock error.
- */
- DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
- fsp->fnum, fsp->fsp_name ));
-
- brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
-
- blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- continue;
- }
-
- if(!change_to_user(conn,vuid)) {
- DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
- vuid ));
- /*
- * Remove the entry and return an error to the client.
- */
- blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
-
- brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
-
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- continue;
- }
-
- if(!set_current_service(conn,True)) {
- DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
- /*
- * Remove the entry and return an error to the client.
- */
- blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
-
- brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
-
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- change_to_root_user();
- continue;
- }
-
- /*
- * Go through the remaining locks and try and obtain them.
- * The call returns True if all locks were obtained successfully
- * and False if we still need to wait.
- */
-
- if(blocking_lock_record_process(blr)) {
-
- brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- blr->lock_pid, sys_getpid(), conn->cnum,
- blr->offset, blr->count, True, NULL, NULL);
-
- free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
- blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
- change_to_root_user();
- continue;
- }
-
- change_to_root_user();
-
- /*
- * Move to the next in the list.
- */
- prev = blr;
- blr = (blocking_lock_record *)ubi_slNext(blr);
- }
+ blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
+ blocking_lock_record *prev = NULL;
+
+ if(blr == NULL)
+ return;
+
+ /*
+ * Go through the queue and see if we can get any of the locks.
+ */
+
+ while(blr != NULL) {
+ connection_struct *conn = NULL;
+ uint16 vuid;
+ files_struct *fsp = NULL;
+
+ /*
+ * Ensure we don't have any old chain_fsp values
+ * sitting around....
+ */
+ chain_size = 0;
+ file_chain_reset();
+ fsp = blr->fsp;
+
+ conn = conn_find(SVAL(blr->inbuf,smb_tid));
+ vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
+ SVAL(blr->inbuf,smb_uid);
+
+ DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
+ fsp->fnum, fsp->fsp_name ));
+
+ if((blr->expire_time != -1) && (blr->expire_time <= t)) {
+ /*
+ * Lock expired - throw away all previously
+ * obtained locks and return lock error.
+ */
+ DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
+ fsp->fnum, fsp->fsp_name ));
+
+ brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
+ blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+
+ blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ continue;
+ }
+
+ if(!change_to_user(conn,vuid)) {
+ DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
+ vuid ));
+ /*
+ * Remove the entry and return an error to the client.
+ */
+ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
+
+ brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
+ blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ continue;
+ }
+
+ if(!set_current_service(conn,True)) {
+ DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
+ /*
+ * Remove the entry and return an error to the client.
+ */
+ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
+
+ brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
+ blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ change_to_root_user();
+ continue;
+ }
+
+ /*
+ * Go through the remaining locks and try and obtain them.
+ * The call returns True if all locks were obtained successfully
+ * and False if we still need to wait.
+ */
+
+ if(blocking_lock_record_process(blr)) {
+
+ brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
+ blr->lock_pid, sys_getpid(), conn->cnum,
+ blr->offset, blr->count, True, NULL, NULL);
+
+ free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
+ blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
+ change_to_root_user();
+ continue;
+ }
+
+ change_to_root_user();
+
+ /*
+ * Move to the next in the list.
+ */
+ prev = blr;
+ blr = (blocking_lock_record *)ubi_slNext(blr);
+ }
}
diff --git a/source/smbd/change_trust_pw.c b/source/smbd/change_trust_pw.c
index 4993e285cac..2eff77b1f70 100644
--- a/source/smbd/change_trust_pw.c
+++ b/source/smbd/change_trust_pw.c
@@ -58,7 +58,7 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m
NULL, 0,
"IPC$", "IPC",
"", "",
- "", 0, NULL)))
+ "", 0, Undefined, NULL)))
{
DEBUG(0,("modify_trust_password: Connection to %s failed!\n", remote_machine));
nt_status = NT_STATUS_UNSUCCESSFUL;
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 5c1d9a79a6e..3ed94ef740e 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -674,6 +674,8 @@ BOOL check_lanman_password(char *user, uchar * pass1,
Code to change the lanman hashed password.
It nulls out the NT hashed password as it will
no longer be valid.
+ NOTE this function is designed to be called as root. Check the old password
+ is correct before calling. JRA.
************************************************************/
BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2)
@@ -730,9 +732,7 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2)
}
/* Now flush the sam_passwd struct to persistent storage */
- become_root();
ret = pdb_update_sam_account (sampass);
- unbecome_root();
return ret;
}
@@ -740,32 +740,23 @@ BOOL change_lanman_password(SAM_ACCOUNT *sampass, uchar *pass2)
/***********************************************************
Code to check and change the OEM hashed password.
************************************************************/
+
NTSTATUS pass_oem_change(char *user,
uchar * lmdata, uchar * lmhash,
uchar * ntdata, uchar * nthash)
{
fstring new_passwd;
- const char *unix_user;
SAM_ACCOUNT *sampass = NULL;
- NTSTATUS nt_status
- = check_oem_password(user, lmdata, lmhash, ntdata, nthash,
+ NTSTATUS nt_status = check_oem_password(user, lmdata, lmhash, ntdata, nthash,
&sampass, new_passwd, sizeof(new_passwd));
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
- /*
- * At this point we have the new case-sensitive plaintext
- * password in the fstring new_passwd. If we wanted to synchronise
- * with UNIX passwords we would call a UNIX password changing
- * function here. However it would have to be done as root
- * as the plaintext of the old users password is not
- * available. JRA.
- */
-
- unix_user = pdb_get_username(sampass);
-
+ /* We've already checked the old password here.... */
+ become_root();
nt_status = change_oem_password(sampass, NULL, new_passwd);
+ unbecome_root();
memset(new_passwd, 0, sizeof(new_passwd));
@@ -942,6 +933,8 @@ static NTSTATUS check_oem_password(const char *user,
/***********************************************************
Code to change the oem password. Changes both the lanman
and NT hashes. Old_passwd is almost always NULL.
+ NOTE this function is designed to be called as root. Check the old password
+ is correct before calling. JRA.
************************************************************/
NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd)
@@ -997,9 +990,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
}
/* Now write it into the file. */
- become_root();
ret = pdb_update_sam_account (hnd);
- unbecome_root();
if (!ret) {
return NT_STATUS_ACCESS_DENIED;
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 1be13270bab..0700aeaa0a6 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -163,8 +163,8 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
share_entry_count = del_share_mode(fsp, &share_entry);
- DEBUG(10,("close_normal_file: share_entry_count = %d for file %s\n",
- share_entry_count, fsp->fsp_name ));
+ DEBUG(10,("close_normal_file: share_entry_count = %lu for file %s\n",
+ (unsigned long)share_entry_count, fsp->fsp_name ));
/*
* We delete on close if it's the last open, and the
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index 6be5f6af7d0..6cf70148463 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -87,8 +87,11 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
* Serve from write cache if we can.
*/
- if(read_from_write_cache(fsp, data, pos, n))
+ if(read_from_write_cache(fsp, data, pos, n)) {
+ fsp->pos = pos + n;
+ fsp->position_information = fsp->pos;
return n;
+ }
flush_write_cache(fsp, READ_FLUSH);
@@ -123,6 +126,9 @@ tryagain:
DEBUG(10,("read_file (%s): pos = %.0f, size = %lu, returned %lu\n",
fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
+ fsp->pos += ret;
+ fsp->position_information = fsp->pos;
+
return(ret);
}
@@ -145,6 +151,16 @@ static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_
DEBUG(10,("real_write_file (%s): pos = %.0f, size = %lu, returned %ld\n",
fsp->fsp_name, (double)pos, (unsigned long)n, (long)ret ));
+ if (ret != -1) {
+ fsp->pos += ret;
+
+/* Yes - this is correct - writes don't update this. JRA. */
+/* Found by Samba4 tests. */
+#if 0
+ fsp->position_information = fsp->pos;
+#endif
+ }
+
return ret;
}
@@ -244,7 +260,7 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
if(!wcp) {
DO_PROFILE_INC(writecache_direct_writes);
total_written = real_write_file(fsp, data, pos, n);
- if ((total_written != -1) && (pos + total_written > (SMB_OFF_T)fsp->size))
+ if ((total_written != -1) && (pos + total_written > (SMB_OFF_T)fsp->size))
fsp->size = (SMB_BIG_UINT)(pos + total_written);
return total_written;
}
@@ -252,6 +268,8 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
DEBUG(9,("write_file (%s)(fd=%d pos=%.0f size=%u) wcp->offset=%.0f wcp->data_size=%u\n",
fsp->fsp_name, fsp->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size));
+ fsp->pos = pos + n;
+
/*
* If we have active cache and it isn't contiguous then we flush.
* NOTE: There is a small problem with running out of disk ....
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index 85e28f5d172..39072f9b912 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -428,6 +428,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
+ srv_signing_trans_start(SVAL(inbuf,smb_mid));
+
if (pscnt < tpscnt || dscnt < tdscnt) {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
@@ -455,6 +457,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
SAFE_FREE(data);
SAFE_FREE(setup);
END_PROFILE(SMBtrans);
+ srv_signing_trans_stop();
return(ERROR_DOS(ERRSRV,ERRerror));
}
@@ -506,11 +509,10 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);
}
}
-
-
+
DEBUG(3,("trans <%s> data=%u params=%u setup=%u\n",
name,tdscnt,tpscnt,suwcnt));
-
+
/*
* WinCE wierdness....
*/
@@ -542,6 +544,8 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
SAFE_FREE(params);
SAFE_FREE(setup);
+ srv_signing_trans_stop();
+
if (close_on_completion)
close_cnum(conn,vuid);
@@ -561,6 +565,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
bad_param:
+ srv_signing_trans_stop();
DEBUG(0,("reply_trans: invalid trans parameters\n"));
SAFE_FREE(data);
SAFE_FREE(params);
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index 04d6a9a8a8e..7fcf25d7c96 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -1897,76 +1897,78 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
char **rdata,char **rparam,
int *rdata_len,int *rparam_len)
{
- char *p = skip_string(param+2,2);
- fstring user;
- fstring pass1,pass2;
+ char *p = skip_string(param+2,2);
+ fstring user;
+ fstring pass1,pass2;
- pull_ascii_fstring(user,p);
+ pull_ascii_fstring(user,p);
- p = skip_string(p,1);
+ p = skip_string(p,1);
- memset(pass1,'\0',sizeof(pass1));
- memset(pass2,'\0',sizeof(pass2));
- memcpy(pass1,p,16);
- memcpy(pass2,p+16,16);
+ memset(pass1,'\0',sizeof(pass1));
+ memset(pass2,'\0',sizeof(pass2));
+ memcpy(pass1,p,16);
+ memcpy(pass2,p+16,16);
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
- *rdata_len = 0;
+ *rdata_len = 0;
- SSVAL(*rparam,0,NERR_badpass);
- SSVAL(*rparam,2,0); /* converter word */
+ SSVAL(*rparam,0,NERR_badpass);
+ SSVAL(*rparam,2,0); /* converter word */
- DEBUG(3,("Set password for <%s>\n",user));
+ DEBUG(3,("Set password for <%s>\n",user));
- /*
- * Attempt to verify the old password against smbpasswd entries
- * Win98 clients send old and new password in plaintext for this call.
- */
+ /*
+ * Attempt to verify the old password against smbpasswd entries
+ * Win98 clients send old and new password in plaintext for this call.
+ */
- {
- auth_serversupplied_info *server_info = NULL;
- DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
- if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
-
- if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2)))
- {
- SSVAL(*rparam,0,NERR_Success);
- }
-
- free_server_info(&server_info);
- }
- data_blob_clear_free(&password);
- }
+ {
+ auth_serversupplied_info *server_info = NULL;
+ DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
- /*
- * If the plaintext change failed, attempt
- * the old encrypted method. NT will generate this
- * after trying the samr method. Note that this
- * method is done as a last resort as this
- * password change method loses the NT password hash
- * and cannot change the UNIX password as no plaintext
- * is received.
- */
+ if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
- if(SVAL(*rparam,0) != NERR_Success)
- {
- SAM_ACCOUNT *hnd = NULL;
+ become_root();
+ if (NT_STATUS_IS_OK(change_oem_password(server_info->sam_account, pass1, pass2))) {
+ SSVAL(*rparam,0,NERR_Success);
+ }
+ unbecome_root();
- if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd) &&
- change_lanman_password(hnd,pass2))
- {
- SSVAL(*rparam,0,NERR_Success);
- }
- pdb_free_sam(&hnd);
- }
+ free_server_info(&server_info);
+ }
+ data_blob_clear_free(&password);
+ }
+ /*
+ * If the plaintext change failed, attempt
+ * the old encrypted method. NT will generate this
+ * after trying the samr method. Note that this
+ * method is done as a last resort as this
+ * password change method loses the NT password hash
+ * and cannot change the UNIX password as no plaintext
+ * is received.
+ */
+
+ if(SVAL(*rparam,0) != NERR_Success) {
+ SAM_ACCOUNT *hnd = NULL;
- memset((char *)pass1,'\0',sizeof(fstring));
- memset((char *)pass2,'\0',sizeof(fstring));
+ if (check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &hnd)) {
+ become_root();
+ if (change_lanman_password(hnd,(uchar *)pass2)) {
+ SSVAL(*rparam,0,NERR_Success);
+ }
+ unbecome_root();
+ pdb_free_sam(&hnd);
+ }
+ }
+
+ memset((char *)pass1,'\0',sizeof(fstring));
+ memset((char *)pass2,'\0',sizeof(fstring));
- return(True);
+ return(True);
}
/****************************************************************************
diff --git a/source/smbd/mangle_hash.c b/source/smbd/mangle_hash.c
index ac8e425fd39..ac2d7681e8e 100644
--- a/source/smbd/mangle_hash.c
+++ b/source/smbd/mangle_hash.c
@@ -313,6 +313,7 @@ static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards)
const char *f;
smb_ucs2_t *ucs2name;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ size_t size;
if (!fname || !*fname)
return False;
@@ -324,9 +325,9 @@ static BOOL is_8_3(const char *fname, BOOL check_case, BOOL allow_wildcards)
if (strlen(f) > 12)
return False;
- ucs2name = acnv_uxu2(f);
- if (!ucs2name) {
- DEBUG(0,("is_8_3: internal error acnv_uxu2() failed!\n"));
+ size = push_ucs2_allocate(&ucs2name, f);
+ if (size == (size_t)-1) {
+ DEBUG(0,("is_8_3: internal error push_ucs2_allocate() failed!\n"));
goto done;
}
diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c
index f452dd845b6..28e3cf97d1f 100644
--- a/source/smbd/negprot.c
+++ b/source/smbd/negprot.c
@@ -277,6 +277,22 @@ static int reply_nt1(char *inbuf, char *outbuf)
if (global_encrypted_passwords_negotiated)
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
+ if (lp_server_signing()) {
+ if (lp_security() >= SEC_USER) {
+ secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
+ /* No raw mode with smb signing. */
+ capabilities &= ~CAP_RAW_MODE;
+ if (lp_server_signing() == Required)
+ secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
+ srv_set_signing_negotiated();
+ } else {
+ DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
+ if (lp_server_signing() == Required) {
+ exit_server("reply_nt1: smb signing required and share level security selected.");
+ }
+ }
+ }
+
set_message(outbuf,17,0,True);
SCVAL(outbuf,smb_vwv1,secword);
@@ -521,6 +537,10 @@ int reply_negprot(connection_struct *conn,
DEBUG( 5, ( "negprot index=%d\n", choice ) );
+ if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
+ exit_server("SMB signing is required and client negotiated a downlevel protocol");
+ }
+
END_PROFILE(SMBnegprot);
return(outsize);
}
diff --git a/source/smbd/notify.c b/source/smbd/notify.c
index de1b3317780..ca6f2b783f2 100644
--- a/source/smbd/notify.c
+++ b/source/smbd/notify.c
@@ -44,6 +44,7 @@ static struct change_notify *change_notify_list;
/****************************************************************************
Setup the common parts of the return packet and send it.
*****************************************************************************/
+
static void change_notify_reply_packet(char *inbuf, NTSTATUS error_code)
{
char outbuf[smb_size+38];
@@ -178,7 +179,7 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
struct change_notify *cnbp;
if((cnbp = (struct change_notify *)malloc(sizeof(*cnbp))) == NULL) {
- DEBUG(0,("call_nt_transact_notify_change: malloc fail !\n" ));
+ DEBUG(0,("change_notify_set: malloc fail !\n" ));
return -1;
}
@@ -197,6 +198,9 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
DLIST_ADD(change_notify_list, cnbp);
+ /* Push the MID of this packet on the signing queue. */
+ srv_defer_sign_response(SVAL(inbuf,smb_mid), True);
+
return True;
}
diff --git a/source/smbd/ntquotas.c b/source/smbd/ntquotas.c
index 2e865000ecc..88d7c4e1643 100644
--- a/source/smbd/ntquotas.c
+++ b/source/smbd/ntquotas.c
@@ -188,7 +188,7 @@ int vfs_get_user_ntquota_list(files_struct *fsp, SMB_NTQUOTA_LIST **qt_list)
}
if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &tmp_qt)!=0) {
- DEBUG(1,("no quota entry for sid[%s] path[%s]\n",
+ DEBUG(5,("no quota entry for sid[%s] path[%s]\n",
sid_string_static(&sid),fsp->conn->connectpath));
continue;
}
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index c574d9d563a..7a58e838772 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -1443,6 +1443,7 @@ int reply_ntcancel(connection_struct *conn,
START_PROFILE(SMBntcancel);
remove_pending_change_notify_requests_by_mid(mid);
remove_pending_lock_requests_by_mid(mid);
+ srv_cancel_sign_response(mid);
DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", mid));
@@ -1723,7 +1724,11 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
char **ppparams, uint32 parameter_count,
char **ppdata, uint32 data_count)
{
- unsigned fnum, control;
+ uint32 function;
+ uint16 fidnum;
+ files_struct *fsp;
+ uint8 isFSctl;
+ uint8 compfilter;
static BOOL logged_message;
char *pdata = *ppdata;
@@ -1732,19 +1737,26 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
}
- fnum = SVAL(*ppsetup, 4);
- control = IVAL(*ppsetup, 0);
+ function = IVAL(*ppsetup, 0);
+ fidnum = SVAL(*ppsetup, 4);
+ isFSctl = CVAL(*ppsetup, 6);
+ compfilter = CVAL(*ppsetup, 7);
+
+ DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
+ function, fidnum, isFSctl, compfilter));
- DEBUG(10,("call_nt_transact_ioctl: fnum=%d control=0x%08x\n",
- fnum, control));
+ fsp=file_fsp(*ppsetup, 4);
+ /* this check is done in each implemented function case for now
+ because I don't want to break anything... --metze
+ FSP_BELONGS_CONN(fsp,conn);*/
- switch (control) {
+ switch (function) {
case FSCTL_SET_SPARSE:
/* pretend this succeeded - tho strictly we should
mark the file sparse (if the local fs supports it)
so we can know if we need to pre-allocate or not */
- DEBUG(10,("FSCTL_SET_SPARSE: fnum=%d control=0x%08x\n",fnum,control));
+ DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
return -1;
@@ -1753,7 +1765,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
but works ok like this --metze
*/
- DEBUG(10,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
+ DEBUG(10,("FSCTL_0x000900C0: called on FID[0x%04X](but not implemented)\n",fidnum));
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
return -1;
@@ -1762,7 +1774,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
* --metze
*/
- DEBUG(10,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
+ DEBUG(10,("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
return -1;
@@ -1771,10 +1783,125 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
* --metze
*/
- DEBUG(10,("FSCTL_SET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
+ DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
return -1;
+ case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
+ {
+ /*
+ * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
+ * and return their volume names. If max_data_count is 16, then it is just
+ * asking for the number of volumes and length of the combined names.
+ *
+ * pdata is the data allocated by our caller, but that uses
+ * total_data_count (which is 0 in our case) rather than max_data_count.
+ * Allocate the correct amount and return the pointer to let
+ * it be deallocated when we return.
+ */
+ uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
+ SHADOW_COPY_DATA *shadow_data = NULL;
+ TALLOC_CTX *shadow_mem_ctx = NULL;
+ BOOL labels = False;
+ uint32 labels_data_count = 0;
+ uint32 i;
+ char *cur_pdata;
+
+ FSP_BELONGS_CONN(fsp,conn);
+
+ if (max_data_count < 16) {
+ DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
+ max_data_count));
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+
+ if (max_data_count > 16) {
+ labels = True;
+ }
+
+ shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA");
+ if (shadow_mem_ctx == NULL) {
+ DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n"));
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ shadow_data = (SHADOW_COPY_DATA *)talloc_zero(shadow_mem_ctx,sizeof(SHADOW_COPY_DATA));
+ if (shadow_data == NULL) {
+ DEBUG(0,("talloc_zero() failed!\n"));
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ shadow_data->mem_ctx = shadow_mem_ctx;
+
+ /*
+ * Call the VFS routine to actually do the work.
+ */
+ if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
+ talloc_destroy(shadow_data->mem_ctx);
+ if (errno == ENOSYS) {
+ DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
+ conn->connectpath));
+ return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ } else {
+ DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
+ conn->connectpath));
+ return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+ }
+ }
+
+ labels_data_count = (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL))+2;
+
+ if (!labels) {
+ data_count = 16;
+ } else {
+ data_count = 12+labels_data_count+4;
+ }
+
+ if (max_data_count<data_count) {
+ DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
+ max_data_count,data_count));
+ talloc_destroy(shadow_data->mem_ctx);
+ return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
+ }
+
+ pdata = nttrans_realloc(ppdata, data_count);
+ if (pdata == NULL) {
+ talloc_destroy(shadow_data->mem_ctx);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ cur_pdata = pdata;
+
+ /* num_volumes 4 bytes */
+ SIVAL(pdata,0,shadow_data->num_volumes);
+
+ if (labels) {
+ /* num_labels 4 bytes */
+ SIVAL(pdata,4,shadow_data->num_volumes);
+ }
+
+ /* needed_data_count 4 bytes */
+ SIVAL(pdata,8,labels_data_count);
+
+ cur_pdata+=12;
+
+ DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
+ shadow_data->num_volumes,fsp->fsp_name));
+ if (labels && shadow_data->labels) {
+ for (i=0;i<shadow_data->num_volumes;i++) {
+ srvstr_push(outbuf, cur_pdata, shadow_data->labels[i], 2*sizeof(SHADOW_COPY_LABEL), STR_UNICODE|STR_TERMINATE);
+ cur_pdata+=2*sizeof(SHADOW_COPY_LABEL);
+ DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
+ }
+ }
+
+ talloc_destroy(shadow_data->mem_ctx);
+
+ send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, pdata, data_count);
+
+ return -1;
+ }
+
case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
{
/* pretend this succeeded -
@@ -1782,24 +1909,24 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
* we have to send back a list with all files owned by this SID
*
* but I have to check that --metze
- */
-
+ */
DOM_SID sid;
uid_t uid;
- size_t sid_len=SID_MAX_SIZE;
-
- DEBUG(10,("FSCTL_FIND_FILES_BY_SID: fnum=%d control=0x%08x\n",fnum,control));
+ size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
- /* this is not the length of the sid :-( so unknown 4 bytes */
- /*sid_len = IVAL(pdata,0);
- DEBUGADD(0,("sid_len: (%u)\n",sid_len));*/
+ DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
+
+ FSP_BELONGS_CONN(fsp,conn);
+
+ /* unknown 4 bytes: this is not the length of the sid :-( */
+ /*unknown = IVAL(pdata,0);*/
sid_parse(pdata+4,sid_len,&sid);
- DEBUGADD(10,("SID: %s\n",sid_string_static(&sid)));
+ DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) {
- DEBUG(0,("sid_to_uid: failed, sid[%s]\n",
- sid_string_static(&sid)));
+ DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%u]\n",
+ sid_string_static(&sid),sid_len));
uid = (-1);
}
@@ -1812,6 +1939,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
* for each file
*
* but I don't know how to deal with the paged results
+ * (maybe we can hang the result anywhere in the fsp struct)
*
* we don't send all files at once
* and at the next we should *not* start from the beginning,
@@ -1828,7 +1956,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
if (!logged_message) {
logged_message = True; /* Only print this once... */
DEBUG(0,("call_nt_transact_ioctl(0x%x): Currently not implemented.\n",
- control));
+ function));
}
}
@@ -2321,6 +2449,8 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
dump_data(10, data, data_count);
}
+ srv_signing_trans_start(SVAL(inbuf,smb_mid));
+
if(num_data_sofar < total_data_count || num_params_sofar < total_parameter_count) {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
@@ -2484,6 +2614,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBnttrans);
+ srv_signing_trans_stop();
return ERROR_DOS(ERRSRV,ERRerror);
}
@@ -2494,6 +2625,8 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
an error packet.
*/
+ srv_signing_trans_stop();
+
SAFE_FREE(setup);
SAFE_FREE(params);
SAFE_FREE(data);
@@ -2504,6 +2637,7 @@ due to being in oplock break state.\n", (unsigned int)function_code ));
bad_param:
+ srv_signing_trans_stop();
SAFE_FREE(params);
SAFE_FREE(data);
SAFE_FREE(setup);
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 6d03eaa29ac..06f1ddfcf2d 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -125,6 +125,7 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
directory.
*/
flags &= ~O_CREAT;
+ local_flags &= ~O_CREAT;
}
}
@@ -166,6 +167,14 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
local_flags |= O_NONBLOCK;
#endif
+ /* Don't create files with Microsoft wildcard characters. */
+ if ((local_flags & O_CREAT) && !VALID_STAT(*psbuf) && ms_has_wild(fname)) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRinvalidname;
+ unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
+ return False;
+ }
+
/* Actually do the open */
fsp->fd = fd_open(conn, fname, local_flags, mode);
if (fsp->fd == -1) {
@@ -218,7 +227,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
fsp->dev = psbuf->st_dev;
fsp->vuid = current_user.vuid;
fsp->size = psbuf->st_size;
- fsp->pos = -1;
fsp->can_lock = True;
fsp->can_read = ((flags & O_WRONLY)==0);
fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
@@ -617,6 +625,12 @@ static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T
DEBUG(5,("open_mode_check: oplock_request = %d, breaking oplock (%x) on file %s, \
dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsigned int)dev, (double)inode));
+ /* Ensure the reply for the open uses the correct sequence number. */
+ /* This isn't a real deferred packet as it's response will also increment
+ * the sequence.
+ */
+ srv_defer_sign_response(get_current_mid(), False);
+
/* Oplock break - unlock to request it. */
unlock_share_entry(conn, dev, inode);
@@ -675,8 +689,8 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
dev = %x, inode = %.0f. Deleting it to continue...\n", (int)broken_entry.pid, fname, (unsigned int)dev, (double)inode));
if (process_exists(broken_entry.pid)) {
- DEBUG(0,("open_mode_check: Existent process %d left active oplock.\n",
- broken_entry.pid ));
+ DEBUG(0,("open_mode_check: Existent process %lu left active oplock.\n",
+ (unsigned long)broken_entry.pid ));
}
if (del_share_entry(dev, inode, &broken_entry, NULL) == -1) {
@@ -874,7 +888,7 @@ files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_
if (file_existed && (GET_FILE_OPEN_DISPOSITION(ofun) == FILE_EXISTS_TRUNCATE)) {
if (!open_match_attributes(conn, fname, psbuf->st_mode, mode, &new_mode)) {
DEBUG(5,("open_file_shared: attributes missmatch for file %s (0%o, 0%o)\n",
- fname, psbuf->st_mode, mode ));
+ fname, (int)psbuf->st_mode, (int)mode ));
file_free(fsp);
errno = EACCES;
return NULL;
@@ -1290,6 +1304,15 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
return NULL;
}
+ if (ms_has_wild(fname)) {
+ file_free(fsp);
+ DEBUG(5,("open_directory: failing create on filename %s with wildcards\n", fname));
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRinvalidname;
+ unix_ERR_ntstatus = NT_STATUS_OBJECT_NAME_INVALID;
+ return NULL;
+ }
+
if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
fname, strerror(errno) ));
@@ -1338,7 +1361,6 @@ files_struct *open_directory(connection_struct *conn, char *fname, SMB_STRUCT_ST
fsp->dev = psbuf->st_dev;
fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid;
- fsp->pos = -1;
fsp->can_lock = True;
fsp->can_read = False;
fsp->can_write = False;
@@ -1401,7 +1423,6 @@ files_struct *open_file_stat(connection_struct *conn, char *fname, SMB_STRUCT_ST
fsp->dev = (SMB_DEV_T)0;
fsp->size = psbuf->st_size;
fsp->vuid = current_user.vuid;
- fsp->pos = -1;
fsp->can_lock = False;
fsp->can_read = False;
fsp->can_write = False;
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index 85256877937..19e6956d9ef 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -660,6 +660,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
time_t start_time;
BOOL shutdown_server = False;
BOOL oplock_timeout = False;
+ BOOL sign_state;
connection_struct *saved_user_conn;
connection_struct *saved_fsp_conn;
int saved_vuid;
@@ -742,8 +743,16 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
/* Remember if we just sent a break to level II on this file. */
fsp->sent_oplock_break = using_levelII? LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT;
- if (!send_smb(smbd_server_fd(), outbuf))
+ /* Save the server smb signing state. */
+ sign_state = srv_oplock_set_signing(False);
+
+ if (!send_smb(smbd_server_fd(), outbuf)) {
+ srv_oplock_set_signing(sign_state);
exit_server("oplock_break: send_smb failed.");
+ }
+
+ /* Restore the sign state to what it was. */
+ srv_oplock_set_signing(sign_state);
/* We need this in case a readraw crosses on the wire. */
global_oplock_break = True;
@@ -791,6 +800,9 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
} else if (smb_read_error == READ_ERROR) {
DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
shutdown_server = True;
+ } else if (smb_read_error == READ_BAD_SIG) {
+ DEBUG( 0, ("oplock_break: bad signature from client\n" ));
+ shutdown_server = True;
} else if (smb_read_error == READ_TIMEOUT) {
DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n", OPLOCK_BREAK_TIMEOUT ) );
oplock_timeout = True;
diff --git a/source/smbd/password.c b/source/smbd/password.c
index e2c143f1e24..b988f2ec745 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -29,10 +29,11 @@ static int next_vuid = VUID_OFFSET;
static int num_validated_vuids;
/****************************************************************************
-check if a uid has been validated, and return an pointer to the user_struct
-if it has. NULL if not. vuid is biased by an offset. This allows us to
-tell random client vuid's (normally zero) from valid vuids.
+ Check if a uid has been validated, and return an pointer to the user_struct
+ if it has. NULL if not. vuid is biased by an offset. This allows us to
+ tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
+
user_struct *get_valid_user_struct(uint16 vuid)
{
user_struct *usp;
@@ -54,8 +55,9 @@ user_struct *get_valid_user_struct(uint16 vuid)
}
/****************************************************************************
-invalidate a uid
+ Invalidate a uid.
****************************************************************************/
+
void invalidate_vuid(uint16 vuid)
{
user_struct *vuser = get_valid_user_struct(vuid);
@@ -85,8 +87,9 @@ void invalidate_vuid(uint16 vuid)
}
/****************************************************************************
-invalidate all vuid entries for this process
+ Invalidate all vuid entries for this process.
****************************************************************************/
+
void invalidate_all_vuids(void)
{
user_struct *usp, *next=NULL;
@@ -108,7 +111,7 @@ void invalidate_all_vuids(void)
*
*/
-int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
+int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob, const char *smb_name)
{
user_struct *vuser = NULL;
@@ -238,38 +241,42 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name)
vuser->homes_snum = -1;
}
+ if (lp_server_signing() && !vuser->guest && !srv_is_signing_active()) {
+ /* Try and turn on server signing on the first non-guest sessionsetup. */
+ srv_set_signing(vuser->session_key, response_blob);
+ }
+
return vuser->vuid;
}
-
/****************************************************************************
-add a name to the session users list
+ Add a name to the session users list.
****************************************************************************/
+
void add_session_user(const char *user)
{
- fstring suser;
- struct passwd *passwd;
+ fstring suser;
+ struct passwd *passwd;
- if (!(passwd = Get_Pwnam(user))) return;
+ if (!(passwd = Get_Pwnam(user)))
+ return;
- fstrcpy(suser,passwd->pw_name);
+ fstrcpy(suser,passwd->pw_name);
- if (suser && *suser && !in_list(suser,session_users,False))
- {
- if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring))
- DEBUG(1,("Too many session users??\n"));
- else
- {
- pstrcat(session_users," ");
- pstrcat(session_users,suser);
+ if (suser && *suser && !in_list(suser,session_users,False)) {
+ if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring)) {
+ DEBUG(1,("Too many session users??\n"));
+ } else {
+ pstrcat(session_users," ");
+ pstrcat(session_users,suser);
+ }
}
- }
}
-
/****************************************************************************
-check if a username is valid
+ Check if a username is valid.
****************************************************************************/
+
BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups)
{
char **valid, **invalid;
@@ -308,8 +315,9 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups)
}
/****************************************************************************
-validate a group username entry. Return the username or NULL
+ Validate a group username entry. Return the username or NULL.
****************************************************************************/
+
static char *validate_group(char *group, DATA_BLOB password,int snum)
{
#ifdef HAVE_NETGROUP
diff --git a/source/smbd/process.c b/source/smbd/process.c
index b025503da4f..373c2f16ae3 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -48,6 +48,15 @@ BOOL global_machine_password_needs_changing = False;
extern int max_send;
/****************************************************************************
+ Function to return the current request mid from Inbuffer.
+****************************************************************************/
+
+uint16 get_current_mid(void)
+{
+ return SVAL(InBuffer,smb_mid);
+}
+
+/****************************************************************************
structure to hold a linked list of queued messages.
for processing.
****************************************************************************/
@@ -87,6 +96,9 @@ static BOOL push_message(ubi_slList *list_head, char *buf, int msg_len)
ubi_slAddTail( list_head, msg);
+ /* Push the MID of this packet on the signing queue. */
+ srv_defer_sign_response(SVAL(buf,smb_mid), True);
+
return True;
}
@@ -1084,16 +1096,21 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
extern int keepalive;
if (smb_read_error == READ_EOF) {
- DEBUG(3,("end of file from client\n"));
+ DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
return False;
}
if (smb_read_error == READ_ERROR) {
- DEBUG(3,("receive_smb error (%s) exiting\n",
+ DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n",
strerror(errno)));
return False;
}
+ if (smb_read_error == READ_BAD_SIG) {
+ DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n"));
+ return False;
+ }
+
*last_timeout_processing_time = t = time(NULL);
if(last_keepalive_sent_time == 0)
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index e7f01ad02fe..35d07d5bf7d 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -39,6 +39,21 @@ unsigned int smb_echo_count = 0;
extern BOOL global_encrypted_passwords_negotiated;
/****************************************************************************
+ Ensure we check the path in the same way as W2K.
+****************************************************************************/
+
+static NTSTATUS check_path_syntax(const char *name)
+{
+ while (*name == '\\')
+ name++;
+ if (strequal(name, "."))
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ else if (strequal(name, ".."))
+ return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
Reply to a special message.
****************************************************************************/
@@ -48,8 +63,6 @@ int reply_special(char *inbuf,char *outbuf)
int msg_type = CVAL(inbuf,0);
int msg_flags = CVAL(inbuf,1);
pstring name1,name2;
-
- int len;
char name_type = 0;
static BOOL already_got_session = False;
@@ -75,23 +88,16 @@ int reply_special(char *inbuf,char *outbuf)
return(0);
}
name_extract(inbuf,4,name1);
- name_extract(inbuf,4 + name_len(inbuf + 4),name2);
+ name_type = name_extract(inbuf,4 + name_len(inbuf + 4),name2);
DEBUG(2,("netbios connect: name1=%s name2=%s\n",
name1,name2));
- name1[15] = 0;
-
- len = strlen(name2);
- if (len == 16) {
- name_type = name2[15];
- name2[15] = 0;
- }
-
set_local_machine_name(name1, True);
set_remote_machine_name(name2, True);
- DEBUG(2,("netbios connect: local=%s remote=%s\n",
- get_local_machine_name(), get_remote_machine_name() ));
+ DEBUG(2,("netbios connect: local=%s remote=%s, name type = %x\n",
+ get_local_machine_name(), get_remote_machine_name(),
+ name_type));
if (name_type == 'R') {
/* We are being asked for a pathworks session ---
@@ -388,10 +394,16 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
BOOL ok = False;
BOOL bad_path = False;
SMB_STRUCT_STAT sbuf;
+ NTSTATUS status;
+
START_PROFILE(SMBchkpth);
srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE);
+ status = check_path_syntax(name);
+ if (!NT_STATUS_IS_OK(status))
+ return ERROR_NT(status);
+
RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
unix_convert(name,conn,0,&bad_path,&sbuf);
@@ -410,8 +422,21 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
one at a time - if a component fails it expects
ERRbadpath, not ERRbadfile.
*/
- if(errno == ENOENT)
- return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+ if(errno == ENOENT) {
+ /*
+ * Windows returns different error codes if
+ * the parent directory is valid but not the
+ * last component - it returns NT_STATUS_OBJECT_NAME_NOT_FOUND
+ * for that case and NT_STATUS_OBJECT_PATH_NOT_FOUND
+ * if the path is invalid.
+ */
+ if (bad_path) {
+ return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+ } else {
+ return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
+ }
+ } else if (errno == ENOTDIR)
+ return ERROR_NT(NT_STATUS_NOT_A_DIRECTORY);
return(UNIXERROR(ERRDOS,ERRbadpath));
}
@@ -519,13 +544,18 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
mode = SVAL(inbuf,smb_vwv0);
mtime = make_unix_date3(inbuf+smb_vwv1);
- if (VALID_STAT_OF_DIR(sbuf))
- mode |= aDIR;
- else
- mode &= ~aDIR;
+ if (mode != FILE_ATTRIBUTE_NORMAL) {
+ if (VALID_STAT_OF_DIR(sbuf))
+ mode |= aDIR;
+ else
+ mode &= ~aDIR;
+
+ if (check_name(fname,conn))
+ ok = (file_chmod(conn,fname,mode,NULL) == 0);
+ } else {
+ ok = True;
+ }
- if (check_name(fname,conn))
- ok = (file_chmod(conn,fname,mode,NULL) == 0);
if (ok)
ok = set_filetime(conn,fname,mtime);
@@ -1224,6 +1254,9 @@ static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
int access_mode;
files_struct *fsp;
+ DEBUG(10,("can_delete: %s, dirtype = %d\n",
+ fname, dirtype ));
+
if (!CAN_WRITE(conn))
return NT_STATUS_MEDIA_WRITE_PROTECTED;
@@ -1231,14 +1264,19 @@ static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
fmode = dos_mode(conn,fname,&sbuf);
+
+ /* Can't delete a directory. */
if (fmode & aDIR)
return NT_STATUS_FILE_IS_A_DIRECTORY;
+ else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
+ return NT_STATUS_OBJECT_NAME_INVALID;
+
if (!lp_delete_readonly(SNUM(conn))) {
if (fmode & aRONLY)
return NT_STATUS_CANNOT_DELETE;
}
if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
- return NT_STATUS_CANNOT_DELETE;
+ return NT_STATUS_NO_SUCH_FILE;
/* We need a better way to return NT status codes from open... */
unix_ERR_class = 0;
@@ -1281,6 +1319,16 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
*directory = *mask = 0;
+ /* We must check for wildcards in the name given
+ * directly by the client - before any unmangling.
+ * This prevents an unmangling of a UNIX name containing
+ * a DOS wildcard like '*' or '?' from unmangling into
+ * a wildcard delete which was not intended.
+ * FIX for #226. JRA.
+ */
+
+ has_wild = ms_has_wild(name);
+
rc = unix_convert(name,conn,0,&bad_path,&sbuf);
p = strrchr_m(name,'/');
@@ -1305,13 +1353,12 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
if (!rc && mangle_is_mangled(mask))
mangle_check_cache( mask );
- has_wild = ms_has_wild(mask);
-
if (!has_wild) {
pstrcat(directory,"/");
pstrcat(directory,mask);
error = can_delete(directory,conn,dirtype);
- if (!NT_STATUS_IS_OK(error)) return error;
+ if (!NT_STATUS_IS_OK(error))
+ return error;
if (SMB_VFS_UNLINK(conn,directory) == 0) {
count++;
@@ -1329,7 +1376,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
*/
if (dirptr) {
- error = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ error = NT_STATUS_NO_SUCH_FILE;
if (strequal(mask,"????????.???"))
pstrcpy(mask,"*");
@@ -1338,12 +1385,15 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
pstring fname;
pstrcpy(fname,dname);
- if(!mask_match(fname, mask, case_sensitive)) continue;
+ if(!mask_match(fname, mask, case_sensitive))
+ continue;
slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
error = can_delete(fname,conn,dirtype);
- if (!NT_STATUS_IS_OK(error)) continue;
- if (SMB_VFS_UNLINK(conn,fname) == 0) count++;
+ if (!NT_STATUS_IS_OK(error))
+ continue;
+ if (SMB_VFS_UNLINK(conn,fname) == 0)
+ count++;
DEBUG(3,("unlink_internals: succesful unlink [%s]\n",fname));
}
CloseDir(dirptr);
@@ -1374,12 +1424,17 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
srvstr_pull_buf(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), STR_TERMINATE);
+ status = check_path_syntax(name);
+ if (!NT_STATUS_IS_OK(status))
+ return ERROR_NT(status);
+
RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
DEBUG(3,("reply_unlink : %s\n",name));
status = unlink_internals(conn, dirtype, name);
- if (!NT_STATUS_IS_OK(status)) return ERROR_NT(status);
+ if (!NT_STATUS_IS_OK(status))
+ return ERROR_NT(status);
/*
* Win2k needs a changenotify request response before it will
@@ -1472,6 +1527,10 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
files_struct *fsp;
START_PROFILE(SMBreadbraw);
+ if (srv_is_signing_active()) {
+ exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
+ }
+
/*
* Special check if an oplock break has been issued
* and the readraw request croses on the wire, we must
@@ -1870,6 +1929,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
int outsize = 0;
START_PROFILE(SMBwritebraw);
+ if (srv_is_signing_active()) {
+ exit_server("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
+ }
+
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
@@ -2250,39 +2313,25 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
switch (mode) {
case 0:
umode = SEEK_SET;
+ res = startpos;
break;
case 1:
umode = SEEK_CUR;
+ res = fsp->pos + startpos;
break;
case 2:
umode = SEEK_END;
break;
default:
umode = SEEK_SET;
+ res = startpos;
break;
}
- if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
- /*
- * Check for the special case where a seek before the start
- * of the file sets the offset to zero. Added in the CIFS spec,
- * section 4.2.7.
- */
-
- if(errno == EINVAL) {
- SMB_OFF_T current_pos = startpos;
-
- if(umode == SEEK_CUR) {
-
- if((current_pos = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1) {
- END_PROFILE(SMBlseek);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- current_pos += startpos;
-
- } else if (umode == SEEK_END) {
-
+ if (umode == SEEK_END) {
+ if((res = SMB_VFS_LSEEK(fsp,fsp->fd,startpos,umode)) == -1) {
+ if(errno == EINVAL) {
+ SMB_OFF_T current_pos = startpos;
SMB_STRUCT_STAT sbuf;
if(SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf) == -1) {
@@ -2291,10 +2340,9 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
current_pos += sbuf.st_size;
+ if(current_pos < 0)
+ res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
}
-
- if(current_pos < 0)
- res = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_SET);
}
if(res == -1) {
@@ -2828,7 +2876,11 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
int ret= -1;
unix_convert(directory,conn,0,&bad_path,&sbuf);
-
+
+ if (ms_has_wild(directory)) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
if (check_name(directory, conn))
ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
diff --git a/source/smbd/sec_ctx.c b/source/smbd/sec_ctx.c
index 411ece52495..8a85792ead5 100644
--- a/source/smbd/sec_ctx.c
+++ b/source/smbd/sec_ctx.c
@@ -199,7 +199,7 @@ BOOL initialise_groups(char *user, uid_t uid, gid_t gid)
/* Call initgroups() to get user groups */
- if (initgroups(user,gid) == -1) {
+ if (winbind_initgroups(user,gid) == -1) {
DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) ));
if (getuid() == 0) {
if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) {
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 18e0887071f..f75c9200693 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -661,7 +661,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
#else
/* the alternative is just to check the directory exists */
if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) {
- DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(SNUM(conn))));
+ DEBUG(0,("'%s' does not exist or is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(SNUM(conn))));
change_to_root_user();
yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
@@ -691,6 +691,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address );
+ dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
dbgtext( "initially as user %s ", user );
dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c
index 7d77ed30710..1435c38c99d 100644
--- a/source/smbd/sesssetup.c
+++ b/source/smbd/sesssetup.c
@@ -3,7 +3,7 @@
handle SMBsessionsetup
Copyright (C) Andrew Tridgell 1998-2001
Copyright (C) Andrew Bartlett 2001
- Copyright (C) Jim McDonough 2002
+ Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
Copyright (C) Luke Howard 2003
This program is free software; you can redistribute it and/or modify
@@ -62,7 +62,7 @@ static int add_signature(char *outbuf, char *p)
char *start = p;
fstring lanman;
- snprintf( lanman, sizeof(lanman), "Samba %s", VERSION );
+ fstr_sprintf( lanman, "Samba %s", VERSION );
p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE);
p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE);
@@ -149,10 +149,10 @@ static int reply_spnego_kerberos(connection_struct *conn,
DATA_BLOB auth_data;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
auth_serversupplied_info *server_info = NULL;
- ADS_STRUCT *ads;
uint8 session_key[16];
uint8 tok_id[2];
BOOL foreign = False;
+ DATA_BLOB nullblob = data_blob(NULL, 0);
ZERO_STRUCT(ticket);
ZERO_STRUCT(auth_data);
@@ -164,38 +164,31 @@ static int reply_spnego_kerberos(connection_struct *conn,
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
- ads = ads_init_simple();
-
- if (!ads) {
- return ERROR_NT(NT_STATUS_LOGON_FAILURE);
- }
-
- ads->auth.realm = strdup(lp_realm());
-
- ret = ads_verify_ticket(ads, &ticket, &client, &auth_data, &ap_rep, session_key);
+ ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, session_key);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(1,("Failed to verify incoming ticket!\n"));
- ads_destroy(&ads);
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
data_blob_free(&auth_data);
+ data_blob_free(&ticket);
DEBUG(3,("Ticket name is [%s]\n", client));
p = strchr_m(client, '@');
if (!p) {
DEBUG(3,("Doesn't look like a valid principal\n"));
- ads_destroy(&ads);
data_blob_free(&ap_rep);
+ SAFE_FREE(client);
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
*p = 0;
- if (strcasecmp(p+1, ads->auth.realm) != 0) {
+ if (strcasecmp(p+1, lp_realm()) != 0) {
DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
if (!lp_allow_trusted_domains()) {
data_blob_free(&ap_rep);
+ SAFE_FREE(client);
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
foreign = True;
@@ -212,7 +205,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
user = smb_xstrdup(client);
}
- ads_destroy(&ads);
+ SAFE_FREE(client);
/* setup the string used by %U */
sub_set_smb_name(user);
@@ -235,7 +228,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
memcpy(server_info->session_key, session_key, sizeof(session_key));
/* register_vuid keeps the server info */
- sess_vuid = register_vuid(server_info, user);
+ sess_vuid = register_vuid(server_info, nullblob, user);
free(user);
@@ -250,6 +243,16 @@ static int reply_spnego_kerberos(connection_struct *conn,
}
SSVAL(outbuf, smb_uid, sess_vuid);
+
+ if (!server_info->guest) {
+ /* We need to start the signing engine
+ * here but a W2K client sends the old
+ * "BSRSPYL " signature instead of the
+ * correct one. Subsequent packets will
+ * be correct.
+ */
+ srv_check_sign_mac(inbuf);
+ }
}
/* wrap that up in a nice GSS-API wrapping */
@@ -275,7 +278,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
End the NTLMSSP exchange context if we are OK/complete fail
***************************************************************************/
-static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf,
+static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf,
AUTH_NTLMSSP_STATE **auth_ntlmssp_state,
DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status)
{
@@ -294,8 +297,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf,
if (NT_STATUS_IS_OK(nt_status)) {
int sess_vuid;
+ DATA_BLOB nullblob = data_blob(NULL, 0);
+
/* register_vuid keeps the server info */
- sess_vuid = register_vuid(server_info, (*auth_ntlmssp_state)->ntlmssp_state->user);
+ sess_vuid = register_vuid(server_info, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
(*auth_ntlmssp_state)->server_info = NULL;
if (sess_vuid == -1) {
@@ -310,6 +315,16 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf,
}
SSVAL(outbuf,smb_uid,sess_vuid);
+
+ if (!server_info->guest) {
+ /* We need to start the signing engine
+ * here but a W2K client sends the old
+ * "BSRSPYL " signature instead of the
+ * correct one. Subsequent packets will
+ * be correct.
+ */
+ srv_check_sign_mac(inbuf);
+ }
}
}
@@ -348,16 +363,27 @@ static int reply_spnego_negotiate(connection_struct *conn,
if (!parse_negTokenTarg(blob1, OIDs, &secblob)) {
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
+
+ /* only look at the first OID for determining the mechToken --
+ accoirding to RFC2478, we should choose the one we want
+ and renegotiate, but i smell a client bug here..
+
+ Problem observed when connecting to a member (samba box)
+ of an AD domain as a user in a Samba domain. Samba member
+ server sent back krb5/mskrb5/ntlmssp as mechtypes, but the
+ client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an
+ NTLMSSP mechtoken. --jerry */
+ if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
+ strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
+ got_kerberos = True;
+ }
+
for (i=0;OIDs[i];i++) {
DEBUG(3,("Got OID %s\n", OIDs[i]));
- if (strcmp(OID_KERBEROS5, OIDs[i]) == 0 ||
- strcmp(OID_KERBEROS5_OLD, OIDs[i]) == 0) {
- got_kerberos = True;
- }
free(OIDs[i]);
}
- DEBUG(3,("Got secblob of size %d\n", secblob.length));
+ DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length));
#ifdef HAVE_KRB5
if (got_kerberos && (SEC_ADS == lp_security())) {
@@ -382,7 +408,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
data_blob_free(&secblob);
- reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state,
+ reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state,
&chal, nt_status);
data_blob_free(&chal);
@@ -419,7 +445,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
data_blob_free(&auth);
- reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state,
+ reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state,
&auth_reply, nt_status);
data_blob_free(&auth_reply);
@@ -742,7 +768,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
free_user_info(&user_info);
data_blob_free(&lm_resp);
- data_blob_free(&nt_resp);
data_blob_clear_free(&plaintext_password);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -750,9 +775,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
}
if (!NT_STATUS_IS_OK(nt_status)) {
+ data_blob_free(&nt_resp);
return ERROR_NT(nt_status_squash(nt_status));
}
-
+
/* it's ok - setup a reply */
set_message(outbuf,3,0,True);
if (Protocol >= PROTOCOL_NT1) {
@@ -770,12 +796,17 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
to a uid can get through without a password, on the same VC */
/* register_vuid keeps the server info */
- sess_vuid = register_vuid(server_info, sub_user);
-
+ sess_vuid = register_vuid(server_info, nt_resp, sub_user);
+ data_blob_free(&nt_resp);
+
if (sess_vuid == -1) {
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
+ if (!server_info->guest && !srv_check_sign_mac(inbuf)) {
+ exit_server("reply_sesssetup_and_X: bad smb signature");
+ }
+
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);
diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c
index 22b8a33a1e2..fbebdb240f4 100644
--- a/source/smbd/statcache.c
+++ b/source/smbd/statcache.c
@@ -98,7 +98,12 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat
translated_path_length--;
}
- original_path = strdup(full_orig_name);
+ if(case_sensitive) {
+ original_path = strdup(full_orig_name);
+ } else {
+ original_path = strdup_upper(full_orig_name);
+ }
+
if (!original_path) {
SAFE_FREE(translated_path);
return;
@@ -111,9 +116,6 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat
original_path_length--;
}
- if(!case_sensitive)
- strupper_m(original_path);
-
if (original_path_length != translated_path_length) {
if (original_path_length < translated_path_length) {
DEBUG(0, ("OOPS - tried to store stat cache entry for werid length paths [%s] %u and [%s] %u)!\n",
@@ -161,6 +163,7 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat
}
scp->original_path = scp->names;
+ /* pointer into the structure... */
scp->translated_path = scp->names + original_path_length + 1;
safe_strcpy(scp->original_path, original_path, original_path_length);
safe_strcpy(scp->translated_path, translated_path, translated_path_length);
@@ -194,7 +197,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
char **start, SMB_STRUCT_STAT *pst)
{
stat_cache_entry *scp;
- pstring chk_name;
+ char *chk_name;
size_t namelen;
hash_element *hash_elem;
char *sp;
@@ -218,10 +221,20 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
return False;
}
- pstrcpy(chk_name, name);
+ if (case_sensitive) {
+ chk_name = strdup(name);
+ if (!chk_name) {
+ DEBUG(0, ("stat_cache_lookup: strdup failed!\n"));
+ return False;
+ }
+
+ } else {
+ chk_name = strdup_upper(name);
+ if (!chk_name) {
+ DEBUG(0, ("stat_cache_lookup: strdup_upper failed!\n"));
+ return False;
+ }
- if(!case_sensitive) {
- strupper_m( chk_name );
/*
* In some language encodings the length changes
* if we uppercase. We need to treat this differently
@@ -252,11 +265,13 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
* We reached the end of the name - no match.
*/
DO_PROFILE_INC(statcache_misses);
+ SAFE_FREE(chk_name);
return False;
}
if((*chk_name == '\0') || (strcmp(chk_name, ".") == 0)
|| (strcmp(chk_name, "..") == 0)) {
DO_PROFILE_INC(statcache_misses);
+ SAFE_FREE(chk_name);
return False;
}
} else {
@@ -265,6 +280,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
if(SMB_VFS_STAT(conn,scp->translated_path, pst) != 0) {
/* Discard this entry - it doesn't exist in the filesystem. */
hash_remove(&stat_cache, hash_elem);
+ SAFE_FREE(chk_name);
return False;
}
@@ -290,6 +306,7 @@ BOOL stat_cache_lookup(connection_struct *conn, pstring name, pstring dirpath,
++*start;
pstrcpy(dirpath, scp->translated_path);
+ SAFE_FREE(chk_name);
return (namelen == scp->translated_path_length);
}
}
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index bdcd04443e9..3716378b37b 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -326,7 +326,13 @@ static BOOL exact_match(char *str,char *mask, BOOL case_sig)
return False;
if (case_sig)
return strcmp(str,mask)==0;
- return StrCaseCmp(str,mask) == 0;
+ if (StrCaseCmp(str,mask) != 0) {
+ return False;
+ }
+ if (ms_has_wild(str)) {
+ return False;
+ }
+ return True;
}
/****************************************************************************
@@ -1359,7 +1365,7 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
* the called hostname and the service name.
*/
SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) );
- len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, 0);
+ len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1, STR_NOALIGN);
SCVAL(pdata,l2_vol_cch,len);
data_len = l2_vol_szVolLabel + len;
DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",
@@ -1815,9 +1821,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
DEBUG(3,("fstat of fnum %d failed (%s)\n", fsp->fnum, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadfid));
}
- if((pos = SMB_VFS_LSEEK(fsp,fsp->fd,0,SEEK_CUR)) == -1)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
+ pos = fsp->position_information;
delete_pending = fsp->delete_on_close;
}
} else {
@@ -1867,6 +1871,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
base_name = p+1;
mode = dos_mode(conn,fname,&sbuf);
+ if (!mode)
+ mode = FILE_ATTRIBUTE_NORMAL;
+
fullpathname = fname;
file_size = get_file_size(sbuf);
allocation_size = get_allocation_size(fsp,&sbuf);
@@ -1906,7 +1913,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
if (strequal(base_name,".")) {
pstrcpy(dos_fname, "\\");
} else {
- snprintf(dos_fname, sizeof(dos_fname), "\\%s", fname);
+ pstr_sprintf(dos_fname, "\\%s", fname);
string_replace(dos_fname, '/', '\\');
}
@@ -1979,7 +1986,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
data_size = 24;
SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,file_size);
- SIVAL(pdata,16,sbuf.st_nlink);
+ if (delete_pending & sbuf.st_nlink)
+ SIVAL(pdata,16,sbuf.st_nlink - 1);
+ else
+ SIVAL(pdata,16,sbuf.st_nlink);
SCVAL(pdata,20,0);
SCVAL(pdata,21,(mode&aDIR)?1:0);
break;
@@ -2037,7 +2047,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
pdata += 40;
SOFF_T(pdata,0,allocation_size);
SOFF_T(pdata,8,file_size);
- SIVAL(pdata,16,sbuf.st_nlink);
+ if (delete_pending && sbuf.st_nlink)
+ SIVAL(pdata,16,sbuf.st_nlink - 1);
+ else
+ SIVAL(pdata,16,sbuf.st_nlink);
SCVAL(pdata,20,delete_pending);
SCVAL(pdata,21,(mode&aDIR)?1:0);
pdata += 24;
@@ -2501,18 +2514,13 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
switch (info_level) {
case SMB_INFO_STANDARD:
{
- if (total_data < l1_cbFile+4)
+ if (total_data < 12)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
/* access time */
tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
-
/* write time */
tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
-
- dosmode = SVAL(pdata,l1_attrFile);
- size = IVAL(pdata,l1_cbFile);
-
break;
}
@@ -2677,8 +2685,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (total_data < 1)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ /* Just ignore this set on a path. */
if (tran_call != TRANSACT2_SETFILEINFO)
- return ERROR_DOS(ERRDOS,ERRunknownlevel);
+ break;
if (fsp == NULL)
return(UNIXERROR(ERRDOS,ERRbadfid));
@@ -2696,6 +2705,27 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
break;
}
+ case SMB_FILE_POSITION_INFORMATION:
+ {
+ SMB_BIG_UINT position_information;
+
+ if (total_data < 8)
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+
+ position_information = (SMB_BIG_UINT)IVAL(pdata,0);
+#ifdef LARGE_SMB_OFF_T
+ position_information |= (((SMB_BIG_UINT)IVAL(pdata,4)) << 32);
+#else /* LARGE_SMB_OFF_T */
+ if (IVAL(pdata,4) != 0) /* more than 32 bits? */
+ return ERROR_DOS(ERRDOS,ERRunknownlevel);
+#endif /* LARGE_SMB_OFF_T */
+ DEBUG(10,("call_trans2setfilepathinfo: Set file position information for file %s to %.0f\n",
+ fname, (double)position_information ));
+ if (fsp)
+ fsp->position_information = position_information;
+ break;
+ }
+
/*
* CIFS UNIX extensions.
*/
@@ -2890,10 +2920,12 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
DEBUG(6,("size: %.0f ", (double)size));
- if (S_ISDIR(sbuf.st_mode))
- dosmode |= aDIR;
- else
- dosmode &= ~aDIR;
+ if (dosmode) {
+ if (S_ISDIR(sbuf.st_mode))
+ dosmode |= aDIR;
+ else
+ dosmode &= ~aDIR;
+ }
DEBUG(6,("dosmode: %x\n" , dosmode));
@@ -3353,6 +3385,8 @@ int reply_trans2(connection_struct *conn,
memcpy( data, smb_base(inbuf) + dsoff, num_data);
}
+ srv_signing_trans_start(SVAL(inbuf,smb_mid));
+
if(num_data_sofar < total_data || num_params_sofar < total_params) {
/* We need to send an interim response then receive the rest
of the parameter/data bytes */
@@ -3525,6 +3559,7 @@ int reply_trans2(connection_struct *conn,
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);
+ srv_signing_trans_stop();
return ERROR_DOS(ERRSRV,ERRerror);
}
@@ -3535,6 +3570,8 @@ int reply_trans2(connection_struct *conn,
an error packet.
*/
+ srv_signing_trans_stop();
+
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);
@@ -3544,6 +3581,7 @@ int reply_trans2(connection_struct *conn,
bad_param:
+ srv_signing_trans_stop();
SAFE_FREE(params);
SAFE_FREE(data);
END_PROFILE(SMBtrans2);
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index 8d3e7cd9be7..b12fcca4b0e 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -370,7 +370,7 @@ BOOL unbecome_user(void)
}
/*****************************************************************
- Convert the suplimentary SIDs returned in a netlogon into UNIX
+ Convert the supplementary SIDs returned in a netlogon into UNIX
group gid_t's. Add to the total group array.
*****************************************************************/
diff --git a/source/smbd/utmp.c b/source/smbd/utmp.c
index 9833a11f2d0..d57e475ce26 100644
--- a/source/smbd/utmp.c
+++ b/source/smbd/utmp.c
@@ -283,8 +283,12 @@ static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim)
* man page appears not to specify (hints non-NULL)
* A correspondent suggest at least ut_name should be NULL
*/
+#if defined(HAVE_UT_UT_NAME)
memset((char *)&u->ut_name, '\0', sizeof(u->ut_name));
+#endif
+#if defined(HAVE_UT_UT_HOST)
memset((char *)&u->ut_host, '\0', sizeof(u->ut_host));
+#endif
}
/* Stolen from logwtmp function in libutil.
* May be more locking/blocking is needed?
@@ -406,7 +410,9 @@ static void sys_utmp_update(struct utmp *u, const char *hostname, BOOL claim)
else
ux.ut_syslen = 0;
#endif
+#if defined(HAVE_UT_UT_HOST)
utmp_strcpy(ux.ut_host, hostname, sizeof(ux.ut_host));
+#endif
uw_pathname(uname, "utmpx", ux_pathname);
uw_pathname(wname, "wtmpx", wx_pathname);
@@ -491,8 +497,8 @@ static BOOL sys_utmp_fill(struct utmp *u,
* If size limit proves troublesome, then perhaps use "ut_id_encode()".
*/
if (strlen(id_str) > sizeof(u->ut_line)) {
- DEBUG(1,("id_str [%s] is too long for %d char utmp field\n",
- id_str, sizeof(u->ut_line)));
+ DEBUG(1,("id_str [%s] is too long for %lu char utmp field\n",
+ id_str, (unsigned long)sizeof(u->ut_line)));
return False;
}
utmp_strcpy(u->ut_line, id_str, sizeof(u->ut_line));
diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c
index 8d44a1a0fa1..a76a7a6abdc 100644
--- a/source/smbd/vfs-wrap.c
+++ b/source/smbd/vfs-wrap.c
@@ -49,6 +49,42 @@ SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *con
result = sys_disk_free(path, small_query, bsize, dfree, dsize);
return result;
}
+
+int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
+{
+#ifdef HAVE_SYS_QUOTAS
+ int result;
+
+ START_PROFILE(syscall_get_quota);
+ result = sys_get_quota(conn->connectpath, qtype, id, qt);
+ END_PROFILE(syscall_get_quota);
+ return result;
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
+{
+#ifdef HAVE_SYS_QUOTAS
+ int result;
+
+ START_PROFILE(syscall_set_quota);
+ result = sys_set_quota(conn->connectpath, qtype, id, qt);
+ END_PROFILE(syscall_set_quota);
+ return result;
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
+{
+ errno = ENOSYS;
+ return -1; /* Not implemented. */
+}
/* Directory operations */
@@ -756,36 +792,6 @@ int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct
return sys_acl_free_qualifier(qualifier, tagtype);
}
-int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
-{
-#ifdef HAVE_SYS_QUOTAS
- int result;
-
- START_PROFILE(syscall_get_quota);
- result = sys_get_quota(conn->connectpath, qtype, id, qt);
- END_PROFILE(syscall_get_quota);
- return result;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
-{
-#ifdef HAVE_SYS_QUOTAS
- int result;
-
- START_PROFILE(syscall_set_quota);
- result = sys_set_quota(conn->connectpath, qtype, id, qt);
- END_PROFILE(syscall_set_quota);
- return result;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
/****************************************************************
Extended attribute operations.
*****************************************************************/
diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c
index 5f3abe7efea..58a8a387925 100644
--- a/source/smbd/vfs.c
+++ b/source/smbd/vfs.c
@@ -56,6 +56,7 @@ static struct vfs_ops default_vfs = {
vfswrap_disk_free,
vfswrap_get_quota,
vfswrap_set_quota,
+ vfswrap_get_shadow_copy_data,
/* Directory operations */
@@ -140,7 +141,6 @@ static struct vfs_ops default_vfs = {
vfswrap_setxattr,
vfswrap_lsetxattr,
vfswrap_fsetxattr
-
}
};
diff --git a/source/torture/cmd_vfs.c b/source/torture/cmd_vfs.c
index f74fcedcf49..d91dbf50e02 100644
--- a/source/torture/cmd_vfs.c
+++ b/source/torture/cmd_vfs.c
@@ -528,7 +528,8 @@ static NTSTATUS cmd_stat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
printf(" Inode: %10u", (unsigned int)st.st_ino);
printf(" Links: %10u\n", (unsigned int)st.st_nlink);
printf(" Access: %05o", (st.st_mode) & 007777);
- printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group);
+ printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user,
+ (unsigned long)st.st_gid, group);
printf(" Access: %s", ctime(&(st.st_atime)));
printf(" Modify: %s", ctime(&(st.st_mtime)));
printf(" Change: %s", ctime(&(st.st_ctime)));
@@ -590,7 +591,8 @@ static NTSTATUS cmd_fstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
printf(" Inode: %10u", (unsigned int)st.st_ino);
printf(" Links: %10u\n", (unsigned int)st.st_nlink);
printf(" Access: %05o", (st.st_mode) & 007777);
- printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group);
+ printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user,
+ (unsigned long)st.st_gid, group);
printf(" Access: %s", ctime(&(st.st_atime)));
printf(" Modify: %s", ctime(&(st.st_mtime)));
printf(" Change: %s", ctime(&(st.st_ctime)));
@@ -640,7 +642,8 @@ static NTSTATUS cmd_lstat(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc,
printf(" Inode: %10u", (unsigned int)st.st_ino);
printf(" Links: %10u\n", (unsigned int)st.st_nlink);
printf(" Access: %05o", (st.st_mode) & 007777);
- printf(" Uid: %5d/%.16s Gid: %5d/%.16s\n", st.st_uid, user, st.st_gid, group);
+ printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n", (unsigned long)st.st_uid, user,
+ (unsigned long)st.st_gid, group);
printf(" Access: %s", ctime(&(st.st_atime)));
printf(" Modify: %s", ctime(&(st.st_mtime)));
printf(" Change: %s", ctime(&(st.st_ctime)));
diff --git a/source/torture/locktest.c b/source/torture/locktest.c
index 63b9590dd61..86379bf3b6d 100644
--- a/source/torture/locktest.c
+++ b/source/torture/locktest.c
@@ -157,7 +157,7 @@ static struct cli_state *connect_one(char *share, int snum)
zero_ip(&ip);
- slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), count++);
+ slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++);
make_nmb_name(&calling, myname, 0x0);
make_nmb_name(&called , server, 0x20);
diff --git a/source/torture/locktest2.c b/source/torture/locktest2.c
index 97844b5609e..5fbaf9ec584 100644
--- a/source/torture/locktest2.c
+++ b/source/torture/locktest2.c
@@ -173,11 +173,11 @@ static struct cli_state *connect_one(char *share)
}
}
- slprintf(myname,sizeof(myname), "lock-%u-%u", getpid(), count++);
+ slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++);
nt_status = cli_full_connection(&c, myname, server_n, NULL, 0, share, "?????",
username, lp_workgroup(), password, 0,
- NULL);
+ Undefined, NULL);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("cli_full_connection failed with error %s\n", nt_errstr(nt_status)));
diff --git a/source/torture/mangle_test.c b/source/torture/mangle_test.c
index 660d4d17af2..9a719349b65 100644
--- a/source/torture/mangle_test.c
+++ b/source/torture/mangle_test.c
@@ -54,7 +54,7 @@ static BOOL test_one(struct cli_state *cli, const char *name)
return False;
}
- snprintf(name2, sizeof(name2), "\\mangle_test\\%s", shortname);
+ fstr_sprintf(name2, "\\mangle_test\\%s", shortname);
if (!cli_unlink(cli, name2)) {
printf("unlink of %s (%s) failed (%s)\n",
name2, name, cli_errstr(cli));
diff --git a/source/torture/masktest.c b/source/torture/masktest.c
index fa901e3d63d..8c44f35f958 100644
--- a/source/torture/masktest.c
+++ b/source/torture/masktest.c
@@ -140,7 +140,7 @@ static BOOL reg_match_one(struct cli_state *cli, const char *pattern, const char
if (strcmp(file,"..") == 0) file = ".";
- return ms_fnmatch(pattern, file, cli->protocol)==0;
+ return ms_fnmatch(pattern, file, cli->protocol, False /* not case sensitive */)==0;
}
static char *reg_test(struct cli_state *cli, char *pattern, char *long_name, char *short_name)
diff --git a/source/torture/nsstest.c b/source/torture/nsstest.c
index 0a08cb6e8f2..a803cd7e719 100644
--- a/source/torture/nsstest.c
+++ b/source/torture/nsstest.c
@@ -29,11 +29,11 @@ static int total_errors;
static void *find_fn(const char *name)
{
- char s[1024];
+ pstring s;
static void *h;
void *res;
- snprintf(s,sizeof(s), "_nss_%s_%s", nss_name, name);
+ pstr_sprintf(s, "_nss_%s_%s", nss_name, name);
if (!h) {
h = sys_dlopen(so_path, RTLD_LAZY);
@@ -296,11 +296,11 @@ static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *sta
static void print_passwd(struct passwd *pwd)
{
- printf("%s:%s:%d:%d:%s:%s:%s\n",
+ printf("%s:%s:%lu:%lu:%s:%s:%s\n",
pwd->pw_name,
pwd->pw_passwd,
- pwd->pw_uid,
- pwd->pw_gid,
+ (unsigned long)pwd->pw_uid,
+ (unsigned long)pwd->pw_gid,
pwd->pw_gecos,
pwd->pw_dir,
pwd->pw_shell);
@@ -309,10 +309,10 @@ static void print_passwd(struct passwd *pwd)
static void print_group(struct group *grp)
{
int i;
- printf("%s:%s:%d: ",
+ printf("%s:%s:%lu: ",
grp->gr_name,
grp->gr_passwd,
- grp->gr_gid);
+ (unsigned long)grp->gr_gid);
if (!grp->gr_mem[0]) {
printf("\n");
@@ -343,9 +343,9 @@ static void nss_test_initgroups(char *name, gid_t gid)
}
for (i=0; i<start-1; i++) {
- printf("%d, ", groups[i]);
+ printf("%lu, ", (unsigned long)groups[i]);
}
- printf("%d\n", groups[i]);
+ printf("%lu\n", (unsigned long)groups[i]);
}
diff --git a/source/torture/torture.c b/source/torture/torture.c
index f26ebb49b30..d20c48d6454 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -159,7 +159,7 @@ BOOL torture_open_connection(struct cli_state **c)
host, NULL, port_to_use,
share, "?????",
username, workgroup,
- password, flags, &retry);
+ password, flags, Undefined, &retry);
if (!NT_STATUS_IS_OK(status)) {
return False;
}
@@ -1128,7 +1128,7 @@ static BOOL run_tcon_devtype_test(int dummy)
host, NULL, port_to_use,
NULL, NULL,
username, workgroup,
- password, flags, &retry);
+ password, flags, Undefined, &retry);
if (!NT_STATUS_IS_OK(status)) {
printf("could not open connection\n");
@@ -4366,7 +4366,7 @@ static BOOL run_error_map_extract(int dummy) {
}
for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
- snprintf(user, sizeof(user), "%X", error);
+ fstr_sprintf(user, "%X", error);
if (cli_session_setup(&c_nt, user,
password, strlen(password),
@@ -4586,7 +4586,7 @@ static BOOL run_test(const char *name)
}
for (i=0;torture_ops[i].name;i++) {
- snprintf(randomfname, sizeof(randomfname), "\\XX%x",
+ fstr_sprintf(randomfname, "\\XX%x",
(unsigned)random());
if (strequal(name, torture_ops[i].name)) {
diff --git a/source/utils/log2pcaphex.c b/source/utils/log2pcaphex.c
new file mode 100644
index 00000000000..b3a34281a85
--- /dev/null
+++ b/source/utils/log2pcaphex.c
@@ -0,0 +1,297 @@
+/*
+ Unix SMB/CIFS implementation.
+ Utility to extract pcap files from samba (log level 10) log files
+
+ Copyright (C) Jelmer Vernooij 2003
+ Thanks to Tim Potter for the genial idea
+
+ Portions (from capconvert.c) (C) Andrew Tridgell 1997
+ Portions (from text2pcap.c) (C) Ashok Narayanan 2001
+
+ Example use with -h parameter:
+ log2pcaphex < samba-log-file | text2pcap -T 139,139 - foo.pcap
+
+ TODO: Have correct IP and TCP checksums.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include <assert.h>
+
+int quiet = 0;
+int hexformat = 0;
+
+#define itoa(a) ((a) < 0xa?'0'+(a):'A' + (a-0xa))
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <memory.h>
+#include <sys/time.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+/* tcpdump file format */
+struct tcpdump_file_header {
+ uint32 magic;
+ uint16 major;
+ uint16 minor;
+ int32 zone;
+ uint32 sigfigs;
+ uint32 snaplen;
+ uint32 linktype;
+};
+
+struct tcpdump_packet {
+ struct timeval ts;
+ uint32 caplen;
+ uint32 len;
+};
+
+typedef struct {
+ uint8 ver_hdrlen;
+ uint8 dscp;
+ uint16 packet_length;
+ uint16 identification;
+ uint8 flags;
+ uint8 fragment;
+ uint8 ttl;
+ uint8 protocol;
+ uint16 hdr_checksum;
+ uint32 src_addr;
+ uint32 dest_addr;
+} hdr_ip_t;
+
+static hdr_ip_t HDR_IP = {0x45, 0, 0, 0x3412, 0, 0, 0xff, 6, 0, 0x01010101, 0x02020202};
+
+typedef struct {
+ uint16 source_port;
+ uint16 dest_port;
+ uint32 seq_num;
+ uint32 ack_num;
+ uint8 hdr_length;
+ uint8 flags;
+ uint16 window;
+ uint16 checksum;
+ uint16 urg;
+} hdr_tcp_t;
+
+static hdr_tcp_t HDR_TCP = {139, 139, 0, 0, 0x50, 0, 0, 0, 0};
+
+void print_pcap_header(FILE *out)
+{
+ struct tcpdump_file_header h;
+ h.magic = TCPDUMP_MAGIC;
+ h.major = 2;
+ h.minor = 4;
+ h.zone = 0;
+ h.sigfigs = 0;
+ h.snaplen = 102400; /* As long packets as possible */
+ h.linktype = 101; /* Raw IP */
+ fwrite(&h, sizeof(struct tcpdump_file_header), 1, out);
+}
+
+void print_pcap_packet(FILE *out, unsigned char *data, long length, long caplen)
+{
+ static int i = 0;
+ struct tcpdump_packet p;
+ i++;
+ p.ts.tv_usec = 0;
+ p.ts.tv_sec = 0;
+ p.caplen = caplen;
+ p.len = length;
+ fwrite(&p, sizeof(struct tcpdump_packet), 1, out);
+ fwrite(data, sizeof(unsigned char), caplen, out);
+}
+
+void print_hex_packet(FILE *out, unsigned char *data, long length)
+{
+ long i,cur = 0;int tmp;
+ while(cur < length) {
+ fprintf(out, "%06X ", cur);
+ for(i = cur; i < length && i < cur + 16; i++) {
+ fprintf(out, "%02x ", data[i]);
+ }
+
+ cur = i;
+ fprintf(out, "\n");
+ }
+}
+
+void print_netbios_packet(FILE *out, unsigned char *data, long length, long actual_length)
+{
+ unsigned char *newdata; long offset = 0;
+ long newlen;
+
+ newlen = length+sizeof(HDR_IP)+sizeof(HDR_TCP);
+ newdata = malloc(newlen);
+
+ HDR_IP.packet_length = htons(newlen);
+ HDR_TCP.window = htons(0x2000);
+ HDR_TCP.source_port = HDR_TCP.dest_port = htons(139);
+
+ memcpy(newdata+offset, &HDR_IP, sizeof(HDR_IP));offset+=sizeof(HDR_IP);
+ memcpy(newdata+offset, &HDR_TCP, sizeof(HDR_TCP));offset+=sizeof(HDR_TCP);
+ memcpy(newdata+offset,data,length);
+
+ print_pcap_packet(out, newdata, newlen, actual_length+offset);
+ free(newdata);
+}
+
+unsigned char *curpacket = NULL;
+long curpacket_len = 0;
+
+void read_log_msg(FILE *in, unsigned char **_buffer, long *buffersize, long *data_offset, long *data_length)
+{
+ unsigned char *buffer;
+ int tmp; long i;
+ assert(fscanf(in, " size=%d\n", buffersize));
+ *buffersize+=4; /* for netbios */
+ buffer = malloc(*buffersize);
+ memset(buffer, 0, *buffersize);
+ /* NetBIOS */
+ buffer[0] = 0x00;
+ buffer[1] = 0x00;
+ memcpy(buffer+2, &buffersize, 2);
+ buffer[4] = 0xFF;
+ buffer[5] = 'S';
+ buffer[6] = 'M';
+ buffer[7] = 'B';
+ assert(fscanf(in, " smb_com=0x%x\n", &tmp)); buffer[smb_com] = tmp;
+ assert(fscanf(in, " smb_rcls=%d\n", &tmp)); buffer[smb_rcls] = tmp;
+ assert(fscanf(in, " smb_reh=%d\n", &tmp)); buffer[smb_reh] = tmp;
+ assert(fscanf(in, " smb_err=%d\n", &tmp)); memcpy(buffer+smb_err, &tmp, 2);
+ assert(fscanf(in, " smb_flg=%d\n", &tmp)); buffer[smb_flg] = tmp;
+ assert(fscanf(in, " smb_flg2=%d\n", &tmp)); memcpy(buffer+smb_flg2, &tmp, 2);
+ assert(fscanf(in, " smb_tid=%d\n", &tmp)); memcpy(buffer+smb_tid, &tmp, 2);
+ assert(fscanf(in, " smb_pid=%d\n", &tmp)); memcpy(buffer+smb_pid, &tmp, 2);
+ assert(fscanf(in, " smb_uid=%d\n", &tmp)); memcpy(buffer+smb_uid, &tmp, 2);
+ assert(fscanf(in, " smb_mid=%d\n", &tmp)); memcpy(buffer+smb_mid, &tmp, 2);
+ assert(fscanf(in, " smt_wct=%d\n", &tmp)); buffer[smb_wct] = tmp;
+ for(i = 0; i < buffer[smb_wct]; i++) {
+ assert(fscanf(in, " smb_vwv[%*2d]=%*5d (0x%X)\n", &tmp));
+ memcpy(buffer+smb_vwv+i*2, &tmp, 2);
+ }
+
+ *data_offset = smb_vwv+buffer[smb_wct]*2;
+ assert(fscanf(in, " smb_bcc=%d\n", data_length)); buffer[(*data_offset)] = *data_length;
+ (*data_offset)+=2;
+ *_buffer = buffer;
+}
+
+long read_log_data(FILE *in, unsigned char *buffer, long data_length)
+{
+ long i, addr; char real[2][16]; int ret;
+ unsigned char tmp;
+ for(i = 0; i < data_length; i++) {
+ if(i % 16 == 0){
+ if(i != 0) { /* Read data after each line */
+ assert(fscanf(in, "%8s %8s", real[0], real[1]) == 2);
+ }
+ ret = fscanf(in, " [%03X]", &addr);
+ if(!ret) {
+ if(!quiet)fprintf(stderr, "Only first %d bytes are logged, packet trace will be incomplete\nTry a higher log level\n", i);
+ return i-1;
+ }
+ assert(addr == i);
+ }
+ if(!fscanf(in, "%02X", &tmp)) {
+ if(!quiet)fprintf(stderr, "Only first %d bytes are logged, packet trace will be incomplete\nTry a higher log level\n", i-1);
+ return i-1;
+ }
+ buffer[i] = tmp;
+ }
+ return data_length;
+}
+
+int main (int argc, char **argv)
+{
+ const char *infile, *outfile;
+ FILE *out, *in;
+ int opt;
+ int c;
+ poptContext pc;
+ char buffer[4096];
+ long data_offset, data_length;
+ long data_bytes_read;
+ int in_packet = 0;
+ int i;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ { "quiet", 'q', POPT_ARG_NONE, &quiet, 0, "Be quiet, don't output warnings" },
+ { "hex", 'h', POPT_ARG_NONE, &hexformat, 0, "Output format readable by text2pcap" },
+ POPT_TABLEEND
+ };
+
+ pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
+ POPT_CONTEXT_KEEP_FIRST);
+ poptSetOtherOptionHelp(pc, "[<infile> [<outfile>]]");
+
+
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ switch (opt) {
+ }
+ }
+
+ poptGetArg(pc); /* Drop argv[0], the program name */
+
+ infile = poptGetArg(pc);
+
+ if(infile) {
+ in = fopen(infile, "r");
+ if(!in) {
+ perror("fopen");
+ return 1;
+ }
+ } else in = stdin;
+
+ outfile = poptGetArg(pc);
+
+ if(outfile) {
+ out = fopen(outfile, "w+");
+ if(!out) {
+ perror("fopen");
+ fprintf(stderr, "Can't find %s, using stdout...\n", outfile);
+ }
+ }
+
+ if(!outfile) out = stdout;
+
+ if(!hexformat)print_pcap_header(out);
+
+ while(!feof(in)) {
+ fgets(buffer, sizeof(buffer), in);
+ if(buffer[0] == '[') { /* Header */
+ if(strstr(buffer, "show_msg")) {
+ in_packet++;
+ if(in_packet == 1)continue;
+ read_log_msg(in, &curpacket, &curpacket_len, &data_offset, &data_length);
+ } else if(in_packet && strstr(buffer, "dump_data")) {
+ data_bytes_read = read_log_data(in, curpacket+data_offset, data_length);
+ } else {
+ if(in_packet){
+ if(hexformat) print_hex_packet(out, curpacket, curpacket_len);
+ else print_netbios_packet(out, curpacket, curpacket_len, data_bytes_read+data_offset);
+ free(curpacket);
+ }
+ in_packet = 0;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/source/utils/net.c b/source/utils/net.c
index e643a3d10d7..8f6b09a3fa4 100644
--- a/source/utils/net.c
+++ b/source/utils/net.c
@@ -77,20 +77,7 @@ static int opt_machine_pass = 0;
BOOL opt_have_ip = False;
struct in_addr opt_dest_ip;
-/*****************************************************************************
- stubb functions
-****************************************************************************/
-
-void become_root( void )
-{
- return;
-}
-
-void unbecome_root( void )
-{
- return;
-}
-
+extern BOOL AllowDebugChange;
uint32 get_sec_channel_type(const char *param)
{
@@ -154,7 +141,7 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
server_ip, opt_port,
"IPC$", "IPC",
opt_user_name, opt_workgroup,
- opt_password, 0, NULL);
+ opt_password, 0, Undefined, NULL);
if (NT_STATUS_IS_OK(nt_status)) {
return nt_status;
@@ -184,7 +171,7 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
server_ip, opt_port,
"IPC$", "IPC",
"", "",
- "", 0, NULL);
+ "", 0, Undefined, NULL);
if (NT_STATUS_IS_OK(nt_status)) {
return nt_status;
@@ -580,6 +567,8 @@ static struct functable net_func[] = {
zero_ip(&opt_dest_ip);
+ /* set default debug level to 0 regardless of what smb.conf sets */
+ DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
dbf = x_stderr;
pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
@@ -615,9 +604,14 @@ static struct functable net_func[] = {
}
}
- lp_load(dyn_CONFIGFILE,True,False,False);
-
- argv_new = (const char **)poptGetArgs(pc);
+ /*
+ * Don't load debug level from smb.conf. It should be
+ * set by cmdline arg or remain default (0)
+ */
+ AllowDebugChange = False;
+ lp_load(dyn_CONFIGFILE,True,False,False);
+
+ argv_new = (const char **)poptGetArgs(pc);
argc_new = argc;
for (i=0; i<argc; i++) {
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index 69d282420d9..631e2351275 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -68,7 +68,7 @@ static int net_ads_lookup(int argc, const char **argv)
{
ADS_STRUCT *ads;
- ads = ads_init(NULL, NULL, opt_host);
+ ads = ads_init(NULL, opt_target_workgroup, opt_host);
if (ads) {
ads->auth.flags |= ADS_AUTH_NO_BIND;
}
@@ -89,7 +89,7 @@ static int net_ads_info(int argc, const char **argv)
{
ADS_STRUCT *ads;
- ads = ads_init(NULL, NULL, opt_host);
+ ads = ads_init(NULL, opt_target_workgroup, opt_host);
if (ads) {
ads->auth.flags |= ADS_AUTH_NO_BIND;
@@ -129,7 +129,7 @@ static ADS_STRUCT *ads_startup(void)
BOOL second_time = False;
char *cp;
- ads = ads_init(NULL, NULL, opt_host);
+ ads = ads_init(NULL, opt_target_workgroup, opt_host);
if (!opt_user_name) {
opt_user_name = "administrator";
@@ -848,7 +848,7 @@ static int net_ads_printer_publish(int argc, const char **argv)
opt_user_name, opt_workgroup,
opt_password ? opt_password : "",
CLI_FULL_CONNECTION_USE_KERBEROS,
- NULL);
+ Undefined, NULL);
if (NT_STATUS_IS_ERR(nt_status)) {
d_printf("Unable to open a connnection to %s to obtain data "
diff --git a/source/utils/net_ads_cldap.c b/source/utils/net_ads_cldap.c
index e74e4b5a4cf..595e6e94347 100644
--- a/source/utils/net_ads_cldap.c
+++ b/source/utils/net_ads_cldap.c
@@ -240,7 +240,7 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
return -1;
}
- p = os3.data;
+ p = (char *)os3.data;
reply->type = IVAL(p, 0); p += 4;
reply->flags = IVAL(p, 0); p += 4;
@@ -248,25 +248,25 @@ static int recv_cldap_netlogon(int sock, struct cldap_netlogon_reply *reply)
memcpy(&reply->guid.info, p, GUID_SIZE);
p += GUID_SIZE;
- p += pull_netlogon_string(reply->forest, p, os3.data);
- p += pull_netlogon_string(reply->unk0, p, os3.data);
- p += pull_netlogon_string(reply->domain, p, os3.data);
- p += pull_netlogon_string(reply->hostname, p, os3.data);
- p += pull_netlogon_string(reply->netbios_domain, p, os3.data);
- p += pull_netlogon_string(reply->unk1, p, os3.data);
- p += pull_netlogon_string(reply->netbios_hostname, p, os3.data);
- p += pull_netlogon_string(reply->unk2, p, os3.data);
+ p += pull_netlogon_string(reply->forest, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->unk0, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->domain, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->hostname, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->netbios_domain, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->unk1, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->netbios_hostname, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->unk2, p, (const char *)os3.data);
if (reply->type == SAMLOGON_AD_R) {
- p += pull_netlogon_string(reply->user_name, p, os3.data);
+ p += pull_netlogon_string(reply->user_name, p, (const char *)os3.data);
} else {
*reply->user_name = 0;
}
- p += pull_netlogon_string(reply->unk3, p, os3.data);
- p += pull_netlogon_string(reply->site_name, p, os3.data);
- p += pull_netlogon_string(reply->unk4, p, os3.data);
- p += pull_netlogon_string(reply->site_name_2, p, os3.data);
+ p += pull_netlogon_string(reply->unk3, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->site_name, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->unk4, p, (const char *)os3.data);
+ p += pull_netlogon_string(reply->site_name_2, p, (const char *)os3.data);
reply->version = IVAL(p, 0);
reply->lmnt_token = SVAL(p, 4);
diff --git a/source/utils/net_cache.c b/source/utils/net_cache.c
index 8dd9db599dc..a9559164587 100644
--- a/source/utils/net_cache.c
+++ b/source/utils/net_cache.c
@@ -214,7 +214,7 @@ static int net_cache_del(int argc, const char **argv)
const char *keystr = argv[0];
if (argc < 1) {
- d_printf("\nUsage: net cache add <key string>\n");
+ d_printf("\nUsage: net cache del <key string>\n");
return -1;
}
diff --git a/source/utils/net_groupmap.c b/source/utils/net_groupmap.c
index 8831839e4eb..99371452307 100644
--- a/source/utils/net_groupmap.c
+++ b/source/utils/net_groupmap.c
@@ -252,11 +252,21 @@ static int net_groupmap_add(int argc, const char **argv)
}
}
- if ( !unixgrp[0] || (!rid && !string_sid[0]) ) {
+ if ( !unixgrp[0] ) {
d_printf("Usage: net groupmap add {rid=<int>|sid=<string>} unixgroup=<string> [type=<domain|local|builtin>] [ntgroup=<string>] [comment=<string>]\n");
return -1;
}
+ if ( (gid = nametogid(unixgrp)) == (gid_t)-1 ) {
+ d_printf("Can't lookup UNIX group %s\n", ntgroup);
+ return -1;
+ }
+
+ if ( (rid == 0) && (string_sid[0] == '\0') ) {
+ d_printf("No rid or sid specified, choosing algorithmic mapping\n");
+ rid = pdb_gid_to_group_rid(gid);
+ }
+
/* append the rid to our own domain/machine SID if we don't have a full SID */
if ( !string_sid[0] ) {
sid_copy(&sid, get_global_sam_sid());
@@ -267,11 +277,6 @@ static int net_groupmap_add(int argc, const char **argv)
if (ntcomment[0])
fstrcpy(ntcomment, "Local Unix group");
- if ( (gid = nametogid(unixgrp)) == (gid_t)-1 ) {
- d_printf("Can't lookup UNIX group %s\n", ntgroup);
- return -1;
- }
-
if ( !ntgroup[0] )
fstrcpy( ntgroup, unixgrp );
diff --git a/source/utils/net_idmap.c b/source/utils/net_idmap.c
index 689d4ff8137..b035d8d2f1b 100644
--- a/source/utils/net_idmap.c
+++ b/source/utils/net_idmap.c
@@ -95,10 +95,14 @@ static int net_idmap_restore(int argc, const char **argv)
if ( (len > 0) && (line[len-1] == '\n') )
line[len-1] = '\0';
+ /* Yuck - this is broken for sizeof(gid_t) != sizeof(int) */
+
if (sscanf(line, "GID %d %s", &id.gid, sid_string) == 2) {
type = ID_GROUPID;
}
+ /* Yuck - this is broken for sizeof(uid_t) != sizeof(int) */
+
if (sscanf(line, "UID %d %s", &id.uid, sid_string) == 2) {
type = ID_USERID;
}
@@ -114,9 +118,10 @@ static int net_idmap_restore(int argc, const char **argv)
}
if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, type))) {
- d_printf("Could not set mapping of %s %d to sid %s\n",
+ d_printf("Could not set mapping of %s %lu to sid %s\n",
(type == ID_GROUPID) ? "GID" : "UID",
- (type == ID_GROUPID) ? id.gid : id.uid,
+ (type == ID_GROUPID) ? (unsigned long)id.gid:
+ (unsigned long)id.uid,
sid_string_static(&sid));
continue;
}
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index 890d4a012b1..36d135c73d1 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -84,7 +84,14 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class,
domain_name, domain_sid);
if (!NT_STATUS_IS_OK(result)) {
- goto error;
+ error:
+ fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ fprintf(stderr, "error: %s\n", nt_errstr(result));
+ }
+
+ exit(1);
}
cli_lsa_close(cli, mem_ctx, &pol);
@@ -92,15 +99,6 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
talloc_destroy(mem_ctx);
return domain_sid;
-
- error:
- fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
-
- if (!NT_STATUS_IS_OK(result)) {
- fprintf(stderr, "error: %s\n", nt_errstr(result));
- }
-
- exit(1);
}
/**
@@ -1782,7 +1780,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
/* find the domain controller */
if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
- DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
+ DEBUG(0, ("Couldn't find domain controller for domain %s\n", domain_name));
return -1;
}
@@ -1988,8 +1986,8 @@ static int rpc_trustdom_list(int argc, const char **argv)
POLICY_HND connect_hnd;
/* trusted domains listing variables */
- int enum_ctx = 0;
- int num_domains, i, pad_len, col_len = 20;
+ unsigned int num_domains, enum_ctx = 0;
+ int i, pad_len, col_len = 20;
DOM_SID *domain_sids;
char **trusted_dom_names;
fstring pdc_name, dummy;
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index e5e9a68b2ec..ed69f8a326b 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -400,8 +400,7 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
return NT_STATUS_OK;
}
-static NTSTATUS
-fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
+static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
{
NTSTATUS nt_ret;
fstring account;
@@ -429,6 +428,7 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
(delta->acb_info & ACB_DOMTRUST) ) {
pstrcpy(add_script, lp_addmachine_script());
} else {
+ *add_script = '\0';
DEBUG(1, ("Unknown user type: %s\n",
smbpasswd_encode_acb_info(delta->acb_info)));
}
@@ -439,8 +439,7 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
add_ret = smbrun(add_script,NULL);
DEBUG(1,("fetch_account: Running the command `%s' "
"gave %d\n", add_script, add_ret));
- }
- else {
+ } else {
DEBUG(8,("fetch_account_info: no add user/machine script. Asking winbindd\n"));
/* don't need a RID allocated since the user already has a SID */
@@ -487,8 +486,8 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
} else {
if (map.gid != passwd->pw_gid) {
if (!(grp = getgrgid(map.gid))) {
- DEBUG(0, ("Could not find unix group %d for user %s (group SID=%s)\n",
- map.gid, pdb_get_username(sam_account), sid_string_static(&group_sid)));
+ DEBUG(0, ("Could not find unix group %lu for user %s (group SID=%s)\n",
+ (unsigned long)map.gid, pdb_get_username(sam_account), sid_string_static(&group_sid)));
} else {
smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account));
}
@@ -551,7 +550,11 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
map.sid = group_sid;
map.sid_name_use = SID_NAME_DOM_GRP;
fstrcpy(map.nt_name, name);
- fstrcpy(map.comment, comment);
+ if (delta->hdr_grp_desc.buffer) {
+ fstrcpy(map.comment, comment);
+ } else {
+ fstrcpy(map.comment, "");
+ }
if (insert)
pdb_add_group_mapping_entry(&map);
@@ -585,7 +588,7 @@ fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta)
}
if (!(grp = getgrgid(map.gid))) {
- DEBUG(0, ("Could not find unix group %d\n", map.gid));
+ DEBUG(0, ("Could not find unix group %lu\n", (unsigned long)map.gid));
return NT_STATUS_NO_SUCH_GROUP;
}
@@ -912,9 +915,40 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
fetch_alias_mem(hdr_delta->target_rid,
&delta->als_mem_info, dom_sid);
break;
+ /* The following types are recognised but not handled */
case SAM_DELTA_DOMAIN_INFO:
d_printf("SAM_DELTA_DOMAIN_INFO not handled\n");
break;
+ case SAM_DELTA_RENAME_GROUP:
+ d_printf("SAM_DELTA_RENAME_GROUP not handled\n");
+ break;
+ case SAM_DELTA_RENAME_USER:
+ d_printf("SAM_DELTA_RENAME_USER not handled\n");
+ break;
+ case SAM_DELTA_RENAME_ALIAS:
+ d_printf("SAM_DELTA_RENAME_ALIAS not handled\n");
+ break;
+ case SAM_DELTA_POLICY_INFO:
+ d_printf("SAM_DELTA_POLICY_INFO not handled\n");
+ break;
+ case SAM_DELTA_TRUST_DOMS:
+ d_printf("SAM_DELTA_TRUST_DOMS not handled\n");
+ break;
+ case SAM_DELTA_PRIVS_INFO:
+ d_printf("SAM_DELTA_PRIVS_INFO not handled\n");
+ break;
+ case SAM_DELTA_SECRET_INFO:
+ d_printf("SAM_DELTA_SECRET_INFO not handled\n");
+ break;
+ case SAM_DELTA_DELETE_GROUP:
+ d_printf("SAM_DELTA_DELETE_GROUP not handled\n");
+ break;
+ case SAM_DELTA_DELETE_USER:
+ d_printf("SAM_DELTA_DELETE_USER not handled\n");
+ break;
+ case SAM_DELTA_MODIFIED_COUNT:
+ d_printf("SAM_DELTA_MODIFIED_COUNT not handled\n");
+ break;
default:
d_printf("Unknown delta record type %d\n", hdr_delta->type);
break;
diff --git a/source/utils/net_time.c b/source/utils/net_time.c
index 40619a0796d..45c17838055 100644
--- a/source/utils/net_time.c
+++ b/source/utils/net_time.c
@@ -71,12 +71,12 @@ static time_t nettime(int *zone)
/* return a time as a string ready to be passed to /bin/date */
static char *systime(time_t t)
{
- static char s[100];
+ static fstring s;
struct tm *tm;
tm = localtime(&t);
- snprintf(s, sizeof(s), "%02d%02d%02d%02d%04d.%02d",
+ fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d",
tm->tm_mon+1, tm->tm_mday, tm->tm_hour,
tm->tm_min, tm->tm_year + 1900, tm->tm_sec);
return s;
diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c
index 3dfa157bdab..7cd7e0b0875 100644
--- a/source/utils/ntlm_auth.c
+++ b/source/utils/ntlm_auth.c
@@ -32,7 +32,9 @@
enum squid_mode {
SQUID_2_4_BASIC,
SQUID_2_5_BASIC,
- SQUID_2_5_NTLMSSP
+ SQUID_2_5_NTLMSSP,
+ GSS_SPNEGO,
+ GSS_SPNEGO_CLIENT
};
@@ -198,10 +200,24 @@ static NTSTATUS contact_winbind_auth_crap(const char *username,
request.flags = flags;
- fstrcpy(request.data.auth_crap.user, username);
+ if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
+ *error_string = smb_xstrdup(
+ "unable to create utf8 string for username");
+ return NT_STATUS_UNSUCCESSFUL;
+ }
- fstrcpy(request.data.auth_crap.domain, domain);
- fstrcpy(request.data.auth_crap.workstation, workstation);
+ if (push_utf8_fstring(request.data.auth_crap.domain, domain) == -1) {
+ *error_string = smb_xstrdup(
+ "unable to create utf8 string for domain");
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (push_utf8_fstring(request.data.auth_crap.workstation,
+ workstation) == -1) {
+ *error_string = smb_xstrdup(
+ "unable to create utf8 string for workstation");
+ return NT_STATUS_UNSUCCESSFUL;
+ }
memcpy(request.data.auth_crap.chal, challenge->data, MIN(challenge->length, 8));
@@ -294,7 +310,7 @@ static void manage_squid_ntlmssp_request(enum squid_mode squid_mode,
}
DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, request.data, request.length);
+ dump_data(10, (const char *)request.data, request.length);
nt_status = ntlmssp_server_update(ntlmssp_state, request, &reply);
@@ -342,6 +358,677 @@ static void manage_squid_basic_request(enum squid_mode squid_mode,
}
}
+static void offer_gss_spnego_mechs(void) {
+
+ DATA_BLOB token;
+ SPNEGO_DATA spnego;
+ ssize_t len;
+ char *reply_base64;
+
+ pstring principal;
+ pstring myname_lower;
+
+ ZERO_STRUCT(spnego);
+
+ pstrcpy(myname_lower, global_myname());
+ strlower_m(myname_lower);
+
+ pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm());
+
+ /* Server negTokenInit (mech offerings) */
+ spnego.type = SPNEGO_NEG_TOKEN_INIT;
+ spnego.negTokenInit.mechTypes = smb_xmalloc(sizeof(char *) * 3);
+#ifdef HAVE_KRB5
+ spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD);
+ spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP);
+ spnego.negTokenInit.mechTypes[2] = NULL;
+#else
+ spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_NTLMSSP);
+ spnego.negTokenInit.mechTypes[1] = NULL;
+#endif
+
+
+ spnego.negTokenInit.mechListMIC = data_blob(principal,
+ strlen(principal));
+
+ len = write_spnego_data(&token, &spnego);
+ free_spnego_data(&spnego);
+
+ if (len == -1) {
+ DEBUG(1, ("Could not write SPNEGO data blob\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ reply_base64 = base64_encode_data_blob(token);
+ x_fprintf(x_stdout, "TT %s *\n", reply_base64);
+
+ SAFE_FREE(reply_base64);
+ data_blob_free(&token);
+ DEBUG(10, ("sent SPNEGO negTokenInit\n"));
+ return;
+}
+
+static void manage_gss_spnego_request(enum squid_mode squid_mode,
+ char *buf, int length)
+{
+ static NTLMSSP_STATE *ntlmssp_state = NULL;
+ SPNEGO_DATA request, response;
+ DATA_BLOB token;
+ NTSTATUS status;
+ ssize_t len;
+
+ char *user = NULL;
+ char *domain = NULL;
+
+ const char *reply_code;
+ char *reply_base64;
+ pstring reply_argument;
+
+ if (strlen(buf) < 2) {
+
+ if (ntlmssp_state != NULL) {
+ DEBUG(1, ("Request for initial SPNEGO request where "
+ "we already have a state\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ if ( (strlen(buf) == 2) && (strcmp(buf, "YR") == 0) ) {
+
+ /* Initial request, get the negTokenInit offering
+ mechanisms */
+
+ offer_gss_spnego_mechs();
+ return;
+ }
+
+ /* All subsequent requests are "KK" (Knock, Knock ;)) and have
+ a blob. This might be negTokenInit or negTokenTarg */
+
+ if ( (strlen(buf) <= 3) || (strncmp(buf, "KK", 2) != 0) ) {
+ DEBUG(1, ("GSS-SPNEGO query [%s] invalid\n", buf));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ token = base64_decode_data_blob(buf + 3);
+ len = read_spnego_data(token, &request);
+ data_blob_free(&token);
+
+ if (len == -1) {
+ DEBUG(1, ("GSS-SPNEGO query [%s] invalid", buf));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ if (request.type == SPNEGO_NEG_TOKEN_INIT) {
+
+ /* Second request from Client. This is where the
+ client offers its mechanism to use. We currently
+ only support NTLMSSP, the decision for Kerberos
+ would be taken here. */
+
+ if ( (request.negTokenInit.mechTypes == NULL) ||
+ (request.negTokenInit.mechTypes[0] == NULL) ) {
+ DEBUG(1, ("Client did not offer any mechanism"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) {
+
+ if ( request.negTokenInit.mechToken.data == NULL ) {
+ DEBUG(1, ("Client did not provide NTLMSSP data\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ if ( ntlmssp_state != NULL ) {
+ DEBUG(1, ("Client wants a new NTLMSSP challenge, but "
+ "already got one\n"));
+ x_fprintf(x_stdout, "BH\n");
+ ntlmssp_server_end(&ntlmssp_state);
+ return;
+ }
+
+ ntlmssp_server_start(&ntlmssp_state);
+ ntlmssp_state->check_password = winbind_pw_check;
+ ntlmssp_state->get_domain = get_winbind_domain;
+ ntlmssp_state->get_global_myname = get_winbind_netbios_name;
+
+ DEBUG(10, ("got NTLMSSP packet:\n"));
+ dump_data(10, (const char *)request.negTokenInit.mechToken.data,
+ request.negTokenInit.mechToken.length);
+
+ response.type = SPNEGO_NEG_TOKEN_TARG;
+ response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
+ response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+
+ status = ntlmssp_server_update(ntlmssp_state,
+ request.negTokenInit.mechToken,
+ &response.negTokenTarg.responseToken);
+ }
+
+#ifdef HAVE_KRB5
+ if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) {
+
+ char *principal;
+ DATA_BLOB auth_data;
+ DATA_BLOB ap_rep;
+ uint8 session_key[16];
+
+ if ( request.negTokenInit.mechToken.data == NULL ) {
+ DEBUG(1, ("Client did not provide Kerberos data\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ response.type = SPNEGO_NEG_TOKEN_TARG;
+ response.negTokenTarg.supportedMech = strdup(OID_KERBEROS5_OLD);
+ response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+ response.negTokenTarg.responseToken = data_blob(NULL, 0);
+
+ status = ads_verify_ticket(lp_realm(),
+ &request.negTokenInit.mechToken,
+ &principal, &auth_data, &ap_rep,
+ session_key);
+
+ /* Now in "principal" we have the name we are
+ authenticated as. */
+
+ if (NT_STATUS_IS_OK(status)) {
+
+ domain = strchr(principal, '@');
+
+ if (domain == NULL) {
+ DEBUG(1, ("Did not get a valid principal "
+ "from ads_verify_ticket\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ *domain++ = '\0';
+ domain = strdup(domain);
+ user = strdup(principal);
+
+ data_blob_free(&ap_rep);
+ data_blob_free(&auth_data);
+
+ SAFE_FREE(principal);
+ }
+ }
+#endif
+
+ } else {
+
+ if ( (request.negTokenTarg.supportedMech == NULL) ||
+ ( strcmp(request.negTokenTarg.supportedMech, OID_NTLMSSP) != 0 ) ) {
+ /* Kerberos should never send a negTokenTarg, OID_NTLMSSP
+ is the only one we support that sends this stuff */
+ DEBUG(1, ("Got a negTokenTarg for something non-NTLMSSP: %s\n",
+ request.negTokenTarg.supportedMech));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ if (request.negTokenTarg.responseToken.data == NULL) {
+ DEBUG(1, ("Got a negTokenTarg without a responseToken!\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ status = ntlmssp_server_update(ntlmssp_state,
+ request.negTokenTarg.responseToken,
+ &response.negTokenTarg.responseToken);
+
+ response.type = SPNEGO_NEG_TOKEN_TARG;
+ response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
+ response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+
+ if (NT_STATUS_IS_OK(status)) {
+ user = strdup(ntlmssp_state->user);
+ domain = strdup(ntlmssp_state->domain);
+ ntlmssp_server_end(&ntlmssp_state);
+ }
+ }
+
+ free_spnego_data(&request);
+
+ if (NT_STATUS_IS_OK(status)) {
+ response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
+ reply_code = "AF";
+ pstr_sprintf(reply_argument, "%s\\%s", domain, user);
+ } else if (NT_STATUS_EQUAL(status,
+ NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ response.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
+ reply_code = "TT";
+ pstr_sprintf(reply_argument, "*");
+ } else {
+ response.negTokenTarg.negResult = SPNEGO_REJECT;
+ reply_code = "NA";
+ pstrcpy(reply_argument, nt_errstr(status));
+ }
+
+ SAFE_FREE(user);
+ SAFE_FREE(domain);
+
+ len = write_spnego_data(&token, &response);
+ free_spnego_data(&response);
+
+ if (len == -1) {
+ DEBUG(1, ("Could not write SPNEGO data blob\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ reply_base64 = base64_encode_data_blob(token);
+
+ x_fprintf(x_stdout, "%s %s %s\n",
+ reply_code, reply_base64, reply_argument);
+
+ SAFE_FREE(reply_base64);
+ data_blob_free(&token);
+
+ return;
+}
+
+static NTLMSSP_CLIENT_STATE *client_ntlmssp_state = NULL;
+
+static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
+{
+ NTSTATUS status;
+ DATA_BLOB null_blob = data_blob(NULL, 0);
+ DATA_BLOB to_server;
+ char *to_server_base64;
+ const char *my_mechs[] = {OID_NTLMSSP, NULL};
+
+ DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n"));
+
+ if (client_ntlmssp_state != NULL) {
+ DEBUG(1, ("Request for initial SPNEGO request where "
+ "we already have a state\n"));
+ return False;
+ }
+
+ if ( (opt_username == NULL) || (opt_domain == NULL) ) {
+ DEBUG(1, ("Need username and domain for NTLMSSP\n"));
+ return False;
+ }
+
+ if (opt_password == NULL) {
+
+ /* Request a password from the calling process. After
+ sending it, the calling process should retry with
+ the negTokenInit. */
+
+ DEBUG(10, ("Requesting password\n"));
+ x_fprintf(x_stdout, "PW\n");
+ return True;
+ }
+
+ status = ntlmssp_client_start(&client_ntlmssp_state);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Could not start NTLMSSP client: %s\n",
+ nt_errstr(status)));
+ ntlmssp_client_end(&client_ntlmssp_state);
+ return False;
+ }
+
+ status = ntlmssp_set_username(client_ntlmssp_state, opt_username);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Could not set username: %s\n",
+ nt_errstr(status)));
+ ntlmssp_client_end(&client_ntlmssp_state);
+ return False;
+ }
+
+ status = ntlmssp_set_domain(client_ntlmssp_state, opt_domain);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Could not set domain: %s\n",
+ nt_errstr(status)));
+ ntlmssp_client_end(&client_ntlmssp_state);
+ return False;
+ }
+
+ status = ntlmssp_set_password(client_ntlmssp_state, opt_password);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Could not set password: %s\n",
+ nt_errstr(status)));
+ ntlmssp_client_end(&client_ntlmssp_state);
+ return False;
+ }
+
+ spnego.type = SPNEGO_NEG_TOKEN_INIT;
+ spnego.negTokenInit.mechTypes = my_mechs;
+ spnego.negTokenInit.reqFlags = 0;
+ spnego.negTokenInit.mechListMIC = null_blob;
+
+ status = ntlmssp_client_update(client_ntlmssp_state, null_blob,
+ &spnego.negTokenInit.mechToken);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n",
+ nt_errstr(status)));
+ ntlmssp_client_end(&client_ntlmssp_state);
+ return False;
+ }
+
+ write_spnego_data(&to_server, &spnego);
+ data_blob_free(&spnego.negTokenInit.mechToken);
+
+ to_server_base64 = base64_encode_data_blob(to_server);
+ data_blob_free(&to_server);
+ x_fprintf(x_stdout, "KK %s\n", to_server_base64);
+ SAFE_FREE(to_server_base64);
+ return True;
+}
+
+static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
+{
+ NTSTATUS status;
+ DATA_BLOB null_blob = data_blob(NULL, 0);
+ DATA_BLOB request;
+ DATA_BLOB to_server;
+ char *to_server_base64;
+
+ DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n"));
+
+ if (client_ntlmssp_state == NULL) {
+ DEBUG(1, ("Got NTLMSSP tArg without a client state\n"));
+ x_fprintf(x_stdout, "BH\n");
+ ntlmssp_client_end(&client_ntlmssp_state);
+ return;
+ }
+
+ if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) {
+ x_fprintf(x_stdout, "NA\n");
+ ntlmssp_client_end(&client_ntlmssp_state);
+ return;
+ }
+
+ if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {
+ x_fprintf(x_stdout, "AF\n");
+ ntlmssp_client_end(&client_ntlmssp_state);
+ return;
+ }
+
+ status = ntlmssp_client_update(client_ntlmssp_state,
+ spnego.negTokenTarg.responseToken,
+ &request);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED from "
+ "ntlmssp_client_update, got: %s\n",
+ nt_errstr(status)));
+ x_fprintf(x_stdout, "BH\n");
+ data_blob_free(&request);
+ ntlmssp_client_end(&client_ntlmssp_state);
+ return;
+ }
+
+ spnego.type = SPNEGO_NEG_TOKEN_TARG;
+ spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
+ spnego.negTokenTarg.supportedMech = OID_NTLMSSP;
+ spnego.negTokenTarg.responseToken = request;
+ spnego.negTokenTarg.mechListMIC = null_blob;
+
+ write_spnego_data(&to_server, &spnego);
+ data_blob_free(&request);
+
+ to_server_base64 = base64_encode_data_blob(to_server);
+ data_blob_free(&to_server);
+ x_fprintf(x_stdout, "KK %s\n", to_server_base64);
+ SAFE_FREE(to_server_base64);
+ return;
+}
+
+#ifdef HAVE_KRB5
+
+static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
+{
+ char *principal;
+ DATA_BLOB tkt, to_server;
+ unsigned char session_key_krb5[16];
+ SPNEGO_DATA reply;
+ char *reply_base64;
+
+ const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};
+ ssize_t len;
+
+ if ( (spnego.negTokenInit.mechListMIC.data == NULL) ||
+ (spnego.negTokenInit.mechListMIC.length == 0) ) {
+ DEBUG(1, ("Did not get a principal for krb5\n"));
+ return False;
+ }
+
+ principal = malloc(spnego.negTokenInit.mechListMIC.length+1);
+
+ if (principal == NULL) {
+ DEBUG(1, ("Could not malloc principal\n"));
+ return False;
+ }
+
+ memcpy(principal, spnego.negTokenInit.mechListMIC.data,
+ spnego.negTokenInit.mechListMIC.length);
+ principal[spnego.negTokenInit.mechListMIC.length] = '\0';
+
+ tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5);
+
+ if (tkt.data == NULL) {
+
+ pstring user;
+
+ /* Let's try to first get the TGT, for that we need a
+ password. */
+
+ if (opt_password == NULL) {
+ DEBUG(10, ("Requesting password\n"));
+ x_fprintf(x_stdout, "PW\n");
+ return True;
+ }
+
+ pstr_sprintf(user, "%s@%s", opt_username, opt_domain);
+
+ if (kerberos_kinit_password(user, opt_password, 0) != 0) {
+ DEBUG(10, ("Requesting TGT failed\n"));
+ x_fprintf(x_stdout, "NA\n");
+ return True;
+ }
+
+ tkt = cli_krb5_get_ticket(principal, 0, session_key_krb5);
+ }
+
+ ZERO_STRUCT(reply);
+
+ reply.type = SPNEGO_NEG_TOKEN_INIT;
+ reply.negTokenInit.mechTypes = my_mechs;
+ reply.negTokenInit.reqFlags = 0;
+ reply.negTokenInit.mechToken = tkt;
+ reply.negTokenInit.mechListMIC = data_blob(NULL, 0);
+
+ len = write_spnego_data(&to_server, &reply);
+ data_blob_free(&tkt);
+
+ if (len == -1) {
+ DEBUG(1, ("Could not write SPNEGO data blob\n"));
+ return False;
+ }
+
+ reply_base64 = base64_encode_data_blob(to_server);
+ x_fprintf(x_stdout, "KK %s *\n", reply_base64);
+
+ SAFE_FREE(reply_base64);
+ data_blob_free(&to_server);
+ DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n"));
+ return True;
+}
+
+static void manage_client_krb5_targ(SPNEGO_DATA spnego)
+{
+ switch (spnego.negTokenTarg.negResult) {
+ case SPNEGO_ACCEPT_INCOMPLETE:
+ DEBUG(1, ("Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n"));
+ x_fprintf(x_stdout, "BH\n");
+ break;
+ case SPNEGO_ACCEPT_COMPLETED:
+ DEBUG(10, ("Accept completed\n"));
+ x_fprintf(x_stdout, "AF\n");
+ break;
+ case SPNEGO_REJECT:
+ DEBUG(10, ("Rejected\n"));
+ x_fprintf(x_stdout, "NA\n");
+ break;
+ default:
+ DEBUG(1, ("Got an invalid negTokenTarg\n"));
+ x_fprintf(x_stdout, "AF\n");
+ }
+}
+
+#endif
+
+static void manage_gss_spnego_client_request(enum squid_mode squid_mode,
+ char *buf, int length)
+{
+ DATA_BLOB request;
+ SPNEGO_DATA spnego;
+ ssize_t len;
+
+ if (strlen(buf) <= 3) {
+ DEBUG(1, ("SPNEGO query [%s] too short\n", buf));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ request = base64_decode_data_blob(buf+3);
+
+ if (strncmp(buf, "PW ", 3) == 0) {
+
+ /* We asked for a password and obviously got it :-) */
+
+ opt_password = strndup((const char *)request.data, request.length);
+
+ if (opt_password == NULL) {
+ DEBUG(1, ("Out of memory\n"));
+ x_fprintf(x_stdout, "BH\n");
+ data_blob_free(&request);
+ return;
+ }
+
+ x_fprintf(x_stdout, "OK\n");
+ data_blob_free(&request);
+ return;
+ }
+
+ if ( (strncmp(buf, "TT ", 3) != 0) &&
+ (strncmp(buf, "AF ", 3) != 0) &&
+ (strncmp(buf, "NA ", 3) != 0) ) {
+ DEBUG(1, ("SPNEGO request [%s] invalid\n", buf));
+ x_fprintf(x_stdout, "BH\n");
+ data_blob_free(&request);
+ return;
+ }
+
+ /* So we got a server challenge to generate a SPNEGO
+ client-to-server request... */
+
+ len = read_spnego_data(request, &spnego);
+ data_blob_free(&request);
+
+ if (len == -1) {
+ DEBUG(1, ("Could not read SPNEGO data for [%s]\n", buf));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ if (spnego.type == SPNEGO_NEG_TOKEN_INIT) {
+
+ /* The server offers a list of mechanisms */
+
+ const char **mechType = spnego.negTokenInit.mechTypes;
+
+ while (*mechType != NULL) {
+
+#ifdef HAVE_KRB5
+ if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) ||
+ (strcmp(*mechType, OID_KERBEROS5) == 0) ) {
+ if (manage_client_krb5_init(spnego))
+ goto out;
+ }
+#endif
+
+ if (strcmp(*mechType, OID_NTLMSSP) == 0) {
+ if (manage_client_ntlmssp_init(spnego))
+ goto out;
+ }
+
+ mechType++;
+ }
+
+ DEBUG(1, ("Server offered no compatible mechanism\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+
+ if (spnego.type == SPNEGO_NEG_TOKEN_TARG) {
+
+ if (spnego.negTokenTarg.supportedMech == NULL) {
+ /* On accept/reject Windows does not send the
+ mechanism anymore. Handle that here and
+ shut down the mechanisms. */
+
+ switch (spnego.negTokenTarg.negResult) {
+ case SPNEGO_ACCEPT_COMPLETED:
+ x_fprintf(x_stdout, "AF\n");
+ break;
+ case SPNEGO_REJECT:
+ x_fprintf(x_stdout, "NA\n");
+ break;
+ default:
+ DEBUG(1, ("Got a negTokenTarg with no mech and an "
+ "unknown negResult: %d\n",
+ spnego.negTokenTarg.negResult));
+ x_fprintf(x_stdout, "BH\n");
+ }
+
+ ntlmssp_client_end(&client_ntlmssp_state);
+ goto out;
+ }
+
+ if (strcmp(spnego.negTokenTarg.supportedMech,
+ OID_NTLMSSP) == 0) {
+ manage_client_ntlmssp_targ(spnego);
+ goto out;
+ }
+
+#if HAVE_KRB5
+ if (strcmp(spnego.negTokenTarg.supportedMech,
+ OID_KERBEROS5_OLD) == 0) {
+ manage_client_krb5_targ(spnego);
+ goto out;
+ }
+#endif
+
+ }
+
+ DEBUG(1, ("Got an SPNEGO token I could not handle [%s]!\n", buf));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+
+ out:
+ free_spnego_data(&spnego);
+ return;
+}
+
static void manage_squid_request(enum squid_mode squid_mode)
{
char buf[SQUID_BUFFER_SIZE+1];
@@ -383,6 +1070,10 @@ static void manage_squid_request(enum squid_mode squid_mode)
manage_squid_basic_request(squid_mode, buf, length);
} else if (squid_mode == SQUID_2_5_NTLMSSP) {
manage_squid_ntlmssp_request(squid_mode, buf, length);
+ } else if (squid_mode == GSS_SPNEGO) {
+ manage_gss_spnego_request(squid_mode, buf, length);
+ } else if (squid_mode == GSS_SPNEGO_CLIENT) {
+ manage_gss_spnego_client_request(squid_mode, buf, length);
}
}
@@ -424,8 +1115,8 @@ static BOOL check_auth_crap(void)
&opt_lm_response,
&opt_nt_response,
flags,
- lm_key,
- nt_key,
+ (unsigned char *)lm_key,
+ (unsigned char *)nt_key,
&error_string);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -439,7 +1130,7 @@ static BOOL check_auth_crap(void)
if (request_lm_key
&& (memcmp(zeros, lm_key,
sizeof(lm_key)) != 0)) {
- hex_encode(lm_key,
+ hex_encode((const unsigned char *)lm_key,
sizeof(lm_key),
&hex_lm_key);
x_fprintf(x_stdout, "LM_KEY: %s\n", hex_lm_key);
@@ -448,7 +1139,7 @@ static BOOL check_auth_crap(void)
if (request_nt_key
&& (memcmp(zeros, nt_key,
sizeof(nt_key)) != 0)) {
- hex_encode(nt_key,
+ hex_encode((const unsigned char *)nt_key,
sizeof(nt_key),
&hex_nt_key);
x_fprintf(x_stdout, "NT_KEY: %s\n", hex_nt_key);
@@ -522,16 +1213,16 @@ static BOOL test_lm(void)
sizeof(lm_key)) != 0) {
DEBUG(1, ("LM Key does not match expectations!\n"));
DEBUG(1, ("lm_key:\n"));
- dump_data(1, lm_key, 8);
+ dump_data(1, (const char *)lm_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
}
if (memcmp(lm_hash, nt_key, 8) != 0) {
DEBUG(1, ("Session Key (first 8, lm hash) does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 8);
+ dump_data(1, (const char *)nt_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
}
return True;
}
@@ -594,18 +1285,18 @@ static BOOL test_lm_ntlm(void)
sizeof(lm_key)) != 0) {
DEBUG(1, ("LM Key does not match expectations!\n"));
DEBUG(1, ("lm_key:\n"));
- dump_data(1, lm_key, 8);
+ dump_data(1, (const char *)lm_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
pass = False;
}
if (memcmp(session_key.data, nt_key,
sizeof(nt_key)) != 0) {
DEBUG(1, ("NT Session Key does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, session_key.data, session_key.length);
+ dump_data(1, (const char *)session_key.data, session_key.length);
pass = False;
}
return pass;
@@ -637,10 +1328,10 @@ static BOOL test_ntlm(void)
flags |= WBFLAG_PAM_NTKEY;
SMBNTencrypt(opt_password,chall.data,nt_response.data);
- E_md4hash(opt_password, nt_hash);
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+ E_md4hash(opt_password, (unsigned char *)nt_hash);
+ SMBsesskeygen_ntv1((const unsigned char *)nt_hash, NULL, session_key.data);
- E_deshash(opt_password, lm_hash);
+ E_deshash(opt_password, (unsigned char *)lm_hash);
nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
opt_workstation,
@@ -648,8 +1339,8 @@ static BOOL test_ntlm(void)
NULL,
&nt_response,
flags,
- lm_key,
- nt_key,
+ (unsigned char *)lm_key,
+ (unsigned char *)nt_key,
&error_string);
data_blob_free(&nt_response);
@@ -677,7 +1368,7 @@ static BOOL test_ntlm(void)
DEBUG(1, ("nt_key:\n"));
dump_data(1, nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, session_key.data, session_key.length);
+ dump_data(1, (const char *)session_key.data, session_key.length);
pass = False;
}
return pass;
@@ -733,17 +1424,17 @@ static BOOL test_ntlm_in_lm(void)
sizeof(lm_key)) != 0) {
DEBUG(1, ("LM Key does not match expectations!\n"));
DEBUG(1, ("lm_key:\n"));
- dump_data(1, lm_key, 8);
+ dump_data(1, (const char *)lm_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
pass = False;
}
if (memcmp(lm_hash, nt_key, 8) != 0) {
DEBUG(1, ("Session Key (first 8 lm hash) does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
pass = False;
}
return pass;
@@ -775,10 +1466,10 @@ static BOOL test_ntlm_in_both(void)
flags |= WBFLAG_PAM_NTKEY;
SMBNTencrypt(opt_password,chall.data,nt_response.data);
- E_md4hash(opt_password, nt_hash);
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+ E_md4hash(opt_password, (unsigned char *)nt_hash);
+ SMBsesskeygen_ntv1((const unsigned char *)nt_hash, NULL, session_key.data);
- E_deshash(opt_password, lm_hash);
+ E_deshash(opt_password, (unsigned char *)lm_hash);
nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
opt_workstation,
@@ -786,8 +1477,8 @@ static BOOL test_ntlm_in_both(void)
&nt_response,
&nt_response,
flags,
- lm_key,
- nt_key,
+ (unsigned char *)lm_key,
+ (unsigned char *)nt_key,
&error_string);
data_blob_free(&nt_response);
@@ -815,7 +1506,7 @@ static BOOL test_ntlm_in_both(void)
DEBUG(1, ("nt_key:\n"));
dump_data(1, nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, session_key.data, session_key.length);
+ dump_data(1, (const char *)session_key.data, session_key.length);
pass = False;
}
@@ -877,9 +1568,9 @@ static BOOL test_ntlmv2(void)
sizeof(nt_key)) != 0) {
DEBUG(1, ("NT Session Key does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, nt_session_key.data, nt_session_key.length);
+ dump_data(1, (const char *)nt_session_key.data, nt_session_key.length);
pass = False;
}
return pass;
@@ -941,9 +1632,9 @@ static BOOL test_lmv2_ntlmv2(void)
sizeof(nt_key)) != 0) {
DEBUG(1, ("NT Session Key does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, nt_session_key.data, nt_session_key.length);
+ dump_data(1, (const char *)nt_session_key.data, nt_session_key.length);
pass = False;
}
return pass;
@@ -1056,18 +1747,18 @@ static BOOL test_ntlm_broken(BOOL break_lm)
sizeof(lm_key)) != 0) {
DEBUG(1, ("LM Key does not match expectations!\n"));
DEBUG(1, ("lm_key:\n"));
- dump_data(1, lm_key, 8);
+ dump_data(1, (const char *)lm_key, 8);
DEBUG(1, ("expected:\n"));
- dump_data(1, lm_hash, 8);
+ dump_data(1, (const char *)lm_hash, 8);
pass = False;
}
if (memcmp(session_key.data, nt_key,
sizeof(nt_key)) != 0) {
DEBUG(1, ("NT Session Key does not match expectations!\n"));
DEBUG(1, ("nt_key:\n"));
- dump_data(1, nt_key, 16);
+ dump_data(1, (const char *)nt_key, 16);
DEBUG(1, ("expected:\n"));
- dump_data(1, session_key.data, session_key.length);
+ dump_data(1, (const char *)session_key.data, session_key.length);
pass = False;
}
return pass;
@@ -1334,6 +2025,10 @@ enum {
squid_stream(SQUID_2_5_BASIC);
} else if (strcmp(helper_protocol, "squid-2.4-basic")== 0) {
squid_stream(SQUID_2_4_BASIC);
+ } else if (strcmp(helper_protocol, "gss-spnego")== 0) {
+ squid_stream(GSS_SPNEGO);
+ } else if (strcmp(helper_protocol, "gss-spnego-client") == 0) {
+ squid_stream(GSS_SPNEGO_CLIENT);
} else {
x_fprintf(x_stderr, "unknown helper protocol [%s]\n", helper_protocol);
exit(1);
@@ -1372,7 +2067,7 @@ enum {
} else {
fstring user;
- snprintf(user, sizeof(user)-1, "%s%c%s", opt_domain, winbind_separator(), opt_username);
+ fstr_sprintf(user, "%s%c%s", opt_domain, winbind_separator(), opt_username);
if (!check_plaintext_auth(user, opt_password, True)) {
exit(1);
}
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index 96d0d3c057f..0f1f6edf086 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -51,21 +51,6 @@
#define MASK_ALWAYS_GOOD 0x0000001F
#define MASK_USER_GOOD 0x00401F00
-/*****************************************************************************
- stubb functions
-****************************************************************************/
-
-void become_root( void )
-{
- return;
-}
-
-void unbecome_root( void )
-{
- return;
-}
-
-
/*********************************************************
Add all currently available users to another db
********************************************************/
@@ -176,16 +161,17 @@ static int print_sam_info (SAM_ACCOUNT *sam_pwent, BOOL verbosity, BOOL smbpwdst
pdb_sethexpwd(lm_passwd, pdb_get_lanman_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
pdb_sethexpwd(nt_passwd, pdb_get_nt_passwd(sam_pwent), pdb_get_acct_ctrl(sam_pwent));
- printf("%s:%d:%s:%s:%s:LCT-%08X:\n",
+ printf("%s:%lu:%s:%s:%s:LCT-%08X:\n",
pdb_get_username(sam_pwent),
- uid,
+ (unsigned long)uid,
lm_passwd,
nt_passwd,
pdb_encode_acct_ctrl(pdb_get_acct_ctrl(sam_pwent),NEW_PW_FORMAT_SPACE_PADDED_LEN),
(uint32)pdb_get_pass_last_set_time(sam_pwent));
} else {
uid = nametouid(pdb_get_username(sam_pwent));
- printf ("%s:%d:%s\n", pdb_get_username(sam_pwent), uid, pdb_get_fullname(sam_pwent));
+ printf ("%s:%lu:%s\n", pdb_get_username(sam_pwent), (unsigned long)uid,
+ pdb_get_fullname(sam_pwent));
}
return 0;
diff --git a/source/utils/profiles.c b/source/utils/profiles.c
index 23df26d1502..3230eb21fc8 100644
--- a/source/utils/profiles.c
+++ b/source/utils/profiles.c
@@ -448,7 +448,7 @@ static int get_sid(DOM_SID *sid, const unsigned char *sid_str)
SIVAL(&sid->sub_auths[i], 0, auth);
i++;
- lstr = strchr(lstr + 1, '-');
+ lstr = (const unsigned char *)strchr(lstr + 1, '-');
}
return 1;
diff --git a/source/utils/smbcacls.c b/source/utils/smbcacls.c
index 69dc2dd47a5..c90c042106e 100644
--- a/source/utils/smbcacls.c
+++ b/source/utils/smbcacls.c
@@ -724,7 +724,8 @@ static struct cli_state *connect_one(const char *share)
&ip, 0,
share, "?????",
cmdline_auth_info.username, lp_workgroup(),
- cmdline_auth_info.password, 0, NULL))) {
+ cmdline_auth_info.password, 0,
+ cmdline_auth_info.signing_state, NULL))) {
return c;
} else {
DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
diff --git a/source/utils/smbcontrol.c b/source/utils/smbcontrol.c
index b7333f23176..190627e2a52 100644
--- a/source/utils/smbcontrol.c
+++ b/source/utils/smbcontrol.c
@@ -591,12 +591,6 @@ static const struct {
{ NULL }
};
-/* Yuck - we need these because we link to printing*.o even though
- they aren't used. */
-
-void become_root(void) {}
-void unbecome_root(void) {}
-
/* Display usage information */
static void usage(poptContext *pc)
diff --git a/source/utils/smbcquotas.c b/source/utils/smbcquotas.c
index 9c7379ca2a9..64321d5bfc3 100644
--- a/source/utils/smbcquotas.c
+++ b/source/utils/smbcquotas.c
@@ -371,7 +371,8 @@ static struct cli_state *connect_one(const char *share)
&ip, 0,
share, "?????",
cmdline_auth_info.username, lp_workgroup(),
- cmdline_auth_info.password, 0, NULL))) {
+ cmdline_auth_info.password, 0,
+ cmdline_auth_info.signing_state, NULL))) {
return c;
} else {
DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index eade5331af6..6ab6d35e73b 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -37,21 +37,6 @@ static const char *remote_machine = NULL;
static fstring ldap_secret;
-/*****************************************************************************
- stubb functions
-****************************************************************************/
-
-void become_root( void )
-{
- return;
-}
-
-void unbecome_root( void )
-{
- return;
-}
-
-
/*********************************************************
Print command usage on stderr and die.
**********************************************************/
diff --git a/source/utils/status.c b/source/utils/status.c
index bbaeecdd6bb..8bf67fc4d63 100644
--- a/source/utils/status.c
+++ b/source/utils/status.c
@@ -45,11 +45,6 @@ static int locks_only = 0; /* Added by RJS */
static BOOL processes_only=False;
static int show_brl;
-/* we need these because we link to locking*.o */
- void become_root(void) {}
- void unbecome_root(void) {}
-
-
/* added by OH */
static void Ucrit_addUsername(const char *username)
{
diff --git a/source/utils/testparm.c b/source/utils/testparm.c
index 16918ecd4ae..bb89e4ebf21 100644
--- a/source/utils/testparm.c
+++ b/source/utils/testparm.c
@@ -287,6 +287,27 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
Level II oplocks can only be set if oplocks are also set.\n",
lp_servicename(s) );
}
+
+ if (lp_map_hidden(s) && !(lp_create_mask(s) & S_IXOTH)) {
+ printf("Invalid combination of parameters for service %s. \
+ Map hidden can only work if create mask includes octal 01 (S_IXOTH).\n",
+ lp_servicename(s) );
+ }
+ if (lp_map_hidden(s) && (lp_force_create_mode(s) & S_IXOTH)) {
+ printf("Invalid combination of parameters for service %s. \
+ Map hidden can only work if force create mode excludes octal 01 (S_IXOTH).\n",
+ lp_servicename(s) );
+ }
+ if (lp_map_system(s) && !(lp_create_mask(s) & S_IXGRP)) {
+ printf("Invalid combination of parameters for service %s. \
+ Map hidden can only work if create mask includes octal 010 (S_IXGRP).\n",
+ lp_servicename(s) );
+ }
+ if (lp_map_system(s) && (lp_force_create_mode(s) & S_IXGRP)) {
+ printf("Invalid combination of parameters for service %s. \
+ Map hidden can only work if force create mode excludes octal 010 (S_IXGRP).\n",
+ lp_servicename(s) );
+ }
}
}
diff --git a/source/web/statuspage.c b/source/web/statuspage.c
index 44461232b81..c579e8f1123 100644
--- a/source/web/statuspage.c
+++ b/source/web/statuspage.c
@@ -93,7 +93,7 @@ static char *mapPid2Machine (pid_t pid)
}
/* PID not in list or machine name NULL? return pid as string */
- snprintf (pidbuf, sizeof (pidbuf) - 1, "%d", pid);
+ snprintf (pidbuf, sizeof (pidbuf) - 1, "%lu", (unsigned long)pid);
return pidbuf;
}
diff --git a/source/web/swat.c b/source/web/swat.c
index d97278c4859..a1c132a0885 100644
--- a/source/web/swat.c
+++ b/source/web/swat.c
@@ -51,10 +51,6 @@ static int iNumNonAutoPrintServices = 0;
#define ENABLE_USER_FLAG "enable_user_flag"
#define RHOST "remote_host"
-/* we need these because we link to locking*.o */
- void become_root(void) {}
- void unbecome_root(void) {}
-
/****************************************************************************
****************************************************************************/
static int enum_index(int value, const struct enum_list *enumlist)
@@ -168,12 +164,12 @@ static const char* get_parm_translated(
static pstring output;
if(strcmp(pLabel, pTranslated) != 0)
{
- snprintf(output, sizeof(output),
+ pstr_sprintf(output,
"<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s <br><span class=\"i18n_translated_parm\">%s</span>",
pAnchor, pHelp, pLabel, pTranslated);
return output;
}
- snprintf(output, sizeof(output),
+ pstr_sprintf(output,
"<A HREF=\"/swat/help/smb.conf.5.html#%s\" target=\"docs\"> %s</A>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s",
pAnchor, pHelp, pLabel);
return output;
@@ -316,9 +312,10 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte
if (printers & !(parm->flags & FLAG_PRINT)) continue;
if (!printers & !(parm->flags & FLAG_SHARE)) continue;
}
- if (parm_filter == FLAG_BASIC) {
+
+ if (!( parm_filter & FLAG_ADVANCED )) {
if (!(parm->flags & FLAG_BASIC)) {
- void *ptr = parm->ptr;
+ void *ptr = parm->ptr;
if (parm->class == P_LOCAL && snum >= 0) {
ptr = lp_local_ptr(snum, ptr);
@@ -359,16 +356,15 @@ static void show_parameters(int snum, int allparameters, unsigned int parm_filte
break;
case P_SEP:
continue;
- }
+ }
}
if (printers && !(parm->flags & FLAG_PRINT)) continue;
}
- if (parm_filter == FLAG_WIZARD) {
- if (!((parm->flags & FLAG_WIZARD))) continue;
- }
- if (parm_filter == FLAG_ADVANCED) {
- if (!((parm->flags & FLAG_ADVANCED))) continue;
- }
+
+ if ((parm_filter & FLAG_WIZARD) && !(parm->flags & FLAG_WIZARD)) continue;
+
+ if ((parm_filter & FLAG_ADVANCED) && !(parm->flags & FLAG_ADVANCED)) continue;
+
if (heading && heading != last_heading) {
d_printf("<tr><td></td></tr><tr><td><b><u>%s</u></b></td></tr>\n", _(heading));
last_heading = heading;
@@ -523,10 +519,12 @@ static void show_main_buttons(void)
****************************************************************************/
static void ViewModeBoxes(int mode)
{
- d_printf("<p>%s\n", _("Configuration View:&nbsp"));
+ d_printf("<p>%s\n", _("Current View Is:&nbsp \n"));
d_printf("<input type=radio name=\"ViewMode\" value=0 %s>Basic\n", (mode == 0) ? "checked" : "");
d_printf("<input type=radio name=\"ViewMode\" value=1 %s>Advanced\n", (mode == 1) ? "checked" : "");
- d_printf("<input type=radio name=\"ViewMode\" value=2 %s>Developer\n", (mode == 2) ? "checked" : "");
+ d_printf("<br>%s\n", _("Change View To:&nbsp"));
+ d_printf("<input type=submit name=\"BasicMode\" value=\"%s\">\n", _("Basic"));
+ d_printf("<input type=submit name=\"AdvMode\" value=\"%s\">\n", _("Advanced"));
d_printf("</p><br>\n");
}
@@ -782,6 +780,10 @@ static void globals_page(void)
if ( cgi_variable("ViewMode") )
mode = atoi(cgi_variable("ViewMode"));
+ if ( cgi_variable("BasicMode"))
+ mode = 0;
+ if ( cgi_variable("AdvMode"))
+ mode = 1;
d_printf("<form name=\"swatform\" method=post action=globals>\n");
@@ -793,9 +795,6 @@ static void globals_page(void)
case 1:
parm_filter = FLAG_ADVANCED;
break;
- case 2:
- parm_filter = FLAG_DEVELOPER;
- break;
}
d_printf("<br>\n");
if (have_write_access) {
@@ -854,8 +853,14 @@ static void shares_page(void)
d_printf("<FORM name=\"swatform\" method=post>\n");
d_printf("<table>\n");
+
if ( cgi_variable("ViewMode") )
mode = atoi(cgi_variable("ViewMode"));
+ if ( cgi_variable("BasicMode"))
+ mode = 0;
+ if ( cgi_variable("AdvMode"))
+ mode = 1;
+
ViewModeBoxes( mode );
switch ( mode ) {
case 0:
@@ -864,9 +869,6 @@ static void shares_page(void)
case 1:
parm_filter = FLAG_ADVANCED;
break;
- case 2:
- parm_filter = FLAG_DEVELOPER;
- break;
}
d_printf("<br><tr>\n");
d_printf("<td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Share"));
@@ -1196,6 +1198,11 @@ static void printers_page(void)
if ( cgi_variable("ViewMode") )
mode = atoi(cgi_variable("ViewMode"));
+ if ( cgi_variable("BasicMode"))
+ mode = 0;
+ if ( cgi_variable("AdvMode"))
+ mode = 1;
+
ViewModeBoxes( mode );
switch ( mode ) {
case 0:
@@ -1204,9 +1211,6 @@ static void printers_page(void)
case 1:
parm_filter = FLAG_ADVANCED;
break;
- case 2:
- parm_filter = FLAG_DEVELOPER;
- break;
}
d_printf("<table>\n");
d_printf("<tr><td><input type=submit name=selectshare value=\"%s\"></td>\n", _("Choose Printer"));