summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/Makefile.in120
-rw-r--r--source/aclocal.m41
-rw-r--r--source/auth/auth.c32
-rw-r--r--source/auth/auth_domain.c288
-rw-r--r--source/auth/auth_rhosts.c2
-rw-r--r--source/auth/auth_sam.c85
-rw-r--r--source/auth/auth_util.c254
-rw-r--r--source/auth/auth_winbind.c2
-rw-r--r--source/client/client.c9
-rwxr-xr-xsource/client/mount.cifs.c4
-rw-r--r--source/client/tree.c6
-rw-r--r--source/configure.in374
-rw-r--r--source/groupdb/mapping.c555
-rw-r--r--source/include/ads.h1
-rw-r--r--source/include/idmap.h7
-rw-r--r--source/include/includes.h12
-rw-r--r--source/include/mapping.h28
-rw-r--r--source/include/passdb.h22
-rw-r--r--source/include/privileges.h25
-rw-r--r--source/include/smb.h11
-rw-r--r--source/include/smb_macros.h8
-rw-r--r--source/include/smbldap.h31
-rw-r--r--source/lib/charcnv.c24
-rw-r--r--source/lib/gencache.c29
-rw-r--r--source/lib/smbldap.c734
-rw-r--r--source/lib/substitute.c8
-rw-r--r--source/lib/system_smbd.c24
-rw-r--r--source/lib/time.c3
-rw-r--r--source/lib/username.c70
-rw-r--r--source/lib/util.c5
-rw-r--r--source/lib/util_str.c59
-rw-r--r--source/lib/util_uuid.c6
-rw-r--r--source/lib/wins_srv.c20
-rw-r--r--source/libads/ads_ldap.c16
-rw-r--r--source/libads/ads_struct.c3
-rw-r--r--source/libads/ldap.c193
-rw-r--r--source/libads/ldap_printer.c8
-rw-r--r--source/libads/sasl.c5
-rw-r--r--source/libsmb/cliconnect.c70
-rw-r--r--source/libsmb/clifile.c4
-rw-r--r--source/libsmb/clikrb5.c2
-rw-r--r--source/libsmb/conncache.c158
-rw-r--r--source/libsmb/namecache.c111
-rw-r--r--source/libsmb/namequery.c742
-rw-r--r--source/libsmb/namequery_dc.c223
-rw-r--r--source/libsmb/netlogon_unigrp.c172
-rw-r--r--source/libsmb/samlogon_cache.c238
-rw-r--r--source/libsmb/smb_signing.c163
-rw-r--r--source/libsmb/trustdom_cache.c129
-rw-r--r--source/libsmb/trusts_util.c94
-rw-r--r--source/modules/vfs_extd_audit.c2
-rw-r--r--source/modules/vfs_recycle.c6
-rw-r--r--source/nsswitch/wb_client.c32
-rw-r--r--source/nsswitch/wb_common.c10
-rw-r--r--source/nsswitch/wbinfo.c2
-rw-r--r--source/nsswitch/winbindd.c19
-rw-r--r--source/nsswitch/winbindd.h6
-rw-r--r--source/nsswitch/winbindd_ads.c139
-rw-r--r--source/nsswitch/winbindd_cache.c507
-rw-r--r--source/nsswitch/winbindd_cm.c217
-rw-r--r--source/nsswitch/winbindd_group.c184
-rw-r--r--source/nsswitch/winbindd_pam.c135
-rw-r--r--source/nsswitch/winbindd_passdb.c8
-rw-r--r--source/nsswitch/winbindd_rpc.c313
-rw-r--r--source/nsswitch/winbindd_sid.c8
-rw-r--r--source/nsswitch/winbindd_user.c27
-rw-r--r--source/nsswitch/winbindd_util.c213
-rw-r--r--source/nsswitch/winbindd_wins.c24
-rw-r--r--source/nsswitch/wins.c13
-rw-r--r--source/pam_smbpass/pam_smb_passwd.c2
-rw-r--r--source/pam_smbpass/support.c2
-rw-r--r--source/param/loadparm.c39
-rw-r--r--source/passdb/machine_sid.c5
-rw-r--r--source/passdb/passdb.c34
-rw-r--r--source/passdb/pdb_interface.c68
-rw-r--r--source/passdb/pdb_ldap.c1026
-rw-r--r--source/passdb/pdb_smbpasswd.c9
-rw-r--r--source/passdb/pdb_tdb.c26
-rw-r--r--source/passdb/pdb_xml.c2
-rw-r--r--source/passdb/secrets.c9
-rw-r--r--source/printing/notify.c2
-rw-r--r--source/printing/nt_printing.c17
-rw-r--r--source/printing/printing.c2
-rwxr-xr-xsource/python/mkpatch6
-rw-r--r--source/rpc_client/cli_samr.c105
-rw-r--r--source/rpc_parse/parse_sec.c122
-rw-r--r--source/rpc_parse/parse_spoolss.c2
-rw-r--r--source/rpc_server/srv_lsa_nt.c58
-rw-r--r--source/rpc_server/srv_netlog_nt.c25
-rw-r--r--source/rpc_server/srv_samr_nt.c101
-rw-r--r--source/rpc_server/srv_spoolss_nt.c2
-rw-r--r--source/rpc_server/srv_util.c25
-rw-r--r--source/rpcclient/cmd_spoolss.c2
-rw-r--r--source/sam/idmap.c231
-rw-r--r--source/sam/idmap_ldap.c24
-rw-r--r--source/sam/idmap_tdb.c332
-rw-r--r--source/sam/idmap_util.c39
-rw-r--r--source/sam/idmap_winbind.c23
-rw-r--r--source/script/mkproto.awk2
-rw-r--r--source/smbd/build_options.c532
-rw-r--r--source/smbd/change_trust_pw.c2
-rw-r--r--source/smbd/lanman.c2
-rw-r--r--source/smbd/mangle_hash.c8
-rw-r--r--source/smbd/ntquotas.c6
-rw-r--r--source/smbd/nttrans.c12
-rw-r--r--source/smbd/posix_acls.c576
-rw-r--r--source/smbd/reply.c2
-rw-r--r--source/smbd/server.c11
-rw-r--r--source/smbd/service.c2
-rw-r--r--source/tdb/tdb.c3
-rw-r--r--source/tdb/tdbback.c201
-rw-r--r--source/tdb/tdbback.h23
-rw-r--r--source/tdb/tdbbackup.c174
-rw-r--r--source/tdb/tdbutil.c1
-rw-r--r--source/torture/nsstest.c49
-rw-r--r--source/torture/smbiconv.c8
-rw-r--r--source/torture/torture.c5
-rw-r--r--source/utils/editreg.c70
-rw-r--r--source/utils/net.c41
-rw-r--r--source/utils/net_ads.c40
-rw-r--r--source/utils/net_groupmap.c89
-rw-r--r--source/utils/net_help.c20
-rw-r--r--source/utils/net_idmap.c156
-rw-r--r--source/utils/net_lookup.c8
-rw-r--r--source/utils/net_rpc.c100
-rw-r--r--source/utils/net_rpc_join.c43
-rw-r--r--source/utils/net_rpc_samsync.c111
-rw-r--r--source/utils/pdbedit.c8
-rw-r--r--source/utils/smbcacls.c13
-rw-r--r--source/utils/smbcontrol.c49
-rw-r--r--source/utils/testparm.c4
131 files changed, 6852 insertions, 4914 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index 8b4e7bdb139..7f85619bc2e 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -34,6 +34,7 @@ PASSDBLIBS=@PASSDBLIBS@
IDMAP_LIBS=@IDMAP_LIBS@
ADSLIBS=@ADSLIBS@
KRB5LIBS=@KRB5_LIBS@
+LDAPLIBS=@LDAP_LIBS@
LINK=$(CC) $(FLAGS) $(LDFLAGS)
@@ -125,11 +126,15 @@ SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ \
BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \
bin/testparm@EXEEXT@ bin/testprns@EXEEXT@ bin/smbstatus@EXEEXT@
BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \
- bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@ bin/editreg@EXEEXT@
+ bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@
BIN_PROGS3 = bin/smbpasswd@EXEEXT@ bin/rpcclient@EXEEXT@ bin/smbcacls@EXEEXT@ \
bin/profiles@EXEEXT@ bin/ntlm_auth@EXEEXT@ \
bin/smbcquotas@EXEEXT@
+# editreg removed from standard build until it is portable. It needs a major rewrite to
+# achieve this (tridge)
+# bin/editreg@EXEEXT@
+
TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \
bin/masktest@EXEEXT@ bin/locktest@EXEEXT@ \
bin/locktest2@EXEEXT@ bin/nsstest@EXEEXT@ bin/vfstest@EXEEXT@
@@ -155,7 +160,7 @@ MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) $(CHARSE
######################################################################
TDBBASE_OBJ = tdb/tdb.o tdb/spinlock.o
-TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o
+TDB_OBJ = $(TDBBASE_OBJ) tdb/tdbutil.o tdb/tdbback.o
SMBLDAP_OBJ = @SMBLDAP@
@@ -203,7 +208,7 @@ LIBADS_SERVER_OBJ = libads/util.o libads/kerberos_verify.o
SECRETS_OBJ = passdb/secrets.o
LIBNMB_OBJ = libsmb/unexpected.o libsmb/namecache.o libsmb/nmblib.o \
- libsmb/namequery.o
+ libsmb/namequery.o libsmb/conncache.o
LIBSAMBA_OBJ = libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o libsmb/ntlmssp.o libsmb/ntlmssp_parse.o libsmb/ntlmssp_sign.o
@@ -217,17 +222,14 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
libsmb/clioplock.o libsmb/errormap.o libsmb/clirap2.o \
libsmb/passchange.o libsmb/doserr.o \
- libsmb/trustdom_cache.o \
- $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ)
+ $(RPC_PARSE_OBJ1) $(LIBSAMBA_OBJ) $(LIBNMB_OBJ)
LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \
rpc_client/cli_netlogon.o rpc_client/cli_srvsvc.o \
rpc_client/cli_wkssvc.o rpc_client/cli_dfs.o \
rpc_client/cli_reg.o rpc_client/cli_pipe.o \
rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \
- rpc_client/cli_ds.o rpc_client/cli_echo.o libsmb/namequery_dc.o
-
-LIBMSRPC_SERVER_OBJ = libsmb/trusts_util.o
+ rpc_client/cli_ds.o rpc_client/cli_echo.o
REGOBJS_OBJ = registry/reg_objects.o
REGISTRY_OBJ = registry/reg_frontend.o registry/reg_cachehook.o registry/reg_printing.o \
@@ -304,7 +306,9 @@ VFS_NETATALK_OBJ = modules/vfs_netatalk.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
-UNIGRP_OBJ = libsmb/netlogon_unigrp.o
+SLCACHE_OBJ = libsmb/samlogon_cache.o
+
+DCUTIL_OBJ = libsmb/namequery_dc.o libsmb/trustdom_cache.o libsmb/trusts_util.o
AUTH_BUILTIN_OBJ = auth/auth_builtin.o
AUTH_DOMAIN_OBJ = auth/auth_domain.o
@@ -315,8 +319,8 @@ AUTH_UNIX_OBJ = auth/auth_unix.o
AUTH_WINBIND_OBJ = auth/auth_winbind.o
AUTH_OBJ = auth/auth.o @AUTH_STATIC@ auth/auth_util.o auth/auth_compat.o \
- auth/auth_ntlmssp.o \
- $(PLAINTEXT_AUTH_OBJ) $(UNIGRP_OBJ)
+ auth/auth_ntlmssp.o \
+ $(PLAINTEXT_AUTH_OBJ) $(SLCACHE_OBJ) $(DCUTIL_OBJ)
MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_map.o smbd/mangle_hash2.o
@@ -345,7 +349,7 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(MSDFS_OBJ) $(LIBSMB_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \
$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
- $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \
+ $(LIBMSRPC_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
$(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) $(IDMAP_OBJ) \
$(UBIQX_OBJ) $(BUILDOPT_OBJ) $(SMBLDAP_OBJ)
@@ -431,7 +435,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
$(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
- $(IDMAP_OBJ) $(SMBLDAP_OBJ)
+ $(IDMAP_OBJ) $(SMBLDAP_OBJ) $(DCUTIL_OBJ)
PAM_WINBIND_OBJ = nsswitch/pam_winbind.po nsswitch/wb_common.po lib/snprintf.po
@@ -472,14 +476,14 @@ CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \
utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \
- utils/net_cache.o utils/net_groupmap.o
+ utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o
NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
- $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) \
+ $(LIBMSRPC_OBJ) \
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
- $(IDMAP_OBJ) $(SMBLDAP_OBJ)
+ $(IDMAP_OBJ) $(SMBLDAP_OBJ) $(DCUTIL_OBJ)
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
$(LIB_OBJ) $(KRBCLIENT_OBJ)
@@ -522,7 +526,7 @@ LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) \
$(PASSDB_GET_SET_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \
- $(POPT_LIB_OBJ)
+ $(POPT_LIB_OBJ) $(DCUTIL_OBJ) $(LIBADS_OBJ)
SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(PARAM_OBJ) \
@@ -549,7 +553,7 @@ SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(SMBD_OBJ_SRV) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \
$(SMBW_OBJ1) $(SMBWRAPPER_OBJ1) $(SMBTORTURE_OBJ1) $(RPCCLIENT_OBJ1) \
- $(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) $(RPC_CLIENT_OBJ) \
+ $(LIBMSRPC_OBJ) $(RPC_CLIENT_OBJ) \
$(RPC_PIPE_OBJ) $(RPC_PARSE_OBJ) $(KRBCLIENT_OBJ) \
$(AUTH_OBJ) $(PARAM_OBJ) $(LOCKING_OBJ) $(SECRETS_OBJ) \
$(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \
@@ -558,12 +562,12 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(LIB_SMBD_OBJ) $(SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) \
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
- $(IDMAP_OBJ) $(RPC_ECHO_OBJ)
+ $(IDMAP_OBJ) $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ)
-NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) \
- $(LIB_OBJ) $(NSSWINS_OBJ)
+WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) \
+ $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ)
-NSS_OBJ = $(NSS_OBJ_0:.o=.po)
+WINBIND_WINS_NSS_PICOBJS = $(WINBIND_WINS_NSS_OBJ:.o=.po)
PICOBJS = $(SMBWRAPPER_OBJ:.o=.po)
LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.po)
@@ -590,14 +594,15 @@ WINBINDD_OBJ1 = \
nsswitch/winbindd_rpc.o \
nsswitch/winbindd_ads.o \
nsswitch/winbindd_dual.o \
- nsswitch/winbindd_passdb.o
+ nsswitch/winbindd_passdb.o
WINBINDD_OBJ = \
$(WINBINDD_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
- $(PROFILE_OBJ) $(UNIGRP_OBJ) $(IDMAP_OBJ) $(SMBLDAP_OBJ) \
- $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ)
+ $(PROFILE_OBJ) $(SLCACHE_OBJ) $(IDMAP_OBJ) $(SMBLDAP_OBJ) \
+ $(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
+ $(DCUTIL_OBJ)
WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_OBJ) \
$(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
@@ -609,7 +614,7 @@ WINBIND_NSS_PICOBJS = $(WINBIND_NSS_OBJ:.o=.po)
POPT_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
-TDBBACKUP_OBJ = tdb/tdbbackup.o $(TDBBASE_OBJ)
+TDBBACKUP_OBJ = tdb/tdbbackup.o tdb/tdbback.o $(TDBBASE_OBJ)
NTLM_AUTH_OBJ = utils/ntlm_auth.o $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ)
@@ -647,9 +652,10 @@ smbfilter : SHOWFLAGS bin/smbfilter@EXEEXT@
talloctort : SHOWFLAGS bin/talloctort@EXEEXT@
-nsswitch : SHOWFLAGS bin/winbindd@EXEEXT@ bin/wbinfo@EXEEXT@ nsswitch/@WINBIND_NSS@ nsswitch/pam_winbind.@SHLIBEXT@
+nsswitch : SHOWFLAGS bin/winbindd@EXEEXT@ bin/wbinfo@EXEEXT@ @WINBIND_NSS@ \
+ @WINBIND_WINS_NSS@ nsswitch/pam_winbind.@SHLIBEXT@
-wins : SHOWFLAGS nsswitch/libnss_wins.@SHLIBEXT@
+wins : SHOWFLAGS @WINBIND_WINS_NSS@
modules: SHOWFLAGS proto_exists $(MODULES)
@@ -727,7 +733,7 @@ bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy
bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(ADSLIBS)
bin/wrepld@EXEEXT@: $(WREPL_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -744,7 +750,7 @@ bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy
bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(ADSLIBS)
bin/net@EXEEXT@: $(NET_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -760,11 +766,11 @@ bin/editreg@EXEEXT@: $(EDITREG_OBJ) @BUILD_POPT@ bin/.dummy
bin/smbspool@EXEEXT@: $(CUPS_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/smbmount@EXEEXT@: $(MOUNT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MOUNT_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(MOUNT_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/smbmnt@EXEEXT@: $(MNT_OBJ) bin/.dummy
@echo Linking $@
@@ -792,7 +798,7 @@ bin/smbcontrol@EXEEXT@: $(SMBCONTROL_OBJ) @BUILD_POPT@ bin/.dummy
bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy
@echo Linking $@
@@ -804,15 +810,15 @@ bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy
bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS) $(IDMAP_LIBS) $(ADSLIBS)
+ @$(CC) $(FLAGS) -o $@ $(SAMTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(PASSDBLIBS) $(IDMAP_LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/nmblookup@EXEEXT@: $(NMBLOOKUP_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@
+ @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(LDAPLIBS)
bin/smbtorture@EXEEXT@: $(SMBTORTURE_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/talloctort@EXEEXT@: $(TALLOCTORT_OBJ) bin/.dummy
@echo Linking $@
@@ -820,31 +826,31 @@ bin/talloctort@EXEEXT@: $(TALLOCTORT_OBJ) bin/.dummy
bin/masktest@EXEEXT@: $(MASKTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/msgtest@EXEEXT@: $(MSGTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/smbcacls@EXEEXT@: $(SMBCACLS_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
bin/smbcquotas@EXEEXT@: $(SMBCQUOTAS_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
bin/locktest@EXEEXT@: $(LOCKTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/nsstest@EXEEXT@: $(NSSTEST_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(NSSTEST_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/vfstest@EXEEXT@: $(VFSTEST_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINTLIBS) $(AUTHLIBS) $(ACLLIBS) $(LIBS) @POPTLIBS@ $(ADSLIBS)
+ @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINTLIBS) $(AUTHLIBS) $(ACLLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
bin/smbiconv@EXEEXT@: $(SMBICONV_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -852,11 +858,11 @@ bin/smbiconv@EXEEXT@: $(SMBICONV_OBJ) @BUILD_POPT@ bin/.dummy
bin/locktest2@EXEEXT@: $(LOCKTEST2_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/rpctorture@EXEEXT@: $(RPCTORTURE_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/debug2html@EXEEXT@: $(DEBUG2HTML_OBJ) bin/.dummy
@echo Linking $@
@@ -864,7 +870,7 @@ bin/debug2html@EXEEXT@: $(DEBUG2HTML_OBJ) bin/.dummy
bin/smbfilter@EXEEXT@: $(SMBFILTER_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
+ @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
bin/smbw_sample@EXEEXT@: $(SMBW_OBJ) utils/smbw_sample.o bin/.dummy
@echo Linking $@
@@ -947,20 +953,20 @@ bin/librpc_echo.@SHLIBEXT@: $(RPC_ECHO_OBJ)
@$(SHLD) $(LDSHFLAGS) -o $@ $(RPC_ECHO_OBJ) -lc \
@SONAMEFLAG@`basename $@`
-nsswitch/libnss_wins.@SHLIBEXT@: $(NSS_OBJ)
- @echo "Linking $@"
- @$(SHLD) $(LDSHFLAGS) -o $@ $(NSS_OBJ) -lc \
- @SONAMEFLAG@`basename $@`
-
bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy
@echo "Linking $@"
- @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(ADSLIBS) @LDAP_LIBS@
+ @$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
-nsswitch/@WINBIND_NSS@: $(WINBIND_NSS_PICOBJS)
+@WINBIND_NSS@: $(WINBIND_NSS_PICOBJS)
@echo "Linking $@"
@$(SHLD) $(WINBIND_NSS_LDSHFLAGS) -o $@ $(WINBIND_NSS_PICOBJS) \
@WINBIND_NSS_EXTRA_LIBS@ @SONAMEFLAG@`basename $@`
+@WINBIND_WINS_NSS@: $(WINBIND_WINS_NSS_PICOBJS)
+ @echo "Linking $@"
+ @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_WINS_NSS_PICOBJS) -lc \
+ @SONAMEFLAG@`basename $@`
+
nsswitch/pam_winbind.@SHLIBEXT@: $(PAM_WINBIND_OBJ) bin/.dummy
@echo "Linking $@"
@$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_WINBIND_OBJ) \
@@ -1001,7 +1007,7 @@ bin/mysql.@SHLIBEXT@: $(MYSQL_OBJ:.o=.po)
bin/ldapsam.@SHLIBEXT@: passdb/pdb_ldap.po
@echo "Building plugin $@"
- @$(SHLD) $(LDSHFLAGS) @LDAP_LIBS@ -o $@ passdb/pdb_ldap.po \
+ @$(SHLD) $(LDSHFLAGS) $(LDAPLIBS) -o $@ passdb/pdb_ldap.po \
@SONAMEFLAG@`basename $@`
bin/tdbsam.@SHLIBEXT@: passdb/pdb_tdb.po
@@ -1029,7 +1035,7 @@ bin/xml.@SHLIBEXT@: $(XML_OBJ:.o=.po)
@$(SHLD) $(LDSHFLAGS) -o $@ $(XML_OBJ:.o=.po) @XML_LIBS@ \
@SONAMEFLAG@`basename $@`
-bin/winbind_idmap.@SHLIBEXT@: sam/idmap_winbind.po
+bin/idmap_winbind.@SHLIBEXT@: sam/idmap_winbind.po
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ sam/idmap_winbind.po \
@SONAMEFLAG@`basename $@`
@@ -1093,7 +1099,7 @@ bin/t_push_ucs2@EXEEXT@: bin/libbigballofmud.@SHLIBEXT@ torture/t_push_ucs2.o
bin/t_snprintf@EXEEXT@: lib/snprintf.c
$(CC) $(FLAGS) -o $@ -DTEST_SNPRINTF lib/snprintf.c -lm
-install: installbin installman installscripts installdat installswat
+install: installbin installman installscripts installdat installswat installmodules
install-everything: install installmodules
@@ -1220,7 +1226,7 @@ clean: delheaders python_clean
# This is quite ugly actually.. But we need to make
# sure the changes to include/config.h are used.
modules_clean:
- @-rm -f @MODULES_CLEAN@ auth/auth.o passdb/pdb_interface.o smbd/server.o lib/iconv.o smbd/vfs.o sam/idmap.o
+ @-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
diff --git a/source/aclocal.m4 b/source/aclocal.m4
index dd1ae8df72b..2661d5299fd 100644
--- a/source/aclocal.m4
+++ b/source/aclocal.m4
@@ -64,7 +64,6 @@ AC_DEFUN(SMB_MODULE,
else
AC_MSG_RESULT([not])
fi
- MODULES_CLEAN="$MODULES_CLEAN $2 $3"
])
AC_DEFUN(SMB_SUBSYSTEM,
diff --git a/source/auth/auth.c b/source/auth/auth.c
index 02c7eb6d84a..d99b00d4a73 100644
--- a/source/auth/auth.c
+++ b/source/auth/auth.c
@@ -244,12 +244,24 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
return NT_STATUS_LOGON_FAILURE;
for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) {
+ NTSTATUS result;
+
mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name,
user_info->domain.str, user_info->smb_name.str);
- nt_status = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info);
+ result = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info);
+
+ /* check if the module did anything */
+ if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_NOT_IMPLEMENTED) ) {
+ DEBUG(10,("check_ntlm_password: %s had nothing to say\n", auth_method->name));
+ talloc_destroy(mem_ctx);
+ continue;
+ }
+
+ nt_status = result;
+
if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] suceeded\n",
+ DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] succeeded\n",
auth_method->name, user_info->smb_name.str));
} else {
DEBUG(5, ("check_ntlm_password: %s authentication for user [%s] FAILED with error %s\n",
@@ -257,9 +269,15 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
}
talloc_destroy(mem_ctx);
-
- if (NT_STATUS_IS_OK(nt_status))
- break;
+
+ /* this sucks. Somehow we have to know if an authentication module is
+ authoritative for a user. Fixme!!! --jerry */
+
+ if ( NT_STATUS_IS_OK(nt_status) ||
+ NT_STATUS_V(nt_status) == NT_STATUS_V(NT_STATUS_WRONG_PASSWORD) )
+ {
+ break;
+ }
}
if (NT_STATUS_IS_OK(nt_status)) {
@@ -271,7 +289,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
unbecome_root();
if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] suceeded\n",
+ DEBUG(5, ("check_ntlm_password: PAM Account for user [%s] succeeded\n",
pdb_username));
} else {
DEBUG(3, ("check_ntlm_password: PAM Account for user [%s] FAILED with error %s\n",
@@ -281,7 +299,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
if (NT_STATUS_IS_OK(nt_status)) {
DEBUG((*server_info)->guest ? 5 : 2,
- ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] suceeded\n",
+ ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n",
(*server_info)->guest ? "guest " : "",
user_info->smb_name.str,
user_info->internal_username.str,
diff --git a/source/auth/auth_domain.c b/source/auth/auth_domain.c
index 29916842805..80320d8266c 100644
--- a/source/auth/auth_domain.c
+++ b/source/auth/auth_domain.c
@@ -29,86 +29,6 @@ extern BOOL global_machine_password_needs_changing;
extern userdom_struct current_user_info;
-/*
- resolve the name of a DC in ways appropriate for an ADS domain mode
- an ADS domain may not have Netbios enabled at all, so this is
- quite different from the RPC case
- Note that we ignore the 'server' parameter here. That has the effect of using
- the 'ADS server' smb.conf parameter, which is what we really want anyway
- */
-static NTSTATUS ads_resolve_dc(fstring remote_machine,
- struct in_addr *dest_ip)
-{
- ADS_STRUCT *ads;
- ads = ads_init_simple();
- if (!ads) {
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- DEBUG(4,("ads_resolve_dc: realm=%s\n", ads->config.realm));
-
- ads->auth.flags |= ADS_AUTH_NO_BIND;
-
-#ifdef HAVE_ADS
- /* a full ads_connect() is actually overkill, as we don't srictly need
- to do the SASL auth in order to get the info we need, but libads
- doesn't offer a better way right now */
- ads_connect(ads);
-#endif
-
- fstrcpy(remote_machine, ads->config.ldap_server_name);
- strupper(remote_machine);
- *dest_ip = ads->ldap_ip;
- ads_destroy(&ads);
-
- if (!*remote_machine || is_zero_ip(*dest_ip)) {
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- DEBUG(4,("ads_resolve_dc: using server='%s' IP=%s\n",
- remote_machine, inet_ntoa(*dest_ip)));
-
- return NT_STATUS_OK;
-}
-
-/*
- resolve the name of a DC in ways appropriate for RPC domain mode
- this relies on the server supporting netbios and port 137 not being
- firewalled
- */
-static NTSTATUS rpc_resolve_dc(const char *server,
- fstring remote_machine,
- struct in_addr *dest_ip)
-{
- if (is_ipaddress(server)) {
- struct in_addr to_ip = *interpret_addr2(server);
-
- /* we need to know the machines netbios name - this is a lousy
- way to find it, but until we have a RPC call that does this
- it will have to do */
- if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) {
- DEBUG(2, ("rpc_resolve_dc: Can't resolve name for IP %s\n", server));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- *dest_ip = to_ip;
- return NT_STATUS_OK;
- }
-
- fstrcpy(remote_machine, server);
- strupper(remote_machine);
- if (!resolve_name(remote_machine, dest_ip, 0x20)) {
- DEBUG(1,("rpc_resolve_dc: Can't resolve address for %s\n",
- remote_machine));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- DEBUG(4,("rpc_resolve_dc: using server='%s' IP=%s\n",
- remote_machine, inet_ntoa(*dest_ip)));
-
- return NT_STATUS_OK;
-}
-
/**
* Connect to a remote server for domain security authenticaion.
*
@@ -121,35 +41,14 @@ static NTSTATUS rpc_resolve_dc(const char *server,
**/
static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
- const char *server,
+ const char *dc_name, struct in_addr dc_ip,
const char *setup_creds_as,
uint16 sec_chan,
const unsigned char *trust_passwd,
BOOL *retry)
{
- struct in_addr dest_ip;
- fstring remote_machine;
NTSTATUS result;
- *retry = False;
-
- if (lp_security() == SEC_ADS)
- result = ads_resolve_dc(remote_machine, &dest_ip);
- else
- result = rpc_resolve_dc(server, remote_machine, &dest_ip);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(2,("connect_to_domain_password_server: unable to resolve DC: %s\n",
- nt_errstr(result)));
- return result;
- }
-
- if (ismyip(dest_ip)) {
- DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n",
- remote_machine));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
/* TODO: Send a SAMLOGON request to determine whether this is a valid
logonserver. We can avoid a 30-second timeout if the DC is down
if the SAMLOGON request fails as it is only over UDP. */
@@ -164,14 +63,13 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
* ACCESS_DENIED errors if 2 auths are done from the same machine. JRA.
*/
- *retry = True;
-
- if (!grab_server_mutex(server))
+ if (!grab_server_mutex(dc_name))
return NT_STATUS_NO_LOGON_SERVERS;
/* Attempt connection */
- result = cli_full_connection(cli, global_myname(), remote_machine,
- &dest_ip, 0, "IPC$", "IPC", "", "", "",0, retry);
+ *retry = True;
+ result = cli_full_connection(cli, global_myname(), dc_name, &dc_ip, 0,
+ "IPC$", "IPC", "", "", "", 0, retry);
if (!NT_STATUS_IS_OK(result)) {
/* map to something more useful */
@@ -198,7 +96,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
if(cli_nt_session_open(*cli, PI_NETLOGON) == False) {
DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
+machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
cli_nt_session_close(*cli);
cli_ulogoff(*cli);
cli_shutdown(*cli);
@@ -217,7 +115,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
if (!NT_STATUS_IS_OK(result)) {
DEBUG(0,("connect_to_domain_password_server: unable to setup the NETLOGON credentials to machine \
-%s. Error was : %s.\n", remote_machine, nt_errstr(result)));
+%s. Error was : %s.\n", dc_name, nt_errstr(result)));
cli_nt_session_close(*cli);
cli_ulogoff(*cli);
cli_shutdown(*cli);
@@ -231,61 +129,6 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
}
/***********************************************************************
- Utility function to attempt a connection to an IP address of a DC.
-************************************************************************/
-
-static NTSTATUS attempt_connect_to_dc(struct cli_state **cli,
- const char *domain,
- struct in_addr *ip,
- const char *setup_creds_as,
- uint16 sec_chan,
- const unsigned char *trust_passwd)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- BOOL retry = True;
- fstring dc_name;
- int i;
-
- /*
- * Ignore addresses we have already tried.
- */
-
- if (is_zero_ip(*ip))
- return NT_STATUS_NO_LOGON_SERVERS;
-
- if (!lookup_dc_name(global_myname(), domain, ip, dc_name))
- return NT_STATUS_NO_LOGON_SERVERS;
-
- for (i = 0; (!NT_STATUS_IS_OK(ret)) && retry && (i < 3); i++)
- ret = connect_to_domain_password_server(cli, dc_name, setup_creds_as,
- sec_chan, trust_passwd, &retry);
- return ret;
-}
-
-/***********************************************************************
- We have been asked to dynamically determine the IP addresses of
- the PDC and BDC's for DOMAIN, and query them in turn.
-************************************************************************/
-static NTSTATUS find_connect_dc(struct cli_state **cli,
- const char *domain,
- const char *setup_creds_as,
- uint16 sec_chan,
- unsigned char *trust_passwd,
- time_t last_change_time)
-{
- struct in_addr dc_ip;
- fstring srv_name;
-
- if (!rpc_find_dc(domain, srv_name, &dc_ip)) {
- DEBUG(0,("find_connect_dc: Failed to find an DCs for %s\n", lp_workgroup()));
- return NT_STATUS_NO_LOGON_SERVERS;
- }
-
- return attempt_connect_to_dc( cli, domain, &dc_ip, setup_creds_as,
- sec_chan, trust_passwd );
-}
-
-/***********************************************************************
Do the same as security=server, but using NT Domain calls and a session
key from the machine password. If the server parameter is specified
use it, otherwise figure out a server from the 'password server' param.
@@ -296,15 +139,17 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
const char *domain,
uchar chal[8],
auth_serversupplied_info **server_info,
- const char *server, const char *setup_creds_as,
+ const char *dc_name, struct in_addr dc_ip,
+ const char *setup_creds_as,
uint16 sec_chan,
unsigned char trust_passwd[16],
time_t last_change_time)
{
- fstring remote_machine;
NET_USER_INFO_3 info3;
struct cli_state *cli = NULL;
NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
+ int i;
+ BOOL retry = True;
/*
* At this point, smb_apasswd points to the lanman response to
@@ -314,20 +159,14 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
* see if they were valid.
*/
- while (!NT_STATUS_IS_OK(nt_status) &&
- next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) {
- if(lp_security() != SEC_ADS && strequal(remote_machine, "*")) {
- nt_status = find_connect_dc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time);
- } else {
- int i;
- BOOL retry = True;
- for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++)
- nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as,
- sec_chan, trust_passwd, &retry);
- }
+ /* rety loop for robustness */
+
+ for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry && (i < 3); i++) {
+ nt_status = connect_to_domain_password_server(&cli, dc_name, dc_ip, setup_creds_as,
+ sec_chan, trust_passwd, &retry);
}
- if (!NT_STATUS_IS_OK(nt_status)) {
+ if ( !NT_STATUS_IS_OK(nt_status) ) {
DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
return nt_status;
}
@@ -340,12 +179,15 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
*/
nt_status = cli_netlogon_sam_network_logon(cli, mem_ctx,
- NULL,
- user_info->smb_name.str, user_info->domain.str,
- user_info->wksta_name.str, chal,
- user_info->lm_resp, user_info->nt_resp,
- &info3);
+ NULL, user_info->smb_name.str, user_info->domain.str,
+ user_info->wksta_name.str, chal, user_info->lm_resp,
+ user_info->nt_resp, &info3);
+ /* let go as soon as possible so we avoid any potential deadlocks
+ with winbind lookup up users or groups */
+
+ release_server_mutex();
+
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("domain_client_validate: unable to validate password "
"for user %s in domain %s to Domain controller %s. "
@@ -360,7 +202,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
} else {
nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str,
user_info->smb_name.str, domain, server_info, &info3);
- uni_group_cache_store_netlogon(mem_ctx, &info3);
+ netsamlogon_cache_store( mem_ctx, &info3 );
}
#if 0
@@ -373,7 +215,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_OK(status)) {
if(cli_nt_logoff(&cli, &ctr) == False) {
DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
+%s to Domain controller %s. Error was %s.\n", user, domain, dc_name, cli_errstr(&cli)));
nt_status = NT_STATUS_LOGON_FAILURE;
}
}
@@ -386,7 +228,6 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
cli_nt_session_close(cli);
cli_ulogoff(cli);
cli_shutdown(cli);
- release_server_mutex();
return nt_status;
}
@@ -401,11 +242,18 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
- char *password_server;
unsigned char trust_passwd[16];
time_t last_change_time;
const char *domain = lp_workgroup();
uint32 sec_channel_type = 0;
+ fstring dc_name;
+ struct in_addr dc_ip;
+
+ if ( lp_server_role() != ROLE_DOMAIN_MEMBER ) {
+ DEBUG(0,("check_ntdomain_security: Configuration error! Cannot use "
+ "ntdomain auth method when not a member of a domain.\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
if (!user_info || !server_info || !auth_context) {
DEBUG(1,("check_ntdomain_security: Critical variables not present. Failing.\n"));
@@ -420,7 +268,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
if(is_myname(user_info->domain.str)) {
DEBUG(3,("check_ntdomain_security: Requested domain was for this machine.\n"));
- return NT_STATUS_LOGON_FAILURE;
+ return NT_STATUS_NOT_IMPLEMENTED;
}
/*
@@ -443,17 +291,18 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
}
}
- /*
- * Treat each name in the 'password server =' line as a potential
- * PDC/BDC. Contact each in turn and try and authenticate.
- */
-
- password_server = lp_passwordserver();
+ /* we need our DC to send the net_sam_logon() request to */
+ if ( !get_dc_name(domain, dc_name, &dc_ip) ) {
+ DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
+ user_info->domain.str));
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+
nt_status = domain_client_validate(mem_ctx, user_info, domain,
- (uchar *)auth_context->challenge.data,
- server_info,
- password_server, global_myname(), sec_channel_type,trust_passwd, last_change_time);
+ (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
+ global_myname(), sec_channel_type,trust_passwd, last_change_time);
+
return nt_status;
}
@@ -485,6 +334,8 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
char *trust_password;
time_t last_change_time;
DOM_SID sid;
+ fstring dc_name;
+ struct in_addr dc_ip;
if (!user_info || !server_info || !auth_context) {
DEBUG(1,("check_trustdomain_security: Critical variables not present. Failing.\n"));
@@ -492,25 +343,22 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
}
/*
- * Check that the requested domain is not our own machine name.
- * If it is, we should never check the PDC here, we use our own local
- * password file.
+ * Check that the requested domain is not our own machine name or domain name.
*/
- if(is_myname(user_info->domain.str)) {
- DEBUG(3,("check_trustdomain_security: Requested domain was for this machine.\n"));
- return NT_STATUS_LOGON_FAILURE;
+ if( is_myname(user_info->domain.str) || strequal(lp_workgroup(), user_info->domain.str) ) {
+ DEBUG(3,("check_trustdomain_security: Requested domain [%s] was for this machine.\n",
+ user_info->domain.str));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
- /*
- * Check that the requested domain is not our own domain,
- * If it is, we should use our own local password file.
- */
-
- if(strequal(lp_workgroup(), (user_info->domain.str))) {
- DEBUG(3,("check_trustdomain_security: Requested domain was for this domain.\n"));
- return NT_STATUS_LOGON_FAILURE;
- }
+ /* No point is bothering if this is not a trusted domain.
+ This return makes "map to guest = bad user" work again.
+ The logic is that if we know nothing about the domain, that
+ user is known to us and does not exist */
+
+ if ( !is_trusted_domain( user_info->domain.str ) )
+ return NT_STATUS_NO_SUCH_USER;
/*
* Get the trusted account password for the trusted domain
@@ -537,11 +385,19 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
}
#endif
- nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str,
- (uchar *)auth_context->challenge.data,
- server_info, "*" /* Do a lookup */,
- lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time);
+ /* use get_dc_name() for consistency even through we know that it will be
+ a netbios name */
+
+ if ( !get_dc_name(user_info->domain.str, dc_name, &dc_ip) ) {
+ DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
+ user_info->domain.str));
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
+ nt_status = domain_client_validate(mem_ctx, user_info, user_info->domain.str,
+ (uchar *)auth_context->challenge.data, server_info, dc_name, dc_ip,
+ lp_workgroup(), SEC_CHAN_DOMAIN, trust_md4_password, last_change_time);
+
return nt_status;
}
diff --git a/source/auth/auth_rhosts.c b/source/auth/auth_rhosts.c
index 2f0de6b81e5..8fec760e212 100644
--- a/source/auth/auth_rhosts.c
+++ b/source/auth/auth_rhosts.c
@@ -139,7 +139,7 @@ static BOOL check_hosts_equiv(SAM_ACCOUNT *account)
char *fname = NULL;
fname = lp_hosts_equiv();
- if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(account), &uid)))
+ if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(account), &uid)))
return False;
/* note: don't allow hosts.equiv on root */
diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c
index 161376616b1..1690e4d5e12 100644
--- a/source/auth/auth_sam.c
+++ b/source/auth/auth_sam.c
@@ -4,6 +4,7 @@
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Andrew Bartlett 2001
+ 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
@@ -470,14 +471,14 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
}
/* module initialisation */
-static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_sam_ignoredomain(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
}
(*auth_method)->auth = check_sam_security;
- (*auth_method)->name = "sam";
+ (*auth_method)->name = "sam_ignoredomain";
return NT_STATUS_OK;
}
@@ -492,83 +493,55 @@ static NTSTATUS check_samstrict_security(const struct auth_context *auth_context
const auth_usersupplied_info *user_info,
auth_serversupplied_info **server_info)
{
+ BOOL is_local_name, is_my_domain;
if (!user_info || !auth_context) {
return NT_STATUS_LOGON_FAILURE;
}
- /* If we are a domain member, we must not
- attempt to check the password locally,
- unless it is one of our aliases. */
+ is_local_name = is_myname(user_info->domain.str);
+ is_my_domain = strequal(user_info->domain.str, lp_workgroup());
+
+ /* check whether or not we service this domain/workgroup name */
- if (!is_myname(user_info->domain.str)) {
- DEBUG(7,("The requested user domain is not the local server name. [%s]\\[%s]\n",
- user_info->domain.str,user_info->internal_username.str));
- return NT_STATUS_NO_SUCH_USER;
+ switch ( lp_server_role() ) {
+ case ROLE_STANDALONE:
+ case ROLE_DOMAIN_MEMBER:
+ if ( !is_local_name ) {
+ DEBUG(6,("check_samstrict_security: %s is not one of my local names (%s)\n",
+ user_info->domain.str, (lp_server_role() == ROLE_DOMAIN_MEMBER
+ ? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") ));
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ if ( !is_local_name && !is_my_domain ) {
+ DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n",
+ user_info->domain.str));
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ default: /* name is ok */
+ break;
}
return check_sam_security(auth_context, my_private_data, mem_ctx, user_info, server_info);
}
/* module initialisation */
-static NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
+static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
{
if (!make_auth_methods(auth_context, auth_method)) {
return NT_STATUS_NO_MEMORY;
}
(*auth_method)->auth = check_samstrict_security;
- (*auth_method)->name = "samstrict";
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
-Check SAM security (above) but with a few extra checks if we're a DC.
-****************************************************************************/
-
-static NTSTATUS check_samstrict_dc_security(const struct auth_context *auth_context,
- void *my_private_data,
- TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
-
- if (!user_info || !auth_context) {
- return NT_STATUS_LOGON_FAILURE;
- }
-
- /* If we are a PDC we must not check the password here
- unless it is one of our aliases, empty
- or equal to our domain name. Other names may be
- Trusted domains.
- */
-
- if ((!is_myworkgroup(user_info->domain.str))&&
- (!is_myname(user_info->domain.str))) {
- DEBUG(7,("The requested user domain is not the local server name or our domain. [%s]\\[%s]\n",
- user_info->domain.str,user_info->internal_username.str));
- return NT_STATUS_NO_SUCH_USER;
- }
-
- return check_sam_security(auth_context, my_private_data, mem_ctx, user_info, server_info);
-}
-
-/* module initialisation */
-static NTSTATUS auth_init_samstrict_dc(struct auth_context *auth_context, const char *param, auth_methods **auth_method)
-{
- if (!make_auth_methods(auth_context, auth_method)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- (*auth_method)->auth = check_samstrict_dc_security;
- (*auth_method)->name = "samstrict_dc";
+ (*auth_method)->name = "sam";
return NT_STATUS_OK;
}
NTSTATUS auth_sam_init(void)
{
- smb_register_auth(AUTH_INTERFACE_VERSION, "samstrict_dc", auth_init_samstrict_dc);
- smb_register_auth(AUTH_INTERFACE_VERSION, "samstrict", auth_init_samstrict);
smb_register_auth(AUTH_INTERFACE_VERSION, "sam", auth_init_sam);
+ smb_register_auth(AUTH_INTERFACE_VERSION, "sam_ignoredomain", auth_init_sam_ignoredomain);
return NT_STATUS_OK;
}
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index d57619942c4..ab08a28ff65 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -204,41 +204,26 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
client_domain, smb_name, wksta_name));
- if (lp_allow_trusted_domains() && *client_domain) {
-
- /* the client could have given us a workstation name
- or other crap for the workgroup - we really need a
- way of telling if this domain name is one of our
- trusted domain names
-
- Also don't allow "" as a domain, fixes a Win9X bug
+ /* don't allow "" as a domain, fixes a Win9X bug
where it doens't supply a domain for logon script
- 'net use' commands.
-
- Finally, we do this by looking up a cache of trusted domains!
- */
+ 'net use' commands.*/
+ if ( *client_domain )
domain = client_domain;
+ else
+ domain = lp_workgroup();
- if (is_trusted_domain(domain)) {
- return make_user_info(user_info, smb_name, internal_username,
- client_domain, domain, wksta_name,
- lm_pwd, nt_pwd, plaintext, ntlmssp_flags,
- encrypted);
- }
+ /* do what win2k does. Always map unknown domains to our own
+ and let the "passdb backend" handle unknown users. */
- } else {
- domain = lp_workgroup();
- }
+ if ( !is_trusted_domain(domain) )
+ domain = get_default_sam_name();
- return make_user_info(user_info,
- smb_name, internal_username,
- client_domain, domain,
- wksta_name,
- lm_pwd, nt_pwd,
- plaintext,
- ntlmssp_flags, encrypted);
+ /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
+ return make_user_info(user_info, smb_name, internal_username,
+ client_domain, domain, wksta_name, lm_pwd, nt_pwd,
+ plaintext, ntlmssp_flags, encrypted);
}
/****************************************************************************
@@ -607,10 +592,10 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
NT_USER_TOKEN *token;
int i;
- if (NT_STATUS_IS_ERR(uid_to_sid(&user_sid, uid))) {
+ if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) {
return NULL;
}
- if (NT_STATUS_IS_ERR(gid_to_sid(&group_sid, gid))) {
+ if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) {
return NULL;
}
@@ -621,7 +606,7 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups,
}
for (i = 0; i < ngroups; i++) {
- if (NT_STATUS_IS_ERR(gid_to_sid(&(group_sids)[i], (groups)[i]))) {
+ if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids)[i], (groups)[i]))) {
DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i]));
SAFE_FREE(group_sids);
return NULL;
@@ -650,29 +635,22 @@ 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(SAM_ACCOUNT *sampass,
+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)
{
- uid_t uid;
- gid_t gid;
int n_unix_groups;
int i;
*n_groups = 0;
*groups = NULL;
- if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sampass), &uid)) || NT_STATUS_IS_ERR(sid_to_gid(pdb_get_group_sid(sampass), &gid))) {
- DEBUG(0, ("get_user_groups_from_local_sam: error fetching uid or gid for user!\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
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 (sys_getgrouplist(pdb_get_username(sampass), gid, *unix_groups, &n_unix_groups) == -1) {
+ 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) {
@@ -681,7 +659,7 @@ static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass,
}
*unix_groups = groups_tmp;
- if (sys_getgrouplist(pdb_get_username(sampass), gid, *unix_groups, &n_unix_groups) == -1) {
+ 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? */
@@ -702,7 +680,7 @@ static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass,
*n_groups = n_unix_groups;
for (i = 0; i < *n_groups; i++) {
- if (NT_STATUS_IS_ERR(gid_to_sid(&(*groups)[i], (*unix_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]));
SAFE_FREE(*groups);
SAFE_FREE(*unix_groups);
@@ -717,35 +695,26 @@ static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass,
Make a user_info struct
***************************************************************************/
-static NTSTATUS make_server_info(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass)
+static NTSTATUS make_server_info(auth_serversupplied_info **server_info)
{
- NTSTATUS ret;
-
*server_info = malloc(sizeof(**server_info));
if (!*server_info) {
DEBUG(0,("make_server_info: malloc failed!\n"));
return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(*server_info);
-
- (*server_info)->sam_fill_level = SAM_FILL_ALL;
- (*server_info)->sam_account = sampass;
- if (NT_STATUS_IS_ERR(ret = sid_to_uid(pdb_get_user_sid(sampass), &((*server_info)->uid))))
- return ret;
- if (NT_STATUS_IS_ERR(ret = sid_to_gid(pdb_get_group_sid(sampass), &((*server_info)->gid))))
- return ret;
-
return NT_STATUS_OK;
}
/***************************************************************************
- Make (and fill) a user_info struct from a SAM_ACCOUNT
+Fill a server_info struct from a SAM_ACCOUNT with their groups
***************************************************************************/
-NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
- SAM_ACCOUNT *sampass)
+static NTSTATUS add_user_groups(auth_serversupplied_info **server_info,
+ SAM_ACCOUNT *sampass,
+ uid_t uid, gid_t gid)
{
- NTSTATUS nt_status = NT_STATUS_OK;
+ NTSTATUS nt_status;
const DOM_SID *user_sid = pdb_get_user_sid(sampass);
const DOM_SID *group_sid = pdb_get_group_sid(sampass);
int n_groupSIDs = 0;
@@ -755,14 +724,11 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
BOOL is_guest;
uint32 rid;
- if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info, sampass))) {
- return nt_status;
- }
-
- if (!NT_STATUS_IS_OK(nt_status
- = get_user_groups_from_local_sam(sampass,
- &n_groupSIDs, &groupSIDs, &unix_groups)))
- {
+ nt_status = get_user_groups_from_local_sam(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);
return nt_status;
@@ -785,9 +751,36 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
(*server_info)->n_groups = n_groupSIDs;
(*server_info)->groups = unix_groups;
-
(*server_info)->ptok = token;
-
+
+ return nt_status;
+}
+
+/***************************************************************************
+ Make (and fill) a user_info struct from a SAM_ACCOUNT
+***************************************************************************/
+
+NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
+ SAM_ACCOUNT *sampass)
+{
+ NTSTATUS nt_status;
+
+ if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info)))
+ return nt_status;
+
+ (*server_info)->sam_account = sampass;
+
+ if (!NT_STATUS_IS_OK(nt_status = sid_to_uid(pdb_get_user_sid(sampass), &((*server_info)->uid))))
+ return nt_status;
+
+ if (!NT_STATUS_IS_OK(nt_status = sid_to_gid(pdb_get_group_sid(sampass), &((*server_info)->gid))))
+ return nt_status;
+
+ if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass,
+ (*server_info)->uid, (*server_info)->gid)))
+ return nt_status;
+
+ (*server_info)->sam_fill_level = SAM_FILL_ALL;
DEBUG(5,("make_server_info_sam: made server info for user %s\n",
pdb_get_username((*server_info)->sam_account)));
@@ -806,7 +799,20 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struc
if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) {
return nt_status;
}
- return make_server_info_sam(server_info, sampass);
+ if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
+ return nt_status;
+ }
+
+ (*server_info)->sam_account = sampass;
+
+ if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass, pwd->pw_uid, pwd->pw_gid))) {
+ return nt_status;
+ }
+
+ (*server_info)->sam_fill_level = SAM_FILL_ALL;
+ (*server_info)->uid = pwd->pw_uid;
+ (*server_info)->gid = pwd->pw_gid;
+ return nt_status;
}
/***************************************************************************
@@ -843,6 +849,39 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
}
/***************************************************************************
+ Purely internal function for make_server_info_info3
+ Fill the sam account from getpwnam
+***************************************************************************/
+static NTSTATUS fill_sam_account(const char *domain,
+ const char *username,
+ uid_t *uid, gid_t *gid,
+ SAM_ACCOUNT **sam_account)
+{
+ fstring dom_user;
+ struct passwd *passwd;
+
+ fstr_sprintf(dom_user, "%s%s%s",
+ domain, lp_winbind_separator(), username);
+
+ passwd = Get_Pwnam(dom_user);
+
+ /* if the lookup for DOMAIN\username failed, try again
+ with just 'username'. This is need for accessing the server
+ as a trust user that actually maps to a local account */
+
+ if ( !passwd )
+ passwd = Get_Pwnam(username);
+
+ if (passwd == NULL)
+ return NT_STATUS_NO_SUCH_USER;
+
+ *uid = passwd->pw_uid;
+ *gid = passwd->pw_gid;
+
+ return pdb_init_sam_pw(sam_account, passwd);
+}
+
+/***************************************************************************
Make a server_info struct from the info3 returned by a domain logon
***************************************************************************/
@@ -865,6 +904,8 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
struct passwd *passwd;
unid_t u_id, g_id;
+ uid_t uid;
+ gid_t gid;
int u_type, g_type;
int n_lgroupSIDs;
@@ -904,44 +945,37 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
u_type = ID_USERID;
g_type = ID_GROUPID;
+
+ /* we are trying to check that idmap isn't stuffing us over - does this
+ user actually exist? */
if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&u_id, &u_type, &user_sid))
&& NT_STATUS_IS_OK(idmap_get_id_from_sid(&g_id, &g_type, &group_sid))
&& ((passwd = getpwuid_alloc(u_id.uid)))) {
+
nt_status = pdb_init_sam_pw(&sam_account, passwd);
+
+ uid = passwd->pw_uid;
+ gid = passwd->pw_gid;
+
+ /* we should check this is the same name */
+
passwd_free(&passwd);
} else {
- int try = 0;
- while (try < 2) {
- char *dom_user;
- dom_user = talloc_asprintf(mem_ctx, "%s%s%s",
- nt_domain,
- lp_winbind_separator(),
- internal_username);
-
- if (!dom_user) {
- DEBUG(0, ("talloc_asprintf failed!\n"));
- nt_status = NT_STATUS_NO_MEMORY;
- } else {
-
- if (!(passwd = Get_Pwnam(dom_user))
- /* Only lookup local for the local
- domain, we don't want this for
- trusted domains */
- && strequal(nt_domain, lp_workgroup())) {
- passwd = Get_Pwnam(internal_username);
- }
-
- if (!passwd) {
- nt_status = NT_STATUS_NO_SUCH_USER;
- } else {
- nt_status = pdb_init_sam_pw(&sam_account, passwd);
- break;
- }
- }
- if (try == 0) {
- auth_add_user_script(nt_domain, internal_username);
- }
- try++;
+
+ /* User not from winbind - try and find them by getpwnam() */
+ nt_status = fill_sam_account(nt_domain,
+ internal_username,
+ &uid, &gid,
+ &sam_account);
+
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
+ DEBUG(3,("User %s does not exist, trying to add it\n",
+ internal_username));
+ auth_add_user_script(nt_domain, internal_username);
+ nt_status = fill_sam_account(nt_domain,
+ internal_username,
+ &uid, &gid,
+ &sam_account);
}
}
@@ -995,17 +1029,29 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info, sam_account))) {
+ if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {
DEBUG(4, ("make_server_info failed!\n"));
pdb_free_sam(&sam_account);
return nt_status;
}
+ /* save this here to _net_sam_logon() doesn't fail (it assumes a
+ valid SAM_ACCOUNT) */
+
+ (*server_info)->sam_account = sam_account;
+
+ /* Fill in the unix info we found on the way */
+
+ (*server_info)->sam_fill_level = SAM_FILL_ALL;
+ (*server_info)->uid = uid;
+ (*server_info)->gid = gid;
+
/* Store the user group information in the server_info
returned to the caller. */
if (!NT_STATUS_IS_OK(nt_status
- = get_user_groups_from_local_sam(sam_account,
+ = get_user_groups_from_local_sam(pdb_get_username(sam_account),
+ uid, gid,
&n_lgroupSIDs,
&lgroupSIDs,
&unix_groups)))
@@ -1022,7 +1068,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
(n_lgroupSIDs + info3->num_groups2 +
info3->num_other_sids));
if (!all_group_SIDs) {
- DEBUG(0, ("create_nt_token_info3: malloc() failed for DOM_SID list!\n"));
+ DEBUG(0, ("malloc() failed for DOM_SID list!\n"));
SAFE_FREE(lgroupSIDs);
return NT_STATUS_NO_MEMORY;
}
@@ -1036,7 +1082,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
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)) {
nt_status = NT_STATUS_INVALID_PARAMETER;
- DEBUG(3,("create_nt_token_info3: could not append additional group rid 0x%x\n",
+ DEBUG(3,("could not append additional group rid 0x%x\n",
info3->gids[i].g_rid));
SAFE_FREE(lgroupSIDs);
return nt_status;
diff --git a/source/auth/auth_winbind.c b/source/auth/auth_winbind.c
index 0b19746597d..6ae8685b113 100644
--- a/source/auth/auth_winbind.c
+++ b/source/auth/auth_winbind.c
@@ -29,7 +29,7 @@
static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response *response, NET_USER_INFO_3 *info3)
{
uint8 *info3_ndr;
- size_t len = response->length - sizeof(response);
+ size_t len = response->length - sizeof(struct winbindd_response);
prs_struct ps;
if (len > 0) {
info3_ndr = response->extra_data;
diff --git a/source/client/client.c b/source/client/client.c
index 69037ca1db8..f2be268efe2 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -2108,7 +2108,7 @@ static struct
/* Yes, this must be here, see crh's comment above. */
{"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
- {"",NULL,NULL,{COMPL_NONE,COMPL_NONE}}
+ {NULL,NULL,NULL,{COMPL_NONE,COMPL_NONE}}
};
@@ -2328,7 +2328,7 @@ static char **completion_fn(const char *text, int start, int end)
if (sp == NULL)
return NULL;
- for (i = 0; commands[i].description; i++)
+ for (i = 0; commands[i].name; i++)
if ((strncmp(commands[i].name, text, sp - buf) == 0) && (commands[i].name[sp - buf] == 0))
break;
if (commands[i].name == NULL)
@@ -2747,7 +2747,7 @@ static void remember_query_host(const char *arg,
{ "tar", 'T', POPT_ARG_STRING, NULL, 'T', "Command line tar", "<c|x>IXFqgbNan" },
{ "directory", 'D', POPT_ARG_STRING, NULL, 'D', "Start from directory", "DIR" },
{ "command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated commands" },
- { "send-buffer", 'b', POPT_ARG_INT, NULL, 'b', "Changes the transmit/send buffer", "BYTES" },
+ { "send-buffer", 'b', POPT_ARG_INT, &io_bufsize, 'b', "Changes the transmit/send buffer", "BYTES" },
{ "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" },
POPT_COMMON_SAMBA
POPT_COMMON_CONNECTION
@@ -2821,9 +2821,6 @@ static void remember_query_host(const char *arg,
case 'D':
fstrcpy(base_directory,poptGetOptArg(pc));
break;
- case 'b':
- io_bufsize = MAX(1, atoi(poptGetOptArg(pc)));
- break;
}
}
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
index 6edb06aedfb..9592dbdf966 100755
--- a/source/client/mount.cifs.c
+++ b/source/client/mount.cifs.c
@@ -377,7 +377,7 @@ int main(int argc, char ** argv)
test_opts = xstrdup(optarg);
break;*/
case 'r': /* mount readonly */
- flags |= MS_RDONLY;;
+ flags |= MS_RDONLY;
break;
case 'U':
uuid = optarg;
@@ -389,7 +389,7 @@ int main(int argc, char ** argv)
printf ("mount: %s\n", version);
exit (0);*/
case 'w':
- flags &= ~MS_RDONLY;;
+ flags &= ~MS_RDONLY;
break;
/* case 0:
break;
diff --git a/source/client/tree.c b/source/client/tree.c
index 94fd93c2106..3b90d15f652 100644
--- a/source/client/tree.c
+++ b/source/client/tree.c
@@ -36,7 +36,7 @@ struct tree_data {
};
-void error_message(gchar *message) {
+static void tree_error_message(gchar *message) {
GtkWidget *dialog, *label, *okay_button;
@@ -344,7 +344,7 @@ static void cb_itemsignal( GtkWidget *item,
slprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not open dir %s, %s\n", get_path(item), strerror(errno));
- error_message(errmsg);
+ tree_error_message(errmsg);
/* gtk_main_quit();*/
@@ -363,7 +363,7 @@ static void cb_itemsignal( GtkWidget *item,
slprintf(errmsg, sizeof(errmsg), "cb_itemsignal: Could not read dir smbc://, %s\n", strerror(errno));
- error_message(errmsg);
+ tree_error_message(errmsg);
/* gtk_main_quit();*/
diff --git a/source/configure.in b/source/configure.in
index c81712da5cf..69d901cdc27 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -173,13 +173,13 @@ AC_ARG_ENABLE(debug,
AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)],
[if eval "test x$enable_developer = xyes"; then
developer=yes
- CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
+ CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
fi])
AC_ARG_ENABLE(krb5developer, [ --enable-krb5developer Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)],
[if eval "test x$enable_krb5developer = xyes"; then
developer=yes
- CFLAGS="${CFLAGS} -g -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
+ CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
fi])
AC_ARG_ENABLE(dmalloc, [ --enable-dmalloc Enable heap debugging [default=no]])
@@ -529,6 +529,7 @@ AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h t
AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
AC_CHECK_HEADERS(security/pam_modules.h security/_pam_macros.h dlfcn.h)
AC_CHECK_HEADERS(sys/syslog.h syslog.h execinfo.h)
+AC_CHECK_HEADERS(langinfo.h locale.h)
# In valgrind 1.0.x, it's just valgrind.h. In 1.9.x+ there's a
# subdirectory of headers.
@@ -843,6 +844,7 @@ 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(setlocale nl_langinfo)
# setbuffer, shmget, shm_open are needed for smbtorture
AC_CHECK_FUNCS(setbuffer shmget shm_open backtrace_symbols)
@@ -2093,31 +2095,29 @@ AC_ARG_WITH(dfs,
#################################################
# active directory support
-with_ads_support=yes
+with_ads_support=auto
AC_MSG_CHECKING([whether to use Active Directory])
AC_ARG_WITH(ads,
[ --with-ads Active Directory support (default yes)],
[ case "$withval" in
- no)
- with_ads_support=no
+ yes|no)
+ with_ads_support="$withval"
;;
esac ])
-if test x"$with_ads_support" = x"yes"; then
- AC_DEFINE(WITH_ADS,1,[Whether to include Active Directory support])
-fi
-
AC_MSG_RESULT($with_ads_support)
FOUND_KRB5=no
KRB5_LIBS=""
-if test x"$with_ads_support" = x"yes"; then
-ac_save_CFLAGS="$CFLAGS"
-ac_save_LIBS="$LIBS"
-CFLAGS=""
-LIBS=""
+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
@@ -2134,158 +2134,239 @@ LIBS=""
fi
if test x$FOUND_KRB5 = x"no"; then
- #################################################
- # check for location of Kerberos 5 install
- AC_MSG_CHECKING(for kerberos 5 install path)
- AC_ARG_WITH(krb5,
- [ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)],
- [ case "$withval" in
- no)
+ #################################################
+ # check for location of Kerberos 5 install
+ AC_MSG_CHECKING(for kerberos 5 install path)
+ AC_ARG_WITH(krb5,
+ [ --with-krb5=base-dir Locate Kerberos 5 support (default=/usr)],
+ [ case "$withval" in
+ no)
+ AC_MSG_RESULT(no)
+ ;;
+ *)
+ AC_MSG_RESULT(yes)
+ LIBS="$LIBS -lkrb5"
+ CFLAGS="$CFLAGS -I$withval/include"
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ FOUND_KRB5=yes
+ ;;
+ esac ],
AC_MSG_RESULT(no)
- ;;
- *)
- AC_MSG_RESULT(yes)
- LIBS="$LIBS -lkrb5"
- CFLAGS="$CFLAGS -I$withval/include"
- CPPFLAGS="$CPPFLAGS -I$withval/include"
- LDFLAGS="$LDFLAGS -L$withval/lib"
- FOUND_KRB5=yes
- ;;
- esac ],
- AC_MSG_RESULT(no)
- )
+ )
fi
-if test x$FOUND_KRB5 = x"no"; then
-#################################################
-# see if this box has the SuSE location for the heimdal kerberos implementation
-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"
- AC_MSG_RESULT(yes)
+ if test x$FOUND_KRB5 = x"no"; then
+ #################################################
+ # see if this box has the SuSE location for the heimdal krb implementation
+ 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"
+ AC_MSG_RESULT(yes)
+ else
+ LIBS="$LIBS -lkrb5"
+ CFLAGS="$CFLAGS -I/usr/include/heimdal"
+ CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
+ AC_MSG_RESULT(yes)
+ fi
else
- LIBS="$LIBS -lkrb5"
- CFLAGS="$CFLAGS -I/usr/include/heimdal"
- CPPFLAGS="$CPPFLAGS -I/usr/include/heimdal"
- AC_MSG_RESULT(yes)
-
+ AC_MSG_RESULT(no)
fi
-else
- AC_MSG_RESULT(no)
-fi
-fi
-
+ fi
-if test x$FOUND_KRB5 = 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"
- AC_MSG_RESULT(yes)
-else
- AC_MSG_RESULT(no)
-fi
-fi
+ if test x$FOUND_KRB5 = 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"
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ fi
# 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
AC_CHECK_HEADERS(krb5.h)
+ if test x"$ac_cv_header_krb5_h" = x"no"; then
+
+ # Give a warning if AD support was not explicitly requested,
+ # i.e with_ads_support = auto, otherwise die with an error.
+
+ if test x"$with_ads_support" = x"yes"; then
+ AC_MSG_ERROR([Active Directory cannot be supported without krb5.h])
+ else
+ AC_MSG_WARN([Active Directory cannot be supported without krb5.h])
+ fi
+
+ # 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"
+
+ 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])
+
# now check for gssapi headers. This is also done here to allow for
# different kerberos include paths
AC_CHECK_HEADERS(gssapi.h gssapi/gssapi_generic.h gssapi/gssapi.h com_err.h)
##################################################################
# we might need the k5crypto and com_err libraries on some systems
- AC_CHECK_LIB(com_err, _et_list, [LIBS="$LIBS -lcom_err"])
- AC_CHECK_LIB(k5crypto, krb5_encrypt_data, [LIBS="$LIBS -lk5crypto"])
+ AC_CHECK_LIB(com_err, _et_list)
+ AC_CHECK_LIB(k5crypto, krb5_encrypt_data)
+
# Heimdal checks.
- AC_CHECK_LIB(crypto, des_set_key, [LIBS="$LIBS -lcrypto"])
- AC_CHECK_LIB(asn1, copy_Authenticator, [LIBS="$LIBS -lasn1"])
- AC_CHECK_LIB(roken, roken_getaddrinfo_hostspec, [LIBS="$LIBS -lroken"])
- AC_CHECK_LIB(resolv, dn_expand, [LIBS="$LIBS -lresolv"])
+ AC_CHECK_LIB(crypto, des_set_key)
+ AC_CHECK_LIB(asn1, copy_Authenticator)
+ AC_CHECK_LIB(roken, 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_CACHE_CHECK([for addrtype in krb5_address],samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS,[
-AC_TRY_COMPILE([#include <krb5.h>],
-[krb5_address kaddr; kaddr.addrtype = ADDRTYPE_INET;],
-samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS=yes,samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS=no)])
-if test x"$samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS" = x"yes"; then
- AC_DEFINE(HAVE_ADDRTYPE_IN_KRB5_ADDRESS,1,[Whether the krb5_address struct has a addrtype property])
-fi
-
-AC_CACHE_CHECK([for addr_type in krb5_address],samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS,[
-AC_TRY_COMPILE([#include <krb5.h>],
-[krb5_address kaddr; kaddr.addr_type = KRB5_ADDRESS_INET;],
-samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS=yes,samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS=no)])
-if test x"$samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS" = x"yes"; then
- AC_DEFINE(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS,1,[Whether the krb5_address struct has a addr_type property])
-fi
-
-AC_CACHE_CHECK([for enc_part2 in krb5_ticket],samba_cv_HAVE_KRB5_TKT_ENC_PART2,[
-AC_TRY_COMPILE([#include <krb5.h>],
-[krb5_ticket tkt; tkt.enc_part2->authorization_data[0]->contents = NULL;],
-samba_cv_HAVE_KRB5_TKT_ENC_PART2=yes,samba_cv_HAVE_KRB5_TKT_ENC_PART2=no)])
-if test x"$samba_cv_HAVE_KRB5_TKT_ENC_PART2" = x"yes"; then
- AC_DEFINE(HAVE_KRB5_TKT_ENC_PART2,1,[Whether the krb5_ticket struct has a enc_part2 property])
-fi
-
-AC_CACHE_CHECK([for keyvalue in krb5_keyblock],samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE,[
-AC_TRY_COMPILE([#include <krb5.h>],
-[krb5_keyblock key; key.keyvalue.data = NULL;],
-samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE=yes,samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE=no)])
-if test x"$samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE" = x"yes"; then
- AC_DEFINE(HAVE_KRB5_KEYBLOCK_KEYVALUE,1,[Whether the krb5_keyblock struct has a keyvalue property])
-fi
-
-AC_CACHE_CHECK([for ENCTYPE_ARCFOUR_HMAC_MD5],samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,[
-AC_TRY_COMPILE([#include <krb5.h>],
-[krb5_enctype enctype; enctype = ENCTYPE_ARCFOUR_HMAC_MD5;],
-samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5=yes,samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5=no)])
-if test x"$samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5" = x"yes"; then
- AC_DEFINE(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,1,[Whether the ENCTYPE_ARCFOUR_HMAC_MD5 key type is available])
-fi
+ 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_CACHE_CHECK([for addrtype in krb5_address],
+ samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_address kaddr; kaddr.addrtype = ADDRTYPE_INET;],
+ samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS=yes,
+ samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS=no)])
+
+ if test x"$samba_cv_HAVE_ADDRTYPE_IN_KRB5_ADDRESS" = x"yes"; then
+ AC_DEFINE(HAVE_ADDRTYPE_IN_KRB5_ADDRESS,1,
+ [Whether the krb5_address struct has a addrtype property])
+ fi
+
+ AC_CACHE_CHECK([for addr_type in krb5_address],
+ samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_address kaddr; kaddr.addr_type = KRB5_ADDRESS_INET;],
+ samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS=yes,
+ samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS=no)])
+
+ if test x"$samba_cv_HAVE_ADDR_TYPE_IN_KRB5_ADDRESS" = x"yes"; then
+ AC_DEFINE(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS,1,
+ [Whether the krb5_address struct has a addr_type property])
+ fi
+
+ AC_CACHE_CHECK([for enc_part2 in krb5_ticket],
+ samba_cv_HAVE_KRB5_TKT_ENC_PART2,
+ [AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_ticket tkt; tkt.enc_part2->authorization_data[0]->contents = NULL;],
+ samba_cv_HAVE_KRB5_TKT_ENC_PART2=yes,samba_cv_HAVE_KRB5_TKT_ENC_PART2=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_TKT_ENC_PART2" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_TKT_ENC_PART2,1,
+ [Whether the krb5_ticket struct has a enc_part2 property])
+ fi
+
+ AC_CACHE_CHECK([for keyvalue in krb5_keyblock],
+ samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_keyblock key; key.keyvalue.data = NULL;],
+ samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE=yes,
+ samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_KEYBLOCK_KEYVALUE" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_KEYBLOCK_KEYVALUE,1,
+ [Whether the krb5_keyblock struct has a keyvalue property])
+ fi
+
+ AC_CACHE_CHECK([for ENCTYPE_ARCFOUR_HMAC_MD5],
+ samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,[
+ AC_TRY_COMPILE([#include <krb5.h>],
+ [krb5_enctype enctype; enctype = ENCTYPE_ARCFOUR_HMAC_MD5;],
+ samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5=yes,
+ samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5=no)])
+
+ if test x"$samba_cv_HAVE_ENCTYPE_ARCFOUR_HMAC_MD5" = x"yes"; then
+ AC_DEFINE(HAVE_ENCTYPE_ARCFOUR_HMAC_MD5,1,
+ [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])])
+ 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])])
+ AC_CHECK_LIB(gssapi_krb5, gss_display_status,
+ [KRB5_LIBS="$KRB5_LIBS -lgssapi_krb5";
+ AC_DEFINE(HAVE_GSSAPI,1,[Whether GSSAPI is available])])
-LIBS="$ac_save_LIBS"; CFLAGS="$ac_save_CFLAGS"
+ CFLAGS="$ac_save_CFLAGS"
+ LIBS="$ac_save_LIBS"
fi
########################################################
@@ -2313,7 +2394,7 @@ if test x"$with_ldap_support" = x"yes"; then
##################################################################
# 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, [LIBS="$LIBS -llber"])
+ AC_CHECK_LIB(lber, ber_scanf)
########################################################
# now see if we can find the ldap libs in standard paths
@@ -2382,7 +2463,7 @@ AC_ARG_WITH(expsam,
;;
nisplussam)
## pdb_nisplussam
- MODULE_pdb_nisplussam=SHARED
+ default_shared_modules="$default_shared_modules pdb_nisplussam"
;;
*)
echo "Unknown module name \"$i\"! Exiting..."
@@ -3554,7 +3635,8 @@ HAVE_WINBIND=yes
# Define the winbind shared library name and any specific linker flags
# it needs to be built with.
-WINBIND_NSS=libnss_winbind.$SHLIBEXT
+WINBIND_NSS="nsswitch/libnss_winbind.$SHLIBEXT"
+WINBIND_WINS_NSS="nsswitch/libnss_wins.$SHLIBEXT"
WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS
case "$host_os" in
@@ -3562,8 +3644,10 @@ case "$host_os" in
WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o"
;;
*irix*)
+ # IRIX has differently named shared libraries
WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_irix.o"
- WINBIND_NSS="libns_winbind.$SHLIBEXT"
+ WINBIND_NSS="nsswitch/libns_winbind.$SHLIBEXT"
+ WINBIND_WINS_NSS="nsswitch/libns_wins.$SHLIBEXT"
;;
*solaris*)
# Solaris winbind client is implemented as a wrapper around
@@ -3576,9 +3660,12 @@ case "$host_os" in
WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o"
;;
*aix*)
+ # AIX has even differently named shared libraries. No
+ # WINS support has been implemented yet.
WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_aix.o"
WINBIND_NSS_LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-ewb_aix_init"
- WINBIND_NSS="WINBIND"
+ WINBIND_NSS="nsswitch/WINBIND"
+ WINBIND_WINS_NSS=""
;;
*)
HAVE_WINBIND=no
@@ -3587,6 +3674,7 @@ case "$host_os" in
esac
AC_SUBST(WINBIND_NSS)
+AC_SUBST(WINBIND_WINS_NSS)
AC_SUBST(WINBIND_NSS_LDSHFLAGS)
AC_SUBST(WINBIND_NSS_EXTRA_OBJS)
AC_SUBST(WINBIND_NSS_EXTRA_LIBS)
@@ -3625,7 +3713,7 @@ if test x"$HAVE_WINBIND" = x"yes"; then
EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/wbinfo\$(EXEEXT)"
EXTRA_SBIN_PROGS="$EXTRA_SBIN_PROGS bin/winbindd\$(EXEEXT)"
if test x"$BLDSHARED" = x"true"; then
- SHLIB_PROGS="$SHLIB_PROGS nsswitch/$WINBIND_NSS"
+ SHLIB_PROGS="$SHLIB_PROGS $WINBIND_NSS $WINBIND_WINS_NSS"
if test x"$with_pam" = x"yes"; then
SHLIB_PROGS="$SHLIB_PROGS nsswitch/pam_winbind.$SHLIBEXT"
@@ -3804,8 +3892,6 @@ SMB_SUBSYSTEM(VFS)
AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
-AC_SUBST(MODULES_CLEAN)
-
#################################################
# do extra things if we are running insure
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c
index 2b7a8526885..ef243ecfc08 100644
--- a/source/groupdb/mapping.c
+++ b/source/groupdb/mapping.c
@@ -37,69 +37,7 @@ PRIVS privs[] = {
{SE_PRIV_PRINT_OPERATOR, "SaPrintOp", "Add or remove printers - Samba" },
{SE_PRIV_ALL, "SaAllPrivs", "all privileges" }
};
-/*
-PRIVS privs[] = {
- { 2, "SeCreateTokenPrivilege" },
- { 3, "SeAssignPrimaryTokenPrivilege" },
- { 4, "SeLockMemoryPrivilege" },
- { 5, "SeIncreaseQuotaPrivilege" },
- { 6, "SeMachineAccountPrivilege" },
- { 7, "SeTcbPrivilege" },
- { 8, "SeSecurityPrivilege" },
- { 9, "SeTakeOwnershipPrivilege" },
- { 10, "SeLoadDriverPrivilege" },
- { 11, "SeSystemProfilePrivilege" },
- { 12, "SeSystemtimePrivilege" },
- { 13, "SeProfileSingleProcessPrivilege" },
- { 14, "SeIncreaseBasePriorityPrivilege" },
- { 15, "SeCreatePagefilePrivilege" },
- { 16, "SeCreatePermanentPrivilege" },
- { 17, "SeBackupPrivilege" },
- { 18, "SeRestorePrivilege" },
- { 19, "SeShutdownPrivilege" },
- { 20, "SeDebugPrivilege" },
- { 21, "SeAuditPrivilege" },
- { 22, "SeSystemEnvironmentPrivilege" },
- { 23, "SeChangeNotifyPrivilege" },
- { 24, "SeRemoteShutdownPrivilege" },
- { 25, "SeUndockPrivilege" },
- { 26, "SeSyncAgentPrivilege" },
- { 27, "SeEnableDelegationPrivilege" },
-};
-*/
-
- /*
- * Those are not really privileges like the other ones.
- * They are handled in a special case and called
- * system privileges.
- *
- * SeNetworkLogonRight
- * SeUnsolicitedInputPrivilege
- * SeBatchLogonRight
- * SeServiceLogonRight
- * SeInteractiveLogonRight
- * SeDenyInteractiveLogonRight
- * SeDenyNetworkLogonRight
- * SeDenyBatchLogonRight
- * SeDenyBatchLogonRight
- */
-#if 0
-/****************************************************************************
-check if the user has the required privilege.
-****************************************************************************/
-static BOOL se_priv_access_check(NT_USER_TOKEN *token, uint32 privilege)
-{
- /* no token, no privilege */
- if (token==NULL)
- return False;
-
- if ((token->privilege & privilege)==privilege)
- return True;
-
- return False;
-}
-#endif
/****************************************************************************
dump the mapping group mapping to a text file
@@ -151,53 +89,35 @@ static BOOL default_group_mapping(void)
fstring str_admins;
fstring str_users;
fstring str_guests;
- LUID_ATTR set;
-
- PRIVILEGE_SET privilege_none;
- PRIVILEGE_SET privilege_all;
- PRIVILEGE_SET privilege_print_op;
-
- init_privilege(&privilege_none);
- init_privilege(&privilege_all);
- init_privilege(&privilege_print_op);
-
- set.attr=0;
- set.luid.high=0;
- set.luid.low=SE_PRIV_PRINT_OPERATOR;
- add_privilege(&privilege_print_op, set);
-
- add_all_privilege(&privilege_all);
/* Add the Wellknown groups */
- add_initial_entry(-1, "S-1-5-32-544", SID_NAME_WKN_GRP, "Administrators", "", privilege_all, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
- add_initial_entry(-1, "S-1-5-32-545", SID_NAME_WKN_GRP, "Users", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
- add_initial_entry(-1, "S-1-5-32-546", SID_NAME_WKN_GRP, "Guests", "", privilege_none, PR_ACCESS_FROM_NETWORK);
- add_initial_entry(-1, "S-1-5-32-547", SID_NAME_WKN_GRP, "Power Users", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-
- add_initial_entry(-1, "S-1-5-32-548", SID_NAME_WKN_GRP, "Account Operators", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
- add_initial_entry(-1, "S-1-5-32-549", SID_NAME_WKN_GRP, "System Operators", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
- add_initial_entry(-1, "S-1-5-32-550", SID_NAME_WKN_GRP, "Print Operators", "", privilege_print_op, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
- add_initial_entry(-1, "S-1-5-32-551", SID_NAME_WKN_GRP, "Backup Operators", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
-
- add_initial_entry(-1, "S-1-5-32-552", SID_NAME_WKN_GRP, "Replicators", "", privilege_none, PR_ACCESS_FROM_NETWORK);
+ add_initial_entry(-1, "S-1-5-32-544", SID_NAME_WKN_GRP, "Administrators", "");
+ add_initial_entry(-1, "S-1-5-32-545", SID_NAME_WKN_GRP, "Users", "");
+ add_initial_entry(-1, "S-1-5-32-546", SID_NAME_WKN_GRP, "Guests", "");
+ add_initial_entry(-1, "S-1-5-32-547", SID_NAME_WKN_GRP, "Power Users", "");
+ add_initial_entry(-1, "S-1-5-32-548", SID_NAME_WKN_GRP, "Account Operators", "");
+ add_initial_entry(-1, "S-1-5-32-549", SID_NAME_WKN_GRP, "System Operators", "");
+ add_initial_entry(-1, "S-1-5-32-550", SID_NAME_WKN_GRP, "Print Operators", "");
+ add_initial_entry(-1, "S-1-5-32-551", SID_NAME_WKN_GRP, "Backup Operators", "");
+ add_initial_entry(-1, "S-1-5-32-552", SID_NAME_WKN_GRP, "Replicators", "");
/* Add the defaults domain groups */
sid_copy(&sid_admins, get_global_sam_sid());
sid_append_rid(&sid_admins, DOMAIN_GROUP_RID_ADMINS);
sid_to_string(str_admins, &sid_admins);
- add_initial_entry(-1, str_admins, SID_NAME_DOM_GRP, "Domain Admins", "", privilege_all, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
+ add_initial_entry(-1, str_admins, SID_NAME_DOM_GRP, "Domain Admins", "");
sid_copy(&sid_users, get_global_sam_sid());
sid_append_rid(&sid_users, DOMAIN_GROUP_RID_USERS);
sid_to_string(str_users, &sid_users);
- add_initial_entry(-1, str_users, SID_NAME_DOM_GRP, "Domain Users", "", privilege_none, PR_ACCESS_FROM_NETWORK|PR_LOG_ON_LOCALLY);
+ add_initial_entry(-1, str_users, SID_NAME_DOM_GRP, "Domain Users", "");
sid_copy(&sid_guests, get_global_sam_sid());
sid_append_rid(&sid_guests, DOMAIN_GROUP_RID_GUESTS);
sid_to_string(str_guests, &sid_guests);
- add_initial_entry(-1, str_guests, SID_NAME_DOM_GRP, "Domain Guests", "", privilege_none, PR_ACCESS_FROM_NETWORK);
+ add_initial_entry(-1, str_guests, SID_NAME_DOM_GRP, "Domain Guests", "");
return True;
}
@@ -255,8 +175,6 @@ static BOOL add_mapping_entry(GROUP_MAP *map, int flag)
pstring key, buf;
fstring string_sid="";
int len;
- int i;
- PRIVILEGE_SET *set;
if(!init_group_mapping()) {
DEBUG(0,("failed to initialize group mapping"));
@@ -265,16 +183,8 @@ static BOOL add_mapping_entry(GROUP_MAP *map, int flag)
sid_to_string(string_sid, &map->sid);
- len = tdb_pack(buf, sizeof(buf), "ddffd",
- map->gid, map->sid_name_use, map->nt_name, map->comment, map->systemaccount);
-
- /* write the privilege list in the TDB database */
-
- set=&map->priv_set;
- len += tdb_pack(buf+len, sizeof(buf)-len, "d", set->count);
- for (i=0; i<set->count; i++)
- len += tdb_pack(buf+len, sizeof(buf)-len, "ddd",
- set->set[i].luid.low, set->set[i].luid.high, set->set[i].attr);
+ len = tdb_pack(buf, sizeof(buf), "ddff",
+ map->gid, map->sid_name_use, map->nt_name, map->comment);
if (len > sizeof(buf))
return False;
@@ -293,8 +203,7 @@ static BOOL add_mapping_entry(GROUP_MAP *map, int flag)
/****************************************************************************
initialise first time the mapping list
****************************************************************************/
-BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use,
- const char *nt_name, const char *comment, PRIVILEGE_SET priv_set, uint32 systemaccount)
+BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_use, const char *nt_name, const char *comment)
{
GROUP_MAP map;
@@ -312,10 +221,6 @@ BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_us
map.sid_name_use=sid_name_use;
fstrcpy(map.nt_name, nt_name);
fstrcpy(map.comment, comment);
- map.systemaccount=systemaccount;
-
- map.priv_set.count=priv_set.count;
- map.priv_set.set=priv_set.set;
pdb_add_group_mapping_entry(&map);
@@ -323,196 +228,15 @@ BOOL add_initial_entry(gid_t gid, const char *sid, enum SID_NAME_USE sid_name_us
}
/****************************************************************************
-initialise a privilege list
-****************************************************************************/
-void init_privilege(PRIVILEGE_SET *priv_set)
-{
- priv_set->count=0;
- priv_set->control=0;
- priv_set->set=NULL;
-}
-
-/****************************************************************************
-free a privilege list
-****************************************************************************/
-BOOL free_privilege(PRIVILEGE_SET *priv_set)
-{
- if (priv_set->count==0) {
- DEBUG(100,("free_privilege: count=0, nothing to clear ?\n"));
- return False;
- }
-
- if (priv_set->set==NULL) {
- DEBUG(0,("free_privilege: list ptr is NULL, very strange !\n"));
- return False;
- }
-
- safe_free(priv_set->set);
- priv_set->count=0;
- priv_set->control=0;
- priv_set->set=NULL;
-
- return True;
-}
-
-/****************************************************************************
-add a privilege to a privilege array
-****************************************************************************/
-BOOL add_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
-{
- LUID_ATTR *new_set;
-
- /* check if the privilege is not already in the list */
- if (check_priv_in_privilege(priv_set, set))
- return False;
-
- /* we can allocate memory to add the new privilege */
-
- new_set=(LUID_ATTR *)Realloc(priv_set->set, (priv_set->count+1)*(sizeof(LUID_ATTR)));
- if (new_set==NULL) {
- DEBUG(0,("add_privilege: could not Realloc memory to add a new privilege\n"));
- return False;
- }
-
- new_set[priv_set->count].luid.high=set.luid.high;
- new_set[priv_set->count].luid.low=set.luid.low;
- new_set[priv_set->count].attr=set.attr;
-
- priv_set->count++;
- priv_set->set=new_set;
-
- return True;
-}
-
-/****************************************************************************
-add all the privileges to a privilege array
-****************************************************************************/
-BOOL add_all_privilege(PRIVILEGE_SET *priv_set)
-{
- LUID_ATTR set;
-
- set.attr=0;
- set.luid.high=0;
-
- set.luid.low=SE_PRIV_ADD_USERS;
- add_privilege(priv_set, set);
-
- set.luid.low=SE_PRIV_ADD_MACHINES;
- add_privilege(priv_set, set);
-
- set.luid.low=SE_PRIV_PRINT_OPERATOR;
- add_privilege(priv_set, set);
-
- return True;
-}
-
-/****************************************************************************
-check if the privilege list is empty
-****************************************************************************/
-BOOL check_empty_privilege(PRIVILEGE_SET *priv_set)
-{
- return (priv_set->count == 0);
-}
-
-/****************************************************************************
-check if the privilege is in the privilege list
-****************************************************************************/
-BOOL check_priv_in_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
-{
- int i;
-
- /* if the list is empty, obviously we can't have it */
- if (check_empty_privilege(priv_set))
- return False;
-
- for (i=0; i<priv_set->count; i++) {
- LUID_ATTR *cur_set;
-
- cur_set=&priv_set->set[i];
- /* check only the low and high part. Checking the attr field has no meaning */
- if( (cur_set->luid.low==set.luid.low) && (cur_set->luid.high==set.luid.high) )
- return True;
- }
-
- return False;
-}
-
-/****************************************************************************
-remove a privilege from a privilege array
-****************************************************************************/
-BOOL remove_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
-{
- LUID_ATTR *new_set;
- LUID_ATTR *old_set;
- int i,j;
-
- /* check if the privilege is in the list */
- if (!check_priv_in_privilege(priv_set, set))
- return False;
-
- /* special case if it's the only privilege in the list */
- if (priv_set->count==1) {
- free_privilege(priv_set);
- init_privilege(priv_set);
-
- return True;
- }
-
- /*
- * the privilege is there, create a new list,
- * and copy the other privileges
- */
-
- old_set=priv_set->set;
-
- new_set=(LUID_ATTR *)malloc((priv_set->count-1)*(sizeof(LUID_ATTR)));
- if (new_set==NULL) {
- DEBUG(0,("remove_privilege: could not malloc memory for new privilege list\n"));
- return False;
- }
-
- for (i=0, j=0; i<priv_set->count; i++) {
- if ((old_set[i].luid.low==set.luid.low) &&
- (old_set[i].luid.high==set.luid.high)) {
- continue;
- }
-
- new_set[j].luid.low=old_set[i].luid.low;
- new_set[j].luid.high=old_set[i].luid.high;
- new_set[j].attr=old_set[i].attr;
-
- j++;
- }
-
- if (j!=priv_set->count-1) {
- DEBUG(0,("remove_privilege: mismatch ! difference is not -1\n"));
- DEBUGADD(0,("old count:%d, new count:%d\n", priv_set->count, j));
- safe_free(new_set);
- return False;
- }
-
- /* ok everything is fine */
-
- priv_set->count--;
- priv_set->set=new_set;
-
- safe_free(old_set);
-
- return True;
-}
-
-/****************************************************************************
Return the sid and the type of the unix group.
****************************************************************************/
-static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
+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 i;
- PRIVILEGE_SET *set;
if(!init_group_mapping()) {
DEBUG(0,("failed to initialize group mapping"));
@@ -531,34 +255,10 @@ static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
if (!dbuf.dptr)
return False;
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
- &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->systemaccount);
-
- set=&map->priv_set;
- init_privilege(set);
- ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
-
- DEBUG(10,("get_group_map_from_sid: %d privileges\n", map->priv_set.count));
-
- set->set = NULL;
- if (set->count) {
- set->set=(LUID_ATTR *)smb_xmalloc(set->count*sizeof(LUID_ATTR));
- }
-
- for (i=0; i<set->count; i++)
- ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd",
- &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
+ ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
+ &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
SAFE_FREE(dbuf.dptr);
- if (ret != dbuf.dsize) {
- DEBUG(0,("get_group_map_from_sid: group mapping TDB corrupted ?\n"));
- free_privilege(set);
- return False;
- }
-
- /* we don't want the privileges */
- if (with_priv==MAPPING_WITHOUT_PRIV)
- free_privilege(set);
sid_copy(&map->sid, &sid);
@@ -569,13 +269,11 @@ static BOOL get_group_map_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
Return the sid and the type of the unix group.
****************************************************************************/
-static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv)
+static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map)
{
TDB_DATA kbuf, dbuf, newkey;
fstring string_sid;
int ret;
- int i;
- PRIVILEGE_SET *set;
if(!init_group_mapping()) {
DEBUG(0,("failed to initialize group mapping"));
@@ -598,33 +296,15 @@ static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv)
string_to_sid(&map->sid, string_sid);
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
- &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->systemaccount);
-
- set=&map->priv_set;
- ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
- set->set = NULL;
- if (set->count) {
- set->set=(LUID_ATTR *)smb_xmalloc(set->count*sizeof(LUID_ATTR));
- }
-
- for (i=0; i<set->count; i++)
- ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd",
- &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
+ ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
+ &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
SAFE_FREE(dbuf.dptr);
- if (ret != dbuf.dsize){
- free_privilege(set);
- continue;
- }
if (gid==map->gid) {
- if (!with_priv)
- free_privilege(&map->priv_set);
+ SAFE_FREE(kbuf.dptr);
return True;
}
-
- free_privilege(set);
}
return False;
@@ -634,13 +314,11 @@ static BOOL get_group_map_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv)
Return the sid and the type of the unix group.
****************************************************************************/
-static BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map, BOOL with_priv)
+static BOOL get_group_map_from_ntname(const char *name, GROUP_MAP *map)
{
TDB_DATA kbuf, dbuf, newkey;
fstring string_sid;
int ret;
- int i;
- PRIVILEGE_SET *set;
if(!init_group_mapping()) {
DEBUG(0,("get_group_map_from_ntname:failed to initialize group mapping"));
@@ -663,35 +341,15 @@ static BOOL get_group_map_from_ntname(char *name, GROUP_MAP *map, BOOL with_priv
string_to_sid(&map->sid, string_sid);
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
- &map->gid, &map->sid_name_use, &map->nt_name, &map->comment, &map->systemaccount);
-
- set=&map->priv_set;
- ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
-
- set->set=(LUID_ATTR *)malloc(set->count*sizeof(LUID_ATTR));
- if (set->set==NULL) {
- DEBUG(0,("get_group_map_from_ntname: could not allocate memory for privileges\n"));
- return False;
- }
-
- for (i=0; i<set->count; i++)
- ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd",
- &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
+ ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
+ &map->gid, &map->sid_name_use, &map->nt_name, &map->comment);
SAFE_FREE(dbuf.dptr);
- if (ret != dbuf.dsize) {
- free_privilege(set);
- continue;
- }
if (StrCaseCmp(name, map->nt_name)==0) {
- if (!with_priv)
- free_privilege(&map->priv_set);
+ SAFE_FREE(kbuf.dptr);
return True;
}
-
- free_privilege(set);
}
return False;
@@ -737,7 +395,7 @@ static BOOL group_map_remove(DOM_SID sid)
****************************************************************************/
static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
- int *num_entries, BOOL unix_only, BOOL with_priv)
+ int *num_entries, BOOL unix_only)
{
TDB_DATA kbuf, dbuf, newkey;
fstring string_sid;
@@ -746,8 +404,6 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
GROUP_MAP *mapt;
int ret;
int entries=0;
- int i;
- PRIVILEGE_SET *set;
if(!init_group_mapping()) {
DEBUG(0,("failed to initialize group mapping"));
@@ -770,43 +426,19 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
fstrcpy(string_sid, kbuf.dptr+strlen(GROUP_PREFIX));
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddffd",
- &map.gid, &map.sid_name_use, &map.nt_name, &map.comment, &map.systemaccount);
-
- set=&map.priv_set;
- init_privilege(set);
-
- ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "d", &set->count);
-
- if (set->count!=0) {
- set->set=(LUID_ATTR *)malloc(set->count*sizeof(LUID_ATTR));
- if (set->set==NULL) {
- DEBUG(0,("enum_group_mapping: could not allocate memory for privileges\n"));
- return False;
- }
- }
-
- for (i=0; i<set->count; i++)
- ret += tdb_unpack(dbuf.dptr+ret, dbuf.dsize-ret, "ddd",
- &(set->set[i].luid.low), &(set->set[i].luid.high), &(set->set[i].attr));
+ ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddff",
+ &map.gid, &map.sid_name_use, &map.nt_name, &map.comment);
SAFE_FREE(dbuf.dptr);
- if (ret != dbuf.dsize) {
- DEBUG(11,("enum_group_mapping: error in memory size\n"));
- free_privilege(set);
- 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));
- free_privilege(set);
continue;
}
if (unix_only==ENUM_ONLY_MAPPED && map.gid==-1) {
DEBUG(11,("enum_group_mapping: group %s is non mapped\n", map.nt_name));
- free_privilege(set);
continue;
}
@@ -819,7 +451,6 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
if (!mapt) {
DEBUG(0,("enum_group_mapping: Unable to enlarge group map!\n"));
SAFE_FREE(*rmap);
- free_privilege(set);
return False;
}
else
@@ -830,12 +461,6 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
mapt[entries].sid_name_use = map.sid_name_use;
fstrcpy(mapt[entries].nt_name, map.nt_name);
fstrcpy(mapt[entries].comment, map.comment);
- mapt[entries].systemaccount=map.systemaccount;
- mapt[entries].priv_set.count=set->count;
- mapt[entries].priv_set.control=set->control;
- mapt[entries].priv_set.set=set->set;
- if (!with_priv)
- free_privilege(&(mapt[entries].priv_set));
entries++;
@@ -846,64 +471,6 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
return True;
}
-
-/****************************************************************************
-convert a privilege string to a privilege array
-****************************************************************************/
-void convert_priv_from_text(PRIVILEGE_SET *se_priv, char *privilege)
-{
- pstring tok;
- const char *p = privilege;
- int i;
- LUID_ATTR set;
-
- /* By default no privilege */
- init_privilege(se_priv);
-
- if (privilege==NULL)
- return;
-
- while(next_token(&p, tok, " ", sizeof(tok)) ) {
- for (i=0; i<=PRIV_ALL_INDEX; i++) {
- if (StrCaseCmp(privs[i].priv, tok)==0) {
- set.attr=0;
- set.luid.high=0;
- set.luid.low=privs[i].se_priv;
- add_privilege(se_priv, set);
- }
- }
- }
-}
-
-/****************************************************************************
-convert a privilege array to a privilege string
-****************************************************************************/
-void convert_priv_to_text(PRIVILEGE_SET *se_priv, char *privilege)
-{
- int i,j;
-
- if (privilege==NULL)
- return;
-
- ZERO_STRUCTP(privilege);
-
- if (check_empty_privilege(se_priv)) {
- fstrcat(privilege, "No privilege");
- return;
- }
-
- for(i=0; i<se_priv->count; i++) {
- j=1;
- while (privs[j].se_priv!=se_priv->set[i].luid.low && j<=PRIV_ALL_INDEX) {
- j++;
- }
-
- fstrcat(privilege, privs[j].priv);
- fstrcat(privilege, " ");
- }
-}
-
-
/*
*
* High level functions
@@ -916,7 +483,7 @@ void convert_priv_to_text(PRIVILEGE_SET *se_priv, char *privilege)
/* get a domain group from it's SID */
-BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
+BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map)
{
struct group *grp;
@@ -928,23 +495,19 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
DEBUG(10, ("get_domain_group_from_sid\n"));
/* if the group is NOT in the database, it CAN NOT be a domain group */
- if(!pdb_getgrsid(map, sid, with_priv))
+ if(!pdb_getgrsid(map, sid))
return False;
DEBUG(10, ("get_domain_group_from_sid: SID found in the TDB\n"));
/* if it's not a domain group, continue */
if (map->sid_name_use!=SID_NAME_DOM_GRP) {
- if (with_priv)
- free_privilege(&map->priv_set);
return False;
}
DEBUG(10, ("get_domain_group_from_sid: SID is a domain group\n"));
if (map->gid==-1) {
- if (with_priv)
- free_privilege(&map->priv_set);
return False;
}
@@ -952,8 +515,6 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
if ( (grp=getgrgid(map->gid)) == NULL) {
DEBUG(10, ("get_domain_group_from_sid: gid DOESN'T exist in UNIX security\n"));
- if (with_priv)
- free_privilege(&map->priv_set);
return False;
}
@@ -965,7 +526,7 @@ BOOL get_domain_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
/* get a local (alias) group from it's SID */
-BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
+BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map)
{
struct group *grp;
@@ -975,22 +536,16 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
}
/* The group is in the mapping table */
- if(pdb_getgrsid(map, sid, with_priv)) {
+ if(pdb_getgrsid(map, sid)) {
if (map->sid_name_use!=SID_NAME_ALIAS) {
- if (with_priv)
- free_privilege(&map->priv_set);
return False;
}
if (map->gid==-1) {
- if (with_priv)
- free_privilege(&map->priv_set);
return False;
}
if ( (grp=getgrgid(map->gid)) == NULL) {
- if (with_priv)
- free_privilege(&map->priv_set);
return False;
}
} else {
@@ -1005,13 +560,10 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
return False;
map->sid_name_use=SID_NAME_ALIAS;
- map->systemaccount=PR_ACCESS_FROM_NETWORK;
fstrcpy(map->nt_name, grp->gr_name);
fstrcpy(map->comment, "Local Unix Group");
- init_privilege(&map->priv_set);
-
sid_copy(&map->sid, &sid);
}
@@ -1020,7 +572,7 @@ BOOL get_local_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
/* get a builtin group from it's SID */
-BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
+BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map)
{
struct group *grp;
@@ -1029,24 +581,18 @@ BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
return(False);
}
- if(!pdb_getgrsid(map, sid, with_priv))
+ if(!pdb_getgrsid(map, sid))
return False;
if (map->sid_name_use!=SID_NAME_WKN_GRP) {
- if (with_priv)
- free_privilege(&map->priv_set);
return False;
}
if (map->gid==-1) {
- if (with_priv)
- free_privilege(&map->priv_set);
return False;
}
if ( (grp=getgrgid(map->gid)) == NULL) {
- if (with_priv)
- free_privilege(&map->priv_set);
return False;
}
@@ -1058,7 +604,7 @@ BOOL get_builtin_group_from_sid(DOM_SID sid, GROUP_MAP *map, BOOL with_priv)
/****************************************************************************
Returns a GROUP_MAP struct based on the gid.
****************************************************************************/
-BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv)
+BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
{
struct group *grp;
@@ -1073,11 +619,9 @@ BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map, BOOL with_priv)
/*
* make a group map from scratch if doesn't exist.
*/
- if (!pdb_getgrgid(map, gid, with_priv)) {
+ if (!pdb_getgrgid(map, gid)) {
map->gid=gid;
map->sid_name_use=SID_NAME_ALIAS;
- map->systemaccount=PR_ACCESS_FROM_NETWORK;
- init_privilege(&map->priv_set);
/* interim solution until we have a last RID allocated */
@@ -1281,23 +825,23 @@ int smb_delete_user_group(const char *unix_group, const char *unix_user)
NTSTATUS pdb_default_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
- DOM_SID sid, BOOL with_priv)
+ DOM_SID sid)
{
- return get_group_map_from_sid(sid, map, with_priv) ?
+ return get_group_map_from_sid(sid, map) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
NTSTATUS pdb_default_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
- gid_t gid, BOOL with_priv)
+ gid_t gid)
{
- return get_group_map_from_gid(gid, map, with_priv) ?
+ return get_group_map_from_gid(gid, map) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
NTSTATUS pdb_default_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
- char *name, BOOL with_priv)
+ const char *name)
{
- return get_group_map_from_ntname(name, map, with_priv) ?
+ return get_group_map_from_ntname(name, map) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
@@ -1325,10 +869,9 @@ NTSTATUS pdb_default_delete_group_mapping_entry(struct pdb_methods *methods,
NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods,
enum SID_NAME_USE sid_name_use,
GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only, BOOL with_priv)
+ BOOL unix_only)
{
- return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only,
- with_priv) ?
+ return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
@@ -1337,19 +880,19 @@ NTSTATUS pdb_default_enum_group_mapping(struct pdb_methods *methods,
*********************************************************************/
NTSTATUS pdb_nop_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
- DOM_SID sid, BOOL with_priv)
+ DOM_SID sid)
{
return NT_STATUS_UNSUCCESSFUL;
}
NTSTATUS pdb_nop_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
- gid_t gid, BOOL with_priv)
+ gid_t gid)
{
return NT_STATUS_UNSUCCESSFUL;
}
NTSTATUS pdb_nop_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
- char *name, BOOL with_priv)
+ const char *name)
{
return NT_STATUS_UNSUCCESSFUL;
}
@@ -1375,7 +918,7 @@ NTSTATUS pdb_nop_delete_group_mapping_entry(struct pdb_methods *methods,
NTSTATUS pdb_nop_enum_group_mapping(struct pdb_methods *methods,
enum SID_NAME_USE sid_name_use,
GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only, BOOL with_priv)
+ BOOL unix_only)
{
return NT_STATUS_UNSUCCESSFUL;
}
diff --git a/source/include/ads.h b/source/include/ads.h
index 7f7568d8b0e..0961c9581c9 100644
--- a/source/include/ads.h
+++ b/source/include/ads.h
@@ -205,6 +205,7 @@ typedef void **ADS_MODLIST;
#define ADS_AUTH_NO_BIND 0x02
#define ADS_AUTH_ANON_BIND 0x04
#define ADS_AUTH_SIMPLE_BIND 0x08
+#define ADS_AUTH_ALLOW_NTLMSSP 0x10
/* Kerberos environment variable names */
#define KRB5_ENV_CCNAME "KRB5CCNAME"
diff --git a/source/include/idmap.h b/source/include/idmap.h
index 4b38128c2f2..47f396e637f 100644
--- a/source/include/idmap.h
+++ b/source/include/idmap.h
@@ -1,3 +1,5 @@
+#ifndef _IDMAP_H_
+#define _IDMAP_H_
/*
Unix SMB/CIFS implementation.
@@ -32,8 +34,7 @@
#define ID_TYPEMASK 0x0f
-#define ID_NOMAP 0x10
-#define ID_CACHE 0x20
+#define ID_QUERY_ONLY 0x10
/* Filled out by IDMAP backends */
struct idmap_methods {
@@ -51,4 +52,4 @@ struct idmap_methods {
/* Called to dump backend status */
void (*status)(void);
};
-
+#endif /* _IDMAP_H_ */
diff --git a/source/include/includes.h b/source/include/includes.h
index 7b4c8dbdff5..edaeda3abed 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -441,6 +441,14 @@
#include <attr/xattr.h>
#endif
+#if HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#if HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
/* Special macros that are no-ops except when run under Valgrind on
* x86. They've moved a little bit from valgrind 1.0.4 to 1.9.4 */
#if HAVE_VALGRIND_MEMCHECK_H
@@ -1035,10 +1043,6 @@ int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
int vasprintf(char **ptr, const char *format, va_list ap);
#endif
-#if !defined(HAVE_BZERO) && defined(HAVE_MEMSET)
-#define bzero(a,b) memset((a),'\0',(b))
-#endif
-
#ifdef REPLACE_GETPASS
#define getpass(prompt) getsmbpass((prompt))
#endif
diff --git a/source/include/mapping.h b/source/include/mapping.h
index d4f2d28e6a1..fdaa2b04532 100644
--- a/source/include/mapping.h
+++ b/source/include/mapping.h
@@ -19,29 +19,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#define PRIV_ALL_INDEX 5
-
-#define SE_PRIV_NONE 0x0000
-#define SE_PRIV_ADD_MACHINES 0x0006
-#define SE_PRIV_SEC_PRIV 0x0008
-#define SE_PRIV_TAKE_OWNER 0x0009
-#define SE_PRIV_ADD_USERS 0xff01
-#define SE_PRIV_PRINT_OPERATOR 0xff03
-#define SE_PRIV_ALL 0xffff
-
#define ENUM_ONLY_MAPPED True
#define ENUM_ALL_MAPPED False
-#define MAPPING_WITH_PRIV True
-#define MAPPING_WITHOUT_PRIV False
-
-#define PR_NONE 0x0000
-#define PR_LOG_ON_LOCALLY 0x0001
-#define PR_ACCESS_FROM_NETWORK 0x0002
-#define PR_LOG_ON_BATCH_JOB 0x0004
-#define PR_LOG_ON_SERVICE 0x0010
-
-
typedef struct _GROUP_MAP {
struct pdb_methods *methods;
gid_t gid;
@@ -49,13 +29,5 @@ typedef struct _GROUP_MAP {
enum SID_NAME_USE sid_name_use;
fstring nt_name;
fstring comment;
- uint32 systemaccount;
- PRIVILEGE_SET priv_set;
} GROUP_MAP;
-typedef struct _PRIVS {
- uint32 se_priv;
- const char *priv;
- const char *description;
-} PRIVS;
-
diff --git a/source/include/passdb.h b/source/include/passdb.h
index e14e250d345..aeddcbcb3ae 100644
--- a/source/include/passdb.h
+++ b/source/include/passdb.h
@@ -203,14 +203,11 @@ typedef struct pdb_context
NTSTATUS (*pdb_delete_sam_account)(struct pdb_context *, SAM_ACCOUNT *username);
- NTSTATUS (*pdb_getgrsid)(struct pdb_context *context, GROUP_MAP *map,
- DOM_SID sid, BOOL with_priv);
+ NTSTATUS (*pdb_getgrsid)(struct pdb_context *context, GROUP_MAP *map, DOM_SID sid);
- NTSTATUS (*pdb_getgrgid)(struct pdb_context *context, GROUP_MAP *map,
- gid_t gid, BOOL with_priv);
+ NTSTATUS (*pdb_getgrgid)(struct pdb_context *context, GROUP_MAP *map, gid_t gid);
- NTSTATUS (*pdb_getgrnam)(struct pdb_context *context, GROUP_MAP *map,
- char *name, BOOL with_priv);
+ NTSTATUS (*pdb_getgrnam)(struct pdb_context *context, GROUP_MAP *map, const char *name);
NTSTATUS (*pdb_add_group_mapping_entry)(struct pdb_context *context,
GROUP_MAP *map);
@@ -224,7 +221,7 @@ typedef struct pdb_context
NTSTATUS (*pdb_enum_group_mapping)(struct pdb_context *context,
enum SID_NAME_USE sid_name_use,
GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only, BOOL with_priv);
+ BOOL unix_only);
void (*free_fn)(struct pdb_context **);
@@ -257,14 +254,11 @@ typedef struct pdb_methods
NTSTATUS (*delete_sam_account)(struct pdb_methods *, SAM_ACCOUNT *username);
- NTSTATUS (*getgrsid)(struct pdb_methods *methods, GROUP_MAP *map,
- DOM_SID sid, BOOL with_priv);
+ NTSTATUS (*getgrsid)(struct pdb_methods *methods, GROUP_MAP *map, DOM_SID sid);
- NTSTATUS (*getgrgid)(struct pdb_methods *methods, GROUP_MAP *map,
- gid_t gid, BOOL with_priv);
+ NTSTATUS (*getgrgid)(struct pdb_methods *methods, GROUP_MAP *map, gid_t gid);
- NTSTATUS (*getgrnam)(struct pdb_methods *methods, GROUP_MAP *map,
- char *name, BOOL with_priv);
+ NTSTATUS (*getgrnam)(struct pdb_methods *methods, GROUP_MAP *map, const char *name);
NTSTATUS (*add_group_mapping_entry)(struct pdb_methods *methods,
GROUP_MAP *map);
@@ -278,7 +272,7 @@ typedef struct pdb_methods
NTSTATUS (*enum_group_mapping)(struct pdb_methods *methods,
enum SID_NAME_USE sid_name_use,
GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only, BOOL with_priv);
+ BOOL unix_only);
void *private_data; /* Private data of some kind */
diff --git a/source/include/privileges.h b/source/include/privileges.h
index 404c5d246bc..67d8a2cbcc1 100644
--- a/source/include/privileges.h
+++ b/source/include/privileges.h
@@ -23,6 +23,22 @@
#ifndef PRIVILEGES_H
#define PRIVILEGES_H
+#define PRIV_ALL_INDEX 5
+
+#define SE_PRIV_NONE 0x0000
+#define SE_PRIV_ADD_MACHINES 0x0006
+#define SE_PRIV_SEC_PRIV 0x0008
+#define SE_PRIV_TAKE_OWNER 0x0009
+#define SE_PRIV_ADD_USERS 0xff01
+#define SE_PRIV_PRINT_OPERATOR 0xff03
+#define SE_PRIV_ALL 0xffff
+
+#define PR_NONE 0x0000
+#define PR_LOG_ON_LOCALLY 0x0001
+#define PR_ACCESS_FROM_NETWORK 0x0002
+#define PR_LOG_ON_BATCH_JOB 0x0004
+#define PR_LOG_ON_SERVICE 0x0010
+
typedef struct LUID
{
uint32 low;
@@ -42,4 +58,11 @@ typedef struct privilege_set
LUID_ATTR *set;
} PRIVILEGE_SET;
-#endif /* _RPC_LSA_H */
+typedef struct _PRIVS {
+ uint32 se_priv;
+ const char *priv;
+ const char *description;
+} PRIVS;
+
+
+#endif /* PRIVILEGES_H */
diff --git a/source/include/smb.h b/source/include/smb.h
index 27c966914fb..f18391516f7 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -1618,4 +1618,15 @@ typedef struct {
#include "popt_common.h"
+#define PORT_NONE 0
+#ifndef LDAP_PORT
+#define LDAP_PORT 389
+#endif
+
+/* used by the IP comparison function */
+struct ip_service {
+ struct in_addr ip;
+ unsigned port;
+};
+
#endif /* _SMB_H */
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index aae3b46f7a4..40b114a6b9e 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -202,6 +202,7 @@ true if two IP addresses are equal
****************************************************************************/
#define ip_equal(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
+#define ip_service_equal(ip1,ip2) ( ((ip1).ip.s_addr == (ip2).ip.s_addr) && ((ip1).port == (ip2).port) )
/*****************************************************************
splits out the last subkey of a key
@@ -247,4 +248,11 @@ copy an IP address from one buffer to another
#define dos_format(fname) string_replace(fname,'/','\\')
+/*****************************************************************************
+ Check to see if we are a DO for this domain
+*****************************************************************************/
+
+#define IS_DC_FOR_DOMAIN(x) ( (lp_server_role()==ROLE_DOMAIN_PDC || lp_server_role()==ROLE_DOMAIN_BDC) \
+ && strequal((x), lp_workgroup()) )
+
#endif /* _SMB_MACROS_H */
diff --git a/source/include/smbldap.h b/source/include/smbldap.h
index 987206b4505..5f3606aa32c 100644
--- a/source/include/smbldap.h
+++ b/source/include/smbldap.h
@@ -19,11 +19,11 @@
*/
-#ifdef HAVE_LDAP
-
#ifndef _SMBLDAP_H
#define _SMBLDAP_H
+#ifdef HAVE_LDAP
+
/* specify schema versions between 2.2. and 3.0 */
#define SCHEMAVER_SAMBAACCOUNT 1
@@ -92,6 +92,7 @@ typedef struct _attrib_map_entry {
const char *name;
} ATTRIB_MAP_ENTRY;
+
/* structures */
extern ATTRIB_MAP_ENTRY attrib_map_v22[];
@@ -108,10 +109,30 @@ extern ATTRIB_MAP_ENTRY sidmap_attr_list[];
const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key );
char** get_attr_list( ATTRIB_MAP_ENTRY table[] );
void free_attr_list( char **list );
-BOOL fetch_ldap_pw(char **dn, char** pw);
-void ldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value);
+void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value);
+void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
+ LDAPMod ***mods,
+ const char *attribute, const char *newval);
+
+/**
+ * Struct to keep the state for all the ldap stuff
+ *
+ */
+
+struct smbldap_state {
+ LDAP *ldap_struct;
+ time_t last_ping;
+ /* retrive-once info */
+ const char *uri;
+ char *bind_dn;
+ char *bind_secret;
+
+ unsigned int num_failures;
+};
+
+#endif /* HAVE_LDAP */
+struct smbldap_state;
#endif /* _SMBLDAP_H */
-#endif /* HAVE_LDAP */
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index 708ef343e1a..55cf73d2b11 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -55,6 +55,30 @@ static const char *charset_name(charset_t ch)
else if (ch == CH_DISPLAY) ret = lp_display_charset();
else if (ch == CH_UTF8) ret = "UTF8";
+#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
+ if (ret && strcasecmp(ret, "LOCALE") == 0) {
+ const char *ln = NULL;
+
+#ifdef HAVE_SETLOCALE
+ setlocale(LC_ALL, "");
+#endif
+ ln = nl_langinfo(CODESET);
+ if (ln) {
+ /* Check whether the charset name is supported
+ by iconv */
+ smb_iconv_t handle = smb_iconv_open(ln,"UCS-2LE");
+ if (handle == (smb_iconv_t) -1) {
+ DEBUG(5,("Locale charset '%s' unsupported, using ASCII instead\n", ln));
+ ln = NULL;
+ } else {
+ DEBUG(5,("Substituting charset '%s' for LOCALE\n", ln));
+ smb_iconv_close(handle);
+ }
+ }
+ ret = ln;
+ }
+#endif
+
if (!ret || !*ret) ret = "ASCII";
return ret;
}
diff --git a/source/lib/gencache.c b/source/lib/gencache.c
index 40b4d1390dc..f3740e3e127 100644
--- a/source/lib/gencache.c
+++ b/source/lib/gencache.c
@@ -319,9 +319,8 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
while (node) {
/* ensure null termination of the key string */
- node->node_key.dptr[node->node_key.dsize] = '\0';
- keystr = node->node_key.dptr;
-
+ keystr = strndup(node->node_key.dptr, node->node_key.dsize);
+
/*
* We don't use gencache_get function, because we need to iterate through
* all of the entries. Validity verification is up to fn routine.
@@ -329,6 +328,8 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
databuf = tdb_fetch(cache, node->node_key);
if (!databuf.dptr || databuf.dsize <= TIMEOUT_LEN) {
SAFE_FREE(databuf.dptr);
+ SAFE_FREE(keystr);
+ node = node->next;
continue;
}
entry = strndup(databuf.dptr, databuf.dsize);
@@ -342,8 +343,30 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
SAFE_FREE(valstr);
SAFE_FREE(entry);
+ SAFE_FREE(keystr);
node = node->next;
}
tdb_search_list_free(first_node);
}
+
+/********************************************************************
+ lock a key
+********************************************************************/
+
+int gencache_lock_entry( const char *key )
+{
+ return tdb_lock_bystring(cache, key, 0);
+}
+
+/********************************************************************
+ unlock a key
+********************************************************************/
+
+void gencache_unlock_entry( const char *key )
+{
+ tdb_unlock_bystring(cache, key);
+ return;
+}
+
+
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index bb37222d5af..84017873177 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -1,7 +1,11 @@
/*
Unix SMB/CIFS mplementation.
LDAP protocol helper functions for SAMBA
+ Copyright (C) Jean François Micouleau 1998
Copyright (C) Gerald Carter 2001-2003
+ Copyright (C) Shahms King 2001
+ Copyright (C) Andrew Bartlett 2002-2003
+ Copyright (C) Stefan (metze) Metzmacher 2002
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,6 +26,16 @@
#include "includes.h"
#include "smbldap.h"
+#ifndef LDAP_OPT_SUCCESS
+#define LDAP_OPT_SUCCESS 0
+#endif
+
+/* Try not to hit the up or down server forever */
+
+#define SMBLDAP_DONT_PING_TIME 10 /* ping only all 10 seconds */
+#define SMBLDAP_NUM_RETRIES 8 /* retry only 8 times */
+
+
/* attributes used by Samba 2.2 */
ATTRIB_MAP_ENTRY attrib_map_v22[] = {
@@ -133,7 +147,7 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
perform a simple table lookup and return the attribute name
**********************************************************************/
-const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
+ const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
{
int i = 0;
@@ -151,7 +165,7 @@ const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
Return the list of attribute names from a mapping table
**********************************************************************/
-char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
+ char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
{
char **names;
int i = 0;
@@ -180,7 +194,7 @@ char** get_attr_list( ATTRIB_MAP_ENTRY table[] )
Cleanup
********************************************************************/
-void free_attr_list( char **list )
+ void free_attr_list( char **list )
{
int i = 0;
@@ -262,7 +276,7 @@ BOOL fetch_ldap_pw(char **dn, char** pw)
manage memory used by the array, by each struct, and values
***********************************************************************/
-void ldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
+ void smbldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
{
LDAPMod **mods;
int i;
@@ -344,3 +358,715 @@ void ldap_set_mod (LDAPMod *** modlist, int modop, const char *attribute, const
*modlist = mods;
}
+
+/**********************************************************************
+ Set attribute to newval in LDAP, regardless of what value the
+ attribute had in LDAP before.
+*********************************************************************/
+ void smbldap_make_mod(LDAP *ldap_struct, LDAPMessage *existing,
+ LDAPMod ***mods,
+ const char *attribute, const char *newval)
+{
+ char **values = NULL;
+
+ if (existing != NULL) {
+ values = ldap_get_values(ldap_struct, existing, attribute);
+ }
+
+ /* all of our string attributes are case insensitive */
+
+ if ((values != NULL) && (values[0] != NULL) &&
+ StrCaseCmp(values[0], newval) == 0)
+ {
+
+ /* Believe it or not, but LDAP will deny a delete and
+ an add at the same time if the values are the
+ same... */
+
+ ldap_value_free(values);
+ return;
+ }
+
+ /* Regardless of the real operation (add or modify)
+ we add the new value here. We rely on deleting
+ the old value, should it exist. */
+
+ if ((newval != NULL) && (strlen(newval) > 0)) {
+ smbldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
+ }
+
+ if (values == NULL) {
+ /* There has been no value before, so don't delete it.
+ Here's a possible race: We might end up with
+ duplicate attributes */
+ return;
+ }
+
+ /* By deleting exactly the value we found in the entry this
+ should be race-free in the sense that the LDAP-Server will
+ deny the complete operation if somebody changed the
+ attribute behind our back. */
+
+ smbldap_set_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
+ ldap_value_free(values);
+}
+
+
+/**********************************************************************
+ Some varients of the LDAP rebind code do not pass in the third 'arg'
+ pointer to a void*, so we try and work around it by assuming that the
+ value of the 'LDAP *' pointer is the same as the one we had passed in
+ **********************************************************************/
+
+struct smbldap_state_lookup {
+ LDAP *ld;
+ struct smbldap_state *smbldap_state;
+ struct smbldap_state_lookup *prev, *next;
+};
+
+static struct smbldap_state_lookup *smbldap_state_lookup_list;
+
+static struct smbldap_state *smbldap_find_state(LDAP *ld)
+{
+ struct smbldap_state_lookup *t;
+
+ for (t = smbldap_state_lookup_list; t; t = t->next) {
+ if (t->ld == ld) {
+ return t->smbldap_state;
+ }
+ }
+ return NULL;
+}
+
+static void smbldap_delete_state(struct smbldap_state *smbldap_state)
+{
+ struct smbldap_state_lookup *t;
+
+ for (t = smbldap_state_lookup_list; t; t = t->next) {
+ if (t->smbldap_state == smbldap_state) {
+ DLIST_REMOVE(smbldap_state_lookup_list, t);
+ SAFE_FREE(t);
+ return;
+ }
+ }
+}
+
+static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
+{
+ struct smbldap_state *tmp_ldap_state;
+ struct smbldap_state_lookup *t;
+ struct smbldap_state_lookup *tmp;
+
+ if ((tmp_ldap_state = smbldap_find_state(ld))) {
+ SMB_ASSERT(tmp_ldap_state == smbldap_state);
+ return;
+ }
+
+ t = smb_xmalloc(sizeof(*t));
+ ZERO_STRUCTP(t);
+
+ DLIST_ADD_END(smbldap_state_lookup_list, t, tmp);
+ t->ld = ld;
+ t->smbldap_state = smbldap_state;
+}
+
+/*******************************************************************
+ open a connection to the ldap server.
+******************************************************************/
+static int smbldap_open_connection (struct smbldap_state *ldap_state)
+
+{
+ int rc = LDAP_SUCCESS;
+ int version;
+ BOOL ldap_v3 = False;
+ LDAP **ldap_struct = &ldap_state->ldap_struct;
+
+#ifdef HAVE_LDAP_INITIALIZE
+ DEBUG(10, ("smbldap_open_connection: %s\n", ldap_state->uri));
+
+ if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
+ DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
+ return rc;
+ }
+#else
+
+ /* Parse the string manually */
+
+ {
+ int port = 0;
+ fstring protocol;
+ fstring host;
+ const char *p = ldap_state->uri;
+ SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
+
+ /* skip leading "URL:" (if any) */
+ if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
+ p += 4;
+ }
+
+ sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
+
+ if (port == 0) {
+ if (strequal(protocol, "ldap")) {
+ port = LDAP_PORT;
+ } else if (strequal(protocol, "ldaps")) {
+ port = LDAPS_PORT;
+ } else {
+ DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
+ }
+ }
+
+ if ((*ldap_struct = ldap_init(host, port)) == NULL) {
+ DEBUG(0, ("ldap_init failed !\n"));
+ return LDAP_OPERATIONS_ERROR;
+ }
+
+ if (strequal(protocol, "ldaps")) {
+#ifdef LDAP_OPT_X_TLS
+ int tls = LDAP_OPT_X_TLS_HARD;
+ if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("Failed to setup a TLS session\n"));
+ }
+
+ DEBUG(3,("LDAPS option set...!\n"));
+#else
+ DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));
+ return LDAP_OPERATIONS_ERROR;
+#endif
+ }
+ }
+#endif
+
+ /* Store the LDAP pointer in a lookup list */
+
+ smbldap_store_state(*ldap_struct, ldap_state);
+
+ /* Upgrade to LDAPv3 if possible */
+
+ if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
+ {
+ if (version != LDAP_VERSION3)
+ {
+ version = LDAP_VERSION3;
+ if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
+ ldap_v3 = True;
+ }
+ } else {
+ ldap_v3 = True;
+ }
+ }
+
+ if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
+#ifdef LDAP_OPT_X_TLS
+ if (ldap_v3) {
+ if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
+ {
+ DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
+ ldap_err2string(rc)));
+ return rc;
+ }
+ DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
+ } else {
+
+ DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
+ return LDAP_OPERATIONS_ERROR;
+ }
+#else
+ DEBUG(0,("smbldap_open_connection: StartTLS not supported by LDAP client libraries!\n"));
+ return LDAP_OPERATIONS_ERROR;
+#endif
+ }
+
+ DEBUG(2, ("smbldap_open_connection: connection opened\n"));
+ return rc;
+}
+
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ This version takes a void* that we can shove useful stuff in :-)
+******************************************************************/
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+#else
+static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
+ int *methodp, int freeit, void *arg)
+{
+ struct smbldap_state *ldap_state = arg;
+
+ /** @TODO Should we be doing something to check what servers we rebind to?
+ Could we get a referral to a machine that we don't want to give our
+ username and password to? */
+
+ if (freeit) {
+ SAFE_FREE(*whop);
+ memset(*credp, '\0', strlen(*credp));
+ SAFE_FREE(*credp);
+ } else {
+ DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
+ ldap_state->bind_dn));
+
+ *whop = strdup(ldap_state->bind_dn);
+ if (!*whop) {
+ return LDAP_NO_MEMORY;
+ }
+ *credp = strdup(ldap_state->bind_secret);
+ if (!*credp) {
+ SAFE_FREE(*whop);
+ return LDAP_NO_MEMORY;
+ }
+ *methodp = LDAP_AUTH_SIMPLE;
+ }
+ return 0;
+}
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ This version takes a void* that we can shove useful stuff in :-)
+ and actually does the connection.
+******************************************************************/
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+static int rebindproc_connect_with_state (LDAP *ldap_struct,
+ LDAP_CONST char *url,
+ ber_tag_t request,
+ ber_int_t msgid, void *arg)
+{
+ struct smbldap_state *ldap_state = arg;
+ int rc;
+ DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n",
+ ldap_state->bind_dn));
+
+ /** @TODO Should we be doing something to check what servers we rebind to?
+ Could we get a referral to a machine that we don't want to give our
+ username and password to? */
+
+ rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
+
+ return rc;
+}
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+/*******************************************************************
+ Add a rebind function for authenticated referrals
+******************************************************************/
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+#else
+# if LDAP_SET_REBIND_PROC_ARGS == 2
+static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
+ int *method, int freeit )
+{
+ struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);
+
+ return rebindproc_with_state(ldap_struct, whop, credp,
+ method, freeit, ldap_state);
+
+}
+# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ this also does the connection, but no void*.
+******************************************************************/
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+# if LDAP_SET_REBIND_PROC_ARGS == 2
+static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
+ ber_int_t msgid)
+{
+ struct smbldap_state *ldap_state = smbldap_find_state(ld);
+
+ return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
+ ldap_state);
+}
+# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+/*******************************************************************
+ connect to the ldap server under system privilege.
+******************************************************************/
+static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct)
+{
+ int rc;
+ char *ldap_dn;
+ char *ldap_secret;
+
+ /* get the password */
+ if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
+ {
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
+ return LDAP_INVALID_CREDENTIALS;
+ }
+
+ ldap_state->bind_dn = ldap_dn;
+ ldap_state->bind_secret = ldap_secret;
+
+ /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
+ (OpenLDAP) doesnt' seem to support it */
+
+ DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
+ ldap_state->uri, ldap_dn));
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+# if LDAP_SET_REBIND_PROC_ARGS == 2
+ ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
+# endif
+# if LDAP_SET_REBIND_PROC_ARGS == 3
+ ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
+# endif
+#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+# if LDAP_SET_REBIND_PROC_ARGS == 2
+ ldap_set_rebind_proc(ldap_struct, &rebindproc);
+# endif
+# if LDAP_SET_REBIND_PROC_ARGS == 3
+ ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
+# endif
+#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
+
+ rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
+
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ &ld_error);
+ DEBUG(ldap_state->num_failures ? 2 : 0,
+ ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
+ ldap_dn ? ldap_dn : "(unknown)", ldap_err2string(rc),
+ ld_error ? ld_error : "(unknown)"));
+ SAFE_FREE(ld_error);
+ ldap_state->num_failures++;
+ return rc;
+ }
+
+ ldap_state->num_failures = 0;
+
+ DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
+ return rc;
+}
+
+/**********************************************************************
+Connect to LDAP server (called before every ldap operation)
+*********************************************************************/
+static int smbldap_open(struct smbldap_state *ldap_state)
+{
+ int rc;
+ SMB_ASSERT(ldap_state);
+
+#ifndef NO_LDAP_SECURITY
+ if (geteuid() != 0) {
+ DEBUG(0, ("smbldap_open: cannot access LDAP when not root..\n"));
+ return LDAP_INSUFFICIENT_ACCESS;
+ }
+#endif
+
+ if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {
+ struct sockaddr_un addr;
+ socklen_t len = sizeof(addr);
+ int sd;
+ if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
+ getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
+ /* the other end has died. reopen. */
+ ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
+ ldap_state->ldap_struct = NULL;
+ ldap_state->last_ping = (time_t)0;
+ } else {
+ ldap_state->last_ping = time(NULL);
+ }
+ }
+
+ if (ldap_state->ldap_struct != NULL) {
+ DEBUG(5,("smbldap_open: already connected to the LDAP server\n"));
+ return LDAP_SUCCESS;
+ }
+
+ if ((rc = smbldap_open_connection(ldap_state))) {
+ return rc;
+ }
+
+ if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {
+ ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
+ ldap_state->ldap_struct = NULL;
+ return rc;
+ }
+
+
+ ldap_state->last_ping = time(NULL);
+ DEBUG(4,("The LDAP server is succesful connected\n"));
+
+ return LDAP_SUCCESS;
+}
+
+/**********************************************************************
+Disconnect from LDAP server
+*********************************************************************/
+static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
+{
+ if (!ldap_state)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if (ldap_state->ldap_struct != NULL) {
+ ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
+ ldap_state->ldap_struct = NULL;
+ }
+
+ smbldap_delete_state(ldap_state);
+
+ DEBUG(5,("The connection to the LDAP server was closed\n"));
+ /* maybe free the results here --metze */
+
+
+
+ return NT_STATUS_OK;
+}
+
+static int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
+{
+ int rc;
+
+ SMB_ASSERT(ldap_state && attempts);
+
+ if (*attempts != 0) {
+ unsigned int sleep_time;
+ uint8 rand_byte;
+
+ /* Sleep for a random timeout */
+ rand_byte = (char)(sys_random());
+
+ sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2;
+ /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
+ on average.
+ */
+ DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n",
+ sleep_time));
+ msleep(sleep_time);
+ }
+ (*attempts)++;
+
+ if ((rc = smbldap_open(ldap_state))) {
+ DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
+ return rc;
+ }
+
+ return LDAP_SUCCESS;
+}
+
+
+/*********************************************************************
+ ********************************************************************/
+
+int smbldap_search(struct smbldap_state *ldap_state,
+ const char *base, int scope, const char *filter,
+ char *attrs[], int attrsonly,
+ LDAPMessage **res)
+{
+ int rc = LDAP_SERVER_DOWN;
+ int attempts = 0;
+ char *utf8_filter;
+
+ SMB_ASSERT(ldap_state);
+
+ if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
+ return LDAP_NO_MEMORY;
+ }
+
+ while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+
+ if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+ continue;
+
+ rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
+ utf8_filter, attrs, attrsonly, res);
+ }
+
+ if (rc == LDAP_SERVER_DOWN) {
+ DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+ smbldap_close(ldap_state);
+ }
+
+ SAFE_FREE(utf8_filter);
+ return rc;
+}
+
+int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
+{
+ int rc = LDAP_SERVER_DOWN;
+ int attempts = 0;
+ char *utf8_dn;
+
+ SMB_ASSERT(ldap_state);
+
+ if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+ return LDAP_NO_MEMORY;
+ }
+
+ while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+
+ if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+ continue;
+
+ rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
+ }
+
+ if (rc == LDAP_SERVER_DOWN) {
+ DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+ smbldap_close(ldap_state);
+ }
+
+ SAFE_FREE(utf8_dn);
+ return rc;
+}
+
+int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[])
+{
+ int rc = LDAP_SERVER_DOWN;
+ int attempts = 0;
+ char *utf8_dn;
+
+ SMB_ASSERT(ldap_state);
+
+ if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+ return LDAP_NO_MEMORY;
+ }
+
+ while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+
+ if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+ continue;
+
+ rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
+ }
+
+ if (rc == LDAP_SERVER_DOWN) {
+ DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+ smbldap_close(ldap_state);
+ }
+
+ SAFE_FREE(utf8_dn);
+ return rc;
+}
+
+int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
+{
+ int rc = LDAP_SERVER_DOWN;
+ int attempts = 0;
+ char *utf8_dn;
+
+ SMB_ASSERT(ldap_state);
+
+ if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
+ return LDAP_NO_MEMORY;
+ }
+
+ while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+
+ if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+ continue;
+
+ rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
+ }
+
+ if (rc == LDAP_SERVER_DOWN) {
+ DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+ smbldap_close(ldap_state);
+ }
+
+ SAFE_FREE(utf8_dn);
+ return rc;
+}
+
+int smbldap_extended_operation(struct smbldap_state *ldap_state,
+ LDAP_CONST char *reqoid, struct berval *reqdata,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ char **retoidp, struct berval **retdatap)
+{
+ int rc = LDAP_SERVER_DOWN;
+ int attempts = 0;
+
+ if (!ldap_state)
+ return (-1);
+
+ while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
+
+ if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
+ continue;
+
+ rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata,
+ serverctrls, clientctrls, retoidp, retdatap);
+ }
+
+ if (rc == LDAP_SERVER_DOWN) {
+ DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
+ smbldap_close(ldap_state);
+ }
+
+ return rc;
+}
+
+/*******************************************************************
+ run the search by name.
+******************************************************************/
+int smbldap_search_suffix (struct smbldap_state *ldap_state, const char *filter,
+ char **search_attr, LDAPMessage ** result)
+{
+ int scope = LDAP_SCOPE_SUBTREE;
+ int rc;
+
+ DEBUG(2, ("smbldap_search_suffix: searching for:[%s]\n", filter));
+
+ rc = smbldap_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
+
+ if (rc != LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ &ld_error);
+ DEBUG(0,("smbldap_search_suffix: Problem during the LDAP search: %s (%s)\n",
+ ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
+ DEBUG(3,("smbldap_search_suffix: Query was: %s, %s\n", lp_ldap_suffix(),
+ filter));
+ SAFE_FREE(ld_error);
+ }
+
+ return rc;
+}
+
+/**********************************************************************
+ Housekeeping
+ *********************************************************************/
+
+void smbldap_free_struct(struct smbldap_state **ldap_state)
+{
+ smbldap_close(*ldap_state);
+
+ if ((*ldap_state)->bind_secret) {
+ memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
+ }
+
+ SAFE_FREE((*ldap_state)->bind_dn);
+ SAFE_FREE((*ldap_state)->bind_secret);
+
+ *ldap_state = NULL;
+
+ /* No need to free any further, as it is talloc()ed */
+}
+
+
+/**********************************************************************
+ Intitalise the 'general' ldap structures, on which ldap operations may be conducted
+ *********************************************************************/
+
+NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, const char *location, struct smbldap_state **smbldap_state)
+{
+ *smbldap_state = talloc_zero(mem_ctx, sizeof(**smbldap_state));
+ if (!*smbldap_state) {
+ DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (location) {
+ (*smbldap_state)->uri = talloc_strdup(mem_ctx, location);
+ } else {
+ (*smbldap_state)->uri = "ldap://localhost";
+ }
+ return NT_STATUS_OK;
+}
+
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index 7ba86481560..a53a50a060e 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -650,7 +650,7 @@ char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
const char *connectpath,
gid_t gid,
const char *smb_name,
- char *str)
+ const char *str)
{
char *a, *t;
a = alloc_sub_advanced(snum, user, connectpath, gid, smb_name, str);
@@ -662,7 +662,7 @@ char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
char *alloc_sub_advanced(int snum, const char *user,
const char *connectpath, gid_t gid,
- const char *smb_name, char *str)
+ const char *smb_name, const char *str)
{
char *a_string, *ret_string;
char *b, *p, *s, *t, *h;
@@ -736,14 +736,14 @@ void standard_sub_conn(connection_struct *conn, char *str, size_t len)
conn->gid, smb_user_name, str, len);
}
-char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, char *str)
+char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *str)
{
return talloc_sub_advanced(mem_ctx, SNUM(conn), conn->user,
conn->connectpath, conn->gid,
smb_user_name, str);
}
-char *alloc_sub_conn(connection_struct *conn, char *str)
+char *alloc_sub_conn(connection_struct *conn, const char *str)
{
return alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
conn->gid, smb_user_name, str);
diff --git a/source/lib/system_smbd.c b/source/lib/system_smbd.c
index 3ae0a6395ed..3498307acb5 100644
--- a/source/lib/system_smbd.c
+++ b/source/lib/system_smbd.c
@@ -107,13 +107,31 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, in
int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
{
+ char *p;
+ int retval;
+
+ DEBUG(10,("sys_getgrouplist: user [%s]\n", user));
+
+ /* see if we should disable winbindd lookups for local users */
+ if ( (p = strchr(user, *lp_winbind_separator())) == NULL ) {
+ if ( setenv(WINBINDD_DONT_ENV, "1", 1) == -1 )
+ DEBUG(0,("sys_getgroup_list: Insufficient environment space for %s\n",
+ WINBINDD_DONT_ENV));
+ else
+ DEBUG(10,("sys_getgrouplist(): disabled winbindd for group lookup [user == %s]\n",
+ user));
+ }
+
#ifdef HAVE_GETGROUPLIST
- return getgrouplist(user, gid, groups, grpcnt);
+ retval = getgrouplist(user, gid, groups, grpcnt);
#else
- int retval;
become_root();
retval = getgrouplist_internals(user, gid, groups, grpcnt);
unbecome_root();
- return retval;
#endif
+
+ /* allow winbindd lookups */
+ setenv( WINBINDD_DONT_ENV, "0", 1);
+
+ return retval;
}
diff --git a/source/lib/time.c b/source/lib/time.c
index f76a1bdc0d8..5309711a056 100644
--- a/source/lib/time.c
+++ b/source/lib/time.c
@@ -308,7 +308,8 @@ time_t nt_time_to_unix(NTTIME *nt)
time_t l_time_min = TIME_T_MIN;
time_t l_time_max = TIME_T_MAX;
- if (nt->high == 0) return(0);
+ if (nt->high == 0 || (nt->high == 0xffffffff && nt->low == 0xffffffff))
+ return(0);
d = ((double)nt->high)*4.0*(double)(1<<30);
d += (nt->low&0xFFF00000);
diff --git a/source/lib/username.c b/source/lib/username.c
index d8f4ff80edb..0005372a8f8 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -325,11 +325,12 @@ static BOOL user_in_netgroup_list(const char *user, const char *ngname)
static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL *winbind_answered)
{
- int num_groups;
int i;
- gid_t *groups = NULL;
gid_t gid, gid_low, gid_high;
BOOL ret = False;
+ static gid_t *groups = NULL;
+ static int num_groups = 0;
+ static fstring last_user = "";
*winbind_answered = False;
@@ -349,27 +350,44 @@ static BOOL user_in_winbind_group_list(const char *user, const char *gname, BOOL
goto err;
}
- /*
- * Get the gid's that this user belongs to.
- */
-
- if ((num_groups = winbind_getgroups(user, 0, NULL)) == -1)
- return False;
+ /* try to user the last user we looked up */
+ /* otherwise fall back to lookups */
+
+ if ( !strequal( last_user, user ) || !groups )
+ {
+ /* clear any cached information */
+
+ SAFE_FREE(groups);
+ fstrcpy( last_user, "" );
+
+ /*
+ * Get the gid's that this user belongs to.
+ */
- if (num_groups == 0) {
- *winbind_answered = True;
- return False;
- }
+ if ((num_groups = winbind_getgroups(user, &groups)) == -1)
+ return False;
+
+ if ( num_groups == -1 )
+ return False;
- if ((groups = (gid_t *)malloc(sizeof(gid_t) * num_groups )) == NULL) {
- DEBUG(0,("user_in_winbind_group_list: malloc fail.\n"));
- goto err;
- }
+ if ( num_groups == 0 ) {
+ *winbind_answered = True;
+ return False;
+ }
+
+ /* save the last username */
+
+ fstrcpy( last_user, user );
+
+ }
+ else
+ DEBUG(10,("user_in_winbind_group_list: using cached user groups for [%s]\n", user));
- if ((num_groups = winbind_getgroups(user, num_groups, groups)) == -1) {
- DEBUG(0,("user_in_winbind_group_list: second winbind_getgroups call \
-failed with error %s\n", strerror(errno) ));
- goto err;
+ 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,("\n"));
}
/*
@@ -571,10 +589,16 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups, size_t n_gr
fstrcpy(domain, *list);
domain[PTR_DIFF(p, *list)] = 0;
- /* Check to see if name is a Windows group */
- if (winbind_lookup_name(domain, groupname, &g_sid, &name_type) && name_type == SID_NAME_DOM_GRP) {
+ /* Check to see if name is a Windows group; Win2k native mode DCs
+ will return domain local groups; while NT4 or mixed mode 2k DCs
+ will not */
+
+ if ( winbind_lookup_name(NULL, *list, &g_sid, &name_type)
+ && ( name_type==SID_NAME_DOM_GRP ||
+ (strequal(lp_workgroup(), domain) && name_type==SID_NAME_ALIAS) ) )
+ {
- /* Check if user name is in the Windows group */
+ /* Check if user name is in the Windows group */
ret = user_in_winbind_group_list(user, *list, &winbind_answered);
if (winbind_answered && ret == True) {
diff --git a/source/lib/util.c b/source/lib/util.c
index 95d3403a7cd..a99e2163db5 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -2345,9 +2345,9 @@ BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
Recursive routine that is called by unix_wild_match.
*********************************************************/
-static BOOL unix_do_match(char *regexp, char *str)
+static BOOL unix_do_match(const char *regexp, const char *str)
{
- char *p;
+ const char *p;
for( p = regexp; *p && *str; ) {
@@ -2467,6 +2467,7 @@ BOOL unix_wild_match(const char *pattern, const char *string)
return unix_do_match(p2, s2) == 0;
}
+
#ifdef __INSURE__
/*******************************************************************
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 87a8ea2eb19..af8d6aa04ca 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -38,6 +38,7 @@
BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
{
const char *s;
+ char *pbuf;
BOOL quoted;
size_t len=1;
@@ -59,17 +60,18 @@ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
return(False);
/* copy over the token */
+ pbuf = buff;
for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
if (*s == '\"') {
quoted = !quoted;
} else {
len++;
- *buff++ = *s;
+ *pbuf++ = *s;
}
}
*ptr = (*s) ? s+1 : s;
- *buff = 0;
+ *pbuf = 0;
return(True);
}
@@ -1469,6 +1471,7 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
#define IPSTR_LIST_SEP ","
+#define IPSTR_LIST_CHAR ','
/**
* Add ip string representation to ipstr list. Used also
@@ -1483,19 +1486,20 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
* reallocated to new length
**/
-char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
+char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
{
char* new_ipstr = NULL;
/* arguments checking */
- if (!ipstr_list || !ip) return NULL;
+ if (!ipstr_list || !service) return NULL;
/* attempt to convert ip to a string and append colon separator to it */
if (*ipstr_list) {
- asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
+ asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
+ inet_ntoa(service->ip), service->port);
SAFE_FREE(*ipstr_list);
} else {
- asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
+ asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
}
*ipstr_list = new_ipstr;
return *ipstr_list;
@@ -1512,7 +1516,7 @@ char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
* @return pointer to allocated ip string
**/
-char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
+char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
{
int i;
@@ -1531,7 +1535,8 @@ char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_c
/**
* Parse given ip string list into array of ip addresses
- * (as in_addr structures)
+ * (as ip_service structures)
+ * e.g. 192.168.1.100:389,192.168.1.78, ...
*
* @param ipstr ip string list to be parsed
* @param ip_list pointer to array of ip addresses which is
@@ -1539,28 +1544,40 @@ char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_c
* @return number of succesfully parsed addresses
**/
-int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
+int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
{
fstring token_str;
- int count;
+ size_t count;
+ int i;
- if (!ipstr_list || !ip_list) return 0;
+ if (!ipstr_list || !ip_list)
+ return 0;
+
+ 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));
+ return 0;
+ }
- for (*ip_list = NULL, count = 0;
- next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
- count++) {
-
+ for ( i=0;
+ next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
+ i++ )
+ {
struct in_addr addr;
+ unsigned port = 0;
+ char *p = strchr(token_str, ':');
+
+ if (p) {
+ *p = 0;
+ port = atoi(p+1);
+ }
/* convert single token to ip address */
if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
break;
-
- /* prepare place for another in_addr structure */
- *ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
- if (!*ip_list) return -1;
-
- (*ip_list)[count] = addr;
+
+ (*ip_list)[i].ip = addr;
+ (*ip_list)[i].port = port;
}
return count;
diff --git a/source/lib/util_uuid.c b/source/lib/util_uuid.c
index 699f2cd6325..83553ec28ec 100644
--- a/source/lib/util_uuid.c
+++ b/source/lib/util_uuid.c
@@ -58,7 +58,7 @@ static void uuid_unpack(const GUID in, struct uuid *uu)
memcpy(uu->node, ptr+10, 6);
}
-void uuid_generate_random(GUID *out)
+void smb_uuid_generate_random(GUID *out)
{
GUID tmp;
struct uuid uu;
@@ -71,7 +71,7 @@ void uuid_generate_random(GUID *out)
uuid_pack(&uu, out);
}
-char *guid_to_string(const GUID in)
+char *smb_uuid_to_string(const GUID in)
{
struct uuid uu;
char *out;
@@ -87,7 +87,7 @@ char *guid_to_string(const GUID in)
return out;
}
-const char *uuid_string_static(const GUID in)
+const char *smb_uuid_string_static(const GUID in)
{
struct uuid uu;
static char out[37];
diff --git a/source/lib/wins_srv.c b/source/lib/wins_srv.c
index 3372f74dcbe..4a54762fde7 100644
--- a/source/lib/wins_srv.c
+++ b/source/lib/wins_srv.c
@@ -70,14 +70,24 @@
static char *wins_srv_keystr(struct in_addr wins_ip, struct in_addr src_ip)
{
- char *keystr;
+ char *keystr = NULL, *wins_ip_addr = NULL, *src_ip_addr = NULL;
- if (asprintf(&keystr, WINS_SRV_FMT, inet_ntoa(wins_ip),
- inet_ntoa(src_ip)) == -1) {
- DEBUG(0, ("wins_srv_is_dead: malloc error\n"));
- return NULL;
+ wins_ip_addr = strdup(inet_ntoa(wins_ip));
+ src_ip_addr = strdup(inet_ntoa(src_ip));
+
+ if ( !wins_ip_addr || !src_ip_addr ) {
+ DEBUG(0,("wins_srv_keystr: malloc error\n"));
+ goto done;
}
+ if (asprintf(&keystr, WINS_SRV_FMT, wins_ip_addr, src_ip_addr) == -1) {
+ DEBUG(0, (": ns_srv_keystr: malloc error for key string\n"));
+ }
+
+done:
+ SAFE_FREE(wins_ip_addr);
+ SAFE_FREE(src_ip_addr);
+
return keystr;
}
diff --git a/source/libads/ads_ldap.c b/source/libads/ads_ldap.c
index 97f12de0f7f..dcceaaeb835 100644
--- a/source/libads/ads_ldap.c
+++ b/source/libads/ads_ldap.c
@@ -34,7 +34,7 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
int count;
ADS_STATUS rc;
void *res = NULL;
- char *exp;
+ char *ldap_exp;
uint32 t;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
char *escaped_name = escape_ldap_string_alloc(name);
@@ -45,15 +45,15 @@ NTSTATUS ads_name_to_sid(ADS_STRUCT *ads,
goto done;
}
- if (asprintf(&exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
+ if (asprintf(&ldap_exp, "(|(sAMAccountName=%s)(userPrincipalName=%s@%s))",
escaped_name, escaped_name, escaped_realm) == -1) {
DEBUG(1,("ads_name_to_sid: asprintf failed!\n"));
status = NT_STATUS_NO_MEMORY;
goto done;
}
- rc = ads_search_retry(ads, &res, exp, attrs);
- free(exp);
+ rc = ads_search_retry(ads, &res, ldap_exp, attrs);
+ free(ldap_exp);
if (!ADS_ERR_OK(rc)) {
DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
goto done;
@@ -102,7 +102,7 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
"sAMAccountType", NULL};
ADS_STATUS rc;
void *msg = NULL;
- char *exp = NULL;
+ char *ldap_exp = NULL;
char *sidstr = NULL;
uint32 atype;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -113,13 +113,13 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
goto done;
}
- if (asprintf(&exp, "(objectSid=%s)", sidstr) == -1) {
+ if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) {
DEBUG(1,("ads_sid_to_name: asprintf failed!\n"));
status = NT_STATUS_NO_MEMORY;
goto done;
}
- rc = ads_search_retry(ads, &msg, exp, attrs);
+ rc = ads_search_retry(ads, &msg, ldap_exp, attrs);
if (!ADS_ERR_OK(rc)) {
status = ads_ntstatus(rc);
DEBUG(1,("ads_sid_to_name ads_search: %s\n", ads_errstr(rc)));
@@ -146,7 +146,7 @@ NTSTATUS ads_sid_to_name(ADS_STRUCT *ads,
done:
if (msg) ads_msgfree(ads, msg);
- SAFE_FREE(exp);
+ SAFE_FREE(ldap_exp);
SAFE_FREE(sidstr);
return status;
diff --git a/source/libads/ads_struct.c b/source/libads/ads_struct.c
index 652bfe31be8..dd31439d830 100644
--- a/source/libads/ads_struct.c
+++ b/source/libads/ads_struct.c
@@ -94,8 +94,7 @@ ADS_STRUCT *ads_init(const char *realm,
ads->server.workgroup = workgroup ? strdup(workgroup) : NULL;
ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL;
- /* we need to know if this is a foreign realm to know if we can
- use lp_ads_server() */
+ /* we need to know if this is a foreign realm */
if (realm && *realm && strcasecmp(lp_realm(), realm) != 0) {
ads->server.foreign = 1;
}
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index 3ce80975da4..60bbef821ca 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -41,6 +41,9 @@
/*
try a connection to a given ldap server, returning True and setting the servers IP
in the ads struct if successful
+
+ TODO : add a negative connection cache in here leveraged off of the one
+ found in the rpc code. --jerry
*/
static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port)
{
@@ -90,133 +93,81 @@ static BOOL ads_try_connect_uri(ADS_STRUCT *ads)
return False;
}
-/* used by the IP comparison function */
-struct ldap_ip {
- struct in_addr ip;
- unsigned port;
-};
-
-/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */
-static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2)
-{
- return ip_compare(&ip1->ip, &ip2->ip);
-}
+/**********************************************************************
+ Try to find an AD dc using our internal name resolution routines
+ Try the realm first and then then workgroup name if netbios is not
+ disabled
+**********************************************************************/
-/* try connecting to a ldap server via DNS */
-static BOOL ads_try_dns(ADS_STRUCT *ads)
+static BOOL ads_find_dc(ADS_STRUCT *ads)
{
const char *c_realm;
- const char *ptr;
- char *realm;
- char *list = NULL;
- pstring tok;
- struct ldap_ip *ip_list;
int count, i=0;
+ struct ip_service *ip_list;
+ pstring realm;
+ BOOL got_realm = False;
+ /* realm */
c_realm = ads->server.realm;
if (!c_realm || !*c_realm) {
c_realm = lp_realm();
}
- if (!c_realm || !*c_realm) {
- c_realm = ads->server.workgroup;
- }
- if (!c_realm || !*c_realm) {
- c_realm = lp_workgroup();
- }
- if (!c_realm) {
- return False;
- }
- realm = smb_xstrdup(c_realm);
+ if ( c_realm )
+ got_realm = True;
- DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm));
- if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) {
- SAFE_FREE(realm);
- return False;
+
+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)
+ return False;
}
+
+ pstrcpy( realm, c_realm );
- DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list));
- SAFE_FREE(realm);
+ DEBUG(6,("ads_find_dc: looking for %s '%s'\n",
+ (got_realm ? "realm" : "domain"), realm));
- count = count_chars(list, ' ') + 1;
- ip_list = malloc(count * sizeof(struct ldap_ip));
- if (!ip_list) {
- return False;
- }
-
- ptr = list;
- while (next_token(&ptr, tok, " ", sizeof(tok))) {
- unsigned port = LDAP_PORT;
- char *p = strchr(tok, ':');
- if (p) {
- *p = 0;
- port = atoi(p+1);
- }
- ip_list[i].ip = *interpret_addr2(tok);
- ip_list[i].port = port;
- if (!is_zero_ip(ip_list[i].ip)) {
- i++;
+ if ( !get_sorted_dc_list(realm, &ip_list, &count, got_realm) ) {
+ /* fall back to netbios if we can */
+ if ( got_realm && !lp_disable_netbios() ) {
+ got_realm = False;
+ goto again;
}
+
+ return False;
}
- free(list);
-
- count = i;
-
- /* we sort the list of addresses by closeness to our interfaces. This
- tries to prevent us using a DC on the other side of the country */
- if (count > 1) {
- qsort(ip_list, count, sizeof(struct ldap_ip),
- QSORT_CAST ldap_ip_compare);
- }
-
- for (i=0;i<count;i++) {
- if (ads_try_connect(ads, inet_ntoa(ip_list[i].ip), ip_list[i].port)) {
- free(ip_list);
+
+ /* if we fail this loop, then giveup since all the IP addresses returned were dead */
+ for ( i=0; i<count; i++ ) {
+ /* since this is an ads conection request, default to LDAP_PORT is not set */
+ int port = (ip_list[i].port!=PORT_NONE) ? ip_list[i].port : LDAP_PORT;
+ fstring server;
+
+ fstrcpy( server, inet_ntoa(ip_list[i].ip) );
+
+ if ( !NT_STATUS_IS_OK(check_negative_conn_cache(realm, server)) )
+ continue;
+
+ if ( ads_try_connect(ads, server, port) ) {
+ SAFE_FREE(ip_list);
return True;
}
+
+ /* keep track of failures */
+ add_failed_connection_entry( realm, server, NT_STATUS_UNSUCCESSFUL );
}
SAFE_FREE(ip_list);
+
return False;
}
-/* try connecting to a ldap server via netbios */
-static BOOL ads_try_netbios(ADS_STRUCT *ads)
-{
- struct in_addr *ip_list, pdc_ip;
- int count;
- int i;
- const char *workgroup = ads->server.workgroup;
- BOOL list_ordered;
-
- if (!workgroup) {
- workgroup = lp_workgroup();
- }
-
- DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup));
-
- /* try the PDC first */
- if (get_pdc_ip(workgroup, &pdc_ip)) {
- DEBUG(6,("ads_try_netbios: trying server '%s'\n",
- inet_ntoa(pdc_ip)));
- if (ads_try_connect(ads, inet_ntoa(pdc_ip), LDAP_PORT))
- return True;
- }
-
- /* now any DC, including backups */
- if (get_dc_list(workgroup, &ip_list, &count, &list_ordered)) {
- for (i=0;i<count;i++) {
- DEBUG(6,("ads_try_netbios: trying server '%s'\n",
- inet_ntoa(ip_list[i])));
- if (ads_try_connect(ads, inet_ntoa(ip_list[i]), LDAP_PORT)) {
- free(ip_list);
- return True;
- }
- }
- free(ip_list);
- }
-
- return False;
-}
/**
* Connect to the LDAP server
@@ -244,20 +195,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
goto got_connection;
}
- /* try with a smb.conf ads server setting if we are connecting
- to the primary workgroup or realm */
- if (!ads->server.foreign &&
- ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) {
- goto got_connection;
- }
-
- /* try via DNS */
- if (ads_try_dns(ads)) {
- goto got_connection;
- }
-
- /* try via netbios lookups */
- if (!lp_disable_netbios() && ads_try_netbios(ads)) {
+ if (ads_find_dc(ads)) {
goto got_connection;
}
@@ -749,14 +687,15 @@ void ads_memfree(ADS_STRUCT *ads, void *mem)
/**
* Get a dn from search results
* @param ads connection to ads server
- * @param res Search results
+ * @param msg Search result
* @return dn string
**/
-char *ads_get_dn(ADS_STRUCT *ads, void *res)
+char *ads_get_dn(ADS_STRUCT *ads, void *msg)
{
char *utf8_dn, *unix_dn;
- utf8_dn = ldap_get_dn(ads->ld, res);
+ utf8_dn = ldap_get_dn(ads->ld, msg);
+
pull_utf8_allocate((void **) &unix_dn, utf8_dn);
ldap_memfree(utf8_dn);
return unix_dn;
@@ -1078,6 +1017,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
#ifndef ENCTYPE_ARCFOUR_HMAC
acct_control |= UF_USE_DES_KEY_ONLY;
#endif
+
if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control)))
goto done;
@@ -1142,7 +1082,7 @@ static void dump_guid(const char *field, struct berval **values)
GUID guid;
for (i=0; values[i]; i++) {
memcpy(guid.info, values[i]->bv_val, sizeof(guid.info));
- printf("%s: %s\n", field, uuid_string_static(guid));
+ printf("%s: %s\n", field, smb_uuid_string_static(guid));
}
}
@@ -1384,7 +1324,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname,
ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname)
{
ADS_STATUS status;
- void *res;
+ void *res, *msg;
char *hostnameDN, *host;
int rc;
@@ -1398,7 +1338,12 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname)
return status;
}
- hostnameDN = ads_get_dn(ads, (LDAPMessage *)res);
+ msg = ads_first_entry(ads, res);
+ if (!msg) {
+ return ADS_ERROR_SYSTEM(ENOENT);
+ }
+
+ hostnameDN = ads_get_dn(ads, (LDAPMessage *)msg);
rc = ldap_delete_s(ads->ld, hostnameDN);
ads_memfree(ads, hostnameDN);
if (rc != LDAP_SUCCESS) {
diff --git a/source/libads/ldap_printer.c b/source/libads/ldap_printer.c
index f5cd4f2885d..aa5ac15b5dd 100644
--- a/source/libads/ldap_printer.c
+++ b/source/libads/ldap_printer.c
@@ -31,7 +31,7 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res,
const char *printer, const char *servername)
{
ADS_STATUS status;
- char *srv_dn, **srv_cn, *exp;
+ char *srv_dn, **srv_cn, *s;
const char *attrs[] = {"*", "nTSecurityDescriptor", NULL};
status = ads_find_machine_acct(ads, res, servername);
@@ -44,12 +44,12 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res,
srv_cn = ldap_explode_dn(srv_dn, 1);
ads_msgfree(ads, *res);
- asprintf(&exp, "(cn=%s-%s)", srv_cn[0], printer);
- status = ads_search(ads, res, exp, attrs);
+ asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
+ status = ads_search(ads, res, s, attrs);
ldap_memfree(srv_dn);
ldap_value_free(srv_cn);
- free(exp);
+ free(s);
return status;
}
diff --git a/source/libads/sasl.c b/source/libads/sasl.c
index 29d4533a54f..598208b17f8 100644
--- a/source/libads/sasl.c
+++ b/source/libads/sasl.c
@@ -198,8 +198,11 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
if (ads_kinit_password(ads) == 0) {
status = ads_sasl_spnego_krb5_bind(ads, principal);
}
- if (ADS_ERR_OK(status))
+ /* only fallback to NTLMSSP if allowed */
+ if (ADS_ERR_OK(status) ||
+ !(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
return status;
+ }
}
#endif
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 8ebac7bae7b..18125e26c30 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -293,14 +293,18 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
uchar nt_hash[16];
E_md4hash(pass, nt_hash);
+ nt_response = data_blob(NULL, 24);
+ SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
+
/* non encrypted password supplied. Ignore ntpass. */
if (lp_client_lanman_auth()) {
lm_response = data_blob(NULL, 24);
- SMBencrypt(pass,cli->secblob.data,lm_response.data);
+ SMBencrypt(pass,cli->secblob.data, lm_response.data);
+ } else {
+ /* LM disabled, place NT# in LM feild instead */
+ lm_response = data_blob(nt_response.data, nt_response.length);
}
- nt_response = data_blob(NULL, 24);
- SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
session_key = data_blob(NULL, 16);
SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
}
@@ -449,6 +453,8 @@ static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
return blob2;
}
+#ifdef HAVE_KRB5
+
/****************************************************************************
Send a extended security session setup blob, returning a reply blob.
****************************************************************************/
@@ -463,7 +469,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
return cli_session_setup_blob_receive(cli);
}
-#ifdef HAVE_KRB5
/****************************************************************************
Use in-memory credentials cache
****************************************************************************/
@@ -499,7 +504,8 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi
return !cli_is_error(cli);
}
-#endif
+#endif /* HAVE_KRB5 */
+
/****************************************************************************
Do a spnego/NTLMSSP encrypted session setup.
@@ -575,7 +581,6 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
}
data_blob_free(&tmp_blob);
} else {
- /* the server might give us back two challenges */
if (!spnego_parse_auth_response(blob, nt_status,
&blob_in)) {
DEBUG(3,("Failed to parse auth response\n"));
@@ -713,8 +718,22 @@ BOOL cli_session_setup(struct cli_state *cli,
/* if its an older server then we have to use the older request format */
- if (cli->protocol < PROTOCOL_NT1)
+ if (cli->protocol < PROTOCOL_NT1) {
+ if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
+ DEBUG(1, ("Server requested LM password but 'client lanman auth'"
+ " is disabled\n"));
+ return False;
+ }
+
+ if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
+ !lp_client_plaintext_auth() && (*pass)) {
+ DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
+ " is disabled\n"));
+ return False;
+ }
+
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 */
@@ -726,17 +745,21 @@ BOOL cli_session_setup(struct cli_state *cli,
password at this point. The password is sent in the tree
connect */
- if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
+ if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
return cli_session_setup_plaintext(cli, user, "", workgroup);
/* if the server doesn't support encryption then we have to use
plaintext. The second password is ignored */
- if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0)
+ if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
+ if (!lp_client_plaintext_auth() && (*pass)) {
+ DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
+ " is disabled\n"));
+ return False;
+ }
return cli_session_setup_plaintext(cli, user, pass, workgroup);
+ }
- /* Indidicate signing */
-
/* if the server supports extended security then use SPNEGO */
if (cli->capabilities & CAP_EXTENDED_SECURITY)
@@ -789,6 +812,12 @@ BOOL cli_send_tconX(struct cli_state *cli,
}
if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) {
+ if (!lp_client_lanman_auth()) {
+ DEBUG(1, ("Server requested LANMAN password but 'client use lanman auth'"
+ " is disabled\n"));
+ return False;
+ }
+
/*
* Non-encrypted passwords - convert to DOS codepage before encryption.
*/
@@ -796,10 +825,17 @@ BOOL cli_send_tconX(struct cli_state *cli,
SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
} else {
if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
+ if (!lp_client_plaintext_auth() && (*pass)) {
+ DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
+ " is disabled\n"));
+ return False;
+ }
+
/*
* Non-encrypted passwords - convert to DOS codepage before using.
*/
passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
+
} else {
memcpy(pword, pass, passlen);
}
@@ -1375,6 +1411,12 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli,
{
char *p;
+ if (!lp_client_plaintext_auth() && (*pass)) {
+ DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
+ " is disabled\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
@@ -1439,7 +1481,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info)
{
- struct in_addr *ip_list;
+ struct ip_service *ip_list;
struct cli_state *cli;
int i, count;
struct in_addr server_ip;
@@ -1453,7 +1495,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user
for (i = 0; i < count; i++) {
static fstring name;
- if (!name_status_find("*", 0, 0x1d, ip_list[i], name))
+ if (!name_status_find("*", 0, 0x1d, ip_list[i].ip, name))
continue;
if (!find_master_ip(name, &server_ip))
@@ -1462,7 +1504,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user
pstrcpy(workgroup, name);
DEBUG(4, ("found master browser %s, %s\n",
- name, inet_ntoa(ip_list[i])));
+ name, inet_ntoa(ip_list[i].ip)));
cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info);
diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c
index b771e135f4e..f021076a46c 100644
--- a/source/libsmb/clifile.c
+++ b/source/libsmb/clifile.c
@@ -600,8 +600,8 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum,
/****************************************************************************
Lock a file.
+ note that timeout is in units of 2 milliseconds
****************************************************************************/
-
BOOL cli_lock(struct cli_state *cli, int fnum,
uint32 offset, uint32 len, int timeout, enum brl_type lock_type)
{
@@ -636,7 +636,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum,
cli_send_smb(cli);
if (timeout != 0) {
- cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 10*1000);
+ cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout*2 + 5*1000);
}
if (!cli_receive_smb(cli)) {
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
index df6043a618b..fd5dd91325a 100644
--- a/source/libsmb/clikrb5.c
+++ b/source/libsmb/clikrb5.c
@@ -255,7 +255,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context,
}
/* obtain ticket & session key */
- memset((char *)&creds, 0, sizeof(creds));
+ ZERO_STRUCT(creds);
if ((retval = krb5_copy_principal(context, server, &creds.server))) {
DEBUG(1,("krb5_copy_principal failed (%s)\n",
error_message(retval)));
diff --git a/source/libsmb/conncache.c b/source/libsmb/conncache.c
new file mode 100644
index 00000000000..da31e25a9ca
--- /dev/null
+++ b/source/libsmb/conncache.c
@@ -0,0 +1,158 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ Winbind daemon connection manager
+
+ Copyright (C) Tim Potter 2001
+ Copyright (C) Andrew Bartlett 2002
+ Copyright (C) Gerald (Jerry) 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.
+*/
+
+
+#include "includes.h"
+
+#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */
+
+#define CONNCACHE_ADDR 1
+#define CONNCACHE_NAME 2
+
+/* cache entry contains either a server name **or** and IP address as
+ the key. This means that a server could have two entries (one for each key) */
+
+struct failed_connection_cache {
+ fstring domain_name;
+ fstring controller;
+ time_t lookup_time;
+ NTSTATUS nt_status;
+ struct failed_connection_cache *prev, *next;
+};
+
+static struct failed_connection_cache *failed_connection_cache;
+
+/**********************************************************************
+ Check for a previously failed connection
+**********************************************************************/
+
+NTSTATUS check_negative_conn_cache( const char *domain, const char *server )
+{
+ struct failed_connection_cache *fcc;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ /* can't check if we don't have strings */
+
+ if ( !domain || !server )
+ return NT_STATUS_OK;
+
+ for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
+
+ if ( !(strequal(domain, fcc->domain_name) && strequal(server, fcc->controller)) )
+ continue; /* no match; check the next entry */
+
+ /* we have a match so see if it is still current */
+
+ if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT)
+ {
+ /* Cache entry has expired, delete it */
+
+ DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n",
+ domain, server ));
+
+ DLIST_REMOVE(failed_connection_cache, fcc);
+ SAFE_FREE(fcc);
+
+ return NT_STATUS_OK;
+ }
+
+ /* The timeout hasn't expired yet so return false */
+
+ DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n",
+ domain, server ));
+
+ result = fcc->nt_status;
+ return result;
+ }
+
+ /* end of function means no cache entry */
+ return NT_STATUS_OK;
+}
+
+/**********************************************************************
+ Add an entry to the failed conneciton cache (aither a name of dotted
+ decimal IP
+**********************************************************************/
+
+void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result)
+{
+ struct failed_connection_cache *fcc;
+
+ SMB_ASSERT(!NT_STATUS_IS_OK(result));
+
+ /* Check we already aren't in the cache. We always have to have
+ a domain, but maybe not a specific DC name. */
+
+ for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
+ if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) )
+ {
+ DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n",
+ domain, server ));
+ return;
+ }
+ }
+
+ /* Create negative lookup cache entry for this domain and controller */
+
+ if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) )
+ {
+ DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
+ return;
+ }
+
+ ZERO_STRUCTP(fcc);
+
+ fstrcpy( fcc->domain_name, domain );
+ fstrcpy( fcc->controller, server );
+ fcc->lookup_time = time(NULL);
+ fcc->nt_status = result;
+
+ DEBUG(10,("add_failed_connection_entry_byname: added domain %s (%s) to failed conn cache\n",
+ domain, server ));
+
+ DLIST_ADD(failed_connection_cache, fcc);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+void flush_negative_conn_cache( void )
+{
+ struct failed_connection_cache *fcc;
+
+ fcc = failed_connection_cache;
+
+ while (fcc) {
+ struct failed_connection_cache *fcc_next;
+
+ fcc_next = fcc->next;
+ DLIST_REMOVE(failed_connection_cache, fcc);
+ free(fcc);
+
+ fcc = fcc_next;
+ }
+
+}
+
+
diff --git a/source/libsmb/namecache.c b/source/libsmb/namecache.c
index d3541b7719d..e3e7ac4e3c2 100644
--- a/source/libsmb/namecache.c
+++ b/source/libsmb/namecache.c
@@ -113,7 +113,7 @@ static char* namecache_key(const char *name, int name_type)
**/
BOOL namecache_store(const char *name, int name_type,
- int num_names, struct in_addr *ip_list)
+ int num_names, struct ip_service *ip_list)
{
time_t expiry;
char *key, *value_string;
@@ -126,27 +126,19 @@ BOOL namecache_store(const char *name, int name_type,
*/
if (!gencache_init()) return False;
- DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ",
- num_names, num_names == 1 ? "": "es", name, name_type));
-
- for (i = 0; i < num_names; i++)
- DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]),
- i == (num_names - 1) ? "" : ", "));
-
- DEBUGADD(5, ("\n"));
+ if ( DEBUGLEVEL >= 5 ) {
+ DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ",
+ num_names, num_names == 1 ? "": "es", name, name_type));
+ for (i = 0; i < num_names; i++)
+ DEBUGADD(5, ("%s:%d%s", inet_ntoa(ip_list[i].ip),
+ ip_list[i].port, (i == (num_names - 1) ? "" : ",")));
+
+ DEBUGADD(5, ("\n"));
+ }
+
key = namecache_key(name, name_type);
-
- /*
- * Cache pdc location or dc lists for only a little while
- * otherwise if we lock on to a bad DC we can potentially be
- * out of action for the entire cache timeout time!
- */
-
- if (name_type == 0x1b || name_type == 0x1c)
- expiry = time(NULL) + 10;
- else
- expiry = time(NULL) + lp_name_cache_timeout();
+ expiry = time(NULL) + lp_name_cache_timeout();
/*
* Generate string representation of ip addresses list
@@ -180,7 +172,7 @@ BOOL namecache_store(const char *name, int name_type,
* false if name isn't found in the cache or has expired
**/
-BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list,
+BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_list,
int *num_names)
{
char *key, *value;
@@ -201,7 +193,9 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list,
if (!gencache_get(key, &value, &timeout)) {
DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type));
+ gencache_del(key);
SAFE_FREE(key);
+ SAFE_FREE(value);
return False;
} else {
DEBUG(5, ("name %s#%02X found.\n", name, name_type));
@@ -213,7 +207,8 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list,
*num_names = ipstr_list_parse(value, ip_list);
SAFE_FREE(key);
- SAFE_FREE(value);
+ SAFE_FREE(value);
+
return *num_names > 0; /* true only if some ip has been fetched */
}
@@ -252,3 +247,75 @@ void namecache_flush(void)
DEBUG(5, ("Namecache flushed\n"));
}
+/* Construct a name status record key. */
+
+static char *namecache_status_record_key(const char *name, int name_type1,
+ int name_type2, struct in_addr keyip)
+{
+ char *keystr;
+
+ asprintf(&keystr, "NBT/%s#%02X.%02X.%s",
+ strupper_static(name), name_type1, name_type2, inet_ntoa(keyip));
+ return keystr;
+}
+
+/* Store a name status record. */
+
+BOOL namecache_status_store(const char *keyname, int keyname_type,
+ int name_type, struct in_addr keyip,
+ const char *srvname)
+{
+ char *key;
+ time_t expiry;
+ BOOL ret;
+
+ if (!gencache_init())
+ return False;
+
+ key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
+ if (!key)
+ return False;
+
+ expiry = time(NULL) + lp_name_cache_timeout();
+ ret = gencache_set(key, srvname, expiry);
+
+ if (ret)
+ DEBUG(5, ("namecache_status_store: entry %s -> %s\n", key, srvname ));
+ else
+ DEBUG(5, ("namecache_status_store: entry %s store failed.\n", key ));
+
+ SAFE_FREE(key);
+ return ret;
+}
+
+/* Fetch a name status record. */
+
+BOOL namecache_status_fetch(const char *keyname, int keyname_type,
+ int name_type, struct in_addr keyip, char *srvname_out)
+{
+ char *key = NULL;
+ char *value = NULL;
+ time_t timeout;
+
+ if (!gencache_init())
+ return False;
+
+ key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
+ if (!key)
+ return False;
+
+ if (!gencache_get(key, &value, &timeout)) {
+ DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key));
+ gencache_del(key);
+ SAFE_FREE(key);
+ SAFE_FREE(value);
+ return False;
+ } else {
+ DEBUG(5, ("namecache_status_fetch: key %s -> %s\n", key, value ));
+ }
+
+ strlcpy(srvname_out, value, 16);
+ SAFE_FREE(key);
+ SAFE_FREE(value);
+ return True;
+}
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index 18ce5e4bd9b..81c0c144373 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -25,8 +25,9 @@
BOOL global_in_nmbd = False;
/****************************************************************************
-generate a random trn_id
+ Generate a random trn_id.
****************************************************************************/
+
static int generate_trn_id(void)
{
static int trn_id;
@@ -40,10 +41,10 @@ static int generate_trn_id(void)
return trn_id % (unsigned)0x7FFF;
}
-
/****************************************************************************
- parse a node status response into an array of structures
+ Parse a node status response into an array of structures.
****************************************************************************/
+
static struct node_status *parse_node_status(char *p, int *num_names)
{
struct node_status *ret;
@@ -51,7 +52,8 @@ static struct node_status *parse_node_status(char *p, int *num_names)
*num_names = CVAL(p,0);
- if (*num_names == 0) return NULL;
+ if (*num_names == 0)
+ return NULL;
ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names));
if (!ret) return NULL;
@@ -71,9 +73,10 @@ static struct node_status *parse_node_status(char *p, int *num_names)
/****************************************************************************
-do a NBT node status query on an open socket and return an array of
-structures holding the returned names or NULL if the query failed
+ Do a NBT node status query on an open socket and return an array of
+ structures holding the returned names or NULL if the query failed.
**************************************************************************/
+
struct node_status *node_status_query(int fd,struct nmb_name *name,
struct in_addr to_ip, int *num_names)
{
@@ -155,11 +158,9 @@ struct node_status *node_status_query(int fd,struct nmb_name *name,
return NULL;
}
-
/****************************************************************************
-find the first type XX name in a node status reply - used for finding
-a servers name given its IP
-return the matched name in *name
+ Find the first type XX name in a node status reply - used for finding
+ a servers name given its IP. Return the matched name in *name.
**************************************************************************/
BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name)
@@ -178,6 +179,11 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
q_type, inet_ntoa(to_ip)));
+ /* Check the cache first. */
+
+ if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
+ return True;
+
sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
if (sock == -1)
goto done;
@@ -197,6 +203,14 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
goto done;
pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
+
+ /* Store the result in the cache. */
+ /* but don't store an entry for 0x1c names here. Here we have
+ a single host and DOMAIN<0x1c> names should be a list of hosts */
+
+ if ( q_type != 0x1c )
+ namecache_status_store(q_name, q_type, type, to_ip, name);
+
result = True;
done:
@@ -205,17 +219,17 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
if (result)
- DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip)));
+ DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
DEBUG(10, ("\n"));
return result;
}
-
/*
comparison function used by sort_ip_list
*/
+
int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
{
int max_bits1=0, max_bits2=0;
@@ -243,11 +257,32 @@ int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
return max_bits2 - max_bits1;
}
+/*******************************************************************
+ compare 2 ldap IPs by nearness to our interfaces - used in qsort
+*******************************************************************/
+
+static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
+{
+ int result;
+
+ if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
+ return result;
+
+ if ( ip1->port > ip2->port )
+ return 1;
+
+ if ( ip1->port < ip2->port )
+ return -1;
+
+ return 0;
+}
+
/*
sort an IP list so that names that are close to one of our interfaces
are at the top. This prevents the problem where a WINS server returns an IP that
is not reachable from our subnet as the first match
*/
+
static void sort_ip_list(struct in_addr *iplist, int count)
{
if (count <= 1) {
@@ -257,6 +292,50 @@ static void sort_ip_list(struct in_addr *iplist, int count)
qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
}
+void sort_ip_list2(struct ip_service *iplist, int count)
+{
+ if (count <= 1) {
+ return;
+ }
+
+ qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare);
+}
+
+/**********************************************************************
+ Remove any duplicate address/port pairs in the list
+ *********************************************************************/
+
+static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
+{
+ int i, j;
+
+ DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
+
+ /* one loop to remove duplicates */
+ for ( i=0; i<count; i++ ) {
+ if ( is_zero_ip(iplist[i].ip) )
+ continue;
+
+ for ( j=i+1; j<count; j++ ) {
+ if ( ip_service_equal(iplist[i], iplist[j]) )
+ zero_ip(&iplist[j].ip);
+ }
+ }
+
+ /* one loop to clean up any holes we left */
+ /* first ip should never be a zero_ip() */
+ for (i = 0; i<count; ) {
+ if ( is_zero_ip(iplist[i].ip) ) {
+ if (i != count-1 )
+ memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
+ count--;
+ continue;
+ }
+ i++;
+ }
+
+ return count;
+}
/****************************************************************************
Do a netbios name query to find someones IP.
@@ -264,6 +343,7 @@ static void sort_ip_list(struct in_addr *iplist, int count)
*count will be set to the number of addresses returned.
*timed_out is set if we failed by timing out
****************************************************************************/
+
struct in_addr *name_query(int fd,const char *name,int name_type,
BOOL bcast,BOOL recurse,
struct in_addr to_ip, int *count, int *flags,
@@ -556,23 +636,49 @@ void endlmhosts(XFILE *fp)
x_fclose(fp);
}
+/********************************************************
+ convert an array if struct in_addrs to struct ip_service
+ return False on failure. Port is set to PORT_NONE;
+*********************************************************/
+
+static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
+{
+ int i;
+ if ( count==0 || !ip_list )
+ return False;
+
+ /* copy the ip address; port will be PORT_NONE */
+ if ( (*return_iplist = (struct ip_service*)malloc(count*sizeof(struct ip_service))) == NULL ) {
+ DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
+ return False;
+ }
+
+ for ( i=0; i<count; i++ ) {
+ (*return_iplist)[i].ip = ip_list[i];
+ (*return_iplist)[i].port = PORT_NONE;
+ }
+
+ return True;
+}
/********************************************************
Resolve via "bcast" method.
*********************************************************/
BOOL name_resolve_bcast(const char *name, int name_type,
- struct in_addr **return_ip_list, int *return_count)
+ struct ip_service **return_iplist, int *return_count)
{
int sock, i;
int num_interfaces = iface_count();
+ struct in_addr *ip_list;
+ BOOL ret;
if (lp_disable_netbios()) {
DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
return False;
}
- *return_ip_list = NULL;
+ *return_iplist = NULL;
*return_count = 0;
/*
@@ -596,27 +702,38 @@ BOOL name_resolve_bcast(const char *name, int name_type,
int flags;
/* Done this way to fix compiler error on IRIX 5.x */
sendto_ip = *iface_n_bcast(i);
- *return_ip_list = name_query(sock, name, name_type, True,
+ ip_list = name_query(sock, name, name_type, True,
True, sendto_ip, return_count, &flags, NULL);
- if(*return_ip_list != NULL) {
- close(sock);
- return True;
- }
+ if( ip_list )
+ goto success;
}
-
+
+ /* failed - no response */
+
close(sock);
return False;
+
+success:
+ ret = True;
+ if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
+ ret = False;
+
+ SAFE_FREE( ip_list );
+ close(sock);
+ return ret;
}
/********************************************************
Resolve via "wins" method.
*********************************************************/
+
BOOL resolve_wins(const char *name, int name_type,
- struct in_addr **return_iplist, int *return_count)
+ struct ip_service **return_iplist, int *return_count)
{
int sock, t, i;
char **wins_tags;
- struct in_addr src_ip;
+ struct in_addr src_ip, *ip_list = NULL;
+ BOOL ret;
if (lp_disable_netbios()) {
DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
@@ -672,12 +789,12 @@ BOOL resolve_wins(const char *name, int name_type,
continue;
}
- *return_iplist = name_query(sock,name,name_type, False,
+ ip_list = name_query(sock,name,name_type, False,
True, wins_ip, return_count, &flags,
&timed_out);
- if (*return_iplist != NULL) {
+ if ( !ip_list )
goto success;
- }
+
close(sock);
if (timed_out) {
@@ -695,9 +812,15 @@ BOOL resolve_wins(const char *name, int name_type,
return False;
success:
+ ret = True;
+ if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
+ ret = False;
+
+ SAFE_FREE( ip_list );
wins_srv_tags_free(wins_tags);
close(sock);
- return True;
+
+ return ret;
}
/********************************************************
@@ -705,7 +828,7 @@ success:
*********************************************************/
static BOOL resolve_lmhosts(const char *name, int name_type,
- struct in_addr **return_iplist, int *return_count)
+ struct ip_service **return_iplist, int *return_count)
{
/*
* "lmhosts" means parse the local lmhosts file.
@@ -728,12 +851,12 @@ static BOOL resolve_lmhosts(const char *name, int name_type,
((name_type2 == -1) || (name_type == name_type2))
) {
endlmhosts(fp);
- *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
- if(*return_iplist == NULL) {
+ if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
return False;
}
- **return_iplist = return_ip;
+ (*return_iplist)[0].ip = return_ip;
+ (*return_iplist)[0].port = PORT_NONE;
*return_count = 1;
return True;
}
@@ -748,13 +871,67 @@ static BOOL resolve_lmhosts(const char *name, int name_type,
Resolve via "hosts" method.
*********************************************************/
-static BOOL resolve_hosts(const char *name,
- struct in_addr **return_iplist, int *return_count)
+static BOOL resolve_hosts(const char *name, int name_type,
+ struct ip_service **return_iplist, int *return_count)
{
/*
* "host" means do a localhost, or dns lookup.
*/
struct hostent *hp;
+
+#ifdef HAVE_ADS
+ if ( name_type == 0x1c ) {
+ int count, i = 0;
+ char *list = NULL;
+ const char *ptr;
+ pstring tok;
+
+ /* try to lookup the _ldap._tcp.<domain> if we are using ADS */
+ if ( lp_security() != SEC_ADS )
+ return False;
+
+ DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n",
+ name));
+
+ if (ldap_domain2hostlist(name, &list) != LDAP_SUCCESS)
+ return False;
+
+ count = count_chars(list, ' ') + 1;
+ if ( (*return_iplist = malloc(count * sizeof(struct ip_service))) == NULL ) {
+ DEBUG(0,("resolve_hosts: malloc failed for %d entries\n", count ));
+ return False;
+ }
+
+ ptr = list;
+ while (next_token(&ptr, tok, " ", sizeof(tok))) {
+ unsigned port = LDAP_PORT;
+ char *p = strchr(tok, ':');
+ if (p) {
+ *p = 0;
+ port = atoi(p+1);
+ }
+ (*return_iplist)[i].ip = *interpret_addr2(tok);
+ (*return_iplist)[i].port = port;
+
+ /* make sure it is a valid IP. I considered checking the negative
+ connection cache, but this is the wrong place for it. Maybe only
+ as a hac. After think about it, if all of the IP addresses retuend
+ from DNS are dead, what hope does a netbios name lookup have?
+ The standard reason for falling back to netbios lookups is that
+ our DNS server doesn't know anything about the DC's -- jerry */
+
+ if ( is_zero_ip((*return_iplist)[i].ip) )
+ continue;
+
+ i++;
+ }
+ SAFE_FREE(list);
+
+ *return_count = i;
+
+ return True;
+ }
+#endif /* HAVE_ADS */
*return_iplist = NULL;
*return_count = 0;
@@ -764,27 +941,33 @@ static BOOL resolve_hosts(const char *name,
if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
struct in_addr return_ip;
putip((char *)&return_ip,(char *)hp->h_addr);
- *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
+ *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service));
if(*return_iplist == NULL) {
DEBUG(3,("resolve_hosts: malloc fail !\n"));
return False;
}
- **return_iplist = return_ip;
+ (*return_iplist)->ip = return_ip;
+ (*return_iplist)->port = PORT_NONE;
*return_count = 1;
return True;
}
return False;
}
-/********************************************************
+/*******************************************************************
Internal interface to resolve a name into an IP address.
Use this function if the string is either an IP address, DNS
or host name or NetBIOS name. This uses the name switch in the
smb.conf to determine the order of name resolution.
-*********************************************************/
+
+ Added support for ip addr/port to support ADS ldap servers.
+ the only place we currently care about the port is in the
+ resolve_hosts() when looking up DC's via SRV RR entries in DNS
+**********************************************************************/
static BOOL internal_resolve_name(const char *name, int name_type,
- struct in_addr **return_iplist, int *return_count)
+ struct ip_service **return_iplist,
+ int *return_count, const char *resolve_order)
{
pstring name_resolve_list;
fstring tok;
@@ -793,7 +976,6 @@ static BOOL internal_resolve_name(const char *name, int name_type,
BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
BOOL is_address = is_ipaddress(name);
BOOL result = False;
- struct in_addr *nodupes_iplist;
int i;
*return_iplist = NULL;
@@ -802,42 +984,56 @@ static BOOL internal_resolve_name(const char *name, int name_type,
DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
if (allzeros || allones || is_address) {
- *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
- if(*return_iplist == NULL) {
- DEBUG(3,("internal_resolve_name: malloc fail !\n"));
+
+ if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
+ DEBUG(0,("internal_resolve_name: malloc fail !\n"));
return False;
}
+
if(is_address) {
+ /* ignore the port here */
+ (*return_iplist)->port = PORT_NONE;
+
/* if it's in the form of an IP address then get the lib to interpret it */
- if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){
+ if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
return False;
}
} else {
- (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
+ (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
*return_count = 1;
}
return True;
}
- /* Check netbios name cache */
+ /* Check name cache */
if (namecache_fetch(name, name_type, return_iplist, return_count)) {
-
- /* This could be a negative response */
-
- return (*return_count > 0);
+ /* This could be a negative response */
+ return (*return_count > 0);
}
- pstrcpy(name_resolve_list, lp_name_resolve_order());
- ptr = name_resolve_list;
- if (!ptr || !*ptr)
+ /* set the name resolution order */
+
+ if ( !resolve_order )
+ pstrcpy(name_resolve_list, lp_name_resolve_order());
+ else
+ pstrcpy(name_resolve_list, resolve_order);
+
+ if ( !name_resolve_list[0] )
ptr = "host";
+ else
+ ptr = name_resolve_list;
+ /* iterate through the name resolution backends */
+
while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
if((strequal(tok, "host") || strequal(tok, "hosts"))) {
- if (name_type == 0x20) {
- if (resolve_hosts(name, return_iplist, return_count)) {
+ /* deal with 0x20 & 0x1c names here. The latter will result
+ in a SRV record lookup for _ldap._tcp.<domain> if we are using
+ 'security = ads' */
+ if ( name_type==0x20 || name_type == 0x1c ) {
+ if (resolve_hosts(name, name_type, return_iplist, return_count)) {
result = True;
goto done;
}
@@ -878,58 +1074,31 @@ static BOOL internal_resolve_name(const char *name, int name_type,
controllers including the PDC in iplist[1..n]. Iterating over
the iplist when the PDC is down will cause two sets of timeouts. */
- if (*return_count && (nodupes_iplist = (struct in_addr *)
- malloc(sizeof(struct in_addr) * (*return_count)))) {
- int nodupes_count = 0;
-
- /* Iterate over return_iplist looking for duplicates */
-
- for (i = 0; i < *return_count; i++) {
- BOOL is_dupe = False;
- int j;
-
- for (j = i + 1; j < *return_count; j++) {
- if (ip_equal((*return_iplist)[i],
- (*return_iplist)[j])) {
- is_dupe = True;
- break;
- }
- }
-
- if (!is_dupe) {
-
- /* This one not a duplicate */
-
- nodupes_iplist[nodupes_count] = (*return_iplist)[i];
- nodupes_count++;
- }
- }
-
- /* Switcheroo with original list */
-
- free(*return_iplist);
-
- *return_iplist = nodupes_iplist;
- *return_count = nodupes_count;
+ if ( *return_count ) {
+ *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
}
/* Save in name cache */
- for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
- DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name,
- name_type, inet_ntoa((*return_iplist)[i])));
-
+ if ( DEBUGLEVEL >= 100 ) {
+ for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
+ DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
+ name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
+ }
+
namecache_store(name, name_type, *return_count, *return_iplist);
/* Display some debugging info */
- DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
- *return_count));
-
- for (i = 0; i < *return_count; i++)
- DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
+ if ( DEBUGLEVEL >= 10 ) {
+ DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
+ *return_count));
- DEBUG(10, ("\n"));
+ for (i = 0; i < *return_count; i++)
+ DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
+ DEBUG(10, ("\n"));
+ }
+
return result;
}
@@ -942,7 +1111,7 @@ static BOOL internal_resolve_name(const char *name, int name_type,
BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
{
- struct in_addr *ip_list = NULL;
+ struct ip_service *ip_list = NULL;
int count = 0;
if (is_ipaddress(name)) {
@@ -950,20 +1119,23 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
return True;
}
- if (internal_resolve_name(name, name_type, &ip_list, &count)) {
+ if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
int i;
+
/* only return valid addresses for TCP connections */
for (i=0; i<count; i++) {
- char *ip_str = inet_ntoa(ip_list[i]);
+ char *ip_str = inet_ntoa(ip_list[i].ip);
if (ip_str &&
strcmp(ip_str, "255.255.255.255") != 0 &&
- strcmp(ip_str, "0.0.0.0") != 0) {
- *return_ip = ip_list[i];
+ strcmp(ip_str, "0.0.0.0") != 0)
+ {
+ *return_ip = ip_list[i].ip;
SAFE_FREE(ip_list);
return True;
}
}
}
+
SAFE_FREE(ip_list);
return False;
}
@@ -974,7 +1146,7 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
BOOL find_master_ip(const char *group, struct in_addr *master_ip)
{
- struct in_addr *ip_list = NULL;
+ struct ip_service *ip_list = NULL;
int count = 0;
if (lp_disable_netbios()) {
@@ -982,13 +1154,13 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip)
return False;
}
- if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
- *master_ip = ip_list[0];
+ if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
+ *master_ip = ip_list[0].ip;
SAFE_FREE(ip_list);
return True;
}
- if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
- *master_ip = ip_list[0];
+ if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
+ *master_ip = ip_list[0].ip;
SAFE_FREE(ip_list);
return True;
}
@@ -998,285 +1170,87 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip)
}
/********************************************************
- Lookup a DC name given a Domain name and IP address.
-*********************************************************/
-
-BOOL lookup_dc_name(const char *srcname, const char *domain,
- struct in_addr *dc_ip, char *ret_name)
-{
-#if !defined(I_HATE_WINDOWS_REPLY_CODE)
- fstring dc_name;
- BOOL ret;
-
- if (lp_disable_netbios()) {
- DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
- return False;
- }
-
- /*
- * Due to the fact win WinNT *sucks* we must do a node status
- * query here... JRA.
- */
-
- *dc_name = '\0';
-
- ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
-
- if(ret && *dc_name) {
- fstrcpy(ret_name, dc_name);
- return True;
- }
-
- return False;
-
-#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
-
-JRA - This code is broken with BDC rollover - we need to do a full
-NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
-
- int retries = 3;
- int retry_time = 2000;
- struct timeval tval;
- struct packet_struct p;
- struct dgram_packet *dgram = &p.packet.dgram;
- char *ptr,*p2;
- char tmp[4];
- int len;
- struct sockaddr_in sock_name;
- int sock_len = sizeof(sock_name);
- const char *mailslot = NET_LOGON_MAILSLOT;
- char *mailslot_name;
- char buffer[1024];
- char *bufp;
- int dgm_id = generate_trn_id();
- int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
-
- if(sock == -1)
- return False;
-
- /* Find out the transient UDP port we have been allocated. */
- if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
- DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
- strerror(errno)));
- close(sock);
- return False;
- }
-
- /*
- * Create the request data.
- */
-
- memset(buffer,'\0',sizeof(buffer));
- bufp = buffer;
- SSVAL(bufp,0,QUERYFORPDC);
- bufp += 2;
- fstrcpy(bufp,srcname);
- bufp += (strlen(bufp) + 1);
- slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
- mailslot_name = bufp;
- bufp += (strlen(bufp) + 1);
- bufp = ALIGN2(bufp, buffer);
- bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
-
- SIVAL(bufp,0,1);
- SSVAL(bufp,4,0xFFFF);
- SSVAL(bufp,6,0xFFFF);
- bufp += 8;
- len = PTR_DIFF(bufp,buffer);
-
- memset((char *)&p,'\0',sizeof(p));
-
- /* DIRECT GROUP or UNIQUE datagram. */
- dgram->header.msg_type = 0x10;
- dgram->header.flags.node_type = M_NODE;
- dgram->header.flags.first = True;
- dgram->header.flags.more = False;
- dgram->header.dgm_id = dgm_id;
- dgram->header.source_ip = *iface_ip(*pdc_ip);
- dgram->header.source_port = ntohs(sock_name.sin_port);
- dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
- dgram->header.packet_offset = 0;
-
- make_nmb_name(&dgram->source_name,srcname,0);
- make_nmb_name(&dgram->dest_name,domain,0x1C);
-
- ptr = &dgram->data[0];
-
- /* Setup the smb part. */
- ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
- memcpy(tmp,ptr,4);
- set_message(ptr,17,17 + len,True);
- memcpy(ptr,tmp,4);
-
- CVAL(ptr,smb_com) = SMBtrans;
- SSVAL(ptr,smb_vwv1,len);
- SSVAL(ptr,smb_vwv11,len);
- SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
- SSVAL(ptr,smb_vwv13,3);
- SSVAL(ptr,smb_vwv14,1);
- SSVAL(ptr,smb_vwv15,1);
- SSVAL(ptr,smb_vwv16,2);
- p2 = smb_buf(ptr);
- pstrcpy(p2,mailslot);
- p2 = skip_string(p2,1);
-
- memcpy(p2,buffer,len);
- p2 += len;
-
- dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
-
- p.ip = *pdc_ip;
- p.port = DGRAM_PORT;
- p.fd = sock;
- p.timestamp = time(NULL);
- p.packet_type = DGRAM_PACKET;
-
- GetTimeOfDay(&tval);
-
- if (!send_packet(&p)) {
- DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
- close(sock);
- return False;
- }
-
- retries--;
-
- while (1) {
- struct timeval tval2;
- struct packet_struct *p_ret;
-
- GetTimeOfDay(&tval2);
- if (TvalDiff(&tval,&tval2) > retry_time) {
- if (!retries)
- break;
- if (!send_packet(&p)) {
- DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
- close(sock);
- return False;
- }
- GetTimeOfDay(&tval);
- retries--;
- }
-
- if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
- struct dgram_packet *dgram2 = &p_ret->packet.dgram;
- char *buf;
- char *buf2;
-
- buf = &dgram2->data[0];
- buf -= 4;
-
- if (CVAL(buf,smb_com) != SMBtrans) {
- DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
- CVAL(buf,smb_com), (unsigned int)SMBtrans ));
- free_packet(p_ret);
- continue;
- }
-
- len = SVAL(buf,smb_vwv11);
- buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
-
- if (len <= 0) {
- DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
- free_packet(p_ret);
- continue;
- }
-
- DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
- nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
- inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
-
- if(SVAL(buf2,0) != QUERYFORPDC_R) {
- DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
- (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
- free_packet(p_ret);
- continue;
- }
-
- buf2 += 2;
- /* Note this is safe as it is a bounded strcpy. */
- fstrcpy(ret_name, buf2);
- ret_name[sizeof(fstring)-1] = '\0';
- close(sock);
- free_packet(p_ret);
- return True;
- }
- }
-
- close(sock);
- return False;
-#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
-}
-
-/********************************************************
Get the IP address list of the primary domain controller
for a domain.
*********************************************************/
BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
{
- struct in_addr *ip_list;
+ struct ip_service *ip_list;
int count;
- int i = 0;
/* Look up #1B name */
- if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
+ if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order()))
return False;
/* if we get more than 1 IP back we have to assume it is a
multi-homed PDC and not a mess up */
-
+
if ( count > 1 ) {
- DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
-
- /* look for a local net */
- for ( i=0; i<count; i++ ) {
- if ( is_local_net( ip_list[i] ) )
- break;
- }
-
- /* if we hit then end then just grab the first
- one from the list */
-
- if ( i == count )
- i = 0;
+ DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
+ sort_ip_list2( ip_list, count );
}
- *ip = ip_list[i];
+ *ip = ip_list[0].ip;
SAFE_FREE(ip_list);
return True;
}
+/*********************************************************************
+ small wrapper function to get the DC list and sort it if neccessary
+*********************************************************************/
+BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL dns_only )
+{
+ BOOL ordered;
+
+ DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
+ (dns_only ? "hosts" : lp_name_resolve_order())));
+
+ if ( !get_dc_list(domain, ip_list, count, dns_only, &ordered) )
+ return False;
+
+ /* only sort if we don't already have an ordered list */
+ if ( !ordered )
+ sort_ip_list2( *ip_list, *count );
+
+ return True;
+}
+
/********************************************************
Get the IP address list of the domain controllers for
a domain.
*********************************************************/
-BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *ordered)
+BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
+ int *count, BOOL dns_only, int *ordered)
{
-
+ /* defined the name resolve order to internal_name_resolve()
+ only used for looking up 0x1c names */
+ const char *resolve_oder = (dns_only ? "hosts" : lp_name_resolve_order());
+
*ordered = False;
/* If it's our domain then use the 'password server' parameter. */
- if (strequal(domain, lp_workgroup())) {
+ if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
const char *p;
char *pserver = lp_passwordserver(); /* UNIX charset. */
+ char *port_str;
+ int port;
fstring name;
int num_addresses = 0;
int local_count, i, j;
- struct in_addr *return_iplist = NULL;
- struct in_addr *auto_ip_list = NULL;
+ struct ip_service *return_iplist = NULL;
+ struct ip_service *auto_ip_list = NULL;
BOOL done_auto_lookup = False;
int auto_count = 0;
if (!*pserver)
- return internal_resolve_name(
- domain, 0x1C, ip_list, count);
+ return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder);
p = pserver;
@@ -1289,7 +1263,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *
while (next_token(&p,name,LIST_SEP,sizeof(name))) {
if (strequal(name, "*")) {
- if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count) )
+ if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_oder) )
num_addresses += auto_count;
done_auto_lookup = True;
DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
@@ -1302,11 +1276,11 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *
just return the list of DC's */
if ( (num_addresses == 0) && !done_auto_lookup )
- return internal_resolve_name(domain, 0x1C, ip_list, count);
-
- return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
+ return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder);
- if (return_iplist == NULL) {
+ if ( (return_iplist = (struct ip_service *)
+ malloc(num_addresses * sizeof(struct ip_service))) == NULL )
+ {
DEBUG(3,("get_dc_list: malloc fail !\n"));
return False;
}
@@ -1322,59 +1296,59 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *
/* copy any addersses from the auto lookup */
if ( strequal(name, "*") ) {
- for ( j=0; j<auto_count; j++ )
- return_iplist[local_count++] = auto_ip_list[j];
+ for ( j=0; j<auto_count; j++ ) {
+ return_iplist[local_count].ip = auto_ip_list[j].ip;
+ return_iplist[local_count].port = auto_ip_list[j].port;
+ local_count++;
+ }
continue;
}
+
+ /* added support for address:port syntax for ads (not that I think
+ anyone will ever run the LDAP server in an AD domain on something
+ other than port 389 */
+
+ port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
+ if ( (port_str=strchr(name, ':')) != NULL ) {
+ *port_str = '\0';
+ port_str++;
+ port = atoi( port_str );
+ }
+
/* explicit lookup; resolve_name() will handle names & IP addresses */
-
- if ( resolve_name( name, &name_ip, 0x20) ) {
- return_iplist[local_count++] = name_ip;
+ if ( resolve_name( name, &name_ip, 0x20 ) ) {
+ return_iplist[local_count].ip = name_ip;
+ return_iplist[local_count].port = port;
+ local_count++;
*ordered = True;
}
-
}
SAFE_FREE(auto_ip_list);
- /* need to remove duplicates in the list if we have
- any explicit password servers */
+ /* need to remove duplicates in the list if we have any
+ explicit password servers */
- if ( *ordered ) {
- /* one loop to remove duplicates */
- for ( i=0; i<local_count; i++ ) {
- if ( is_zero_ip(return_iplist[i]) )
- continue;
-
- for ( j=i+1; j<local_count; j++ ) {
- if ( ip_equal( return_iplist[i], return_iplist[j]) )
- zero_ip(&return_iplist[j]);
- }
- }
-
- /* one loop to clean up any holes we left */
- /* first ip should never be a zero_ip() */
- for (i = 0; i<local_count; ) {
- if ( is_zero_ip(return_iplist[i]) ) {
- if (i != local_count-1 )
- memmove(&return_iplist[i], &return_iplist[i+1],
- (local_count - i - 1)*sizeof(return_iplist[i]));
- local_count--;
- continue;
- }
- i++;
- }
- }
+ if ( local_count )
+ local_count = remove_duplicate_addrs2( return_iplist, local_count );
+ if ( DEBUGLEVEL >= 4 ) {
+ DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
+ *ordered ? "":"un"));
+ DEBUG(4,("get_dc_list: "));
+ for ( i=0; i<local_count; i++ )
+ DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
+ DEBUGADD(4,("\n"));
+ }
+
*ip_list = return_iplist;
*count = local_count;
-
- DEBUG(8,("get_dc_list: return %d ip addresses\n", *count));
return (*count != 0);
}
- return internal_resolve_name(domain, 0x1C, ip_list, count);
+ DEBUG(10,("get_dc_list: defaulting to internal auto lookup for domain %s\n", domain));
+
+ return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder);
}
-
diff --git a/source/libsmb/namequery_dc.c b/source/libsmb/namequery_dc.c
index e98b728963e..8bfb00b9adc 100644
--- a/source/libsmb/namequery_dc.c
+++ b/source/libsmb/namequery_dc.c
@@ -5,6 +5,7 @@
Copyright (C) Tim Potter 2001
Copyright (C) Andrew Bartlett 2002
+ 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
@@ -24,148 +25,58 @@
#include "includes.h"
-
-#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */
-
-struct failed_connection_cache {
- fstring domain_name;
- fstring controller;
- time_t lookup_time;
- NTSTATUS nt_status;
- struct failed_connection_cache *prev, *next;
-};
-
-static struct failed_connection_cache *failed_connection_cache;
-
-/**********************************************************************
- Check for a previously failed connection
-**********************************************************************/
-
-static NTSTATUS check_negative_conn_cache( const char *domain, const char *server )
+/**************************************************************************
+ Find the name and IP address for a server in he realm/domain
+ *************************************************************************/
+
+static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_name)
{
- struct failed_connection_cache *fcc;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-
- /* can't check if we don't have strings */
-
- if ( !domain || !server )
- return NT_STATUS_OK;
-
- for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
-
- /*
- * we have a match IFF the domain and server name matches
- * (a) the domain matches,
- * (b) the IP address matches (if we have one)
- * (c) the server name (if specified) matches
- */
-
- if ( !strequal(domain, fcc->domain_name) || !strequal(server, fcc->controller) )
- continue; /* no match; check the next entry */
-
- /* we have a match so see if it is still current */
-
- if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT)
- {
- /* Cache entry has expired, delete it */
-
- DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n",
- domain, server ));
-
- DLIST_REMOVE(failed_connection_cache, fcc);
- SAFE_FREE(fcc);
-
- return NT_STATUS_OK;
- }
-
- /* The timeout hasn't expired yet so return false */
-
- DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n",
- domain, server ));
-
- result = fcc->nt_status;
- return result;
- }
+ ADS_STRUCT *ads;
+ const char *realm = domain;
- /* end of function means no cache entry */
- return NT_STATUS_OK;
-}
-
-/**********************************************************************
- Add an entry to the failed conneciton cache
-**********************************************************************/
+ if (strcasecmp(realm, lp_workgroup()) == 0)
+ realm = lp_realm();
-void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result)
-{
- struct failed_connection_cache *fcc;
+ ads = ads_init(realm, domain, NULL);
+ if (!ads)
+ return False;
- SMB_ASSERT(!NT_STATUS_IS_OK(result));
+ /* we don't need to bind, just connect */
+ ads->auth.flags |= ADS_AUTH_NO_BIND;
- /* Check we already aren't in the cache. We always have to have
- a domain, but maybe not a specific DC name. */
+ DEBUG(4,("ads_dc_name: domain=%s\n", domain));
- for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
- if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) )
- {
- DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n",
- domain, server ));
- return;
- }
- }
+#ifdef HAVE_ADS
+ /* a full ads_connect() is actually overkill, as we don't srictly need
+ to do the SASL auth in order to get the info we need, but libads
+ doesn't offer a better way right now */
+ ads_connect(ads);
+#endif
- /* Create negative lookup cache entry for this domain and controller */
+ if (!ads->config.realm)
+ return False;
- if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) )
- {
- DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
- return;
- }
-
- ZERO_STRUCTP(fcc);
+ fstrcpy(srv_name, ads->config.ldap_server_name);
+ strupper(srv_name);
+ *dc_ip = ads->ldap_ip;
+ ads_destroy(&ads);
- fstrcpy( fcc->domain_name, domain );
- fstrcpy( fcc->controller, server );
- fcc->lookup_time = time(NULL);
- fcc->nt_status = result;
+ DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n",
+ srv_name, inet_ntoa(*dc_ip)));
- DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n",
- domain, server ));
-
- DLIST_ADD(failed_connection_cache, fcc);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void flush_negative_conn_cache( void )
-{
- struct failed_connection_cache *fcc;
-
- fcc = failed_connection_cache;
-
- while (fcc) {
- struct failed_connection_cache *fcc_next;
-
- fcc_next = fcc->next;
- DLIST_REMOVE(failed_connection_cache, fcc);
- free(fcc);
-
- fcc = fcc_next;
- }
-
+ return True;
}
/****************************************************************************
- Utility function to return the name of a DC using RPC. The name is
- guaranteed to be valid since we have already done a name_status_find on it
- and we have checked our negative connection cache
+ Utility function to return the name of a DC. The name is guaranteed to be
+ valid since we have already done a name_status_find on it
***************************************************************************/
-
-BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out)
+
+static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
{
- struct in_addr *ip_list = NULL, dc_ip, exclude_ip;
+ struct ip_service *ip_list = NULL;
+ struct in_addr dc_ip, exclude_ip;
int count, i;
- BOOL list_ordered;
BOOL use_pdc_only;
NTSTATUS result;
@@ -177,10 +88,12 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out)
if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) )
{
- DEBUG(10,("rpc_find_dc: Atempting to lookup PDC to avoid sam sync delays\n"));
+ DEBUG(10,("rpc_dc_name: Atempting to lookup PDC to avoid sam sync delays\n"));
- if (name_status_find(domain, 0x1c, 0x20, dc_ip, srv_name)) {
- /* makre we we haven't tried this on previously and failed */
+ /* check the connection cache and perform the node status
+ lookup only if the IP is not found to be bad */
+
+ if (name_status_find(domain, 0x1b, 0x20, dc_ip, srv_name) ) {
result = check_negative_conn_cache( domain, srv_name );
if ( NT_STATUS_IS_OK(result) )
goto done;
@@ -191,7 +104,7 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out)
/* get a list of all domain controllers */
- if (!get_dc_list( domain, &ip_list, &count, &list_ordered) ) {
+ if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
return False;
}
@@ -200,40 +113,37 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out)
if ( use_pdc_only ) {
for (i = 0; i < count; i++) {
- if (ip_equal( exclude_ip, ip_list[i]))
- zero_ip(&ip_list[i]);
+ if (ip_equal( exclude_ip, ip_list[i].ip))
+ zero_ip(&ip_list[i].ip);
}
}
- /* Pick a nice close server, but only if the list was not ordered */
- if (!list_ordered && (count > 1) ) {
- qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
- }
-
for (i = 0; i < count; i++) {
- if (is_zero_ip(ip_list[i]))
+ if (is_zero_ip(ip_list[i].ip))
continue;
- if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
+ if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) {
result = check_negative_conn_cache( domain, srv_name );
if ( NT_STATUS_IS_OK(result) ) {
- dc_ip = ip_list[i];
+ dc_ip = ip_list[i].ip;
goto done;
}
}
}
-
+
SAFE_FREE(ip_list);
- return False;
-done:
+ /* No-one to talk to )-: */
+ return False; /* Boo-hoo */
+
+ done:
/* We have the netbios name and IP address of a domain controller.
Ideally we should sent a SAMLOGON request to determine whether
the DC is alive and kicking. If we can catch a dead DC before
performing a cli_connect() we can avoid a 30-second timeout. */
- DEBUG(3, ("rpc_find_dc: Returning DC %s (%s) for domain %s\n", srv_name,
+ DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
inet_ntoa(dc_ip), domain));
*ip_out = dc_ip;
@@ -243,3 +153,28 @@ done:
return True;
}
+/**********************************************************************
+ wrapper around ads and rpc methods of finds DC's
+**********************************************************************/
+
+BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
+{
+ struct in_addr dc_ip;
+ BOOL ret;
+
+ zero_ip(&dc_ip);
+
+ ret = False;
+ if (lp_security() == SEC_ADS)
+ 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/netlogon_unigrp.c b/source/libsmb/netlogon_unigrp.c
deleted file mode 100644
index 466410d8005..00000000000
--- a/source/libsmb/netlogon_unigrp.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Universal groups helpers
- Copyright (C) Alexander Bokovoy 2002.
- Copyright (C) Andrew Bartlett 2002.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- This work was sponsored by Optifacio Software Services, Inc.
-*/
-
-#include "includes.h"
-#define UNIGROUP_PREFIX "UNIGROUP"
-
-/*
- Handle for netlogon_unigrp.tdb database. It is used internally
- in cli_store_uni_groups_*() and cli_fetch_uni_groups()
- and is initialized on first call to cli_store_uni_groups_*()
-*/
-static TDB_CONTEXT *netlogon_unigrp_tdb = NULL;
-
-/*
- Store universal groups info into netlogon_unigrp.tdb for
- later usage. We use 'domain_SID/user_rid' as key and
- array of uint32 where array[0] is number of elements
- and elements are array[1] ... array[array[0]]
-*/
-
-BOOL uni_group_cache_init(void)
-{
- if (!netlogon_unigrp_tdb) {
- netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0,
- TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
- }
-
- return (netlogon_unigrp_tdb != NULL);
-}
-
-BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user)
-{
- TDB_DATA key,data;
- fstring keystr, sid_string;
- DOM_SID user_sid;
- unsigned int i;
-
- if (!uni_group_cache_init()) {
- DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n"));
- return False;
- }
-
- sid_copy(&user_sid, &user->dom_sid.sid);
- sid_append_rid(&user_sid, user->user_rid);
-
- /* Prepare key as USER-SID string */
- slprintf(keystr, sizeof(keystr), "%s/%s",
- UNIGROUP_PREFIX,
- sid_to_string(sid_string, &user_sid));
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
-
- /* Prepare data */
- data.dsize = (user->num_groups2+1)*sizeof(uint32);
- data.dptr = talloc(mem_ctx, data.dsize);
- if(!data.dptr) {
- DEBUG(0,("uni_group_cache_store_netlogon: cannot allocate memory!\n"));
- talloc_destroy(mem_ctx);
- return False;
- }
-
- /* Store data in byteorder-independent format */
- SIVAL(&((uint32*)data.dptr)[0],0,user->num_groups2);
- for(i=1; i<=user->num_groups2; i++) {
- SIVAL(&((uint32*)data.dptr)[i],0,user->gids[i-1].g_rid);
- }
- if (tdb_store(netlogon_unigrp_tdb, key, data, TDB_REPLACE) == -1)
- return False;
- return True;
-}
-
-/*
- Fetch universal groups info from netlogon_unigrp.tdb for given
- domain sid and user rid and allocate it using given mem_ctx.
- Universal groups are returned as array of uint32 elements
- and elements are array[0] ... array[num_elements-1]
-
-*/
-DOM_SID **uni_group_cache_fetch(DOM_SID *domain, DOM_SID *user_sid,
- TALLOC_CTX *mem_ctx, uint32 *num_groups)
-{
- TDB_DATA key,data;
- fstring keystr;
- DOM_SID **groups;
- uint32 i;
- uint32 group_count;
- fstring sid_string;
-
- if (!domain) {
- DEBUG(1,("uni_group_cache_fetch: expected non-null domain sid\n"));
- return NULL;
- }
- if (!mem_ctx) {
- DEBUG(1,("uni_group_cache_fetch: expected non-null memory context\n"));
- return NULL;
- }
- if (!num_groups) {
- DEBUG(1,("uni_group_cache_fetch: expected non-null num_groups\n"));
- return NULL;
- }
- if (!netlogon_unigrp_tdb) {
- netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0,
- TDB_DEFAULT, O_RDWR, 0644);
- }
- if (!netlogon_unigrp_tdb) {
- DEBUG(5,("uni_group_cache_fetch: cannot open netlogon_unigrp.tdb for read - normal if not created yet\n"));
- return NULL;
- }
-
- *num_groups = 0;
-
- /* Fetch universal groups */
- slprintf(keystr, sizeof(keystr), "%s/%s",
- UNIGROUP_PREFIX,
- sid_to_string(sid_string, user_sid));
- key.dptr = keystr;
- key.dsize = strlen(keystr) + 1;
- data = tdb_fetch(netlogon_unigrp_tdb, key);
-
- /* There is no cached universal groups in netlogon_unigrp.tdb */
- /* for this user. */
- if (!data.dptr)
- return NULL;
-
- /* Transfer data to receiver's memory context */
- group_count = IVAL(&((uint32*)data.dptr)[0],0);
- groups = talloc(mem_ctx, (group_count)*sizeof(*groups));
- if (groups) {
- for(i=0; i<group_count; i++) {
- groups[i] = talloc(mem_ctx, sizeof(**groups));
- if (!groups[i]) {
- DEBUG(1,("uni_group_cache_fetch: cannot allocate uni groups in receiver's memory context\n"));
- return NULL;
- }
- sid_copy(groups[i], domain);
- sid_append_rid(groups[i], IVAL(&((uint32*)data.dptr)[i+1],0));
- }
- } else {
- DEBUG(1,("uni_group_cache_fetch: cannot allocate uni groups in receiver's memory context\n"));
- }
- SAFE_FREE(data.dptr);
- *num_groups = group_count;
- return groups;
-}
-
-/* Shutdown netlogon_unigrp database */
-BOOL uni_group_cache_shutdown(void)
-{
- if(netlogon_unigrp_tdb)
- return (tdb_close(netlogon_unigrp_tdb) == 0);
- return True;
-}
diff --git a/source/libsmb/samlogon_cache.c b/source/libsmb/samlogon_cache.c
new file mode 100644
index 00000000000..7863ad7727e
--- /dev/null
+++ b/source/libsmb/samlogon_cache.c
@@ -0,0 +1,238 @@
+/*
+ Unix SMB/CIFS implementation.
+ Net_sam_logon info3 helpers
+ Copyright (C) Alexander Bokovoy 2002.
+ Copyright (C) Andrew Bartlett 2002.
+ Copyright (C) Gerald Carter 2003.
+ 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.
+*/
+
+#include "includes.h"
+
+#define NETSAMLOGON_TDB "netsamlogon_cache.tdb"
+
+static TDB_CONTEXT *netsamlogon_tdb = NULL;
+
+/***********************************************************************
+ open the tdb
+ ***********************************************************************/
+
+BOOL netsamlogon_cache_init(void)
+{
+ if (!netsamlogon_tdb) {
+ netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0,
+ TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
+ }
+
+ return (netsamlogon_tdb != NULL);
+}
+
+
+/***********************************************************************
+ Shutdown samlogon_cache database
+***********************************************************************/
+
+BOOL netsamlogon_cache_shutdown(void)
+{
+ if(netsamlogon_tdb)
+ return (tdb_close(netsamlogon_tdb) == 0);
+
+ return True;
+}
+
+/***********************************************************************
+ Clear cache getpwnam and getgroups entries from the winbindd cache
+***********************************************************************/
+void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user)
+{
+ fstring domain;
+ TDB_DATA key;
+ BOOL got_tdb = False;
+
+ /* We may need to call this function from smbd which will not have
+ winbindd_cache.tdb open. Open the tdb if a NULL is passed. */
+
+ if (!tdb) {
+ tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000,
+ TDB_DEFAULT, O_RDWR, 0600);
+ if (!tdb) {
+ DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n"));
+ return;
+ }
+ got_tdb = True;
+ }
+
+ unistr2_to_ascii(domain, &user->uni_logon_dom, sizeof(domain) - 1);
+
+ /* Clear U/DOMAIN/RID cache entry */
+
+ asprintf(&key.dptr, "U/%s/%d", domain, user->user_rid);
+ key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */
+
+ DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr));
+
+ tdb_delete(tdb, key);
+
+ SAFE_FREE(key.dptr);
+
+ /* Clear UG/DOMAIN/RID cache entry */
+
+ asprintf(&key.dptr, "UG/%s/%d", domain, user->user_rid);
+ key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */
+
+ DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr));
+
+ tdb_delete(tdb, key);
+
+ SAFE_FREE(key.dptr);
+
+ if (got_tdb)
+ tdb_close(tdb);
+}
+
+/***********************************************************************
+ Store a NET_USER_INFO_3 structure in a tdb for later user
+***********************************************************************/
+
+BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user)
+{
+ TDB_DATA data;
+ fstring keystr;
+ prs_struct ps;
+ BOOL result = False;
+ DOM_SID user_sid;
+ time_t t = time(NULL);
+
+
+ if (!netsamlogon_cache_init()) {
+ DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB));
+ return False;
+ }
+
+ sid_copy( &user_sid, &user->dom_sid.sid );
+ sid_append_rid( &user_sid, user->user_rid );
+
+ /* Prepare key as DOMAIN-SID/USER-RID string */
+ slprintf(keystr, sizeof(keystr), "%s", sid_string_static(&user_sid));
+
+ DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr));
+
+ /* Prepare data */
+
+ prs_init( &ps,MAX_PDU_FRAG_LEN , mem_ctx, MARSHALL);
+
+ if ( !prs_uint32( "timestamp", &ps, 0, (uint32*)&t ) )
+ return False;
+
+ if ( net_io_user_info3("", user, &ps, 0, 3) )
+ {
+ data.dsize = prs_offset( &ps );
+ data.dptr = prs_data_p( &ps );
+
+ if (tdb_store_by_string(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1)
+ result = True;
+
+ prs_mem_free( &ps );
+ }
+
+ return result;
+}
+
+/***********************************************************************
+ Retrieves a NET_USER_INFO_3 structure from a tdb. Caller must
+ free the user_info struct (malloc()'d memory)
+***********************************************************************/
+
+NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
+{
+ NET_USER_INFO_3 *user = NULL;
+ TDB_DATA data, key;
+ prs_struct ps;
+ fstring keystr;
+ uint32 t;
+
+ if (!netsamlogon_cache_init()) {
+ DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB));
+ return False;
+ }
+
+ /* Prepare key as DOMAIN-SID/USER-RID string */
+ slprintf(keystr, sizeof(keystr), "%s", sid_string_static(user_sid));
+ DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr));
+ key.dptr = keystr;
+ key.dsize = strlen(keystr)+1;
+ data = tdb_fetch( netsamlogon_tdb, key );
+
+ if ( data.dptr ) {
+
+ if ( (user = (NET_USER_INFO_3*)malloc(sizeof(NET_USER_INFO_3))) == NULL )
+ return NULL;
+
+ prs_init( &ps, 0, mem_ctx, UNMARSHALL );
+ prs_give_memory( &ps, data.dptr, data.dsize, True );
+
+ if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) {
+ prs_mem_free( &ps );
+ return False;
+ }
+
+ if ( !net_io_user_info3("", user, &ps, 0, 3) ) {
+ SAFE_FREE( user );
+ }
+
+ prs_mem_free( &ps );
+
+#if 0 /* The netsamlogon cache needs to hang around. Something about
+ this feels wrong, but it is the only way we can get all of the
+ groups. The old universal groups cache didn't expire either.
+ --jerry */
+ {
+ time_t now = time(NULL);
+ uint32 time_diff;
+
+ /* is the entry expired? */
+ time_diff = now - t;
+
+ if ( (time_diff < 0 ) || (time_diff > lp_winbind_cache_time()) ) {
+ DEBUG(10,("netsamlogon_cache_get: cache entry expired \n"));
+ tdb_delete( netsamlogon_tdb, key );
+ SAFE_FREE( user );
+ }
+#endif
+ }
+
+ return user;
+}
+
+BOOL netsamlogon_cache_have(DOM_SID *user_sid)
+{
+ TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have");
+ NET_USER_INFO_3 *user = NULL;
+ BOOL result;
+
+ if (!mem_ctx)
+ return False;
+
+ user = netsamlogon_cache_get(mem_ctx, user_sid);
+
+ result = (user != NULL);
+
+ talloc_destroy(mem_ctx);
+ SAFE_FREE(user);
+
+ return result;
+}
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
index eedf7f401f9..fee2b666703 100644
--- a/source/libsmb/smb_signing.c
+++ b/source/libsmb/smb_signing.c
@@ -21,12 +21,50 @@
#include "includes.h"
+/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */
+struct outstanding_packet_lookup {
+ uint16 mid;
+ uint32 reply_seq_num;
+ struct outstanding_packet_lookup *prev, *next;
+};
+
struct smb_basic_signing_context {
DATA_BLOB mac_key;
uint32 send_seq_num;
- uint32 reply_seq_num;
+ struct outstanding_packet_lookup *outstanding_packet_list;
};
+static void store_sequence_for_reply(struct outstanding_packet_lookup **list,
+ uint16 mid, uint32 reply_seq_num)
+{
+ struct outstanding_packet_lookup *t;
+ struct outstanding_packet_lookup *tmp;
+
+ t = smb_xmalloc(sizeof(*t));
+ ZERO_STRUCTP(t);
+
+ DLIST_ADD_END(*list, t, tmp);
+ t->mid = mid;
+ t->reply_seq_num = reply_seq_num;
+}
+
+static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
+ uint16 mid, uint32 *reply_seq_num)
+{
+ struct outstanding_packet_lookup *t;
+
+ for (t = *list; t; t = t->next) {
+ if (t->mid == mid) {
+ *reply_seq_num = t->reply_seq_num;
+ DLIST_REMOVE(*list, t);
+ return True;
+ }
+ }
+ DEBUG(0, ("Unexpected incoming packet, it's MID (%u) does not match"
+ " a MID in our outstanding list!\n", mid));
+ return False;
+}
+
/***********************************************************
SMB signing - Common code before we set a new signing implementation
************************************************************/
@@ -99,35 +137,67 @@ static BOOL signing_good(struct cli_state *cli, BOOL good)
}
/***********************************************************
- SMB signing - Simple implementation - calculate a MAC to send.
+ SMB signing - Simple implementation - calculate a MAC on the packet
************************************************************/
-static void cli_simple_sign_outgoing_message(struct cli_state *cli)
+static void simple_packet_signature(struct smb_basic_signing_context *data,
+ const uchar *buf, uint32 seq_number,
+ unsigned char calc_md5_mac[16])
{
- unsigned char calc_md5_mac[16];
+ const size_t offset_end_of_sig = (smb_ss_field + 8);
+ unsigned char sequence_buf[8];
struct MD5Context md5_ctx;
- struct smb_basic_signing_context *data = cli->sign_info.signing_context;
/*
* Firstly put the sequence number into the first 4 bytes.
* and zero out the next 4 bytes.
*
- * We put the sequence into the packet, because we are going
- * to copy over it anyway.
+ * We do this here, to avoid modifying the packet.
*/
- SIVAL(cli->outbuf, smb_ss_field,
- data->send_seq_num);
- SIVAL(cli->outbuf, smb_ss_field + 4, 0);
- /* mark the packet as signed - BEFORE we sign it...*/
- mark_packet_signed(cli);
+ SIVAL(sequence_buf, 0, seq_number);
+ SIVAL(sequence_buf, 4, 0);
- /* Calculate the 16 byte MAC and place first 8 bytes into the field. */
+ /* 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.
+ */
MD5Init(&md5_ctx);
+
+ /* intialise with the key */
MD5Update(&md5_ctx, data->mac_key.data,
data->mac_key.length);
- MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf));
+
+ /* copy in the first bit of the SMB header */
+ MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4);
+
+ /* copy in the sequence number, instead of the signature */
+ MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
+
+ /* copy in the rest of the packet in, skipping the signature */
+ MD5Update(&md5_ctx, buf + offset_end_of_sig,
+ smb_len(buf) - (offset_end_of_sig - 4));
+
+ /* caclulate the MD5 sig */
MD5Final(calc_md5_mac, &md5_ctx);
+}
+
+
+/***********************************************************
+ SMB signing - Simple implementation - send the MAC.
+************************************************************/
+
+static void cli_simple_sign_outgoing_message(struct cli_state *cli)
+{
+ unsigned char calc_md5_mac[16];
+ struct smb_basic_signing_context *data = cli->sign_info.signing_context;
+
+ /* mark the packet as signed - BEFORE we sign it...*/
+ mark_packet_signed(cli);
+
+ simple_packet_signature(data, cli->outbuf, data->send_seq_num,
+ calc_md5_mac);
DEBUG(10, ("sent SMB signature of\n"));
dump_data(10, calc_md5_mac, 8);
@@ -136,8 +206,11 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli)
/* cli->outbuf[smb_ss_field+2]=0;
Uncomment this to test if the remote server actually verifies signatures...*/
+
data->send_seq_num++;
- data->reply_seq_num = data->send_seq_num;
+ store_sequence_for_reply(&data->outstanding_packet_list,
+ cli->mid,
+ data->send_seq_num);
data->send_seq_num++;
}
@@ -148,50 +221,21 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli)
static BOOL cli_simple_check_incoming_message(struct cli_state *cli)
{
BOOL good;
+ uint32 reply_seq_number;
unsigned char calc_md5_mac[16];
- unsigned char server_sent_mac[8];
- unsigned char sequence_buf[8];
- struct MD5Context md5_ctx;
- struct smb_basic_signing_context *data = cli->sign_info.signing_context;
- const size_t offset_end_of_sig = (smb_ss_field + 8);
+ unsigned char *server_sent_mac;
- /*
- * Firstly put the sequence number into the first 4 bytes.
- * and zero out the next 4 bytes.
- *
- * We do this here, to avoid modifying the packet.
- */
-
- SIVAL(sequence_buf, 0, data->reply_seq_num);
- SIVAL(sequence_buf, 4, 0);
-
- /* get a copy of the server-sent mac */
- memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac));
-
- /* 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.
- */
- MD5Init(&md5_ctx);
-
- /* intialise with the key */
- MD5Update(&md5_ctx, data->mac_key.data,
- data->mac_key.length);
-
- /* copy in the first bit of the SMB header */
- MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4);
-
- /* copy in the sequence number, instead of the signature */
- MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
+ struct smb_basic_signing_context *data = cli->sign_info.signing_context;
- /* copy in the rest of the packet in, skipping the signature */
- MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig,
- smb_len(cli->inbuf) - (offset_end_of_sig - 4));
+ if (!get_sequence_for_reply(&data->outstanding_packet_list,
+ SVAL(cli->inbuf, smb_mid),
+ &reply_seq_number)) {
+ return False;
+ }
- /* caclulate the MD5 sig */
- MD5Final(calc_md5_mac, &md5_ctx);
+ simple_packet_signature(data, cli->inbuf, reply_seq_number, calc_md5_mac);
+ server_sent_mac = &cli->inbuf[smb_ss_field];
good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
if (!good) {
@@ -211,6 +255,13 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli)
static void cli_simple_free_signing_context(struct cli_state *cli)
{
struct smb_basic_signing_context *data = cli->sign_info.signing_context;
+ struct outstanding_packet_lookup *list = data->outstanding_packet_list;
+
+ while (list) {
+ struct outstanding_packet_lookup *old_head = list;
+ DLIST_REMOVE(list, list);
+ SAFE_FREE(old_head);
+ }
data_blob_free(&data->mac_key);
SAFE_FREE(cli->sign_info.signing_context);
@@ -235,6 +286,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[
}
data = smb_xmalloc(sizeof(*data));
+
cli->sign_info.signing_context = data;
data->mac_key = data_blob(NULL, response.length + 16);
@@ -245,6 +297,9 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[
/* Initialise the sequence number */
data->send_seq_num = 0;
+ /* 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;
diff --git a/source/libsmb/trustdom_cache.c b/source/libsmb/trustdom_cache.c
index cddbb2daa61..83781250880 100644
--- a/source/libsmb/trustdom_cache.c
+++ b/source/libsmb/trustdom_cache.c
@@ -26,6 +26,7 @@
#define DBGC_CLASS DBGC_ALL /* there's no proper class yet */
#define TDOMKEY_FMT "TDOM/%s"
+#define TDOMTSKEY "TDOMCACHE/TIMESTAMP"
/**
@@ -89,7 +90,7 @@ BOOL trustdom_cache_shutdown(void)
static char* trustdom_cache_key(const char* name)
{
- char* keystr;
+ char* keystr = NULL;
asprintf(&keystr, TDOMKEY_FMT, strupper_static(name));
return keystr;
@@ -165,11 +166,14 @@ BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid)
/* prepare a key and get the value */
key = trustdom_cache_key(name);
+ if (!key) return False;
if (!gencache_get(key, &value, &timeout)) {
DEBUG(5, ("no entry for trusted domain %s found.\n", name));
+ SAFE_FREE(key);
return False;
} else {
+ SAFE_FREE(key);
DEBUG(5, ("trusted domain %s found (%s)\n", name, value));
}
@@ -183,6 +187,71 @@ BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid)
}
+/*******************************************************************
+ fetch the timestamp from the last update
+*******************************************************************/
+
+uint32 trustdom_cache_fetch_timestamp( void )
+{
+ char *value;
+ time_t timeout;
+ uint32 timestamp;
+
+ /* init the cache */
+ if (!gencache_init())
+ return False;
+
+ if (!gencache_get(TDOMTSKEY, &value, &timeout)) {
+ DEBUG(5, ("no timestamp for trusted domain cache located.\n"));
+ return 0;
+ }
+
+ timestamp = atoi(value);
+
+ return timestamp;
+}
+
+/*******************************************************************
+ store the timestamp from the last update
+*******************************************************************/
+
+BOOL trustdom_cache_store_timestamp( uint32 t, time_t timeout )
+{
+ fstring value;
+
+ /* init the cache */
+ if (!gencache_init())
+ return False;
+
+ snprintf(value, sizeof(value), "%d", t );
+
+ if (!gencache_set(TDOMTSKEY, value, timeout)) {
+ DEBUG(5, ("failed to set timestamp for trustdom_cache\n"));
+ return False;
+ }
+
+ return True;
+}
+
+
+/*******************************************************************
+ lock the timestamp entry in the trustdom_cache
+*******************************************************************/
+
+BOOL trustdom_cache_lock_timestamp( void )
+{
+ return gencache_lock_entry( TDOMTSKEY ) != -1;
+}
+
+/*******************************************************************
+ unlock the timestamp entry in the trustdom_cache
+*******************************************************************/
+
+void trustdom_cache_unlock_timestamp( void )
+{
+ gencache_unlock_entry( TDOMTSKEY );
+}
+
/**
* Delete single trustdom entry. Look at the
* gencache_iterate definition.
@@ -213,3 +282,61 @@ void trustdom_cache_flush(void)
DEBUG(5, ("Trusted domains cache flushed\n"));
}
+/********************************************************************
+ update the trustdom_cache if needed
+********************************************************************/
+#define TRUSTDOM_UPDATE_INTERVAL 600
+
+void update_trustdom_cache( void )
+{
+ char **domain_names;
+ DOM_SID *dom_sids;
+ uint32 num_domains;
+ uint32 last_check;
+ int time_diff;
+ TALLOC_CTX *mem_ctx = NULL;
+ time_t now = time(NULL);
+ int i;
+
+ /* get the timestamp. We have to initialise it if the last timestamp == 0 */
+
+ if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 )
+ trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL);
+
+ time_diff = now - last_check;
+
+ if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) {
+ DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n"));
+ return;
+ }
+
+ /* lock the timestamp */
+ if ( !trustdom_cache_lock_timestamp() )
+ return;
+
+ if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) {
+ DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n"));
+ goto done;
+ }
+
+ /* get the domains and store them */
+
+ if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names,
+ &num_domains, &dom_sids) )
+ {
+ for ( i=0; i<num_domains; i++ ) {
+ trustdom_cache_store( domain_names[i], NULL, &dom_sids[i],
+ now+TRUSTDOM_UPDATE_INTERVAL);
+ }
+
+ trustdom_cache_store_timestamp( now, now+TRUSTDOM_UPDATE_INTERVAL );
+ }
+
+done:
+ /* unlock and we're done */
+ trustdom_cache_unlock_timestamp();
+
+ talloc_destroy( mem_ctx );
+
+ return;
+}
diff --git a/source/libsmb/trusts_util.c b/source/libsmb/trusts_util.c
index 6244c844f29..464a3324c16 100644
--- a/source/libsmb/trusts_util.c
+++ b/source/libsmb/trusts_util.c
@@ -123,6 +123,71 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli,
}
+/*********************************************************************
+ Enumerate the list of trusted domains from a DC
+*********************************************************************/
+
+BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain,
+ char ***domain_names, uint32 *num_domains,
+ DOM_SID **sids )
+{
+ POLICY_HND pol;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ fstring dc_name;
+ struct in_addr dc_ip;
+ uint32 enum_ctx = 0;
+ struct cli_state *cli = NULL;
+ BOOL retry;
+
+ *domain_names = NULL;
+ *num_domains = 0;
+ *sids = NULL;
+
+ /* lookup a DC first */
+
+ if ( !get_dc_name(domain, dc_name, &dc_ip) ) {
+ DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n",
+ domain));
+ return False;
+ }
+
+ /* setup the anonymous connection */
+
+ result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC",
+ "", "", "", 0, &retry);
+ if ( !NT_STATUS_IS_OK(result) )
+ goto done;
+
+ /* open the LSARPC_PIPE */
+
+ if ( !cli_nt_session_open( cli, PI_LSARPC ) ) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* get a handle */
+
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
+ POLICY_VIEW_LOCAL_INFORMATION, &pol);
+ if ( !NT_STATUS_IS_OK(result) )
+ goto done;
+
+ /* Lookup list of trusted domains */
+
+ result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
+ num_domains, domain_names, sids);
+ if ( !NT_STATUS_IS_OK(result) )
+ goto done;
+
+done:
+ /* cleanup */
+
+ cli_nt_session_close( cli );
+ cli_shutdown( cli );
+
+ return NT_STATUS_IS_OK(result);
+}
+
/**
* Verify whether or not given domain is trusted.
@@ -139,31 +204,28 @@ BOOL is_trusted_domain(const char* dom_name)
time_t lct;
BOOL ret;
+ /* if we are a DC, then check for a direct trust relationships */
+
if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
- /*
- * Query the secrets db as an ultimate source of information
- * about trusted domain names. This is PDC or BDC case.
- */
ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
SAFE_FREE(pass);
if (ret)
- return ret;
+ return True;
}
+
+ /* if winbindd is not up then we need to update the trustdom_cache ourselves */
- /*
- * Query the trustdom_cache updated periodically. The only
- * way for domain member server.
- */
- if (trustdom_cache_enable() &&
- trustdom_cache_fetch(dom_name, &trustdom_sid)) {
- trustdom_cache_shutdown();
+ if ( !winbind_ping() )
+ update_trustdom_cache();
+
+ /* now the trustdom cache should be available a DC could still
+ * have a transitive trust so fall back to the cache of trusted
+ * domains (like a domain member would use */
+
+ if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
return True;
}
- /*
- * if nothing's been found, then give up here, although
- * the last resort might be to query the PDC.
- */
return False;
}
diff --git a/source/modules/vfs_extd_audit.c b/source/modules/vfs_extd_audit.c
index e677552eeae..06cddc78e43 100644
--- a/source/modules/vfs_extd_audit.c
+++ b/source/modules/vfs_extd_audit.c
@@ -328,7 +328,7 @@ NTSTATUS vfs_extd_audit_init(void)
{
NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "extd_audit", audit_op_tuples);
- if (NT_STATUS_IS_ERR(ret))
+ if (!NT_STATUS_IS_OK(ret))
return ret;
vfs_extd_audit_debug_level = debug_add_class("extd_audit");
diff --git a/source/modules/vfs_recycle.c b/source/modules/vfs_recycle.c
index 45c661edb7a..e725daedba4 100644
--- a/source/modules/vfs_recycle.c
+++ b/source/modules/vfs_recycle.c
@@ -287,7 +287,7 @@ static BOOL matchparam(const char **haystack_list, const char *needle)
}
for(i=0; haystack_list[i] ; i++) {
- if(!unix_wild_match((char *)haystack_list[i], (char *)needle)) {
+ if(!unix_wild_match(haystack_list[i], needle)) {
return True;
}
}
@@ -333,7 +333,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
BOOL exist;
int rc = -1;
- repository = alloc_sub_conn(conn, (char *)recycle_repository(handle));
+ repository = alloc_sub_conn(conn, recycle_repository(handle));
ALLOC_CHECK(repository, done);
/* shouldn't we allow absolute path names here? --metze */
trim_string(repository, "/", "/");
@@ -482,7 +482,7 @@ NTSTATUS vfs_recycle_init(void)
{
NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "recycle", recycle_ops);
- if (NT_STATUS_IS_ERR(ret))
+ if (!NT_STATUS_IS_OK(ret))
return ret;
vfs_recycle_debug_level = debug_add_class("recycle");
diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c
index 996d15180dc..196e44020c5 100644
--- a/source/nsswitch/wb_client.c
+++ b/source/nsswitch/wb_client.c
@@ -269,11 +269,8 @@ static int wb_getgroups(const char *user, gid_t **groups)
time consuming. If size is zero, list is not modified and the total
number of groups for the user is returned. */
-int winbind_getgroups(const char *user, int size, gid_t *list)
+int winbind_getgroups(const char *user, gid_t **list)
{
- gid_t *groups = NULL;
- int result, i;
-
/*
* Don't do the lookup if the name has no separator _and_ we are not in
* 'winbind use default domain' mode.
@@ -284,24 +281,19 @@ int winbind_getgroups(const char *user, int size, gid_t *list)
/* Fetch list of groups */
- result = wb_getgroups(user, &groups);
+ return wb_getgroups(user, list);
+}
- if (size == 0)
- goto done;
+/**********************************************************************
+ simple wrapper function to see if winbindd is alive
+**********************************************************************/
- if (result > size) {
- result = -1;
- errno = EINVAL; /* This is what getgroups() does */
- goto done;
- }
-
- /* Copy list of groups across */
+BOOL winbind_ping( void )
+{
+ NSS_STATUS result;
- for (i = 0; i < result; i++) {
- list[i] = groups[i];
- }
+ result = winbindd_request(WINBINDD_PING, NULL, NULL);
- done:
- SAFE_FREE(groups);
- return result;
+ return result == NSS_STATUS_SUCCESS;
}
+
diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c
index ac1ccb217ed..adcfdaa9d8a 100644
--- a/source/nsswitch/wb_common.c
+++ b/source/nsswitch/wb_common.c
@@ -395,11 +395,15 @@ int read_reply(struct winbindd_response *response)
NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
{
struct winbindd_request lrequest;
-
+ char *env;
+ int value;
+
/* Check for our tricky environment variable */
- if (getenv(WINBINDD_DONT_ENV)) {
- return NSS_STATUS_NOTFOUND;
+ if ( (env = getenv(WINBINDD_DONT_ENV)) != NULL ) {
+ value = atoi(env);
+ if ( value == 1 )
+ return NSS_STATUS_NOTFOUND;
}
if (!request) {
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index 61c54b37382..75e1d825ce5 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -710,7 +710,7 @@ int main(int argc, char **argv)
{ "sequence", 0, POPT_ARG_NONE, 0, OPT_SEQUENCE, "Show sequence numbers of all domains" },
{ "user-groups", 'r', POPT_ARG_STRING, &string_arg, 'r', "Get user groups", "USER" },
{ "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" },
- { "set-auth-user", 'A', POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
+ { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" },
{ "get-auth-user", 0, POPT_ARG_NONE, NULL, OPT_GET_AUTH_USER, "Retrieve user and password used by winbindd (root only)", NULL },
{ "ping", 'p', POPT_ARG_NONE, 0, 'p', "Ping winbindd to see if it is alive" },
POPT_COMMON_VERSION
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index c7e45e54293..ff9d0b90b9d 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -135,8 +135,17 @@ static void print_winbindd_status(void)
static void flush_caches(void)
{
+#if 0
/* Clear cached user and group enumation info */
- wcache_flush_cache();
+ if (!opt_dual_daemon) /* Until we have coherent cache flush. */
+ wcache_flush_cache();
+#endif
+
+ /* We need to invalidate cached user list entries on a SIGHUP
+ otherwise cached access denied errors due to restrict anonymous
+ hang around until the sequence number changes. */
+
+ wcache_invalidate_cache();
}
/* Handle the signal by unlinking socket and exiting */
@@ -833,7 +842,10 @@ int main(int argc, char **argv)
/* Winbind daemon initialisation */
- if (!idmap_init())
+ if (!winbindd_upgrade_idmap())
+ return 1;
+
+ if (!idmap_init(lp_idmap_backend()))
return 1;
if (!idmap_init_wellknown_sids())
@@ -886,12 +898,13 @@ int main(int argc, char **argv)
}
poptFreeContext(pc);
+ netsamlogon_cache_init(); /* Non-critical */
+
/* Loop waiting for requests */
process_loop();
trustdom_cache_shutdown();
- uni_group_cache_shutdown();
return 0;
}
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index 987a58e502f..2acb89b24bb 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/nsswitch/winbindd.h
@@ -98,9 +98,12 @@ struct winbindd_domain {
BOOL native_mode; /* is this a win2k domain in native mode ? */
/* Lookup methods for this domain (LDAP or RPC) */
-
struct winbindd_methods *methods;
+ /* the backend methods are used by the cache layer to find the right
+ backend */
+ struct winbindd_methods *backend;
+
/* Private data for the backends (used for connection cache) */
void *private;
@@ -109,6 +112,7 @@ struct winbindd_domain {
time_t last_seq_check;
uint32 sequence_number;
+ NTSTATUS last_status;
/* Linked list info */
diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c
index beb40af79de..1bb608b5bf3 100644
--- a/source/nsswitch/winbindd_ads.c
+++ b/source/nsswitch/winbindd_ads.c
@@ -65,7 +65,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
status = ads_connect(ads);
if (!ADS_ERR_OK(status) || !ads->config.realm) {
- extern struct winbindd_methods msrpc_methods;
+ extern struct winbindd_methods msrpc_methods, cache_methods;
DEBUG(1,("ads_connect for domain %s failed: %s\n",
domain->name, ads_errstr(status)));
ads_destroy(&ads);
@@ -75,7 +75,11 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
if (status.error_type == ADS_ERROR_SYSTEM &&
status.err.rc == ECONNREFUSED) {
DEBUG(1,("Trying MSRPC methods\n"));
- domain->methods = &msrpc_methods;
+ if (domain->methods == &cache_methods) {
+ domain->backend = &msrpc_methods;
+ } else {
+ domain->methods = &msrpc_methods;
+ }
}
return NULL;
}
@@ -112,7 +116,11 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
DEBUG(3,("ads: query_user_list\n"));
ads = ads_cached_connection(domain);
- if (!ads) goto done;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ goto done;
+ }
rc = ads_search_retry(ads, &res, "(objectCategory=user)", attrs);
if (!ADS_ERR_OK(rc)) {
@@ -209,7 +217,11 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
DEBUG(3,("ads: enum_dom_groups\n"));
ads = ads_cached_connection(domain);
- if (!ads) goto done;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ goto done;
+ }
rc = ads_search_retry(ads, &res, "(objectCategory=group)", attrs);
if (!ADS_ERR_OK(rc)) {
@@ -232,7 +244,9 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
i = 0;
group_flags = ATYPE_GLOBAL_GROUP;
- if ( domain->native_mode )
+
+ /* only grab domain local groups for our domain */
+ if ( domain->native_mode && strequal(lp_realm(), domain->alt_name) )
group_flags |= ATYPE_LOCAL_GROUP;
for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
@@ -282,7 +296,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
{
/*
* This is a stub function only as we returned the domain
- * ocal groups in enum_dom_groups() if the domain->native field
+ * local groups in enum_dom_groups() if the domain->native field
* was true. This is a simple performance optimization when
* using LDAP.
*
@@ -307,8 +321,11 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
DEBUG(3,("ads: name_to_sid\n"));
ads = ads_cached_connection(domain);
- if (!ads)
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
return NT_STATUS_UNSUCCESSFUL;
+ }
return ads_name_to_sid(ads, name, sid, type);
}
@@ -322,9 +339,13 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
{
ADS_STRUCT *ads = NULL;
DEBUG(3,("ads: sid_to_name\n"));
+
ads = ads_cached_connection(domain);
- if (!ads)
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
return NT_STATUS_UNSUCCESSFUL;
+ }
return ads_sid_to_name(ads, mem_ctx, sid, name, type);
}
@@ -338,7 +359,7 @@ static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
const char *dn,
char **name, uint32 *name_type, DOM_SID *sid)
{
- char *exp;
+ char *ldap_exp;
void *res = NULL;
const char *attrs[] = {"userPrincipalName", "sAMAccountName",
"objectSid", "sAMAccountType", NULL};
@@ -346,13 +367,15 @@ static BOOL dn_lookup(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
uint32 atype;
char *escaped_dn = escape_ldap_string_alloc(dn);
+ DEBUG(3,("ads: dn_lookup\n"));
+
if (!escaped_dn) {
return False;
}
- asprintf(&exp, "(distinguishedName=%s)", dn);
- rc = ads_search_retry(ads, &res, exp, attrs);
- SAFE_FREE(exp);
+ asprintf(&ldap_exp, "(distinguishedName=%s)", dn);
+ rc = ads_search_retry(ads, &res, ldap_exp, attrs);
+ SAFE_FREE(ldap_exp);
SAFE_FREE(escaped_dn);
if (!ADS_ERR_OK(rc)) {
@@ -392,7 +415,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
ADS_STATUS rc;
int count;
void *msg = NULL;
- char *exp;
+ char *ldap_exp;
char *sidstr;
uint32 group_rid;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -402,12 +425,16 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
DEBUG(3,("ads: query_user\n"));
ads = ads_cached_connection(domain);
- if (!ads) goto done;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ goto done;
+ }
sidstr = sid_binstring(sid);
- asprintf(&exp, "(objectSid=%s)", sidstr);
- rc = ads_search_retry(ads, &msg, exp, attrs);
- free(exp);
+ asprintf(&ldap_exp, "(objectSid=%s)", sidstr);
+ rc = ads_search_retry(ads, &msg, ldap_exp, attrs);
+ free(ldap_exp);
free(sidstr);
if (!ADS_ERR_OK(rc)) {
DEBUG(1,("query_user(sid=%s) ads_search: %s\n", sid_to_string(sid_string, sid), ads_errstr(rc)));
@@ -461,22 +488,28 @@ static NTSTATUS lookup_usergroups_alt(struct winbindd_domain *domain,
int count;
void *res = NULL;
void *msg = NULL;
- char *exp;
+ char *ldap_exp;
ADS_STRUCT *ads;
const char *group_attrs[] = {"objectSid", NULL};
+ DEBUG(3,("ads: lookup_usergroups_alt\n"));
+
ads = ads_cached_connection(domain);
- if (!ads) goto done;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ goto done;
+ }
/* buggy server, no tokenGroups. Instead lookup what groups this user
is a member of by DN search on member*/
- if (asprintf(&exp, "(&(member=%s)(objectClass=group))", user_dn) == -1) {
+ if (asprintf(&ldap_exp, "(&(member=%s)(objectClass=group))", user_dn) == -1) {
DEBUG(1,("lookup_usergroups(dn=%s) asprintf failed!\n", user_dn));
return NT_STATUS_NO_MEMORY;
}
- rc = ads_search_retry(ads, &res, exp, group_attrs);
- free(exp);
+ rc = ads_search_retry(ads, &res, ldap_exp, group_attrs);
+ free(ldap_exp);
if (!ADS_ERR_OK(rc)) {
DEBUG(1,("lookup_usergroups ads_search member=%s: %s\n", user_dn, ads_errstr(rc)));
@@ -540,7 +573,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
ADS_STATUS rc;
int count;
void *msg = NULL;
- char *exp;
+ char *ldap_exp;
char *user_dn;
DOM_SID *sids;
int i;
@@ -554,22 +587,26 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
*num_groups = 0;
ads = ads_cached_connection(domain);
- if (!ads) goto done;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ goto done;
+ }
if (!(sidstr = sid_binstring(sid))) {
DEBUG(1,("lookup_usergroups(sid=%s) sid_binstring returned NULL\n", sid_to_string(sid_string, sid)));
status = NT_STATUS_NO_MEMORY;
goto done;
}
- if (asprintf(&exp, "(objectSid=%s)", sidstr) == -1) {
+ if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) {
free(sidstr);
DEBUG(1,("lookup_usergroups(sid=%s) asprintf failed!\n", sid_to_string(sid_string, sid)));
status = NT_STATUS_NO_MEMORY;
goto done;
}
- rc = ads_search_retry(ads, &msg, exp, attrs);
- free(exp);
+ rc = ads_search_retry(ads, &msg, ldap_exp, attrs);
+ free(ldap_exp);
free(sidstr);
if (!ADS_ERR_OK(rc)) {
@@ -648,7 +685,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
int count;
void *res=NULL;
ADS_STRUCT *ads = NULL;
- char *exp;
+ char *ldap_exp;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
char *sidstr;
const char *attrs[] = {"member", NULL};
@@ -656,17 +693,23 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
int i, num_members;
fstring sid_string;
+ DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, sid_string_static(group_sid)));
+
*num_names = 0;
ads = ads_cached_connection(domain);
- if (!ads) goto done;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ goto done;
+ }
sidstr = sid_binstring(group_sid);
/* search for all members of the group */
- asprintf(&exp, "(objectSid=%s)",sidstr);
- rc = ads_search_retry(ads, &res, exp, attrs);
- free(exp);
+ asprintf(&ldap_exp, "(objectSid=%s)",sidstr);
+ rc = ads_search_retry(ads, &res, ldap_exp, attrs);
+ free(ldap_exp);
free(sidstr);
if (!ADS_ERR_OK(rc)) {
@@ -730,10 +773,16 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
ADS_STRUCT *ads = NULL;
ADS_STATUS rc;
+ DEBUG(3,("ads: fetch sequence_number for %s\n", domain->name));
+
*seq = DOM_SEQUENCE_NONE;
ads = ads_cached_connection(domain);
- if (!ads) return NT_STATUS_UNSUCCESSFUL;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ return NT_STATUS_UNSUCCESSFUL;
+ }
rc = ads_USN(ads, seq);
if (!ADS_ERR_OK(rc)) {
@@ -755,11 +804,17 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
ADS_STRUCT *ads;
ADS_STATUS rc;
+ DEBUG(3,("ads: trusted_domains\n"));
+
*num_domains = 0;
*names = NULL;
ads = ads_cached_connection(domain);
- if (!ads) return NT_STATUS_UNSUCCESSFUL;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ return NT_STATUS_UNSUCCESSFUL;
+ }
rc = ads_trusted_domains(ads, mem_ctx, num_domains, names, alt_names, dom_sids);
@@ -772,8 +827,14 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
ADS_STRUCT *ads;
ADS_STATUS rc;
+ DEBUG(3,("ads: domain_sid\n"));
+
ads = ads_cached_connection(domain);
- if (!ads) return NT_STATUS_UNSUCCESSFUL;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ return NT_STATUS_UNSUCCESSFUL;
+ }
rc = ads_domain_sid(ads, sid);
@@ -796,8 +857,14 @@ static NTSTATUS alternate_name(struct winbindd_domain *domain)
TALLOC_CTX *ctx;
char *workgroup;
+ DEBUG(3,("ads: alternate_name\n"));
+
ads = ads_cached_connection(domain);
- if (!ads) return NT_STATUS_UNSUCCESSFUL;
+
+ if (!ads) {
+ domain->last_status = NT_STATUS_SERVER_DISABLED;
+ return NT_STATUS_UNSUCCESSFUL;
+ }
if (!(ctx = talloc_init("alternate_name"))) {
return NT_STATUS_NO_MEMORY;
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index 1b817592ae8..eb7170ff607 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -4,6 +4,8 @@
Winbind cache backend functions
Copyright (C) Andrew Tridgell 2001
+ 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
@@ -26,7 +28,6 @@
#define DBGC_CLASS DBGC_WINBIND
struct winbind_cache {
- struct winbindd_methods *backend;
TDB_CONTEXT *tdb;
};
@@ -46,12 +47,14 @@ void wcache_flush_cache(void)
{
extern BOOL opt_nocache;
- if (!wcache) return;
+ if (!wcache)
+ return;
if (wcache->tdb) {
tdb_close(wcache->tdb);
wcache->tdb = NULL;
}
- if (opt_nocache) return;
+ if (opt_nocache)
+ return;
wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000,
TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600);
@@ -59,6 +62,7 @@ void wcache_flush_cache(void)
if (!wcache->tdb) {
DEBUG(0,("Failed to open winbindd_cache.tdb!\n"));
}
+ DEBUG(10,("wcache_flush_cache success\n"));
}
void winbindd_check_cache_size(time_t t)
@@ -93,30 +97,39 @@ void winbindd_check_cache_size(time_t t)
/* get the winbind_cache structure */
static struct winbind_cache *get_cache(struct winbindd_domain *domain)
{
- extern struct winbindd_methods msrpc_methods;
struct winbind_cache *ret = wcache;
- if (ret) return ret;
-
- ret = smb_xmalloc(sizeof(*ret));
- ZERO_STRUCTP(ret);
- switch (lp_security()) { /* winbind pdc disabled until ready
- if (!strcmp(domain->name, lp_workgroup()) && (lp_security() == SEC_USER)) {
- extern struct winbindd_methods passdb_methods;
- ret->backend = &passdb_methods;
-
- } else switch (lp_security()) { */
+ if (!domain->backend) {
+ extern struct winbindd_methods msrpc_methods;
+ switch (lp_security()) {
#ifdef HAVE_ADS
- case SEC_ADS: {
- extern struct winbindd_methods ads_methods;
- ret->backend = &ads_methods;
- break;
- }
+ 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) ) {
+ domain->backend = &ads_methods;
+ break;
+ }
+
+ if ( domain->native_mode ) {
+ domain->backend = &ads_methods;
+ break;
+ }
+
+ /* fall through */
+ }
#endif
- default:
- ret->backend = &msrpc_methods;
+ default:
+ domain->backend = &msrpc_methods;
+ }
}
+ if (ret)
+ return ret;
+
+ ret = smb_xmalloc(sizeof(*ret));
+ ZERO_STRUCTP(ret);
+
wcache = ret;
wcache_flush_cache();
@@ -128,12 +141,12 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain)
*/
static void centry_free(struct cache_entry *centry)
{
- if (!centry) return;
+ if (!centry)
+ return;
SAFE_FREE(centry->data);
free(centry);
}
-
/*
pull a uint32 from a cache entry
*/
@@ -204,8 +217,10 @@ static DOM_SID *centry_sid(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
{
DOM_SID *sid;
char *sid_string;
+
sid = talloc(mem_ctx, sizeof(*sid));
- if (!sid) return NULL;
+ if (!sid)
+ return NULL;
sid_string = centry_string(centry, mem_ctx);
if (!string_to_sid(sid, sid_string)) {
@@ -217,8 +232,17 @@ static DOM_SID *centry_sid(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
/* the server is considered down if it can't give us a sequence number */
static BOOL wcache_server_down(struct winbindd_domain *domain)
{
- if (!wcache->tdb) return False;
- return (domain->sequence_number == DOM_SEQUENCE_NONE);
+ BOOL ret;
+
+ if (!wcache->tdb)
+ return False;
+
+ ret = (domain->sequence_number == DOM_SEQUENCE_NONE);
+
+ if (ret)
+ DEBUG(10,("wcache_server_down: server for Domain %s down\n",
+ domain->name ));
+ return ret;
}
static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
@@ -227,14 +251,18 @@ static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
fstring key;
uint32 time_diff;
- if (!wcache->tdb)
+ if (!wcache->tdb) {
+ DEBUG(10,("fetch_cache_seqnum: tdb == NULL\n"));
return NT_STATUS_UNSUCCESSFUL;
+ }
snprintf( key, sizeof(key), "SEQNUM/%s", domain->name );
data = tdb_fetch_by_string( wcache->tdb, key );
- if ( !data.dptr || data.dsize!=8 )
+ if ( !data.dptr || data.dsize!=8 ) {
+ DEBUG(10,("fetch_cache_seqnum: invalid data size key [%s]\n", key ));
return NT_STATUS_UNSUCCESSFUL;
+ }
domain->sequence_number = IVAL(data.dptr, 0);
domain->last_seq_check = IVAL(data.dptr, 4);
@@ -242,8 +270,12 @@ static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
/* have we expired? */
time_diff = now - domain->last_seq_check;
- if ( time_diff > lp_winbind_cache_time() )
+ if ( time_diff > lp_winbind_cache_time() ) {
+ DEBUG(10,("fetch_cache_seqnum: timeout [%s][%u @ %u]\n",
+ domain->name, domain->sequence_number,
+ (uint32)domain->last_seq_check));
return NT_STATUS_UNSUCCESSFUL;
+ }
DEBUG(10,("fetch_cache_seqnum: success [%s][%u @ %u]\n",
domain->name, domain->sequence_number,
@@ -258,8 +290,10 @@ static NTSTATUS store_cache_seqnum( struct winbindd_domain *domain )
fstring key_str;
char buf[8];
- if (!wcache->tdb)
+ if (!wcache->tdb) {
+ DEBUG(10,("store_cache_seqnum: tdb == NULL\n"));
return NT_STATUS_UNSUCCESSFUL;
+ }
snprintf( key_str, sizeof(key_str), "SEQNUM/%s", domain->name );
key.dptr = key_str;
@@ -270,8 +304,10 @@ static NTSTATUS store_cache_seqnum( struct winbindd_domain *domain )
data.dptr = buf;
data.dsize = 8;
- if ( tdb_store( wcache->tdb, key, data, TDB_REPLACE) == -1 )
+ if ( tdb_store( wcache->tdb, key, data, TDB_REPLACE) == -1 ) {
+ DEBUG(10,("store_cache_seqnum: tdb_store fail key [%s]\n", key_str ));
return NT_STATUS_UNSUCCESSFUL;
+ }
DEBUG(10,("store_cache_seqnum: success [%s][%u @ %u]\n",
domain->name, domain->sequence_number,
@@ -280,8 +316,6 @@ static NTSTATUS store_cache_seqnum( struct winbindd_domain *domain )
return NT_STATUS_OK;
}
-
-
/*
refresh the domain sequence number. If force is True
then always refresh it, no matter how recently we fetched it
@@ -303,7 +337,8 @@ static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
/* see if we have to refetch the domain sequence number */
if (!force && (time_diff < cache_time)) {
- return;
+ DEBUG(10, ("refresh_sequence_number: %s time ok\n", domain->name));
+ goto done;
}
/* try to get the sequence number from the tdb cache first */
@@ -313,20 +348,21 @@ static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
if ( NT_STATUS_IS_OK(status) )
goto done;
- status = wcache->backend->sequence_number(domain, &domain->sequence_number);
+ status = domain->backend->sequence_number(domain, &domain->sequence_number);
if (!NT_STATUS_IS_OK(status)) {
domain->sequence_number = DOM_SEQUENCE_NONE;
}
+ domain->last_status = status;
domain->last_seq_check = time(NULL);
/* save the new sequence number ni the cache */
store_cache_seqnum( domain );
done:
- DEBUG(10, ("refresh_sequence_number: seq number is now %d\n",
- domain->sequence_number));
+ DEBUG(10, ("refresh_sequence_number: %s seq number is now %d\n",
+ domain->name, domain->sequence_number));
return;
}
@@ -334,12 +370,14 @@ done:
/*
decide if a cache entry has expired
*/
-static BOOL centry_expired(struct winbindd_domain *domain, struct cache_entry *centry)
+static BOOL centry_expired(struct winbindd_domain *domain, const char *keystr, struct cache_entry *centry)
{
/* if the server is OK and our cache entry came from when it was down then
the entry is invalid */
if (domain->sequence_number != DOM_SEQUENCE_NONE &&
centry->sequence_number == DOM_SEQUENCE_NONE) {
+ DEBUG(10,("centry_expired: Key %s for domain %s invalid sequence.\n",
+ keystr, domain->name ));
return True;
}
@@ -347,9 +385,14 @@ static BOOL centry_expired(struct winbindd_domain *domain, struct cache_entry *c
current sequence number then it is OK */
if (wcache_server_down(domain) ||
centry->sequence_number == domain->sequence_number) {
+ DEBUG(10,("centry_expired: Key %s for domain %s is good.\n",
+ keystr, domain->name ));
return False;
}
+ DEBUG(10,("centry_expired: Key %s for domain %s expired\n",
+ keystr, domain->name ));
+
/* it's expired */
return True;
}
@@ -380,9 +423,9 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
key.dptr = kstr;
key.dsize = strlen(kstr);
data = tdb_fetch(wcache->tdb, key);
- free(kstr);
if (!data.dptr) {
/* a cache miss */
+ free(kstr);
return NULL;
}
@@ -393,25 +436,38 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
if (centry->len < 8) {
/* huh? corrupt cache? */
+ DEBUG(10,("wcache_fetch: Corrupt cache for key %s domain %s (len < 8) ?\n",
+ kstr, domain->name ));
centry_free(centry);
+ free(kstr);
return NULL;
}
centry->status = NT_STATUS(centry_uint32(centry));
centry->sequence_number = centry_uint32(centry);
- if (centry_expired(domain, centry)) {
+ if (centry_expired(domain, kstr, centry)) {
extern BOOL opt_dual_daemon;
+ DEBUG(10,("wcache_fetch: entry %s expired for domain %s\n",
+ kstr, domain->name ));
+
if (opt_dual_daemon) {
extern BOOL background_process;
background_process = True;
+ DEBUG(10,("wcache_fetch: background processing expired entry %s for domain %s\n",
+ kstr, domain->name ));
} else {
centry_free(centry);
+ free(kstr);
return NULL;
}
}
+ DEBUG(10,("wcache_fetch: returning entry %s for domain %s\n",
+ kstr, domain->name ));
+
+ free(kstr);
return centry;
}
@@ -421,7 +477,8 @@ static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
static void centry_expand(struct cache_entry *centry, uint32 len)
{
uint8 *p;
- if (centry->len - centry->ofs >= len) return;
+ if (centry->len - centry->ofs >= len)
+ return;
centry->len *= 2;
p = realloc(centry->data, centry->len);
if (!p) {
@@ -466,7 +523,8 @@ static void centry_put_string(struct cache_entry *centry, const char *s)
len = strlen(s);
/* can't handle more than 254 char strings. Truncating is probably best */
- if (len > 254) len = 254;
+ if (len > 254)
+ len = 254;
centry_put_uint8(centry, len);
centry_expand(centry, len);
memcpy(centry->data + centry->ofs, s, len);
@@ -486,7 +544,8 @@ struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status
{
struct cache_entry *centry;
- if (!wcache->tdb) return NULL;
+ if (!wcache->tdb)
+ return NULL;
centry = smb_xmalloc(sizeof(*centry));
@@ -532,11 +591,13 @@ static void wcache_save_name_to_sid(struct winbindd_domain *domain,
fstring sid_string;
centry = centry_start(domain, status);
- if (!centry) return;
+ if (!centry)
+ return;
centry_put_sid(centry, sid);
fstrcpy(uname, name);
strupper(uname);
centry_end(centry, "NS/%s", sid_to_string(sid_string, sid));
+ DEBUG(10,("wcache_save_name_to_sid: %s -> %s\n", uname, sid_string));
centry_free(centry);
}
@@ -547,12 +608,14 @@ static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS sta
fstring sid_string;
centry = centry_start(domain, status);
- if (!centry) return;
+ if (!centry)
+ return;
if (NT_STATUS_IS_OK(status)) {
centry_put_uint32(centry, type);
centry_put_string(centry, name);
}
centry_end(centry, "SN/%s", sid_to_string(sid_string, sid));
+ DEBUG(10,("wcache_save_sid_to_name: %s -> %s\n", sid_string, name));
centry_free(centry);
}
@@ -563,12 +626,14 @@ static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WI
fstring sid_string;
centry = centry_start(domain, status);
- if (!centry) return;
+ if (!centry)
+ return;
centry_put_string(centry, info->acct_name);
centry_put_string(centry, info->full_name);
centry_put_sid(centry, info->user_sid);
centry_put_sid(centry, info->group_sid);
centry_end(centry, "U/%s", sid_to_string(sid_string, info->user_sid));
+ DEBUG(10,("wcache_save_user: %s (acct_name %s)\n", sid_string, info->acct_name));
centry_free(centry);
}
@@ -582,19 +647,23 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- unsigned int i;
+ unsigned int i, retry;
- if (!cache->tdb) goto do_query;
+ if (!cache->tdb)
+ goto do_query;
centry = wcache_fetch(cache, domain, "UL/%s", domain->name);
- if (!centry) goto do_query;
+ if (!centry)
+ goto do_query;
*num_entries = centry_uint32(centry);
- if (*num_entries == 0) goto do_cached;
+ if (*num_entries == 0)
+ goto do_cached;
(*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info)) smb_panic("query_user_list out of memory");
+ if (! (*info))
+ smb_panic("query_user_list out of memory");
for (i=0; i<(*num_entries); i++) {
(*info)[i].acct_name = centry_string(centry, mem_ctx);
(*info)[i].full_name = centry_string(centry, mem_ctx);
@@ -604,6 +673,10 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
do_cached:
status = centry->status;
+
+ DEBUG(10,("query_user_list: [Cached] - cached list for domain %s status %s\n",
+ domain->name, get_friendly_nt_error_msg(status) ));
+
centry_free(centry);
return status;
@@ -611,23 +684,48 @@ do_query:
*num_entries = 0;
*info = NULL;
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* Return status value returned by seq number check */
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
+
+ /* Put the query_user_list() in a retry loop. There appears to be
+ * some bug either with Windows 2000 or Samba's handling of large
+ * rpc replies. This manifests itself as sudden disconnection
+ * at a random point in the enumeration of a large (60k) user list.
+ * The retry loop simply tries the operation again. )-: It's not
+ * pretty but an acceptable workaround until we work out what the
+ * real problem is. */
- status = cache->backend->query_user_list(domain, mem_ctx, num_entries, info);
+ retry = 0;
+ do {
+
+ DEBUG(10,("query_user_list: [Cached] - doing backend query for list for domain %s\n",
+ domain->name ));
+
+ status = domain->backend->query_user_list(domain, mem_ctx, num_entries, info);
+ if (!NT_STATUS_IS_OK(status))
+ DEBUG(3, ("query_user_list: returned 0x%08x, retrying\n", NT_STATUS_V(status)));
+ if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL)) {
+ DEBUG(3, ("query_user_list: flushing connection cache\n"));
+ winbindd_cm_flush();
+ }
+
+ } while (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) &&
+ (retry++ < 5));
/* and save it */
refresh_sequence_number(domain, False);
centry = centry_start(domain, status);
- if (!centry) goto skip_save;
+ if (!centry)
+ goto skip_save;
centry_put_uint32(centry, *num_entries);
for (i=0; i<(*num_entries); i++) {
centry_put_string(centry, (*info)[i].acct_name);
centry_put_string(centry, (*info)[i].full_name);
centry_put_sid(centry, (*info)[i].user_sid);
centry_put_sid(centry, (*info)[i].group_sid);
- if (cache->backend->consistent) {
+ if (domain->backend->consistent) {
/* when the backend is consistent we can pre-prime some mappings */
wcache_save_name_to_sid(domain, NT_STATUS_OK,
(*info)[i].acct_name,
@@ -658,17 +756,21 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
NTSTATUS status;
unsigned int i;
- if (!cache->tdb) goto do_query;
+ if (!cache->tdb)
+ goto do_query;
centry = wcache_fetch(cache, domain, "GL/%s/domain", domain->name);
- if (!centry) goto do_query;
+ if (!centry)
+ goto do_query;
*num_entries = centry_uint32(centry);
- if (*num_entries == 0) goto do_cached;
+ if (*num_entries == 0)
+ goto do_cached;
(*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info)) smb_panic("enum_dom_groups out of memory");
+ if (! (*info))
+ smb_panic("enum_dom_groups out of memory");
for (i=0; i<(*num_entries); i++) {
fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
@@ -677,6 +779,10 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
do_cached:
status = centry->status;
+
+ DEBUG(10,("enum_dom_groups: [Cached] - cached list for domain %s status %s\n",
+ domain->name, get_friendly_nt_error_msg(status) ));
+
centry_free(centry);
return status;
@@ -684,16 +790,21 @@ do_query:
*num_entries = 0;
*info = NULL;
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* Return status value returned by seq number check */
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
- status = cache->backend->enum_dom_groups(domain, mem_ctx, num_entries, info);
+ DEBUG(10,("enum_dom_groups: [Cached] - doing backend query for list for domain %s\n",
+ domain->name ));
+
+ status = domain->backend->enum_dom_groups(domain, mem_ctx, num_entries, info);
/* and save it */
refresh_sequence_number(domain, False);
centry = centry_start(domain, status);
- if (!centry) goto skip_save;
+ if (!centry)
+ goto skip_save;
centry_put_uint32(centry, *num_entries);
for (i=0; i<(*num_entries); i++) {
centry_put_string(centry, (*info)[i].acct_name);
@@ -718,17 +829,21 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
NTSTATUS status;
unsigned int i;
- if (!cache->tdb) goto do_query;
+ if (!cache->tdb)
+ goto do_query;
centry = wcache_fetch(cache, domain, "GL/%s/local", domain->name);
- if (!centry) goto do_query;
+ if (!centry)
+ goto do_query;
*num_entries = centry_uint32(centry);
- if (*num_entries == 0) goto do_cached;
+ if (*num_entries == 0)
+ goto do_cached;
(*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info)) smb_panic("enum_dom_groups out of memory");
+ if (! (*info))
+ smb_panic("enum_dom_groups out of memory");
for (i=0; i<(*num_entries); i++) {
fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
@@ -743,11 +858,14 @@ do_cached:
indicate this. */
if (wcache_server_down(domain)) {
- DEBUG(10, ("query_user_list: returning cached user list and server was down\n"));
+ DEBUG(10, ("enum_local_groups: returning cached user list and server was down\n"));
status = NT_STATUS_MORE_PROCESSING_REQUIRED;
} else
status = centry->status;
+ DEBUG(10,("enum_local_groups: [Cached] - cached list for domain %s status %s\n",
+ domain->name, get_friendly_nt_error_msg(status) ));
+
centry_free(centry);
return status;
@@ -755,16 +873,21 @@ do_query:
*num_entries = 0;
*info = NULL;
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* Return status value returned by seq number check */
- status = cache->backend->enum_local_groups(domain, mem_ctx, num_entries, info);
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
+
+ DEBUG(10,("enum_local_groups: [Cached] - doing backend query for list for domain %s\n",
+ domain->name ));
+
+ status = domain->backend->enum_local_groups(domain, mem_ctx, num_entries, info);
/* and save it */
refresh_sequence_number(domain, False);
centry = centry_start(domain, status);
- if (!centry) goto skip_save;
+ if (!centry)
+ goto skip_save;
centry_put_uint32(centry, *num_entries);
for (i=0; i<(*num_entries); i++) {
centry_put_string(centry, (*info)[i].acct_name);
@@ -791,12 +914,14 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
fstring uname;
DOM_SID *sid2;
- if (!cache->tdb) goto do_query;
+ if (!cache->tdb)
+ goto do_query;
fstrcpy(uname, name);
strupper(uname);
centry = wcache_fetch(cache, domain, "NS/%s/%s", domain->name, uname);
- if (!centry) goto do_query;
+ if (!centry)
+ goto do_query;
*type = centry_uint32(centry);
sid2 = centry_sid(centry, mem_ctx);
if (!sid2) {
@@ -806,16 +931,31 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
}
status = centry->status;
+
+ DEBUG(10,("name_to_sid: [Cached] - cached name for domain %s status %s\n",
+ domain->name, get_friendly_nt_error_msg(status) ));
+
centry_free(centry);
return status;
do_query:
ZERO_STRUCTP(sid);
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->name_to_sid(domain, mem_ctx, name, sid, type);
+ /* If the seq number check indicated that there is a problem
+ * with this DC, then return that status... except for
+ * access_denied. This is special because the dc may be in
+ * "restrict anonymous = 1" mode, in which case it will deny
+ * most unauthenticated operations, but *will* allow the LSA
+ * name-to-sid that we try as a fallback. */
+
+ if (!(NT_STATUS_IS_OK(domain->last_status)
+ || NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED)))
+ return domain->last_status;
+
+ DEBUG(10,("name_to_sid: [Cached] - doing backend query for name for domain %s\n",
+ domain->name ));
+
+ status = domain->backend->name_to_sid(domain, mem_ctx, name, sid, type);
/* and save it */
wcache_save_name_to_sid(domain, status, name, sid, *type);
@@ -839,25 +979,42 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
NTSTATUS status;
fstring sid_string;
- if (!cache->tdb) goto do_query;
+ if (!cache->tdb)
+ goto do_query;
centry = wcache_fetch(cache, domain, "SN/%s", sid_to_string(sid_string, sid));
- if (!centry) goto do_query;
+ if (!centry)
+ goto do_query;
if (NT_STATUS_IS_OK(centry->status)) {
*type = centry_uint32(centry);
*name = centry_string(centry, mem_ctx);
}
status = centry->status;
+
+ DEBUG(10,("sid_to_name: [Cached] - cached name for domain %s status %s\n",
+ domain->name, get_friendly_nt_error_msg(status) ));
+
centry_free(centry);
return status;
do_query:
*name = NULL;
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->sid_to_name(domain, mem_ctx, sid, name, type);
+ /* If the seq number check indicated that there is a problem
+ * with this DC, then return that status... except for
+ * access_denied. This is special because the dc may be in
+ * "restrict anonymous = 1" mode, in which case it will deny
+ * most unauthenticated operations, but *will* allow the LSA
+ * sid-to-name that we try as a fallback. */
+
+ if (!(NT_STATUS_IS_OK(domain->last_status)
+ || NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED)))
+ return domain->last_status;
+
+ DEBUG(10,("sid_to_name: [Cached] - doing backend query for name for domain %s\n",
+ domain->name ));
+
+ status = domain->backend->sid_to_name(domain, mem_ctx, sid, name, type);
/* and save it */
refresh_sequence_number(domain, False);
@@ -877,29 +1034,51 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- fstring sid_string;
- if (!cache->tdb) goto do_query;
+ if (!cache->tdb)
+ goto do_query;
- centry = wcache_fetch(cache, domain, "U/%s", sid_to_string(sid_string, user_sid));
- if (!centry) goto do_query;
+ centry = wcache_fetch(cache, domain, "U/%s", sid_string_static(user_sid));
+
+ /* If we have an access denied cache entry and a cached info3 in the
+ samlogon cache then do a query. This will force the rpc back end
+ to return the info3 data. */
+
+ if (NT_STATUS_V(domain->last_status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) &&
+ netsamlogon_cache_have(user_sid)) {
+ DEBUG(10, ("query_user: cached access denied and have cached info3\n"));
+ domain->last_status = NT_STATUS_OK;
+ centry_free(centry);
+ goto do_query;
+ }
+
+ if (!centry)
+ goto do_query;
info->acct_name = centry_string(centry, mem_ctx);
info->full_name = centry_string(centry, mem_ctx);
info->user_sid = centry_sid(centry, mem_ctx);
info->group_sid = centry_sid(centry, mem_ctx);
status = centry->status;
+
+ DEBUG(10,("query_user: [Cached] - cached info for domain %s status %s\n",
+ domain->name, get_friendly_nt_error_msg(status) ));
+
centry_free(centry);
return status;
do_query:
ZERO_STRUCTP(info);
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
+ /* Return status value returned by seq number check */
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
- status = cache->backend->query_user(domain, mem_ctx, user_sid, info);
+ DEBUG(10,("sid_to_name: [Cached] - doing backend query for info for domain %s\n",
+ domain->name ));
+
+ status = domain->backend->query_user(domain, mem_ctx, user_sid, info);
/* and save it */
refresh_sequence_number(domain, False);
@@ -921,23 +1100,44 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
unsigned int i;
fstring sid_string;
- if (!cache->tdb) goto do_query;
+ if (!cache->tdb)
+ goto do_query;
centry = wcache_fetch(cache, domain, "UG/%s", sid_to_string(sid_string, user_sid));
- if (!centry) goto do_query;
+
+ /* If we have an access denied cache entry and a cached info3 in the
+ samlogon cache then do a query. This will force the rpc back end
+ to return the info3 data. */
+
+ if (NT_STATUS_V(domain->last_status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) &&
+ netsamlogon_cache_have(user_sid)) {
+ DEBUG(10, ("query_user: cached access denied and have cached info3\n"));
+ domain->last_status = NT_STATUS_OK;
+ centry_free(centry);
+ goto do_query;
+ }
+
+ if (!centry)
+ goto do_query;
*num_groups = centry_uint32(centry);
- if (*num_groups == 0) goto do_cached;
+ if (*num_groups == 0)
+ goto do_cached;
(*user_gids) = talloc(mem_ctx, sizeof(**user_gids) * (*num_groups));
- if (! (*user_gids)) smb_panic("lookup_usergroups out of memory");
+ if (! (*user_gids))
+ smb_panic("lookup_usergroups out of memory");
for (i=0; i<(*num_groups); i++) {
(*user_gids)[i] = centry_sid(centry, mem_ctx);
}
do_cached:
status = centry->status;
+
+ DEBUG(10,("lookup_usergroups: [Cached] - cached info for domain %s status %s\n",
+ domain->name, get_friendly_nt_error_msg(status) ));
+
centry_free(centry);
return status;
@@ -945,15 +1145,21 @@ do_query:
(*num_groups) = 0;
(*user_gids) = NULL;
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->lookup_usergroups(domain, mem_ctx, user_sid, num_groups, user_gids);
+ /* Return status value returned by seq number check */
+
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
+
+ DEBUG(10,("lookup_usergroups: [Cached] - doing backend query for info for domain %s\n",
+ domain->name ));
+
+ status = domain->backend->lookup_usergroups(domain, mem_ctx, user_sid, num_groups, user_gids);
/* and save it */
refresh_sequence_number(domain, False);
centry = centry_start(domain, status);
- if (!centry) goto skip_save;
+ if (!centry)
+ goto skip_save;
centry_put_uint32(centry, *num_groups);
for (i=0; i<(*num_groups); i++) {
centry_put_sid(centry, (*user_gids)[i]);
@@ -978,14 +1184,17 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
unsigned int i;
fstring sid_string;
- if (!cache->tdb) goto do_query;
+ if (!cache->tdb)
+ goto do_query;
centry = wcache_fetch(cache, domain, "GM/%s", sid_to_string(sid_string, group_sid));
- if (!centry) goto do_query;
+ if (!centry)
+ goto do_query;
*num_names = centry_uint32(centry);
- if (*num_names == 0) goto do_cached;
+ if (*num_names == 0)
+ goto do_cached;
(*sid_mem) = talloc(mem_ctx, sizeof(**sid_mem) * (*num_names));
(*names) = talloc(mem_ctx, sizeof(**names) * (*num_names));
@@ -1003,6 +1212,10 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
do_cached:
status = centry->status;
+
+ DEBUG(10,("lookup_groupmem: [Cached] - cached info for domain %s status %s\n",
+ domain->name, get_friendly_nt_error_msg(status) ));
+
centry_free(centry);
return status;
@@ -1012,17 +1225,22 @@ do_query:
(*names) = NULL;
(*name_types) = NULL;
+ /* Return status value returned by seq number check */
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->lookup_groupmem(domain, mem_ctx, group_sid, num_names,
- sid_mem, names, name_types);
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
+
+ DEBUG(10,("lookup_groupmem: [Cached] - doing backend query for info for domain %s\n",
+ domain->name ));
+
+ status = domain->backend->lookup_groupmem(domain, mem_ctx, group_sid, num_names,
+ sid_mem, names, name_types);
/* and save it */
refresh_sequence_number(domain, False);
centry = centry_start(domain, status);
- if (!centry) goto skip_save;
+ if (!centry)
+ goto skip_save;
centry_put_uint32(centry, *num_names);
for (i=0; i<(*num_names); i++) {
centry_put_sid(centry, (*sid_mem)[i]);
@@ -1054,29 +1272,78 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
char ***alt_names,
DOM_SID **dom_sids)
{
- struct winbind_cache *cache = get_cache(domain);
+ get_cache(domain);
+
+ DEBUG(10,("trusted_domains: [Cached] - doing backend query for info for domain %s\n",
+ domain->name ));
/* we don't cache this call */
- return cache->backend->trusted_domains(domain, mem_ctx, num_domains,
+ return domain->backend->trusted_domains(domain, mem_ctx, num_domains,
names, alt_names, dom_sids);
}
/* find the domain sid */
static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
{
- struct winbind_cache *cache = get_cache(domain);
+ get_cache(domain);
+
+ DEBUG(10,("domain_sid: [Cached] - doing backend query for info for domain %s\n",
+ domain->name ));
/* we don't cache this call */
- return cache->backend->domain_sid(domain, sid);
+ return domain->backend->domain_sid(domain, sid);
}
/* find the alternate names for the domain, if any */
static NTSTATUS alternate_name(struct winbindd_domain *domain)
{
- struct winbind_cache *cache = get_cache(domain);
+ get_cache(domain);
+
+ DEBUG(10,("alternate_name: [Cached] - doing backend query for info for domain %s\n",
+ domain->name ));
/* we don't cache this call */
- return cache->backend->alternate_name(domain);
+ return domain->backend->alternate_name(domain);
+}
+
+/* Invalidate cached user and group lists coherently */
+
+static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+ void *state)
+{
+ if (strncmp(kbuf.dptr, "UL/", 3) == 0 ||
+ strncmp(kbuf.dptr, "GL/", 3) == 0)
+ tdb_delete(the_tdb, kbuf);
+
+ return 0;
+}
+
+/* Invalidate the getpwnam and getgroups entries for a winbindd domain */
+
+void wcache_invalidate_samlogon(struct winbindd_domain *domain,
+ NET_USER_INFO_3 *info3)
+{
+ struct winbind_cache *cache;
+
+ if (!domain)
+ return;
+
+ cache = get_cache(domain);
+ netsamlogon_clear_cached_user(cache->tdb, info3);
+}
+
+void wcache_invalidate_cache(void)
+{
+ struct winbindd_domain *domain;
+
+ for (domain = domain_list(); domain; domain = domain->next) {
+ struct winbind_cache *cache = get_cache(domain);
+
+ DEBUG(10, ("wcache_invalidate_cache: invalidating cache "
+ "entries for %s\n", domain->name));
+ if (cache)
+ tdb_traverse(cache->tdb, traverse_fn, NULL);
+ }
}
/* the ADS backend methods are exposed via this structure */
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index 9a34293cdb0..7f351677783 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -51,9 +51,6 @@
- I'm pretty annoyed by all the make_nmb_name() stuff. It should be
moved down into another function.
- - There needs to be a utility function in libsmb/namequery.c that does
- cm_get_dc_name()
-
- Take care when destroying cli_structs as they can be shared between
various sam handles.
@@ -79,139 +76,6 @@ struct winbindd_cm_conn {
static struct winbindd_cm_conn *cm_conns = NULL;
-/* Get a domain controller name. Cache positive and negative lookups so we
- don't go to the network too often when something is badly broken. */
-
-#define GET_DC_NAME_CACHE_TIMEOUT 30 /* Seconds between dc lookups */
-
-struct get_dc_name_cache {
- fstring domain_name;
- fstring srv_name;
- time_t lookup_time;
- struct get_dc_name_cache *prev, *next;
-};
-
-/*
- find the DC for a domain using methods appropriate for a ADS domain
-*/
-static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
-{
- ADS_STRUCT *ads;
- const char *realm = domain;
-
- if (strcasecmp(realm, lp_workgroup()) == 0)
- realm = lp_realm();
-
- ads = ads_init(realm, domain, NULL);
- if (!ads)
- return False;
-
- /* we don't need to bind, just connect */
- ads->auth.flags |= ADS_AUTH_NO_BIND;
-
- DEBUG(4,("cm_ads_find_dc: domain=%s\n", domain));
-
-#ifdef HAVE_ADS
- /* a full ads_connect() is actually overkill, as we don't srictly need
- to do the SASL auth in order to get the info we need, but libads
- doesn't offer a better way right now */
- ads_connect(ads);
-#endif
-
- if (!ads->config.realm)
- return False;
-
- fstrcpy(srv_name, ads->config.ldap_server_name);
- strupper(srv_name);
- *dc_ip = ads->ldap_ip;
- ads_destroy(&ads);
-
- DEBUG(4,("cm_ads_find_dc: using server='%s' IP=%s\n",
- srv_name, inet_ntoa(*dc_ip)));
-
- return True;
-}
-
-
-
-static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
-{
- static struct get_dc_name_cache *get_dc_name_cache;
- struct get_dc_name_cache *dcc;
- struct in_addr dc_ip;
- BOOL ret;
-
- /* Check the cache for previous lookups */
-
- for (dcc = get_dc_name_cache; dcc; dcc = dcc->next) {
-
- if (!strequal(domain, dcc->domain_name))
- continue; /* Not our domain */
-
- if ((time(NULL) - dcc->lookup_time) >
- GET_DC_NAME_CACHE_TIMEOUT) {
-
- /* Cache entry has expired, delete it */
-
- DEBUG(10, ("get_dc_name_cache entry expired for %s\n", domain));
-
- DLIST_REMOVE(get_dc_name_cache, dcc);
- SAFE_FREE(dcc);
-
- break;
- }
-
- /* Return a positive or negative lookup for this domain */
-
- if (dcc->srv_name[0]) {
- DEBUG(10, ("returning positive get_dc_name_cache entry for %s\n", domain));
- fstrcpy(srv_name, dcc->srv_name);
- return True;
- } else {
- DEBUG(10, ("returning negative get_dc_name_cache entry for %s\n", domain));
- return False;
- }
- }
-
- /* Add cache entry for this lookup. */
-
- DEBUG(10, ("Creating get_dc_name_cache entry for %s\n", domain));
-
- if (!(dcc = (struct get_dc_name_cache *)
- malloc(sizeof(struct get_dc_name_cache))))
- return False;
-
- ZERO_STRUCTP(dcc);
-
- fstrcpy(dcc->domain_name, domain);
- dcc->lookup_time = time(NULL);
-
- DLIST_ADD(get_dc_name_cache, dcc);
-
- zero_ip(&dc_ip);
-
- ret = False;
- if (lp_security() == SEC_ADS)
- ret = cm_ads_find_dc(domain, &dc_ip, srv_name);
-
- if (!ret) {
- /* fall back on rpc methods if the ADS methods fail */
- ret = rpc_find_dc(domain, srv_name, &dc_ip);
- }
-
- if (!ret)
- return False;
-
- /* We have a name so make the cache entry positive now */
- fstrcpy(dcc->srv_name, srv_name);
-
- DEBUG(3, ("cm_get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name,
- inet_ntoa(dc_ip), domain));
-
- *ip_out = dc_ip;
-
- return True;
-}
/* Choose between anonymous or authenticated connections. We need to use
an authenticated connection if DCs have the RestrictAnonymous registry
@@ -265,7 +129,7 @@ static NTSTATUS cm_open_connection(const char *domain, const int pipe_index,
/* connection failure cache has been moved inside of get_dc_name
so we can deal with half dead DC's --jerry */
- if (!cm_get_dc_name(domain, new_conn->controller, &dc_ip)) {
+ if (!get_dc_name(domain, new_conn->controller, &dc_ip)) {
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
add_failed_connection_entry(domain, "", result);
return result;
@@ -455,8 +319,14 @@ BOOL cm_check_for_native_mode_win2k( const char *domain )
ret = True;
done:
+
+#if 0
+ /*
+ * I don't think we need to shutdown here ? JRA.
+ */
if ( conn.cli )
cli_shutdown( conn.cli );
+#endif
return ret;
}
@@ -465,7 +335,7 @@ done:
/* Return a LSA policy handle on a domain */
-CLI_POLICY_HND *cm_get_lsa_handle(const char *domain)
+NTSTATUS cm_get_lsa_handle(const char *domain, CLI_POLICY_HND **return_hnd)
{
struct winbindd_cm_conn *conn;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
@@ -475,13 +345,16 @@ CLI_POLICY_HND *cm_get_lsa_handle(const char *domain)
/* Look for existing connections */
if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_LSARPC, &conn)))
- return NULL;
+ return result;
/* This *shitty* code needs scrapping ! JRA */
+
if (policy_handle_is_valid(&conn->pol)) {
hnd.pol = conn->pol;
hnd.cli = conn->cli;
- return &hnd;
+ *return_hnd = &hnd;
+
+ return NT_STATUS_OK;
}
result = cli_lsa_open_policy(conn->cli, conn->cli->mem_ctx, False,
@@ -491,7 +364,7 @@ CLI_POLICY_HND *cm_get_lsa_handle(const char *domain)
/* Hit the cache code again. This cleans out the old connection and gets a new one */
if (conn->cli->fd == -1) { /* Try again, if the remote host disapeared */
if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_LSARPC, &conn)))
- return NULL;
+ return result;
result = cli_lsa_open_policy(conn->cli, conn->cli->mem_ctx, False,
des_access, &conn->pol);
@@ -501,19 +374,21 @@ CLI_POLICY_HND *cm_get_lsa_handle(const char *domain)
cli_shutdown(conn->cli);
DLIST_REMOVE(cm_conns, conn);
SAFE_FREE(conn);
- return NULL;
+ return result;
}
}
hnd.pol = conn->pol;
hnd.cli = conn->cli;
- return &hnd;
+ *return_hnd = &hnd;
+
+ return NT_STATUS_OK;
}
/* Return a SAM policy handle on a domain */
-CLI_POLICY_HND *cm_get_sam_handle(char *domain)
+NTSTATUS cm_get_sam_handle(char *domain, CLI_POLICY_HND **return_hnd)
{
struct winbindd_cm_conn *conn;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
@@ -523,39 +398,49 @@ CLI_POLICY_HND *cm_get_sam_handle(char *domain)
/* Look for existing connections */
if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_SAMR, &conn)))
- return NULL;
+ return result;
/* This *shitty* code needs scrapping ! JRA */
+
if (policy_handle_is_valid(&conn->pol)) {
hnd.pol = conn->pol;
hnd.cli = conn->cli;
- return &hnd;
+
+ *return_hnd = &hnd;
+
+ return NT_STATUS_OK;
}
+
result = cli_samr_connect(conn->cli, conn->cli->mem_ctx,
des_access, &conn->pol);
if (!NT_STATUS_IS_OK(result)) {
/* Hit the cache code again. This cleans out the old connection and gets a new one */
if (conn->cli->fd == -1) { /* Try again, if the remote host disapeared */
+
if (!NT_STATUS_IS_OK(result = get_connection_from_cache(domain, PIPE_SAMR, &conn)))
- return NULL;
+ return result;
result = cli_samr_connect(conn->cli, conn->cli->mem_ctx,
des_access, &conn->pol);
}
if (!NT_STATUS_IS_OK(result)) {
+
cli_shutdown(conn->cli);
DLIST_REMOVE(cm_conns, conn);
SAFE_FREE(conn);
- return NULL;
+
+ return result;
}
}
hnd.pol = conn->pol;
hnd.cli = conn->cli;
- return &hnd;
+ *return_hnd = &hnd;
+
+ return NT_STATUS_OK;
}
/* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the
@@ -608,6 +493,9 @@ NTSTATUS cm_get_netlogon_cli(const char *domain,
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());
result = cli_nt_establish_netlogon(conn->cli, sec_channel_type, trust_passwd);
@@ -659,3 +547,34 @@ void winbindd_cm_status(void)
else
DEBUG(0, ("\tNo active connections\n"));
}
+
+/* Close all cached connections */
+
+void winbindd_cm_flush(void)
+{
+ struct winbindd_cm_conn *conn, tmp;
+
+ /* Flush connection cache */
+
+ for (conn = cm_conns; conn; conn = conn->next) {
+
+ if (!connection_ok(conn))
+ continue;
+
+ DEBUG(10, ("Closing connection to %s on %s\n",
+ conn->pipe_name, conn->controller));
+
+ if (conn->cli)
+ cli_shutdown(conn->cli);
+
+ tmp.next = conn->next;
+
+ DLIST_REMOVE(cm_conns, conn);
+ SAFE_FREE(conn);
+ conn = &tmp;
+ }
+
+ /* Flush failed connection cache */
+
+ flush_negative_conn_cache();
+}
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index 94b6326b90a..70c8de6ee93 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -5,6 +5,7 @@
Copyright (C) Tim Potter 2000
Copyright (C) Jeremy Allison 2001.
+ Copyright (C) Gerald (Jerry) 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
@@ -75,9 +76,12 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
*num_gr_mem = 0;
- if (group_name_type != SID_NAME_DOM_GRP) {
- DEBUG(1, ("SID %s in domain %s isn't a domain group\n",
- sid_to_string(sid_string, group_sid), domain->name));
+ if ( !((group_name_type==SID_NAME_DOM_GRP) ||
+ ((group_name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
+ {
+ DEBUG(1, ("SID %s in domain %s isn't a domain group (%d)\n",
+ sid_to_string(sid_string, group_sid), domain->name,
+ group_name_type));
goto done;
}
@@ -210,6 +214,15 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
if (!parse_domain_user(tmp, name_domain, name_group))
return WINBINDD_ERROR;
+ /* don't handle our own domain if we are a DC. This code handles cases where
+ the account doesn't exist anywhere and gets passed on down the NSS layer */
+
+ if ( IS_DC_FOR_DOMAIN(domain->name) ) {
+ DEBUG(7,("winbindd_getgrnam: rejecting getpwnam() for %s\\%s since I am on the PDC for this domain\n",
+ name_domain, name_group));
+ return WINBINDD_ERROR;
+ }
+
/* Get info for the domain */
if ((domain = find_domain_from_name(name_domain)) == NULL) {
@@ -227,13 +240,15 @@ enum winbindd_result winbindd_getgrnam(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
- if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) {
+ if ( !((name_type==SID_NAME_DOM_GRP) ||
+ ((name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
+ {
DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
name_group, name_type));
return WINBINDD_ERROR;
}
- if (NT_STATUS_IS_ERR(sid_to_gid(&group_sid, &gid))) {
+ if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid))) {
DEBUG(1, ("error converting unix gid to sid\n"));
return WINBINDD_ERROR;
}
@@ -278,7 +293,7 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
/* Get rid from gid */
- if (NT_STATUS_IS_ERR(uid_to_sid(&group_sid, state->request.data.gid))) {
+ if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, state->request.data.gid))) {
DEBUG(1, ("could not convert gid %d to rid\n",
state->request.data.gid));
return WINBINDD_ERROR;
@@ -291,13 +306,6 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
- if (!((name_type == SID_NAME_ALIAS) ||
- (name_type == SID_NAME_DOM_GRP))) {
- DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
- group_name, name_type));
- return WINBINDD_ERROR;
- }
-
/* Fill in group structure */
domain = find_domain_from_sid(&group_sid);
@@ -307,6 +315,14 @@ enum winbindd_result winbindd_getgrgid(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
+ if ( !((name_type==SID_NAME_DOM_GRP) ||
+ ((name_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
+ {
+ DEBUG(1, ("name '%s' is not a local or domain group: %d\n",
+ group_name, name_type));
+ return WINBINDD_ERROR;
+ }
+
if (!fill_grent(&state->response.data.gr, dom_name, group_name,
state->request.data.gid) ||
!fill_grent_mem(domain, &group_sid, name_type,
@@ -353,6 +369,12 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
for (domain = domain_list(); domain != NULL; domain = domain->next) {
struct getent_state *domain_state;
+
+ /* don't add our domaina if we are a PDC */
+
+ if ( IS_DC_FOR_DOMAIN(domain->name) )
+ continue;
+
/* Create a state record for this domain */
if ((domain_state = (struct getent_state *)
@@ -450,10 +472,10 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
ent->num_sam_entries = num_entries;
- /* get the domain local groups if we are a member of a native win2k domain */
+ /* get the domain local groups if we are a member of a native win2k domain
+ and are not using LDAP to get the groups */
- if ( domain->native_mode
- && domain->methods->enum_local_groups
+ if ( lp_security() != SEC_ADS && domain->native_mode
&& strequal(lp_workgroup(), domain->name) )
{
DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n"));
@@ -590,7 +612,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state)
sid_copy(&group_sid, &domain->sid);
sid_append_rid(&group_sid, name_list[ent->sam_entry_index].rid);
- if (NT_STATUS_IS_ERR(sid_to_gid(&group_sid, &group_gid))) {
+ if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &group_gid))) {
DEBUG(1, ("could not look up gid for group %s\n",
name_list[ent->sam_entry_index].acct_name));
@@ -743,7 +765,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
ZERO_STRUCT(groups);
/* Get list of sam groups */
- ZERO_STRUCT(groups);
+
fstrcpy(groups.domain_name, domain->name);
get_sam_group_entries(&groups);
@@ -799,21 +821,26 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
}
/* Get user supplementary groups. This is much quicker than trying to
- invert the groups database. */
+ invert the groups database. We merge the groups from the gids and
+ other_sids info3 fields as trusted domain, universal group
+ memberships, and nested groups (win2k native mode only) are not
+ returned by the getgroups RPC call but are present in the info3. */
enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
{
fstring name_domain, name_user;
- DOM_SID user_sid;
+ DOM_SID user_sid, group_sid;
enum SID_NAME_USE name_type;
- uint32 num_groups, num_gids;
+ uint32 num_groups = 0;
+ uint32 num_gids = 0;
NTSTATUS status;
- DOM_SID **user_gids;
+ DOM_SID **user_grpsids;
struct winbindd_domain *domain;
enum winbindd_result result = WINBINDD_ERROR;
gid_t *gid_list;
unsigned int i;
TALLOC_CTX *mem_ctx;
+ NET_USER_INFO_3 *info3 = NULL;
/* Ensure null termination */
state->request.data.username[sizeof(state->request.data.username)-1]='\0';
@@ -853,33 +880,110 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
goto done;
}
- status = domain->methods->lookup_usergroups(domain, mem_ctx,
- &user_sid, &num_groups,
- &user_gids);
- if (!NT_STATUS_IS_OK(status)) goto done;
+ /* Treat the info3 cache as authoritative as the
+ lookup_usergroups() function may return cached data. */
- /* Copy data back to client */
+ if ((info3 = netsamlogon_cache_get(mem_ctx, &user_sid))) {
- num_gids = 0;
- gid_list = malloc(sizeof(gid_t) * num_groups);
+ DEBUG(10, ("winbindd_getgroups: info3 has %d groups, %d other sids\n",
+ info3->num_groups2, info3->num_other_sids));
- if (state->response.extra_data)
- goto done;
+ num_groups = info3->num_other_sids + info3->num_groups2;
+ gid_list = calloc(sizeof(gid_t), num_groups);
- for (i = 0; i < num_groups; i++) {
- gid_t gid;
+ /* Go through each other sid and convert it to a gid */
+
+ for (i = 0; i < info3->num_other_sids; i++) {
+ fstring name;
+ fstring dom_name;
+ enum SID_NAME_USE sid_type;
+
+ /* Is this sid known to us? It can either be
+ a trusted domain sid or a foreign sid. */
+
+ if (!winbindd_lookup_name_by_sid( &info3->other_sids[i].sid,
+ dom_name, name, &sid_type))
+ {
+ DEBUG(10, ("winbindd_getgroups: could not lookup name for %s\n",
+ sid_string_static(&info3->other_sids[i].sid)));
+ continue;
+ }
+
+ /* Check it is a domain group or an alias (domain local group)
+ in a win2k native mode domain. */
+
+ if ( !((sid_type==SID_NAME_DOM_GRP) ||
+ ((sid_type==SID_NAME_ALIAS) && strequal(lp_workgroup(), domain->name))) )
+ {
+ DEBUG(10, ("winbindd_getgroups: sid type %d "
+ "for %s is not a domain group\n",
+ sid_type,
+ sid_string_static(
+ &info3->other_sids[i].sid)));
+ continue;
+ }
+
+ /* Map to a gid */
+
+ if (!NT_STATUS_IS_OK(sid_to_gid(&info3->other_sids[i].sid,
+ &gid_list[num_gids])) )
+ {
+ DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n",
+ sid_string_static(&info3->other_sids[i].sid)));
+ continue;
+ }
+
+ /* 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(
+ &info3->other_sids[i].sid),
+ gid_list[num_gids]));
+
+ num_gids++;
+ }
+
+ for (i = 0; i < info3->num_groups2; i++) {
- if (NT_STATUS_IS_ERR(sid_to_gid(user_gids[i], &gid))) {
- fstring sid_string;
+ /* create the group SID */
+
+ sid_copy( &group_sid, &domain->sid );
+ sid_append_rid( &group_sid, info3->gids[i].g_rid );
- DEBUG(1, ("unable to convert group sid %s to gid\n",
- sid_to_string(sid_string, user_gids[i])));
- continue;
+ if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid_list[num_gids])) ) {
+ DEBUG(10, ("winbindd_getgroups: could not map sid %s to gid\n",
+ sid_string_static(&group_sid)));
+ }
+
+ num_gids++;
+ }
+
+ SAFE_FREE(info3);
+
+ } else {
+ status = domain->methods->lookup_usergroups(domain, mem_ctx,
+ &user_sid, &num_groups,
+ &user_grpsids);
+ if (!NT_STATUS_IS_OK(status))
+ goto done;
+
+ gid_list = malloc(sizeof(gid_t) * num_groups);
+
+ if (state->response.extra_data)
+ goto done;
+
+ for (i = 0; i < num_groups; i++) {
+ if (!NT_STATUS_IS_OK(sid_to_gid(user_grpsids[i], &gid_list[num_gids]))) {
+ DEBUG(1, ("unable to convert group sid %s to gid\n",
+ sid_string_static(user_grpsids[i])));
+ continue;
+ }
+ num_gids++;
}
- gid_list[num_gids] = gid;
- num_gids++;
}
+ /* Send data back to client */
+
state->response.data.num_entries = num_gids;
state->response.extra_data = gid_list;
state->response.length += num_gids * sizeof(gid_t);
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index 3b306eed3b2..3099944301f 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -1,4 +1,4 @@
-/*
+/*
Unix SMB/CIFS implementation.
Winbind daemon - pam auth funcions
@@ -53,7 +53,61 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-/* Return a password structure from a username. */
+/*******************************************************************
+ 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 ( lp_server_role()==ROLE_DOMAIN_MEMBER || strequal(domain, lp_workgroup()) )
+ {
+ /*
+ * Get the machine account password for the domain to contact.
+ * This is either our own domain for a workstation, or possibly
+ * any domain for a PDC with trusted domains.
+ */
+
+ if ( !secrets_fetch_trust_account_password (domain, 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;
+ }
+ else if ( lp_allow_trusted_domains() )
+ {
+ /* if we are not a domain member, then we must be a DC and
+ this must be a trusted domain */
+
+ 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;
+ }
+
+ /* Failure */
+ return False;
+}
+
+/**********************************************************************
+ Authenticate a user with a clear test password
+**********************************************************************/
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
{
@@ -70,6 +124,8 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
DATA_BLOB nt_resp;
DOM_CRED ret_creds;
int attempts = 0;
+ unsigned char local_lm_response[24];
+ unsigned char local_nt_response[24];
/* Ensure null termination */
state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';
@@ -95,38 +151,29 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
goto done;
}
- {
- unsigned char local_lm_response[24];
- unsigned char local_nt_response[24];
-
- generate_random_buffer(chal, 8, False);
- SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
+ /* do password magic */
+
+ generate_random_buffer(chal, 8, False);
+ SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
- SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);
+ SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);
- lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
- nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
- }
+ lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
+ nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
- /*
- * Get the machine account password for our primary domain
- */
-
- if (!secrets_fetch_trust_account_password(
- lp_workgroup(), trust_passwd, &last_change_time,
- &sec_channel_type)) {
- DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
- "password for domain %s\n", lp_workgroup()));
+ if ( !get_trust_pw(name_domain, trust_passwd, &last_change_time, &sec_channel_type) ) {
result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
goto done;
}
+ /* check authentication loop */
+
do {
ZERO_STRUCT(info3);
ZERO_STRUCT(ret_creds);
/* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd,
+ result = cm_get_netlogon_cli(name_domain, trust_passwd,
sec_channel_type, False, &cli);
if (!NT_STATUS_IS_OK(result)) {
@@ -151,7 +198,6 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
- uni_group_cache_store_netlogon(mem_ctx, &info3);
done:
/* give us a more useful (more correct?) error code */
@@ -174,8 +220,10 @@ done:
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
-
-/* Challenge Response Authentication Protocol */
+
+/**********************************************************************
+ Challenge Response Authentication Protocol
+**********************************************************************/
enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
{
@@ -188,7 +236,6 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
TALLOC_CTX *mem_ctx = NULL;
char *user = NULL;
const char *domain = NULL;
- const char *contact_domain;
const char *workstation;
DOM_CRED ret_creds;
int attempts = 0;
@@ -236,11 +283,10 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
DEBUG(3, ("[%5d]: pam auth crap domain: %s user: %s\n", state->pid,
domain, user));
-
- if (lp_allow_trusted_domains() && (state->request.data.auth_crap.flags & WINBIND_PAM_CONTACT_TRUSTDOM)) {
- contact_domain = domain;
- } else {
- contact_domain = lp_workgroup();
+
+ if ( !get_trust_pw(domain, trust_passwd, &last_change_time, &sec_channel_type) ) {
+ result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ goto done;
}
if (*state->request.data.auth_crap.workstation) {
@@ -265,28 +311,12 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
lm_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len);
nt_resp = data_blob_talloc(mem_ctx, state->request.data.auth_crap.nt_resp, state->request.data.auth_crap.nt_resp_len);
- /*
- * Get the machine account password for the domain to contact.
- * This is either our own domain for a workstation, or possibly
- * any domain for a PDC with trusted domains.
- */
-
- if (!secrets_fetch_trust_account_password (
- contact_domain, trust_passwd, &last_change_time,
- &sec_channel_type)) {
- DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
- "password for domain %s\n", contact_domain));
- result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- goto done;
- }
-
do {
ZERO_STRUCT(info3);
ZERO_STRUCT(ret_creds);
/* Don't shut this down - it belongs to the connection cache code */
- result = cm_get_netlogon_cli(contact_domain, trust_passwd,
- sec_channel_type, False, &cli);
+ result = cm_get_netlogon_cli(domain, trust_passwd, sec_channel_type, False, &cli);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n",
@@ -313,11 +343,13 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
if (NT_STATUS_IS_OK(result)) {
- uni_group_cache_store_netlogon(mem_ctx, &info3);
+ netsamlogon_cache_store( cli->mem_ctx, &info3 );
+ wcache_invalidate_samlogon(find_domain_from_name(domain), &info3);
+
if (state->request.data.auth_crap.flags & WINBIND_PAM_INFO3_NDR) {
result = append_info3_as_ndr(mem_ctx, state, &info3);
}
-
+
if (state->request.data.auth_crap.flags & WINBIND_PAM_NTKEY) {
memcpy(state->response.data.auth.nt_session_key, info3.user_sess_key, sizeof(state->response.data.auth.nt_session_key) /* 16 */);
}
@@ -382,9 +414,8 @@ enum winbindd_result winbindd_pam_chauthtok(struct winbindd_cli_state *state)
/* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain))) {
+ if ( NT_STATUS_IS_ERR(result = cm_get_sam_handle(domain, &hnd)) ) {
DEBUG(1, ("could not get SAM handle on DC for %s\n", domain));
- result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
goto done;
}
diff --git a/source/nsswitch/winbindd_passdb.c b/source/nsswitch/winbindd_passdb.c
index 503b97899c4..401662b6a79 100644
--- a/source/nsswitch/winbindd_passdb.c
+++ b/source/nsswitch/winbindd_passdb.c
@@ -41,7 +41,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
DEBUG(3,("pdb: query_user_list\n"));
- if (NT_STATUS_IS_ERR(result = pdb_init_sam(&sam_account))) {
+ if (!NT_STATUS_IS_OK(result = pdb_init_sam(&sam_account))) {
return result;
}
@@ -84,7 +84,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
i++;
- if (NT_STATUS_IS_ERR(pdb_reset_sam(sam_account))) {
+ if (!NT_STATUS_IS_OK(pdb_reset_sam(sam_account))) {
result = NT_STATUS_UNSUCCESSFUL;
break;
}
@@ -177,7 +177,7 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
if (NT_STATUS_IS_OK(sid_to_uid(sid, &id))) { /* this is a user */
- if (NT_STATUS_IS_ERR(result = pdb_init_sam(&sam_account))) {
+ if (!NT_STATUS_IS_OK(result = pdb_init_sam(&sam_account))) {
return result;
}
@@ -217,7 +217,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
DEBUG(3,("pdb: query_user sid=%s\n", sid_string_static(user_sid)));
- if (NT_STATUS_IS_ERR(result = pdb_init_sam(&sam_account))) {
+ if (!NT_STATUS_IS_OK(result = pdb_init_sam(&sam_account))) {
return result;
}
diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c
index 9ec35617f11..81a79751f89 100644
--- a/source/nsswitch/winbindd_rpc.c
+++ b/source/nsswitch/winbindd_rpc.c
@@ -51,8 +51,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
do {
/* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain->name)))
- goto done;
+ if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) )
+ return result;
/* Get domain handle */
@@ -136,6 +136,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
NTSTATUS status;
uint32 start = 0;
int retry;
+ NTSTATUS result;
*num_entries = 0;
*info = NULL;
@@ -144,8 +145,8 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
retry = 0;
do {
- if (!(hnd = cm_get_sam_handle(domain->name)))
- return NT_STATUS_UNSUCCESSFUL;
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
+ return result;
status = cli_samr_open_domain(hnd->cli, mem_ctx,
&hnd->pol, des_access, &domain->sid, &dom_pol);
@@ -209,8 +210,8 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
retry = 0;
do {
- if ( !(hnd = cm_get_sam_handle(domain->name)) )
- return NT_STATUS_UNSUCCESSFUL;
+ if ( !NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)) )
+ return result;
result = cli_samr_open_domain( hnd->cli, mem_ctx, &hnd->pol,
des_access, &domain->sid, &dom_pol);
@@ -262,7 +263,7 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
enum SID_NAME_USE *type)
{
CLI_POLICY_HND *hnd;
- NTSTATUS status;
+ NTSTATUS result;
DOM_SID *sids = NULL;
uint32 *types = NULL;
const char *full_name;
@@ -277,24 +278,27 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
return NT_STATUS_NO_MEMORY;
}
+ DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", name, domain->name ));
+
retry = 0;
do {
- if (!(hnd = cm_get_lsa_handle(domain->name))) {
- return NT_STATUS_UNSUCCESSFUL;
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd))) {
+ return result;
}
- status = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1,
+ result = cli_lsa_lookup_names(hnd->cli, mem_ctx, &hnd->pol, 1,
&full_name, &sids, &types);
- } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
/* Return rid and type if lookup successful */
- if (NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_IS_OK(result)) {
sid_copy(sid, &sids[0]);
*type = types[0];
}
- return status;
+ return result;
}
/*
@@ -310,21 +314,23 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
char **domains;
char **names;
uint32 *types;
- NTSTATUS status;
+ NTSTATUS result;
int retry;
- DEBUG(3,("rpc: sid_to_name\n"));
+ DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid),
+ domain->name ));
retry = 0;
do {
- if (!(hnd = cm_get_lsa_handle(domain->name)))
- return NT_STATUS_UNSUCCESSFUL;
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
+ return result;
- status = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
+ result = cli_lsa_lookup_sids(hnd->cli, mem_ctx, &hnd->pol,
1, sid, &domains, &names, &types);
- } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
- if (NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_IS_OK(result)) {
*type = types[0];
*name = names[0];
DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
@@ -335,7 +341,8 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
return NT_STATUS_UNSUCCESSFUL;
}
}
- return status;
+
+ return result;
}
/* Lookup user information from a rid or username. */
@@ -352,24 +359,48 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
int retry;
fstring sid_string;
uint32 user_rid;
+ NET_USER_INFO_3 *user;
DEBUG(3,("rpc: query_user rid=%s\n", sid_to_string(sid_string, user_sid)));
if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) {
goto done;
}
-
+
+ /* try netsamlogon cache first */
+
+ if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
+ {
+
+ DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
+ sid_string_static(user_sid)));
+
+ user_info->user_sid = rid_to_talloced_sid( domain, mem_ctx, user_rid );
+ user_info->group_sid = rid_to_talloced_sid( domain, mem_ctx, user->group_rid );
+
+ user_info->acct_name = unistr2_tdup(mem_ctx, &user->uni_user_name);
+ user_info->full_name = unistr2_tdup(mem_ctx, &user->uni_full_name);
+
+ SAFE_FREE(user);
+
+ return NT_STATUS_OK;
+ }
+
+ /* no cache; hit the wire */
+
retry = 0;
do {
- /* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain->name)))
+ /* Get sam handle; if we fail here there is no hope */
+
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
goto done;
-
+
/* Get domain handle */
result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -417,7 +448,7 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID ***user_gids)
+ uint32 *num_groups, DOM_SID ***user_grpsids)
{
CLI_POLICY_HND *hnd;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -429,30 +460,47 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
unsigned int retry;
fstring sid_string;
uint32 user_rid;
+ NET_USER_INFO_3 *user;
DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_to_string(sid_string, user_sid)));
*num_groups = 0;
+ *user_grpsids = NULL;
- /* First try cached universal groups from logon */
- *user_gids = uni_group_cache_fetch(&domain->sid, user_sid, mem_ctx, num_groups);
- if((*num_groups > 0) && *user_gids) {
+ /* so lets see if we have a cached user_info_3 */
+
+ if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
+ {
+ DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
+ sid_string_static(user_sid)));
+
+ *num_groups = user->num_groups;
+
+ (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
+ for (i=0;i<(*num_groups);i++) {
+ (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user->gids[i].g_rid);
+ }
+
+ SAFE_FREE(user);
+
return NT_STATUS_OK;
- } else {
- *user_gids = NULL;
- *num_groups = 0;
}
+ /* no cache; hit the wire */
+
retry = 0;
do {
- /* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain->name)))
+ /* Get sam handle; if we fail here there is no hope */
+
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
goto done;
/* Get domain handle */
+
result = cli_samr_open_domain(hnd->cli, mem_ctx, &hnd->pol,
des_access, &domain->sid, &dom_pol);
- } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) &&
+ hnd && hnd->cli && hnd->cli->fd == -1);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -480,14 +528,14 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
goto done;
- (*user_gids) = talloc(mem_ctx, sizeof(uint32) * (*num_groups));
- if (!(*user_gids)) {
+ (*user_grpsids) = talloc(mem_ctx, sizeof(DOM_SID*) * (*num_groups));
+ if (!(*user_grpsids)) {
result = NT_STATUS_NO_MEMORY;
goto done;
}
for (i=0;i<(*num_groups);i++) {
- (*user_gids)[i] = rid_to_talloced_sid(domain, mem_ctx, user_groups[i].g_rid);
+ (*user_grpsids)[i] = rid_to_talloced_sid(domain, mem_ctx, user_groups[i].g_rid);
}
done:
@@ -532,7 +580,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
retry = 0;
do {
/* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain->name)))
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
goto done;
/* Get domain handle */
@@ -601,9 +649,12 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
&tmp_num_names,
&tmp_names, &tmp_types);
- if (!NT_STATUS_IS_OK(result))
+ /* see if we have a real error (and yes the STATUS_SOME_UNMAPPED is
+ the one returned from 2k) */
+
+ if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED))
goto done;
-
+
/* Copy result into array. The talloc system will take
care of freeing the temporary arrays later on. */
@@ -618,7 +669,9 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
*num_names = total_names;
- done:
+ result = NT_STATUS_OK;
+
+done:
if (got_group_pol)
cli_samr_close(hnd->cli, mem_ctx, &group_pol);
@@ -628,6 +681,137 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
return result;
}
+#ifdef HAVE_LDAP
+
+#include <ldap.h>
+
+static SIG_ATOMIC_T gotalarm;
+
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+
+static void gotalarm_sig(void)
+{
+ gotalarm = 1;
+}
+
+static LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to)
+{
+ LDAP *ldp = NULL;
+
+ /* Setup timeout */
+ gotalarm = 0;
+ CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+ alarm(to);
+ /* End setup timeout. */
+
+ ldp = ldap_open(server, port);
+
+ /* Teardown timeout. */
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
+ alarm(0);
+
+ return ldp;
+}
+
+static int get_ldap_seq(const char *server, int port, uint32 *seq)
+{
+ int ret = -1;
+ struct timeval to;
+ char *attrs[] = {"highestCommittedUSN", NULL};
+ LDAPMessage *res = NULL;
+ char **values = NULL;
+ LDAP *ldp = NULL;
+
+ *seq = DOM_SEQUENCE_NONE;
+
+ /*
+ * 10 second timeout on open. This is needed as the search timeout
+ * doesn't seem to apply to doing an open as well. JRA.
+ */
+
+ if ((ldp = ldap_open_with_timeout(server, port, 10)) == NULL)
+ return -1;
+
+ /* Timeout if no response within 20 seconds. */
+ to.tv_sec = 10;
+ to.tv_usec = 0;
+
+ if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", &attrs[0], 0, &to, &res))
+ goto done;
+
+ if (ldap_count_entries(ldp, res) != 1)
+ goto done;
+
+ values = ldap_get_values(ldp, res, "highestCommittedUSN");
+ if (!values || !values[0])
+ goto done;
+
+ *seq = atoi(values[0]);
+ ret = 0;
+
+ done:
+
+ if (values)
+ ldap_value_free(values);
+ if (res)
+ ldap_msgfree(res);
+ if (ldp)
+ ldap_unbind(ldp);
+ return ret;
+}
+
+/**********************************************************************
+ Get the sequence number for a Windows AD native mode domain using
+ LDAP queries
+**********************************************************************/
+
+int get_ldap_sequence_number( const char* domain, uint32 *seq)
+{
+ int ret = -1;
+ int i, port = LDAP_PORT;
+ struct ip_service *ip_list = NULL;
+ int count;
+
+ if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
+ DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
+ return False;
+ }
+
+ /* Finally return first DC that we can contact */
+
+ for (i = 0; i < count; i++) {
+ fstring ipstr;
+
+ /* since the is an LDAP lookup, default to the LDAP_PORT is not set */
+ port = (ip_list[i].port!= PORT_NONE) ? ip_list[i].port : LDAP_PORT;
+
+ fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
+
+ if (is_zero_ip(ip_list[i].ip))
+ continue;
+
+ if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
+ goto done;
+
+ /* add to failed connection cache */
+ add_failed_connection_entry( domain, ipstr, NT_STATUS_UNSUCCESSFUL );
+ }
+
+done:
+ if ( ret == 0 ) {
+ DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s:%d)\n",
+ domain, inet_ntoa(ip_list[i].ip), port));
+ }
+
+ SAFE_FREE(ip_list);
+
+ return ret;
+}
+
+#endif /* HAVE_LDAP */
+
/* find the sequence number for a domain */
static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
{
@@ -636,7 +820,6 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
SAM_UNK_CTR ctr;
uint16 switch_value = 2;
NTSTATUS result;
- uint32 seqnum = DOM_SEQUENCE_NONE;
POLICY_HND dom_pol;
BOOL got_dom_pol = False;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
@@ -651,8 +834,24 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
retry = 0;
do {
- /* Get sam handle */
- if (!(hnd = cm_get_sam_handle(domain->name)))
+#ifdef HAVE_LDAP
+ if ( domain->native_mode )
+ {
+ DEBUG(8,("using get_ldap_seq() to retrieve the sequence number\n"));
+
+ if ( get_ldap_sequence_number( domain->name, seq ) == 0 ) {
+ result = NT_STATUS_OK;
+ DEBUG(10,("domain_sequence_number: LDAP for domain %s is %u\n",
+ domain->name, *seq));
+ goto done;
+ }
+
+ DEBUG(10,("domain_sequence_number: failed to get LDAP sequence number for domain %s\n",
+ domain->name ));
+ }
+#endif /* HAVE_LDAP */
+ /* Get sam handle */
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain->name, &hnd)))
goto done;
/* Get domain handle */
@@ -671,11 +870,11 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
switch_value, &ctr);
if (NT_STATUS_IS_OK(result)) {
- seqnum = ctr.info.inf2.seq_num;
- DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)seqnum ));
+ *seq = ctr.info.inf2.seq_num;
+ DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)*seq));
} else {
DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
- (unsigned)seqnum, domain->name ));
+ (unsigned)*seq, domain->name ));
}
done:
@@ -685,8 +884,6 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
talloc_destroy(mem_ctx);
- *seq = seqnum;
-
return result;
}
@@ -710,7 +907,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
retry = 0;
do {
- if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(lp_workgroup(), &hnd)))
goto done;
result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx,
@@ -725,7 +922,7 @@ done:
/* find the domain sid for a domain */
static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
{
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
TALLOC_CTX *mem_ctx;
CLI_POLICY_HND *hnd;
fstring level5_dom;
@@ -738,17 +935,17 @@ static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
retry = 0;
do {
- /* Get sam handle */
- if (!(hnd = cm_get_lsa_handle(domain->name)))
+ /* Get lsa handle */
+ if (!NT_STATUS_IS_OK(result = cm_get_lsa_handle(domain->name, &hnd)))
goto done;
- status = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
+ result = cli_lsa_query_info_policy(hnd->cli, mem_ctx,
&hnd->pol, 0x05, level5_dom, sid);
- } while (!NT_STATUS_IS_OK(status) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
+ } while (!NT_STATUS_IS_OK(result) && (retry++ < 1) && hnd && hnd->cli && hnd->cli->fd == -1);
done:
talloc_destroy(mem_ctx);
- return status;
+ return result;
}
/* find alternate names list for the domain - none for rpc */
diff --git a/source/nsswitch/winbindd_sid.c b/source/nsswitch/winbindd_sid.c
index f5dd904dc16..5d7741850c8 100644
--- a/source/nsswitch/winbindd_sid.c
+++ b/source/nsswitch/winbindd_sid.c
@@ -137,7 +137,7 @@ enum winbindd_result winbindd_sid_to_uid(struct winbindd_cli_state *state)
}
/* Find uid for this sid and return it */
- if (NT_STATUS_IS_ERR(sid_to_uid(&sid, &(state->response.data.uid)))) {
+ if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &(state->response.data.uid)))) {
DEBUG(1, ("Could not get uid for sid %s\n",
state->request.data.sid));
return WINBINDD_ERROR;
@@ -166,7 +166,7 @@ enum winbindd_result winbindd_sid_to_gid(struct winbindd_cli_state *state)
}
/* Find gid for this sid and return it */
- if (NT_STATUS_IS_ERR(sid_to_gid(&sid, &(state->response.data.gid)))) {
+ if (!NT_STATUS_IS_OK(sid_to_gid(&sid, &(state->response.data.gid)))) {
DEBUG(1, ("Could not get gid for sid %s\n",
state->request.data.sid));
return WINBINDD_ERROR;
@@ -192,7 +192,7 @@ enum winbindd_result winbindd_uid_to_sid(struct winbindd_cli_state *state)
state->request.data.uid));
/* Lookup rid for this uid */
- if (NT_STATUS_IS_ERR(uid_to_sid(&sid, state->request.data.uid))) {
+ if (!NT_STATUS_IS_OK(uid_to_sid(&sid, state->request.data.uid))) {
DEBUG(1, ("Could not convert uid %d to rid\n",
state->request.data.uid));
return WINBINDD_ERROR;
@@ -221,7 +221,7 @@ enum winbindd_result winbindd_gid_to_sid(struct winbindd_cli_state *state)
state->request.data.gid));
/* Lookup sid for this uid */
- if (NT_STATUS_IS_ERR(gid_to_sid(&sid, state->request.data.gid))) {
+ if (!NT_STATUS_IS_OK(gid_to_sid(&sid, state->request.data.gid))) {
DEBUG(1, ("Could not convert gid %d to sid\n",
state->request.data.gid));
return WINBINDD_ERROR;
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
index dc07bc42e74..9d9360a6fae 100644
--- a/source/nsswitch/winbindd_user.c
+++ b/source/nsswitch/winbindd_user.c
@@ -5,6 +5,7 @@
Copyright (C) Tim Potter 2000
Copyright (C) Jeremy Allison 2001.
+ Copyright (C) Gerald (Jerry) 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
@@ -26,13 +27,14 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
+extern userdom_struct current_user_info;
+
/* Fill a pwent structure with information we have obtained */
static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
DOM_SID *user_sid, DOM_SID *group_sid,
char *full_name, struct winbindd_pw *pw)
{
- extern userdom_struct current_user_info;
fstring output_username;
pstring homedir;
fstring sid_string;
@@ -42,14 +44,14 @@ static BOOL winbindd_fill_pwent(char *dom_name, char *user_name,
/* Resolve the uid number */
- if (NT_STATUS_IS_ERR(sid_to_uid(user_sid, &(pw->pw_uid)))) {
+ if (!NT_STATUS_IS_OK(sid_to_uid(user_sid, &(pw->pw_uid)))) {
DEBUG(1, ("error getting user id for sid %s\n", sid_to_string(sid_string, user_sid)));
return False;
}
/* Resolve the gid number */
- if (NT_STATUS_IS_ERR(sid_to_gid(group_sid, &(pw->pw_gid)))) {
+ if (!NT_STATUS_IS_OK(sid_to_gid(group_sid, &(pw->pw_gid)))) {
DEBUG(1, ("error getting group id for sid %s\n", sid_to_string(sid_string, group_sid)));
return False;
}
@@ -114,6 +116,15 @@ enum winbindd_result winbindd_getpwnam(struct winbindd_cli_state *state)
name_user))
return WINBINDD_ERROR;
+ /* don't handle our own domain if we are a DC. This code handles cases where
+ the account doesn't exist anywhere and gets passed on down the NSS layer */
+
+ if ( IS_DC_FOR_DOMAIN(domain->name) ) {
+ DEBUG(7,("winbindd_getpwnam: rejecting getpwnam() for %s\\%s since I am on the PDC for this domain\n",
+ name_domain, name_user));
+ return WINBINDD_ERROR;
+ }
+
if ((domain = find_domain_from_name(name_domain)) == NULL) {
DEBUG(5, ("no such domain: %s\n", name_domain));
return WINBINDD_ERROR;
@@ -191,7 +202,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
/* Get rid from uid */
- if (NT_STATUS_IS_ERR(uid_to_sid(&user_sid, state->request.data.uid))) {
+ if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, state->request.data.uid))) {
DEBUG(1, ("could not convert uid %d to SID\n",
state->request.data.uid));
return WINBINDD_ERROR;
@@ -235,7 +246,7 @@ enum winbindd_result winbindd_getpwuid(struct winbindd_cli_state *state)
/* Check group has a gid number */
- if (NT_STATUS_IS_ERR(sid_to_gid(user_info.group_sid, &gid))) {
+ if (!NT_STATUS_IS_OK(sid_to_gid(user_info.group_sid, &gid))) {
DEBUG(1, ("error getting group id for user %s\n", user_name));
talloc_destroy(mem_ctx);
return WINBINDD_ERROR;
@@ -284,6 +295,12 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
for(domain = domain_list(); domain != NULL; domain = domain->next) {
struct getent_state *domain_state;
+
+ /* don't add our domaina if we are a PDC */
+
+ if ( IS_DC_FOR_DOMAIN( domain->name ) )
+ continue;
+
/* Create a state record for this domain */
if ((domain_state = (struct getent_state *)
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 84f5d195686..0bc4beeac6c 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -118,6 +118,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
}
domain->methods = methods;
+ domain->backend = NULL;
domain->sequence_number = DOM_SEQUENCE_NONE;
domain->last_seq_check = 0;
if (sid) {
@@ -379,12 +380,14 @@ BOOL winbindd_param_init(void)
/* Parse winbind uid and winbind_gid parameters */
if (!lp_idmap_uid(&server_state.uid_low, &server_state.uid_high)) {
- DEBUG(0, ("winbind uid range missing or invalid\n"));
+ DEBUG(0, ("winbindd: idmap uid range missing or invalid\n"));
+ DEBUG(0, ("winbindd: cannot continue, exiting.\n"));
return False;
}
if (!lp_idmap_gid(&server_state.gid_low, &server_state.gid_high)) {
- DEBUG(0, ("winbind gid range missing or invalid\n"));
+ DEBUG(0, ("winbindd: idmap gid range missing or invalid\n"));
+ DEBUG(0, ("winbindd: cannot continue, exiting.\n"));
return False;
}
@@ -573,3 +576,209 @@ DOM_SID *rid_to_talloced_sid(struct winbindd_domain *domain,
return sid;
}
+/*****************************************************************************
+ For idmap conversion: convert one record to new format
+ Ancient versions (eg 2.2.3a) of winbindd_idmap.tdb mapped DOMAINNAME/rid
+ instead of the SID.
+*****************************************************************************/
+static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state)
+{
+ struct winbindd_domain *domain;
+ char *p;
+ DOM_SID sid;
+ uint32 rid;
+ fstring keystr;
+ fstring dom_name;
+ TDB_DATA key2;
+ BOOL *failed = (BOOL *)state;
+
+ DEBUG(10,("Converting %s\n", key.dptr));
+
+ p = strchr(key.dptr, '/');
+ if (!p)
+ return 0;
+
+ *p = 0;
+ fstrcpy(dom_name, key.dptr);
+ *p++ = '/';
+
+ domain = find_domain_from_name(dom_name);
+ if (domain == NULL) {
+ /* We must delete the old record. */
+ DEBUG(0,("Unable to find domain %s\n", dom_name ));
+ DEBUG(0,("deleting record %s\n", key.dptr ));
+
+ if (tdb_delete(tdb, key) != 0) {
+ DEBUG(0, ("Unable to delete record %s\n", key.dptr));
+ *failed = True;
+ return -1;
+ }
+
+ return 0;
+ }
+
+ rid = atoi(p);
+
+ sid_copy(&sid, &domain->sid);
+ sid_append_rid(&sid, rid);
+
+ sid_to_string(keystr, &sid);
+ key2.dptr = keystr;
+ key2.dsize = strlen(keystr) + 1;
+
+ if (tdb_store(tdb, key2, data, TDB_INSERT) != 0) {
+ DEBUG(0,("Unable to add record %s\n", key2.dptr ));
+ *failed = True;
+ return -1;
+ }
+
+ if (tdb_store(tdb, data, key2, TDB_REPLACE) != 0) {
+ DEBUG(0,("Unable to update record %s\n", data.dptr ));
+ *failed = True;
+ return -1;
+ }
+
+ if (tdb_delete(tdb, key) != 0) {
+ DEBUG(0,("Unable to delete record %s\n", key.dptr ));
+ *failed = True;
+ return -1;
+ }
+
+ return 0;
+}
+
+/* These definitions are from sam/idmap_tdb.c. Replicated here just
+ out of laziness.... :-( */
+
+/* High water mark keys */
+#define HWM_GROUP "GROUP HWM"
+#define HWM_USER "USER HWM"
+
+/* idmap version determines auto-conversion */
+#define IDMAP_VERSION 2
+
+
+/*****************************************************************************
+ Convert the idmap database from an older version.
+*****************************************************************************/
+
+static BOOL idmap_convert(const char *idmap_name)
+{
+ int32 vers;
+ BOOL bigendianheader;
+ BOOL failed = False;
+ TDB_CONTEXT *idmap_tdb;
+
+ if (!(idmap_tdb = tdb_open_log(idmap_name, 0,
+ TDB_DEFAULT, O_RDWR,
+ 0600))) {
+ DEBUG(0, ("idmap_convert: Unable to open idmap database\n"));
+ return False;
+ }
+
+ bigendianheader = (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False;
+
+ vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");
+
+ if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) {
+ /* Arrggghh ! Bytereversed or old big-endian - make order independent ! */
+ /*
+ * high and low records were created on a
+ * big endian machine and will need byte-reversing.
+ */
+
+ int32 wm;
+
+ wm = tdb_fetch_int32(idmap_tdb, HWM_USER);
+
+ if (wm != -1) {
+ wm = IREV(wm);
+ } else {
+ wm = server_state.uid_low;
+ }
+
+ if (tdb_store_int32(idmap_tdb, HWM_USER, wm) == -1) {
+ DEBUG(0, ("idmap_convert: Unable to byteswap user hwm in idmap database\n"));
+ tdb_close(idmap_tdb);
+ return False;
+ }
+
+ wm = tdb_fetch_int32(idmap_tdb, HWM_GROUP);
+ if (wm != -1) {
+ wm = IREV(wm);
+ } else {
+ wm = server_state.gid_low;
+ }
+
+ if (tdb_store_int32(idmap_tdb, HWM_GROUP, wm) == -1) {
+ DEBUG(0, ("idmap_convert: Unable to byteswap group hwm in idmap database\n"));
+ tdb_close(idmap_tdb);
+ return False;
+ }
+ }
+
+ /* the old format stored as DOMAIN/rid - now we store the SID direct */
+ tdb_traverse(idmap_tdb, convert_fn, &failed);
+
+ if (failed) {
+ DEBUG(0, ("Problem during conversion\n"));
+ tdb_close(idmap_tdb);
+ return False;
+ }
+
+ if (tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION) == -1) {
+ DEBUG(0, ("idmap_convert: Unable to dtore idmap version in databse\n"));
+ tdb_close(idmap_tdb);
+ return False;
+ }
+
+ tdb_close(idmap_tdb);
+ return True;
+}
+
+/*****************************************************************************
+ Convert the idmap database from an older version if necessary
+*****************************************************************************/
+
+BOOL winbindd_upgrade_idmap(void)
+{
+ pstring idmap_name;
+ pstring backup_name;
+ SMB_STRUCT_STAT stbuf;
+ TDB_CONTEXT *idmap_tdb;
+
+ pstrcpy(idmap_name, lock_path("winbindd_idmap.tdb"));
+
+ if (!file_exist(idmap_name, &stbuf)) {
+ /* nothing to convert return */
+ return True;
+ }
+
+ if (!(idmap_tdb = tdb_open_log(idmap_name, 0,
+ TDB_DEFAULT, O_RDWR,
+ 0600))) {
+ DEBUG(0, ("idmap_convert: Unable to open idmap database\n"));
+ return False;
+ }
+
+ if (tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION") == IDMAP_VERSION) {
+ /* nothing to convert return */
+ tdb_close(idmap_tdb);
+ return True;
+ }
+
+ /* backup_tdb expects the tdb not to be open */
+ tdb_close(idmap_tdb);
+
+ DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n"));
+
+ pstrcpy(backup_name, idmap_name);
+ pstrcat(backup_name, ".bak");
+
+ if (backup_tdb(idmap_name, backup_name) != 0) {
+ DEBUG(0, ("Could not backup idmap database\n"));
+ return False;
+ }
+
+ return idmap_convert(idmap_name);
+}
diff --git a/source/nsswitch/winbindd_wins.c b/source/nsswitch/winbindd_wins.c
index a1d38ed69ad..66903e250da 100644
--- a/source/nsswitch/winbindd_wins.c
+++ b/source/nsswitch/winbindd_wins.c
@@ -86,14 +86,26 @@ static struct node_status *lookup_byaddr_backend(char *addr, int *count)
static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
int fd;
- struct in_addr *ret = NULL;
- int j, flags = 0;
+ struct ip_service *ret = NULL;
+ struct in_addr *return_ip;
+ int j, i, flags = 0;
*count = 0;
/* always try with wins first */
if (resolve_wins(name,0x20,&ret,count)) {
- return ret;
+ if ( count == 0 )
+ return NULL;
+ if ( (return_ip = (struct in_addr *)malloc((*count)*sizeof(struct in_addr))) == NULL ) {
+ free( ret );
+ return NULL;
+ }
+
+ /* copy the IP addresses */
+ for ( i=0; i<(*count); i++ )
+ return_ip[i] = ret[i].ip;
+
+ return return_ip;
}
fd = wins_lookup_open_socket_in();
@@ -106,12 +118,12 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
j >= 0;
j--) {
struct in_addr *bcast = iface_n_bcast(j);
- ret = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
- if (ret) break;
+ return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
+ if (return_ip) break;
}
close(fd);
- return ret;
+ return return_ip;
}
/* Get hostname from IP */
diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c
index 9bb2d6755cb..62493ef0a9e 100644
--- a/source/nsswitch/wins.c
+++ b/source/nsswitch/wins.c
@@ -112,8 +112,8 @@ static struct node_status *lookup_byaddr_backend(char *addr, int *count)
static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
int fd = -1;
- struct in_addr *ret = NULL;
- struct in_addr p;
+ struct ip_service *address = NULL;
+ struct in_addr *ret;
int j, flags = 0;
if (!initialised) {
@@ -123,7 +123,13 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
*count = 0;
/* always try with wins first */
- if (resolve_wins(name,0x20,&ret,count)) {
+ if (resolve_wins(name,0x20,&address,count)) {
+ if ( (ret = (struct in_addr *)malloc(sizeof(struct in_addr))) == NULL ) {
+ free( address );
+ return NULL;
+ }
+ *ret = address[0].ip;
+ free( address );
return ret;
}
@@ -139,7 +145,6 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
if (ret) break;
}
-out:
close(fd);
return ret;
}
diff --git a/source/pam_smbpass/pam_smb_passwd.c b/source/pam_smbpass/pam_smb_passwd.c
index 78b89c60b76..bef587a916c 100644
--- a/source/pam_smbpass/pam_smb_passwd.c
+++ b/source/pam_smbpass/pam_smb_passwd.c
@@ -298,7 +298,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
uid_t uid;
/* password updated */
- if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sampass), &uid))) {
+ if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sampass), &uid))) {
_log_err( LOG_NOTICE, "Unable to get uid for user %s",
pdb_get_username(sampass));
_log_err( LOG_NOTICE, "password for (%s) changed by (%s/%d)",
diff --git a/source/pam_smbpass/support.c b/source/pam_smbpass/support.c
index 62cc866fae0..8a0432c8550 100644
--- a/source/pam_smbpass/support.c
+++ b/source/pam_smbpass/support.c
@@ -399,7 +399,7 @@ int _smb_verify_password( pam_handle_t * pamh, SAM_ACCOUNT *sampass,
service ? service : "**unknown**", name);
new->count = 1;
}
- if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sampass), &(new->id)))) {
+ if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sampass), &(new->id)))) {
_log_err(LOG_NOTICE,
"failed auth request by %s for service %s as %s",
uidtoname(getuid()),
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 30fc6c5d121..d6e24dfc3c6 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -126,7 +126,6 @@ typedef struct
char *szPasswordServer;
char *szSocketOptions;
char *szRealm;
- char *szADSserver;
char *szUsernameMap;
char *szLogonScript;
char *szLogonPath;
@@ -276,6 +275,7 @@ typedef struct
BOOL bUseSpnego;
BOOL bClientLanManAuth;
BOOL bClientNTLMv2Auth;
+ BOOL bClientPlaintextAuth;
BOOL bClientUseSpnego;
BOOL bDebugHiresTimestamp;
BOOL bDebugPid;
@@ -412,6 +412,7 @@ typedef struct
BOOL bNTAclSupport;
BOOL bUseSendfile;
BOOL bProfileAcls;
+ BOOL bMap_acl_inherit;
param_opt_struct *param_opt;
char dummy[3]; /* for alignment */
@@ -531,6 +532,7 @@ static service sDefault = {
True, /* bNTAclSupport */
False, /* bUseSendfile */
False, /* bProfileAcls */
+ False, /* bMap_acl_inherit */
NULL, /* Parametric options */
@@ -567,6 +569,7 @@ static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr);
static void set_server_role(void);
static void set_default_server_announce_type(void);
+static void set_allowed_client_auth(void);
static const struct enum_list enum_protocol[] = {
{PROTOCOL_NT1, "NT1"},
@@ -732,7 +735,6 @@ static struct parm_struct parm_table[] = {
{"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},
- {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, 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},
@@ -778,6 +780,7 @@ static struct parm_struct parm_table[] = {
{"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},
@@ -859,6 +862,7 @@ static struct parm_struct parm_table[] = {
{"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},
@@ -1118,8 +1122,8 @@ static struct parm_struct parm_table[] = {
{"idmap only", P_BOOL, P_GLOBAL, &Globals.bIdmapOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"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},
- {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_DEPRECATED },
+ {"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 | FLAG_DEPRECATED },
{"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},
@@ -1277,8 +1281,13 @@ static void init_globals(void)
/* using UTF8 by default allows us to support all chars */
string_set(&Globals.unix_charset, "UTF8");
- /* using UTF8 by default allows us to support all chars */
+#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
+ /* If the system supports nl_langinfo(), try to grab the value
+ from the user's locale */
+ string_set(&Globals.display_charset, "LOCALE");
+#else
string_set(&Globals.display_charset, "ASCII");
+#endif
/* Use codepage 850 as a default for the dos character set */
string_set(&Globals.dos_charset, "CP850");
@@ -1386,6 +1395,7 @@ static void init_globals(void)
Globals.bStatCache = True; /* use stat cache by default */
Globals.restrict_anonymous = 0;
Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
+ 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) */
@@ -1409,9 +1419,9 @@ static void init_globals(void)
#ifdef WITH_LDAP_SAMCONFIG
string_set(&Globals.szLdapServer, "localhost");
Globals.ldap_port = 636;
- Globals.szPassdbBackend = str_list_make("ldapsam_compat guest", NULL);
+ Globals.szPassdbBackend = str_list_make("ldapsam_compat", NULL);
#else
- Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
+ Globals.szPassdbBackend = str_list_make("smbpasswd", NULL);
#endif /* WITH_LDAP_SAMCONFIG */
string_set(&Globals.szLdapSuffix, "");
@@ -1590,7 +1600,6 @@ FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
-FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
@@ -1695,6 +1704,7 @@ FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
+FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
@@ -1826,6 +1836,7 @@ 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_profile_acls, bProfileAcls)
+FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
@@ -3821,6 +3832,19 @@ static void set_server_role(void)
}
}
+/***********************************************************
+ If we should send plaintext/LANMAN passwords in the clinet
+************************************************************/
+static void set_allowed_client_auth(void)
+{
+ if (Globals.bClientNTLMv2Auth) {
+ Globals.bClientLanManAuth = False;
+ }
+ if (!Globals.bClientLanManAuth) {
+ Globals.bClientPlaintextAuth = False;
+ }
+}
+
/***************************************************************************
Load the services array from the services file. Return True on success,
False on failure.
@@ -3888,6 +3912,7 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
set_server_role();
set_default_server_announce_type();
+ set_allowed_client_auth();
bLoaded = True;
diff --git a/source/passdb/machine_sid.c b/source/passdb/machine_sid.c
index a578ecc7113..4e7476781c8 100644
--- a/source/passdb/machine_sid.c
+++ b/source/passdb/machine_sid.c
@@ -191,8 +191,9 @@ DOM_SID *get_global_sam_sid(void)
/* memory for global_sam_sid is allocated in
pdb_generate_sam_sid() as needed */
- if (!pdb_generate_sam_sid())
- global_sam_sid=NULL;
+ if (!pdb_generate_sam_sid()) {
+ smb_panic("Could not generate a machine SID\n");
+ }
return global_sam_sid;
}
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index f34513b2257..ece4a1e057a 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -27,6 +27,30 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB
+/******************************************************************
+ get the default domain/netbios name to be used when
+ testing authentication. For example, if you connect
+ to a Windows member server using a bogus domain name, the
+ Windows box will map the BOGUS\user to DOMAIN\user. A
+ standalone box will map to WKS\user.
+******************************************************************/
+
+const char *get_default_sam_name(void)
+{
+ /* standalone servers can only use the local netbios name */
+ if ( lp_server_role() == ROLE_STANDALONE )
+ return global_myname();
+
+ /* Windows domain members default to the DOMAIN
+ name when not specified */
+ return lp_workgroup();
+}
+
+/******************************************************************
+ get the default domain/netbios name to be used when dealing
+ with our passdb list of accounts
+******************************************************************/
+
const char *get_global_sam_name(void)
{
if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
@@ -190,7 +214,7 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
*/
ret = pdb_set_sam_sids(sam_account, pwd);
- if (NT_STATUS_IS_ERR(ret)) return ret;
+ if (!NT_STATUS_IS_OK(ret)) return ret;
/* check if this is a user account or a machine account */
if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
@@ -413,7 +437,7 @@ NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd)
}
/* call the mapping code here */
- if(pdb_getgrgid(&map, pwd->pw_gid, MAPPING_WITHOUT_PRIV)) {
+ if(pdb_getgrgid(&map, pwd->pw_gid)) {
if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){
DEBUG(0,("Can't set Group SID!\n"));
return NT_STATUS_INVALID_PARAMETER;
@@ -717,7 +741,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
pdb_free_sam(&sam_account);
- if (pdb_getgrsid(&map, *sid, MAPPING_WITHOUT_PRIV)) {
+ if (pdb_getgrsid(&map, *sid)) {
if (map.gid!=(gid_t)-1) {
DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
} else {
@@ -827,7 +851,7 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
*/
/* check if it's a mapped group */
- if (pdb_getgrnam(&map, user, MAPPING_WITHOUT_PRIV)) {
+ if (pdb_getgrnam(&map, user)) {
/* yes it's a mapped group */
sid_copy(&local_sid, &map.sid);
*psid_name_use = map.sid_name_use;
@@ -849,7 +873,7 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
* JFM, 30/11/2001
*/
- if (pdb_getgrgid(&map, grp->gr_gid, MAPPING_WITHOUT_PRIV)){
+ if (pdb_getgrgid(&map, grp->gr_gid)){
return False;
}
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 7640228ab98..5ebc14030f0 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -258,7 +258,7 @@ static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCO
}
static NTSTATUS context_getgrsid(struct pdb_context *context,
- GROUP_MAP *map, DOM_SID sid, BOOL with_priv)
+ GROUP_MAP *map, DOM_SID sid)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
@@ -269,7 +269,7 @@ static NTSTATUS context_getgrsid(struct pdb_context *context,
}
curmethods = context->pdb_methods;
while (curmethods){
- ret = curmethods->getgrsid(curmethods, map, sid, with_priv);
+ ret = curmethods->getgrsid(curmethods, map, sid);
if (NT_STATUS_IS_OK(ret)) {
map->methods = curmethods;
return ret;
@@ -281,7 +281,7 @@ static NTSTATUS context_getgrsid(struct pdb_context *context,
}
static NTSTATUS context_getgrgid(struct pdb_context *context,
- GROUP_MAP *map, gid_t gid, BOOL with_priv)
+ GROUP_MAP *map, gid_t gid)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
@@ -292,7 +292,7 @@ static NTSTATUS context_getgrgid(struct pdb_context *context,
}
curmethods = context->pdb_methods;
while (curmethods){
- ret = curmethods->getgrgid(curmethods, map, gid, with_priv);
+ ret = curmethods->getgrgid(curmethods, map, gid);
if (NT_STATUS_IS_OK(ret)) {
map->methods = curmethods;
return ret;
@@ -304,7 +304,7 @@ static NTSTATUS context_getgrgid(struct pdb_context *context,
}
static NTSTATUS context_getgrnam(struct pdb_context *context,
- GROUP_MAP *map, char *name, BOOL with_priv)
+ GROUP_MAP *map, const char *name)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
@@ -315,7 +315,7 @@ static NTSTATUS context_getgrnam(struct pdb_context *context,
}
curmethods = context->pdb_methods;
while (curmethods){
- ret = curmethods->getgrnam(curmethods, map, name, with_priv);
+ ret = curmethods->getgrnam(curmethods, map, name);
if (NT_STATUS_IS_OK(ret)) {
map->methods = curmethods;
return ret;
@@ -371,7 +371,7 @@ static NTSTATUS context_delete_group_mapping_entry(struct pdb_context *context,
static NTSTATUS context_enum_group_mapping(struct pdb_context *context,
enum SID_NAME_USE sid_name_use,
GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only, BOOL with_priv)
+ BOOL unix_only)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
@@ -382,8 +382,7 @@ static NTSTATUS context_enum_group_mapping(struct pdb_context *context,
return context->pdb_methods->enum_group_mapping(context->pdb_methods,
sid_name_use, rmap,
- num_entries, unix_only,
- with_priv);
+ num_entries, unix_only);
}
/******************************************************************
@@ -517,12 +516,21 @@ NTSTATUS make_pdb_context_list(struct pdb_context **context, const char **select
int i = 0;
struct pdb_methods *curmethods, *tmpmethods;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ BOOL have_guest = False;
if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) {
return nt_status;
}
+ if (!selected) {
+ DEBUG(0, ("ERROR: empty passdb backend list!\n"));
+ return nt_status;
+ }
+
while (selected[i]){
+ if (strcmp(selected[i], "guest") == 0) {
+ have_guest = True;
+ }
/* Try to initialise pdb */
DEBUG(5,("Trying to load: %s\n", selected[i]));
if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods, *context, selected[i]))) {
@@ -535,6 +543,27 @@ NTSTATUS make_pdb_context_list(struct pdb_context **context, const char **select
i++;
}
+ if (have_guest)
+ return NT_STATUS_OK;
+
+ if ( (lp_guestaccount() == NULL) ||
+ (*lp_guestaccount() == '\0') ) {
+ /* We explicitly don't want guest access. No idea what
+ else that breaks, but be it that way. */
+ return NT_STATUS_OK;
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods,
+ *context,
+ "guest"))) {
+ DEBUG(1, ("Loading guest module failed!\n"));
+ free_pdb_context(context);
+ return nt_status;
+ }
+
+ curmethods->parent = *context;
+ DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
+
return NT_STATUS_OK;
}
@@ -562,13 +591,13 @@ static struct pdb_context *pdb_get_static_context(BOOL reload)
if ((pdb_context) && (reload)) {
pdb_context->free_fn(&pdb_context);
- if (NT_STATUS_IS_ERR(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
+ if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
return NULL;
}
}
if (!pdb_context) {
- if (NT_STATUS_IS_ERR(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
+ if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
return NULL;
}
}
@@ -668,7 +697,7 @@ BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct));
}
-BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid, BOOL with_priv)
+BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -677,10 +706,10 @@ BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid, BOOL with_priv)
}
return NT_STATUS_IS_OK(pdb_context->
- pdb_getgrsid(pdb_context, map, sid, with_priv));
+ pdb_getgrsid(pdb_context, map, sid));
}
-BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid, BOOL with_priv)
+BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -689,10 +718,10 @@ BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid, BOOL with_priv)
}
return NT_STATUS_IS_OK(pdb_context->
- pdb_getgrgid(pdb_context, map, gid, with_priv));
+ pdb_getgrgid(pdb_context, map, gid));
}
-BOOL pdb_getgrnam(GROUP_MAP *map, char *name, BOOL with_priv)
+BOOL pdb_getgrnam(GROUP_MAP *map, char *name)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -701,7 +730,7 @@ BOOL pdb_getgrnam(GROUP_MAP *map, char *name, BOOL with_priv)
}
return NT_STATUS_IS_OK(pdb_context->
- pdb_getgrnam(pdb_context, map, name, with_priv));
+ pdb_getgrnam(pdb_context, map, name));
}
BOOL pdb_add_group_mapping_entry(GROUP_MAP *map)
@@ -741,7 +770,7 @@ BOOL pdb_delete_group_mapping_entry(DOM_SID sid)
}
BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
- int *num_entries, BOOL unix_only, BOOL with_priv)
+ int *num_entries, BOOL unix_only)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -751,8 +780,7 @@ BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
return NT_STATUS_IS_OK(pdb_context->
pdb_enum_group_mapping(pdb_context, sid_name_use,
- rmap, num_entries, unix_only,
- with_priv));
+ rmap, num_entries, unix_only));
}
/***************************************************************
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index e484818c5d1..ec164a7e7be 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -4,7 +4,7 @@
Copyright (C) Jean François Micouleau 1998
Copyright (C) Gerald Carter 2001-2003
Copyright (C) Shahms King 2001
- Copyright (C) Andrew Bartlett 2002
+ Copyright (C) Andrew Bartlett 2002-2003
Copyright (C) Stefan (metze) Metzmacher 2002
This program is free software; you can redistribute it and/or modify
@@ -51,9 +51,12 @@
#include <lber.h>
#include <ldap.h>
-#ifndef LDAP_OPT_SUCCESS
-#define LDAP_OPT_SUCCESS 0
-#endif
+/*
+ * Work around versions of the LDAP client libs that don't have the OIDs
+ * defined, or have them defined under the old name.
+ * This functionality is really a factor of the server, not the client
+ *
+ */
#if defined(LDAP_EXOP_X_MODIFY_PASSWD) && !defined(LDAP_EXOP_MODIFY_PASSWD)
#define LDAP_EXOP_MODIFY_PASSWD LDAP_EXOP_X_MODIFY_PASSWD
@@ -73,6 +76,7 @@
#define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U)
#endif
+
#ifndef SAM_ACCOUNT
#define SAM_ACCOUNT struct sam_passwd
#endif
@@ -80,15 +84,13 @@
#include "smbldap.h"
struct ldapsam_privates {
+ struct smbldap_state *smbldap_state;
+
/* Former statics */
- LDAP *ldap_struct;
LDAPMessage *result;
LDAPMessage *entry;
int index;
- time_t last_ping;
- /* retrive-once info */
- const char *uri;
const char *domain_name;
DOM_SID domain_sid;
@@ -103,17 +105,8 @@ struct ldapsam_privates {
uint32 low_allocated_group_rid;
uint32 high_allocated_group_rid;
- char *bind_dn;
- char *bind_secret;
-
- unsigned int num_failures;
};
-#define LDAPSAM_DONT_PING_TIME 10 /* ping only all 10 seconds */
-
-static struct ldapsam_privates *static_ldap_state;
-
-
/**********************************************************************
get the attribute name given a user schame version
**********************************************************************/
@@ -155,551 +148,6 @@ static char** get_userattr_list( int schema_ver )
return NULL;
}
-
-/*******************************************************************
- open a connection to the ldap server.
-******************************************************************/
-static int ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP ** ldap_struct)
-{
- int rc = LDAP_SUCCESS;
- int version;
- BOOL ldap_v3 = False;
-
-#ifdef HAVE_LDAP_INITIALIZE
- DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
-
- if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) {
- DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
- return rc;
- }
-
-#else
-
- /* Parse the string manually */
-
- {
- int port = 0;
- fstring protocol;
- fstring host;
- const char *p = ldap_state->uri;
- SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);
-
- /* skip leading "URL:" (if any) */
- if ( strncasecmp( p, "URL:", 4 ) == 0 ) {
- p += 4;
- }
-
- sscanf(p, "%10[^:]://%254s[^:]:%d", protocol, host, &port);
-
- if (port == 0) {
- if (strequal(protocol, "ldap")) {
- port = LDAP_PORT;
- } else if (strequal(protocol, "ldaps")) {
- port = LDAPS_PORT;
- } else {
- DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));
- }
- }
-
- if ((*ldap_struct = ldap_init(host, port)) == NULL) {
- DEBUG(0, ("ldap_init failed !\n"));
- return LDAP_OPERATIONS_ERROR;
- }
-
- if (strequal(protocol, "ldaps")) {
-#ifdef LDAP_OPT_X_TLS
- int tls = LDAP_OPT_X_TLS_HARD;
- if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)
- {
- DEBUG(0, ("Failed to setup a TLS session\n"));
- }
-
- DEBUG(3,("LDAPS option set...!\n"));
-#else
- DEBUG(0,("ldapsam_open_connection: Secure connection not supported by LDAP client libraries!\n"));
- return LDAP_OPERATIONS_ERROR;
-#endif
- }
- }
-#endif
-
- if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS)
- {
- if (version != LDAP_VERSION3)
- {
- version = LDAP_VERSION3;
- if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) {
- ldap_v3 = True;
- }
- } else {
- ldap_v3 = True;
- }
- }
-
- if (lp_ldap_ssl() == LDAP_SSL_START_TLS) {
-#ifdef LDAP_OPT_X_TLS
- if (ldap_v3) {
- if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS)
- {
- DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",
- ldap_err2string(rc)));
- return rc;
- }
- DEBUG (3, ("StartTLS issued: using a TLS connection\n"));
- } else {
-
- DEBUG(0, ("Need LDAPv3 for Start TLS\n"));
- return LDAP_OPERATIONS_ERROR;
- }
-#else
- DEBUG(0,("ldapsam_open_connection: StartTLS not supported by LDAP client libraries!\n"));
- return LDAP_OPERATIONS_ERROR;
-#endif
- }
-
- DEBUG(2, ("ldapsam_open_connection: connection opened\n"));
- return rc;
-}
-
-
-/*******************************************************************
- a rebind function for authenticated referrals
- This version takes a void* that we can shove useful stuff in :-)
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-#else
-static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
- int *methodp, int freeit, void *arg)
-{
- struct ldapsam_privates *ldap_state = arg;
-
- /** @TODO Should we be doing something to check what servers we rebind to?
- Could we get a referral to a machine that we don't want to give our
- username and password to? */
-
- if (freeit) {
- SAFE_FREE(*whop);
- memset(*credp, '\0', strlen(*credp));
- SAFE_FREE(*credp);
- } else {
- DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n",
- ldap_state->bind_dn));
-
- *whop = strdup(ldap_state->bind_dn);
- if (!*whop) {
- return LDAP_NO_MEMORY;
- }
- *credp = strdup(ldap_state->bind_secret);
- if (!*credp) {
- SAFE_FREE(*whop);
- return LDAP_NO_MEMORY;
- }
- *methodp = LDAP_AUTH_SIMPLE;
- }
- return 0;
-}
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- a rebind function for authenticated referrals
- This version takes a void* that we can shove useful stuff in :-)
- and actually does the connection.
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-static int rebindproc_connect_with_state (LDAP *ldap_struct,
- LDAP_CONST char *url,
- ber_tag_t request,
- ber_int_t msgid, void *arg)
-{
- struct ldapsam_privates *ldap_state = arg;
- int rc;
- DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n",
- ldap_state->bind_dn));
-
- /** @TODO Should we be doing something to check what servers we rebind to?
- Could we get a referral to a machine that we don't want to give our
- username and password to? */
-
- rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
-
- return rc;
-}
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- Add a rebind function for authenticated referrals
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-#else
-# if LDAP_SET_REBIND_PROC_ARGS == 2
-static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
- int *method, int freeit )
-{
- return rebindproc_with_state(ldap_struct, whop, credp,
- method, freeit, static_ldap_state);
-
-}
-# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- a rebind function for authenticated referrals
- this also does the connection, but no void*.
-******************************************************************/
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-# if LDAP_SET_REBIND_PROC_ARGS == 2
-static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
- ber_int_t msgid)
-{
- return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid,
- static_ldap_state);
-}
-# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
-/*******************************************************************
- connect to the ldap server under system privilege.
-******************************************************************/
-static int ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
-{
- int rc;
- char *ldap_dn;
- char *ldap_secret;
-
- /* The rebind proc needs this *HACK*. We are not multithreaded, so
- this will work, but it's not nice. */
- static_ldap_state = ldap_state;
-
- /* get the password */
- if (!fetch_ldap_pw(&ldap_dn, &ldap_secret))
- {
- DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
- return LDAP_INVALID_CREDENTIALS;
- }
-
- ldap_state->bind_dn = ldap_dn;
- ldap_state->bind_secret = ldap_secret;
-
- /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
- (OpenLDAP) doesnt' seem to support it */
-
- DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",
- ldap_state->uri, ldap_dn));
-
-#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
-# if LDAP_SET_REBIND_PROC_ARGS == 2
- ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);
-# endif
-# if LDAP_SET_REBIND_PROC_ARGS == 3
- ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);
-# endif
-#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-# if LDAP_SET_REBIND_PROC_ARGS == 2
- ldap_set_rebind_proc(ldap_struct, &rebindproc);
-# endif
-# if LDAP_SET_REBIND_PROC_ARGS == 3
- ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);
-# endif
-#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/
-
- rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(ldap_state->num_failures ? 2 : 0,
- ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
- ldap_dn ? ld_error : "(unknown)", ldap_err2string(rc),
- ld_error));
- SAFE_FREE(ld_error);
- ldap_state->num_failures++;
- return rc;
- }
-
- ldap_state->num_failures = 0;
-
- DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
- return rc;
-}
-
-/**********************************************************************
-Connect to LDAP server
-*********************************************************************/
-static int ldapsam_open(struct ldapsam_privates *ldap_state)
-{
- int rc;
- SMB_ASSERT(ldap_state);
-
-#ifndef NO_LDAP_SECURITY
- if (geteuid() != 0) {
- DEBUG(0, ("ldapsam_open: cannot access LDAP when not root..\n"));
- return LDAP_INSUFFICIENT_ACCESS;
- }
-#endif
-
- if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + LDAPSAM_DONT_PING_TIME) < time(NULL))) {
- struct sockaddr_un addr;
- socklen_t len = sizeof(addr);
- int sd;
- if (ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd) == 0 &&
- getpeername(sd, (struct sockaddr *) &addr, &len) < 0) {
- /* the other end has died. reopen. */
- ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
- ldap_state->ldap_struct = NULL;
- ldap_state->last_ping = (time_t)0;
- } else {
- ldap_state->last_ping = time(NULL);
- }
- }
-
- if (ldap_state->ldap_struct != NULL) {
- DEBUG(5,("ldapsam_open: already connected to the LDAP server\n"));
- return LDAP_SUCCESS;
- }
-
- if ((rc = ldapsam_open_connection(ldap_state, &ldap_state->ldap_struct))) {
- return rc;
- }
-
- if ((rc = ldapsam_connect_system(ldap_state, ldap_state->ldap_struct))) {
- ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
- ldap_state->ldap_struct = NULL;
- return rc;
- }
-
-
- ldap_state->last_ping = time(NULL);
- DEBUG(4,("The LDAP server is succesful connected\n"));
-
- return LDAP_SUCCESS;
-}
-
-/**********************************************************************
-Disconnect from LDAP server
-*********************************************************************/
-static NTSTATUS ldapsam_close(struct ldapsam_privates *ldap_state)
-{
- if (!ldap_state)
- return NT_STATUS_INVALID_PARAMETER;
-
- if (ldap_state->ldap_struct != NULL) {
- ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);
- ldap_state->ldap_struct = NULL;
- }
-
- DEBUG(5,("The connection to the LDAP server was closed\n"));
- /* maybe free the results here --metze */
-
- return NT_STATUS_OK;
-}
-
-static int ldapsam_retry_open(struct ldapsam_privates *ldap_state, int *attempts)
-{
- int rc;
-
- SMB_ASSERT(ldap_state && attempts);
-
- if (*attempts != 0) {
- unsigned int sleep_time;
- uint8 rand_byte;
-
- /* Sleep for a random timeout */
- rand_byte = (char)(sys_random());
-
- sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2;
- /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
- on average.
- */
- DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n",
- sleep_time));
- msleep(sleep_time);
- }
- (*attempts)++;
-
- if ((rc = ldapsam_open(ldap_state))) {
- DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
- return rc;
- }
-
- return LDAP_SUCCESS;
-}
-
-
-/*********************************************************************
- ********************************************************************/
-
-static int ldapsam_search(struct ldapsam_privates *ldap_state,
- const char *base, int scope, const char *filter,
- char *attrs[], int attrsonly,
- LDAPMessage **res)
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
- char *utf8_filter;
-
- SMB_ASSERT(ldap_state);
-
- if (push_utf8_allocate(&utf8_filter, filter) == (size_t)-1) {
- return LDAP_NO_MEMORY;
- }
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
-
- if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
- utf8_filter, attrs, attrsonly, res);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- ldapsam_close(ldap_state);
- }
-
- SAFE_FREE(utf8_filter);
- return rc;
-}
-
-static int ldapsam_modify(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[])
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
- char *utf8_dn;
-
- SMB_ASSERT(ldap_state);
-
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
- return LDAP_NO_MEMORY;
- }
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
-
- if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- ldapsam_close(ldap_state);
- }
-
- SAFE_FREE(utf8_dn);
- return rc;
-}
-
-static int ldapsam_add(struct ldapsam_privates *ldap_state, const char *dn, LDAPMod *attrs[])
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
- char *utf8_dn;
-
- SMB_ASSERT(ldap_state);
-
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
- return LDAP_NO_MEMORY;
- }
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
-
- if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- ldapsam_close(ldap_state);
- }
-
- SAFE_FREE(utf8_dn);
- return rc;
-}
-
-static int ldapsam_delete(struct ldapsam_privates *ldap_state, char *dn)
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
- char *utf8_dn;
-
- SMB_ASSERT(ldap_state);
-
- if (push_utf8_allocate(&utf8_dn, dn) == (size_t)-1) {
- return LDAP_NO_MEMORY;
- }
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
-
- if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- ldapsam_close(ldap_state);
- }
-
- SAFE_FREE(utf8_dn);
- return rc;
-}
-
-static int ldapsam_extended_operation(struct ldapsam_privates *ldap_state, LDAP_CONST char *reqoid, struct berval *reqdata, LDAPControl **serverctrls, LDAPControl **clientctrls, char **retoidp, struct berval **retdatap)
-{
- int rc = LDAP_SERVER_DOWN;
- int attempts = 0;
-
- if (!ldap_state)
- return (-1);
-
- while ((rc == LDAP_SERVER_DOWN) && (attempts < 8)) {
-
- if ((rc = ldapsam_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata, serverctrls, clientctrls, retoidp, retdatap);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- ldapsam_close(ldap_state);
- }
-
- return rc;
-}
-
-/*******************************************************************
- run the search by name.
-******************************************************************/
-static int ldapsam_search_suffix (struct ldapsam_privates *ldap_state, const char *filter,
- char **search_attr, LDAPMessage ** result)
-{
- int scope = LDAP_SCOPE_SUBTREE;
- int rc;
-
- DEBUG(2, ("ldapsam_search_suffix: searching for:[%s]\n", filter));
-
- rc = ldapsam_search(ldap_state, lp_ldap_suffix(), scope, filter, search_attr, 0, result);
-
- if (rc != LDAP_SUCCESS) {
- char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
- &ld_error);
- DEBUG(0,("ldapsam_search_suffix: Problem during the LDAP search: %s (%s)\n",
- ld_error?ld_error:"(unknown)", ldap_err2string (rc)));
- DEBUG(3,("ldapsam_search_suffix: Query was: %s, %s\n", lp_ldap_suffix(),
- filter));
- SAFE_FREE(ld_error);
- }
-
- return rc;
-}
-
/*******************************************************************
generate the LDAP search filter for the objectclass based on the
version of the schema we are using
@@ -718,7 +166,7 @@ static const char* get_objclass_filter( int schema_ver )
snprintf( objclass_filter, sizeof(objclass_filter)-1, "(objectclass=%s)", LDAP_OBJ_SAMBASAMACCOUNT );
break;
default:
- DEBUG(0,("ldapsam_search_suffix_by_name(): Invalid schema version specified!\n"));
+ DEBUG(0,("pdb_ldapsam: get_objclass_filter(): Invalid schema version specified!\n"));
break;
}
@@ -728,8 +176,9 @@ static const char* get_objclass_filter( int schema_ver )
/*******************************************************************
run the search by name.
******************************************************************/
-static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state, const char *user,
- LDAPMessage ** result, char **attr)
+static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state,
+ const char *user,
+ LDAPMessage ** result, char **attr)
{
pstring filter;
char *escape_user = escape_ldap_string_alloc(user);
@@ -754,15 +203,15 @@ static int ldapsam_search_suffix_by_name (struct ldapsam_privates *ldap_state, c
all_string_sub(filter, "%u", escape_user, sizeof(pstring));
SAFE_FREE(escape_user);
- return ldapsam_search_suffix(ldap_state, filter, attr, result);
+ return smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
}
/*******************************************************************
run the search by rid.
******************************************************************/
static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
- uint32 rid, LDAPMessage ** result,
- char **attr)
+ uint32 rid, LDAPMessage ** result,
+ char **attr)
{
pstring filter;
int rc;
@@ -772,7 +221,7 @@ static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
snprintf(filter, sizeof(filter)-1, "(&(rid=%i)%s)", rid,
get_objclass_filter(ldap_state->schema_ver));
- rc = ldapsam_search_suffix(ldap_state, filter, attr, result);
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
return rc;
}
@@ -781,8 +230,8 @@ static int ldapsam_search_suffix_by_rid (struct ldapsam_privates *ldap_state,
run the search by SID.
******************************************************************/
static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
- const DOM_SID *sid, LDAPMessage ** result,
- char **attr)
+ const DOM_SID *sid, LDAPMessage ** result,
+ char **attr)
{
pstring filter;
int rc;
@@ -795,7 +244,7 @@ static int ldapsam_search_suffix_by_sid (struct ldapsam_privates *ldap_state,
sid_to_string(sid_string, sid),
get_objclass_filter(ldap_state->schema_ver));
- rc = ldapsam_search_suffix(ldap_state, filter, attr, result);
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, attr, result);
return rc;
}
@@ -834,58 +283,6 @@ static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
return True;
}
-/**********************************************************************
- Set attribute to newval in LDAP, regardless of what value the
- attribute had in LDAP before.
-*********************************************************************/
-static void make_ldap_mod(LDAP *ldap_struct, LDAPMessage *existing,
- LDAPMod ***mods,
- const char *attribute, const char *newval)
-{
- char **values = NULL;
-
- if (existing != NULL) {
- values = ldap_get_values(ldap_struct, existing, attribute);
- }
-
- /* all of our string attributes are case insensitive */
-
- if ((values != NULL) && (values[0] != NULL) &&
- StrCaseCmp(values[0], newval) == 0)
- {
-
- /* Believe it or not, but LDAP will deny a delete and
- an add at the same time if the values are the
- same... */
-
- ldap_value_free(values);
- return;
- }
-
- /* Regardless of the real operation (add or modify)
- we add the new value here. We rely on deleting
- the old value, should it exist. */
-
- if ((newval != NULL) && (strlen(newval) > 0)) {
- ldap_set_mod(mods, LDAP_MOD_ADD, attribute, newval);
- }
-
- if (values == NULL) {
- /* There has been no value before, so don't delete it.
- Here's a possible race: We might end up with
- duplicate attributes */
- return;
- }
-
- /* By deleting exactly the value we found in the entry this
- should be race-free in the sense that the LDAP-Server will
- deny the complete operation if somebody changed the
- attribute behind our back. */
-
- ldap_set_mod(mods, LDAP_MOD_DELETE, attribute, values[0]);
- ldap_value_free(values);
-}
-
/*******************************************************************
Delete complete object or objectclass and attrs from
object found in search_result depending on lp_ldap_delete_dn
@@ -901,19 +298,19 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
char *name, *dn;
BerElement *ptr = NULL;
- rc = ldap_count_entries(ldap_state->ldap_struct, result);
+ rc = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
if (rc != 1) {
DEBUG(0, ("Entry must exist exactly once!\n"));
return NT_STATUS_UNSUCCESSFUL;
}
- entry = ldap_first_entry(ldap_state->ldap_struct, result);
- dn = ldap_get_dn(ldap_state->ldap_struct, entry);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+ dn = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
if (lp_ldap_delete_dn()) {
NTSTATUS ret = NT_STATUS_OK;
- rc = ldapsam_delete(ldap_state, dn);
+ rc = smbldap_delete(ldap_state->smbldap_state, dn);
if (rc != LDAP_SUCCESS) {
DEBUG(0, ("Could not delete object %s\n", dn));
@@ -925,9 +322,9 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
/* Ok, delete only the SAM attributes */
- for (name = ldap_first_attribute(ldap_state->ldap_struct, entry, &ptr);
+ for (name = ldap_first_attribute(ldap_state->smbldap_state->ldap_struct, entry, &ptr);
name != NULL;
- name = ldap_next_attribute(ldap_state->ldap_struct, entry, ptr))
+ name = ldap_next_attribute(ldap_state->smbldap_state->ldap_struct, entry, ptr))
{
char **attrib;
@@ -938,7 +335,7 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
{
if (StrCaseCmp(*attrib, name) == 0) {
DEBUG(10, ("deleting attribute %s\n", name));
- ldap_set_mod(&mods, LDAP_MOD_DELETE, name, NULL);
+ smbldap_set_mod(&mods, LDAP_MOD_DELETE, name, NULL);
}
}
@@ -949,14 +346,14 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
ber_free(ptr, 0);
}
- ldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
+ smbldap_set_mod(&mods, LDAP_MOD_DELETE, "objectClass", objectclass);
- rc = ldapsam_modify(ldap_state, dn, mods);
+ rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
ldap_mods_free(mods, True);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(0, ("could not delete attributes for %s, error: %s (%s)\n",
@@ -989,7 +386,8 @@ static int ldapsam_search_domain_info(struct ldapsam_privates *ldap_state,
attr_list = get_attr_list( dominfo_attr_list );
- rc = ldapsam_search_suffix(ldap_state, filter, attr_list , result);
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
+ attr_list , result);
free_attr_list( attr_list );
if (rc != LDAP_SUCCESS) {
@@ -1013,7 +411,7 @@ static uint32 entry_to_rid(struct ldapsam_privates *ldap_state, LDAPMessage *ent
DOM_SID dom_sid;
uint32 rid;
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
LDAP_ATTRIBUTE_SID, sid_string))
{
return 0;
@@ -1070,7 +468,8 @@ static uint32 search_next_allocated_rid(struct ldapsam_privates *ldap_state, int
DEBUG(2, ("search_top_allocated_rid: searching for:[%s]\n", filter));
- rc = ldapsam_search_suffix(ldap_state, filter, sid_attr, &result);
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
+ sid_attr, &result);
if (rc != LDAP_SUCCESS) {
DEBUG(3, ("LDAP search failed! cannot find base for NUA RIDs: %s\n", ldap_err2string(rc)));
@@ -1080,18 +479,18 @@ static uint32 search_next_allocated_rid(struct ldapsam_privates *ldap_state, int
return 0;
}
- count = ldap_count_entries(ldap_state->ldap_struct, result);
+ count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
DEBUG(2, ("search_top_allocated_rid: %d entries in the base!\n", count));
if (count == 0) {
DEBUG(3, ("LDAP search returned no records, assuming no allocated RIDs present!: %s\n", ldap_err2string(rc)));
DEBUGADD(3, ("Query was: %s, %s\n", lp_ldap_suffix(), filter));
} else {
- entry = ldap_first_entry(ldap_state->ldap_struct,result);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,result);
top_rid = entry_to_rid(ldap_state, entry, rid_type);
- while ((entry = ldap_next_entry(ldap_state->ldap_struct, entry))) {
+ while ((entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct, entry))) {
rid = entry_to_rid(ldap_state, entry, rid_type);
if (((rid & ~RID_TYPE_MASK) == rid_type) && (rid > top_rid)) {
@@ -1164,14 +563,15 @@ static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state)
ldap_state->domain_name, LDAP_OBJ_DOMINFO);
attr_list = get_attr_list( dominfo_attr_list );
- rc = ldapsam_search_suffix(ldap_state, filter, attr_list, &result);
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
+ attr_list, &result);
free_attr_list( attr_list );
if (rc != LDAP_SUCCESS) {
return NT_STATUS_UNSUCCESSFUL;
}
- num_result = ldap_count_entries(ldap_state->ldap_struct, result);
+ num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
if (num_result > 1) {
DEBUG (0, ("More than domain with that name exists: bailing out!\n"));
@@ -1189,27 +589,27 @@ static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state)
ldap_msgfree(result);
/* make the changes - the entry *must* not already have samba attributes */
- ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
ldap_state->domain_name);
sid_to_string(tmp, &ldap_state->domain_sid);
- ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), tmp);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID), tmp);
snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_user_rid);
- ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), tmp);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID), tmp);
snprintf(tmp, sizeof(tmp)-1, "%i", next_allocated_group_rid);
- ldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), tmp);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID), tmp);
- ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_DOMINFO);
switch(ldap_op)
{
case LDAP_MOD_ADD:
- rc = ldapsam_add(ldap_state, dn, mods);
+ rc = smbldap_add(ldap_state->smbldap_state, dn, mods);
break;
case LDAP_MOD_REPLACE:
- rc = ldapsam_modify(ldap_state, dn, mods);
+ rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
break;
default:
DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
@@ -1218,7 +618,7 @@ static NTSTATUS add_new_domain_info(struct ldapsam_privates *ldap_state)
if (rc!=LDAP_SUCCESS) {
char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(1,
("failed to %s domain dn= %s with: %s\n\t%s\n",
@@ -1252,11 +652,12 @@ static BOOL sid_in_use(struct ldapsam_privates *ldap_state,
slprintf(filter, sizeof(filter)-1, "(%s=%s)", LDAP_ATTRIBUTE_SID, sid_to_string(sid_string, sid));
- rc = ldapsam_search_suffix(ldap_state, filter, sid_attr, &result);
+ rc = smbldap_search_suffix(ldap_state->smbldap_state,
+ filter, sid_attr, &result);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
DEBUG(2, ("Failed to check if sid %s is alredy in use: %s\n",
sid_string, ld_error));
SAFE_FREE(ld_error);
@@ -1265,7 +666,7 @@ static BOOL sid_in_use(struct ldapsam_privates *ldap_state,
return True;
}
- if ((count = ldap_count_entries(ldap_state->ldap_struct, result)) > 0) {
+ if ((count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result)) > 0) {
DEBUG(3, ("Sid %s already in use - trying next RID\n",
sid_string));
ldap_msgfree(result);
@@ -1311,7 +712,7 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri
return ret;
}
- if (ldap_count_entries(ldap_state->ldap_struct, result) < 1) {
+ if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) < 1) {
DEBUG(3, ("Got no domain info entries for domain %s\n",
ldap_state->domain_name));
ldap_msgfree(result);
@@ -1323,20 +724,20 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri
}
}
- if ((count = ldap_count_entries(ldap_state->ldap_struct, result)) > 1) {
+ if ((count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result)) > 1) {
DEBUG(0, ("Got too many (%d) domain info entries for domain %s\n",
count, ldap_state->domain_name));
ldap_msgfree(result);
return ret;
}
- entry = ldap_first_entry(ldap_state->ldap_struct, result);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
if (!entry) {
ldap_msgfree(result);
return ret;
}
- if ((dn = ldap_get_dn(ldap_state->ldap_struct, entry)) == NULL) {
+ if ((dn = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry)) == NULL) {
DEBUG(0, ("Could not get domain info DN\n"));
ldap_msgfree(result);
return ret;
@@ -1347,7 +748,7 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri
switch (rid_type) {
case USER_RID_TYPE:
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
old_rid_string))
{
@@ -1357,7 +758,7 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri
}
break;
case GROUP_RID_TYPE:
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
old_rid_string))
{
@@ -1384,7 +785,7 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri
/* Try to make the modification atomically by enforcing the
old value in the delete mod. */
- make_ldap_mod(ldap_state->ldap_struct, entry, &mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods,
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_USERRID),
next_rid_string);
break;
@@ -1396,19 +797,19 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri
/* Try to make the modification atomically by enforcing the
old value in the delete mod. */
- make_ldap_mod(ldap_state->ldap_struct, entry, &mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, entry, &mods,
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_NEXT_GROUPRID),
next_rid_string);
break;
}
- if ((rc = ldap_modify_s(ldap_state->ldap_struct, dn, mods)) == LDAP_SUCCESS) {
+ if ((rc = ldap_modify_s(ldap_state->smbldap_state->ldap_struct, dn, mods)) == LDAP_SUCCESS) {
DOM_SID dom_sid;
DOM_SID sid;
pstring domain_sid_string;
int error = 0;
- if (!get_single_attribute(ldap_state->ldap_struct, result,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, result,
get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOM_SID),
domain_sid_string))
{
@@ -1444,7 +845,7 @@ static NTSTATUS ldapsam_next_rid(struct ldapsam_privates *ldap_state, uint32 *ri
return NT_STATUS_OK;
}
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
DEBUG(2, ("Failed to modify rid: %s\n", ld_error));
SAFE_FREE(ld_error);
@@ -1486,7 +887,7 @@ static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
char **ldap_values;
char **values;
- if ((ldap_values = ldap_get_values (ldap_state->ldap_struct, entry, "objectClass")) == NULL) {
+ if ((ldap_values = ldap_get_values (ldap_state->smbldap_state->ldap_struct, entry, "objectClass")) == NULL) {
DEBUG (1, ("get_unix_attributes: no objectClass! \n"));
return False;
}
@@ -1504,13 +905,13 @@ static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state,
}
ldap_value_free(ldap_values);
- if ( !get_single_attribute(ldap_state->ldap_struct, entry,
+ if ( !get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_UNIX_HOME), homedir) )
{
return False;
}
- if ( !get_single_attribute(ldap_state->ldap_struct, entry,
+ if ( !get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_GIDNUMBER), temp) )
{
return False;
@@ -1583,12 +984,12 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
return False;
}
- if (ldap_state->ldap_struct == NULL) {
- DEBUG(0, ("init_sam_from_ldap: ldap_state->ldap_struct is NULL!\n"));
+ if (ldap_state->smbldap_state->ldap_struct == NULL) {
+ DEBUG(0, ("init_sam_from_ldap: ldap_state->smbldap_state->ldap_struct is NULL!\n"));
return False;
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry, "uid", username)) {
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry, "uid", username)) {
DEBUG(1, ("No uid attribute found for this user!\n"));
return False;
}
@@ -1608,13 +1009,13 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
if ( ldap_state->schema_ver == SCHEMAVER_SAMBASAMACCOUNT )
{
- if (get_single_attribute(ldap_state->ldap_struct, entry,
+ if (get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID), temp))
{
pdb_set_user_sid_from_string(sampass, temp, PDB_SET);
}
- if (get_single_attribute(ldap_state->ldap_struct, entry,
+ if (get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_SID), temp))
{
pdb_set_group_sid_from_string(sampass, temp, PDB_SET);
@@ -1628,14 +1029,14 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
}
else
{
- if (get_single_attribute(ldap_state->ldap_struct, entry,
+ if (get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID), temp))
{
user_rid = (uint32)atol(temp);
pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PRIMARY_GROUP_RID), temp))
{
pdb_set_group_sid_from_rid(sampass, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT);
@@ -1673,7 +1074,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
{
GROUP_MAP map;
/* call the mapping code here */
- if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) {
+ if(pdb_getgrgid(&map, gid)) {
pdb_set_group_sid(sampass, &map.sid, PDB_SET);
}
else {
@@ -1682,7 +1083,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
}
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET), temp))
{
/* leave as default */
@@ -1691,7 +1092,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp))
{
/* leave as default */
@@ -1700,7 +1101,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_logon_time(sampass, logon_time, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp))
{
/* leave as default */
@@ -1709,7 +1110,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp))
{
/* leave as default */
@@ -1718,7 +1119,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp))
{
/* leave as default */
@@ -1727,7 +1128,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp))
{
/* leave as default */
@@ -1742,10 +1143,10 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
* that fits your needs; using cn then displayName rather than 'userFullName'
*/
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME), fullname))
{
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_CN), fullname))
{
/* leave as default */
@@ -1756,7 +1157,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_fullname(sampass, fullname, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE), dir_drive))
{
pdb_set_dir_drive(sampass, talloc_sub_specified(sampass->mem_ctx,
@@ -1768,7 +1169,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir))
{
pdb_set_homedir(sampass, talloc_sub_specified(sampass->mem_ctx,
@@ -1780,7 +1181,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_homedir(sampass, homedir, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script))
{
pdb_set_logon_script(sampass, talloc_sub_specified(sampass->mem_ctx,
@@ -1792,7 +1193,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_logon_script(sampass, logon_script, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path))
{
pdb_set_profile_path(sampass, talloc_sub_specified(sampass->mem_ctx,
@@ -1804,7 +1205,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_profile_path(sampass, profile_path, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC), acct_desc))
{
/* leave as default */
@@ -1812,7 +1213,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS), workstations))
{
/* leave as default */;
@@ -1826,7 +1227,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
hours_len = 21;
memset(hours, 0xff, hours_len);
- if (!get_single_attribute (ldap_state->ldap_struct, entry,
+ if (!get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW), temp))
{
/* leave as default */
@@ -1838,7 +1239,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
ZERO_STRUCT(smblmpwd);
}
- if (!get_single_attribute (ldap_state->ldap_struct, entry,
+ if (!get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW), temp))
{
/* leave as default */
@@ -1850,7 +1251,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
ZERO_STRUCT(smbntpwd);
}
- if (!get_single_attribute (ldap_state->ldap_struct, entry,
+ if (!get_single_attribute (ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp))
{
acct_ctrl |= ACB_NORMAL;
@@ -1902,7 +1303,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
* do this on a per-mod basis
*/
if (need_update(sampass, PDB_USERNAME))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
"uid", pdb_get_username(sampass));
DEBUG(2, ("Setting entry for user: %s\n", pdb_get_username(sampass)));
@@ -1952,13 +1353,13 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
return False;
}
slprintf(temp, sizeof(temp) - 1, "%i", rid);
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_RID),
temp);
break;
case SCHEMAVER_SAMBASAMACCOUNT:
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_SID),
sid_to_string(sid_string, user_sid));
break;
@@ -1989,13 +1390,13 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
}
slprintf(temp, sizeof(temp) - 1, "%i", rid);
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver,
LDAP_ATTR_PRIMARY_GROUP_RID), temp);
break;
case SCHEMAVER_SAMBASAMACCOUNT:
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver,
LDAP_ATTR_PRIMARY_GROUP_SID), sid_to_string(sid_string, group_sid));
break;
@@ -2016,63 +1417,63 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
*/
if (need_update(sampass, PDB_FULLNAME))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DISPLAY_NAME),
pdb_get_fullname(sampass));
if (need_update(sampass, PDB_ACCTDESC))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_DESC),
pdb_get_acct_desc(sampass));
if (need_update(sampass, PDB_WORKSTATIONS))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_USER_WKS),
pdb_get_workstations(sampass));
if (need_update(sampass, PDB_SMBHOME))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH),
pdb_get_homedir(sampass));
if (need_update(sampass, PDB_DRIVE))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_DRIVE),
pdb_get_dir_drive(sampass));
if (need_update(sampass, PDB_LOGONSCRIPT))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT),
pdb_get_logon_script(sampass));
if (need_update(sampass, PDB_PROFILE))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH),
pdb_get_profile_path(sampass));
slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logon_time(sampass));
if (need_update(sampass, PDB_LOGONTIME))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_TIME), temp);
slprintf(temp, sizeof(temp) - 1, "%li", pdb_get_logoff_time(sampass));
if (need_update(sampass, PDB_LOGOFFTIME))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGOFF_TIME), temp);
slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_kickoff_time(sampass));
if (need_update(sampass, PDB_KICKOFFTIME))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_KICKOFF_TIME), temp);
slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_can_change_time(sampass));
if (need_update(sampass, PDB_CANCHANGETIME))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_CAN_CHANGE), temp);
slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_must_change_time(sampass));
if (need_update(sampass, PDB_MUSTCHANGETIME))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_MUST_CHANGE), temp);
if ((pdb_get_acct_ctrl(sampass)&(ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST))
@@ -2083,7 +1484,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
pdb_get_acct_ctrl(sampass));
if (need_update(sampass, PDB_LMPASSWD))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LMPW),
temp);
@@ -2091,13 +1492,13 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
pdb_get_acct_ctrl(sampass));
if (need_update(sampass, PDB_NTPASSWD))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_NTPW),
temp);
slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
if (need_update(sampass, PDB_PASSLASTSET))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_LAST_SET),
temp);
}
@@ -2105,7 +1506,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
/* FIXME: Hours stuff goes in LDAP */
if (need_update(sampass, PDB_ACCTCTRL))
- make_ldap_mod(ldap_state->ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO),
pdb_encode_acct_ctrl (pdb_get_acct_ctrl(sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN));
@@ -2129,7 +1530,8 @@ static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
all_string_sub(filter, "%u", "*", sizeof(pstring));
attr_list = get_userattr_list(ldap_state->schema_ver);
- rc = ldapsam_search_suffix(ldap_state, filter, attr_list, &ldap_state->result);
+ rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
+ attr_list, &ldap_state->result);
free_attr_list( attr_list );
if (rc != LDAP_SUCCESS) {
@@ -2141,10 +1543,10 @@ static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
}
DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
- ldap_count_entries(ldap_state->ldap_struct,
+ ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
ldap_state->result)));
- ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct,
+ ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
ldap_state->result);
ldap_state->index = 0;
@@ -2172,10 +1574,6 @@ static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
BOOL bret = False;
- /* The rebind proc needs this *HACK*. We are not multithreaded, so
- this will work, but it's not nice. */
- static_ldap_state = ldap_state;
-
while (!bret) {
if (!ldap_state->entry)
return ret;
@@ -2183,7 +1581,7 @@ static NTSTATUS ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT
ldap_state->index++;
bret = init_sam_from_ldap(ldap_state, user, ldap_state->entry);
- ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
+ ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
ldap_state->entry);
}
@@ -2210,7 +1608,7 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT
if ( rc != LDAP_SUCCESS )
return NT_STATUS_NO_SUCH_USER;
- count = ldap_count_entries(ldap_state->ldap_struct, result);
+ count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
if (count < 1) {
DEBUG(4,
@@ -2224,7 +1622,7 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT
return NT_STATUS_NO_SUCH_USER;
}
- entry = ldap_first_entry(ldap_state->ldap_struct, result);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
if (entry) {
if (!init_sam_from_ldap(ldap_state, user, entry)) {
DEBUG(1,("ldapsam_getsampwnam: init_sam_from_ldap failed for user '%s'!\n", sname));
@@ -2281,7 +1679,7 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT
break;
}
- count = ldap_count_entries(ldap_state->ldap_struct, result);
+ count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
if (count < 1)
{
@@ -2300,7 +1698,7 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT
return NT_STATUS_NO_SUCH_USER;
}
- entry = ldap_first_entry(ldap_state->ldap_struct, result);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
if (entry)
{
if (!init_sam_from_ldap(ldap_state, user, entry)) {
@@ -2339,11 +1737,13 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
switch(ldap_op)
{
case LDAP_MOD_ADD:
- ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_ACCOUNT);
- rc = ldapsam_add(ldap_state, dn, mods);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_ACCOUNT);
+ rc = smbldap_add(ldap_state->smbldap_state,
+ dn, mods);
break;
case LDAP_MOD_REPLACE:
- rc = ldapsam_modify(ldap_state, dn ,mods);
+ rc = smbldap_modify(ldap_state->smbldap_state,
+ dn ,mods);
break;
default:
DEBUG(0,("Wrong LDAP operation type: %d!\n", ldap_op));
@@ -2352,7 +1752,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
if (rc!=LDAP_SUCCESS) {
char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(1,
("failed to %s user dn= %s with: %s\n\t%s\n",
@@ -2406,8 +1806,10 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
SAFE_FREE(utf8_password);
ber_free(ber, 1);
- if ((rc = ldapsam_extended_operation(ldap_state, LDAP_EXOP_MODIFY_PASSWD,
- bv, NULL, NULL, &retoid, &retdata))!=LDAP_SUCCESS) {
+ if ((rc = smbldap_extended_operation(ldap_state->smbldap_state,
+ LDAP_EXOP_MODIFY_PASSWD,
+ bv, NULL, NULL, &retoid,
+ &retdata)) != LDAP_SUCCESS) {
DEBUG(0,("LDAP Password could not be changed for user %s: %s\n",
pdb_get_username(newpwd),ldap_err2string(rc)));
} else {
@@ -2505,14 +1907,14 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
if (rc != LDAP_SUCCESS)
return NT_STATUS_UNSUCCESSFUL;
- if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
+ if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
DEBUG(0, ("No user to modify!\n"));
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
- entry = ldap_first_entry(ldap_state->ldap_struct, result);
- dn = ldap_get_dn(ldap_state->ldap_struct, entry);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+ dn = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
if (!init_ldap_from_sam(ldap_state, entry, &mods, newpwd,
element_is_changed)) {
@@ -2535,7 +1937,7 @@ static NTSTATUS ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_A
if (!NT_STATUS_IS_OK(ret)) {
char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(0,("failed to modify user with uid = %s, error: %s (%s)\n",
pdb_get_username(newpwd), ld_error?ld_error:"(unknwon)", ldap_err2string(rc)));
@@ -2594,7 +1996,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
return NT_STATUS_UNSUCCESSFUL;
}
- if (ldap_count_entries(ldap_state->ldap_struct, result) != 0) {
+ if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 0) {
DEBUG(0,("User '%s' already in the base, with samba attributes\n",
username));
ldap_msgfree(result);
@@ -2611,13 +2013,14 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
all_string_sub( filter, "%u", escape_user, sizeof(filter) );
SAFE_FREE( escape_user );
- rc = ldapsam_search_suffix(ldap_state, filter, attr_list, &result);
+ rc = smbldap_search_suffix(ldap_state->smbldap_state,
+ filter, attr_list, &result);
free_attr_list( attr_list );
if ( rc != LDAP_SUCCESS )
return NT_STATUS_UNSUCCESSFUL;
- num_result = ldap_count_entries(ldap_state->ldap_struct, result);
+ num_result = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
if (num_result > 1) {
DEBUG (0, ("More than one user with that uid exists: bailing out!\n"));
@@ -2631,8 +2034,8 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
DEBUG(3,("User exists without samba attributes: adding them\n"));
ldap_op = LDAP_MOD_REPLACE;
- entry = ldap_first_entry (ldap_state->ldap_struct, result);
- tmp = ldap_get_dn (ldap_state->ldap_struct, entry);
+ entry = ldap_first_entry (ldap_state->smbldap_state->ldap_struct, result);
+ tmp = ldap_get_dn (ldap_state->smbldap_state->ldap_struct, entry);
slprintf (dn, sizeof (dn) - 1, "%s", tmp);
ldap_memfree (tmp);
} else {
@@ -2662,10 +2065,10 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
switch ( ldap_state->schema_ver )
{
case SCHEMAVER_SAMBAACCOUNT:
- ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBAACCOUNT);
break;
case SCHEMAVER_SAMBASAMACCOUNT:
- ldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectclass", LDAP_OBJ_SAMBASAMACCOUNT);
break;
default:
DEBUG(0,("ldapsam_add_sam_account: invalid schema version specified\n"));
@@ -2673,7 +2076,7 @@ static NTSTATUS ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCO
}
ret = ldapsam_modify_entry(my_methods,newpwd,dn,mods,ldap_op, element_is_set_or_changed);
- if (NT_STATUS_IS_ERR(ret)) {
+ if (!NT_STATUS_IS_OK(ret)) {
DEBUG(0,("failed to modify/add user with uid = %s (dn = %s)\n",
pdb_get_username(newpwd),dn));
ldap_mods_free(mods, True);
@@ -2694,16 +2097,7 @@ static void free_private_data(void **vp)
{
struct ldapsam_privates **ldap_state = (struct ldapsam_privates **)vp;
- ldapsam_close(*ldap_state);
-
- if ((*ldap_state)->bind_secret) {
- memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
- }
-
- ldapsam_close(*ldap_state);
-
- SAFE_FREE((*ldap_state)->bind_dn);
- SAFE_FREE((*ldap_state)->bind_secret);
+ smbldap_free_struct(&(*ldap_state)->smbldap_state);
*ldap_state = NULL;
@@ -2725,13 +2119,14 @@ static int ldapsam_search_one_group (struct ldapsam_privates *ldap_state,
attr_list = get_attr_list(groupmap_attr_list);
- rc = ldapsam_search(ldap_state, lp_ldap_group_suffix (), scope,
+ rc = smbldap_search(ldap_state->smbldap_state,
+ lp_ldap_group_suffix (), scope,
filter, attr_list, 0, result);
free_attr_list( attr_list );
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(0, ("ldapsam_search_one_group: "
"Problem during the LDAP search: LDAP error: %s (%s)",
@@ -2753,13 +2148,13 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
pstring temp;
if (ldap_state == NULL || map == NULL || entry == NULL ||
- ldap_state->ldap_struct == NULL)
+ ldap_state->smbldap_state->ldap_struct == NULL)
{
DEBUG(0, ("init_group_from_ldap: NULL parameters found!\n"));
return False;
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GIDNUMBER), temp))
{
DEBUG(0, ("Mandatory attribute %s not found\n",
@@ -2770,7 +2165,7 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
map->gid = (gid_t)atol(temp);
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_SID), temp))
{
DEBUG(0, ("Mandatory attribute %s not found\n",
@@ -2779,7 +2174,7 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
}
string_to_sid(&map->sid, temp);
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), temp))
{
DEBUG(0, ("Mandatory attribute %s not found\n",
@@ -2794,11 +2189,11 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
return False;
}
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), temp))
{
temp[0] = '\0';
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_CN), temp))
{
DEBUG(0, ("Attributes cn not found either "
@@ -2808,16 +2203,13 @@ static BOOL init_group_from_ldap(struct ldapsam_privates *ldap_state,
}
fstrcpy(map->nt_name, temp);
- if (!get_single_attribute(ldap_state->ldap_struct, entry,
+ if (!get_single_attribute(ldap_state->smbldap_state->ldap_struct, entry,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), temp))
{
temp[0] = '\0';
}
fstrcpy(map->comment, temp);
- map->systemaccount = 0;
- init_privilege(&map->priv_set);
-
return True;
}
@@ -2839,15 +2231,15 @@ static BOOL init_ldap_from_group(LDAP *ldap_struct,
*mods = NULL;
sid_to_string(tmp, &map->sid);
- make_ldap_mod(ldap_struct, existing, mods,
+ 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);
- make_ldap_mod(ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_struct, existing, mods,
get_attr_key2string(groupmap_attr_list, LDAP_ATTR_GROUP_TYPE), tmp);
- make_ldap_mod(ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_struct, existing, mods,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DISPLAY_NAME), map->nt_name);
- make_ldap_mod(ldap_struct, existing, mods,
+ smbldap_make_mod(ldap_struct, existing, mods,
get_attr_key2string( groupmap_attr_list, LDAP_ATTR_DESC), map->comment);
return True;
@@ -2871,7 +2263,7 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
return NT_STATUS_NO_SUCH_GROUP;
}
- count = ldap_count_entries(ldap_state->ldap_struct, result);
+ count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result);
if (count < 1) {
DEBUG(4, ("Did not find group for filter %s\n", filter));
@@ -2884,7 +2276,7 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
return NT_STATUS_NO_SUCH_GROUP;
}
- entry = ldap_first_entry(ldap_state->ldap_struct, result);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
if (!entry) {
ldap_msgfree(result);
@@ -2906,7 +2298,7 @@ static NTSTATUS ldapsam_getgroup(struct pdb_methods *methods,
*********************************************************************/
static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
- DOM_SID sid, BOOL with_priv)
+ DOM_SID sid)
{
pstring filter;
@@ -2922,7 +2314,7 @@ static NTSTATUS ldapsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
*********************************************************************/
static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
- gid_t gid, BOOL with_priv)
+ gid_t gid)
{
pstring filter;
@@ -2938,7 +2330,7 @@ static NTSTATUS ldapsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
*********************************************************************/
static NTSTATUS ldapsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
- char *name, BOOL with_priv)
+ const char *name)
{
pstring filter;
@@ -2989,7 +2381,7 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
int rc;
if (NT_STATUS_IS_OK(ldapsam_getgrgid(methods, &dummy,
- map->gid, False))) {
+ map->gid))) {
DEBUG(0, ("Group %i already exists in LDAP\n", map->gid));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -2999,19 +2391,19 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
return NT_STATUS_UNSUCCESSFUL;
}
- if (ldap_count_entries(ldap_state->ldap_struct, result) != 1) {
+ if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) != 1) {
DEBUG(2, ("Group %i must exist exactly once in LDAP\n",
map->gid));
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
- entry = ldap_first_entry(ldap_state->ldap_struct, result);
- tmp = ldap_get_dn(ldap_state->ldap_struct, entry);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+ tmp = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
pstrcpy(dn, tmp);
ldap_memfree(tmp);
- if (!init_ldap_from_group(ldap_state->ldap_struct,
+ if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
result, &mods, map)) {
DEBUG(0, ("init_ldap_from_group failed!\n"));
ldap_mods_free(mods, True);
@@ -3026,14 +2418,14 @@ static NTSTATUS ldapsam_add_group_mapping_entry(struct pdb_methods *methods,
return NT_STATUS_UNSUCCESSFUL;
}
- ldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP );
+ smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_GROUPMAP );
- rc = ldapsam_modify(ldap_state, dn, mods);
+ rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
ldap_mods_free(mods, True);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ 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,
ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
@@ -3065,16 +2457,16 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
return NT_STATUS_UNSUCCESSFUL;
}
- if (ldap_count_entries(ldap_state->ldap_struct, result) == 0) {
+ if (ldap_count_entries(ldap_state->smbldap_state->ldap_struct, result) == 0) {
DEBUG(0, ("No group to modify!\n"));
ldap_msgfree(result);
return NT_STATUS_UNSUCCESSFUL;
}
- entry = ldap_first_entry(ldap_state->ldap_struct, result);
- dn = ldap_get_dn(ldap_state->ldap_struct, entry);
+ entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, result);
+ dn = ldap_get_dn(ldap_state->smbldap_state->ldap_struct, entry);
- if (!init_ldap_from_group(ldap_state->ldap_struct,
+ if (!init_ldap_from_group(ldap_state->smbldap_state->ldap_struct,
result, &mods, map)) {
DEBUG(0, ("init_ldap_from_group failed\n"));
ldap_msgfree(result);
@@ -3088,13 +2480,13 @@ static NTSTATUS ldapsam_update_group_mapping_entry(struct pdb_methods *methods,
return NT_STATUS_UNSUCCESSFUL;
}
- rc = ldapsam_modify(ldap_state, dn, mods);
+ rc = smbldap_modify(ldap_state->smbldap_state, dn, mods);
ldap_mods_free(mods, True);
if (rc != LDAP_SUCCESS) {
char *ld_error = NULL;
- ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
+ 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,
ld_error ? ld_error : "(unknown)", ldap_err2string(rc)));
@@ -3150,7 +2542,7 @@ static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
snprintf( filter, sizeof(filter)-1, "(objectclass=%s)", LDAP_OBJ_GROUPMAP);
attr_list = get_attr_list( groupmap_attr_list );
- rc = ldapsam_search(ldap_state, lp_ldap_group_suffix(),
+ rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
LDAP_SCOPE_SUBTREE, filter,
attr_list, 0, &ldap_state->result);
free_attr_list( attr_list );
@@ -3164,10 +2556,10 @@ static NTSTATUS ldapsam_setsamgrent(struct pdb_methods *my_methods, BOOL update)
}
DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
- ldap_count_entries(ldap_state->ldap_struct,
+ ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
ldap_state->result)));
- ldap_state->entry = ldap_first_entry(ldap_state->ldap_struct, ldap_state->result);
+ ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct, ldap_state->result);
ldap_state->index = 0;
return NT_STATUS_OK;
@@ -3191,10 +2583,6 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
BOOL bret = False;
- /* The rebind proc needs this *HACK*. We are not multithreaded, so
- this will work, but it's not nice. */
- static_ldap_state = ldap_state;
-
while (!bret) {
if (!ldap_state->entry)
return ret;
@@ -3202,7 +2590,7 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
ldap_state->index++;
bret = init_group_from_ldap(ldap_state, map, ldap_state->entry);
- ldap_state->entry = ldap_next_entry(ldap_state->ldap_struct,
+ ldap_state->entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
ldap_state->entry);
}
@@ -3215,7 +2603,7 @@ static NTSTATUS ldapsam_getsamgrent(struct pdb_methods *my_methods,
static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
enum SID_NAME_USE sid_name_use,
GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only, BOOL with_priv)
+ BOOL unix_only)
{
GROUP_MAP map;
GROUP_MAP *mapt;
@@ -3263,6 +2651,7 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods,
}
/**********************************************************************
+ Intitalise the parts of the pdb_context that are common to all pdb_ldap modes
*********************************************************************/
static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
@@ -3296,18 +2685,15 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
/* TODO: Setup private data and free */
- ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(struct ldapsam_privates));
-
+ ldap_state = talloc_zero(pdb_context->mem_ctx, sizeof(*ldap_state));
if (!ldap_state) {
DEBUG(0, ("talloc() failed for ldapsam private_data!\n"));
return NT_STATUS_NO_MEMORY;
}
- if (location) {
- ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
- } else {
- ldap_state->uri = "ldap://localhost";
- }
+ if (!NT_STATUS_IS_OK(nt_status =
+ smbldap_init(pdb_context->mem_ctx, location,
+ &ldap_state->smbldap_state)));
ldap_state->domain_name = talloc_strdup(pdb_context->mem_ctx, get_global_sam_name());
if (!ldap_state->domain_name) {
@@ -3324,6 +2710,7 @@ static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **
}
/**********************************************************************
+ Initialise the 'compat' mode for pdb_ldap
*********************************************************************/
static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
@@ -3331,21 +2718,8 @@ static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **
NTSTATUS nt_status;
struct ldapsam_privates *ldap_state;
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
- return nt_status;
- }
-
- (*pdb_method)->name = "ldapsam_compat";
-
- ldap_state = (*pdb_method)->private_data;
- ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
-
- if (location) {
- ldap_state->uri = talloc_strdup(pdb_context->mem_ctx, location);
- } else {
-#ifndef WITH_LDAP_SAMCONFIG
- ldap_state->uri = "ldap://localhost";
-#else
+#ifdef WITH_LDAP_SAMCONFIG
+ if (!location) {
int ldap_port = lp_ldap_port();
/* remap default port if not using SSL (ie clear or TLS) */
@@ -3353,17 +2727,27 @@ static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS **
ldap_port = 389;
}
- ldap_state->uri = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
- if (!ldap_state->uri) {
+ location = talloc_asprintf(pdb_context->mem_ctx, "%s://%s:%d", lp_ldap_ssl() == LDAP_SSL_ON ? "ldaps" : "ldap", lp_ldap_server(), ldap_port);
+ if (!location) {
return NT_STATUS_NO_MEMORY;
}
+ }
#endif
+
+ if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) {
+ return nt_status;
}
+ (*pdb_method)->name = "ldapsam_compat";
+
+ ldap_state = (*pdb_method)->private_data;
+ ldap_state->schema_ver = SCHEMAVER_SAMBAACCOUNT;
+
return NT_STATUS_OK;
}
/**********************************************************************
+ Initialise the normal mode for pdb_ldap
*********************************************************************/
static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index 7095e8a4529..e00680917c5 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -1512,7 +1512,7 @@ static void free_private_data(void **vp)
/* No need to free any further, as it is talloc()ed */
}
-NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+static NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
NTSTATUS nt_status;
struct smbpasswd_privates *privates;
@@ -1559,15 +1559,14 @@ NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
(*pdb_method)->free_private_data = free_private_data;
if (lp_idmap_uid(&privates->low_nua_userid, &privates->high_nua_userid)) {
- DEBUG(0, ("idmap uid range defined, non unix accounts enabled\n"));
+ DEBUG(3, ("idmap uid range defined, non unix accounts enabled\n"));
privates->permit_non_unix_accounts = True;
}
return NT_STATUS_OK;
}
-int pdb_smbpasswd_init(void)
+NTSTATUS pdb_smbpasswd_init(void)
{
- smb_register_passdb(PASSDB_INTERFACE_VERSION, "smbpasswd", pdb_init_smbpasswd);
- return True;
+ return smb_register_passdb(PASSDB_INTERFACE_VERSION, "smbpasswd", pdb_init_smbpasswd);
}
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index 7f8c2a26f76..2cf7a0119f3 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -242,6 +242,8 @@ done:
SAFE_FREE(acct_desc);
SAFE_FREE(workstations);
SAFE_FREE(munged_dial);
+ SAFE_FREE(unknown_str);
+ SAFE_FREE(hours);
return ret;
}
@@ -488,6 +490,7 @@ static void close_tdb(struct tdbsam_privates *tdb_state)
static void tdbsam_endsampwent(struct pdb_methods *my_methods)
{
struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
+ SAFE_FREE(tdb_state->key.dptr);
close_tdb(tdb_state);
DEBUG(7, ("endtdbpwent: closed sam database.\n"));
@@ -501,7 +504,7 @@ static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
- TDB_DATA data;
+ TDB_DATA data, old_key;
const char *prefix = USERPREFIX;
int prefixlen = strlen (prefix);
@@ -512,10 +515,16 @@ static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *
}
/* skip all non-USER entries (eg. RIDs) */
- while ((tdb_state->key.dsize != 0) && (strncmp(tdb_state->key.dptr, prefix, prefixlen)))
+ while ((tdb_state->key.dsize != 0) && (strncmp(tdb_state->key.dptr, prefix, prefixlen))) {
+
+ old_key = tdb_state->key;
+
/* increment to next in line */
tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
+ SAFE_FREE(old_key.dptr);
+ }
+
/* do we have an valid iteration pointer? */
if(tdb_state->passwd_tdb == NULL) {
DEBUG(0,("pdb_get_sampwent: Bad TDB Context pointer.\n"));
@@ -536,9 +545,13 @@ static NTSTATUS tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *
}
SAFE_FREE(data.dptr);
+ old_key = tdb_state->key;
+
/* increment to next in line */
tdb_state->key = tdb_nextkey(tdb_state->passwd_tdb, tdb_state->key);
+ SAFE_FREE(old_key.dptr);
+
return NT_STATUS_OK;
}
@@ -912,7 +925,7 @@ static void free_private_data(void **vp)
}
-NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
NTSTATUS nt_status;
struct tdbsam_privates *tdb_state;
@@ -955,7 +968,7 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con
(*pdb_method)->free_private_data = free_private_data;
if (lp_idmap_uid(&low_nua_uid, &high_nua_uid)) {
- DEBUG(0, ("idmap uid range defined, non unix accounts enabled\n"));
+ DEBUG(3, ("idmap uid range defined, non unix accounts enabled\n"));
tdb_state->permit_non_unix_accounts = True;
@@ -970,9 +983,8 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con
return NT_STATUS_OK;
}
-int pdb_tdbsam_init(void)
+NTSTATUS pdb_tdbsam_init(void)
{
- smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam);
- return True;
+ return smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam);
}
diff --git a/source/passdb/pdb_xml.c b/source/passdb/pdb_xml.c
index 7a5c0e2b53b..154d8c927f6 100644
--- a/source/passdb/pdb_xml.c
+++ b/source/passdb/pdb_xml.c
@@ -28,7 +28,7 @@
*/
-#define XML_URL "http://www.samba.org/ns"
+#define XML_URL "http://samba.org/~jelmer/sambapdb.dtd"
#include "includes.h"
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index 5df0edc29aa..c039fe53b42 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -151,7 +151,7 @@ BOOL secrets_fetch_domain_guid(const char *domain, GUID *guid)
DEBUG(6,("key is %s, size is %d\n", key, (int)size));
if ((NULL == dyn_guid) && (ROLE_DOMAIN_PDC == lp_server_role())) {
- uuid_generate_random(&new_guid);
+ smb_uuid_generate_random(&new_guid);
if (!secrets_store_domain_guid(domain, &new_guid))
return False;
dyn_guid = (GUID *)secrets_fetch(key, &size);
@@ -252,8 +252,7 @@ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
channel);
if (plaintext) {
- /* we have an ADS password - use that */
- DEBUG(4,("Using ADS machine password\n"));
+ DEBUG(4,("Using cleartext machine password\n"));
E_md4hash(plaintext, ret_pwd);
SAFE_FREE(plaintext);
return True;
@@ -453,6 +452,7 @@ char *secrets_fetch_machine_password(const char *domain,
last_set_time = secrets_fetch(key, &size);
if (last_set_time) {
*pass_last_set_time = IVAL(last_set_time,0);
+ SAFE_FREE(last_set_time);
} else {
*pass_last_set_time = 0;
}
@@ -467,6 +467,7 @@ char *secrets_fetch_machine_password(const char *domain,
channel_type = secrets_fetch(key, &size);
if (channel_type) {
*channel = IVAL(channel_type,0);
+ SAFE_FREE(channel_type);
} else {
*channel = get_default_sec_channel();
}
@@ -614,7 +615,7 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, unsigned in
DEBUG(0, ("strndup failed!\n"));
return NT_STATUS_NO_MEMORY;
}
-
+
packed_pass = secrets_fetch(secrets_key, &size);
packed_size = tdb_trusted_dom_pass_unpack(packed_pass, size, pass);
/* packed representation isn't needed anymore */
diff --git a/source/printing/notify.c b/source/printing/notify.c
index ee973da211c..479d883134b 100644
--- a/source/printing/notify.c
+++ b/source/printing/notify.c
@@ -480,7 +480,7 @@ void notify_printer_location(int snum, char *location)
snum, strlen(location) + 1, location);
}
-void notify_printer_byname( char *printername, uint32 change, char *value )
+void notify_printer_byname( const char *printername, uint32 change, char *value )
{
int snum = print_queue_snum(printername);
int type = PRINTER_NOTIFY_TYPE;
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index f6c5c183a47..814cf53d85c 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -2443,6 +2443,7 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su
return num_subkeys;
}
+#ifdef HAVE_ADS
static void map_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
const char *sz)
{
@@ -2555,7 +2556,6 @@ static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
return True;
}
-#ifdef HAVE_ADS
static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, GUID guid)
{
int i;
@@ -2601,8 +2601,9 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
printer->info_2->sharename);
- /* connect to the ADS server */
- ads = ads_init(NULL, NULL, lp_ads_server());
+ /* initial ads structure */
+
+ ads = ads_init(NULL, NULL, NULL);
if (!ads) {
DEBUG(3, ("ads_init() failed\n"));
return WERR_SERVER_UNAVAILABLE;
@@ -2610,7 +2611,9 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
SAFE_FREE(ads->auth.password);
ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
- NULL, NULL);
+ NULL, NULL);
+
+ /* ads_connect() will find the DC for us */
ads_rc = ads_connect(ads);
if (!ADS_ERR_OK(ads_rc)) {
DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
@@ -2663,7 +2666,7 @@ WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
return win_rc;
}
- ads = ads_init(NULL, NULL, lp_ads_server());
+ ads = ads_init(NULL, NULL, NULL);
if (!ads) {
DEBUG(3, ("ads_init() failed\n"));
return WERR_SERVER_UNAVAILABLE;
@@ -2671,7 +2674,9 @@ WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
SAFE_FREE(ads->auth.password);
ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
- NULL, NULL);
+ NULL, NULL);
+
+ /* ads_connect() will find the DC for us */
ads_rc = ads_connect(ads);
if (!ADS_ERR_OK(ads_rc)) {
DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
diff --git a/source/printing/printing.c b/source/printing/printing.c
index add690fb8be..79f8571e31c 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -1465,7 +1465,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
else
remove_from_jobs_changed(snum, jobid);
- /* Delete the tdb entry if the delete suceeded or the job hasn't
+ /* Delete the tdb entry if the delete succeeded or the job hasn't
been spooled. */
if (result == 0) {
diff --git a/source/python/mkpatch b/source/python/mkpatch
deleted file mode 100755
index ab5be1b6a2f..00000000000
--- a/source/python/mkpatch
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-#
-# Make samba-head.patch. Must be run from samba source directory.
-#
-
-cvs -z3 diff -u Makefile.in configure.in > python/samba-head.patch
diff --git a/source/rpc_client/cli_samr.c b/source/rpc_client/cli_samr.c
index 4fe8fba7b0b..635b7e71350 100644
--- a/source/rpc_client/cli_samr.c
+++ b/source/rpc_client/cli_samr.c
@@ -35,6 +35,8 @@ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_CONNECT r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_connect to %s\n", cli->desthost));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -82,6 +84,8 @@ NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_CONNECT4 r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -129,6 +133,8 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_CLOSE_HND r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_close\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -177,6 +183,8 @@ NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_OPEN_DOMAIN r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_open_domain with sid %s\n", sid_string_static(domain_sid) ));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -225,6 +233,8 @@ NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_OPEN_USER r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_open_user with rid 0x%x\n", user_rid ));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -273,6 +283,8 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_OPEN_GROUP r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_open_group with rid 0x%x\n", group_rid ));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -321,6 +333,8 @@ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_USERINFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_query_userinfo\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -365,6 +379,8 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_GROUPINFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_query_groupinfo\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -410,6 +426,8 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_USERGROUPS r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_query_usergroups\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -457,6 +475,8 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
unsigned int ptr=1;
+ DEBUG(10,("cli_samr_query_useraliases\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -503,6 +523,8 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_GROUPMEM r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_query_groupmem\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -568,6 +590,8 @@ NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
int i;
+ DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -646,6 +670,8 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 name_idx, i;
+ DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -724,6 +750,8 @@ NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 name_idx, i;
+ DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -804,6 +832,8 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 i;
+ DEBUG(10,("cli_samr_query_aliasmem\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -862,6 +892,8 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_OPEN_ALIAS r;
NTSTATUS result;
+ DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -903,6 +935,57 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
+/* Query alias info */
+
+NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *alias_pol, uint16 switch_value,
+ ALIAS_INFO_CTR *ctr)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_QUERY_ALIASINFO q;
+ SAMR_R_QUERY_ALIASINFO r;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ DEBUG(10,("cli_samr_query_dom_info\n"));
+
+ 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);
+
+ /* Marshall data and send request */
+
+ init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
+
+ if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (!NT_STATUS_IS_OK(result = r.status)) {
+ goto done;
+ }
+
+ *ctr = r.ctr;
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
/* Query domain info */
NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
@@ -914,6 +997,8 @@ NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_DOMAIN_INFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_query_dom_info\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -997,6 +1082,8 @@ NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_DISPINFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1059,6 +1146,8 @@ NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 i;
+ DEBUG(10,("cli_samr_lookup_rids\n"));
+
if (num_rids > 1000) {
DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
"more than ~1000 rids are looked up at once.\n"));
@@ -1133,6 +1222,8 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 i;
+ DEBUG(10,("cli_samr_lookup_names\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1196,6 +1287,8 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_CREATE_USER r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1249,6 +1342,8 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_SET_USERINFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_set_userinfo\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1299,6 +1394,8 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_SET_USERINFO2 r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_set_userinfo2\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1345,6 +1442,8 @@ NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_DELETE_DOM_USER r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_delete_dom_user\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1390,6 +1489,8 @@ NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_QUERY_SEC_OBJ r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_query_sec_obj\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1435,6 +1536,8 @@ NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_GET_DOM_PWINFO r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1487,6 +1590,8 @@ NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
SAMR_R_LOOKUP_DOMAIN r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ DEBUG(10,("cli_samr_lookup_domain\n"));
+
ZERO_STRUCT(q);
ZERO_STRUCT(r);
diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c
index 870402db5d3..3848bd7051f 100644
--- a/source/rpc_parse/parse_sec.c
+++ b/source/rpc_parse/parse_sec.c
@@ -3,7 +3,7 @@
* Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-1998
+ * Copyright (C) Jeremy R. Allison 1995-2003.
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
* Copyright (C) Paul Ashton 1997-1998.
*
@@ -901,7 +901,7 @@ BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int
}
/*******************************************************************
- adds new SID with its permissions to SEC_DESC
+ Add a new SID with its permissions to SEC_DESC.
********************************************************************/
NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size)
@@ -913,7 +913,8 @@ NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32
*sd_size = 0;
- if (!ctx || !psd || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
+ if (!ctx || !psd || !sid || !sd_size)
+ return NT_STATUS_INVALID_PARAMETER;
status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid, mask);
@@ -933,14 +934,15 @@ NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32
}
/*******************************************************************
- modify SID's permissions at SEC_DESC
+ Modify a SID's permissions in a SEC_DESC.
********************************************************************/
NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
{
NTSTATUS status;
- if (!sd || !sid) return NT_STATUS_INVALID_PARAMETER;
+ if (!sd || !sid)
+ return NT_STATUS_INVALID_PARAMETER;
status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask);
@@ -951,7 +953,7 @@ NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask)
}
/*******************************************************************
- delete SID from SEC_DESC
+ Delete a SID from a SEC_DESC.
********************************************************************/
NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size)
@@ -963,7 +965,8 @@ NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t
*sd_size = 0;
- if (!ctx || !psd[0] || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER;
+ if (!ctx || !psd[0] || !sid || !sd_size)
+ return NT_STATUS_INVALID_PARAMETER;
status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid);
@@ -981,3 +984,108 @@ NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t
sd = 0;
return NT_STATUS_OK;
}
+
+/*******************************************************************
+ Comparison function to sort non-inherited first.
+*******************************************************************/
+
+static int nt_ace_inherit_comp( SEC_ACE *a1, SEC_ACE *a2)
+{
+ int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE;
+ int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE;
+
+ if (a1_inh == a2_inh)
+ return 0;
+
+ if (!a1_inh && a2_inh)
+ return -1;
+ return 1;
+}
+
+/*******************************************************************
+ Comparison function to apply the order explained below in a group.
+*******************************************************************/
+
+static int nt_ace_canon_comp( SEC_ACE *a1, SEC_ACE *a2)
+{
+ if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
+ (a2->type != SEC_ACE_TYPE_ACCESS_DENIED))
+ return -1;
+
+ if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
+ (a1->type != SEC_ACE_TYPE_ACCESS_DENIED))
+ return 1;
+
+ /* Both access denied or access allowed. */
+
+ /* 1. ACEs that apply to the object itself */
+
+ if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
+ (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY))
+ return -1;
+ else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
+ (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY))
+ return 1;
+
+ /* 2. ACEs that apply to a subobject of the object, such as
+ * a property set or property. */
+
+ if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
+ !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
+ return -1;
+ else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
+ !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
+ return 1;
+
+ return 0;
+}
+
+/*******************************************************************
+ Functions to convert a SEC_DESC ACE DACL list into canonical order.
+ JRA.
+
+--- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
+
+The following describes the preferred order:
+
+ To ensure that noninherited ACEs have precedence over inherited ACEs,
+ place all noninherited ACEs in a group before any inherited ACEs.
+ This ordering ensures, for example, that a noninherited access-denied ACE
+ is enforced regardless of any inherited ACE that allows access.
+
+ Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows:
+ 1. Access-denied ACEs that apply to the object itself
+ 2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
+ 3. Access-allowed ACEs that apply to the object itself
+ 4. Access-allowed ACEs that apply to a subobject of the object"
+
+********************************************************************/
+
+void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces)
+{
+ unsigned int i;
+
+ if (!srclist || num_aces == 0)
+ return;
+
+ /* Sort so that non-inherited ACE's come first. */
+ qsort( srclist, num_aces, sizeof(srclist[0]), QSORT_CAST nt_ace_inherit_comp);
+
+ /* Find the boundary between non-inherited ACEs. */
+ for (i = 0; i < num_aces; i++ ) {
+ SEC_ACE *curr_ace = &srclist[i];
+
+ if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE)
+ break;
+ }
+
+ /* i now points at entry number of the first inherited ACE. */
+
+ /* Sort the non-inherited ACEs. */
+ if (i)
+ qsort( srclist, i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
+
+ /* Now sort the inherited ACEs. */
+ if (num_aces - i)
+ qsort( &srclist[i], num_aces - i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
+}
diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c
index a5d2087a3a3..03b204e69d4 100644
--- a/source/rpc_parse/parse_spoolss.c
+++ b/source/rpc_parse/parse_spoolss.c
@@ -645,7 +645,7 @@ static BOOL spool_io_user_level(const char *desc, SPOOL_USER_CTR *q_u, prs_struc
BOOL spoolss_io_devmode(const char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
{
- uint32 available_space; /* size of the device mode left to parse */
+ int available_space; /* size of the device mode left to parse */
/* only important on unmarshalling */
int i = 0;
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index 2a24d7faa57..93e97a74929 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -403,8 +403,16 @@ NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL
/* get the generic lsa policy SD until we store it */
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
- if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status))
- return status;
+ if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
+ if (geteuid() != 0) {
+ return status;
+ }
+ DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+ acc_granted, des_access));
+ DEBUGADD(4,("but overwritten by euid == 0\n"));
+ acc_granted = des_access;
+ }
+
/* associate the domain SID with the (unique) handle. */
if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
@@ -441,8 +449,15 @@ NTSTATUS _lsa_open_policy(pipes_struct *p, LSA_Q_OPEN_POL *q_u, LSA_R_OPEN_POL *
/* get the generic lsa policy SD until we store it */
lsa_get_generic_sd(p->mem_ctx, &psd, &sd_size);
- if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status))
- return status;
+ if(!se_access_check(psd, p->pipe_user.nt_user_token, des_access, &acc_granted, &status)) {
+ if (geteuid() != 0) {
+ return status;
+ }
+ DEBUG(4,("ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
+ acc_granted, des_access));
+ DEBUGADD(4,("but overwritten by euid == 0\n"));
+ acc_granted = des_access;
+ }
/* associate the domain SID with the (unique) handle. */
if ((info = (struct lsa_info *)malloc(sizeof(struct lsa_info))) == NULL)
@@ -844,7 +859,7 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU
return NT_STATUS_ACCESS_DENIED;
/* get the list of mapped groups (domain, local, builtin) */
- if(!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV))
+ if(!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED))
return NT_STATUS_OK;
if (q_u->enum_context >= num_entries)
@@ -949,8 +964,6 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LS
{
struct lsa_info *info=NULL;
GROUP_MAP map;
- int i=0;
-
LUID_ATTR *set=NULL;
r_u->status = NT_STATUS_OK;
@@ -959,9 +972,10 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LS
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!pdb_getgrsid(&map, info->sid, MAPPING_WITH_PRIV))
+ if (!pdb_getgrsid(&map, info->sid))
return NT_STATUS_NO_SUCH_GROUP;
+#if 0 /* privileges currently not implemented! */
DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", map.priv_set.count));
if (map.priv_set.count!=0) {
@@ -982,6 +996,9 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, LSA_Q_ENUMPRIVSACCOUNT *q_u, LS
init_lsa_r_enum_privsaccount(r_u, set, map.priv_set.count, 0);
free_privilege(&map.priv_set);
+#endif
+
+ init_lsa_r_enum_privsaccount(r_u, set, 0, 0);
return r_u->status;
}
@@ -1000,7 +1017,7 @@ NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!pdb_getgrsid(&map, info->sid, MAPPING_WITHOUT_PRIV))
+ if (!pdb_getgrsid(&map, info->sid))
return NT_STATUS_NO_SUCH_GROUP;
/*
@@ -1012,7 +1029,7 @@ NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA
they can be ORed together
*/
- r_u->access=map.systemaccount;
+ r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
return r_u->status;
}
@@ -1031,16 +1048,12 @@ NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!pdb_getgrsid(&map, info->sid, MAPPING_WITH_PRIV))
+ if (!pdb_getgrsid(&map, info->sid))
return NT_STATUS_NO_SUCH_GROUP;
- map.systemaccount=q_u->access;
-
if(!pdb_update_group_mapping_entry(&map))
return NT_STATUS_NO_SUCH_GROUP;
- free_privilege(&map.priv_set);
-
return r_u->status;
}
@@ -1050,20 +1063,22 @@ NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA
NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u)
{
+#if 0
struct lsa_info *info=NULL;
GROUP_MAP map;
int i=0;
-
LUID_ATTR *luid_attr=NULL;
PRIVILEGE_SET *set=NULL;
+#endif
r_u->status = NT_STATUS_OK;
+#if 0 /* privileges are not implemented */
/* find the connection policy handle. */
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!pdb_getgrsid(&map, info->sid, MAPPING_WITH_PRIV))
+ if (!pdb_getgrsid(&map, info->sid))
return NT_STATUS_NO_SUCH_GROUP;
set=&q_u->set;
@@ -1085,6 +1100,7 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u
free_privilege(&map.priv_set);
+#endif
return r_u->status;
}
@@ -1094,20 +1110,22 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u
NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEPRIVS *r_u)
{
+#if 0
struct lsa_info *info=NULL;
GROUP_MAP map;
int i=0;
-
LUID_ATTR *luid_attr=NULL;
PRIVILEGE_SET *set=NULL;
+#endif
r_u->status = NT_STATUS_OK;
+#if 0 /* privileges are not implemented */
/* find the connection policy handle. */
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!pdb_getgrsid(&map, info->sid, MAPPING_WITH_PRIV))
+ if (!pdb_getgrsid(&map, info->sid))
return NT_STATUS_NO_SUCH_GROUP;
if (q_u->allrights!=0) {
@@ -1141,7 +1159,7 @@ NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEP
return NT_STATUS_NO_SUCH_GROUP;
free_privilege(&map.priv_set);
-
+#endif
return r_u->status;
}
diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c
index aa573b81540..fa19708773d 100644
--- a/source/rpc_server/srv_netlog_nt.c
+++ b/source/rpc_server/srv_netlog_nt.c
@@ -524,6 +524,7 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
auth_serversupplied_info *server_info = NULL;
extern userdom_struct current_user_info;
SAM_ACCOUNT *sampw;
+ struct auth_context *auth_context = NULL;
usr_info = (NET_USER_INFO_3 *)talloc(p->mem_ctx, sizeof(NET_USER_INFO_3));
if (!usr_info)
@@ -598,10 +599,11 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", q_u->sam_id.ctr->switch_value, nt_username));
+ status = NT_STATUS_OK;
+
switch (ctr->switch_value) {
case NET_LOGON_TYPE:
{
- struct auth_context *auth_context = NULL;
if (!NT_STATUS_IS_OK(status = make_auth_context_fixed(&auth_context, ctr->auth.id2.lm_chal))) {
return status;
}
@@ -615,11 +617,7 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
ctr->auth.id2.nt_chal_resp.buffer,
ctr->auth.id2.nt_chal_resp.str_str_len)) {
status = NT_STATUS_NO_MEMORY;
- } else {
- status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
- }
- (auth_context->free)(&auth_context);
-
+ }
break;
}
case INTERACTIVE_LOGON_TYPE:
@@ -628,8 +626,8 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
convert this to chellange/responce for the auth
subsystem to chew on */
{
- struct auth_context *auth_context = NULL;
const uint8 *chal;
+
if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) {
return status;
}
@@ -643,12 +641,7 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
ctr->auth.id1.nt_owf.data,
p->dc.sess_key)) {
status = NT_STATUS_NO_MEMORY;
- } else {
- status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
}
-
- (auth_context->free)(&auth_context);
-
break;
}
default:
@@ -656,6 +649,14 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
return NT_STATUS_INVALID_INFO_CLASS;
} /* end switch */
+ if ( NT_STATUS_IS_OK(status) ) {
+ become_root();
+ status = auth_context->check_ntlm_password(auth_context,
+ user_info, &server_info);
+ unbecome_root();
+ }
+
+ (auth_context->free)(&auth_context);
free_user_info(&user_info);
DEBUG(5, ("_net_sam_logon: check_password returned status %s\n",
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index ee496126ada..ebf483da660 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -304,7 +304,7 @@ static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
become_root();
- if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) {
+ if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED)) {
DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -900,7 +900,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
/* well-known aliases */
if (sid_equal(sid, &global_sid_Builtin) && !lp_hide_local_users()) {
- pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
+ pdb_enum_group_mapping(SID_NAME_WKN_GRP, &map, (int *)&num_entries, ENUM_ONLY_MAPPED);
if (num_entries != 0) {
*d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
@@ -937,7 +937,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
for (; (num_entries < max_entries) && (grp != NULL); grp = grp->next) {
uint32 trid;
- if(!pdb_getgrgid(&smap, grp->gr_gid, MAPPING_WITHOUT_PRIV))
+ if(!pdb_getgrgid(&smap, grp->gr_gid))
continue;
if (smap.sid_name_use!=SID_NAME_ALIAS) {
@@ -1018,7 +1018,7 @@ static NTSTATUS get_group_domain_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DO
*p_num_entries = 0;
- pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV);
+ pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
num_entries=group_entries-start_idx;
@@ -1346,7 +1346,7 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM
!sid_check_is_in_builtin(&sid))
return NT_STATUS_OBJECT_TYPE_MISMATCH;
- if (!pdb_getgrsid(&map, sid, MAPPING_WITHOUT_PRIV))
+ if (!pdb_getgrsid(&map, sid))
return NT_STATUS_NO_SUCH_ALIAS;
switch (q_u->switch_level) {
@@ -2731,6 +2731,41 @@ static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
}
/*******************************************************************
+ The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
+ ********************************************************************/
+static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
+{
+ struct group *grp;
+ gid_t gid;
+
+ if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
+ &gid))) {
+ DEBUG(2,("Could not get gid for primary group of "
+ "user %s\n", pdb_get_username(sampass)));
+ return False;
+ }
+
+ grp = getgrgid(gid);
+
+ if (grp == NULL) {
+ DEBUG(2,("Could not find primary group %d for "
+ "user %s\n", gid, pdb_get_username(sampass)));
+ return False;
+ }
+
+ if (smb_set_primary_group(grp->gr_name,
+ pdb_get_username(sampass)) != 0) {
+ DEBUG(2,("Could not set primary group for user %s to "
+ "%s\n",
+ pdb_get_username(sampass), grp->gr_name));
+ return False;
+ }
+
+ return True;
+}
+
+
+/*******************************************************************
set_user_info_21
********************************************************************/
@@ -2759,6 +2794,9 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
* id21. I don't know if they need to be set. --jerry
*/
+ if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
+ set_unix_primary_group(pwd);
+
/* write the change out */
if(!pdb_update_sam_account(pwd)) {
pdb_free_sam(&pwd);
@@ -2826,6 +2864,9 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
ZERO_STRUCT(plaintext_buf);
+ if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
+ set_unix_primary_group(pwd);
+
if(!pdb_update_sam_account(pwd)) {
pdb_free_sam(&pwd);
return False;
@@ -3174,12 +3215,12 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_
if (sid_equal(&alias_sid, &global_sid_Builtin)) {
DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
- if(!get_builtin_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
+ if(!get_builtin_group_from_sid(als_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
} else {
if (sid_equal(&alias_sid, get_global_sam_sid())) {
DEBUG(10, ("lookup on Server SID\n"));
- if(!get_local_group_from_sid(als_sid, &map, MAPPING_WITHOUT_PRIV))
+ if(!get_local_group_from_sid(als_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
}
}
@@ -3280,7 +3321,7 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_
sid_append_rid(&group_sid, group_rid);
DEBUG(10, ("lookup on Domain SID\n"));
- if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
+ if(!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
@@ -3364,13 +3405,13 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD
if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
DEBUG(10, ("adding member on Server SID\n"));
- if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
+ if(!get_local_group_from_sid(alias_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
} else {
if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
DEBUG(10, ("adding member on BUILTIN SID\n"));
- if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
+ if( !get_local_group_from_sid(alias_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
} else
@@ -3389,7 +3430,7 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD
}
/* check a real user exist before we run the script to add a user to a group */
- if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
+ if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
pdb_free_sam(&sam_user);
return NT_STATUS_NO_SUCH_USER;
}
@@ -3461,7 +3502,7 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE
return NT_STATUS_NO_SUCH_ALIAS;
}
- if( !get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
+ if( !get_local_group_from_sid(alias_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
if ((grp=getgrgid(map.gid)) == NULL)
@@ -3531,7 +3572,7 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
DEBUG(10, ("lookup on Domain SID\n"));
- if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
+ if(!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
sid_copy(&user_sid, get_global_sam_sid());
@@ -3549,7 +3590,7 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
}
/* check a real user exist before we run the script to add a user to a group */
- if (NT_STATUS_IS_ERR(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
+ if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
pdb_free_sam(&sam_user);
return NT_STATUS_NO_SUCH_USER;
}
@@ -3626,7 +3667,7 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE
sid_copy(&user_sid, get_global_sam_sid());
sid_append_rid(&user_sid, q_u->rid);
- if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
+ if (!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
if ((grp=getgrgid(map.gid)) == NULL)
@@ -3771,7 +3812,7 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S
DEBUG(10, ("lookup on Domain SID\n"));
- if(!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
+ if(!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
gid=map.gid;
@@ -3833,7 +3874,7 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S
DEBUG(10, ("lookup on Local SID\n"));
- if(!get_local_group_from_sid(alias_sid, &map, MAPPING_WITHOUT_PRIV))
+ if(!get_local_group_from_sid(alias_sid, &map))
return NT_STATUS_NO_SUCH_ALIAS;
gid=map.gid;
@@ -3870,12 +3911,9 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
fstring sid_string;
struct group *grp;
struct samr_info *info;
- PRIVILEGE_SET priv_set;
uint32 acc_granted;
gid_t gid;
- init_privilege(&priv_set);
-
/* Find the policy handle. Open a policy on it. */
if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
return NT_STATUS_INVALID_HANDLE;
@@ -3910,7 +3948,7 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
sid_append_rid(&info_sid, r_u->rid);
sid_to_string(sid_string, &info_sid);
- if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
+ if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
return NT_STATUS_ACCESS_DENIED;
if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
@@ -3935,12 +3973,9 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
fstring sid_string;
struct group *grp;
struct samr_info *info;
- PRIVILEGE_SET priv_set;
uint32 acc_granted;
gid_t gid;
- init_privilege(&priv_set);
-
/* Find the policy handle. Open a policy on it. */
if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
return NT_STATUS_INVALID_HANDLE;
@@ -3975,7 +4010,7 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
sid_to_string(sid_string, &info_sid);
/* add the group to the mapping table */
- if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL, priv_set, PR_ACCESS_FROM_NETWORK))
+ if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
return NT_STATUS_ACCESS_DENIED;
if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
@@ -4011,7 +4046,7 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM
return r_u->status;
}
- if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITHOUT_PRIV))
+ if (!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_INVALID_HANDLE;
ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
@@ -4063,7 +4098,7 @@ NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_
return r_u->status;
}
- if (!get_domain_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
+ if (!get_domain_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
ctr=q_u->ctr;
@@ -4076,17 +4111,13 @@ NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_
unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
break;
default:
- free_privilege(&map.priv_set);
return NT_STATUS_INVALID_INFO_CLASS;
}
if(!pdb_update_group_mapping_entry(&map)) {
- free_privilege(&map.priv_set);
return NT_STATUS_NO_SUCH_GROUP;
}
- free_privilege(&map.priv_set);
-
return NT_STATUS_OK;
}
@@ -4110,7 +4141,7 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_
return r_u->status;
}
- if (!get_local_group_from_sid(group_sid, &map, MAPPING_WITH_PRIV))
+ if (!get_local_group_from_sid(group_sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
ctr=&q_u->ctr;
@@ -4120,17 +4151,13 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_
unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
break;
default:
- free_privilege(&map.priv_set);
return NT_STATUS_INVALID_INFO_CLASS;
}
if(!pdb_update_group_mapping_entry(&map)) {
- free_privilege(&map.priv_set);
return NT_STATUS_NO_SUCH_GROUP;
}
- free_privilege(&map.priv_set);
-
return NT_STATUS_OK;
}
@@ -4205,7 +4232,7 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G
DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
/* check if that group really exists */
- if (!get_domain_group_from_sid(info->sid, &map, MAPPING_WITHOUT_PRIV))
+ if (!get_domain_group_from_sid(info->sid, &map))
return NT_STATUS_NO_SUCH_GROUP;
/* get a (unique) handle. open a policy on it. */
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 92b1481ab82..217d2cbaea1 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -4330,7 +4330,7 @@ static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p
GUID guid;
if (is_printer_published(print_hnd, snum, &guid)) {
- asprintf(&guid_str, "{%s}", uuid_string_static(guid));
+ asprintf(&guid_str, "{%s}", smb_uuid_string_static(guid));
strupper(guid_str);
init_unistr(&printer->guid, guid_str);
printer->action = SPOOL_DS_PUBLISH;
diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c
index c43eb22375e..03e53118a89 100644
--- a/source/rpc_server/srv_util.c
+++ b/source/rpc_server/srv_util.c
@@ -129,7 +129,7 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui
fstrcpy(user_name, pdb_get_username(sam_pass));
grid=pdb_get_group_rid(sam_pass);
- if (NT_STATUS_IS_ERR(sid_to_gid(pdb_get_group_sid(sam_pass), &gid))) {
+ if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sam_pass), &gid))) {
/* this should never happen */
DEBUG(2,("get_alias_user_groups: sid_to_gid failed!\n"));
pdb_free_sam(&sam_pass);
@@ -147,14 +147,17 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui
return NT_STATUS_UNSUCCESSFUL;
}
+ become_root();
+
for (i=0;i<num_groups;i++) {
- if(!get_group_from_gid(groups[i], &map, MAPPING_WITHOUT_PRIV)) {
+
+ if (!get_group_from_gid(groups[i], &map)) {
DEBUG(10,("get_alias_user_groups: gid %d. not found\n", (int)groups[i]));
continue;
}
/* if it's not an alias, continue */
- if (map.sid_name_use!=SID_NAME_ALIAS) {
+ if (map.sid_name_use != SID_NAME_ALIAS) {
DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name));
continue;
}
@@ -194,6 +197,8 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui
break;
}
+ unbecome_root();
+
if(num_groups) free(groups);
/* now check for the user's gid (the primary group rid) */
@@ -208,11 +213,15 @@ NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, ui
DEBUG(10,("get_alias_user_groups: looking for gid %d of user %s\n", (int)gid, user_name));
- if(!get_group_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) {
+ become_root();
+
+ if(!get_group_from_gid(gid, &map)) {
DEBUG(0,("get_alias_user_groups: gid of user %s doesn't exist. Check your /etc/passwd and /etc/group files\n", user_name));
goto done;
}
+ unbecome_root();
+
/* the primary group isn't an alias */
if (map.sid_name_use!=SID_NAME_ALIAS) {
DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name));
@@ -280,11 +289,17 @@ BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SA
DEBUG(10,("get_domain_user_groups: searching domain groups [%s] is a member of\n", user_name));
+ /* we must wrap this is become/unbecome root for ldap backends */
+ become_root();
+
/* first get the list of the domain groups */
- if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV))
+ if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, &num_entries, ENUM_ONLY_MAPPED))
return False;
DEBUG(10,("get_domain_user_groups: there are %d mapped groups\n", num_entries));
+ unbecome_root();
+ /* end wrapper for group enumeration */
+
/*
* alloc memory. In the worse case, we alloc memory for nothing.
* but I prefer to alloc for nothing
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index e4ff06a35ec..96a4b890aed 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -487,7 +487,7 @@ static WERROR cmd_spoolss_setprinter(struct cli_state *cli,
/* get a printer handle */
result = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
- MAXIMUM_ALLOWED_ACCESS, servername,
+ PRINTER_ALL_ACCESS, servername,
user, &pol);
if (!W_ERROR_IS_OK(result))
diff --git a/source/sam/idmap.c b/source/sam/idmap.c
index d031c49e257..a8c47ab9ae5 100644
--- a/source/sam/idmap.c
+++ b/source/sam/idmap.c
@@ -4,6 +4,7 @@
Copyright (C) Tim Potter 2000
Copyright (C) Anthony Liguori <aliguor@us.ibm.com> 2003
Copyright (C) Simo Sorce 2003
+ Copyright (C) Jeremy Allison 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
@@ -32,37 +33,37 @@ struct idmap_function_entry {
static struct idmap_function_entry *backends = NULL;
-static struct idmap_methods *local_map;
+static struct idmap_methods *cache_map;
static struct idmap_methods *remote_map;
-static void lazy_initialize_idmap(void)
-{
- static BOOL initialized = False;
-
- if(!initialized) {
- idmap_init();
- initialized = True;
- }
-}
+/**********************************************************************
+ Get idmap methods. Don't allow tdb to be a remote method.
+**********************************************************************/
-static struct idmap_methods *get_methods(const char *name)
+static struct idmap_methods *get_methods(const char *name, BOOL cache_method)
{
struct idmap_function_entry *entry = backends;
- while(entry) {
- if (strcmp(entry->name, name) == 0) return entry->methods;
- entry = entry->next;
+ for(entry = backends; entry; entry = entry->next) {
+ if (!cache_method && strequal(entry->name, "tdb"))
+ continue; /* tdb is only cache method. */
+ if (strequal(entry->name, name))
+ return entry->methods;
}
return NULL;
}
+/**********************************************************************
+ Allow a module to register itself as a method.
+**********************************************************************/
+
NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods *methods)
{
struct idmap_function_entry *entry;
if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
- DEBUG(0, ("Failed to register idmap module.\n"
+ DEBUG(0, ("smb_register_idmap: Failed to register idmap module.\n"
"The module was compiled against SMB_IDMAP_INTERFACE_VERSION %d,\n"
"current SMB_IDMAP_INTERFACE_VERSION is %d.\n"
"Please recompile against the current version of samba!\n",
@@ -71,12 +72,12 @@ NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods
}
if (!name || !name[0] || !methods) {
- DEBUG(0,("smb_register_idmap() called with NULL pointer or empty name!\n"));
+ DEBUG(0,("smb_register_idmap: called with NULL pointer or empty name!\n"));
return NT_STATUS_INVALID_PARAMETER;
}
- if (get_methods(name)) {
- DEBUG(0,("idmap module %s already registered!\n", name));
+ if (get_methods(name, False)) {
+ DEBUG(0,("smb_register_idmap: idmap module %s already registered!\n", name));
return NT_STATUS_OBJECT_NAME_COLLISION;
}
@@ -85,171 +86,203 @@ NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods
entry->methods = methods;
DLIST_ADD(backends, entry);
- DEBUG(5, ("Successfully added idmap backend '%s'\n", name));
+ DEBUG(5, ("smb_register_idmap: Successfully added idmap backend '%s'\n", name));
return NT_STATUS_OK;
}
-/* Initialize backend */
-BOOL idmap_init(void)
-{
- const char *remote_backend = lp_idmap_backend();
+/**********************************************************************
+ Initialise idmap cache and a remote backend (if configured).
+**********************************************************************/
+BOOL idmap_init(const char *remote_backend)
+{
if (!backends)
static_init_idmap;
- if (!local_map) {
- local_map = get_methods("tdb");
+ if (!cache_map) {
+ cache_map = get_methods("tdb", True);
- if (!local_map) {
- DEBUG(0, ("idmap_init: could not find tdb backend!\n"));
+ if (!cache_map) {
+ DEBUG(0, ("idmap_init: could not find tdb cache backend!\n"));
return False;
}
- if (NT_STATUS_IS_ERR(local_map->init( NULL ))) {
- DEBUG(0, ("idmap_init: could not load or create local backend!\n"));
+ if (!NT_STATUS_IS_OK(cache_map->init( NULL ))) {
+ DEBUG(0, ("idmap_init: could not initialise tdb cache backend!\n"));
return False;
}
}
if (!remote_map && remote_backend && *remote_backend != 0) {
+ char *rem_backend = smb_xstrdup(remote_backend);
fstring params = "";
char *pparams;
/* get any mode parameters passed in */
- if ( (pparams = strchr( remote_backend, ':' )) != NULL ) {
- pparams = '\0';
+ if ( (pparams = strchr( rem_backend, ':' )) != NULL ) {
+ *pparams = '\0';
pparams++;
fstrcpy( params, pparams );
}
- DEBUG(3, ("idmap_init: using '%s' as remote backend\n", remote_backend));
+ DEBUG(3, ("idmap_init: using '%s' as remote backend\n", rem_backend));
- if((remote_map = get_methods(remote_backend)) ||
- (NT_STATUS_IS_OK(smb_probe_module("idmap", remote_backend)) &&
- (remote_map = get_methods(remote_backend)))) {
+ if((remote_map = get_methods(rem_backend, False)) ||
+ (NT_STATUS_IS_OK(smb_probe_module("idmap", rem_backend)) &&
+ (remote_map = get_methods(rem_backend, False)))) {
remote_map->init(params);
} else {
- DEBUG(0, ("idmap_init: could not load remote backend '%s'\n", remote_backend));
+ DEBUG(0, ("idmap_init: could not load remote backend '%s'\n", rem_backend));
+ SAFE_FREE(rem_backend);
return False;
}
-
+ SAFE_FREE(rem_backend);
}
return True;
}
+/**************************************************************************
+ This is a rare operation, designed to allow an explicit mapping to be
+ set up for a sid to a POSIX id.
+**************************************************************************/
+
NTSTATUS idmap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
{
- NTSTATUS ret;
-
- lazy_initialize_idmap();
-
- ret = local_map->set_mapping(sid, id, id_type);
- if (NT_STATUS_IS_ERR(ret)) {
- DEBUG (0, ("idmap_set_mapping: Error, unable to modify local cache!\n"));
- DEBUGADD(0, ("Error: %s", nt_errstr(ret)));
- return ret;
+ struct idmap_methods *map = remote_map;
+ DOM_SID tmp_sid;
+
+ DEBUG(10, ("idmap_set_mapping: Set %s to %s %d\n",
+ sid_string_static(sid),
+ ((id_type & ID_TYPEMASK) == ID_USERID) ? "UID" : "GID",
+ ((id_type & ID_TYPEMASK) == ID_USERID) ? id.uid : id.gid));
+
+ if ( (NT_STATUS_IS_OK(cache_map->
+ get_sid_from_id(&tmp_sid, id,
+ id_type | ID_QUERY_ONLY))) &&
+ sid_equal(sid, &tmp_sid) ) {
+ /* Nothing to do, we already have that mapping */
+ DEBUG(10, ("idmap_set_mapping: Mapping already there\n"));
+ return NT_STATUS_OK;
}
- /* Being able to update the remote cache is seldomly right.
- Generally this is a forbidden operation. */
- if (!(id_type & ID_CACHE) && (remote_map != NULL)) {
- remote_map->set_mapping(sid, id, id_type);
- if (NT_STATUS_IS_ERR(ret)) {
- DEBUG (0, ("idmap_set_mapping: Error, unable to modify remote cache!\n"));
- DEBUGADD(0, ("Error: %s", nt_errstr(ret)));
- }
+ if (map == NULL) {
+ /* Ok, we don't have a authoritative remote
+ mapping. So update our local cache only. */
+ map = cache_map;
}
- return ret;
+ return map->set_mapping(sid, id, id_type);
}
-/* Get ID from SID */
+/**************************************************************************
+ Get ID from SID. This can create a mapping for a SID to a POSIX id.
+**************************************************************************/
+
NTSTATUS idmap_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
{
NTSTATUS ret;
int loc_type;
- lazy_initialize_idmap();
-
loc_type = *id_type;
- if (remote_map) { /* We have a central remote idmap */
- loc_type |= ID_NOMAP;
+
+ if (remote_map) {
+ /* We have a central remote idmap so only look in
+ cache, don't allocate */
+ loc_type |= ID_QUERY_ONLY;
}
- ret = local_map->get_id_from_sid(id, &loc_type, sid);
- if (NT_STATUS_IS_ERR(ret)) {
- if (remote_map) {
- ret = remote_map->get_id_from_sid(id, id_type, sid);
- if (NT_STATUS_IS_ERR(ret)) {
- DEBUG(3, ("idmap_get_id_from_sid: error fetching id!\n"));
- return ret;
- } else {
- loc_type |= ID_CACHE;
- idmap_set_mapping(sid, *id, loc_type);
- }
- }
- } else {
+
+ ret = cache_map->get_id_from_sid(id, &loc_type, sid);
+
+ if (NT_STATUS_IS_OK(ret)) {
*id_type = loc_type & ID_TYPEMASK;
+ return NT_STATUS_OK;
+ }
+
+ if (remote_map == NULL) {
+ return ret;
+ }
+
+ /* Ok, the mapping was not in the cache, give the remote map a
+ second try. */
+
+ ret = remote_map->get_id_from_sid(id, id_type, sid);
+
+ if (NT_STATUS_IS_OK(ret)) {
+ /* The remote backend gave us a valid mapping, cache it. */
+ ret = cache_map->set_mapping(sid, *id, *id_type);
}
return ret;
}
-/* Get SID from ID */
+/**************************************************************************
+ Get SID from ID. This must have been created before.
+**************************************************************************/
+
NTSTATUS idmap_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
{
NTSTATUS ret;
int loc_type;
- lazy_initialize_idmap();
-
loc_type = id_type;
if (remote_map) {
- loc_type = id_type | ID_NOMAP;
+ loc_type = id_type | ID_QUERY_ONLY;
}
- ret = local_map->get_sid_from_id(sid, id, loc_type);
- if (NT_STATUS_IS_ERR(ret)) {
- if (remote_map) {
- ret = remote_map->get_sid_from_id(sid, id, id_type);
- if (NT_STATUS_IS_ERR(ret)) {
- DEBUG(3, ("idmap_get_sid_from_id: unable to fetch sid!\n"));
- return ret;
- } else {
- loc_type |= ID_CACHE;
- idmap_set_mapping(sid, id, loc_type);
- }
- }
+
+ ret = cache_map->get_sid_from_id(sid, id, loc_type);
+
+ if (NT_STATUS_IS_OK(ret))
+ return ret;
+
+ if (remote_map == NULL)
+ return ret;
+
+ /* We have a second chance, ask our authoritative backend */
+
+ ret = remote_map->get_sid_from_id(sid, id, id_type);
+
+ if (NT_STATUS_IS_OK(ret)) {
+ /* The remote backend gave us a valid mapping, cache it. */
+ ret = cache_map->set_mapping(sid, id, id_type);
}
return ret;
}
-/* Close backend */
+/**************************************************************************
+ Shutdown maps.
+**************************************************************************/
+
NTSTATUS idmap_close(void)
{
NTSTATUS ret;
- ret = local_map->close();
- if (NT_STATUS_IS_ERR(ret)) {
- DEBUG(3, ("idmap_close: failed to close local cache!\n"));
+ ret = cache_map->close();
+ if (!NT_STATUS_IS_OK(ret)) {
+ DEBUG(3, ("idmap_close: failed to close local tdb cache!\n"));
}
+ cache_map = NULL;
if (remote_map) {
ret = remote_map->close();
- if (NT_STATUS_IS_ERR(ret)) {
+ if (!NT_STATUS_IS_OK(ret)) {
DEBUG(3, ("idmap_close: failed to close remote idmap repository!\n"));
}
+ remote_map = NULL;
}
return ret;
}
-/* Dump backend status */
+/**************************************************************************
+ Dump backend status.
+**************************************************************************/
+
void idmap_status(void)
{
- lazy_initialize_idmap();
-
- local_map->status();
- if (remote_map) remote_map->status();
+ cache_map->status();
+ if (remote_map)
+ remote_map->status();
}
diff --git a/source/sam/idmap_ldap.c b/source/sam/idmap_ldap.c
index 379f7729abb..b31ce18925c 100644
--- a/source/sam/idmap_ldap.c
+++ b/source/sam/idmap_ldap.c
@@ -575,8 +575,8 @@ static NTSTATUS ldap_allocate_id(unid_t *id, int id_type)
snprintf(new_id_str, sizeof(new_id_str), "%u",
((id_type & ID_USERID) ? id->uid : id->gid) + 1);
- ldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str );
- ldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str );
+ smbldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str );
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str );
rc = ldap_modify_s(ldap_state.ldap_struct, dn, mods);
@@ -829,9 +829,9 @@ static NTSTATUS ldap_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
snprintf(id_str, sizeof(id_str), "%u", ((id_type & ID_USERID) ? id.uid : id.gid));
sid_to_string( sid_str, sid );
- ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY );
- ldap_set_mod( &mods, LDAP_MOD_ADD, type, id_str );
- ldap_set_mod( &mods, LDAP_MOD_ADD,
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDMAP_ENTRY );
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, type, id_str );
+ smbldap_set_mod( &mods, LDAP_MOD_ADD,
get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), sid_str );
do {
@@ -910,10 +910,10 @@ static NTSTATUS ldap_idmap_init( char *params )
snprintf( uid_str, sizeof(uid_str), "%d", luid );
snprintf( gid_str, sizeof(gid_str), "%d", lgid );
- ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDPOOL );
- ldap_set_mod( &mods, LDAP_MOD_ADD,
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_IDPOOL );
+ smbldap_set_mod( &mods, LDAP_MOD_ADD,
get_attr_key2string(idpool_attr_list, LDAP_ATTR_UIDNUMBER), uid_str );
- ldap_set_mod( &mods, LDAP_MOD_ADD,
+ smbldap_set_mod( &mods, LDAP_MOD_ADD,
get_attr_key2string(idpool_attr_list, LDAP_ATTR_GIDNUMBER), gid_str );
do {
@@ -931,15 +931,15 @@ static NTSTATUS ldap_idmap_init( char *params )
mods = NULL;
snprintf( dn, sizeof(dn), "%s,%s", IDMAP_USER_SUFFIX, lp_ldap_idmap_suffix() );
- ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU );
- ldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap people" );
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU );
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap people" );
ldap_add_s(ldap_state.ldap_struct, dn, mods);
ldap_mods_free( mods, True );
mods = NULL;
snprintf( dn, sizeof(dn), "%s,%s", IDMAP_GROUP_SUFFIX, lp_ldap_idmap_suffix() );
- ldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU );
- ldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap group" );
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_OU );
+ smbldap_set_mod( &mods, LDAP_MOD_ADD, "ou", "idmap group" );
ldap_add_s(ldap_state.ldap_struct, dn, mods);
ldap_mods_free( mods, True );
#endif
diff --git a/source/sam/idmap_tdb.c b/source/sam/idmap_tdb.c
index 278269e8198..18a082cb848 100644
--- a/source/sam/idmap_tdb.c
+++ b/source/sam/idmap_tdb.c
@@ -48,41 +48,71 @@ static struct idmap_state {
/* Allocate either a user or group id from the pool */
static NTSTATUS db_allocate_id(unid_t *id, int id_type)
{
+ BOOL ret;
int hwm;
- if (!id) return NT_STATUS_INVALID_PARAMETER;
+ if (!id)
+ return NT_STATUS_INVALID_PARAMETER;
/* Get current high water mark */
switch (id_type & ID_TYPEMASK) {
case ID_USERID:
+
if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) {
return NT_STATUS_INTERNAL_DB_ERROR;
}
+ /* 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));
return NT_STATUS_UNSUCCESSFUL;
}
- (*id).uid = hwm++;
+ /* fetch a new id and increment it */
+ ret = tdb_change_uint32_atomic(idmap_tdb, HWM_USER, &hwm, 1);
+ if (!ret) {
+ DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* 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));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ (*id).uid = hwm;
+ DEBUG(10,("db_allocate_id: ID_USERID (*id).uid = %d\n", (unsigned int)hwm));
- /* Store new high water mark */
- tdb_store_int32(idmap_tdb, HWM_USER, hwm);
break;
case ID_GROUPID:
if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) {
return NT_STATUS_INTERNAL_DB_ERROR;
}
+ /* 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));
return NT_STATUS_UNSUCCESSFUL;
}
- (*id).gid = hwm++;
+ /* fetch a new id and increment it */
+ ret = tdb_change_uint32_atomic(idmap_tdb, HWM_GROUP, &hwm, 1);
+
+ if (!ret) {
+ DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* 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));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ (*id).gid = hwm;
+ DEBUG(10,("db_allocate_id: ID_GROUPID (*id).uid = %d\n", (unsigned int)hwm));
- /* Store new high water mark */
- tdb_store_int32(idmap_tdb, HWM_GROUP, hwm);
break;
default:
return NT_STATUS_INVALID_PARAMETER;
@@ -92,13 +122,14 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type)
}
/* Get a sid from an id */
-static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
+static NTSTATUS internal_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
{
TDB_DATA key, data;
fstring keystr;
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
- if (!sid) return NT_STATUS_INVALID_PARAMETER;
+ if (!sid)
+ return NT_STATUS_INVALID_PARAMETER;
switch (id_type & ID_TYPEMASK) {
case ID_USERID:
@@ -114,10 +145,13 @@ static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
+ DEBUG(10,("internal_get_sid_from_id: fetching record %s\n", keystr ));
+
data = tdb_fetch(idmap_tdb, key);
if (data.dptr) {
if (string_to_sid(sid, data.dptr)) {
+ DEBUG(10,("internal_get_sid_from_id: fetching record %s -> %s\n", keystr, data.dptr ));
ret = NT_STATUS_OK;
}
SAFE_FREE(data.dptr);
@@ -126,14 +160,15 @@ static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
return ret;
}
-/* Get an id from a sid */
-static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
+/* Error codes for get_id_from_sid */
+enum getidfromsiderr { GET_ID_FROM_SID_OK = 0, GET_ID_FROM_SID_NOTFOUND, GET_ID_FROM_SID_WRONG_TYPE, GET_ID_FROM_SID_ERR };
+
+static enum getidfromsiderr internal_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
{
- TDB_DATA data, key;
+ enum getidfromsiderr ret = GET_ID_FROM_SID_ERR;
fstring keystr;
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if (!sid || !id || !id_type) return NT_STATUS_INVALID_PARAMETER;
+ TDB_DATA key, data;
+ int type = *id_type & ID_TYPEMASK;
/* Check if sid is present in database */
sid_to_string(keystr, sid);
@@ -141,71 +176,186 @@ static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
+ DEBUG(10,("internal_get_id_from_sid: fetching record %s of type 0x%x\n", keystr, type ));
+
data = tdb_fetch(idmap_tdb, key);
+ if (!data.dptr) {
+ DEBUG(10,("internal_get_id_from_sid: record %s not found\n", keystr ));
+ return GET_ID_FROM_SID_NOTFOUND;
+ } else {
+ DEBUG(10,("internal_get_id_from_sid: record %s -> %s\n", keystr, data.dptr ));
+ }
- if (data.dptr) {
- int type = *id_type & ID_TYPEMASK;
+ if (type == ID_EMPTY || type == ID_USERID) {
+ fstring scanstr;
+ /* Parse and return existing uid */
+ fstrcpy(scanstr, "UID %d");
+
+ if (sscanf(data.dptr, scanstr, &((*id).uid)) == 1) {
+ /* uid ok? */
+ if (type == ID_EMPTY) {
+ *id_type = ID_USERID;
+ }
+ DEBUG(10,("internal_get_id_from_sid: %s fetching record %s -> %s \n",
+ (type == ID_EMPTY) ? "ID_EMPTY" : "ID_USERID",
+ keystr, data.dptr ));
+ ret = GET_ID_FROM_SID_OK;
+ } else {
+ ret = GET_ID_FROM_SID_WRONG_TYPE;
+ }
+ }
+
+ if ((ret != GET_ID_FROM_SID_OK) && (type == ID_EMPTY || type == ID_GROUPID)) {
fstring scanstr;
+ /* Parse and return existing gid */
+ fstrcpy(scanstr, "GID %d");
+
+ if (sscanf(data.dptr, scanstr, &((*id).gid)) == 1) {
+ /* gid ok? */
+ if (type == ID_EMPTY) {
+ *id_type = ID_GROUPID;
+ }
+ DEBUG(10,("internal_get_id_from_sid: %s fetching record %s -> %s \n",
+ (type == ID_EMPTY) ? "ID_EMPTY" : "ID_GROUPID",
+ keystr, data.dptr ));
+ ret = GET_ID_FROM_SID_OK;
+ } else {
+ ret = GET_ID_FROM_SID_WRONG_TYPE;
+ }
+ }
+
+ SAFE_FREE(data.dptr);
- if (type == ID_EMPTY || type == ID_USERID) {
- /* Parse and return existing uid */
- fstrcpy(scanstr, "UID %d");
+ return ret;
+}
- if (sscanf(data.dptr, scanstr, &((*id).uid)) == 1) {
- /* uid ok? */
- if (type == ID_EMPTY) {
- *id_type = ID_USERID;
- }
- ret = NT_STATUS_OK;
- goto idok;
- }
+/* Get a sid from an id */
+static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type_in)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ enum getidfromsiderr iderr;
+ int id_type = id_type_in & ID_TYPEMASK;
+ unid_t id_tmp = id;
+ int id_type_tmp = id_type;
+
+ DEBUG(10,("db_get_sid_from_id: id_type_in = 0x%x\n", id_type_in));
+
+ ret = internal_get_sid_from_id(sid, id, id_type);
+ if (!NT_STATUS_IS_OK(ret)) {
+ return ret;
+ }
+
+ iderr = internal_get_id_from_sid(&id_tmp, &id_type_tmp, sid);
+ if (iderr != GET_ID_FROM_SID_OK) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ if (id_type_tmp != id_type) {
+ return NT_STATUS_UNSUCCESSFUL;
+ } else if (id_type == ID_USERID) {
+ if (id_tmp.uid != id.uid) {
+ return NT_STATUS_UNSUCCESSFUL;
}
+ } else if (id_type == ID_GROUPID) {
+ if (id_tmp.gid != id.gid) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ } else {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ return ret;
+}
+/* Get an id from a sid */
+static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+ enum getidfromsiderr iderr;
- if (type == ID_EMPTY || type == ID_GROUPID) {
- /* Parse and return existing gid */
- fstrcpy(scanstr, "GID %d");
+ DEBUG(10,("db_get_id_from_sid\n"));
- if (sscanf(data.dptr, scanstr, &((*id).gid)) == 1) {
- /* gid ok? */
- if (type == ID_EMPTY) {
- *id_type = ID_GROUPID;
- }
- ret = NT_STATUS_OK;
+ if (!sid || !id || !id_type)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ iderr = internal_get_id_from_sid(id, id_type, sid);
+ if (iderr == GET_ID_FROM_SID_OK) {
+ DOM_SID sid_tmp;
+ ret = internal_get_sid_from_id(&sid_tmp, *id, *id_type);
+ if (NT_STATUS_IS_OK(ret)) {
+ if (!sid_equal(&sid_tmp, sid)) {
+ return NT_STATUS_UNSUCCESSFUL;
}
}
-idok:
- SAFE_FREE(data.dptr);
+ } else if (iderr == GET_ID_FROM_SID_WRONG_TYPE) {
+ /* We found a record but not the type we wanted.
+ * This is an error, not an opportunity to overwrite...
+ * JRA.
+ */
+ return NT_STATUS_UNSUCCESSFUL;
+ }
- } else if (!(*id_type & ID_NOMAP) &&
+ if (!(*id_type & ID_QUERY_ONLY) && (iderr != GET_ID_FROM_SID_OK) &&
(((*id_type & ID_TYPEMASK) == ID_USERID)
|| (*id_type & ID_TYPEMASK) == ID_GROUPID)) {
+ TDB_DATA sid_data;
+ TDB_DATA ugid_data;
+ fstring sid_string;
+
+ sid_to_string(sid_string, sid);
+
+ sid_data.dptr = sid_string;
+ sid_data.dsize = strlen(sid_string)+1;
+
+ /* Lock the record for this SID. */
+ if (tdb_chainlock(idmap_tdb, sid_data) != 0) {
+ DEBUG(10,("db_get_id_from_sid: failed to lock record %s. Error %s\n",
+ sid_string, tdb_errorstr(idmap_tdb) ));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
- /* Allocate a new id for this sid */
- ret = db_allocate_id(id, *id_type);
- if (NT_STATUS_IS_OK(ret)) {
- fstring keystr2;
+ do {
+ fstring ugid_str;
+ /* Allocate a new id for this sid */
+ ret = db_allocate_id(id, *id_type);
+ if (!NT_STATUS_IS_OK(ret))
+ break;
+
+ /* Store the UID side */
/* Store new id */
if (*id_type & ID_USERID) {
- slprintf(keystr2, sizeof(keystr2), "UID %d", (*id).uid);
+ slprintf(ugid_str, sizeof(ugid_str), "UID %d", (*id).uid);
} else {
- slprintf(keystr2, sizeof(keystr2), "GID %d", (*id).gid);
+ slprintf(ugid_str, sizeof(ugid_str), "GID %d", (*id).gid);
}
+
+ ugid_data.dptr = ugid_str;
+ ugid_data.dsize = strlen(ugid_str) + 1;
- data.dptr = keystr2;
- data.dsize = strlen(keystr2) + 1;
+ DEBUG(10,("db_get_id_from_sid: storing %s -> %s\n",
+ ugid_data.dptr, sid_data.dptr ));
- if (tdb_store(idmap_tdb, key, data, TDB_REPLACE) == -1) {
- /* TODO: print tdb error !! */
- return NT_STATUS_UNSUCCESSFUL;
+ if (tdb_store(idmap_tdb, ugid_data, sid_data, TDB_INSERT) != -1) {
+ ret = NT_STATUS_OK;
+ break;
}
- if (tdb_store(idmap_tdb, data, key, TDB_REPLACE) == -1) {
+ if (tdb_error(idmap_tdb) != TDB_ERR_EXISTS)
+ DEBUG(10,("db_get_id_from_sid: error %s\n", tdb_errorstr(idmap_tdb) ));
+ ret = NT_STATUS_UNSUCCESSFUL;
+ } while (tdb_error(idmap_tdb) == TDB_ERR_EXISTS);
+
+ if (NT_STATUS_IS_OK(ret)) {
+
+ DEBUG(10,("db_get_id_from_sid: storing %s -> %s\n",
+ sid_data.dptr, ugid_data.dptr ));
+
+ if (tdb_store(idmap_tdb, sid_data, ugid_data, TDB_REPLACE) == -1) {
+ DEBUG(10,("db_get_id_from_sid: error %s\n", tdb_errorstr(idmap_tdb) ));
/* TODO: print tdb error !! */
+ tdb_chainunlock(idmap_tdb, sid_data);
return NT_STATUS_UNSUCCESSFUL;
}
-
- ret = NT_STATUS_OK;
}
+
+ tdb_chainunlock(idmap_tdb, sid_data);
}
return ret;
@@ -217,7 +367,10 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
fstring ksidstr;
fstring kidstr;
- if (!sid) return NT_STATUS_INVALID_PARAMETER;
+ DEBUG(10,("db_set_mapping: id_type = 0x%x\n", id_type));
+
+ if (!sid)
+ return NT_STATUS_INVALID_PARAMETER;
sid_to_string(ksidstr, sid);
@@ -238,31 +391,50 @@ static NTSTATUS db_set_mapping(const DOM_SID *sid, unid_t id, int id_type)
/* *DELETE* prevoius mappings if any.
* This is done both SID and [U|G]ID passed in */
+ /* Lock the record for this SID. */
+ if (tdb_chainlock(idmap_tdb, ksid) != 0) {
+ DEBUG(10,("db_set_mapping: failed to lock record %s. Error %s\n",
+ ksidstr, tdb_errorstr(idmap_tdb) ));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ DEBUG(10,("db_set_mapping: fetching %s\n", ksid.dptr));
+
data = tdb_fetch(idmap_tdb, ksid);
if (data.dptr) {
+ DEBUG(10,("db_set_mapping: deleting %s and %s\n", data.dptr, ksid.dptr ));
tdb_delete(idmap_tdb, data);
tdb_delete(idmap_tdb, ksid);
+ SAFE_FREE(data.dptr);
}
data = tdb_fetch(idmap_tdb, kid);
if (data.dptr) {
+ DEBUG(10,("db_set_mapping: deleting %s and %s\n", data.dptr, kid.dptr ));
tdb_delete(idmap_tdb, data);
tdb_delete(idmap_tdb, kid);
+ SAFE_FREE(data.dptr);
}
if (tdb_store(idmap_tdb, ksid, kid, TDB_INSERT) == -1) {
DEBUG(0, ("idb_set_mapping: tdb_store 1 error: %s\n", tdb_errorstr(idmap_tdb)));
+ tdb_chainunlock(idmap_tdb, ksid);
return NT_STATUS_UNSUCCESSFUL;
}
if (tdb_store(idmap_tdb, kid, ksid, TDB_INSERT) == -1) {
DEBUG(0, ("idb_set_mapping: tdb_store 2 error: %s\n", tdb_errorstr(idmap_tdb)));
+ tdb_chainunlock(idmap_tdb, ksid);
return NT_STATUS_UNSUCCESSFUL;
}
+
+ tdb_chainunlock(idmap_tdb, ksid);
+ DEBUG(10,("db_set_mapping: stored %s -> %s and %s -> %s\n", ksid.dptr, kid.dptr, kid.dptr, ksid.dptr ));
return NT_STATUS_OK;
}
/*****************************************************************************
Initialise idmap database.
*****************************************************************************/
+
static NTSTATUS db_idmap_init( char *params )
{
SMB_STRUCT_STAT stbuf;
@@ -271,30 +443,22 @@ static NTSTATUS db_idmap_init( char *params )
BOOL tdb_is_new = False;
/* use the old database if present */
- if (!file_exist(lock_path("idmap.tdb"), &stbuf)) {
- if (file_exist(lock_path("winbindd_idmap.tdb"), &stbuf)) {
- DEBUG(0, ("idmap_init: using winbindd_idmap.tdb file!\n"));
- tdbfile = strdup(lock_path("winbindd_idmap.tdb"));
- if (!tdbfile) {
- DEBUG(0, ("idmap_init: out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
- } else {
- tdb_is_new = True;
- }
- }
+ tdbfile = strdup(lock_path("winbindd_idmap.tdb"));
if (!tdbfile) {
- tdbfile = strdup(lock_path("idmap.tdb"));
- if (!tdbfile) {
- DEBUG(0, ("idmap_init: out of memory!\n"));
- return NT_STATUS_NO_MEMORY;
- }
+ DEBUG(0, ("idmap_init: out of memory!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!file_exist(tdbfile, &stbuf)) {
+ tdb_is_new = True;
}
- /* Open tdb cache */
+ DEBUG(10,("db_idmap_init: Opening tdbfile %s\n", tdbfile ));
+
+ /* Open idmap repository */
if (!(idmap_tdb = tdb_open_log(tdbfile, 0,
TDB_DEFAULT, O_RDWR | O_CREAT,
- 0600))) {
+ 0644))) {
DEBUG(0, ("idmap_init: Unable to open idmap database\n"));
SAFE_FREE(tdbfile);
return NT_STATUS_UNSUCCESSFUL;
@@ -302,16 +466,20 @@ static NTSTATUS db_idmap_init( char *params )
SAFE_FREE(tdbfile);
- /* check against earlier versions */
if (tdb_is_new) {
- /* TODO: delete the file if this fail */
+ /* the file didn't existed before opening it, let's
+ * store idmap version as nobody else yet opened and
+ * stored it. I do not like this method but didn't
+ * found a way to understand if an opened tdb have
+ * been just created or not --- SSS */
tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION);
- } else {
- version = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");
- if (version != IDMAP_VERSION) {
- DEBUG(0, ("idmap_init: Unable to open idmap database, it's in an old format!\n"));
- return NT_STATUS_INTERNAL_DB_ERROR;
- }
+ }
+
+ /* check against earlier versions */
+ version = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");
+ if (version != IDMAP_VERSION) {
+ DEBUG(0, ("idmap_init: Unable to open idmap database, it's in an old format!\n"));
+ return NT_STATUS_INTERNAL_DB_ERROR;
}
/* Create high water marks for group and user id */
diff --git a/source/sam/idmap_util.c b/source/sam/idmap_util.c
index 8c3a3788327..42762e48fad 100644
--- a/source/sam/idmap_util.c
+++ b/source/sam/idmap_util.c
@@ -146,13 +146,13 @@ NTSTATUS uid_to_sid(DOM_SID *sid, uid_t uid)
flags = ID_USERID;
if (!lp_idmap_only() && !idmap_check_ugid_is_in_free_range(uid)) {
- flags |= ID_NOMAP;
+ flags |= ID_QUERY_ONLY;
}
id.uid = uid;
- if (NT_STATUS_IS_ERR(ret = idmap_get_sid_from_id(sid, id, flags))) {
+ if (!NT_STATUS_IS_OK(ret = idmap_get_sid_from_id(sid, id, flags))) {
DEBUG(10, ("uid_to_sid: Failed to map uid = [%u]\n", (unsigned int)uid));
- if (flags & ID_NOMAP) {
+ if (flags & ID_QUERY_ONLY) {
sid_copy(sid, get_global_sam_sid());
sid_append_rid(sid, fallback_pdb_uid_to_user_rid(uid));
@@ -182,13 +182,13 @@ NTSTATUS gid_to_sid(DOM_SID *sid, gid_t gid)
flags = ID_GROUPID;
if (!lp_idmap_only() && !idmap_check_ugid_is_in_free_range(gid)) {
- flags |= ID_NOMAP;
+ flags |= ID_QUERY_ONLY;
}
id.gid = gid;
- if (NT_STATUS_IS_ERR(ret = idmap_get_sid_from_id(sid, id, flags))) {
+ if (!NT_STATUS_IS_OK(ret = idmap_get_sid_from_id(sid, id, flags))) {
DEBUG(10, ("gid_to_sid: Failed to map gid = [%u]\n", (unsigned int)gid));
- if (flags & ID_NOMAP) {
+ if (flags & ID_QUERY_ONLY) {
sid_copy(sid, get_global_sam_sid());
sid_append_rid(sid, pdb_gid_to_group_rid(gid));
@@ -221,17 +221,16 @@ NTSTATUS sid_to_uid(const DOM_SID *sid, uid_t *uid)
flags = ID_USERID;
if (!lp_idmap_only()) {
if (!idmap_check_sid_is_in_free_range(sid)) {
- flags |= ID_NOMAP;
+ flags |= ID_QUERY_ONLY;
fallback = True;
}
}
- if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &flags, sid))) {
+ if (NT_STATUS_IS_OK(ret = idmap_get_id_from_sid(&id, &flags, sid))) {
DEBUG(10,("sid_to_uid: uid = [%d]\n", id.uid));
*uid = id.uid;
- ret = NT_STATUS_OK;
} else if (fallback) {
uint32 rid;
@@ -279,24 +278,22 @@ NTSTATUS sid_to_gid(const DOM_SID *sid, gid_t *gid)
flags = ID_GROUPID;
if (!lp_idmap_only()) {
if (!idmap_check_sid_is_in_free_range(sid)) {
- flags |= ID_NOMAP;
+ flags |= ID_QUERY_ONLY;
fallback = True;
}
}
- if (NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &flags, sid))) {
+ if (NT_STATUS_IS_OK(ret = idmap_get_id_from_sid(&id, &flags, sid))) {
DEBUG(10,("sid_to_gid: gid = [%d]\n", id.gid));
*gid = id.gid;
- ret = NT_STATUS_OK;
} else if (fallback) {
uint32 rid;
if (!sid_peek_rid(sid, &rid)) {
DEBUG(10,("sid_to_uid: invalid SID!\n"));
- ret = NT_STATUS_INVALID_PARAMETER;
- goto done;
+ return NT_STATUS_INVALID_PARAMETER;
}
DEBUG(10,("sid_to_gid: Fall back to algorithmic mapping\n"));
@@ -311,7 +308,6 @@ NTSTATUS sid_to_gid(const DOM_SID *sid, gid_t *gid)
}
}
-done:
return ret;
}
@@ -341,30 +337,31 @@ BOOL idmap_init_wellknown_sids(void)
id.uid = pass->pw_uid;
sid_copy(&sid, get_global_sam_sid());
sid_append_rid(&sid, DOMAIN_USER_RID_GUEST);
- if (NT_STATUS_IS_ERR(idmap_set_mapping(&sid, id, flags))) {
+ if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, flags))) {
passwd_free(&pass);
return False;
}
/* now fill in group mappings */
- if(pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV)) {
+ if(pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED)) {
int i;
for (i = 0; i < num_entries; i++) {
id.gid = map[i].gid;
- idmap_set_mapping(&(map[i].sid), id, ID_GROUPID);
+ idmap_set_mapping(&map[i].sid, id, ID_GROUPID);
}
+ SAFE_FREE(map);
}
/* check if DOMAIN_GROUP_RID_GUESTS SID is set, if not store the
* guest account gid as mapping */
- flags = ID_GROUPID | ID_NOMAP;
+ flags = ID_GROUPID | ID_QUERY_ONLY;
sid_copy(&sid, get_global_sam_sid());
sid_append_rid(&sid, DOMAIN_GROUP_RID_GUESTS);
- if (NT_STATUS_IS_ERR(idmap_get_id_from_sid(&id, &flags, &sid))) {
+ if (!NT_STATUS_IS_OK(idmap_get_id_from_sid(&id, &flags, &sid))) {
flags = ID_GROUPID;
id.gid = pass->pw_gid;
- if (NT_STATUS_IS_ERR(idmap_set_mapping(&sid, id, flags))) {
+ if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, flags))) {
passwd_free(&pass);
return False;
}
diff --git a/source/sam/idmap_winbind.c b/source/sam/idmap_winbind.c
index d15d8f20a15..159071e292d 100644
--- a/source/sam/idmap_winbind.c
+++ b/source/sam/idmap_winbind.c
@@ -46,10 +46,14 @@ static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
case ID_USERID:
request.data.uid = id.uid;
operation = WINBINDD_UID_TO_SID;
+ DEBUG(10,("db_get_sid_from_id: asking winbindd uid %u -> sid\n",
+ (unsigned int)id.uid ));
break;
case ID_GROUPID:
request.data.gid = id.gid;
operation = WINBINDD_GID_TO_SID;
+ DEBUG(10,("db_get_sid_from_id: asking winbindd gid %u -> sid\n",
+ (unsigned int)id.gid ));
break;
default:
return NT_STATUS_INVALID_PARAMETER;
@@ -58,6 +62,7 @@ static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
/* Make The Request */
result = winbindd_request(operation, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
+ DEBUG(10,("db_get_sid_from_id: winbindd replied ok (%s)\n", response.data.sid.sid ));
if (!string_to_sid(sid, response.data.sid.sid)) {
return NT_STATUS_INVALID_SID;
}
@@ -66,6 +71,8 @@ static NTSTATUS db_get_sid_from_id(DOM_SID *sid, unid_t id, int id_type)
sid_copy(sid, &global_sid_NULL);
}
+ DEBUG(10,("db_get_sid_from_id: winbindd lookup fail\n"));
+
return NT_STATUS_UNSUCCESSFUL;
}
@@ -86,32 +93,40 @@ static NTSTATUS db_get_id_from_sid(unid_t *id, int *id_type, const DOM_SID *sid)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
+ sid_to_string(sid_str, sid);
+ fstrcpy(request.data.sid, sid_str);
+
switch (*id_type & ID_TYPEMASK) {
case ID_USERID:
operation = WINBINDD_SID_TO_UID;
+ DEBUG(10,("db_get_id_from_sid: asking winbindd %s -> uid\n",
+ sid_str ));
break;
case ID_GROUPID:
operation = WINBINDD_SID_TO_GID;
+ DEBUG(10,("db_get_id_from_sid: asking winbindd %s -> gid\n",
+ sid_str ));
break;
default:
return NT_STATUS_INVALID_PARAMETER;
}
- sid_to_string(sid_str, sid);
- fstrcpy(request.data.sid, sid_str);
-
/* Make The Request */
result = winbindd_request(operation, &request, &response);
if (result == NSS_STATUS_SUCCESS) {
if (operation == WINBINDD_SID_TO_UID) {
(*id).uid = response.data.uid;
+ DEBUG(10,("db_get_id_from_sid: winbindd replied ok (%u)\n", response.data.uid));
} else {
(*id).gid = response.data.gid;
+ DEBUG(10,("db_get_id_from_sid: winbindd replied ok (%u)\n", response.data.gid ));
}
return NT_STATUS_OK;
}
+ DEBUG(10,("db_get_id_from_sid: winbindd lookup fail\n"));
+
return NT_STATUS_UNSUCCESSFUL;
}
@@ -142,11 +157,9 @@ static struct idmap_methods winbind_methods = {
db_set_mapping,
db_close,
db_status
-
};
NTSTATUS idmap_winbind_init(void)
{
return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "winbind", &winbind_methods);
}
-
diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk
index 919ae2aa7e6..31cbd96474c 100644
--- a/source/script/mkproto.awk
+++ b/source/script/mkproto.awk
@@ -142,7 +142,7 @@ END {
gotstart = 1;
}
- if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^ADS_MODLIST|^PyObject|^SORTED_TREE|^REGISTRY_HOOK|^REGISTRY_VALUE|^DEVICEMODE|^PAC_DATA/ ) {
+ if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T|^ADS_MODLIST|^PyObject|^SORTED_TREE|^REGISTRY_HOOK|^REGISTRY_VALUE|^DEVICEMODE|^PAC_DATA|^NET_USER_INFO_3/ ) {
gotstart = 1;
}
diff --git a/source/smbd/build_options.c b/source/smbd/build_options.c
deleted file mode 100644
index 43335666a63..00000000000
--- a/source/smbd/build_options.c
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Build Options for Samba Suite
- Copyright (C) Vance Lankhaar <vlankhaar@hotmail.com> 2001
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 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
- 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 "build_env.h"
-#include "dynconfig.h"
-
-static void output(BOOL screen, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
-
-/*
-#define OUTPUT(x) snprintf(outstring,sizeof(outstring),x); output(screen,outstring);
-*/
-/****************************************************************************
-helper function for build_options
-****************************************************************************/
-static void output(BOOL screen, const char *format, ...)
-{
- char *ptr;
- va_list ap;
-
- va_start(ap, format);
- vasprintf(&ptr,format,ap);
- va_end(ap);
-
- if (screen) {
- d_printf("%s", ptr);
- } else {
- DEBUG(4,("%s", ptr));
- }
-
- SAFE_FREE(ptr);
-}
-
-/****************************************************************************
-options set at build time for the samba suite
-****************************************************************************/
-void build_options(BOOL screen)
-{
- if ((DEBUGLEVEL < 4) && (!screen)) {
- return;
- }
-
-#ifdef _BUILD_ENV_H
- /* Output information about the build environment */
- output(screen,"Build environment:\n");
- output(screen," Built by: %s@%s\n",BUILD_ENV_USER,BUILD_ENV_HOST);
- output(screen," Built on: %s\n",BUILD_ENV_DATE);
-
- output(screen," Built using: %s\n",BUILD_ENV_COMPILER);
- output(screen," Build host: %s\n",BUILD_ENV_UNAME);
- output(screen," SRCDIR: %s\n",BUILD_ENV_SRCDIR);
- output(screen," BUILDDIR: %s\n",BUILD_ENV_BUILDDIR);
-
-
-#endif
-
- /* Output various options (most correspond to --with options) */
- output(screen,"\nBuild options:\n");
-#ifdef WITH_SMBWRAPPER
- output(screen," WITH_SMBWRAPPER\n");
-#endif
-#ifdef WITH_AFS
- output(screen," WITH_AFS\n");
-#endif
-#ifdef WITH_DFS
- output(screen," WITH_DFS\n");
-#endif
-#ifdef KRB4_AUTH
- output(screen," KRB4_AUTH");
-#endif
-#ifdef HAVE_KRB5
- output(screen," HAVE_KRB5");
-#endif
-#ifdef HAVE_GSSAPI
- output(screen," HAVE_GSSAPI");
-#endif
-#ifdef HAVE_LDAP
- output(screen," HAVE_LDAP");
-#endif
-#ifdef WITH_AUTOMOUNT
- output(screen," WITH_AUTOMOUNT\n");
-#endif
-#ifdef WITH_SMBMOUNT
- output(screen," WITH_SMBMOUNT\n");
-#endif
-#ifdef WITH_PAM
- output(screen," WITH_PAM\n");
-#endif
-#ifdef WITH_NISPLUS_HOME
- output(screen," WITH_NISPLUS_HOME\n");
-#endif
-#ifdef WITH_SYSLOG
- output(screen," WITH_SYSLOG\n");
-#endif
-#ifdef WITH_PROFILE
- output(screen," WITH_PROFILE\n");
-#endif
-#ifdef WITH_QUOTAS
- output(screen," WITH_QUOTAS\n");
-#endif
-#ifdef WITH_VFS
- output(screen," WITH_VFS\n");
-#endif
-#ifdef USE_SPINLOCKS
- output(screen," USE_SPINLOCKS\n");
-#endif
-#ifdef SPARC_SPINLOCKS
- output(screen," SPARC_SPINLOCKS\n");
-#endif
-#ifdef INTEL_SPINLOCKS
- output(screen," INTEL_SPINLOCKS\n");
-#endif
-#ifdef MIPS_SPINLOCKS
- output(screen," MIPS_SPINLOCKS\n");
-#endif
-#ifdef POWERPC_SPINLOCKS
- output(screen," POWERPC_SPINLOCKS\n");
-#endif
-#ifdef HAVE_UNIXWARE_ACLS
- output(screen," HAVE_UNIXWARE_ACLS\n");
-#endif
-#ifdef HAVE_SOLARIS_ACLS
- output(screen," HAVE_SOLARIS_ACLS\n");
-#endif
-#ifdef HAVE_IRIX_ACLS
- output(screen," HAVE_IRIX_ACLS\n");
-#endif
-#ifdef HAVE_AIX_ACLS
- output(screen," HAVE_AIX_ACLS\n");
-#endif
-#ifdef HAVE_POSIX_ACLS
- output(screen," HAVE_POSIX_ACLS\n");
-#endif
-#ifdef HAVE_TRU64_ACLS
- output(screen," HAVE_TRU64_ACLS\n");
-#endif
-
-#ifdef HAVE_ACL_GET_PERM_NP
- output(screen," HAVE_ACL_GET_PERM_NP\n");
-#endif
-#ifdef HAVE_NO_ACLS
- output(screen," HAVE_NO_ACLS\n");
-#endif
-#ifdef HAVE_LIBREADLINE
- output(screen," HAVE_LIBREADLINE\n");
-#endif
-#ifdef WITH_LIBICONV
- output(screen," WITH_LIBICONV: %s\n",WITH_LIBICONV);
-#endif
-
-
- /* Output various paths to files and directories */
- output(screen,"\nPaths:\n");
- output(screen," CONFIGFILE: %s\n", dyn_CONFIGFILE);
-#ifdef PRIVATE_DIR
- output(screen," PRIVATE_DIR: %s\n",PRIVATE_DIR);
-#endif
-#ifdef LMHOSTSFILE
- output(screen," LMHOSTSFILE: %s\n",LMHOSTSFILE);
-#endif
- output(screen," SBINDIR: %s\n", dyn_SBINDIR);
- output(screen," BINDIR: %s\n", dyn_BINDIR);
- output(screen," LOCKDIR: %s\n",dyn_LOCKDIR);
- output(screen," LOGFILEBASE: %s\n", dyn_LOGFILEBASE);
-
- /*Output various other options (most map to defines in the configure script*/
- output(screen,"\nOther Build Options:\n");
-#ifdef HAVE_VOLATILE
- output(screen," HAVE_VOLATILE\n");
-#endif
-#ifdef HAVE_SHADOW_H
- output(screen," HAVE_SHADOW_H\n");
-#endif
-#ifdef HAVE_CRYPT
- output(screen," HAVE_CRYPT\n");
-#endif
-#ifdef USE_BOTH_CRYPT_CALLS
- output(screen," USE_BOTH_CRYPT_CALLS\n");
-#endif
-#ifdef HAVE_TRUNCATED_SALT
- output(screen," HAVE_TRUNCATED_SALT\n");
-#endif
-#ifdef HAVE_CUPS
- output(screen," HAVE_CUPS\n");
-#endif
-#ifdef HAVE_CUPS_CUPS_H
- output(screen," HAVE_CUPS_CUPS_H\n");
-#endif
-#ifdef HAVE_CUPS_LANGUAGE_H
- output(screen," HAVE_CUPS_LANGUAGE_H\n");
-#endif
-#ifdef HAVE_DLOPEN
- output(screen," HAVE_DLOPEN\n");
-#endif
-#ifdef HAVE_DLCLOSE
- output(screen," HAVE_DLCLOSE\n");
-#endif
-#ifdef HAVE_DLSYM
- output(screen," HAVE_DLSYM\n");
-#endif
-#ifdef HAVE_DLERROR
- output(screen," HAVE_DLERROR\n");
-#endif
-#ifdef HAVE_UNIXSOCKET
- output(screen," HAVE_UNIXSOCKET\n");
-#endif
-#ifdef HAVE_SOCKLEN_T_TYPE
- output(screen," HAVE_SOCKLEN_T_TYPE\n");
-#endif
-#ifdef HAVE_SIG_ATOMIC_T_TYPE
- output(screen," HAVE_SIG_ATOMIC_T_TYPE\n");
-#endif
-#ifdef HAVE_SETRESUID
- output(screen," HAVE_SETRESUID\n");
-#endif
-#ifdef HAVE_SETRESGID
- output(screen," HAVE_SETRESGID\n");
-#endif
-#ifdef HAVE_CONNECT
- output(screen," HAVE_CONNECT\n");
-#endif
-#ifdef HAVE_YP_GET_DEFAULT_DOMAIN
- output(screen," HAVE_YP_GET_DEFAULT_DOMAIN\n");
-#endif
-#ifdef HAVE_STAT64
- output(screen," HAVE_STAT64\n");
-#endif
-#ifdef HAVE_LSTAT64
- output(screen," HAVE_LSTAT64\n");
-#endif
-#ifdef HAVE_FSTAT64
- output(screen," HAVE_FSTAT64\n");
-#endif
-#ifdef HAVE_STRCASECMP
- output(screen," HAVE_STRCASECMP\n");
-#endif
-#ifdef HAVE_MEMSET
- output(screen," HAVE_MEMSET\n");
-#endif
-#ifdef HAVE_LONGLONG
- output(screen," HAVE_LONGLONG\n");
-#endif
-#ifdef COMPILER_SUPPORTS_LL
- output(screen," COMPILER_SUPPORTS_LL\n");
-#endif
-#ifdef SIZEOF_OFF_T
- output(screen," SIZEOF_OFF_T: %d\n",SIZEOF_OFF_T);
-#endif
-#ifdef HAVE_OFF64_T
- output(screen," HAVE_OFF64_T\n");
-#endif
-#ifdef SIZEOF_INO_T
- output(screen," SIZEOF_INO_T: %d\n",SIZEOF_INO_T);
-#endif
-#ifdef HAVE_INO64_T
- output(screen," HAVE_INO64_T\n");
-#endif
-#ifdef HAVE_STRUCT_DIRENT64
- output(screen," HAVE_STRUCT_DIRENT64\n");
-#endif
-#ifdef HAVE_UNSIGNED_CHAR
- output(screen," HAVE_UNSIGNED_CHAR\n");
-#endif
-#ifdef HAVE_SOCK_SIN_LEN
- output(screen," HAVE_SOCK_SIN_LEN\n");
-#endif
-#ifdef SEEKDIR_RETURNS_VOID
- output(screen," SEEKDIR_RETURNS_VOID\n");
-#endif
-#ifdef HAVE_FUNCTION_MACRO
- output(screen," HAVE_FUNCTION_MACRO\n");
-#endif
-#ifdef HAVE_GETTIMEOFDAY
- output(screen," HAVE_GETTIMEOFDAY\n");
-#endif
-#ifdef HAVE_C99_VSNPRINTF
- output(screen," HAVE_C99_VSNPRINTF\n");
-#endif
-#ifdef HAVE_BROKEN_READDIR
- output(screen," HAVE_BROKEN_READDIR\n");
-#endif
-#ifdef HAVE_NATIVE_ICONV
- output(screen," HAVE_NATIVE_ICONV\n");
-#endif
-#ifdef HAVE_KERNEL_OPLOCKS_LINUX
- output(screen," HAVE_KERNEL_OPLOCKS_LINUX\n");
-#endif
-#ifdef HAVE_KERNEL_CHANGE_NOTIFY
- output(screen," HAVE_KERNEL_CHANGE_NOTIFY\n");
-#endif
-#ifdef HAVE_KERNEL_SHARE_MODES
- output(screen," HAVE_KERNEL_SHARE_MODES\n");
-#endif
-#ifdef HAVE_KERNEL_OPLOCKS_IRIX
- output(screen," HAVE_KERNEL_OPLOCKS_IRIX\n");
-#endif
-#ifdef HAVE_IRIX_SPECIFIC_CAPABILITIES
- output(screen," HAVE_IRIX_SPECIFIC_CAPABILITIES\n");
-#endif
-#ifdef HAVE_INT16_FROM_RPC_RPC_H
- output(screen," HAVE_INT16_FROM_RPC_RPC_H\n");
-#endif
-#ifdef HAVE_UINT16_FROM_RPC_RPC_H
- output(screen," HAVE_UINT16_FROM_RPC_RPC_H\n");
-#endif
-#ifdef HAVE_INT32_FROM_RPC_RPC_H
- output(screen," HAVE_INT16_FROM_RPC_RPC_H\n");
-#endif
-#ifdef HAVE_UINT32_FROM_RPC_RPC_H
- output(screen," HAVE_UINT32_FROM_RPC_RPC_H\n");
-#endif
-#ifdef HAVE_RPC_AUTH_ERROR_CONFLICT
- output(screen," HAVE_RPC_AUTH_ERROR_CONFLICT\n");
-#endif
-#ifdef HAVE_FTRUNCATE_EXTEND
- output(screen," HAVE_FTRUNCATE_EXTEND\n");
-#endif
-#ifdef HAVE_WORKING_AF_LOCAL
- output(screen," HAVE_WORKING_AF_LOCAL\n");
-#endif
-#ifdef HAVE_BROKEN_GETGROUPS
- output(screen," HAVE_BROKEN_GETGROUPS\n");
-#endif
-#ifdef REPLACE_GETPASS
- output(screen," REPLACE_GETPASS\n");
-#endif
-#ifdef REPLACE_INET_NTOA
- output(screen," REPLACE_INET_NTOA\n");
-#endif
-#ifdef HAVE_SECURE_MKSTEMP
- output(screen," HAVE_SECURE_MKSTEMP\n");
-#endif
-#ifdef SYSCONF_SC_NGROUPS_MAX
- output(screen," SYSCONF_SC_NGROUPS_MAX\n");
-#endif
-#ifdef HAVE_IFACE_AIX
- output(screen," HAVE_IFACE_AIX\n");
-#endif
-#ifdef HAVE_IFACE_IFCONF
- output(screen," HAVE_IFACE_IFCONF\n");
-#endif
-#ifdef HAVE_IFACE_IFREQ
- output(screen," HAVE_IFACE_IFREQ\n");
-#endif
-#ifdef USE_SETRESUID
- output(screen," USE_SETRESUID\n");
-#endif
-#ifdef USE_SETRESGID
- output(screen," USE_SETREUID\n");
-#endif
-#ifdef USE_SETEUID
- output(screen," USE_SETEUID\n");
-#endif
-#ifdef USE_SETUIDX
- output(screen," USE_SETUIDX\n");
-#endif
-#ifdef HAVE_MMAP
- output(screen," HAVE_MMAP\n");
-#endif
-#ifdef MMAP_BLACKLIST
- output(screen," MMAP_BLACKLIST\n");
-#endif
-#ifdef FTRUNCATE_NEEDS_ROOT
- output(screen," FTRUNCATE_NEEDS_ROOT\n");
-#endif
-#ifdef HAVE_FCNTL_LOCK
- output(screen," HAVE_FCNTL_LOCK\n");
-#endif
-#ifdef HAVE_BROKEN_FCNTL64_LOCKS
- output(screen," HAVE_BROKEN_FCNTL64_LOCKS\n");
-#endif
-#ifdef HAVE_STRUCT_FLOCK64
- output(screen," HAVE_STRUCT_FLOCK64\n");
-#endif
-#ifdef BROKEN_NISPLUS_INCLUDE_FILES
- output(screen," BROKEN_NISPLUS_INCLUDE_FILES\n");
-#endif
-#ifdef HAVE_LIBPAM
- output(screen," HAVE_LIBPAM\n");
-#endif
-#ifdef STAT_STATVFS64
- output(screen," STAT_STATVFS64\n");
-#endif
-#ifdef STAT_STATVFS
- output(screen," STAT_STATVFS\n");
-#endif
-#ifdef STAT_STATFS3_OSF1
- output(screen," STAT_STATFS3_OSF1\n");
-#endif
-#ifdef STAT_STATFS2_BSIZE
- output(screen," STAT_STATFS2_BSIZE\n");
-#endif
-#ifdef STAT_STATFS4
- output(screen," STAT_STATFS4\n");
-#endif
-#ifdef STAT_STATFS2_FSIZE
- output(screen," STAT_STATFS2_FSIZE\n");
-#endif
-#ifdef STAT_STATFS2_FS_DATA
- output(screen," STAT_STATFS2_FS_DATA\n");
-#endif
-#ifdef HAVE_EXPLICIT_LARGEFILE_SUPPORT
- output(screen," HAVE_EXPLICIT_LARGEFILE_SUPPORT\n");
-#endif
-
-#ifdef WITH_UTMP
- /* Output UTMP Stuff */
- output(screen,"\nUTMP Related:\n");
- output(screen," WITH_UTMP\n");
-
-#ifdef HAVE_UTIMBUF
- output(screen," HAVE_UTIMBUF\n");
-#endif
-#ifdef HAVE_UT_UT_NAME
- output(screen," HAVE_UT_UT_NAME\n");
-#endif
-#ifdef HAVE_UT_UT_USER
- output(screen," HAVE_UT_UT_USER\n");
-#endif
-#ifdef HAVE_UT_UT_ID
- output(screen," HAVE_UT_UT_ID\n");
-#endif
-#ifdef HAVE_UT_UT_HOST
- output(screen," HAVE_UT_UT_HOST\n");
-#endif
-#ifdef HAVE_UT_UT_TIME
- output(screen," HAVE_UT_UT_TIME\n");
-#endif
-#ifdef HAVE_UT_UT_TV
- output(screen," HAVE_UT_UT_TV\n");
-#endif
-#ifdef HAVE_UT_UT_TYPE
- output(screen," HAVE_UT_UT_TYPE\n");
-#endif
-#ifdef HAVE_UT_UT_PID
- output(screen," HAVE_UT_UT_PID\n");
-#endif
-#ifdef HAVE_UT_UT_EXIT
- output(screen," HAVE_UT_UT_EXIT\n");
-#endif
-#ifdef HAVE_UT_UT_ADDR
- output(screen," HAVE_UT_UT_ADDR\n");
-#endif
-#ifdef PUTUTLINE_RETURNS_UTMP
- output(screen," PUTUTLINE_RETURNS_UTMP\n");
-#endif
-#ifdef HAVE_UX_UT_SYSLEN
- output(screen," HAVE_UX_UT_SYSLEN\n");
-#endif
-#endif /* WITH_UTMP */
-
- /* Output Build OS */
- output(screen,"\nBuilt for host os:\n");
-#ifdef LINUX
- output(screen," LINUX\n");
-#endif
-#ifdef SUNOS5
- output(screen," SUNOS5\n");
-#endif
-#ifdef SUNOS4
- output(screen," SUNOS4\n");
-#endif
- /* BSD Isn't Defined in the configure script, but there is something about it in include/config.h.in (and I guess acconfig.h) */
-#ifdef BSD
- output(screen," BSD\n");
-#endif
-#ifdef IRIX
- output(screen," IRIX\n");
-#endif
-#ifdef IRIX6
- output(screen," IRIX6\n");
-#endif
-#ifdef AIX
- output(screen," AIX\n");
-#endif
-#ifdef HPUX
- output(screen," HPUX\n");
-#endif
-#ifdef QNX
- output(screen," QNX\n");
-#endif
-#ifdef OSF1
- output(screen," OSF1\n");
-#endif
-#ifdef SCO
- output(screen," SCO\n");
-#endif
-#ifdef UNIXWARE
- output(screen," UNIXWARE\n");
-#endif
-#ifdef NEXT2
- output(screen," NEXT2\n");
-#endif
-#ifdef RELIANTUNIX
- output(screen," RELIANTUNIX\n");
-#endif
-
- /* Output the sizes of the various types */
- output(screen,"\nType sizes:\n");
- output(screen," sizeof(char): %d\n",sizeof(char));
- output(screen," sizeof(int): %d\n",sizeof(int));
- output(screen," sizeof(long): %d\n",sizeof(long));
- output(screen," sizeof(uint8): %d\n",sizeof(uint8));
- output(screen," sizeof(uint16): %d\n",sizeof(uint16));
- output(screen," sizeof(uint32): %d\n",sizeof(uint32));
- output(screen," sizeof(short): %d\n",sizeof(short));
- output(screen," sizeof(void*): %d\n",sizeof(void*));
-
- output(screen,"\nBuiltin modules:\n");
- output(screen,"%s\n", STRING_STATIC_MODULES);
-}
-
-
-
diff --git a/source/smbd/change_trust_pw.c b/source/smbd/change_trust_pw.c
index 8aff96d0d6d..4993e285cac 100644
--- a/source/smbd/change_trust_pw.c
+++ b/source/smbd/change_trust_pw.c
@@ -43,7 +43,7 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m
goto failed;
}
- if ( !lookup_dc_name(global_myname(), domain, &pdc_ip, dc_name) )
+ if ( !name_status_find( domain, 0x1b, 0x20, pdc_ip, dc_name) )
goto failed;
}
/* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index 98857c6d320..6976a066846 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -1649,7 +1649,7 @@ static BOOL api_RNetGroupEnum(connection_struct *conn,uint16 vuid, char *param,c
return False;
/* get list of domain groups SID_DOMAIN_GRP=2 */
- if(!pdb_enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False, False)) {
+ if(!pdb_enum_group_mapping(SID_NAME_DOM_GRP , &group_list, &num_entries, False)) {
DEBUG(3,("api_RNetGroupEnum:failed to get group list"));
return False;
}
diff --git a/source/smbd/mangle_hash.c b/source/smbd/mangle_hash.c
index d2eb996899c..d4cf369f287 100644
--- a/source/smbd/mangle_hash.c
+++ b/source/smbd/mangle_hash.c
@@ -217,7 +217,7 @@ static NTSTATUS is_valid_name(const smb_ucs2_t *fname, BOOL allow_wildcards)
return NT_STATUS_UNSUCCESSFUL;
ret = has_valid_chars(fname, allow_wildcards);
- if (NT_STATUS_IS_ERR(ret))
+ if (!NT_STATUS_IS_OK(ret))
return ret;
str = strdup_w(fname);
@@ -285,10 +285,10 @@ static NTSTATUS is_8_3_w(const smb_ucs2_t *fname, BOOL allow_wildcards)
if (strcmp_wa(fname, ".") == 0 || strcmp_wa(fname, "..") == 0)
return NT_STATUS_OK;
- if (NT_STATUS_IS_ERR(is_valid_name(fname, allow_wildcards)))
+ if (!NT_STATUS_IS_OK(is_valid_name(fname, allow_wildcards)))
goto done;
- if (NT_STATUS_IS_ERR(mangle_get_prefix(fname, &pref, &ext, allow_wildcards)))
+ if (!NT_STATUS_IS_OK(mangle_get_prefix(fname, &pref, &ext, allow_wildcards)))
goto done;
plen = strlen_w(pref);
@@ -735,7 +735,7 @@ static void name_map(char *OutName, BOOL need83, BOOL cache83)
return;
}
- if( !need83 && NT_STATUS_IS_ERR(is_valid_name(OutName_ucs2, False)))
+ if( !need83 && !NT_STATUS_IS_OK(is_valid_name(OutName_ucs2, False)))
need83 = True;
/* check if it's already in 8.3 format */
diff --git a/source/smbd/ntquotas.c b/source/smbd/ntquotas.c
index 6a217a32587..2e865000ecc 100644
--- a/source/smbd/ntquotas.c
+++ b/source/smbd/ntquotas.c
@@ -84,7 +84,7 @@ int vfs_get_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid,
id.uid = -1;
- if (psid && NT_STATUS_IS_ERR(sid_to_uid(psid, &id.uid))) {
+ if (psid && !NT_STATUS_IS_OK(sid_to_uid(psid, &id.uid))) {
DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
sid_string_static(psid)));
}
@@ -128,7 +128,7 @@ int vfs_set_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid,
D.isoftlimit = limit_blk2inodes(D.softlimit);
D.ihardlimit = limit_blk2inodes(D.hardlimit);
- if (psid && NT_STATUS_IS_ERR(sid_to_uid(psid, &id.uid))) {
+ if (psid && !NT_STATUS_IS_OK(sid_to_uid(psid, &id.uid))) {
DEBUG(0,("sid_to_uid: failed, SID[%s]\n",
sid_string_static(psid)));
}
@@ -182,7 +182,7 @@ int vfs_get_user_ntquota_list(files_struct *fsp, SMB_NTQUOTA_LIST **qt_list)
continue;
}
- if (NT_STATUS_IS_ERR(uid_to_sid(&sid, usr->pw_uid))) {
+ if (!NT_STATUS_IS_OK(uid_to_sid(&sid, usr->pw_uid))) {
DEBUG(0,("uid_to_sid failed for %ld\n",(long)usr->pw_uid));
continue;
}
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index fa7b78ecc26..13692d3c2c2 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -1753,7 +1753,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
but works ok like this --metze
*/
- DEBUG(1,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
+ DEBUG(10,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_OK, NULL, 0, NULL, 0);
return -1;
@@ -1762,7 +1762,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
* --metze
*/
- DEBUG(1,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
+ DEBUG(10,("FSCTL_GET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
return -1;
@@ -1771,7 +1771,7 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
* --metze
*/
- DEBUG(1,("FSCTL_SET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
+ DEBUG(10,("FSCTL_SET_REPARSE_POINT: fnum=%d control=0x%08x\n",fnum,control));
send_nt_replies(inbuf, outbuf, bufsize, NT_STATUS_NOT_A_REPARSE_POINT, NULL, 0, NULL, 0);
return -1;
@@ -1788,16 +1788,16 @@ static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *ou
uid_t uid;
size_t sid_len=SID_MAX_SIZE;
- DEBUG(1,("FSCTL_FIND_FILES_BY_SID: fnum=%d control=0x%08x\n",fnum,control));
+ DEBUG(10,("FSCTL_FIND_FILES_BY_SID: fnum=%d control=0x%08x\n",fnum,control));
/* 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));*/
sid_parse(pdata+4,sid_len,&sid);
- DEBUGADD(2,("SID: %s\n",sid_string_static(&sid)));
+ DEBUGADD(10,("SID: %s\n",sid_string_static(&sid)));
- if (NT_STATUS_IS_ERR(sid_to_uid(&sid, &uid))) {
+ if (!NT_STATUS_IS_OK(sid_to_uid(&sid, &uid))) {
DEBUG(0,("sid_to_uid: failed, sid[%s]\n",
sid_string_static(&sid)));
uid = (-1);
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 12eef46595d..95b45fcc997 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -42,10 +42,448 @@ typedef struct canon_ace {
enum ace_owner owner_type;
enum ace_attribute attr;
posix_id unix_ug;
+ BOOL inherited;
} canon_ace;
#define ALL_ACE_PERMS (S_IRUSR|S_IWUSR|S_IXUSR)
+/*
+ * EA format of user.SAMBA_PAI (Samba_Posix_Acl_Interitance)
+ * attribute on disk.
+ *
+ * | 1 | 1 | 2 | 2 | ....
+ * +------+------+-------------+---------------------+-------------+--------------------+
+ * | vers | flag | num_entries | num_default_entries | ..entries.. | default_entries... |
+ * +------+------+-------------+---------------------+-------------+--------------------+
+ */
+
+#define SAMBA_POSIX_INHERITANCE_EA_NAME "user.SAMBA_PAI"
+
+#define PAI_VERSION_OFFSET 0
+#define PAI_FLAG_OFFSET 1
+#define PAI_NUM_ENTRIES_OFFSET 2
+#define PAI_NUM_DEFAULT_ENTRIES_OFFSET 4
+#define PAI_ENTRIES_BASE 6
+
+#define PAI_VERSION 1
+#define PAI_ACL_FLAG_PROTECTED 0x1
+#define PAI_ENTRY_LENGTH 5
+
+/*
+ * In memory format of user.SAMBA_PAI attribute.
+ */
+
+struct pai_entry {
+ struct pai_entry *next, *prev;
+ enum ace_owner owner_type;
+ posix_id unix_ug;
+};
+
+struct pai_val {
+ BOOL protected;
+ unsigned int num_entries;
+ struct pai_entry *entry_list;
+ unsigned int num_def_entries;
+ struct pai_entry *def_entry_list;
+};
+
+/************************************************************************
+ Return a uint32 of the pai_entry principal.
+************************************************************************/
+
+static uint32 get_pai_entry_val(struct pai_entry *paie)
+{
+ switch (paie->owner_type) {
+ case UID_ACE:
+ DEBUG(10,("get_pai_entry_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
+ return (uint32)paie->unix_ug.uid;
+ case GID_ACE:
+ DEBUG(10,("get_pai_entry_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
+ return (uint32)paie->unix_ug.gid;
+ case WORLD_ACE:
+ default:
+ DEBUG(10,("get_pai_entry_val: world ace\n"));
+ return (uint32)-1;
+ }
+}
+
+/************************************************************************
+ Return a uint32 of the entry principal.
+************************************************************************/
+
+static uint32 get_entry_val(canon_ace *ace_entry)
+{
+ switch (ace_entry->owner_type) {
+ case UID_ACE:
+ DEBUG(10,("get_entry_val: uid = %u\n", (unsigned int)ace_entry->unix_ug.uid ));
+ return (uint32)ace_entry->unix_ug.uid;
+ case GID_ACE:
+ DEBUG(10,("get_entry_val: gid = %u\n", (unsigned int)ace_entry->unix_ug.gid ));
+ return (uint32)ace_entry->unix_ug.gid;
+ case WORLD_ACE:
+ default:
+ DEBUG(10,("get_entry_val: world ace\n"));
+ return (uint32)-1;
+ }
+}
+
+/************************************************************************
+ Count the inherited entries.
+************************************************************************/
+
+static unsigned int num_inherited_entries(canon_ace *ace_list)
+{
+ unsigned int num_entries = 0;
+
+ for (; ace_list; ace_list = ace_list->next)
+ if (ace_list->inherited)
+ num_entries++;
+ return num_entries;
+}
+
+/************************************************************************
+ Create the on-disk format. Caller must free.
+************************************************************************/
+
+static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, BOOL protected, size_t *store_size)
+{
+ char *pai_buf = NULL;
+ canon_ace *ace_list = NULL;
+ char *entry_offset = NULL;
+ unsigned int num_entries = 0;
+ unsigned int num_def_entries = 0;
+
+ for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next)
+ if (ace_list->inherited)
+ num_entries++;
+
+ for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next)
+ if (ace_list->inherited)
+ num_def_entries++;
+
+ DEBUG(10,("create_pai_buf: num_entries = %u, num_def_entries = %u\n", num_entries, num_def_entries ));
+
+ *store_size = PAI_ENTRIES_BASE + ((num_entries + num_def_entries)*PAI_ENTRY_LENGTH);
+
+ pai_buf = malloc(*store_size);
+ if (!pai_buf) {
+ return NULL;
+ }
+
+ /* Set up the header. */
+ memset(pai_buf, '\0', PAI_ENTRIES_BASE);
+ SCVAL(pai_buf,PAI_VERSION_OFFSET,PAI_VERSION);
+ SCVAL(pai_buf,PAI_FLAG_OFFSET,(protected ? PAI_ACL_FLAG_PROTECTED : 0));
+ SSVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET,num_entries);
+ SSVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET,num_def_entries);
+
+ entry_offset = pai_buf + PAI_ENTRIES_BASE;
+
+ for (ace_list = dir_ace_list; ace_list; ace_list = ace_list->next) {
+ if (ace_list->inherited) {
+ uint8 type_val = (unsigned char)ace_list->owner_type;
+ uint32 entry_val = get_entry_val(ace_list);
+
+ SCVAL(entry_offset,0,type_val);
+ SIVAL(entry_offset,1,entry_val);
+ entry_offset += PAI_ENTRY_LENGTH;
+ }
+ }
+
+ for (ace_list = file_ace_list; ace_list; ace_list = ace_list->next) {
+ if (ace_list->inherited) {
+ uint8 type_val = (unsigned char)ace_list->owner_type;
+ uint32 entry_val = get_entry_val(ace_list);
+
+ SCVAL(entry_offset,0,type_val);
+ SIVAL(entry_offset,1,entry_val);
+ entry_offset += PAI_ENTRY_LENGTH;
+ }
+ }
+
+ return pai_buf;
+}
+
+/************************************************************************
+ Store the user.SAMBA_PAI attribute on disk.
+************************************************************************/
+
+static void store_inheritance_attributes(files_struct *fsp, canon_ace *file_ace_list,
+ canon_ace *dir_ace_list, BOOL protected)
+{
+ int ret;
+ size_t store_size;
+ char *pai_buf;
+
+ if (!lp_map_acl_inherit(SNUM(fsp->conn)))
+ return;
+
+ /*
+ * Don't store if this ACL isn't protected and
+ * none of the entries in it are marked as inherited.
+ */
+
+ if (!protected && num_inherited_entries(file_ace_list) == 0 && num_inherited_entries(dir_ace_list) == 0) {
+ /* Instead just remove the attribute if it exists. */
+ if (fsp->fd != -1)
+ SMB_VFS_FREMOVEXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME);
+ else
+ SMB_VFS_REMOVEXATTR(fsp->conn, fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME);
+ return;
+ }
+
+ pai_buf = create_pai_buf(file_ace_list, dir_ace_list, protected, &store_size);
+
+ if (fsp->fd != -1)
+ ret = SMB_VFS_FSETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
+ pai_buf, store_size, 0);
+ else
+ ret = SMB_VFS_SETXATTR(fsp->conn,fsp->fsp_name, SAMBA_POSIX_INHERITANCE_EA_NAME,
+ pai_buf, store_size, 0);
+
+ SAFE_FREE(pai_buf);
+
+ DEBUG(10,("store_inheritance_attribute:%s for file %s\n", protected ? " (protected)" : "", fsp->fsp_name));
+ if (ret == -1 && errno != ENOSYS)
+ DEBUG(1,("store_inheritance_attribute: Error %s\n", strerror(errno) ));
+}
+
+/************************************************************************
+ Delete the in memory inheritance info.
+************************************************************************/
+
+static void free_inherited_info(struct pai_val *pal)
+{
+ if (pal) {
+ struct pai_entry *paie, *paie_next;
+ for (paie = pal->entry_list; paie; paie = paie_next) {
+ paie_next = paie->next;
+ SAFE_FREE(paie);
+ }
+ for (paie = pal->def_entry_list; paie; paie = paie_next) {
+ paie_next = paie->next;
+ SAFE_FREE(paie);
+ }
+ SAFE_FREE(pal);
+ }
+}
+
+/************************************************************************
+ Was this ACL protected ?
+************************************************************************/
+
+static BOOL get_protected_flag(struct pai_val *pal)
+{
+ if (!pal)
+ return False;
+ return pal->protected;
+}
+
+/************************************************************************
+ Was this ACE inherited ?
+************************************************************************/
+
+static BOOL get_inherited_flag(struct pai_val *pal, canon_ace *ace_entry, BOOL default_ace)
+{
+ struct pai_entry *paie;
+
+ if (!pal)
+ return False;
+
+ /* If the entry exists it is inherited. */
+ for (paie = (default_ace ? pal->def_entry_list : pal->entry_list); paie; paie = paie->next) {
+ if (ace_entry->owner_type == paie->owner_type &&
+ get_entry_val(ace_entry) == get_pai_entry_val(paie))
+ return True;
+ }
+ return False;
+}
+
+/************************************************************************
+ Ensure an attribute just read is valid.
+************************************************************************/
+
+static BOOL check_pai_ok(char *pai_buf, size_t pai_buf_data_size)
+{
+ uint16 num_entries;
+ uint16 num_def_entries;
+
+ if (pai_buf_data_size < PAI_ENTRIES_BASE) {
+ /* Corrupted - too small. */
+ return False;
+ }
+
+ if (CVAL(pai_buf,PAI_VERSION_OFFSET) != PAI_VERSION)
+ return False;
+
+ num_entries = SVAL(pai_buf,PAI_NUM_ENTRIES_OFFSET);
+ num_def_entries = SVAL(pai_buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
+
+ /* Check the entry lists match. */
+ /* Each entry is 5 bytes (type plus 4 bytes of uid or gid). */
+
+ if (((num_entries + num_def_entries)*PAI_ENTRY_LENGTH) + PAI_ENTRIES_BASE != pai_buf_data_size)
+ return False;
+
+ return True;
+}
+
+
+/************************************************************************
+ Convert to in-memory format.
+************************************************************************/
+
+static struct pai_val *create_pai_val(char *buf, size_t size)
+{
+ char *entry_offset;
+ struct pai_val *paiv = NULL;
+ int i;
+
+ if (!check_pai_ok(buf, size))
+ return NULL;
+
+ paiv = malloc(sizeof(struct pai_val));
+ if (!paiv)
+ return NULL;
+
+ memset(paiv, '\0', sizeof(struct pai_val));
+
+ paiv->protected = (CVAL(buf,PAI_FLAG_OFFSET) == PAI_ACL_FLAG_PROTECTED);
+
+ paiv->num_entries = SVAL(buf,PAI_NUM_ENTRIES_OFFSET);
+ paiv->num_def_entries = SVAL(buf,PAI_NUM_DEFAULT_ENTRIES_OFFSET);
+
+ entry_offset = buf + PAI_ENTRIES_BASE;
+
+ DEBUG(10,("create_pai_val:%s num_entries = %u, num_def_entries = %u\n",
+ paiv->protected ? " (protected)" : "", paiv->num_entries, paiv->num_def_entries ));
+
+ for (i = 0; i < paiv->num_entries; i++) {
+ struct pai_entry *paie;
+
+ paie = malloc(sizeof(struct pai_entry));
+ if (!paie) {
+ free_inherited_info(paiv);
+ return NULL;
+ }
+
+ paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
+ switch( paie->owner_type) {
+ case UID_ACE:
+ paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
+ DEBUG(10,("create_pai_val: uid = %u\n", (unsigned int)paie->unix_ug.uid ));
+ break;
+ case GID_ACE:
+ paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
+ DEBUG(10,("create_pai_val: gid = %u\n", (unsigned int)paie->unix_ug.gid ));
+ break;
+ case WORLD_ACE:
+ paie->unix_ug.world = -1;
+ DEBUG(10,("create_pai_val: world ace\n"));
+ break;
+ default:
+ free_inherited_info(paiv);
+ return NULL;
+ }
+ entry_offset += PAI_ENTRY_LENGTH;
+ DLIST_ADD(paiv->entry_list, paie);
+ }
+
+ for (i = 0; i < paiv->num_def_entries; i++) {
+ struct pai_entry *paie;
+
+ paie = malloc(sizeof(struct pai_entry));
+ if (!paie) {
+ free_inherited_info(paiv);
+ return NULL;
+ }
+
+ paie->owner_type = (enum ace_owner)CVAL(entry_offset,0);
+ switch( paie->owner_type) {
+ case UID_ACE:
+ paie->unix_ug.uid = (uid_t)IVAL(entry_offset,1);
+ DEBUG(10,("create_pai_val: (def) uid = %u\n", (unsigned int)paie->unix_ug.uid ));
+ break;
+ case GID_ACE:
+ paie->unix_ug.gid = (gid_t)IVAL(entry_offset,1);
+ DEBUG(10,("create_pai_val: (def) gid = %u\n", (unsigned int)paie->unix_ug.gid ));
+ break;
+ case WORLD_ACE:
+ paie->unix_ug.world = -1;
+ DEBUG(10,("create_pai_val: (def) world ace\n"));
+ break;
+ default:
+ free_inherited_info(paiv);
+ return NULL;
+ }
+ entry_offset += PAI_ENTRY_LENGTH;
+ DLIST_ADD(paiv->def_entry_list, paie);
+ }
+
+ return paiv;
+}
+
+/************************************************************************
+ Load the user.SAMBA_PAI attribute.
+************************************************************************/
+
+static struct pai_val *load_inherited_info(files_struct *fsp)
+{
+ char *pai_buf;
+ size_t pai_buf_size = 1024;
+ struct pai_val *paiv = NULL;
+ ssize_t ret;
+
+ if (!lp_map_acl_inherit(SNUM(fsp->conn)))
+ return NULL;
+
+ if ((pai_buf = malloc(pai_buf_size)) == NULL)
+ return NULL;
+
+ do {
+ if (fsp->fd != -1)
+ ret = SMB_VFS_FGETXATTR(fsp, fsp->fd, SAMBA_POSIX_INHERITANCE_EA_NAME,
+ pai_buf, pai_buf_size);
+ else
+ ret = SMB_VFS_GETXATTR(fsp->conn,fsp->fsp_name,SAMBA_POSIX_INHERITANCE_EA_NAME,
+ pai_buf, pai_buf_size);
+
+ if (ret == -1) {
+ if (errno != ERANGE) {
+ break;
+ }
+ /* Buffer too small - enlarge it. */
+ pai_buf_size *= 2;
+ SAFE_FREE(pai_buf);
+ if ((pai_buf = malloc(pai_buf_size)) == NULL)
+ return NULL;
+ }
+ } while (ret == -1);
+
+ DEBUG(10,("load_inherited_info: ret = %d for file %s\n", ret, fsp->fsp_name));
+
+ if (ret == -1) {
+ /* No attribute or not supported. */
+#if defined(ENOATTR)
+ if (errno != ENOATTR)
+ DEBUG(10,("load_inherited_info: Error %s\n", strerror(errno) ));
+#else
+ if (errno != ENOSYS)
+ DEBUG(10,("load_inherited_info: Error %s\n", strerror(errno) ));
+#endif
+ SAFE_FREE(pai_buf);
+ return NULL;
+ }
+
+ paiv = create_pai_val(pai_buf, ret);
+
+ if (paiv && paiv->protected)
+ DEBUG(10,("load_inherited_info: ACL is protected for file %s\n", fsp->fsp_name));
+
+ SAFE_FREE(pai_buf);
+ return paiv;
+}
+
/****************************************************************************
Functions to manipulate the internal ACE format.
****************************************************************************/
@@ -106,10 +544,10 @@ static void print_canon_ace(canon_ace *pace, int num)
dbgtext( "SID = %s ", sid_to_string( str, &pace->trustee));
if (pace->owner_type == UID_ACE) {
const char *u_name = uidtoname(pace->unix_ug.uid);
- dbgtext( "uid %u (%s) ", (unsigned int)pace->unix_ug.uid, u_name);
+ dbgtext( "uid %u (%s) ", (unsigned int)pace->unix_ug.uid, u_name );
} else if (pace->owner_type == GID_ACE) {
char *g_name = gidtoname(pace->unix_ug.gid);
- dbgtext( "gid %u (%s) ", (unsigned int)pace->unix_ug.gid, g_name);
+ dbgtext( "gid %u (%s) ", (unsigned int)pace->unix_ug.gid, g_name );
} else
dbgtext( "other ");
switch (pace->type) {
@@ -129,6 +567,8 @@ static void print_canon_ace(canon_ace *pace, int num)
dbgtext( "SMB_ACL_OTHER ");
break;
}
+ if (pace->inherited)
+ dbgtext( "(inherited) ");
dbgtext( "perms ");
dbgtext( "%c", pace->perms & S_IRUSR ? 'r' : '-');
dbgtext( "%c", pace->perms & S_IWUSR ? 'w' : '-');
@@ -468,7 +908,7 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
if (security_info_sent & OWNER_SECURITY_INFORMATION) {
sid_copy(&owner_sid, psd->owner_sid);
- if (NT_STATUS_IS_ERR(sid_to_uid(&owner_sid, puser))) {
+ if (!NT_STATUS_IS_OK(sid_to_uid(&owner_sid, puser))) {
#if ACL_FORCE_UNMAPPABLE
/* this allows take ownership to work reasonably */
extern struct current_user current_user;
@@ -488,7 +928,7 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
if (security_info_sent & GROUP_SECURITY_INFORMATION) {
sid_copy(&grp_sid, psd->grp_sid);
- if (NT_STATUS_IS_ERR(sid_to_gid( &grp_sid, pgrp))) {
+ if (!NT_STATUS_IS_OK(sid_to_gid( &grp_sid, pgrp))) {
#if ACL_FORCE_UNMAPPABLE
/* this allows take group ownership to work reasonably */
extern struct current_user current_user;
@@ -766,7 +1206,7 @@ static void check_owning_objs(canon_ace *ace, DOM_SID *pfile_owner_sid, DOM_SID
Unpack a SEC_DESC into two canonical ace lists.
****************************************************************************/
-static BOOL create_canon_ace_lists(files_struct *fsp,
+static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
DOM_SID *pfile_owner_sid,
DOM_SID *pfile_grp_sid,
canon_ace **ppfile_ace, canon_ace **ppdir_ace,
@@ -901,7 +1341,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
current_ace->type = SMB_ACL_OTHER;
} else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Owner)) {
current_ace->owner_type = UID_ACE;
- current_ace->unix_ug.world = -1;
+ current_ace->unix_ug.uid = pst->st_uid;
current_ace->type = SMB_ACL_USER_OBJ;
/*
@@ -914,7 +1354,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
} else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Group)) {
current_ace->owner_type = GID_ACE;
- current_ace->unix_ug.world = -1;
+ current_ace->unix_ug.gid = pst->st_gid;
current_ace->type = SMB_ACL_GROUP_OBJ;
/*
@@ -949,6 +1389,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp,
current_ace->perms |= map_nt_perms( psa->info, S_IRUSR);
current_ace->attr = (psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED) ? ALLOW_ACE : DENY_ACE;
+ current_ace->inherited = ((psa->flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False);
/*
* Now add the created ace to either the file list, the directory
@@ -1473,7 +1914,7 @@ static BOOL unpack_canon_ace(files_struct *fsp,
* Now go through the DACL and create the canon_ace lists.
*/
- if (!create_canon_ace_lists( fsp, pfile_owner_sid, pfile_grp_sid,
+ if (!create_canon_ace_lists( fsp, pst, pfile_owner_sid, pfile_grp_sid,
&file_ace, &dir_ace, psd->dacl))
return False;
@@ -1616,7 +2057,7 @@ static void arrange_posix_perms( char *filename, canon_ace **pp_list_head)
****************************************************************************/
static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf,
- DOM_SID *powner, DOM_SID *pgroup, SMB_ACL_TYPE_T the_acl_type)
+ DOM_SID *powner, DOM_SID *pgroup, struct pai_val *pal, SMB_ACL_TYPE_T the_acl_type)
{
extern DOM_SID global_sid_World;
connection_struct *conn = fsp->conn;
@@ -1723,6 +2164,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
ace->trustee = sid;
ace->unix_ug = unix_ug;
ace->owner_type = owner_type;
+ ace->inherited = get_inherited_flag(pal, ace, (the_acl_type == SMB_ACL_TYPE_DEFAULT));
DLIST_ADD(list_head, ace);
}
@@ -1734,14 +2176,12 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
if (!ensure_canon_entry_valid(&list_head, fsp, powner, pgroup, psbuf, False))
goto fail;
- arrange_posix_perms(fsp->fsp_name,&list_head );
-
/*
* Now go through the list, masking the permissions with the
* acl_mask. Ensure all DENY Entries are at the start of the list.
*/
- DEBUG(10,("canonicalise_acl: ace entries before arrange :\n"));
+ DEBUG(10,("canonicalise_acl: %s ace entries before arrange :\n", the_acl_type == SMB_ACL_TYPE_ACCESS ? "Access" : "Default" ));
for ( ace_count = 0, ace = list_head; ace; ace = next_ace, ace_count++) {
next_ace = ace->next;
@@ -1759,6 +2199,8 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
}
}
+ arrange_posix_perms(fsp->fsp_name,&list_head );
+
print_canon_ace_list( "canonicalise_acl: ace entries after arrange", list_head );
return list_head;
@@ -1908,6 +2350,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
if( DEBUGLVL( 10 ))
print_canon_ace( p_ace, i);
+
}
if (needs_mask && !got_mask_entry) {
@@ -2109,16 +2552,6 @@ posix perms.\n", fsp->fsp_name ));
return True;
}
-static int nt_ace_comp( SEC_ACE *a1, SEC_ACE *a2)
-{
- if (a1->type == a2->type)
- return 0;
-
- if (a1->type == SEC_ACE_TYPE_ACCESS_DENIED && a2->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
- return -1;
- return 1;
-}
-
/****************************************************************************
Incoming NT ACLs on a directory can be split into a default POSIX acl (CI|OI|IO) and
a normal POSIX acl. Win2k needs these split acls re-merging into one ACL
@@ -2132,24 +2565,51 @@ static size_t merge_default_aces( SEC_ACE *nt_ace_list, size_t num_aces)
for (i = 0; i < num_aces; i++) {
for (j = i+1; j < num_aces; j++) {
+ uint32 i_flags_ni = (nt_ace_list[i].flags & ~SEC_ACE_FLAG_INHERITED_ACE);
+ uint32 j_flags_ni = (nt_ace_list[j].flags & ~SEC_ACE_FLAG_INHERITED_ACE);
+ BOOL i_inh = (nt_ace_list[i].flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False;
+ BOOL j_inh = (nt_ace_list[j].flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False;
+
/* We know the lower number ACE's are file entries. */
if ((nt_ace_list[i].type == nt_ace_list[j].type) &&
(nt_ace_list[i].size == nt_ace_list[j].size) &&
(nt_ace_list[i].info.mask == nt_ace_list[j].info.mask) &&
sid_equal(&nt_ace_list[i].trustee, &nt_ace_list[j].trustee) &&
- (nt_ace_list[i].flags == 0) &&
- (nt_ace_list[j].flags == (SEC_ACE_FLAG_OBJECT_INHERIT|
- SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY))) {
+ (i_inh == j_inh) &&
+ (i_flags_ni == 0) &&
+ (j_flags_ni == (SEC_ACE_FLAG_OBJECT_INHERIT|
+ SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY))) {
/*
- * These are identical except for the flags.
- * Merge the inherited ACE onto the non-inherited ACE.
+ * W2K wants to have access allowed zero access ACE's
+ * at the end of the list. If the mask is zero, merge
+ * the non-inherited ACE onto the inherited ACE.
*/
- nt_ace_list[i].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT;
- if (num_aces - j - 1 > 0)
- memmove(&nt_ace_list[j], &nt_ace_list[j+1], (num_aces-j-1) *
- sizeof(SEC_ACE));
+ if (nt_ace_list[i].info.mask == 0) {
+ nt_ace_list[j].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
+ (i_inh ? SEC_ACE_FLAG_INHERITED_ACE : 0);
+ if (num_aces - i - 1 > 0)
+ memmove(&nt_ace_list[i], &nt_ace_list[i+1], (num_aces-i-1) *
+ sizeof(SEC_ACE));
+
+ DEBUG(10,("merge_default_aces: Merging zero access ACE %u onto ACE %u.\n",
+ (unsigned int)i, (unsigned int)j ));
+ } else {
+ /*
+ * These are identical except for the flags.
+ * Merge the inherited ACE onto the non-inherited ACE.
+ */
+
+ nt_ace_list[i].flags = SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
+ (i_inh ? SEC_ACE_FLAG_INHERITED_ACE : 0);
+ if (num_aces - j - 1 > 0)
+ memmove(&nt_ace_list[j], &nt_ace_list[j+1], (num_aces-j-1) *
+ sizeof(SEC_ACE));
+
+ DEBUG(10,("merge_default_aces: Merging ACE %u onto ACE %u.\n",
+ (unsigned int)j, (unsigned int)i ));
+ }
num_aces--;
break;
}
@@ -2186,7 +2646,9 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
canon_ace *file_ace = NULL;
canon_ace *dir_ace = NULL;
size_t num_profile_acls = 0;
-
+ struct pai_val *pal = NULL;
+ SEC_DESC *psd = NULL;
+
*ppdesc = NULL;
DEBUG(10,("get_nt_acl: called for file %s\n", fsp->fsp_name ));
@@ -2228,6 +2690,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
posix_acl ? "present" : "absent",
dir_acl ? "present" : "absent" ));
+ pal = load_inherited_info(fsp);
+
/*
* Get the owner, group and world SIDs.
*/
@@ -2241,7 +2705,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
create_file_sids(&sbuf, &owner_sid, &group_sid);
}
- if (security_info & DACL_SECURITY_INFORMATION) {
+ if ((security_info & DACL_SECURITY_INFORMATION) && !(security_info & PROTECTED_DACL_SECURITY_INFORMATION)) {
/*
* In the optimum case Creator Owner and Creator Group would be used for
@@ -2253,7 +2717,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
*/
/* Create the canon_ace lists. */
- file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, SMB_ACL_TYPE_ACCESS );
+ file_ace = canonicalise_acl( fsp, posix_acl, &sbuf, &owner_sid, &group_sid, pal, SMB_ACL_TYPE_ACCESS );
/* We must have *some* ACLS. */
@@ -2265,7 +2729,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
if (fsp->is_directory && dir_acl) {
dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
&global_sid_Creator_Owner,
- &global_sid_Creator_Group, SMB_ACL_TYPE_DEFAULT );
+ &global_sid_Creator_Group, pal, SMB_ACL_TYPE_DEFAULT );
}
/*
@@ -2347,7 +2811,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
SEC_ACCESS acc;
acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, 0);
+ init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, ace->inherited ? SEC_ACE_FLAG_INHERITED_ACE : 0);
}
/* The User must have access to a profile share - even if we can't map the SID. */
@@ -2355,7 +2819,8 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
SEC_ACCESS acc;
init_sec_access(&acc,FILE_GENERIC_ALL);
- init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc, 0);
+ init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ acc, 0);
}
ace = dir_ace;
@@ -2365,7 +2830,9 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
- SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY|
+ (ace->inherited ? SEC_ACE_FLAG_INHERITED_ACE : 0));
}
/* The User must have access to a profile share - even if we can't map the SID. */
@@ -2375,7 +2842,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
init_sec_access(&acc,FILE_GENERIC_ALL);
init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc,
SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY);
+ SEC_ACE_FLAG_INHERIT_ONLY|0);
}
/*
@@ -2386,12 +2853,6 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
num_aces = merge_default_aces(nt_ace_list, num_aces);
- /*
- * Sort to force deny entries to the front.
- */
-
- if (num_aces)
- qsort( nt_ace_list, num_aces, sizeof(nt_ace_list[0]), QSORT_CAST nt_ace_comp);
}
if (num_aces) {
@@ -2402,21 +2863,16 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
}
} /* security_info & DACL_SECURITY_INFORMATION */
- *ppdesc = make_standard_sec_desc( main_loop_talloc_get(),
+ psd = make_standard_sec_desc( main_loop_talloc_get(),
(security_info & OWNER_SECURITY_INFORMATION) ? &owner_sid : NULL,
(security_info & GROUP_SECURITY_INFORMATION) ? &group_sid : NULL,
psa,
&sd_size);
- if(!*ppdesc) {
+ if(!psd) {
DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
sd_size = 0;
} else {
-#if 1
- /*
- * JRA. Setting this flag causes W2K clients not to
- * propagate ACL sets down a directory tree correctly.
- */
/*
* Windows 2000: The DACL_PROTECTED flag in the security
* descriptor marks the ACL as non-inheriting, i.e., no
@@ -2426,10 +2882,15 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
* any ACEs that are inherited dynamically. The DACL_PROTECTED
* flag doesn't seem to bother Windows NT.
*/
- (*ppdesc)->type |= SE_DESC_DACL_PROTECTED;
-#endif
+ if (get_protected_flag(pal))
+ psd->type |= SE_DESC_DACL_PROTECTED;
}
+ if (psd->dacl)
+ dacl_sort_into_canonical_order(psd->dacl->ace, (unsigned int)psd->dacl->num_aces);
+
+ *ppdesc = psd;
+
done:
if (posix_acl)
@@ -2438,6 +2899,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
+ free_inherited_info(pal);
SAFE_FREE(nt_ace_list);
return sd_size;
@@ -2660,6 +3122,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
}
}
+ if (acl_set_support)
+ store_inheritance_attributes(fsp, file_ace_list, dir_ace_list,
+ (psd->type & SE_DESC_DACL_PROTECTED) ? True : False);
+
/*
* If we cannot set using POSIX ACLs we fall back to checking if we need to chmod.
*/
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index be51a328911..e7f01ad02fe 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -39,7 +39,7 @@ unsigned int smb_echo_count = 0;
extern BOOL global_encrypted_passwords_negotiated;
/****************************************************************************
- Reply to an special message.
+ Reply to a special message.
****************************************************************************/
int reply_special(char *inbuf,char *outbuf)
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 07723cc20e7..a767014232b 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -845,8 +845,12 @@ void build_options(BOOL screen);
if(!initialize_password_db(False))
exit(1);
- if (!idmap_init())
- exit(1);
+ {
+ const char *idmap_back = lp_idmap_backend();
+
+ if (!idmap_init((idmap_back && *idmap_back) ? "winbind" : NULL))
+ exit(1);
+ }
if (!idmap_init_wellknown_sids())
exit(1);
@@ -855,8 +859,6 @@ void build_options(BOOL screen);
init_modules();
- uni_group_cache_init(); /* Non-critical */
-
/* possibly reload the services file. */
reload_services(True);
@@ -891,7 +893,6 @@ void build_options(BOOL screen);
smbd_process();
- uni_group_cache_shutdown();
namecache_shutdown();
exit_server("normal exit");
return(0);
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 31bb343474b..11659f28706 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -366,6 +366,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
}
fstrcpy(user,pass->pw_name);
conn->force_user = True;
+ conn->uid = pass->pw_uid;
+ conn->gid = pass->pw_gid;
string_set(&conn->user,pass->pw_name);
passwd_free(&pass);
DEBUG(3,("Guest only user %s\n",user));
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c
index c414ae0d310..34681ea78f2 100644
--- a/source/tdb/tdb.c
+++ b/source/tdb/tdb.c
@@ -1257,7 +1257,8 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock,
/* Try to clean dead ones from old traverses */
current = tlock->off;
tlock->off = rec->next;
- if (do_delete(tdb, current, rec) != 0)
+ if (!tdb->read_only &&
+ do_delete(tdb, current, rec) != 0)
goto fail;
}
tdb_unlock(tdb, tlock->hash, F_WRLCK);
diff --git a/source/tdb/tdbback.c b/source/tdb/tdbback.c
new file mode 100644
index 00000000000..744cface557
--- /dev/null
+++ b/source/tdb/tdbback.c
@@ -0,0 +1,201 @@
+/*
+ Unix SMB/CIFS implementation.
+ low level tdb backup and restore utility
+ Copyright (C) Andrew Tridgell 2002
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <ctype.h>
+#include <signal.h>
+#include "tdb.h"
+
+static int failed;
+
+char *add_suffix(const char *name, const char *suffix)
+{
+ char *ret;
+ int len = strlen(name) + strlen(suffix) + 1;
+ ret = malloc(len);
+ if (!ret) {
+ fprintf(stderr,"Out of memory!\n");
+ exit(1);
+ }
+ strncpy(ret, name, len);
+ strncat(ret, suffix, len);
+ return ret;
+}
+
+static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+ TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state;
+
+ if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) {
+ fprintf(stderr,"Failed to insert into %s\n", tdb_new->name);
+ failed = 1;
+ return 1;
+ }
+ return 0;
+}
+
+
+static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+{
+ return 0;
+}
+
+/*
+ carefully backup a tdb, validating the contents and
+ only doing the backup if its OK
+ this function is also used for restore
+*/
+int backup_tdb(const char *old_name, const char *new_name)
+{
+ TDB_CONTEXT *tdb;
+ TDB_CONTEXT *tdb_new;
+ char *tmp_name;
+ struct stat st;
+ int count1, count2;
+
+ tmp_name = add_suffix(new_name, ".tmp");
+
+ /* stat the old tdb to find its permissions */
+ if (stat(old_name, &st) != 0) {
+ perror(old_name);
+ return 1;
+ }
+
+ /* open the old tdb */
+ tdb = tdb_open(old_name, 0, 0, O_RDWR, 0);
+ if (!tdb) {
+ printf("Failed to open %s\n", old_name);
+ return 1;
+ }
+
+ /* create the new tdb */
+ unlink(tmp_name);
+ tdb_new = tdb_open(tmp_name, tdb->header.hash_size,
+ TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL,
+ st.st_mode & 0777);
+ if (!tdb_new) {
+ perror(tmp_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ /* lock the old tdb */
+ if (tdb_lockall(tdb) != 0) {
+ fprintf(stderr,"Failed to lock %s\n", old_name);
+ tdb_close(tdb);
+ tdb_close(tdb_new);
+ unlink(tmp_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ failed = 0;
+
+ /* traverse and copy */
+ count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new);
+ if (count1 < 0 || failed) {
+ fprintf(stderr,"failed to copy %s\n", old_name);
+ tdb_close(tdb);
+ tdb_close(tdb_new);
+ unlink(tmp_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ /* close the old tdb */
+ tdb_close(tdb);
+
+ /* close the new tdb and re-open read-only */
+ tdb_close(tdb_new);
+ tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0);
+ if (!tdb_new) {
+ fprintf(stderr,"failed to reopen %s\n", tmp_name);
+ unlink(tmp_name);
+ perror(tmp_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ /* traverse the new tdb to confirm */
+ count2 = tdb_traverse(tdb_new, test_fn, 0);
+ if (count2 != count1) {
+ fprintf(stderr,"failed to copy %s\n", old_name);
+ tdb_close(tdb_new);
+ unlink(tmp_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ /* make sure the new tdb has reached stable storage */
+ fsync(tdb_new->fd);
+
+ /* close the new tdb and rename it to .bak */
+ tdb_close(tdb_new);
+ unlink(new_name);
+ if (rename(tmp_name, new_name) != 0) {
+ perror(new_name);
+ free(tmp_name);
+ return 1;
+ }
+
+ free(tmp_name);
+
+ return 0;
+}
+
+
+
+/*
+ verify a tdb and if it is corrupt then restore from *.bak
+*/
+int verify_tdb(const char *fname, const char *bak_name)
+{
+ TDB_CONTEXT *tdb;
+ int count = -1;
+
+ /* open the tdb */
+ tdb = tdb_open(fname, 0, 0, O_RDONLY, 0);
+
+ /* traverse the tdb, then close it */
+ if (tdb) {
+ count = tdb_traverse(tdb, test_fn, NULL);
+ tdb_close(tdb);
+ }
+
+ /* count is < 0 means an error */
+ if (count < 0) {
+ printf("restoring %s\n", fname);
+ return backup_tdb(bak_name, fname);
+ }
+
+ printf("%s : %d records\n", fname, count);
+
+ return 0;
+}
diff --git a/source/tdb/tdbback.h b/source/tdb/tdbback.h
new file mode 100644
index 00000000000..7ebeaa494d6
--- /dev/null
+++ b/source/tdb/tdbback.h
@@ -0,0 +1,23 @@
+/*
+ Unix SMB/CIFS implementation.
+ low level tdb backup and restore utility
+ Copyright (C) Andrew Tridgell 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.
+*/
+
+char *add_suffix(const char *name, const char *suffix);
+int backup_tdb(const char *old_name, const char *new_name);
+int verify_tdb(const char *fname, const char *bak_name);
diff --git a/source/tdb/tdbbackup.c b/source/tdb/tdbbackup.c
index 36ba7db9188..0eaf6b6c0b7 100644
--- a/source/tdb/tdbbackup.c
+++ b/source/tdb/tdbbackup.c
@@ -55,175 +55,7 @@
#include <ctype.h>
#include <signal.h>
#include "tdb.h"
-
-static int failed;
-
-static char *add_suffix(const char *name, const char *suffix)
-{
- char *ret;
- int len = strlen(name) + strlen(suffix) + 1;
- ret = malloc(len);
- if (!ret) {
- fprintf(stderr,"Out of memory!\n");
- exit(1);
- }
- strncpy(ret, name, len);
- strncat(ret, suffix, len);
- return ret;
-}
-
-static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state;
-
- if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) {
- fprintf(stderr,"Failed to insert into %s\n", tdb_new->name);
- failed = 1;
- return 1;
- }
- return 0;
-}
-
-
-static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
-{
- return 0;
-}
-
-/*
- carefully backup a tdb, validating the contents and
- only doing the backup if its OK
- this function is also used for restore
-*/
-static int backup_tdb(const char *old_name, const char *new_name)
-{
- TDB_CONTEXT *tdb;
- TDB_CONTEXT *tdb_new;
- char *tmp_name;
- struct stat st;
- int count1, count2;
-
- tmp_name = add_suffix(new_name, ".tmp");
-
- /* stat the old tdb to find its permissions */
- if (stat(old_name, &st) != 0) {
- perror(old_name);
- return 1;
- }
-
- /* open the old tdb */
- tdb = tdb_open(old_name, 0, 0, O_RDWR, 0);
- if (!tdb) {
- printf("Failed to open %s\n", old_name);
- return 1;
- }
-
- /* create the new tdb */
- unlink(tmp_name);
- tdb_new = tdb_open(tmp_name, tdb->header.hash_size,
- TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL,
- st.st_mode & 0777);
- if (!tdb_new) {
- perror(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* lock the old tdb */
- if (tdb_lockall(tdb) != 0) {
- fprintf(stderr,"Failed to lock %s\n", old_name);
- tdb_close(tdb);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- failed = 0;
-
- /* traverse and copy */
- count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new);
- if (count1 < 0 || failed) {
- fprintf(stderr,"failed to copy %s\n", old_name);
- tdb_close(tdb);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* close the old tdb */
- tdb_close(tdb);
-
- /* close the new tdb and re-open read-only */
- tdb_close(tdb_new);
- tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0);
- if (!tdb_new) {
- fprintf(stderr,"failed to reopen %s\n", tmp_name);
- unlink(tmp_name);
- perror(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* traverse the new tdb to confirm */
- count2 = tdb_traverse(tdb_new, test_fn, 0);
- if (count2 != count1) {
- fprintf(stderr,"failed to copy %s\n", old_name);
- tdb_close(tdb_new);
- unlink(tmp_name);
- free(tmp_name);
- return 1;
- }
-
- /* make sure the new tdb has reached stable storage */
- fsync(tdb_new->fd);
-
- /* close the new tdb and rename it to .bak */
- tdb_close(tdb_new);
- unlink(new_name);
- if (rename(tmp_name, new_name) != 0) {
- perror(new_name);
- free(tmp_name);
- return 1;
- }
-
- printf("%s : %d records\n", old_name, count1);
- free(tmp_name);
-
- return 0;
-}
-
-
-
-/*
- verify a tdb and if it is corrupt then restore from *.bak
-*/
-static int verify_tdb(const char *fname, const char *bak_name)
-{
- TDB_CONTEXT *tdb;
- int count = -1;
-
- /* open the tdb */
- tdb = tdb_open(fname, 0, 0, O_RDONLY, 0);
-
- /* traverse the tdb, then close it */
- if (tdb) {
- count = tdb_traverse(tdb, test_fn, NULL);
- tdb_close(tdb);
- }
-
- /* count is < 0 means an error */
- if (count < 0) {
- printf("restoring %s\n", fname);
- return backup_tdb(bak_name, fname);
- }
-
- printf("%s : %d records\n", fname, count);
-
- return 0;
-}
-
+#include "tdbback.h"
/*
see if one file is newer than another
@@ -245,7 +77,7 @@ static void usage(void)
printf("Usage: tdbbackup [options] <fname...>\n\n");
printf(" -h this help message\n");
printf(" -s suffix set the backup suffix\n");
- printf(" -v veryify mode (restore if corrupt)\n");
+ printf(" -v verify mode (restore if corrupt)\n");
}
@@ -255,7 +87,7 @@ static void usage(void)
int ret = 0;
int c;
int verify = 0;
- char *suffix = ".bak";
+ const char *suffix = ".bak";
extern int optind;
extern char *optarg;
diff --git a/source/tdb/tdbutil.c b/source/tdb/tdbutil.c
index 19dfe642df0..595062dc876 100644
--- a/source/tdb/tdbutil.c
+++ b/source/tdb/tdbutil.c
@@ -821,6 +821,7 @@ void tdb_search_list_free(TDB_LIST_NODE* node)
while (node) {
next_node = node->next;
+ SAFE_FREE(node->node_key.dptr);
SAFE_FREE(node);
node = next_node;
};
diff --git a/source/torture/nsstest.c b/source/torture/nsstest.c
index a82fa05203e..0a08cb6e8f2 100644
--- a/source/torture/nsstest.c
+++ b/source/torture/nsstest.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
nss tester for winbindd
Copyright (C) Andrew Tridgell 2001
+ 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
@@ -44,6 +45,7 @@ static void *find_fn(const char *name)
res = sys_dlsym(h, s);
if (!res) {
printf("Can't find function %s\n", s);
+ total_errors++;
return NULL;
}
return res;
@@ -65,6 +67,9 @@ static struct passwd *nss_getpwent(void)
static char buf[1000];
NSS_STATUS status;
+ if (!_nss_getpwent_r)
+ return NULL;
+
status = _nss_getpwent_r(&pwd, buf, sizeof(buf), &nss_errno);
if (status == NSS_STATUS_NOTFOUND) {
return NULL;
@@ -83,6 +88,9 @@ static struct passwd *nss_getpwnam(const char *name)
static struct passwd pwd;
static char buf[1000];
NSS_STATUS status;
+
+ if (!_nss_getpwnam_r)
+ return NULL;
status = _nss_getpwnam_r(name, &pwd, buf, sizeof(buf), &nss_errno);
if (status == NSS_STATUS_NOTFOUND) {
@@ -102,6 +110,9 @@ static struct passwd *nss_getpwuid(uid_t uid)
static struct passwd pwd;
static char buf[1000];
NSS_STATUS status;
+
+ if (!_nss_getpwuid_r)
+ return NULL;
status = _nss_getpwuid_r(uid, &pwd, buf, sizeof(buf), &nss_errno);
if (status == NSS_STATUS_NOTFOUND) {
@@ -118,6 +129,10 @@ static void nss_setpwent(void)
{
NSS_STATUS (*_nss_setpwent)(void) = find_fn("setpwent");
NSS_STATUS status;
+
+ if (!_nss_setpwent)
+ return;
+
status = _nss_setpwent();
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("setpwent", status);
@@ -128,6 +143,10 @@ static void nss_endpwent(void)
{
NSS_STATUS (*_nss_endpwent)(void) = find_fn("endpwent");
NSS_STATUS status;
+
+ if (!_nss_endpwent)
+ return;
+
status = _nss_endpwent();
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("endpwent", status);
@@ -144,7 +163,11 @@ static struct group *nss_getgrent(void)
static int buflen = 1024;
NSS_STATUS status;
- if (!buf) buf = malloc(buflen);
+ if (!_nss_getgrent_r)
+ return NULL;
+
+ if (!buf)
+ buf = malloc(buflen);
again:
status = _nss_getgrent_r(&grp, buf, buflen, &nss_errno);
@@ -172,7 +195,11 @@ static struct group *nss_getgrnam(const char *name)
static int buflen = 1000;
NSS_STATUS status;
- if (!buf) buf = malloc(buflen);
+ if (!_nss_getgrnam_r)
+ return NULL;
+
+ if (!buf)
+ buf = malloc(buflen);
again:
status = _nss_getgrnam_r(name, &grp, buf, buflen, &nss_errno);
if (status == NSS_STATUS_TRYAGAIN) {
@@ -199,7 +226,12 @@ static struct group *nss_getgrgid(gid_t gid)
static int buflen = 1000;
NSS_STATUS status;
- if (!buf) buf = malloc(buflen);
+ if (!_nss_getgrgid_r)
+ return NULL;
+
+ if (!buf)
+ buf = malloc(buflen);
+
again:
status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno);
if (status == NSS_STATUS_TRYAGAIN) {
@@ -221,6 +253,10 @@ static void nss_setgrent(void)
{
NSS_STATUS (*_nss_setgrent)(void) = find_fn("setgrent");
NSS_STATUS status;
+
+ if (!_nss_setgrent)
+ return;
+
status = _nss_setgrent();
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("setgrent", status);
@@ -231,6 +267,10 @@ static void nss_endgrent(void)
{
NSS_STATUS (*_nss_endgrent)(void) = find_fn("endgrent");
NSS_STATUS status;
+
+ if (!_nss_endgrent)
+ return;
+
status = _nss_endgrent();
if (status != NSS_STATUS_SUCCESS) {
report_nss_error("endgrent", status);
@@ -244,7 +284,8 @@ static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *sta
find_fn("initgroups_dyn");
NSS_STATUS status;
- if (!_nss_initgroups) return NSS_STATUS_UNAVAIL;
+ if (!_nss_initgroups)
+ return NSS_STATUS_UNAVAIL;
status = _nss_initgroups(user, group, start, size, groups, 0, &nss_errno);
if (status != NSS_STATUS_SUCCESS) {
diff --git a/source/torture/smbiconv.c b/source/torture/smbiconv.c
index ce21a09025e..3524136fb1e 100644
--- a/source/torture/smbiconv.c
+++ b/source/torture/smbiconv.c
@@ -198,6 +198,10 @@ int main(int argc, char *argv[])
while(poptGetNextOpt(pc) != -1);
+ /* the following functions are part of the Samba debugging
+ facilities. See lib/debug.c */
+ setup_logging("smbiconv", True);
+
if(preload)smb_load_modules(str_list_make(preload, NULL));
if(output) {
@@ -209,10 +213,6 @@ int main(int argc, char *argv[])
}
}
- /* the following functions are part of the Samba debugging
- facilities. See lib/debug.c */
- setup_logging("smbiconv", True);
-
cd = smb_iconv_open(to, from);
if((int)cd == -1) {
DEBUG(0,("unable to find from or to encoding, exiting...\n"));
diff --git a/source/torture/torture.c b/source/torture/torture.c
index 07d7f1547ed..f26ebb49b30 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -866,7 +866,7 @@ static BOOL run_locktest1(int dummy)
lock_timeout = (1 + (random() % 20));
printf("Testing lock timeout with timeout=%u\n", lock_timeout);
t1 = time(NULL);
- if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
+ if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 500, WRITE_LOCK)) {
printf("lock3 succeeded! This is a locking bug\n");
return False;
} else {
@@ -875,9 +875,10 @@ static BOOL run_locktest1(int dummy)
}
t2 = time(NULL);
- if (t2 - t1 < 5) {
+ if (ABS(t2 - t1) < lock_timeout-1) {
printf("error: This server appears not to support timed lock requests\n");
}
+
printf("server slept for %u seconds for a %u second timeout\n",
(unsigned int)(t2-t1), lock_timeout);
diff --git a/source/utils/editreg.c b/source/utils/editreg.c
index 92a39c39e2a..a0cfa2bb07d 100644
--- a/source/utils/editreg.c
+++ b/source/utils/editreg.c
@@ -412,16 +412,16 @@ typedef struct val_list_s {
#define MAXSUBAUTHS 15
#endif
-typedef struct dom_sid_s {
+typedef struct sid_s {
unsigned char ver, auths;
unsigned char auth[6];
unsigned int sub_auths[MAXSUBAUTHS];
-} DOM_SID;
+} sid_t;
typedef struct ace_struct_s {
unsigned char type, flags;
unsigned int perms; /* Perhaps a better def is in order */
- DOM_SID *trustee;
+ sid_t *trustee;
} ACE;
typedef struct acl_struct_s {
@@ -432,7 +432,7 @@ typedef struct acl_struct_s {
typedef struct sec_desc_s {
unsigned int rev, type;
- DOM_SID *owner, *group;
+ sid_t *owner, *group;
ACL *sacl, *dacl;
} SEC_DESC;
@@ -537,7 +537,7 @@ typedef struct ace_struct {
unsigned char flags;
unsigned short length;
unsigned int perms;
- DOM_SID trustee;
+ sid_t trustee;
} REG_ACE;
typedef struct acl_struct {
@@ -904,7 +904,7 @@ int nt_delete_key_by_name(REGF *regf, char *name)
}
static
-int nt_delete_sid(DOM_SID *sid)
+int nt_delete_sid(sid_t *sid)
{
if (sid) free(sid);
@@ -1099,7 +1099,7 @@ VAL_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value)
tmp = (VAL_KEY *)malloc(sizeof(VAL_KEY));
if (!tmp) goto error;
- bzero(tmp, sizeof(VAL_KEY));
+ memset(tmp, 0, sizeof(VAL_KEY));
tmp->name = strdup(name);
tmp->has_name = True;
if (!tmp->name) goto error;
@@ -1173,15 +1173,15 @@ VAL_KEY *nt_delete_reg_value(REG_KEY *key, char *name)
* Convert a string of the form S-1-5-x[-y-z-r] to a SID
*/
static
-int string_to_sid(DOM_SID **sid, const char *sid_str)
+int sid_string_to_sid(sid_t **sid, const char *sid_str)
{
int i = 0, auth;
const char *lstr;
- *sid = (DOM_SID *)malloc(sizeof(DOM_SID));
+ *sid = (sid_t *)malloc(sizeof(sid_t));
if (!*sid) return 0;
- bzero(*sid, sizeof(DOM_SID));
+ memset(*sid, 0, sizeof(sid_t));
if (strncmp(sid_str, "S-1-5", 5)) {
fprintf(stderr, "Does not conform to S-1-5...: %s\n", sid_str);
@@ -1226,7 +1226,7 @@ ACE *nt_create_ace(int type, int flags, unsigned int perms, const char *sid)
ace->type = type;
ace->flags = flags;
ace->perms = perms;
- if (!string_to_sid(&ace->trustee, sid))
+ if (!sid_string_to_sid(&ace->trustee, sid))
goto error;
return ace;
@@ -1287,8 +1287,8 @@ SEC_DESC *nt_create_def_sec_desc(REGF *regf)
tmp->rev = 1;
tmp->type = 0x8004;
- if (!string_to_sid(&tmp->owner, "S-1-5-32-544")) goto error;
- if (!string_to_sid(&tmp->group, "S-1-5-18")) goto error;
+ if (!sid_string_to_sid(&tmp->owner, "S-1-5-32-544")) goto error;
+ if (!sid_string_to_sid(&tmp->group, "S-1-5-18")) goto error;
tmp->sacl = NULL;
tmp->dacl = nt_create_default_acl(regf);
@@ -1402,7 +1402,7 @@ REG_KEY *nt_add_reg_key_list(REGF *regf, REG_KEY *key, char * name, int create)
tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
- bzero(tmp, sizeof(REG_KEY));
+ memset(tmp, 0, sizeof(REG_KEY));
tmp->name = strdup(c1);
if (!tmp->name) goto error;
@@ -1466,7 +1466,7 @@ REG_KEY *nt_add_reg_key(REGF *regf, char *name, int create)
tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
if (!tmp) goto error;
- bzero(tmp, sizeof(REG_KEY));
+ memset(tmp, 0, sizeof(REG_KEY));
tmp->name = strdup(c1);
if (!tmp->name) goto error;
tmp->security = nt_create_init_sec(regf);
@@ -1654,7 +1654,7 @@ REGF *nt_create_regf(void)
{
REGF *tmp = (REGF *)malloc(sizeof(REGF));
if (!tmp) return tmp;
- bzero(tmp, sizeof(REGF));
+ memset(tmp, 0, sizeof(REGF));
tmp->owner_sid_str = def_owner_sid_str;
return tmp;
}
@@ -1815,7 +1815,7 @@ KEY_SEC_DESC *lookup_create_sec_key(REGF *regf, SK_MAP *sk_map, int sk_off)
if (!tmp) {
return NULL;
}
- bzero(tmp, sizeof(KEY_SEC_DESC)); /* Neatly sets offset to 0 */
+ memset(tmp, 0, sizeof(KEY_SEC_DESC)); /* Neatly sets offset to 0 */
tmp->state = SEC_DESC_RES;
if (!alloc_sk_map_entry(regf, tmp, sk_off)) {
return NULL;
@@ -1829,9 +1829,9 @@ KEY_SEC_DESC *lookup_create_sec_key(REGF *regf, SK_MAP *sk_map, int sk_off)
* We could allocate the SID to be only the size needed, but I am too lazy.
*/
static
-DOM_SID *dup_sid(DOM_SID *sid)
+sid_t *dup_sid(sid_t *sid)
{
- DOM_SID *tmp = (DOM_SID *)malloc(sizeof(DOM_SID));
+ sid_t *tmp = (sid_t *)malloc(sizeof(sid_t));
int i;
if (!tmp) return NULL;
@@ -1916,12 +1916,12 @@ SEC_DESC *process_sec_desc(REGF *regf, REG_SEC_DESC *sec_desc)
IVAL(&sec_desc->group_off));
if (verbose) fprintf(stdout, "SEC_DESC DACL Off: %0X\n",
IVAL(&sec_desc->dacl_off));
- tmp->owner = dup_sid((DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->owner_off)));
+ tmp->owner = dup_sid((sid_t *)((char *)sec_desc + IVAL(&sec_desc->owner_off)));
if (!tmp->owner) {
free(tmp);
return NULL;
}
- tmp->group = dup_sid((DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->group_off)));
+ tmp->group = dup_sid((sid_t *)((char *)sec_desc + IVAL(&sec_desc->group_off)));
if (!tmp->group) {
free(tmp);
return NULL;
@@ -1991,7 +1991,7 @@ KEY_SEC_DESC *process_sk(REGF *regf, SK_HDR *sk_hdr, int sk_off, int size)
if (!tmp) {
tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
if (!tmp) return NULL;
- bzero(tmp, sizeof(KEY_SEC_DESC));
+ memset(tmp, 0, sizeof(KEY_SEC_DESC));
/*
* Allocate an entry in the SK_MAP ...
@@ -2059,7 +2059,7 @@ VAL_KEY *process_vk(REGF *regf, VK_HDR *vk_hdr, int size)
if (!tmp) {
goto error;
}
- bzero(tmp, sizeof(VAL_KEY));
+ memset(tmp, 0, sizeof(VAL_KEY));
tmp->has_name = flag;
tmp->data_type = dat_type;
@@ -2268,7 +2268,7 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent)
/* Allocate the key struct now */
tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
if (!tmp) return tmp;
- bzero(tmp, sizeof(REG_KEY));
+ memset(tmp, 0, sizeof(REG_KEY));
tmp->type = (SVAL(&nk_hdr->type)==0x2C?REG_ROOT_KEY:REG_SUB_KEY);
@@ -2295,7 +2295,7 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent)
clsnamep = LOCN(regf->base, clsnam_off);
if (verbose) fprintf(stdout, "Class Name Offset: %0X\n", clsnam_off);
- bzero(cls_name, clsname_len);
+ memset(cls_name, 0, clsname_len);
uni_to_ascii(clsnamep, cls_name, sizeof(cls_name), clsname_len);
/*
@@ -2494,12 +2494,12 @@ HBIN_BLK *nt_create_hbin_blk(REGF *regf, int size)
size = (size + (REGF_HDR_BLKSIZ - 1)) & ~(REGF_HDR_BLKSIZ - 1);
tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK));
- bzero(tmp, sizeof(HBIN_BLK));
+ memset(tmp, 0, sizeof(HBIN_BLK));
tmp->data = malloc(size);
if (!tmp->data) goto error;
- bzero(tmp->data, size); /* Make it pristine */
+ memset(tmp->data, 0, size); /* Make it pristine */
tmp->size = size;
tmp->file_offset = regf->blk_tail->file_offset + regf->blk_tail->size;
@@ -2618,7 +2618,7 @@ void *nt_alloc_regf_space(REGF *regf, int size, unsigned int *off)
* Compute the size of a SID stored ...
*/
static
-unsigned int sid_size(DOM_SID *sid)
+unsigned int sid_size(sid_t *sid)
{
unsigned int size;
@@ -2686,7 +2686,7 @@ unsigned int sec_desc_size(SEC_DESC *sd)
* Store a SID at the location provided
*/
static
-int nt_store_SID(REGF *regf, DOM_SID *sid, unsigned char *locn)
+int nt_store_SID(REGF *regf, sid_t *sid, unsigned char *locn)
{
int i;
unsigned char *p = locn;
@@ -2986,13 +2986,13 @@ REGF_HDR *nt_get_reg_header(REGF *regf)
tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK));
if (!tmp) return 0;
- bzero(tmp, sizeof(HBIN_BLK));
+ memset(tmp, 0, sizeof(HBIN_BLK));
tmp->type = REG_OUTBLK_HDR;
tmp->size = REGF_HDR_BLKSIZ;
tmp->data = malloc(REGF_HDR_BLKSIZ);
if (!tmp->data) goto error;
- bzero(tmp->data, REGF_HDR_BLKSIZ); /* Make it pristine, unlike Windows */
+ memset(tmp->data, 0, REGF_HDR_BLKSIZ); /* Make it pristine, unlike Windows */
regf->blk_head = regf->blk_tail = tmp;
return (REGF_HDR *)tmp->data;
@@ -3864,7 +3864,7 @@ void print_perms(int perms)
}
static
-void print_sid(DOM_SID *sid)
+void print_sid(sid_t *sid)
{
int i, comps = sid->auths;
fprintf(stdout, "S-%u-%u", sid->ver, sid->auth[5]);
@@ -3921,7 +3921,7 @@ int print_val(const char *path, char *val_name, int val_type, int data_len,
{
char data_asc[1024];
- bzero(data_asc, sizeof(data_asc));
+ memset(data_asc, 0, sizeof(data_asc));
if (!terminal && first)
fprintf(stdout, "%s\n", path);
data_to_ascii((unsigned char *)data_blk, data_len, val_type, data_asc,
@@ -3955,7 +3955,7 @@ int main(int argc, char *argv[])
char *cmd_file_name = NULL;
char *out_file_name = NULL;
CMD_FILE *cmd_file = NULL;
- DOM_SID *lsid;
+ sid_t *lsid;
if (argc < 2) {
usage();
@@ -3987,7 +3987,7 @@ int main(int argc, char *argv[])
case 'O':
def_owner_sid_str = strdup(optarg);
regf_opt += 2;
- if (!string_to_sid(&lsid, def_owner_sid_str)) {
+ if (!sid_string_to_sid(&lsid, def_owner_sid_str)) {
fprintf(stderr, "Default Owner SID: %s is incorrectly formatted\n",
def_owner_sid_str);
free(&def_owner_sid_str[0]);
diff --git a/source/utils/net.c b/source/utils/net.c
index aa245a920a7..25a752179f3 100644
--- a/source/utils/net.c
+++ b/source/utils/net.c
@@ -206,7 +206,7 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
if (is_zero_ip(pdc_ip))
return False;
- if (!lookup_dc_name(global_myname(), opt_target_workgroup, &pdc_ip, dc_name))
+ if ( !name_status_find(opt_target_workgroup, 0x1b, 0x20, pdc_ip, dc_name) )
return False;
*server_name = strdup(dc_name);
@@ -248,20 +248,18 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
}
-BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
+BOOL net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
{
if (get_pdc_ip(domain_name, server_ip)) {
- fstring dc_name;
-
if (is_zero_ip(*server_ip))
return False;
- if (!lookup_dc_name(global_myname(), domain_name, server_ip, dc_name))
+ if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name))
return False;
- fstrcpy(server_name, dc_name);
- return True;
- } else
+ return True;
+ }
+ else
return False;
}
@@ -348,26 +346,6 @@ static int net_file(int argc, const char **argv)
return net_rap_file(argc, argv);
}
-/***********************************************************
- migrated functionality from smbgroupedit
- **********************************************************/
-static int net_groupmap(int argc, const char **argv)
-{
- if ( 0 == argc )
- return net_help_groupmap( argc, argv );
-
- if ( !StrCaseCmp( argv[0], "add" ) )
- return net_groupmap_add(argc-1, argv+1);
- else if ( !StrCaseCmp( argv[0], "modify" ) )
- return net_groupmap_modify(argc-1, argv+1);
- else if ( !StrCaseCmp( argv[0], "delete" ) )
- return net_groupmap_delete(argc-1, argv+1);
- else if ( !StrCaseCmp( argv[0], "list" ) )
- return net_groupmap_list(argc-1, argv+1);
-
- return net_help_groupmap( argc, argv );
-}
-
/*
Retrieve our local SID or the SID for the specified name
*/
@@ -471,7 +449,7 @@ static uint32 get_maxrid(void)
pdb_free_sam(&pwd);
if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries,
- ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV))
+ ENUM_ONLY_MAPPED))
return max_rid;
for (i = 0; i < num_entries; i++) {
@@ -544,6 +522,7 @@ static struct functable net_func[] = {
{"SETLOCALSID", net_setlocalsid},
{"GETDOMAINSID", net_getdomainsid},
{"MAXRID", net_maxrid},
+ {"IDMAP", net_idmap},
{"HELP", net_help},
{NULL, NULL}
@@ -655,6 +634,10 @@ static struct functable net_func[] = {
exit(1);
load_interfaces();
+
+ /* this makes sure that when we do things like call scripts,
+ that it won't assert becouse we are not root */
+ sec_init();
if (opt_machine_pass) {
char *user = NULL;
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index 5051f181881..9454cbc9f5d 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -899,20 +899,34 @@ static int net_ads_password(int argc, const char **argv)
const char *auth_password = opt_password;
char *realm = NULL;
char *new_password = NULL;
- char *c;
- char *prompt;
+ char *c, *prompt;
+ const char *user;
ADS_STATUS ret;
+ if (opt_user_name == NULL || opt_password == NULL) {
+ d_printf("You must supply an administrator username/password\n");
+ return -1;
+ }
+
- if ((argc != 1) || (opt_user_name == NULL) ||
- (opt_password == NULL) || (strchr(opt_user_name, '@') == NULL) ||
- (strchr(argv[0], '@') == NULL)) {
- return net_ads_usage(argc, argv);
+ if (argc != 1) {
+ d_printf("ERROR: You must say which username to change password for\n");
+ return -1;
+ }
+
+ user = argv[0];
+ if (!strchr(user, '@')) {
+ asprintf(&c, "%s@%s", argv[0], lp_realm());
+ user = c;
}
use_in_memory_ccache();
c = strchr(auth_principal, '@');
- realm = ++c;
+ if (c) {
+ realm = ++c;
+ } else {
+ realm = lp_realm();
+ }
/* use the realm so we can eventually change passwords for users
in realms other than default */
@@ -927,12 +941,12 @@ static int net_ads_password(int argc, const char **argv)
return -1;
}
- asprintf(&prompt, "Enter new password for %s:", argv[0]);
+ asprintf(&prompt, "Enter new password for %s:", user);
new_password = getpass(prompt);
ret = kerberos_set_password(ads->auth.kdc_server, auth_principal,
- auth_password, argv[0], new_password, ads->auth.time_offset);
+ auth_password, user, new_password, ads->auth.time_offset);
if (!ADS_ERR_OK(ret)) {
d_printf("Password change failed :-( ...\n");
ads_destroy(&ads);
@@ -940,7 +954,7 @@ static int net_ads_password(int argc, const char **argv)
return -1;
}
- d_printf("Password change for %s completed.\n", argv[0]);
+ d_printf("Password change for %s completed.\n", user);
ads_destroy(&ads);
free(prompt);
@@ -1018,7 +1032,7 @@ static int net_ads_search(int argc, const char **argv)
{
ADS_STRUCT *ads;
ADS_STATUS rc;
- const char *exp;
+ const char *ldap_exp;
const char **attrs;
void *res = NULL;
@@ -1030,12 +1044,12 @@ static int net_ads_search(int argc, const char **argv)
return -1;
}
- exp = argv[0];
+ ldap_exp = argv[0];
attrs = (argv + 1);
rc = ads_do_search_all(ads, ads->config.bind_path,
LDAP_SCOPE_SUBTREE,
- exp, attrs, &res);
+ ldap_exp, attrs, &res);
if (!ADS_ERR_OK(rc)) {
d_printf("search failed: %s\n", ads_errstr(rc));
return -1;
diff --git a/source/utils/net_groupmap.c b/source/utils/net_groupmap.c
index 905fdf62871..590a005e176 100644
--- a/source/utils/net_groupmap.c
+++ b/source/utils/net_groupmap.c
@@ -65,7 +65,7 @@ static BOOL get_sid_from_input(DOM_SID *sid, char *input)
if (StrnCaseCmp( input, "S-", 2)) {
/* Perhaps its the NT group name? */
- if (!pdb_getgrnam(&map, input, MAPPING_WITHOUT_PRIV)) {
+ if (!pdb_getgrnam(&map, input)) {
printf("NT Group %s doesn't exist in mapping DB\n", input);
return False;
} else {
@@ -88,11 +88,9 @@ static void print_map_entry ( GROUP_MAP map, BOOL long_list )
{
fstring string_sid;
fstring group_type;
- fstring priv_text;
decode_sid_name_use(group_type, map.sid_name_use);
sid_to_string(string_sid, &map.sid);
- convert_priv_to_text(&(map.priv_set), priv_text);
if (!long_list)
d_printf("%s (%s) -> %s\n", map.nt_name, string_sid, gidtoname(map.gid));
@@ -102,14 +100,13 @@ static void print_map_entry ( GROUP_MAP map, BOOL long_list )
d_printf("\tUnix group: %s\n", gidtoname(map.gid));
d_printf("\tGroup type: %s\n", group_type);
d_printf("\tComment : %s\n", map.comment);
- d_printf("\tPrivilege : %s\n\n", priv_text);
}
}
/*********************************************************
List the groups.
**********************************************************/
-int net_groupmap_list(int argc, const char **argv)
+static int net_groupmap_list(int argc, const char **argv)
{
int entries;
BOOL long_list = False;
@@ -155,23 +152,21 @@ int net_groupmap_list(int argc, const char **argv)
}
/* Get the current mapping from the database */
- if(!pdb_getgrsid(&map, sid, MAPPING_WITH_PRIV)) {
+ if(!pdb_getgrsid(&map, sid)) {
d_printf("Failure to local group SID in the database\n");
return -1;
}
print_map_entry( map, long_list );
- free_privilege(&(map.priv_set));
}
else {
GROUP_MAP *map=NULL;
/* enumerate all group mappings */
- if ( !pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &entries, ENUM_ALL_MAPPED, MAPPING_WITH_PRIV) )
+ if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &entries, ENUM_ALL_MAPPED))
return -1;
for (i=0; i<entries; i++) {
print_map_entry( map[i], long_list );
- free_privilege(&(map[i].priv_set));
}
}
@@ -182,9 +177,8 @@ int net_groupmap_list(int argc, const char **argv)
Add a new group mapping entry
**********************************************************/
-int net_groupmap_add(int argc, const char **argv)
+static int net_groupmap_add(int argc, const char **argv)
{
- PRIVILEGE_SET se_priv;
DOM_SID sid;
fstring ntgroup = "";
fstring unixgrp = "";
@@ -280,25 +274,16 @@ int net_groupmap_add(int argc, const char **argv)
fstrcpy( ntgroup, unixgrp );
- init_privilege(&se_priv);
-#if 0
- if (privilege!=NULL)
- convert_priv_from_text(&se_priv, privilege);
-#endif
-
- if (!add_initial_entry(gid, string_sid, sid_type, ntgroup,
- ntcomment, se_priv, PR_ACCESS_FROM_NETWORK) ) {
+ if (!add_initial_entry(gid, string_sid, sid_type, ntgroup, ntcomment)) {
d_printf("adding entry for group %s failed!\n", ntgroup);
return -1;
}
- free_privilege(&se_priv);
-
d_printf("Successully added group %s to the mapping db\n", ntgroup);
return 0;
}
-int net_groupmap_modify(int argc, const char **argv)
+static int net_groupmap_modify(int argc, const char **argv)
{
DOM_SID sid;
GROUP_MAP map;
@@ -381,7 +366,7 @@ int net_groupmap_modify(int argc, const char **argv)
}
/* Get the current mapping from the database */
- if(!pdb_getgrsid(&map, sid, MAPPING_WITH_PRIV)) {
+ if(!pdb_getgrsid(&map, sid)) {
d_printf("Failure to local group SID in the database\n");
return -1;
}
@@ -390,9 +375,8 @@ int net_groupmap_modify(int argc, const char **argv)
* Allow changing of group type only between domain and local
* We disallow changing Builtin groups !!! (SID problem)
*/
- if ( sid_type != SID_NAME_UNKNOWN )
- {
- if ( map.sid_name_use == SID_NAME_WKN_GRP ) {
+ if (sid_type != SID_NAME_UNKNOWN) {
+ if (map.sid_name_use == SID_NAME_WKN_GRP) {
d_printf("You can only change between domain and local groups.\n");
return -1;
}
@@ -418,26 +402,17 @@ int net_groupmap_modify(int argc, const char **argv)
map.gid = gid;
}
-#if 0
- /* Change the privilege if new one */
- if (privilege!=NULL)
- convert_priv_from_text(&map.priv_set, privilege);
-#endif
-
if ( !pdb_update_group_mapping_entry(&map) ) {
d_printf("Could not update group database\n");
- free_privilege(&map.priv_set);
return -1;
}
- free_privilege(&map.priv_set);
-
d_printf("Updated mapping entry for %s\n", ntgroup);
return 0;
}
-int net_groupmap_delete(int argc, const char **argv)
+static int net_groupmap_delete(int argc, const char **argv)
{
DOM_SID sid;
fstring ntgroup = "";
@@ -491,3 +466,45 @@ int net_groupmap_delete(int argc, const char **argv)
return 0;
}
+int net_help_groupmap(int argc, const char **argv)
+{
+ d_printf("net groupmap add"\
+ "\n Create a new group mapping\n");
+ d_printf("net groupmap modify"\
+ "\n Update a group mapping\n");
+ d_printf("net groupmap delete"\
+ "\n Remove a group mapping\n");
+ d_printf("net groupmap list"\
+ "\n List current group map\n");
+
+ return -1;
+}
+
+
+/***********************************************************
+ migrated functionality from smbgroupedit
+ **********************************************************/
+int net_groupmap(int argc, const char **argv)
+{
+ struct functable func[] = {
+ {"add", net_groupmap_add},
+ {"modify", net_groupmap_modify},
+ {"delete", net_groupmap_delete},
+ {"list", net_groupmap_list},
+ {"help", net_help_groupmap},
+ {NULL, NULL}
+ };
+
+ /* we shouldn't have silly checks like this */
+ if (getuid() != 0) {
+ d_printf("You must be root to edit group mappings.\nExiting...\n");
+ return -1;
+ }
+
+ return net_run_function(argc, argv, func, net_help_groupmap);
+ if ( 0 == argc )
+ return net_help_groupmap( argc, argv );
+
+ return net_help_groupmap( argc, argv );
+}
+
diff --git a/source/utils/net_help.c b/source/utils/net_help.c
index f24367f246b..1f3afb1690e 100644
--- a/source/utils/net_help.c
+++ b/source/utils/net_help.c
@@ -99,26 +99,6 @@ int net_help_group(int argc, const char **argv)
return -1;
}
-int net_help_groupmap(int argc, const char **argv)
-{
- if (getuid() != 0) {
- d_printf("You must be root to edit group mappings.\nExiting...\n");
- return -1;
- }
-
- d_printf("net groupmap add"\
- "\n Create a new group mapping\n");
- d_printf("net groupmap modify"\
- "\n Update a group mapping\n");
- d_printf("net groupmap delete"\
- "\n Remove a group mapping\n");
- d_printf("net groupmap list"\
- "\n List current group map\n");
-
- return -1;
-}
-
-
int net_help_join(int argc, const char **argv)
{
d_printf("\nnet [<method>] join [misc. options]\n"
diff --git a/source/utils/net_idmap.c b/source/utils/net_idmap.c
new file mode 100644
index 00000000000..689d4ff8137
--- /dev/null
+++ b/source/utils/net_idmap.c
@@ -0,0 +1,156 @@
+/*
+ Samba Unix/Linux SMB client library
+ Distributed SMB/CIFS Server Management Utility
+ Copyright (C) 2003 Andrew Bartlett (abartlet@samba.org)
+
+ 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 "../utils/net.h"
+
+
+/***********************************************************
+ Helper function for net_idmap_dump. Dump one entry.
+ **********************************************************/
+static int net_idmap_dump_one_entry(TDB_CONTEXT *tdb,
+ TDB_DATA key,
+ TDB_DATA data,
+ void *unused)
+{
+ if (strcmp(key.dptr, "USER HWM") == 0) {
+ printf("USER HWM %d\n", IVAL(data.dptr,0));
+ return 0;
+ }
+
+ if (strcmp(key.dptr, "GROUP HWM") == 0) {
+ printf("GROUP HWM %d\n", IVAL(data.dptr,0));
+ return 0;
+ }
+
+ if (strncmp(key.dptr, "S-", 2) != 0)
+ return 0;
+
+ printf("%s %s\n", data.dptr, key.dptr);
+ return 0;
+}
+
+/***********************************************************
+ Dump the current idmap
+ **********************************************************/
+static int net_idmap_dump(int argc, const char **argv)
+{
+ TDB_CONTEXT *idmap_tdb;
+
+ if ( argc != 1 )
+ return net_help_idmap( argc, argv );
+
+ idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0);
+
+ if (idmap_tdb == NULL) {
+ d_printf("Could not open idmap: %s\n", argv[0]);
+ return -1;
+ }
+
+ tdb_traverse(idmap_tdb, net_idmap_dump_one_entry, NULL);
+
+ tdb_close(idmap_tdb);
+
+ return 0;
+}
+
+/***********************************************************
+ Write entries from stdin to current local idmap
+ **********************************************************/
+static int net_idmap_restore(int argc, const char **argv)
+{
+ if (!idmap_init(lp_idmap_backend())) {
+ d_printf("Could not init idmap\n");
+ return -1;
+ }
+
+ while (!feof(stdin)) {
+ fstring line, sid_string;
+ int len;
+ unid_t id;
+ int type = ID_EMPTY;
+ DOM_SID sid;
+
+ if (fgets(line, sizeof(line)-1, stdin) == NULL)
+ break;
+
+ len = strlen(line);
+
+ if ( (len > 0) && (line[len-1] == '\n') )
+ line[len-1] = '\0';
+
+ if (sscanf(line, "GID %d %s", &id.gid, sid_string) == 2) {
+ type = ID_GROUPID;
+ }
+
+ if (sscanf(line, "UID %d %s", &id.uid, sid_string) == 2) {
+ type = ID_USERID;
+ }
+
+ if (type == ID_EMPTY) {
+ d_printf("ignoring invalid line [%s]\n", line);
+ continue;
+ }
+
+ if (!string_to_sid(&sid, sid_string)) {
+ d_printf("ignoring invalid sid [%s]\n", sid_string);
+ continue;
+ }
+
+ if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, type))) {
+ d_printf("Could not set mapping of %s %d to sid %s\n",
+ (type == ID_GROUPID) ? "GID" : "UID",
+ (type == ID_GROUPID) ? id.gid : id.uid,
+ sid_string_static(&sid));
+ continue;
+ }
+
+ }
+
+ idmap_close();
+ return 0;
+}
+
+int net_help_idmap(int argc, const char **argv)
+{
+ d_printf("net idmap dump filename"\
+ "\n Dump current id mapping\n");
+
+ d_printf("net idmap restore"\
+ "\n Restore entries from stdin to current local idmap\n");
+
+ return -1;
+}
+
+/***********************************************************
+ Look at the current idmap
+ **********************************************************/
+int net_idmap(int argc, const char **argv)
+{
+ struct functable func[] = {
+ {"dump", net_idmap_dump},
+ {"restore", net_idmap_restore},
+ {"help", net_help_idmap},
+ {NULL, NULL}
+ };
+
+ return net_run_function(argc, argv, func, net_help_idmap);
+}
+
+
diff --git a/source/utils/net_lookup.c b/source/utils/net_lookup.c
index 271094480c3..8456da4e0cb 100644
--- a/source/utils/net_lookup.c
+++ b/source/utils/net_lookup.c
@@ -124,11 +124,11 @@ static int net_lookup_ldap(int argc, const char **argv)
static int net_lookup_dc(int argc, const char **argv)
{
- struct in_addr *ip_list, addr;
+ struct ip_service *ip_list;
+ struct in_addr addr;
char *pdc_str = NULL;
const char *domain=opt_target_workgroup;
int count, i;
- BOOL list_ordered;
if (argc > 0)
domain=argv[0];
@@ -140,12 +140,12 @@ static int net_lookup_dc(int argc, const char **argv)
asprintf(&pdc_str, "%s", inet_ntoa(addr));
d_printf("%s\n", pdc_str);
- if (!get_dc_list(domain, &ip_list, &count, &list_ordered)) {
+ if (!get_sorted_dc_list(domain, &ip_list, &count, False)) {
SAFE_FREE(pdc_str);
return 0;
}
for (i=0;i<count;i++) {
- char *dc_str = inet_ntoa(ip_list[i]);
+ char *dc_str = inet_ntoa(ip_list[i].ip);
if (!strequal(pdc_str, dc_str))
d_printf("%s\n", dc_str);
}
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index 544525b705a..552aacebbd0 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -915,7 +915,7 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
{
POLICY_HND connect_pol, domain_pol;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- uint32 start_idx=0, max_entries=250, num_entries, i;
+ uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
struct acct_info *groups;
DOM_SID global_sid_Builtin;
@@ -943,32 +943,73 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
d_printf("\nGroup name Comment"\
"\n-----------------------------\n");
do {
- result = cli_samr_enum_dom_groups(cli, mem_ctx, &domain_pol,
- &start_idx, max_entries,
- &groups, &num_entries);
+ SAM_DISPINFO_CTR ctr;
+ SAM_DISPINFO_3 info3;
+ uint32 max_size;
+
+ ZERO_STRUCT(ctr);
+ ZERO_STRUCT(info3);
+ ctr.sam.info3 = &info3;
+
+ get_query_dispinfo_params(
+ loop_count, &max_entries, &max_size);
+
+ result = cli_samr_query_dispinfo(cli, mem_ctx, &domain_pol,
+ &start_idx, 3, &num_entries,
+ max_entries, max_size, &ctr);
for (i = 0; i < num_entries; i++) {
+
+ fstring group, desc;
+
+ unistr2_to_ascii(group, &(&ctr.sam.info3->str[i])->uni_grp_name, sizeof(group)-1);
+ unistr2_to_ascii(desc, &(&ctr.sam.info3->str[i])->uni_grp_desc, sizeof(desc)-1);
+
if (opt_long_list_entries)
- printf("%-21.21s %-50.50s\n",
- groups[i].acct_name,
- groups[i].acct_desc);
+ printf("%-21.21s %-50.50s\n",
+ group, desc);
else
- printf("%-21.21s\n", groups[i].acct_name);
+ printf("%-21.21s\n", group);
}
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
/* query domain aliases */
+ start_idx = 0;
do {
result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
&start_idx, max_entries,
&groups, &num_entries);
-
+
for (i = 0; i < num_entries; i++) {
- if (opt_long_list_entries)
+
+ char *description = NULL;
+
+ if (opt_long_list_entries) {
+
+ POLICY_HND alias_pol;
+ ALIAS_INFO_CTR ctr;
+
+ if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
+ &domain_pol,
+ 0x8,
+ groups[i].rid,
+ &alias_pol))) &&
+ (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
+ &alias_pol, 3,
+ &ctr))) &&
+ (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
+ &alias_pol)))) {
+ description = unistr2_tdup(mem_ctx,
+ &ctr.alias.info3.uni_acct_desc);
+ }
+ }
+
+ if (description != NULL) {
printf("%-21.21s %-50.50s\n",
groups[i].acct_name,
- groups[i].acct_desc);
- else
+ description);
+ } else {
printf("%-21.21s\n", groups[i].acct_name);
+ }
}
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
cli_samr_close(cli, mem_ctx, &domain_pol);
@@ -981,18 +1022,43 @@ rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
goto done;
}
/* query builtin aliases */
+ start_idx = 0;
do {
result = cli_samr_enum_als_groups(cli, mem_ctx, &domain_pol,
&start_idx, max_entries,
&groups, &num_entries);
for (i = 0; i < num_entries; i++) {
- if (opt_long_list_entries)
+
+ char *description = NULL;
+
+ if (opt_long_list_entries) {
+
+ POLICY_HND alias_pol;
+ ALIAS_INFO_CTR ctr;
+
+ if ((NT_STATUS_IS_OK(cli_samr_open_alias(cli, mem_ctx,
+ &domain_pol,
+ 0x8,
+ groups[i].rid,
+ &alias_pol))) &&
+ (NT_STATUS_IS_OK(cli_samr_query_alias_info(cli, mem_ctx,
+ &alias_pol, 3,
+ &ctr))) &&
+ (NT_STATUS_IS_OK(cli_samr_close(cli, mem_ctx,
+ &alias_pol)))) {
+ description = unistr2_tdup(mem_ctx,
+ &ctr.alias.info3.uni_acct_desc);
+ }
+ }
+
+ if (description != NULL) {
printf("%-21.21s %-50.50s\n",
groups[i].acct_name,
- groups[i].acct_desc);
- else
- printf("%s\n", groups[i].acct_name);
+ description);
+ } else {
+ printf("%-21.21s\n", groups[i].acct_name);
+ }
}
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
@@ -1715,7 +1781,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
opt_user_name = acct_name;
/* find the domain controller */
- if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
+ if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
return -1;
}
diff --git a/source/utils/net_rpc_join.c b/source/utils/net_rpc_join.c
index e389cf8ef8d..e8fa39ec92d 100644
--- a/source/utils/net_rpc_join.c
+++ b/source/utils/net_rpc_join.c
@@ -49,7 +49,6 @@ int net_rpc_join_ok(const char *domain)
int retval = 1;
uint32 channel;
NTSTATUS result;
- uint32 neg_flags = 0x000001ff;
/* Connect to remote machine */
if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) {
@@ -68,10 +67,12 @@ int net_rpc_join_ok(const char *domain)
goto done;
}
- CHECK_RPC_ERR(cli_nt_setup_creds(cli,
- channel,
- stored_md4_trust_password, &neg_flags, 2),
- "error in domain join verification");
+ /* ensure that schannel uses the right domain */
+ fstrcpy(cli->domain, domain);
+ if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, channel, stored_md4_trust_password))) {
+ DEBUG(0,("Error in domain join verfication\n"));
+ goto done;
+ }
retval = 0; /* Success! */
@@ -131,7 +132,6 @@ int net_rpc_join_newstyle(int argc, const char **argv)
uint32 flags = 0x3e8;
char *acct_name;
const char *const_acct_name;
- uint32 neg_flags = 0x000001ff;
/* check what type of join */
if (argc >= 0) {
@@ -167,7 +167,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
/* Fetch domain sid */
if (!cli_nt_session_open(cli, PI_LSARPC)) {
- DEBUG(0, ("Error connecting to SAM pipe\n"));
+ DEBUG(0, ("Error connecting to LSA pipe\n"));
goto done;
}
@@ -240,7 +240,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
acct_name, nt_errstr(result)));
if (name_types[0] != SID_NAME_USER) {
- DEBUG(0, ("%s is not a user account\n", acct_name));
+ DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types[0]));
goto done;
}
@@ -315,11 +315,26 @@ int net_rpc_join_newstyle(int argc, const char **argv)
goto done;
}
- CHECK_RPC_ERR(cli_nt_setup_creds(cli,
- sec_channel_type,
- md4_trust_password, &neg_flags, 2),
- "error in domain join verification");
-
+ /* ensure that schannel uses the right domain */
+ fstrcpy(cli->domain, domain);
+
+ result = cli_nt_establish_netlogon(cli, sec_channel_type,
+ md4_trust_password);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("Error domain join verification: %s\n\n",
+ nt_errstr(result)));
+
+ if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) &&
+ (sec_channel_type == SEC_CHAN_BDC) ) {
+ d_printf("Please make sure that no computer account\n"
+ "named like this machine (%s) exists in the domain\n",
+ global_myname());
+ }
+
+ goto done;
+ }
+
/* Now store the secret in the secrets database */
strupper(domain);
@@ -366,7 +381,7 @@ done:
**/
int net_rpc_testjoin(int argc, const char **argv)
{
- char *domain = smb_xstrdup(lp_workgroup());
+ char *domain = smb_xstrdup(opt_target_workgroup);
/* Display success or failure */
if (net_rpc_join_ok(domain) != 0) {
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index ae6f52ebc41..ada2d274ba1 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -410,7 +410,9 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
GROUP_MAP map;
struct group *grp;
DOM_SID sid;
- BOOL try_add = False;
+ struct passwd *passwd;
+ unid_t id;
+ int u_type;
fstrcpy(account, unistr2_static(&delta->uni_acct_name));
d_printf("Creating account: %s\n", account);
@@ -418,7 +420,7 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
if (!NT_STATUS_IS_OK(nt_ret = pdb_init_sam(&sam_account)))
return nt_ret;
- if (!pdb_getsampwnam(sam_account, account)) {
+ if (!(passwd = Get_Pwnam(account))) {
/* Create appropriate user */
if (delta->acb_info & ACB_NORMAL) {
pstrcpy(add_script, lp_adduser_script());
@@ -429,8 +431,6 @@ fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
} else {
DEBUG(1, ("Unknown user type: %s\n",
smbpasswd_encode_acb_info(delta->acb_info)));
- pdb_free_sam(&sam_account);
- return NT_STATUS_NO_SUCH_USER;
}
if (*add_script) {
int add_ret;
@@ -439,45 +439,64 @@ 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));
- }
- try_add = True;
+ /* try and find the possible unix account again */
+ passwd = Get_Pwnam(account);
+ }
}
sam_account_from_delta(sam_account, delta);
-
- if (try_add) {
- if (!pdb_add_sam_account(sam_account)) {
- DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
- account));
- }
- } else {
+ if (!pdb_add_sam_account(sam_account)) {
+ DEBUG(1, ("SAM Account for %s failed to be added to the passdb!\n",
+ account));
if (!pdb_update_sam_account(sam_account)) {
DEBUG(1, ("SAM Account for %s failed to be updated in the passdb!\n",
account));
+ pdb_free_sam(&sam_account);
+ return NT_STATUS_OK;
+/* return NT_STATUS_ACCESS_DENIED; */
}
}
sid = *pdb_get_group_sid(sam_account);
- if (!pdb_getgrsid(&map, sid, False)) {
+ if (!pdb_getgrsid(&map, sid)) {
DEBUG(0, ("Primary group of %s has no mapping!\n",
pdb_get_username(sam_account)));
pdb_free_sam(&sam_account);
return NT_STATUS_NO_SUCH_GROUP;
}
-
- 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(&sid)));
+
+ if (!passwd) {
+ /* if no unix user, changing the mapping won't help */
pdb_free_sam(&sam_account);
- return NT_STATUS_NO_SUCH_GROUP;
+ return NT_STATUS_OK;
+ }
+
+ 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(&sid)));
+ pdb_free_sam(&sam_account);
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account));
+ }
+
+ nt_ret = idmap_get_id_from_sid(&id, &u_type, pdb_get_user_sid(sam_account));
+ if (!NT_STATUS_IS_OK(nt_ret)) {
+ pdb_free_sam(&sam_account);
+ return nt_ret;
}
- smb_set_primary_group(grp->gr_name, pdb_get_username(sam_account));
+ if ((u_type != ID_USERID) || (id.uid != passwd->pw_uid)) {
+ id.uid = passwd->pw_uid;
+ nt_ret = idmap_set_mapping(pdb_get_user_sid(sam_account), id, ID_USERID);
+ }
pdb_free_sam(&sam_account);
- return NT_STATUS_OK;
+ return nt_ret;
}
static NTSTATUS
@@ -499,7 +518,7 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
sid_append_rid(&group_sid, rid);
sid_to_string(sid_string, &group_sid);
- if (pdb_getgrsid(&map, group_sid, False)) {
+ if (pdb_getgrsid(&map, group_sid)) {
grp = getgrgid(map.gid);
insert = False;
}
@@ -525,9 +544,6 @@ fetch_group_info(uint32 rid, SAM_GROUP_INFO *delta)
fstrcpy(map.nt_name, name);
fstrcpy(map.comment, comment);
- map.priv_set.count = 0;
- map.priv_set.set = NULL;
-
if (insert)
pdb_add_group_mapping_entry(&map);
else
@@ -554,7 +570,7 @@ fetch_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *delta)
sid_copy(&group_sid, get_global_sam_sid());
sid_append_rid(&group_sid, rid);
- if (!get_domain_group_from_sid(group_sid, &map, False)) {
+ if (!get_domain_group_from_sid(group_sid, &map)) {
DEBUG(0, ("Could not find global group %d\n", rid));
return NT_STATUS_NO_SUCH_GROUP;
}
@@ -679,7 +695,7 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta,
sid_append_rid(&alias_sid, rid);
sid_to_string(sid_string, &alias_sid);
- if (pdb_getgrsid(&map, alias_sid, False)) {
+ if (pdb_getgrsid(&map, alias_sid)) {
grp = getgrgid(map.gid);
insert = False;
}
@@ -709,9 +725,6 @@ static NTSTATUS fetch_alias_info(uint32 rid, SAM_ALIAS_INFO *delta,
fstrcpy(map.nt_name, name);
fstrcpy(map.comment, comment);
- map.priv_set.count = 0;
- map.priv_set.set = NULL;
-
if (insert)
pdb_add_group_mapping_entry(&map);
else
@@ -899,7 +912,7 @@ fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
}
}
-static void
+static NTSTATUS
fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
DOM_SID dom_sid)
{
@@ -911,9 +924,8 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
SAM_DELTA_CTR *deltas;
uint32 num_deltas;
- if (!(mem_ctx = talloc_init("fetch_database"))) {
- return;
- }
+ if (!(mem_ctx = talloc_init("fetch_database")))
+ return NT_STATUS_NO_MEMORY;
switch( db_type ) {
case SAM_DATABASE_DOMAIN:
@@ -945,11 +957,15 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
for (i = 0; i < num_deltas; i++) {
fetch_sam_entry(&hdr_deltas[i], &deltas[i], dom_sid);
}
- }
+ } else
+ return result;
+
sync_context += 1;
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
talloc_destroy(mem_ctx);
+
+ return result;
}
/* dump sam database via samsync rpc calls */
@@ -990,10 +1006,27 @@ int rpc_vampire(int argc, const char **argv)
}
dom_sid = *get_global_sam_sid();
- fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, dom_sid);
+ result = fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, dom_sid);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ d_printf("Failed to fetch domain database: %s\n",
+ nt_errstr(result));
+ if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED))
+ d_printf("Perhaps %s is a Windows 2000 native mode "
+ "domain?\n", lp_workgroup());
+ goto fail;
+ }
sid_copy(&dom_sid, &global_sid_Builtin);
- fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds, dom_sid);
+
+ result = fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds,
+ dom_sid);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ d_printf("Failed to fetch builtin database: %s\n",
+ nt_errstr(result));
+ goto fail;
+ }
/* Currently we crash on PRIVS somewhere in unmarshalling */
/* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */
@@ -1003,8 +1036,8 @@ int rpc_vampire(int argc, const char **argv)
return 0;
fail:
- if (cli) {
+ if (cli)
cli_nt_session_close(cli);
- }
+
return -1;
}
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index d540bf42dec..3fa27513472 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -91,7 +91,7 @@ static int export_groups (struct pdb_context *in, struct pdb_context *out) {
if (NT_STATUS_IS_ERR(in->pdb_enum_group_mapping(in, SID_NAME_UNKNOWN,
&maps, &entries,
- False, False))) {
+ False))) {
fprintf(stderr, "Can't get group mappings!\n");
return 1;
}
@@ -485,7 +485,7 @@ static int delete_user_entry (struct pdb_context *in, const char *username)
return -1;
}
- if (NT_STATUS_IS_ERR(in->pdb_getsampwnam(in, samaccount, username))) {
+ if (!NT_STATUS_IS_OK(in->pdb_getsampwnam(in, samaccount, username))) {
fprintf (stderr, "user %s does not exist in the passdb\n", username);
return -1;
}
@@ -511,7 +511,7 @@ static int delete_machine_entry (struct pdb_context *in, const char *machinename
return -1;
}
- if (NT_STATUS_IS_ERR(in->pdb_getsampwnam(in, samaccount, name))) {
+ if (!NT_STATUS_IS_OK(in->pdb_getsampwnam(in, samaccount, name))) {
fprintf (stderr, "machine %s does not exist in the passdb\n", name);
return -1;
}
@@ -609,7 +609,7 @@ int main (int argc, char **argv)
if (!init_names())
exit(1);
- if (!idmap_init())
+ if (!idmap_init(lp_idmap_backend()))
exit(1);
if (!idmap_init_wellknown_sids())
diff --git a/source/utils/smbcacls.c b/source/utils/smbcacls.c
index 9d8a6577263..69dc2dd47a5 100644
--- a/source/utils/smbcacls.c
+++ b/source/utils/smbcacls.c
@@ -30,7 +30,6 @@ static int test_args = False;
static TALLOC_CTX *ctx;
#define CREATE_ACCESS_READ READ_CONTROL_ACCESS
-#define CREATE_ACCESS_WRITE (WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS)
/* numeric is set when the user wants numeric SIDs and ACEs rather
than going via LSA calls to resolve them */
@@ -506,11 +505,11 @@ static int owner_set(struct cli_state *cli, enum chown_mode change_mode,
}
sd = make_sec_desc(ctx,old->revision,
- (change_mode == REQUEST_CHOWN) ? &sid : old->owner_sid,
- (change_mode == REQUEST_CHGRP) ? &sid : old->grp_sid,
- NULL, old->dacl, &sd_size);
+ (change_mode == REQUEST_CHOWN) ? &sid : NULL,
+ (change_mode == REQUEST_CHGRP) ? &sid : NULL,
+ NULL, NULL, &sd_size);
- fnum = cli_nt_create(cli, filename, CREATE_ACCESS_WRITE);
+ fnum = cli_nt_create(cli, filename, WRITE_OWNER_ACCESS);
if (fnum == -1) {
printf("Failed to open %s: %s\n", filename, cli_errstr(cli));
@@ -680,10 +679,10 @@ static int cacl_set(struct cli_state *cli, char *filename,
sort_acl(old->dacl);
/* Create new security descriptor and set it */
- sd = make_sec_desc(ctx,old->revision, old->owner_sid, old->grp_sid,
+ sd = make_sec_desc(ctx,old->revision, NULL, NULL,
NULL, old->dacl, &sd_size);
- fnum = cli_nt_create(cli, filename, CREATE_ACCESS_WRITE);
+ fnum = cli_nt_create(cli, filename, WRITE_DAC_ACCESS);
if (fnum == -1) {
printf("cacl_set failed to open %s: %s\n", filename, cli_errstr(cli));
diff --git a/source/utils/smbcontrol.c b/source/utils/smbcontrol.c
index 06add6af228..e168cf7837c 100644
--- a/source/utils/smbcontrol.c
+++ b/source/utils/smbcontrol.c
@@ -34,7 +34,7 @@ static int num_replies; /* Used by message callback fns */
/* Send a message to a destination pid. Zero means broadcast smbd. */
-static BOOL send_message(pid_t pid, int msg_type, void *buf, int len,
+static BOOL send_message(pid_t pid, int msg_type, const void *buf, int len,
BOOL duplicates)
{
TDB_CONTEXT *tdb;
@@ -92,7 +92,7 @@ static void print_string_cb(int msg_type, pid_t pid, void *buf, size_t len)
/* Send no message. Useful for testing. */
-static BOOL do_noop(const pid_t pid, const int argc, char **argv)
+static BOOL do_noop(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> noop\n");
@@ -106,7 +106,7 @@ static BOOL do_noop(const pid_t pid, const int argc, char **argv)
/* Send a debug string */
-static BOOL do_debug(const pid_t pid, const int argc, char **argv)
+static BOOL do_debug(const pid_t pid, const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> debug "
@@ -120,7 +120,7 @@ static BOOL do_debug(const pid_t pid, const int argc, char **argv)
/* Force a browser election */
-static BOOL do_election(const pid_t pid, const int argc, char **argv)
+static BOOL do_election(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> force-election\n");
@@ -139,7 +139,7 @@ static void pong_cb(int msg_type, pid_t pid, void *buf, size_t len)
num_replies++;
}
-static BOOL do_ping(const pid_t pid, const int argc, char **argv)
+static BOOL do_ping(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> ping\n");
@@ -167,7 +167,7 @@ static BOOL do_ping(const pid_t pid, const int argc, char **argv)
/* Set profiling options */
-static BOOL do_profile(const pid_t pid, const int argc, char **argv)
+static BOOL do_profile(const pid_t pid, const int argc, const char **argv)
{
int v;
@@ -239,7 +239,7 @@ static void profilelevel_rqst(int msg_type, pid_t pid, void *buf, size_t len)
send_message(pid, MSG_PROFILELEVEL, &v, sizeof(int), False);
}
-static BOOL do_profilelevel(const pid_t pid, const int argc, char **argv)
+static BOOL do_profilelevel(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> profilelevel\n");
@@ -268,7 +268,7 @@ static BOOL do_profilelevel(const pid_t pid, const int argc, char **argv)
/* Display debug level settings */
-static BOOL do_debuglevel(const pid_t pid, const int argc, char **argv)
+static BOOL do_debuglevel(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> debuglevel\n");
@@ -296,9 +296,9 @@ static BOOL do_debuglevel(const pid_t pid, const int argc, char **argv)
/* Send a print notify message */
-static BOOL do_printnotify(const pid_t pid, const int argc, char **argv)
+static BOOL do_printnotify(const pid_t pid, const int argc, const char **argv)
{
- char *cmd;
+ const char *cmd;
/* Check for subcommand */
@@ -434,7 +434,7 @@ send:
/* Close a share */
-static BOOL do_closeshare(const pid_t pid, const int argc, char **argv)
+static BOOL do_closeshare(const pid_t pid, const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> close-share "
@@ -448,7 +448,7 @@ static BOOL do_closeshare(const pid_t pid, const int argc, char **argv)
/* Force a SAM synchronisation */
-static BOOL do_samsync(const pid_t pid, const int argc, char **argv)
+static BOOL do_samsync(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> samsync\n");
@@ -461,7 +461,7 @@ static BOOL do_samsync(const pid_t pid, const int argc, char **argv)
/* Force a SAM replication */
-static BOOL do_samrepl(const pid_t pid, const int argc, char **argv)
+static BOOL do_samrepl(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> samrepl\n");
@@ -474,7 +474,7 @@ static BOOL do_samrepl(const pid_t pid, const int argc, char **argv)
/* Display talloc pool usage */
-static BOOL do_poolusage(const pid_t pid, const int argc, char **argv)
+static BOOL do_poolusage(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> pool-usage\n");
@@ -502,7 +502,7 @@ static BOOL do_poolusage(const pid_t pid, const int argc, char **argv)
/* Perform a dmalloc mark */
-static BOOL do_dmalloc_mark(const pid_t pid, const int argc, char **argv)
+static BOOL do_dmalloc_mark(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> dmalloc-mark\n");
@@ -515,8 +515,7 @@ static BOOL do_dmalloc_mark(const pid_t pid, const int argc, char **argv)
/* Perform a dmalloc changed */
-static BOOL do_dmalloc_changed(const pid_t pid, const int argc,
- char **argv)
+static BOOL do_dmalloc_changed(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> "
@@ -530,7 +529,7 @@ static BOOL do_dmalloc_changed(const pid_t pid, const int argc,
/* Shutdown a server process */
-static BOOL do_shutdown(const pid_t pid, const int argc, char **argv)
+static BOOL do_shutdown(const pid_t pid, const int argc, const char **argv)
{
if (argc != 1) {
fprintf(stderr, "Usage: smbcontrol <dest> shutdown\n");
@@ -542,7 +541,7 @@ static BOOL do_shutdown(const pid_t pid, const int argc, char **argv)
/* Notify a driver upgrade */
-static BOOL do_drvupgrade(const pid_t pid, const int argc, char **argv)
+static BOOL do_drvupgrade(const pid_t pid, const int argc, const char **argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: smbcontrol <dest> drvupgrade "
@@ -558,7 +557,7 @@ static BOOL do_drvupgrade(const pid_t pid, const int argc, char **argv)
static const struct {
const char *name; /* Option name */
- BOOL (*fn)(const pid_t pid, const int argc, char **argv);
+ BOOL (*fn)(const pid_t pid, const int argc, const char **argv);
const char *help; /* Short help text */
} msg_types[] = {
{ "debug", do_debug, "Set debuglevel" },
@@ -613,7 +612,7 @@ static void usage(poptContext *pc)
/* Return the pid number for a string destination */
-static pid_t parse_dest(char *dest)
+static pid_t parse_dest(const char *dest)
{
pid_t pid;
@@ -644,9 +643,9 @@ static pid_t parse_dest(char *dest)
/* Execute smbcontrol command */
-static BOOL do_command(int argc, char **argv)
+static BOOL do_command(int argc, const char **argv)
{
- char *dest = argv[0], *command = argv[1];
+ const char *dest = argv[0], *command = argv[1];
pid_t pid;
int i;
@@ -669,7 +668,7 @@ static BOOL do_command(int argc, char **argv)
/* Main program */
-int main(int argc, char **argv)
+int main(int argc, const char **argv)
{
poptContext pc;
int opt;
@@ -726,7 +725,7 @@ int main(int argc, char **argv)
argv. The argc parameter should have been decremented to the
correct value in the above switch statement. */
- argv = (char **)poptGetArgs(pc);
+ argv = (const char **)poptGetArgs(pc);
argc--; /* Don't forget about argv[0] */
if (argc == 1)
diff --git a/source/utils/testparm.c b/source/utils/testparm.c
index e3d6ce02748..16918ecd4ae 100644
--- a/source/utils/testparm.c
+++ b/source/utils/testparm.c
@@ -183,6 +183,10 @@ via the %%o substitution. With encrypted passwords this is not possible.\n", lp_
}
#endif
+ if (!lp_passdb_backend()) {
+ printf("ERROR: passdb backend must have a value or be left out\n");
+ }
+
return ret;
}