summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/Makefile.in80
-rw-r--r--source/VERSION4
-rw-r--r--source/auth/auth_util.c74
-rwxr-xr-xsource/autogen.sh1
-rw-r--r--source/client/client.c6
-rw-r--r--source/configure.in3
-rw-r--r--source/groupdb/mapping.c13
-rw-r--r--source/include/ads.h3
-rw-r--r--source/include/client.h2
-rw-r--r--source/include/includes.h2
-rw-r--r--source/include/passdb.h6
-rw-r--r--source/include/privileges.h65
-rw-r--r--source/include/rpc_lsa.h20
-rw-r--r--source/include/rpc_misc.h7
-rw-r--r--source/include/rpc_reg.h40
-rw-r--r--source/include/rpc_samr.h8
-rw-r--r--source/include/smb.h8
-rw-r--r--source/include/smbldap.h3
-rw-r--r--source/include/vfs_macros.h4
-rw-r--r--source/lib/account_pol.c100
-rw-r--r--source/lib/privileges.c853
-rw-r--r--source/lib/select.c30
-rw-r--r--source/lib/smbldap.c103
-rw-r--r--source/lib/util.c15
-rw-r--r--source/lib/util_sid.c64
-rw-r--r--source/lib/util_str.c16
-rw-r--r--source/libads/kerberos.c2
-rw-r--r--source/libads/kerberos_verify.c2
-rw-r--r--source/libads/ldap.c20
-rw-r--r--source/libsmb/clientgen.c16
-rw-r--r--source/libsmb/clitrans.c4
-rw-r--r--source/modules/vfs_expand_msdfs.c4
-rw-r--r--source/modules/vfs_shadow_copy.c1
-rw-r--r--source/nsswitch/winbindd.h8
-rw-r--r--source/nsswitch/winbindd_ads.c1
-rw-r--r--source/nsswitch/winbindd_cache.c86
-rw-r--r--source/nsswitch/winbindd_cm.c26
-rw-r--r--source/nsswitch/winbindd_group.c41
-rw-r--r--source/nsswitch/winbindd_passdb.c8
-rw-r--r--source/nsswitch/winbindd_rpc.c62
-rw-r--r--source/param/loadparm.c10
-rw-r--r--source/passdb/passdb.c26
-rw-r--r--source/passdb/pdb_get_set.c18
-rw-r--r--source/passdb/pdb_interface.c12
-rw-r--r--source/passdb/pdb_ldap.c115
-rw-r--r--source/passdb/pdb_mysql.c5
-rw-r--r--source/passdb/pdb_pgsql.c2
-rw-r--r--source/passdb/pdb_smbpasswd.c2
-rw-r--r--source/passdb/pdb_sql.c8
-rw-r--r--source/passdb/pdb_tdb.c17
-rw-r--r--source/passdb/pdb_xml.c2
-rw-r--r--source/passdb/privileges.c341
-rw-r--r--source/passdb/util_sam_sid.c24
-rw-r--r--source/printing/load.c48
-rw-r--r--source/printing/nt_printing.c69
-rw-r--r--source/printing/pcap.c468
-rw-r--r--source/printing/print_aix.c111
-rw-r--r--source/printing/print_cups.c595
-rw-r--r--source/printing/print_svid.c69
-rw-r--r--source/printing/printing.c3
-rw-r--r--source/rpc_client/cli_dfs.c10
-rw-r--r--source/rpc_client/cli_ds.c4
-rw-r--r--source/rpc_client/cli_echo.c8
-rw-r--r--source/rpc_client/cli_lsarpc.c123
-rw-r--r--source/rpc_client/cli_netlogon.c20
-rw-r--r--source/rpc_client/cli_pipe.c76
-rw-r--r--source/rpc_client/cli_reg.c14
-rw-r--r--source/rpc_client/cli_samr.c92
-rw-r--r--source/rpc_client/cli_shutdown.c4
-rw-r--r--source/rpc_client/cli_spoolss.c74
-rw-r--r--source/rpc_client/cli_spoolss_notify.c10
-rw-r--r--source/rpc_client/cli_srvsvc.c16
-rw-r--r--source/rpc_client/cli_wkssvc.c2
-rw-r--r--source/rpc_parse/parse_lsa.c116
-rw-r--r--source/rpc_parse/parse_misc.c100
-rw-r--r--source/rpc_parse/parse_prs.c57
-rw-r--r--source/rpc_parse/parse_reg.c50
-rw-r--r--source/rpc_parse/parse_samr.c53
-rw-r--r--source/rpc_parse/parse_sec.c82
-rw-r--r--source/rpc_server/srv_lsa.c130
-rw-r--r--source/rpc_server/srv_lsa_nt.c492
-rw-r--r--source/rpc_server/srv_reg_nt.c126
-rw-r--r--source/rpc_server/srv_samr_nt.c552
-rw-r--r--source/rpc_server/srv_spoolss_nt.c84
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c152
-rw-r--r--source/rpcclient/cmd_lsarpc.c50
-rw-r--r--source/rpcclient/cmd_reg.c4
-rw-r--r--source/rpcclient/cmd_samr.c82
-rw-r--r--source/rpcclient/rpcclient.c18
-rw-r--r--source/sam/idmap_rid.c28
-rw-r--r--source/script/mkproto.awk2
-rw-r--r--source/smbd/conn.c4
-rw-r--r--source/smbd/ipc.c6
-rw-r--r--source/smbd/lanman.c2
-rw-r--r--source/smbd/message.c8
-rw-r--r--source/smbd/process.c15
-rw-r--r--source/smbd/server.c36
-rw-r--r--source/smbd/service.c37
-rw-r--r--source/torture/rpctorture.c6
-rw-r--r--source/torture/vfstest.c7
-rw-r--r--source/utils/net.c4
-rw-r--r--source/utils/net.h13
-rw-r--r--source/utils/net_help.c3
-rw-r--r--source/utils/net_rpc.c149
-rw-r--r--source/utils/net_rpc_join.c4
-rw-r--r--source/utils/net_rpc_rights.c413
-rw-r--r--source/utils/net_rpc_samsync.c8
-rw-r--r--source/utils/pdbedit.c6
-rw-r--r--source/utils/smbfilter.c4
-rw-r--r--source/utils/testprns.c18
-rw-r--r--source/web/cgi.c4
111 files changed, 4609 insertions, 2525 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index a6e434464fe..466958b5abb 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -310,7 +310,7 @@ PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o
PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
passdb/util_sam_sid.o passdb/pdb_compat.o \
- passdb/privileges.o passdb/lookup_sid.o \
+ passdb/lookup_sid.o \
passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o \
lib/system_smbd.o
@@ -397,7 +397,7 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
$(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(BUILDOPT_OBJ) $(SMBLDAP_OBJ)
-PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
+PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \
printing/print_cups.o printing/print_generic.o \
printing/lpq_parse.o printing/load.o
@@ -434,41 +434,41 @@ SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(LIBSMB_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(SECRETS_OBJ) $(KRBCLIENT_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
+ $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) \
$(PASSCHANGE_OBJ) $(DUMMYROOT_OBJ)
SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
- $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
+ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ)
STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
+ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
$(SECRETS_OBJ) $(LIBSAMBA_OBJ) $(DUMMYROOT_OBJ) $(ERRORMAP_OBJ)
SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
+ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
$(SECRETS_OBJ) $(LIBSAMBA_OBJ) \
$(PRINTBASE_OBJ) $(DUMMYROOT_OBJ) $(ERRORMAP_OBJ)
SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \
+ $(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) \
$(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ)
TESTPARM_OBJ = utils/testparm.o \
- $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
+ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
$(SECRETS_OBJ) $(LIBSAMBA_OBJ)
-TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
- $(LIB_NONSMBD_OBJ)
+TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) \
+ $(LIB_NONSMBD_OBJ) libsmb/nterr.o
SMBPASSWD_OBJ = utils/smbpasswd.o $(PASSCHANGE_OBJ) $(PARAM_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
+ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
$(SMBLDAP_OBJ) $(RPC_PARSE_OBJ) $(LIBMSRPC_OBJ) $(DUMMYROOT_OBJ)
PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(PASSDB_OBJ) $(LIBSAMBA_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \
+ $(LIB_NONSMBD_OBJ) $(GROUPDB_OBJ) $(SECRETS_OBJ) \
$(POPT_LIB_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ)
SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ)
@@ -481,7 +481,7 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \
rpcclient/cmd_echo.o rpcclient/cmd_shutdown.o
RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(LIBMSRPC_OBJ) \
$(READLINE_OBJ) $(GROUPDB_OBJ) $(KRBCLIENT_OBJ) \
$(LIBADS_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) \
@@ -497,7 +497,7 @@ SMBW_OBJ1 = smbwrapper/smbw.o \
smbwrapper/smbw_cache.o
SMBW_OBJ = $(SMBW_OBJ1) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
+ $(LIB_NONSMBD_OBJ)
SMBWRAPPER_OBJ1 = smbwrapper/wrapped.o
@@ -506,7 +506,7 @@ SMBWRAPPER_OBJ = $(SMBW_OBJ) $(SMBWRAPPER_OBJ1)
LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \
libsmb/libsmb_cache.o \
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \
+ $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
$(SECRETS_OBJ)
@@ -524,7 +524,7 @@ LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.@PICSUFFIX@)
CLIENT_OBJ1 = client/client.o client/clitar.o
-CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
+CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
$(READLINE_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ)
@@ -532,67 +532,67 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_ads_cldap.o utils/net_help.o \
utils/net_rap.o utils/net_rpc.o utils/net_rpc_samsync.o \
utils/net_rpc_join.o utils/net_time.o utils/net_lookup.o \
utils/net_cache.o utils/net_groupmap.o utils/net_idmap.o \
- utils/net_status.o utils/net_rpc_printer.o
+ utils/net_status.o utils/net_rpc_printer.o utils/net_rpc_rights.o
NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \
+ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \
$(LIBMSRPC_OBJ) $(IDMAP_OBJ) \
$(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) $(POPT_LIB_OBJ) \
$(SMBLDAP_OBJ) $(DCUTIL_OBJ) $(DUMMYROOT_OBJ) $(SERVER_MUTEX_OBJ) \
$(AFS_OBJ) $(AFS_SETTOKEN_OBJ)
-CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
+CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ)
MOUNT_OBJ = client/smbmount.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
MNT_OBJ = client/smbmnt.o $(VERSION_OBJ) $(SNPRINTF_OBJ)
UMOUNT_OBJ = client/smbumount.o
-NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBNMB_OBJ) \
+NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(LIBNMB_OBJ) \
$(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/utable.o \
torture/denytest.o torture/mangle_test.o
SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) \
- $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
+ $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ)
MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ)
+ $(LIB_NONSMBD_OBJ)
MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
+ $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
LOCKTEST_OBJ = torture/locktest.o $(PARAM_OBJ) $(LOCKING_OBJ) $(KRBCLIENT_OBJ) \
- $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)
+ $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)
NSSTEST_OBJ = torture/nsstest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
+ $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ)
VFSTEST_OBJ = torture/cmd_vfs.o torture/vfstest.o $(SMBD_OBJ_BASE) $(READLINE_OBJ)
-SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
+SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) $(LIBSAMBA_OBJ)
LOG2PCAP_OBJ = utils/log2pcaphex.o
LOCKTEST2_OBJ = torture/locktest2.o $(PARAM_OBJ) $(LOCKING_OBJ) $(LIBSMB_OBJ) \
- $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)
+ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(DUMMYROOT_OBJ) $(SECRETS_OBJ)
SMBCACLS_OBJ = utils/smbcacls.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
- $(KRBCLIENT_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
+ $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) \
$(PASSDB_GET_SET_OBJ) $(LIBMSRPC_OBJ) $(SECRETS_OBJ) \
$(POPT_LIB_OBJ) $(DCUTIL_OBJ) $(LIBADS_OBJ)
SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
$(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
+ $(LIB_NONSMBD_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \
$(LIBMSRPC_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
-TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ)
+TALLOCTORT_OBJ = lib/talloctort.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) libsmb/nterr.o
RPCTORTURE_OBJ = torture/rpctorture.o \
rpcclient/display.o \
@@ -601,13 +601,13 @@ RPCTORTURE_OBJ = torture/rpctorture.o \
rpcclient/cmd_samr.o \
rpcclient/cmd_srvsvc.o \
rpcclient/cmd_netlogon.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
$(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ)
DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o
SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(SECRETS_OBJ) \
- $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ)
+ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ)
PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(SMBD_OBJ_SRV) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \
@@ -623,7 +623,7 @@ PROTO_OBJ = $(SMBD_OBJ_MAIN) \
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
$(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ)
-WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) \
+WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) \
$(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ)
WINBIND_WINS_NSS_PICOBJS = $(WINBIND_WINS_NSS_OBJ:.o=.@PICSUFFIX@)
@@ -634,7 +634,7 @@ LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@)
PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \
$(DUMMYROOT_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(SECRETS_OBJ) $(UBIQX_OBJ) $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ)
+ $(SECRETS_OBJ) $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ)
PAM_SMBPASS_PICOOBJ = $(PAM_SMBPASS_OBJ_0:.o=.@PICSUFFIX@)
@@ -659,7 +659,7 @@ WINBINDD_OBJ1 = \
WINBINDD_OBJ = \
$(WINBINDD_OBJ1) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
- $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_NONSMBD_OBJ) \
+ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \
$(PROFILE_OBJ) $(SLCACHE_OBJ) $(SMBLDAP_OBJ) \
$(SECRETS_OBJ) $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \
@@ -667,7 +667,7 @@ WINBINDD_OBJ = \
$(AFS_OBJ) $(AFS_SETTOKEN_OBJ)
WBINFO_OBJ = nsswitch/wbinfo.o $(LIBSAMBA_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(UBIQX_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ) $(AFS_SETTOKEN_OBJ)
+ $(SECRETS_OBJ) $(POPT_LIB_OBJ) $(AFS_SETTOKEN_OBJ)
WINBIND_NSS_OBJ = $(WBCOMMON_OBJ) lib/replace1.o @WINBIND_NSS_EXTRA_OBJS@
@@ -1235,10 +1235,10 @@ bin/wbinfo@EXEEXT@: $(WBINFO_OBJ) @BUILD_POPT@ bin/.dummy
@$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(WBINFO_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@
bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(UBIQX_OBJ) @BUILD_POPT@ bin/.dummy
+ @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(LDFLAGS) $(DYNEXP) $(NTLM_AUTH_OBJ) \
- $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(LIBS) \
+ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBS) \
@POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ)
@@ -1336,7 +1336,7 @@ installclientlib: installdirs libsmbclient
# Python extensions
PYTHON_OBJS = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_OBJ) $(RPC_PARSE_OBJ) \
- $(UBIQX_OBJ) $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
+ $(LIBMSRPC_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(SECRETS_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(DUMMYROOT_OBJ)
PYTHON_PICOBJS = $(PYTHON_OBJS:.o=.@PICSUFFIX@)
diff --git a/source/VERSION b/source/VERSION
index e7bcb1326b0..aad6252e56a 100644
--- a/source/VERSION
+++ b/source/VERSION
@@ -29,7 +29,7 @@ SAMBA_VERSION_RELEASE=11
# e.g. SAMBA_VERSION_PRE_RELEASE=1 #
# -> "2.2.9pre1" #
########################################################
-SAMBA_VERSION_PRE_RELEASE=1
+SAMBA_VERSION_PRE_RELEASE=2
########################################################
# For 'rc' releases the version will be #
@@ -51,7 +51,7 @@ SAMBA_VERSION_RC_RELEASE=
# e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes #
# -> "3.0.0-SVN-build-199" #
########################################################
-SAMBA_VERSION_IS_SVN_SNAPSHOT=no
+SAMBA_VERSION_IS_SVN_SNAPSHOT=
########################################################
# This can be set by vendors if they want... #
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index 2eacc2b0d10..4a23ec8adc5 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -493,6 +493,8 @@ void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
for (i = 0; i < token->num_sids; i++)
DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i,
sid_to_string(sid_str, &token->user_sids[i])));
+
+ dump_se_priv( dbg_class, dbg_lev, &token->privileges );
}
/****************************************************************************
@@ -583,6 +585,10 @@ static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *gro
ptoken->num_sids--;
}
}
+
+ /* add privileges assigned to this user */
+
+ get_privileges_for_sids( &ptoken->privileges, ptoken->user_sids, ptoken->num_sids );
debug_nt_user_token(DBGC_AUTH, 10, ptoken);
@@ -1410,12 +1416,13 @@ BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_me
void delete_nt_token(NT_USER_TOKEN **pptoken)
{
- if (*pptoken) {
- NT_USER_TOKEN *ptoken = *pptoken;
- SAFE_FREE( ptoken->user_sids );
- ZERO_STRUCTP(ptoken);
- }
- SAFE_FREE(*pptoken);
+ if (*pptoken) {
+ NT_USER_TOKEN *ptoken = *pptoken;
+
+ SAFE_FREE( ptoken->user_sids );
+ ZERO_STRUCTP(ptoken);
+ }
+ SAFE_FREE(*pptoken);
}
/****************************************************************************
@@ -1429,21 +1436,58 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
if (!ptoken)
return NULL;
- if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL)
- return NULL;
-
- ZERO_STRUCTP(token);
+ if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL)
+ return NULL;
- if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
- SAFE_FREE(token);
- return NULL;
- }
+ ZERO_STRUCTP(token);
+
+ token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
+
+ if ( !token ) {
+ SAFE_FREE(token);
+ return NULL;
+ }
- token->num_sids = ptoken->num_sids;
+ token->num_sids = ptoken->num_sids;
+
+ /* copy the privileges; don't consider failure to be critical here */
+
+ if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
+ DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!. Continuing with 0 privileges assigned.\n"));
+ }
return token;
}
+/****************************************************************************
+ Check for a SID in an NT_USER_TOKEN
+****************************************************************************/
+
+BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
+{
+ int i;
+
+ if ( !sid || !token )
+ return False;
+
+ for ( i=0; i<token->num_sids; i++ ) {
+ if ( sid_equal( sid, &token->user_sids[i] ) )
+ return True;
+ }
+
+ return False;
+}
+
+BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
+{
+ DOM_SID domain_sid;
+
+ sid_copy( &domain_sid, get_global_sam_sid() );
+ sid_append_rid( &domain_sid, rid );
+
+ return nt_token_check_sid( &domain_sid, token );\
+}
+
/**
* Verify whether or not given domain is trusted.
*
diff --git a/source/autogen.sh b/source/autogen.sh
index e8160d21731..3c2011e5a7e 100755
--- a/source/autogen.sh
+++ b/source/autogen.sh
@@ -51,6 +51,7 @@ echo "$0: running script/mkversion.sh"
./script/mkversion.sh || exit 1
rm -rf autom4te*.cache
+rm -f configure include/config.h*
echo "$0: running $AUTOHEADER"
$AUTOHEADER || exit 1
diff --git a/source/client/client.c b/source/client/client.c
index 7470a7ba5fd..a0804449985 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -582,17 +582,17 @@ static int cmd_dir(void)
if(mask[strlen(mask)-1]!='\\')
pstrcat(mask,"\\");
} else {
- *mask = '\0';
+ pstrcpy(mask, "\\");
}
if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
dos_format(p);
if (*p == '\\')
- pstrcpy(mask,p);
+ pstrcpy(mask,p + 1);
else
pstrcat(mask,p);
} else {
- pstrcat(mask,"\\*");
+ pstrcat(mask,"*");
}
do_list(mask, attribute, display_finfo, recurse, True);
diff --git a/source/configure.in b/source/configure.in
index 35300151104..330eed79f12 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -238,7 +238,7 @@ 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} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER -O1"
+ 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)],
@@ -1005,6 +1005,7 @@ 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 timegm)
AC_CHECK_FUNCS(setlocale nl_langinfo)
+AC_CHECK_FUNCS(nanosleep)
# setbuffer, shmget, shm_open are needed for smbtorture
AC_CHECK_FUNCS(setbuffer shmget shm_open backtrace_symbols)
AC_CHECK_HEADERS(libexc.h)
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c
index 7095997dc8d..e574a7cf204 100644
--- a/source/groupdb/mapping.c
+++ b/source/groupdb/mapping.c
@@ -2,7 +2,7 @@
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
- * Copyright (C) Jean François Micouleau 1998-2001.
+ * Copyright (C) Jean François Micouleau 1998-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
@@ -35,17 +35,6 @@ static TDB_CONTEXT *tdb; /* used for driver files */
*/
#define MEMBEROF_PREFIX "MEMBEROF/"
-PRIVS privs[] = {
- {SE_PRIV_NONE, "no_privs", "No privilege" }, /* this one MUST be first */
- {SE_PRIV_ADD_MACHINES, "SeMachineAccountPrivilege", "Add workstations to the domain" },
- {SE_PRIV_SEC_PRIV, "SeSecurityPrivilege", "Manage the audit logs" },
- {SE_PRIV_TAKE_OWNER, "SeTakeOwnershipPrivilege", "Take ownership of file" },
- {SE_PRIV_ADD_USERS, "SaAddUsers", "Add users to the domain - Samba" },
- {SE_PRIV_PRINT_OPERATOR, "SaPrintOp", "Add or remove printers - Samba" },
- {SE_PRIV_ALL, "SaAllPrivs", "all privileges" }
-};
-
-
/****************************************************************************
dump the mapping group mapping to a text file
****************************************************************************/
diff --git a/source/include/ads.h b/source/include/ads.h
index de020f2a3f4..27f9384d5d0 100644
--- a/source/include/ads.h
+++ b/source/include/ads.h
@@ -76,9 +76,6 @@ typedef void **ADS_MODLIST;
/* time between reconnect attempts */
#define ADS_RECONNECT_TIME 5
-/* timeout on searches */
-#define ADS_SEARCH_TIMEOUT 10
-
/* ldap control oids */
#define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319"
#define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339"
diff --git a/source/include/client.h b/source/include/client.h
index b556538f743..c182544362f 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -123,7 +123,7 @@ struct cli_state {
of the pipe we're talking to,
if any */
- uint16 nt_pipe_fnum; /* Pipe handle. */
+ uint16 nt_pipe_fnum[PI_MAX_PIPES]; /* Pipe handle. */
/* Secure pipe parameters */
int pipe_auth_flags;
diff --git a/source/include/includes.h b/source/include/includes.h
index 66ff4fa9f02..45c7133f1ea 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -814,6 +814,8 @@ extern int errno;
#include "version.h"
+#include "privileges.h"
+
#include "smb.h"
#include "nameserv.h"
diff --git a/source/include/passdb.h b/source/include/passdb.h
index db6bc2ac75e..1b9ccc50ee4 100644
--- a/source/include/passdb.h
+++ b/source/include/passdb.h
@@ -241,7 +241,7 @@ struct acct_info
* this SAMBA will load. Increment this if *ANY* changes are made to the interface.
*/
-#define PASSDB_INTERFACE_VERSION 5
+#define PASSDB_INTERFACE_VERSION 6
typedef struct pdb_context
{
@@ -251,7 +251,7 @@ typedef struct pdb_context
/* These functions are wrappers for the functions listed above.
They may do extra things like re-reading a SAM_ACCOUNT on update */
- NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update);
+ NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update, uint16 acb_mask);
void (*pdb_endsampwent)(struct pdb_context *);
@@ -349,7 +349,7 @@ typedef struct pdb_methods
struct pdb_methods *next;
struct pdb_methods *prev;
- NTSTATUS (*setsampwent)(struct pdb_methods *, BOOL update);
+ NTSTATUS (*setsampwent)(struct pdb_methods *, BOOL update, uint16 acb_mask);
void (*endsampwent)(struct pdb_methods *);
diff --git a/source/include/privileges.h b/source/include/privileges.h
index b7e1b44c2af..76cabf3ba90 100644
--- a/source/include/privileges.h
+++ b/source/include/privileges.h
@@ -4,6 +4,8 @@
Copyright (C) Andrew Tridgell 1992-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
Copyright (C) Paul Ashton 1997
+ Copyright (C) Simo Sorce 2003
+ Copyright (C) Gerald (Jerry) Carter 2004
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
@@ -23,22 +25,62 @@
#ifndef PRIVILEGES_H
#define PRIVILEGES_H
-#define PRIV_ALL_INDEX 5
+/* privilege bitmask */
-#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 SE_PRIV_MASKSIZE 4
+typedef struct {
+ uint32 mask[SE_PRIV_MASKSIZE];
+} SE_PRIV;
+
+
+/* common privilege defines */
+
+#define SE_END { { 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_NONE { { 0x00000000, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_ALL_PRIVS { { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF } }
+
+
+/*
+ * We will use our own set of privileges since it makes no sense
+ * to implement all of the Windows set when only a portion will
+ * be used. Use 128-bit mask to give room to grow.
+ */
+
+#define SE_NETWORK_LOGON { { 0x00000001, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_INTERACTIVE_LOGON { { 0x00000002, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_BATCH_LOGON { { 0x00000004, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_SERVICE_LOGON { { 0x00000008, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_MACHINE_ACCOUNT { { 0x00000010, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_PRINT_OPERATOR { { 0x00000020, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_ADD_USERS { { 0x00000040, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_DISK_OPERATOR { { 0x00000080, 0x00000000, 0x00000000, 0x00000000 } }
+#define SE_REMOTE_SHUTDOWN { { 0x00000100, 0x00000000, 0x00000000, 0x00000000 } }
+
+/* defined in lib/privilegs.c */
+
+extern const SE_PRIV se_machine_account;
+extern const SE_PRIV se_print_operator;
+extern const SE_PRIV se_add_users;
+extern const SE_PRIV se_disk_operators;
+extern const SE_PRIV se_remote_shutdown;
+
+
+/*
+ * These are used in Lsa replies (srv_lsa_nt.c)
+ */
#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
+
+#ifndef _BOOL
+typedef int BOOL;
+#define _BOOL /* So we don't typedef BOOL again in vfs.h */
+#endif
+
typedef struct LUID
{
uint32 low;
@@ -49,7 +91,7 @@ typedef struct LUID_ATTR
{
LUID luid;
uint32 attr;
-} LUID_ATTR ;
+} LUID_ATTR;
typedef struct privilege_set
{
@@ -61,10 +103,9 @@ typedef struct privilege_set
} PRIVILEGE_SET;
typedef struct _PRIVS {
- uint32 se_priv;
- const char *priv;
+ SE_PRIV se_priv;
+ const char *name;
const char *description;
} PRIVS;
-
#endif /* PRIVILEGES_H */
diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h
index 43ffa37d597..a2bc72d2b2e 100644
--- a/source/include/rpc_lsa.h
+++ b/source/include/rpc_lsa.h
@@ -635,6 +635,20 @@ typedef struct lsa_r_unk_get_connuser
} LSA_R_UNK_GET_CONNUSER;
+typedef struct lsa_q_createaccount
+{
+ POLICY_HND pol; /* policy handle */
+ DOM_SID2 sid;
+ uint32 access; /* access */
+} LSA_Q_CREATEACCOUNT;
+
+typedef struct lsa_r_createaccount
+{
+ POLICY_HND pol; /* policy handle */
+ NTSTATUS status;
+} LSA_R_CREATEACCOUNT;
+
+
typedef struct lsa_q_openaccount
{
POLICY_HND pol; /* policy handle */
@@ -657,7 +671,7 @@ typedef struct lsa_r_enumprivsaccount
{
uint32 ptr;
uint32 count;
- PRIVILEGE_SET *set;
+ PRIVILEGE_SET set;
NTSTATUS status;
} LSA_R_ENUMPRIVSACCOUNT;
@@ -703,7 +717,7 @@ typedef struct lsa_q_addprivs
{
POLICY_HND pol; /* policy handle */
uint32 count;
- PRIVILEGE_SET *set;
+ PRIVILEGE_SET set;
} LSA_Q_ADDPRIVS;
typedef struct lsa_r_addprivs
@@ -718,7 +732,7 @@ typedef struct lsa_q_removeprivs
uint32 allrights;
uint32 ptr;
uint32 count;
- PRIVILEGE_SET *set;
+ PRIVILEGE_SET set;
} LSA_Q_REMOVEPRIVS;
typedef struct lsa_r_removeprivs
diff --git a/source/include/rpc_misc.h b/source/include/rpc_misc.h
index ee8208e90ea..6abc85a4cac 100644
--- a/source/include/rpc_misc.h
+++ b/source/include/rpc_misc.h
@@ -124,11 +124,6 @@ typedef struct unihdr2_info
uint32 buffer; /* 32 bit buffer pointer */
} UNIHDR2;
-/* clueless as to what maximum length should be */
-#define MAX_UNISTRLEN 256
-#define MAX_STRINGLEN 256
-#define MAX_BUFFERLEN 512
-
/* UNISTR - unicode string size and buffer */
typedef struct unistr_info
{
@@ -408,7 +403,7 @@ BUFHDR4;
typedef struct buffer4_info
{
uint32 buf_len;
- uint8 buffer[MAX_BUFFERLEN];
+ uint8 *buffer;
}
BUFFER4;
diff --git a/source/include/rpc_reg.h b/source/include/rpc_reg.h
index 46ec88283df..bfb5f1e0763 100644
--- a/source/include/rpc_reg.h
+++ b/source/include/rpc_reg.h
@@ -158,7 +158,7 @@ typedef struct q_reg_open_hkcr_info
typedef struct r_reg_open_hkcr_info
{
POLICY_HND pol; /* policy handle */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_OPEN_HKCR;
@@ -178,7 +178,7 @@ REG_Q_OPEN_HKLM;
typedef struct r_reg_open_hklm_info
{
POLICY_HND pol; /* policy handle */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
}
REG_R_OPEN_HKLM;
@@ -198,7 +198,7 @@ typedef struct q_reg_open_hku_info
typedef struct r_reg_open_hku_info
{
POLICY_HND pol; /* policy handle */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_OPEN_HKU;
@@ -213,7 +213,7 @@ typedef struct q_reg_open_flush_key_info
/* REG_R_FLUSH_KEY */
typedef struct r_reg_open_flush_key_info
{
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_FLUSH_KEY;
@@ -234,7 +234,7 @@ typedef struct q_reg_set_key_sec_info
/* REG_R_SET_KEY_SEC */
typedef struct r_reg_set_key_sec_info
{
- NTSTATUS status;
+ WERROR status;
} REG_R_SET_KEY_SEC;
@@ -261,7 +261,7 @@ typedef struct r_reg_get_key_sec_info
BUFHDR hdr_sec; /* header for security data */
SEC_DESC_BUF *data; /* security data */
- NTSTATUS status;
+ WERROR status;
} REG_R_GET_KEY_SEC;
@@ -282,7 +282,7 @@ typedef struct q_reg_create_value_info
/* REG_R_CREATE_VALUE */
typedef struct r_reg_create_value_info
{
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_CREATE_VALUE;
@@ -329,7 +329,7 @@ typedef struct r_reg_enum_value_info
uint32 ptr2; /* pointer */
uint32 len_value2; /* */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_ENUM_VALUE;
@@ -365,7 +365,7 @@ typedef struct r_reg_create_key_info
POLICY_HND key_pol; /* policy handle */
uint32 unknown; /* 0x0000 0000 */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_CREATE_KEY;
@@ -383,7 +383,7 @@ typedef struct r_reg_delete_key_info
{
POLICY_HND key_pol; /* policy handle */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_DELETE_KEY;
@@ -402,7 +402,7 @@ typedef struct r_reg_delete_val_info
{
POLICY_HND key_pol; /* policy handle */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_DELETE_VALUE;
@@ -430,7 +430,7 @@ typedef struct r_reg_query_key_info
uint32 sec_desc; /* 0x0000 0078 */
NTTIME mod_time; /* modified time */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_QUERY_KEY;
@@ -446,7 +446,7 @@ typedef struct q_reg_unk_1a_info
typedef struct r_reg_unk_1a_info
{
uint32 unknown; /* 0x0500 0000 */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_UNKNOWN_1A;
@@ -468,7 +468,7 @@ typedef struct q_reg_unknown_14
/* REG_R_UNKNOWN_1A */
typedef struct r_reg_unknown_14
{
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_SAVE_KEY;
@@ -486,7 +486,7 @@ typedef struct reg_r_close_info
{
POLICY_HND pol; /* policy handle. should be all zeros. */
- NTSTATUS status; /* return code */
+ WERROR status; /* return code */
} REG_R_CLOSE;
@@ -531,7 +531,7 @@ typedef struct r_reg_enum_key_info
uint32 ptr3; /* pointer */
NTTIME time; /* current time? */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_ENUM_KEY;
@@ -575,7 +575,7 @@ typedef struct r_reg_info_info
uint32 ptr_len;
uint32 buf_len;
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_INFO;
@@ -599,7 +599,7 @@ typedef struct q_reg_open_entry_info
typedef struct r_reg_open_entry_info
{
POLICY_HND pol; /* policy handle */
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_OPEN_ENTRY;
@@ -620,7 +620,7 @@ typedef struct q_reg_shutdown_info
/* REG_R_SHUTDOWN */
typedef struct r_reg_shutdown_info
{
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_SHUTDOWN;
@@ -635,7 +635,7 @@ typedef struct q_reg_abort_shutdown_info
/* REG_R_ABORT_SHUTDOWN */
typedef struct r_reg_abort_shutdown_info
{
- NTSTATUS status; /* return status */
+ WERROR status; /* return status */
} REG_R_ABORT_SHUTDOWN;
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index 9945f674c82..a007bcd2e57 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -412,6 +412,13 @@ typedef struct sam_user_info_10
} SAM_USER_INFO_10;
+/* SAM_USER_INFO_7 */
+typedef struct sam_user_info_7
+{
+ UNIHDR hdr_name; /* unicode header for name */
+ UNISTR2 uni_name; /* unicode string for name */
+
+} SAM_USER_INFO_7;
/* SAMR_Q_CLOSE_HND - probably a policy handle close */
@@ -1273,6 +1280,7 @@ typedef struct sam_userinfo_ctr_info
union
{
+ SAM_USER_INFO_7 *id7; /* auth-level 0x07 */
SAM_USER_INFO_10 *id10; /* auth-level 0x10 */
SAM_USER_INFO_11 *id11; /* auth-level 0x11 */
SAM_USER_INFO_12 *id12; /* auth-level 0x12 */
diff --git a/source/include/smb.h b/source/include/smb.h
index a7db0c0a868..913061014db 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -281,6 +281,11 @@ typedef struct sid_info
} DOM_SID;
+typedef struct sid_list {
+ uint32 count;
+ DOM_SID *list;
+} SID_LIST;
+
/*
* The complete list of SIDS belonging to this user.
* Created when a vuid is registered.
@@ -297,6 +302,7 @@ typedef struct sid_info
typedef struct _nt_user_token {
size_t num_sids;
DOM_SID *user_sids;
+ SE_PRIV privileges;
} NT_USER_TOKEN;
/*** query a local group, get a list of these: shows who is in that group ***/
@@ -638,7 +644,7 @@ typedef struct {
#define AP_RESET_COUNT_TIME 7
#define AP_BAD_ATTEMPT_LOCKOUT 8
#define AP_TIME_TO_LOGOUT 9
-
+#define AP_REFUSE_MACHINE_PW_CHANGE 10
/*
* Flags for local user manipulation.
diff --git a/source/include/smbldap.h b/source/include/smbldap.h
index 47f336cdb7a..adb51430dc6 100644
--- a/source/include/smbldap.h
+++ b/source/include/smbldap.h
@@ -1,5 +1,5 @@
/*
- Unix SMB/CIFS mplementation.
+ Unix SMB/CIFS implementation.
LDAP protocol helper functions for SAMBA
Copyright (C) Gerald Carter 2001-2003
@@ -145,6 +145,7 @@ struct smbldap_state {
const char *uri;
char *bind_dn;
char *bind_secret;
+ BOOL paged_results;
unsigned int num_failures;
diff --git a/source/include/vfs_macros.h b/source/include/vfs_macros.h
index 79f5bbf3c16..7681b443ebd 100644
--- a/source/include/vfs_macros.h
+++ b/source/include/vfs_macros.h
@@ -40,7 +40,7 @@
#define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (conn), (dirp)))
#define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (conn), (dirp), (offset)))
#define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (conn), (dirp)))
-#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewinddir((conn)->vfs.handles.rewinddir, (conn), (dirp)))
+#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewind_dir((conn)->vfs.handles.rewind_dir, (conn), (dirp)))
#define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(conn), (path), (mode)))
#define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (conn), (path)))
#define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, (conn), dir))
@@ -141,7 +141,7 @@
#define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (conn), (dirp)))
#define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (conn), (dirp), (offset)))
#define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (conn), (dirp)))
-#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewinddir((conn)->vfs_opaque.handles.rewinddir, (conn), (dirp)))
+#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewind_dir((conn)->vfs_opaque.handles.rewind_dir, (conn), (dirp)))
#define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(conn), (path), (mode)))
#define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (conn), (path)))
#define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, (conn), dir))
diff --git a/source/lib/account_pol.c b/source/lib/account_pol.c
index aa593832584..72d6e77ddda 100644
--- a/source/lib/account_pol.c
+++ b/source/lib/account_pol.c
@@ -20,9 +20,29 @@
*/
#include "includes.h"
-static TDB_CONTEXT *tdb; /* used for driver files */
+static TDB_CONTEXT *tdb;
+
+#define DATABASE_VERSION 2
+
+extern DOM_SID global_sid_World;
+extern DOM_SID global_sid_Builtin_Administrators;
+extern DOM_SID global_sid_Builtin_Account_Operators;
+extern DOM_SID global_sid_Builtin_Server_Operators;
+extern DOM_SID global_sid_Builtin_Print_Operators;
+extern DOM_SID global_sid_Builtin_Backup_Operators;
-#define DATABASE_VERSION 1
+
+/****************************************************************************
+ Set default for a field if it is empty
+****************************************************************************/
+
+static void set_default_on_empty(int field, uint32 value)
+{
+ if (account_policy_get(field, NULL))
+ return;
+ account_policy_set(field, value);
+ return;
+}
/****************************************************************************
Open the account policy tdb.
@@ -44,21 +64,50 @@ BOOL init_account_policy(void)
/* handle a Samba upgrade */
tdb_lock_bystring(tdb, vstring,0);
if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
- tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
- account_policy_set(AP_MIN_PASSWORD_LEN, MINPASSWDLENGTH); /* 5 chars minimum */
- account_policy_set(AP_PASSWORD_HISTORY, 0); /* don't keep any old password */
- account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, 0); /* don't force user to logon */
- account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)-1); /* don't expire */
- account_policy_set(AP_MIN_PASSWORD_AGE, 0); /* 0 days */
- account_policy_set(AP_LOCK_ACCOUNT_DURATION, 30); /* lockout for 30 minutes */
- account_policy_set(AP_RESET_COUNT_TIME, 30); /* reset after 30 minutes */
- account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, 0); /* don't lockout */
- account_policy_set(AP_TIME_TO_LOGOUT, -1); /* don't force logout */
+ set_default_on_empty(
+ AP_MIN_PASSWORD_LEN,
+ MINPASSWDLENGTH);/* 5 chars minimum */
+ set_default_on_empty(
+ AP_PASSWORD_HISTORY,
+ 0); /* don't keep any old password */
+ set_default_on_empty(
+ AP_USER_MUST_LOGON_TO_CHG_PASS,
+ 0); /* don't force user to logon */
+ set_default_on_empty(
+ AP_MAX_PASSWORD_AGE,
+ (uint32)-1); /* don't expire */
+ set_default_on_empty(
+ AP_MIN_PASSWORD_AGE,
+ 0); /* 0 days */
+ set_default_on_empty(
+ AP_LOCK_ACCOUNT_DURATION,
+ 30); /* lockout for 30 minutes */
+ set_default_on_empty(
+ AP_RESET_COUNT_TIME,
+ 30); /* reset after 30 minutes */
+ set_default_on_empty(
+ AP_BAD_ATTEMPT_LOCKOUT,
+ 0); /* don't lockout */
+ set_default_on_empty(
+ AP_TIME_TO_LOGOUT,
+ -1); /* don't force logout */
+ set_default_on_empty(
+ AP_REFUSE_MACHINE_PW_CHANGE,
+ 0); /* allow machine pw changes */
}
tdb_unlock_bystring(tdb, vstring);
+ /* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
+
+ privilege_create_account( &global_sid_World );
+ privilege_create_account( &global_sid_Builtin_Administrators );
+ privilege_create_account( &global_sid_Builtin_Account_Operators );
+ privilege_create_account( &global_sid_Builtin_Server_Operators );
+ privilege_create_account( &global_sid_Builtin_Print_Operators );
+ privilege_create_account( &global_sid_Builtin_Backup_Operators );
+
return True;
}
@@ -75,6 +124,7 @@ static const struct {
{AP_RESET_COUNT_TIME, "reset count minutes"},
{AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt"},
{AP_TIME_TO_LOGOUT, "disconnect time"},
+ {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change"},
{0, NULL}
};
@@ -138,21 +188,26 @@ int account_policy_name_to_fieldnum(const char *name)
BOOL account_policy_get(int field, uint32 *value)
{
fstring name;
+ uint32 regval;
if(!init_account_policy())return False;
- *value = 0;
+ if (value)
+ *value = 0;
fstrcpy(name, decode_account_policy_name(field));
if (!*name) {
DEBUG(1, ("account_policy_get: Field %d is not a valid account policy type! Cannot get, returning 0.\n", field));
return False;
}
- if (!tdb_fetch_uint32(tdb, name, value)) {
+ if (!tdb_fetch_uint32(tdb, name, &regval)) {
DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name));
return False;
}
- DEBUG(10,("account_policy_get: %s:%d\n", name, *value));
+ if (value)
+ *value = regval;
+
+ DEBUG(10,("account_policy_get: %s:%d\n", name, regval));
return True;
}
@@ -180,3 +235,18 @@ BOOL account_policy_set(int field, uint32 value)
return True;
}
+
+/****************************************************************************
+****************************************************************************/
+
+TDB_CONTEXT *get_account_pol_tdb( void )
+{
+
+ if ( !tdb ) {
+ if ( !init_account_policy() )
+ return NULL;
+ }
+
+ return tdb;
+}
+
diff --git a/source/lib/privileges.c b/source/lib/privileges.c
index 2b8d7613c18..628b2dd3251 100644
--- a/source/lib/privileges.c
+++ b/source/lib/privileges.c
@@ -3,6 +3,7 @@
Privileges handling functions
Copyright (C) Jean François Micouleau 1998-2001
Copyright (C) Simo Sorce 2002-2003
+ Copyright (C) Gerald (Jerry) Carter 2004
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
@@ -19,143 +20,270 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
#include "includes.h"
-/* defines */
+#define PRIVPREFIX "PRIV_"
-#define ALLOC_CHECK(ptr, err, label, str) do { if ((ptr) == NULL) { DEBUG(0, ("%s: out of memory!\n", str)); err = NT_STATUS_NO_MEMORY; goto label; } } while(0)
-#define NTSTATUS_CHECK(err, label, str1, str2) do { if (!NT_STATUS_IS_OK(err)) { DEBUG(0, ("%s: %s failed!\n", str1, str2)); } } while(0)
+#define GENERATE_LUID_LOW(x) (x)+1;
-/****************************************************************************
- Check if a user is a mapped group.
-
- This function will check if the group SID is mapped onto a
- system managed gid or onto a winbind manged sid.
- In the first case it will be threated like a mapped group
- and the backend should take the member list with a getgrgid
- and ignore any user that have been possibly set into the group
- object.
-
- In the second case, the group is a fully SAM managed group
- served back to the system through winbind. In this case the
- members of a Local group are "unrolled" to cope with the fact
- that unix cannot contain groups inside groups.
- The backend MUST never call any getgr* / getpw* function or
- loops with winbind may happen.
- ****************************************************************************/
+static SE_PRIV se_priv_all = SE_ALL_PRIVS;
+static SE_PRIV se_priv_end = SE_END;
+static SE_PRIV se_priv_none = SE_NONE;
-#if 0
-NTSTATUS is_mapped_group(BOOL *mapped, const DOM_SID *sid)
-{
- NTSTATUS result;
- gid_t id;
-
- /* look if mapping exist, do not make idmap alloc an uid if SID is not found */
- result = idmap_get_gid_from_sid(&id, sid, False);
- if (NT_STATUS_IS_OK(result)) {
- *mapped = gid_is_in_winbind_range(id);
- } else {
- *mapped = False;
- }
+/* Define variables for all privileges so we can use the
+ SE_PRIV* in the various se_priv_XXX() functions */
- return result;
-}
-#endif
+const SE_PRIV se_machine_account = SE_MACHINE_ACCOUNT;
+const SE_PRIV se_print_operator = SE_PRINT_OPERATOR;
+const SE_PRIV se_add_users = SE_ADD_USERS;
+const SE_PRIV se_disk_operators = SE_DISK_OPERATOR;
+const SE_PRIV se_remote_shutdown = SE_REMOTE_SHUTDOWN;
-/****************************************************************************
- duplicate alloc luid_attr
- ****************************************************************************/
-NTSTATUS dupalloc_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_la)
-{
- NTSTATUS ret;
+PRIVS privs[] = {
+#if 0 /* usrmgr will display these twice if you include them. We don't
+ use them but we'll keep the bitmasks reserved in privileges.h anyways */
+
+ {SE_NETWORK_LOGON, "SeNetworkLogonRight", "Access this computer from network"},
+ {SE_INTERACTIVE_LOGON, "SeInteractiveLogonRight", "Log on locally"},
+ {SE_BATCH_LOGON, "SeBatchLogonRight", "Log on as a batch job"},
+ {SE_SERVICE_LOGON, "SeServiceLogonRight", "Log on as a service"},
+#endif
+ {SE_MACHINE_ACCOUNT, "SeMachineAccountPrivilege", "Add machines to domain"},
+ {SE_PRINT_OPERATOR, "SePrintOperatorPrivilege", "Manage printers"},
+ {SE_ADD_USERS, "SeAddUsersPrivilege", "Add users and groups to the domain"},
+ {SE_REMOTE_SHUTDOWN, "SeRemoteShutdownPrivilege", "Force shutdown from a remote system"},
+ {SE_DISK_OPERATOR, "SeDiskOperatorPrivilege", "Manage disk shares"},
+
+ {SE_END, "", ""}
+};
+
+#if 0 /* not needed currently */
+PRIVS privs[] = {
+ {SE_ASSIGN_PRIMARY_TOKEN, "SeAssignPrimaryTokenPrivilege", "Assign Primary Token"},
+ {SE_CREATE_TOKEN, "SeCreateTokenPrivilege", "Create Token"},
+ {SE_LOCK_MEMORY, "SeLockMemoryPrivilege", "Lock Memory"},
+ {SE_INCREASE_QUOTA, "SeIncreaseQuotaPrivilege", "Increase Quota"},
+ {SE_UNSOLICITED_INPUT, "SeUnsolicitedInputPrivilege", "Unsolicited Input"},
+ {SE_TCB, "SeTcbPrivilege", "Act as part of the operating system"},
+ {SE_SECURITY, "SeSecurityPrivilege", "Security Privilege"},
+ {SE_TAKE_OWNERSHIP, "SeTakeOwnershipPrivilege", "Take Ownership Privilege"},
+ {SE_LOAD_DRIVER, "SeLocalDriverPrivilege", "Local Driver Privilege"},
+ {SE_SYSTEM_PROFILE, "SeSystemProfilePrivilege", "System Profile Privilege"},
+ {SE_SYSTEM_TIME, "SeSystemtimePrivilege", "System Time"},
+ {SE_PROF_SINGLE_PROCESS, "SeProfileSingleProcessPrivilege", "Profile Single Process Privilege"},
+ {SE_INC_BASE_PRIORITY, "SeIncreaseBasePriorityPrivilege", "Increase Base Priority Privilege"},
+ {SE_CREATE_PAGEFILE, "SeCreatePagefilePrivilege", "Create Pagefile Privilege"},
+ {SE_CREATE_PERMANENT, "SeCreatePermanentPrivilege", "Create Permanent"},
+ {SE_BACKUP, "SeBackupPrivilege", "Backup Privilege"},
+ {SE_RESTORE, "SeRestorePrivilege", "Restore Privilege"},
+ {SE_SHUTDOWN, "SeShutdownPrivilege", "Shutdown Privilege"},
+ {SE_DEBUG, "SeDebugPrivilege", "Debug Privilege"},
+ {SE_AUDIT, "SeAuditPrivilege", "Audit"},
+ {SE_SYSTEM_ENVIRONMENT, "SeSystemEnvironmentPrivilege", "System Environment Privilege"},
+ {SE_CHANGE_NOTIFY, "SeChangeNotifyPrivilege", "Change Notify"},
+ {SE_UNDOCK, "SeUndockPrivilege", "Undock"},
+ {SE_SYNC_AGENT, "SeSynchronizationAgentPrivilege", "Synchronization Agent"},
+ {SE_ENABLE_DELEGATION, "SeEnableDelegationPrivilege", "Enable Delegation"},
+ {SE_ALL_PRIVS, "SeAllPrivileges", "All Privileges"}
+ {SE_END, "", ""}
+};
+#endif
- /* don't crash if the source pointer is NULL (since we don't
- do priviledges now anyways) */
+typedef struct priv_sid_list {
+ SE_PRIV privilege;
+ SID_LIST sids;
+} PRIV_SID_LIST;
- if ( !old_la )
- return NT_STATUS_OK;
- *new_la = TALLOC_P(mem_ctx, LUID_ATTR);
- ALLOC_CHECK(new_la, ret, done, "dupalloc_luid_attr");
+/***************************************************************************
+ copy an SE_PRIV structure
+****************************************************************************/
- (*new_la)->luid.high = old_la->luid.high;
- (*new_la)->luid.low = old_la->luid.low;
- (*new_la)->attr = old_la->attr;
+BOOL se_priv_copy( SE_PRIV *dst, const SE_PRIV *src )
+{
+ if ( !dst || !src )
+ return False;
+
+ memcpy( dst, src, sizeof(SE_PRIV) );
- ret = NT_STATUS_OK;
-
-done:
- return ret;
+ return True;
}
-/****************************************************************************
- initialise a privilege list
- ****************************************************************************/
-NTSTATUS init_privilege(PRIVILEGE_SET **priv_set)
+/***************************************************************************
+ combine 2 SE_PRIV structures and store the resulting set in mew_mask
+****************************************************************************/
+
+static void se_priv_add( SE_PRIV *mask, const SE_PRIV *addpriv )
{
- NTSTATUS ret;
- TALLOC_CTX *mem_ctx = talloc_init("privilege set");
- ALLOC_CHECK(mem_ctx, ret, done, "init_privilege");
+ int i;
+
+ for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) {
+ mask->mask[i] |= addpriv->mask[i];
+ }
+}
+
+/***************************************************************************
+ remove one SE_PRIV sytucture from another and store the resulting set
+ in mew_mask
+****************************************************************************/
+
+static void se_priv_remove( SE_PRIV *mask, const SE_PRIV *removepriv )
+{
+ int i;
+
+ for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) {
+ mask->mask[i] &= ~removepriv->mask[i];
+ }
+}
- *priv_set = TALLOC_ZERO_P(mem_ctx, PRIVILEGE_SET);
- ALLOC_CHECK(*priv_set, ret, done, "init_privilege");
+/***************************************************************************
+ invert a given SE_PRIV and store the set in new_mask
+****************************************************************************/
- (*priv_set)->mem_ctx = mem_ctx;
+static void se_priv_invert( SE_PRIV *new_mask, const SE_PRIV *mask )
+{
+ SE_PRIV allprivs;
+
+ se_priv_copy( &allprivs, &se_priv_all );
+ se_priv_remove( &allprivs, mask );
+ se_priv_copy( new_mask, &allprivs );
+}
- ret = NT_STATUS_OK;
+/***************************************************************************
+ check if 2 SE_PRIV structure are equal
+****************************************************************************/
-done:
- return ret;
+static BOOL se_priv_equal( const SE_PRIV *mask1, const SE_PRIV *mask2 )
+{
+ return ( memcmp(mask1, mask2, sizeof(SE_PRIV)) == 0 );
}
-NTSTATUS init_priv_with_ctx(TALLOC_CTX *mem_ctx, PRIVILEGE_SET **priv_set)
+
+/***************************************************************************
+ dump an SE_PRIV structure to the log files
+****************************************************************************/
+
+void dump_se_priv( int dbg_cl, int dbg_lvl, const SE_PRIV *mask )
{
- NTSTATUS ret;
+ int i;
+
+ DEBUGADDC( dbg_cl, dbg_lvl,("SE_PRIV "));
+
+ for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) {
+ DEBUGADDC( dbg_cl, dbg_lvl,(" 0x%x", mask->mask[i] ));
+ }
+
+ DEBUGADDC( dbg_cl, dbg_lvl, ("\n"));
+}
- *priv_set = TALLOC_ZERO_P(mem_ctx, PRIVILEGE_SET);
- ALLOC_CHECK(*priv_set, ret, done, "init_privilege");
+/***************************************************************************
+ Retrieve the privilege mask (set) for a given SID
+****************************************************************************/
- (*priv_set)->mem_ctx = mem_ctx;
- (*priv_set)->ext_ctx = True;
+static BOOL get_privileges( const DOM_SID *sid, SE_PRIV *mask )
+{
+ TDB_CONTEXT *tdb = get_account_pol_tdb();
+ fstring keystr;
+ TDB_DATA key, data;
- ret = NT_STATUS_OK;
+ /* Fail if the admin has not enable privileges */
+
+ if ( !lp_enable_privileges() ) {
+ return False;
+ }
+
+ if ( !tdb )
+ return False;
-done:
- return ret;
+ /* PRIV_<SID> (NULL terminated) as the key */
+
+ fstr_sprintf( keystr, "%s%s", PRIVPREFIX, sid_string_static(sid) );
+ key.dptr = keystr;
+ key.dsize = strlen(keystr) + 1;
+
+ data = tdb_fetch( tdb, key );
+
+ if ( !data.dptr ) {
+ DEBUG(3,("get_privileges: No privileges assigned to SID [%s]\n",
+ sid_string_static(sid)));
+ return False;
+ }
+
+ SMB_ASSERT( data.dsize == sizeof( SE_PRIV ) );
+
+ se_priv_copy( mask, (SE_PRIV*)data.dptr );
+
+
+ return True;
}
-void reset_privilege(PRIVILEGE_SET *priv_set)
+/***************************************************************************
+ Store the privilege mask (set) for a given SID
+****************************************************************************/
+
+static BOOL set_privileges( const DOM_SID *sid, SE_PRIV *mask )
{
- priv_set->count = 0;
- priv_set->control = 0;
- priv_set->set = NULL;
+ TDB_CONTEXT *tdb = get_account_pol_tdb();
+ fstring keystr;
+ TDB_DATA key, data;
+
+ if ( !tdb )
+ return False;
+
+ /* PRIV_<SID> (NULL terminated) as the key */
+
+ fstr_sprintf( keystr, "%s%s", PRIVPREFIX, sid_string_static(sid) );
+ key.dptr = keystr;
+ key.dsize = strlen(keystr) + 1;
+
+ /* no packing. static size structure, just write it out */
+
+ data.dptr = (char*)mask;
+ data.dsize = sizeof(SE_PRIV);
+
+ return ( tdb_store(tdb, key, data, TDB_REPLACE) != -1 );
}
-void destroy_privilege(PRIVILEGE_SET **priv_set)
+/****************************************************************************
+ check if the privilege is in the privilege list
+****************************************************************************/
+
+static BOOL is_privilege_assigned( SE_PRIV *privileges, SE_PRIV *check )
{
- reset_privilege(*priv_set);
- if (!((*priv_set)->ext_ctx))
- /* mem_ctx is local, destroy it */
- talloc_destroy((*priv_set)->mem_ctx);
- *priv_set = NULL;
+ SE_PRIV p1, p2;
+
+ if ( !privileges || !check )
+ return False;
+
+ se_priv_copy( &p1, check );
+
+ /* invert the SE_PRIV we want to check for and remove that from the
+ original set. If we are left with the SE_PRIV we are checking
+ for then return True */
+
+ se_priv_invert( &p1, check );
+ se_priv_copy( &p2, privileges );
+ se_priv_remove( &p2, &p1 );
+
+ return se_priv_equal( &p2, check );
}
/****************************************************************************
add a privilege to a privilege array
****************************************************************************/
-NTSTATUS add_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
+
+static BOOL privilege_set_add(PRIVILEGE_SET *priv_set, LUID_ATTR set)
{
- NTSTATUS ret;
LUID_ATTR *new_set;
- /* check if the privilege is not already in the list */
- if (NT_STATUS_IS_OK(check_priv_in_privilege(priv_set, set)))
- return NT_STATUS_UNSUCCESSFUL;
-
/* we can allocate memory to add the new privilege */
new_set = TALLOC_REALLOC_ARRAY(priv_set->mem_ctx, priv_set->set, LUID_ATTR, priv_set->count + 1);
- ALLOC_CHECK(new_set, ret, done, "add_privilege");
+ if ( !new_set ) {
+ DEBUG(0,("privilege_set_add: failed to allocate memory!\n"));
+ return False;
+ }
new_set[priv_set->count].luid.high = set.luid.high;
new_set[priv_set->count].luid.low = set.luid.low;
@@ -164,187 +292,470 @@ NTSTATUS add_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
priv_set->count++;
priv_set->set = new_set;
- ret = NT_STATUS_OK;
+ return True;
+}
+
+/*********************************************************************
+ Generate the LUID_ATTR structure based on a bitmask
+*********************************************************************/
+
+LUID_ATTR get_privilege_luid( SE_PRIV *mask )
+{
+ LUID_ATTR priv_luid;
+ int i;
-done:
- return ret;
+ priv_luid.attr = 0;
+ priv_luid.luid.high = 0;
+
+ for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
+
+ /* just use the index+1 (so its non-zero) into the
+ array as the lower portion of the LUID */
+
+ if ( se_priv_equal( &privs[i].se_priv, mask ) ) {
+ priv_luid.luid.low = GENERATE_LUID_LOW(i);
+ }
+ }
+
+ return priv_luid;
}
-/****************************************************************************
- add all the privileges to a privilege array
- ****************************************************************************/
-NTSTATUS add_all_privilege(PRIVILEGE_SET *priv_set)
+/*********************************************************************
+ Generate the LUID_ATTR structure based on a bitmask
+*********************************************************************/
+
+const char* get_privilege_dispname( const char *name )
{
- NTSTATUS result = NT_STATUS_OK;
- LUID_ATTR set;
+ int i;
- set.attr = 0;
- set.luid.high = 0;
+ for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
+
+ if ( strequal( privs[i].name, name ) ) {
+ return privs[i].description;
+ }
+ }
+
+ return NULL;
+}
+
+/*********************************************************************
+ get a list of all privleges for all sids the in list
+*********************************************************************/
+
+BOOL get_privileges_for_sids(SE_PRIV *privileges, DOM_SID *slist, int scount)
+{
+ SE_PRIV mask;
+ int i;
+ BOOL found = False;
- /* TODO: set a proper list of privileges */
- set.luid.low = SE_PRIV_ADD_USERS;
- result = add_privilege(priv_set, set);
- NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
+ se_priv_copy( privileges, &se_priv_none );
+
+ for ( i=0; i<scount; i++ ) {
+ /* don't add unless we actually have a privilege assigned */
- set.luid.low = SE_PRIV_ADD_MACHINES;
- result = add_privilege(priv_set, set);
- NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
+ if ( !get_privileges( &slist[i], &mask ) )
+ continue;
- set.luid.low = SE_PRIV_PRINT_OPERATOR;
- result = add_privilege(priv_set, set);
- NTSTATUS_CHECK(result, done, "add_all_privilege", "add_privilege");
+ DEBUG(5,("get_privileges_for_sids: sid = %s\nPrivilege set:\n",
+ sid_string_static(&slist[i])));
+ dump_se_priv( DBGC_ALL, 5, &mask );
+
+ se_priv_add( privileges, &mask );
+ found = True;
+ }
- return result;
+ return found;
}
-/****************************************************************************
- check if the privilege list is empty
- ****************************************************************************/
-NTSTATUS check_empty_privilege(PRIVILEGE_SET *priv_set)
+
+/*********************************************************************
+ travseral functions for privilege_enumerate_accounts
+*********************************************************************/
+
+static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
{
- if (!priv_set)
- return NT_STATUS_INVALID_PARAMETER;
+ PRIV_SID_LIST *priv = state;
+ int prefixlen = strlen(PRIVPREFIX);
+ DOM_SID sid;
+ fstring sid_string;
+
+ /* easy check first */
+
+ if ( data.dsize != sizeof(SE_PRIV) )
+ return 0;
- if (priv_set->count == 0)
- return NT_STATUS_OK;
+ /* check we have a PRIV_+SID entry */
+
+ if ( strncmp(key.dptr, PRIVPREFIX, prefixlen) != 0)
+ return 0;
+
+ /* check to see if we are looking for a particular privilege */
- return NT_STATUS_UNSUCCESSFUL;
+ if ( !se_priv_equal(&priv->privilege, &se_priv_none) ) {
+ SE_PRIV mask;
+
+ se_priv_copy( &mask, (SE_PRIV*)data.dptr );
+
+ /* if the SID does not have the specified privilege
+ then just return */
+
+ if ( !is_privilege_assigned( &mask, &priv->privilege) )
+ return 0;
+ }
+
+ fstrcpy( sid_string, &key.dptr[strlen(PRIVPREFIX)] );
+
+ if ( !string_to_sid(&sid, sid_string) ) {
+ DEBUG(0,("travsersal_fn_enum__acct: Could not convert SID [%s]\n",
+ sid_string));
+ return 0;
+ }
+
+ add_sid_to_array( &sid, &priv->sids.list, &priv->sids.count );
+
+ return 0;
}
-/****************************************************************************
- check if the privilege is in the privilege list
- ****************************************************************************/
-NTSTATUS check_priv_in_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
+/*********************************************************************
+ Retreive list of privileged SIDs (for _lsa_enumerate_accounts()
+*********************************************************************/
+
+NTSTATUS privilege_enumerate_accounts(DOM_SID **sids, int *num_sids)
+{
+ TDB_CONTEXT *tdb = get_account_pol_tdb();
+ PRIV_SID_LIST priv;
+
+ ZERO_STRUCT(priv);
+
+ se_priv_copy( &priv.privilege, &se_priv_none );
+
+ tdb_traverse( tdb, priv_traverse_fn, &priv);
+
+ /* give the memory away; caller will free */
+
+ *sids = priv.sids.list;
+ *num_sids = priv.sids.count;
+
+ return NT_STATUS_OK;
+}
+
+/***************************************************************************
+ Add privilege to sid
+****************************************************************************/
+
+BOOL grant_privilege(const DOM_SID *sid, SE_PRIV *priv_mask)
+{
+ SE_PRIV old_mask, new_mask;
+
+ if ( get_privileges( sid, &old_mask ) )
+ se_priv_copy( &new_mask, &old_mask );
+ else
+ se_priv_copy( &new_mask, &se_priv_none );
+
+ se_priv_add( &new_mask, priv_mask );
+
+ DEBUG(10,("grant_privilege: %s\n", sid_string_static(sid)));
+
+ DEBUGADD( 10, ("original privilege mask:\n"));
+ dump_se_priv( DBGC_ALL, 10, &old_mask );
+
+ DEBUGADD( 10, ("new privilege mask:\n"));
+ dump_se_priv( DBGC_ALL, 10, &new_mask );
+
+ return set_privileges( sid, &new_mask );
+}
+
+/*********************************************************************
+ Add a privilege based on its name
+*********************************************************************/
+
+BOOL grant_privilege_by_name(DOM_SID *sid, const char *name)
{
int i;
- if (!priv_set)
- return NT_STATUS_INVALID_PARAMETER;
+ for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
+ if ( strequal(privs[i].name, name) ) {
+ return grant_privilege( sid, &privs[i].se_priv );
+ }
+ }
- /* if the list is empty, obviously we can't have it */
- if (NT_STATUS_IS_OK(check_empty_privilege(priv_set)))
- return NT_STATUS_UNSUCCESSFUL;
+ DEBUG(3, ("grant_privilege_by_name: No Such Privilege Found (%s)\n", name));
- for (i = 0; i < priv_set->count; i++) {
- LUID_ATTR *cur_set;
+ return False;
+}
- 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 NT_STATUS_OK;
- }
- }
+/***************************************************************************
+ Remove privilege from sid
+****************************************************************************/
+
+BOOL revoke_privilege(const DOM_SID *sid, SE_PRIV *priv_mask)
+{
+ SE_PRIV mask;
+
+ /* if the user has no privileges, then we can't revoke any */
+
+ if ( !get_privileges( sid, &mask ) )
+ return True;
+
+ DEBUG(10,("revoke_privilege: %s\n", sid_string_static(sid)));
+
+ DEBUGADD( 10, ("original privilege mask:\n"));
+ dump_se_priv( DBGC_ALL, 10, &mask );
- return NT_STATUS_UNSUCCESSFUL;
+ se_priv_remove( &mask, priv_mask );
+
+ DEBUGADD( 10, ("new privilege mask:\n"));
+ dump_se_priv( DBGC_ALL, 10, &mask );
+
+ return set_privileges( sid, &mask );
}
-/****************************************************************************
- remove a privilege from a privilege array
- ****************************************************************************/
-NTSTATUS remove_privilege(PRIVILEGE_SET *priv_set, LUID_ATTR set)
+/*********************************************************************
+ Revoke all privileges
+*********************************************************************/
+
+BOOL revoke_all_privileges( DOM_SID *sid )
{
- NTSTATUS ret;
- LUID_ATTR *new_set;
- LUID_ATTR *old_set;
- int i,j;
+ return revoke_privilege( sid, &se_priv_all );
+}
- if (!priv_set)
- return NT_STATUS_INVALID_PARAMETER;
+/*********************************************************************
+ Add a privilege based on its name
+*********************************************************************/
- /* check if the privilege is in the list */
- if (!NT_STATUS_IS_OK(check_priv_in_privilege(priv_set, set)))
- return NT_STATUS_UNSUCCESSFUL;
+BOOL revoke_privilege_by_name(DOM_SID *sid, const char *name)
+{
+ int i;
- /* special case if it's the only privilege in the list */
- if (priv_set->count == 1) {
- reset_privilege(priv_set);
- return NT_STATUS_OK;
- }
+ for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
+ if ( strequal(privs[i].name, name) ) {
+ return revoke_privilege( sid, &privs[i].se_priv );
+ }
+ }
- /*
- * the privilege is there, create a new list,
- * and copy the other privileges
- */
+ DEBUG(3, ("revoke_privilege_by_name: No Such Privilege Found (%s)\n", name));
- old_set = priv_set->set;
+ return False;
+}
- new_set = TALLOC_ARRAY(priv_set->mem_ctx, LUID_ATTR, priv_set->count - 1);
- ALLOC_CHECK(new_set, ret, done, "remove_privilege");
+/***************************************************************************
+ Retrieve the SIDs assigned to a given privilege
+****************************************************************************/
- 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;
+NTSTATUS privilege_create_account(const DOM_SID *sid )
+{
+ return ( grant_privilege(sid, &se_priv_none) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL);
+}
- j++;
- }
+/****************************************************************************
+ initialise a privilege list and set the talloc context
+ ****************************************************************************/
+NTSTATUS privilege_set_init(PRIVILEGE_SET *priv_set)
+{
+ TALLOC_CTX *mem_ctx;
- 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));
- return NT_STATUS_INTERNAL_ERROR;
+ ZERO_STRUCTP( priv_set );
+
+ mem_ctx = talloc_init("privilege set");
+ if ( !mem_ctx ) {
+ DEBUG(0,("privilege_set_init: failed to initialize talloc ctx!\n"));
+ return NT_STATUS_NO_MEMORY;
}
-
- /* ok everything is fine */
-
- priv_set->count--;
- priv_set->set = new_set;
+
+ priv_set->mem_ctx = mem_ctx;
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ initialise a privilege list and with someone else's talloc context
+****************************************************************************/
+
+NTSTATUS privilege_set_init_by_ctx(TALLOC_CTX *mem_ctx, PRIVILEGE_SET *priv_set)
+{
+ ZERO_STRUCTP( priv_set );
- ret = NT_STATUS_OK;
+ priv_set->mem_ctx = mem_ctx;
+ priv_set->ext_ctx = True;
-done:
- return ret;
+ return NT_STATUS_OK;
}
/****************************************************************************
- duplicates a privilege array
- the new privilege set must be passed inited
- (use init_privilege or init_priv_with_ctx)
+ Free all memory used by a PRIVILEGE_SET
+****************************************************************************/
+
+void privilege_set_free(PRIVILEGE_SET *priv_set)
+{
+ if ( !priv_set )
+ return;
+
+ if ( !( priv_set->ext_ctx ) )
+ talloc_destroy( priv_set->mem_ctx );
+
+ ZERO_STRUCTP( priv_set );
+}
+
+/****************************************************************************
+ duplicate alloc luid_attr
****************************************************************************/
-NTSTATUS dup_priv_set(PRIVILEGE_SET *new_priv_set, PRIVILEGE_SET *priv_set)
+
+NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_la, int count)
{
- NTSTATUS ret;
- LUID_ATTR *new_set;
- LUID_ATTR *old_set;
int i;
- if (!new_priv_set || !priv_set)
- return NT_STATUS_INVALID_PARAMETER;
+ /* don't crash if the source pointer is NULL (since we don't
+ do priviledges now anyways) */
- /* special case if there are no privileges in the list */
- if (priv_set->count == 0) {
+ if ( !old_la )
return NT_STATUS_OK;
+
+ *new_la = TALLOC_ARRAY(mem_ctx, LUID_ATTR, count);
+ if ( !*new_la ) {
+ DEBUG(0,("dup_luid_attr: failed to alloc new LUID_ATTR array [%d]\n", count));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<count; i++) {
+ (*new_la)[i].luid.high = old_la[i].luid.high;
+ (*new_la)[i].luid.low = old_la[i].luid.low;
+ (*new_la)[i].attr = old_la[i].attr;
}
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Does the user have the specified privilege ? We only deal with one privilege
+ at a time here.
+*****************************************************************************/
- /*
- * create a new list,
- * and copy the other privileges
- */
+BOOL user_has_privileges(NT_USER_TOKEN *token, SE_PRIV *privilege)
+{
+ if ( !token )
+ return False;
+
+ return is_privilege_assigned( &token->privileges, privilege );
+}
- old_set = priv_set->set;
+/****************************************************************************
+ Convert a LUID to a named string
+****************************************************************************/
- new_set = TALLOC_ARRAY(new_priv_set->mem_ctx, LUID_ATTR, priv_set->count - 1);
- ALLOC_CHECK(new_set, ret, done, "dup_priv_set");
+char* luid_to_privilege_name(const LUID *set)
+{
+ static fstring name;
+ int max = count_all_privileges();
+
+ if (set->high != 0)
+ return NULL;
+
+ if ( set->low > max )
+ return NULL;
+
+ fstrcpy( name, privs[set->low - 1].name );
+
+ return name;
+}
+
+/****************************************************************************
+ Convert an LUID to a 32-bit mask
+****************************************************************************/
+
+SE_PRIV* luid_to_privilege_mask(const LUID *set)
+{
+ static SE_PRIV mask;
+ int max = count_all_privileges();
+
+ if (set->high != 0)
+ return NULL;
+
+ if ( set->low > max )
+ return NULL;
+
+ se_priv_copy( &mask, &privs[set->low - 1].se_priv );
+
+ return &mask;
+}
- for (i=0; i < priv_set->count; i++) {
+/*******************************************************************
+ return the number of elements in the privlege array
+*******************************************************************/
+
+int count_all_privileges( void )
+{
+ static int count;
+
+ if ( count )
+ return count;
+
+ /* loop over the array and count it */
+ for ( count=0; !se_priv_equal(&privs[count].se_priv, &se_priv_end); count++ ) ;
+
+ return count;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+BOOL se_priv_to_privilege_set( PRIVILEGE_SET *set, SE_PRIV *mask )
+{
+ int i;
+ uint32 num_privs = count_all_privileges();
+ LUID_ATTR luid;
+
+ luid.attr = 0;
+ luid.luid.high = 0;
+
+ for ( i=0; i<num_privs; i++ ) {
+ if ( !is_privilege_assigned(mask, &privs[i].se_priv) )
+ continue;
- new_set[i].luid.low = old_set[i].luid.low;
- new_set[i].luid.high = old_set[i].luid.high;
- new_set[i].attr = old_set[i].attr;
+ luid.luid.low = GENERATE_LUID_LOW(i);
+
+ if ( !privilege_set_add( set, luid ) )
+ return False;
}
-
- new_priv_set->count = priv_set->count;
- new_priv_set->control = priv_set->control;
- new_priv_set->set = new_set;
+
+ return True;
+}
+
+/*******************************************************************
+*******************************************************************/
+
+BOOL privilege_set_to_se_priv( SE_PRIV *mask, PRIVILEGE_SET *privset )
+{
+ int i;
+ uint32 num_privs = count_all_privileges();
+
+ ZERO_STRUCTP( mask );
- ret = NT_STATUS_OK;
+ for ( i=0; i<privset->count; i++ ) {
+ SE_PRIV r;
+
+ /* sanity check for invalid privilege. we really
+ only care about the low 32 bits */
+
+ if ( privset->set[i].luid.high != 0 )
+ return False;
+
+ /* make sure :LUID.low is in range */
+ if ( privset->set[i].luid.low == 0 || privset->set[i].luid.low > num_privs )
+ return False;
+
+ r = privs[privset->set[i].luid.low - 1].se_priv;
+ se_priv_add( mask, &r );
+ }
+
+ return True;
+}
-done:
- return ret;
+/*******************************************************************
+*******************************************************************/
+
+BOOL is_privileged_sid( DOM_SID *sid )
+{
+ SE_PRIV mask;
+
+ return get_privileges( sid, &mask );
}
diff --git a/source/lib/select.c b/source/lib/select.c
index f88ad52de65..f3d119bdb15 100644
--- a/source/lib/select.c
+++ b/source/lib/select.c
@@ -128,12 +128,23 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf
{
int ret;
fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf;
- struct timeval tval2, *ptval;
+ struct timeval tval2, *ptval, end_time;
readfds2 = (readfds ? &readfds_buf : NULL);
writefds2 = (writefds ? &writefds_buf : NULL);
errorfds2 = (errorfds ? &errorfds_buf : NULL);
- ptval = (tval ? &tval2 : NULL);
+ if (tval) {
+ GetTimeOfDay(&end_time);
+ end_time.tv_sec += tval->tv_sec;
+ end_time.tv_usec += tval->tv_usec;
+ end_time.tv_sec += end_time.tv_usec / 1000000;
+ end_time.tv_usec %= 1000000;
+ errno = 0;
+ tval2 = *tval;
+ ptval = &tval2;
+ } else {
+ ptval = NULL;
+ }
do {
if (readfds)
@@ -142,8 +153,19 @@ int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorf
writefds_buf = *writefds;
if (errorfds)
errorfds_buf = *errorfds;
- if (tval)
- tval2 = *tval;
+ if (ptval && (errno == EINTR)) {
+ struct timeval now_time;
+ SMB_BIG_INT tdif;
+
+ GetTimeOfDay(&now_time);
+ tdif = usec_time_diff(&end_time, &now_time);
+ if (tdif <= 0) {
+ ret = 0; /* time expired. */
+ break;
+ }
+ ptval->tv_sec = tdif / 1000000;
+ ptval->tv_usec = tdif % 1000000;
+ }
ret = sys_select(maxfd, readfds2, writefds2, errorfds2, ptval);
} while (ret == -1 && errno == EINTR);
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index 4afafde9bb6..7908bc254da 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -1,5 +1,5 @@
/*
- Unix SMB/CIFS mplementation.
+ Unix SMB/CIFS implementation.
LDAP protocol helper functions for SAMBA
Copyright (C) Jean François Micouleau 1998
Copyright (C) Gerald Carter 2001-2003
@@ -806,6 +806,7 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
int rc;
char *ldap_dn;
char *ldap_secret;
+ int version;
/* get the password */
if (!fetch_ldap_pw(&ldap_dn, &ldap_secret)) {
@@ -855,7 +856,14 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
ldap_state->num_failures = 0;
+ ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);
+
+ if (smbldap_has_control(ldap_state, ADS_PAGE_CTL_OID) && version == 3) {
+ ldap_state->paged_results = True;
+ }
+
DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));
+ DEBUGADD(3, ("ldap_connect_system: LDAP server %s support paged results\n", ldap_state->paged_results?"does":"does not"));
return rc;
}
@@ -1431,3 +1439,96 @@ char *smbldap_get_dn(LDAP *ld, LDAPMessage *entry)
return unix_dn;
}
+/*******************************************************************
+ Check if root-dse has a certain Control or Extension
+********************************************************************/
+
+static BOOL smbldap_check_root_dse(struct smbldap_state *ldap_state, const char **attrs, const char *value)
+{
+ LDAPMessage *msg = NULL;
+ LDAPMessage *entry = NULL;
+ char **values = NULL;
+ int rc, num_result, num_values, i;
+ BOOL result = False;
+
+ if (!attrs[0]) {
+ DEBUG(3,("smbldap_check_root_dse: nothing to look for\n"));
+ return False;
+ }
+
+ if (!strequal(attrs[0], "supportedExtension") &&
+ !strequal(attrs[0], "supportedControl")) {
+ DEBUG(3,("smbldap_check_root_dse: no idea what to query root-dse for: %s ?\n", attrs[0]));
+ return False;
+ }
+
+ rc = ldap_search_s(ldap_state->ldap_struct, "", LDAP_SCOPE_BASE,
+ "(objectclass=*)", attrs, 0 , &msg);
+
+ if (rc != LDAP_SUCCESS) {
+ DEBUG(3,("smbldap_check_root_dse: Could not search rootDSE\n"));
+ return False;
+ }
+
+ num_result = ldap_count_entries(ldap_state->ldap_struct, msg);
+
+ if (num_result != 1) {
+ DEBUG(3,("smbldap_check_root_dse: Expected one rootDSE, got %d\n", num_result));
+ goto done;
+ }
+
+ entry = ldap_first_entry(ldap_state->ldap_struct, msg);
+
+ if (entry == NULL) {
+ DEBUG(3,("smbldap_check_root_dse: Could not retrieve rootDSE\n"));
+ goto done;
+ }
+
+ values = ldap_get_values(ldap_state->ldap_struct, entry, attrs[0]);
+
+ if (values == NULL) {
+ DEBUG(5,("smbldap_check_root_dse: LDAP Server does not support any %s\n", attrs[0]));
+ goto done;
+ }
+
+ num_values = ldap_count_values(values);
+
+ if (num_values == 0) {
+ DEBUG(5,("smbldap_check_root_dse: LDAP Server does not have any %s\n", attrs[0]));
+ goto done;
+ }
+
+ for (i=0; i<num_values; i++) {
+ if (strcmp(values[i], value) == 0)
+ result = True;
+ }
+
+
+ done:
+ if (values != NULL)
+ ldap_value_free(values);
+ if (msg != NULL)
+ ldap_msgfree(msg);
+
+ return result;
+}
+
+/*******************************************************************
+ Check if LDAP-Server supports a certain Control (OID in string format)
+********************************************************************/
+
+BOOL smbldap_has_control(struct smbldap_state *ldap_state, const char *control)
+{
+ const char *attrs[] = { "supportedControl", NULL };
+ return smbldap_check_root_dse(ldap_state, attrs, control);
+}
+
+/*******************************************************************
+ Check if LDAP-Server supports a certain Extension (OID in string format)
+********************************************************************/
+
+BOOL smbldap_has_extension(struct smbldap_state *ldap_state, const char *extension)
+{
+ const char *attrs[] = { "supportedExtension", NULL };
+ return smbldap_check_root_dse(ldap_state, attrs, extension);
+}
diff --git a/source/lib/util.c b/source/lib/util.c
index 4d66ed96558..455f87aaab8 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -779,12 +779,24 @@ SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
void smb_msleep(unsigned int t)
{
+#if defined(HAVE_NANOSLEEP)
+ struct timespec tval;
+ int ret;
+
+ tval.tv_sec = t/1000;
+ tval.tv_nsec = 1000000*(t%1000);
+
+ do {
+ errno = 0;
+ ret = nanosleep(&tval, &tval);
+ } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
+#else
unsigned int tdiff=0;
struct timeval tval,t1,t2;
fd_set fds;
GetTimeOfDay(&t1);
- GetTimeOfDay(&t2);
+ t2 = t1;
while (tdiff < t) {
tval.tv_sec = (t-tdiff)/1000;
@@ -808,6 +820,7 @@ void smb_msleep(unsigned int t)
tdiff = TvalDiff(&t1,&t2);
}
+#endif
}
/****************************************************************************
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index 197157a2f72..0ba774e184d 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -647,3 +647,67 @@ DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
return dst;
}
+
+/********************************************************************
+ Add SID to an array SIDs
+********************************************************************/
+
+void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num)
+{
+ *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1);
+
+ if (*sids == NULL)
+ return;
+
+ sid_copy(&((*sids)[*num]), sid);
+ *num += 1;
+
+ return;
+}
+
+
+/********************************************************************
+ Add SID to an array SIDs ensuring that it is not already there
+********************************************************************/
+
+void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids)
+{
+ int i;
+
+ for (i=0; i<(*num_sids); i++) {
+ if (sid_compare(sid, &(*sids)[i]) == 0)
+ return;
+ }
+
+ add_sid_to_array(sid, sids, num_sids);
+}
+
+/********************************************************************
+ Remove SID from an array
+********************************************************************/
+
+void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, int *num)
+{
+ DOM_SID *sid_list = *sids;
+ int i;
+
+ for ( i=0; i<*num; i++ ) {
+
+ /* if we find the SID, then decrement the count
+ and break out of the loop */
+
+ if ( sid_equal(sid, &sid_list[i]) ) {
+ *num -= 1;
+ break;
+ }
+ }
+
+ /* This loop will copy the remainder of the array
+ if i < num of sids ni the array */
+
+ for ( ; i<*num; i++ )
+ sid_copy( &sid_list[i], &sid_list[i+1] );
+
+ return;
+}
+
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 6ebada94d71..6b6581b4a7b 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -2092,3 +2092,19 @@ void string_append(char **left, const char *right)
safe_strcat(*left, right, new_len-1);
}
+
+BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
+ const char *str, const char ***strings,
+ int *num)
+{
+ char *dup_str = talloc_strdup(mem_ctx, str);
+
+ *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
+
+ if ((*strings == NULL) || (dup_str == NULL))
+ return False;
+
+ (*strings)[*num] = dup_str;
+ *num += 1;
+ return True;
+}
diff --git a/source/libads/kerberos.c b/source/libads/kerberos.c
index b08e28e0ba4..4c9997e080e 100644
--- a/source/libads/kerberos.c
+++ b/source/libads/kerberos.c
@@ -3,7 +3,7 @@
kerberos utility library
Copyright (C) Andrew Tridgell 2001
Copyright (C) Remus Koos 2001
- Copyright (C) Nalin Dahyabhai 2004.
+ Copyright (C) Nalin Dahyabhai <nalin@redhat.com> 2004.
Copyright (C) Jeremy Allison 2004.
This program is free software; you can redistribute it and/or modify
diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c
index f7cbe8674bb..d73fc28a296 100644
--- a/source/libads/kerberos_verify.c
+++ b/source/libads/kerberos_verify.c
@@ -110,7 +110,7 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut
ret = krb5_rd_req(context, &auth_context, p_packet, host_princ, keytab, NULL, pp_tkt);
krb5_free_principal(context, host_princ);
if (ret) {
- DEBUG(0, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret)));
+ DEBUG(10, ("krb5_rd_req(%s) failed: %s\n", host_princ_s[i], error_message(ret)));
} else {
DEBUG(10,("krb5_rd_req succeeded for principal %s\n", host_princ_s[i]));
auth_ok = True;
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index 8c37a90e732..494bd930e4e 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -75,20 +75,24 @@ static int ldap_search_with_timeout(LDAP *ld,
int attrsonly,
LDAPControl **sctrls,
LDAPControl **cctrls,
- struct timeval *timeout,
int sizelimit,
LDAPMessage **res )
{
+ struct timeval timeout;
int result;
- /* Setup timeout */
+ /* Setup timeout for the ldap_search_ext_s call - local and remote. */
+ timeout.tv_sec = lp_ldap_timeout();
+ timeout.tv_usec = 0;
+
+ /* Setup alarm timeout.... Do we need both of these ? JRA. */
gotalarm = 0;
CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
alarm(lp_ldap_timeout());
/* End setup timeout. */
result = ldap_search_ext_s(ld, base, scope, filter, attrs,
- attrsonly, sctrls, cctrls, timeout,
+ attrsonly, sctrls, cctrls, &timeout,
sizelimit, res);
/* Teardown timeout. */
@@ -504,14 +508,14 @@ ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path,
rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr,
search_attrs, 0, controls,
- NULL, NULL, LDAP_NO_LIMIT,
+ NULL, LDAP_NO_LIMIT,
(LDAPMessage **)res);
ber_free(cookie_be, 1);
ber_bvfree(cookie_bv);
if (rc) {
- DEBUG(3,("ldap_search_with_timeout(%s) -> %s\n", expr,
+ DEBUG(3,("ads_do_paged_search: ldap_search_with_timeout(%s) -> %s\n", expr,
ldap_err2string(rc)));
goto done;
}
@@ -655,7 +659,6 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
const char *expr,
const char **attrs, void **res)
{
- struct timeval timeout;
int rc;
char *utf8_expr, *utf8_path, **search_attrs = NULL;
TALLOC_CTX *ctx;
@@ -689,15 +692,12 @@ ADS_STATUS ads_do_search(ADS_STRUCT *ads, const char *bind_path, int scope,
}
}
- timeout.tv_sec = ADS_SEARCH_TIMEOUT;
- timeout.tv_usec = 0;
-
/* see the note in ads_do_paged_search - we *must* disable referrals */
ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr,
search_attrs, 0, NULL, NULL,
- &timeout, LDAP_NO_LIMIT,
+ LDAP_NO_LIMIT,
(LDAPMessage **)res);
if (rc == LDAP_SIZELIMIT_EXCEEDED) {
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index 682e0d8b85a..39fe91172d4 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -245,6 +245,7 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state)
struct cli_state *cli_initialise(struct cli_state *cli)
{
BOOL alloced_cli = False;
+ int i;
/* Check the effective uid - make sure we are not setuid */
if (is_setuid_root()) {
@@ -315,7 +316,9 @@ struct cli_state *cli_initialise(struct cli_state *cli)
/* initialise signing */
cli_null_set_signing(cli);
- cli->nt_pipe_fnum = 0;
+ for (i=0; i<PI_MAX_PIPES; i++)
+ cli->nt_pipe_fnum[i] = 0;
+
cli->saved_netlogon_pipe_fnum = 0;
cli->initialised = 1;
@@ -344,14 +347,17 @@ close the session
void cli_nt_session_close(struct cli_state *cli)
{
+ int i;
+
if (cli->ntlmssp_pipe_state) {
ntlmssp_end(&cli->ntlmssp_pipe_state);
}
- if (cli->nt_pipe_fnum != 0)
- cli_close(cli, cli->nt_pipe_fnum);
-
- cli->nt_pipe_fnum = 0;
+ for (i=0; i<PI_MAX_PIPES; i++) {
+ if (cli->nt_pipe_fnum[i] != 0)
+ cli_close(cli, cli->nt_pipe_fnum[i]);
+ cli->nt_pipe_fnum[i] = 0;
+ }
cli->pipe_idx = -1;
}
diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c
index 761741a91bc..3f1afa75d69 100644
--- a/source/libsmb/clitrans.c
+++ b/source/libsmb/clitrans.c
@@ -504,7 +504,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
*/
if (cli_is_dos_error(cli)) {
cli_dos_error(cli, &eclass, &ecode);
- if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
+ if (cli->nt_pipe_fnum[cli->pipe_idx] == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
cli_signing_trans_stop(cli);
return(False);
}
@@ -638,7 +638,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
}
if (cli_is_dos_error(cli)) {
cli_dos_error(cli, &eclass, &ecode);
- if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
+ if(cli->nt_pipe_fnum[cli->pipe_idx] == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) {
cli_signing_trans_stop(cli);
return(False);
}
diff --git a/source/modules/vfs_expand_msdfs.c b/source/modules/vfs_expand_msdfs.c
index 07fbe59825e..d22f6a7f98e 100644
--- a/source/modules/vfs_expand_msdfs.c
+++ b/source/modules/vfs_expand_msdfs.c
@@ -40,7 +40,7 @@ static BOOL read_target_host(const char *mapfile, pstring targethost)
{
XFILE *f;
pstring buf;
- char *s, *space = buf;
+ char *space = buf;
BOOL found = False;
f = x_fopen(mapfile, O_RDONLY, 0);
@@ -53,7 +53,7 @@ static BOOL read_target_host(const char *mapfile, pstring targethost)
DEBUG(10, ("Scanning mapfile [%s]\n", mapfile));
- while ((s=x_fgets(buf, sizeof(buf), f)) != NULL) {
+ while (x_fgets(buf, sizeof(buf), f) != NULL) {
if ((strlen(buf) > 0) && (buf[strlen(buf)-1] == '\n'))
buf[strlen(buf)-1] = '\0';
diff --git a/source/modules/vfs_shadow_copy.c b/source/modules/vfs_shadow_copy.c
index 133e8e9c647..513f33b3cb3 100644
--- a/source/modules/vfs_shadow_copy.c
+++ b/source/modules/vfs_shadow_copy.c
@@ -137,6 +137,7 @@ int shadow_copy_closedir(vfs_handle_struct *handle, connection_struct *conn, DIR
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
+ SAFE_FREE(dirp->dirs);
SAFE_FREE(dirp);
return 0;
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
index 22deaf82c6e..cd1d16e3441 100644
--- a/source/nsswitch/winbindd.h
+++ b/source/nsswitch/winbindd.h
@@ -183,6 +183,14 @@ struct winbindd_methods {
const DOM_SID *user_sid,
uint32 *num_groups, DOM_SID ***user_gids);
+ /* Lookup all aliases that the sids delivered are member of. This is
+ * to implement 'domain local groups' correctly */
+ NTSTATUS (*lookup_useraliases)(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, DOM_SID **sids,
+ uint32 *num_aliases,
+ uint32 **alias_rids);
+
/* find all members of the group with the specified group_rid */
NTSTATUS (*lookup_groupmem)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c
index f77b76cd9ab..335e21adcbe 100644
--- a/source/nsswitch/winbindd_ads.c
+++ b/source/nsswitch/winbindd_ads.c
@@ -966,6 +966,7 @@ struct winbindd_methods ads_methods = {
msrpc_sid_to_name,
query_user,
lookup_usergroups,
+ msrpc_lookup_useraliases,
lookup_groupmem,
sequence_number,
trusted_domains,
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index ba274ec8e70..460ce934cb7 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -5,6 +5,7 @@
Copyright (C) Andrew Tridgell 2001
Copyright (C) Gerald Carter 2003
+ Copyright (C) Volker Lendecke 2005
This program is free software; you can redistribute it and/or modify
@@ -1202,6 +1203,90 @@ skip_save:
return status;
}
+static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, DOM_SID **sids,
+ uint32 *num_aliases, uint32 **alias_rids)
+{
+ struct winbind_cache *cache = get_cache(domain);
+ struct cache_entry *centry = NULL;
+ NTSTATUS status;
+ char *sidlist = talloc_strdup(mem_ctx, "");
+ int i;
+
+ if (!cache->tdb)
+ goto do_query;
+
+ if (num_sids == 0) {
+ *num_aliases = 0;
+ *alias_rids = NULL;
+ return NT_STATUS_OK;
+ }
+
+ /* We need to cache indexed by the whole list of SIDs, the aliases
+ * resulting might come from any of the SIDs. */
+
+ for (i=0; i<num_sids; i++) {
+ sidlist = talloc_asprintf(mem_ctx, "%s/%s", sidlist,
+ sid_string_static(sids[i]));
+ if (sidlist == NULL)
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ centry = wcache_fetch(cache, domain, "UA%s", sidlist);
+
+ if (!centry)
+ goto do_query;
+
+ *num_aliases = centry_uint32(centry);
+ *alias_rids = NULL;
+
+ (*alias_rids) = TALLOC_ARRAY(mem_ctx, uint32, *num_aliases);
+
+ if (!(*alias_rids))
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<(*num_aliases); i++)
+ (*alias_rids)[i] = centry_uint32(centry);
+
+ status = centry->status;
+
+ DEBUG(10,("lookup_useraliases: [Cached] - cached info for domain %s "
+ "status %s\n", domain->name,
+ get_friendly_nt_error_msg(status)));
+
+ centry_free(centry);
+ return status;
+
+ do_query:
+ (*num_aliases) = 0;
+ (*alias_rids) = NULL;
+
+ 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_useraliases(domain, mem_ctx,
+ num_sids, sids,
+ num_aliases, alias_rids);
+
+ /* and save it */
+ refresh_sequence_number(domain, False);
+ centry = centry_start(domain, status);
+ if (!centry)
+ goto skip_save;
+ centry_put_uint32(centry, *num_aliases);
+ for (i=0; i<(*num_aliases); i++)
+ centry_put_uint32(centry, (*alias_rids)[i]);
+ centry_end(centry, "UA%s", sidlist);
+ centry_free(centry);
+
+ skip_save:
+ return status;
+}
+
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
@@ -1387,6 +1472,7 @@ struct winbindd_methods cache_methods = {
sid_to_name,
query_user,
lookup_usergroups,
+ lookup_useraliases,
lookup_groupmem,
sequence_number,
trusted_domains,
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index 1843ec188b0..90ecfe18915 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -266,7 +266,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
(peeraddr_len != sizeof(struct sockaddr_in)) ||
(peeraddr_in->sin_family != PF_INET))
+ {
+ DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
goto done;
+ }
if (ntohs(peeraddr_in->sin_port) == 139) {
struct nmb_name calling;
@@ -443,21 +446,6 @@ static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
return True;
}
-static BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
- const char *str, char ***array, int *num)
-{
- char *dup_str = talloc_strdup(mem_ctx, str);
-
- *array = TALLOC_REALLOC_ARRAY(mem_ctx, *array, char *, (*num)+1);
-
- if ((*array == NULL) || (dup_str == NULL))
- return False;
-
- (*array)[*num] = dup_str;
- *num += 1;
- return True;
-}
-
static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
struct in_addr ip, uint16 port,
struct sockaddr_in **addrs, int *num)
@@ -505,6 +493,8 @@ static BOOL get_dcs_1c(TALLOC_CTX *mem_ctx,
}
}
+ SAFE_FREE(iplist);
+
return True;
}
@@ -554,6 +544,12 @@ static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
if (!resolve_name(dcname, &ip, 0x20))
continue;
+ /* Even if we got the dcname, double check the name to use for
+ * the netlogon auth2 */
+
+ if (!name_status_find(domain->name, 0x1c, 0x20, ip, dcname))
+ continue;
+
add_one_dc_unique(mem_ctx, domain->name, dcname, ip,
dcs, num_dcs);
}
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index d64c2e4a19c..502a4b85841 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -6,6 +6,7 @@
Copyright (C) Tim Potter 2000
Copyright (C) Jeremy Allison 2001.
Copyright (C) Gerald (Jerry) Carter 2003.
+ Copyright (C) Volker Lendecke 2005
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
@@ -1234,6 +1235,46 @@ enum winbindd_result winbindd_getusersids(struct winbindd_cli_state *state)
goto no_groups;
}
+ domain = find_our_domain();
+
+ if (domain == NULL) {
+ DEBUG(0, ("Could not find our domain\n"));
+ goto done;
+ }
+
+ /* Note that I do not check for AD or its mode. XP in a real NT4
+ * domain also asks for this info. -- vl */
+
+ if (!IS_DC) {
+ uint32_t *alias_rids = NULL;
+ int num_aliases;
+
+ /* We need to include the user SID to expand */
+ user_grpsids = TALLOC_REALLOC_ARRAY(mem_ctx, user_grpsids,
+ DOM_SID *, num_groups+1);
+ user_grpsids[num_groups] = &user_sid;
+
+ status = domain->methods->lookup_useraliases(domain, mem_ctx,
+ num_groups,
+ user_grpsids+1,
+ &num_aliases,
+ &alias_rids);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("Could not expand alias sids: %s\n",
+ nt_errstr(status)));
+ goto done;
+ }
+
+ for (i=0; i<num_aliases; i++) {
+ DOM_SID sid;
+ sid_copy(&sid, &domain->sid);
+ sid_append_rid(&sid, alias_rids[i]);
+ add_sid_to_parray_unique(mem_ctx, &sid, &user_grpsids,
+ &num_groups);
+ }
+ }
+
if (lp_winbind_nested_groups()) {
int k;
/* num_groups is changed during the loop, that's why we have
diff --git a/source/nsswitch/winbindd_passdb.c b/source/nsswitch/winbindd_passdb.c
index a208186b5f5..4dcc018c64b 100644
--- a/source/nsswitch/winbindd_passdb.c
+++ b/source/nsswitch/winbindd_passdb.c
@@ -292,6 +292,13 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
return NT_STATUS_NO_SUCH_USER;
}
+static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, const DOM_SID **sids,
+ uint32 *num_aliases, DOM_SID ***aliases)
+{
+ return NT_STATUS_NO_SUCH_USER;
+}
/* Lookup group membership given a rid. */
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
@@ -384,6 +391,7 @@ struct winbindd_methods passdb_methods = {
sid_to_name,
query_user,
lookup_usergroups,
+ lookup_useraliases,
lookup_groupmem,
sequence_number,
trusted_domains,
diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c
index e6edb70f079..10d6e4f4fa9 100644
--- a/source/nsswitch/winbindd_rpc.c
+++ b/source/nsswitch/winbindd_rpc.c
@@ -5,6 +5,7 @@
Copyright (C) Tim Potter 2000-2001,2003
Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Volker Lendecke 2005
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
@@ -561,6 +562,66 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
return result;
}
+NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, DOM_SID **sids,
+ uint32 *num_aliases, uint32 **alias_rids)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ CLI_POLICY_HND *hnd;
+ BOOL got_dom_pol = False;
+ POLICY_HND dom_pol;
+ DOM_SID2 *sid2;
+ int i, retry;
+
+ *num_aliases = 0;
+ *alias_rids = NULL;
+
+ retry = 0;
+ do {
+ /* Get sam handle; if we fail here there is no hope */
+
+ if (!NT_STATUS_IS_OK(result = cm_get_sam_handle(domain,
+ &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);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ got_dom_pol = True;
+
+ sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids);
+
+ if (sid2 == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ for (i=0; i<num_sids; i++) {
+ sid_copy(&sid2[i].sid, sids[i]);
+ sid2[i].num_auths = sid2[i].sid.num_auths;
+ }
+
+ result = cli_samr_query_useraliases(hnd->cli, mem_ctx, &dom_pol,
+ num_sids, sid2,
+ num_aliases, alias_rids);
+
+ done:
+
+ if (got_dom_pol)
+ cli_samr_close(hnd->cli, mem_ctx, &dom_pol);
+
+ return result;
+}
+
/* Lookup group membership given a rid. */
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
@@ -980,6 +1041,7 @@ struct winbindd_methods msrpc_methods = {
msrpc_sid_to_name,
query_user,
lookup_usergroups,
+ msrpc_lookup_useraliases,
lookup_groupmem,
sequence_number,
trusted_domains,
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 5ca19134bb5..8531b2fdd13 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -291,6 +291,7 @@ typedef struct
BOOL bKernelChangeNotify;
BOOL bUseKerberosKeytab;
BOOL bDeferSharingViolations;
+ BOOL bEnablePrivileges;
int restrict_anonymous;
int name_cache_timeout;
int client_signing;
@@ -809,6 +810,7 @@ static struct parm_struct parm_table[] = {
{"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
{"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
{"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
+ {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
{"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
{"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
@@ -1092,6 +1094,7 @@ static struct parm_struct parm_table[] = {
{"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
{"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
{"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
+ {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
{"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
{"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
{"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
@@ -1537,6 +1540,12 @@ static void init_globals(void)
Globals.bDeferSharingViolations = True;
string_set(&Globals.smb_ports, SMB_PORTS);
+
+ /* don't enable privileges by default since Domain
+ Admins can then assign thr rights to perform certain
+ operations as root */
+
+ Globals.bEnablePrivileges = False;
}
static TALLOC_CTX *lp_talloc;
@@ -1774,6 +1783,7 @@ FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
+FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index aeea4316f38..1f5e4be6cf6 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -1777,6 +1777,7 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
uint32 pwHistLen = 0;
BOOL ret = True;
+ fstring tmpstring;
if(sampass == NULL || buf == NULL) {
DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
@@ -1840,7 +1841,9 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
pdb_set_fullname(sampass, fullname, PDB_SET);
if (homedir) {
- pdb_set_homedir(sampass, homedir, PDB_SET);
+ fstrcpy( tmpstring, homedir );
+ standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ pdb_set_homedir(sampass, tmpstring, PDB_SET);
}
else {
pdb_set_homedir(sampass,
@@ -1850,14 +1853,14 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
if (dir_drive)
pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
- else {
- pdb_set_dir_drive(sampass,
- talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
- PDB_DEFAULT);
- }
+ else
+ pdb_set_dir_drive(sampass, lp_logon_drive(), PDB_DEFAULT );
- if (logon_script)
- pdb_set_logon_script(sampass, logon_script, PDB_SET);
+ if (logon_script) {
+ fstrcpy( tmpstring, logon_script );
+ standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ pdb_set_logon_script(sampass, tmpstring, PDB_SET);
+ }
else {
pdb_set_logon_script(sampass,
talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
@@ -1865,8 +1868,11 @@ BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
if (profile_path) {
- pdb_set_profile_path(sampass, profile_path, PDB_SET);
- } else {
+ fstrcpy( tmpstring, profile_path );
+ standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ pdb_set_profile_path(sampass, tmpstring, PDB_SET);
+ }
+ else {
pdb_set_profile_path(sampass,
talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
PDB_DEFAULT);
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
index 2ca76384721..92e2cee7100 100644
--- a/source/passdb/pdb_get_set.c
+++ b/source/passdb/pdb_get_set.c
@@ -327,14 +327,6 @@ const char* pdb_get_munged_dial (const SAM_ACCOUNT *sampass)
return (NULL);
}
-uint32 pdb_get_fields_present (const SAM_ACCOUNT *sampass)
-{
- if (sampass)
- return (sampass->private.fields_present);
- else
- return (-1);
-}
-
uint16 pdb_get_bad_password_count(const SAM_ACCOUNT *sampass)
{
if (sampass)
@@ -1048,16 +1040,6 @@ BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const char *password, enum
return pdb_set_init_flags(sampass, PDB_PLAINTEXT_PW, flag);
}
-BOOL pdb_set_fields_present (SAM_ACCOUNT *sampass, uint32 fields_present, enum pdb_value_state flag)
-{
- if (!sampass)
- return False;
-
- sampass->private.fields_present = fields_present;
-
- return pdb_set_init_flags(sampass, PDB_FIELDS_PRESENT, flag);
-}
-
BOOL pdb_set_bad_password_count(SAM_ACCOUNT *sampass, uint16 bad_password_count, enum pdb_value_state flag)
{
if (!sampass)
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 9bc38fb4449..ea097c10f69 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -119,7 +119,7 @@ static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
return NULL;
}
-static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update)
+static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update, uint16 acb_mask)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
@@ -135,7 +135,7 @@ static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update)
return ret;
}
- while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update))) {
+ while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update, acb_mask))) {
context->pwent_methods = context->pwent_methods->next;
if (context->pwent_methods == NULL)
return NT_STATUS_UNSUCCESSFUL;
@@ -176,7 +176,7 @@ static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *us
if (context->pwent_methods == NULL)
return ret;
- context->pwent_methods->setsampwent(context->pwent_methods, False);
+ context->pwent_methods->setsampwent(context->pwent_methods, False, 0);
}
user->methods = context->pwent_methods;
pdb_force_pw_initialization(user);
@@ -857,7 +857,7 @@ static struct pdb_context *pdb_get_static_context(BOOL reload)
Backward compatibility functions for the original passdb interface
*******************************************************************/
-BOOL pdb_setsampwent(BOOL update)
+BOOL pdb_setsampwent(BOOL update, uint16 acb_mask)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -865,7 +865,7 @@ BOOL pdb_setsampwent(BOOL update)
return False;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update));
+ return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update, acb_mask));
}
void pdb_endsampwent(void)
@@ -1243,7 +1243,7 @@ static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM
return NT_STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update)
+static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index a84b2f35b28..8b7661d9a36 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -1,5 +1,5 @@
/*
- Unix SMB/CIFS mplementation.
+ Unix SMB/CIFS implementation.
LDAP protocol helper functions for SAMBA
Copyright (C) Jean François Micouleau 1998
Copyright (C) Gerald Carter 2001-2003
@@ -476,6 +476,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pstring temp;
LOGIN_CACHE *cache_entry = NULL;
int pwHistLen;
+ pstring tmpstring;
/*
* do a little initialization
@@ -635,9 +636,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
if (!smbldap_get_single_pstring(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_basic(sampass->mem_ctx, username, lp_logon_drive()),
- PDB_DEFAULT );
+ pdb_set_dir_drive( sampass, lp_logon_drive(), PDB_DEFAULT );
} else {
pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
}
@@ -649,7 +648,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
PDB_DEFAULT );
} else {
- pdb_set_homedir(sampass, homedir, PDB_SET);
+ pstrcpy( tmpstring, homedir );
+ standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ pdb_set_homedir(sampass, tmpstring, PDB_SET);
}
if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
@@ -659,7 +660,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
PDB_DEFAULT );
} else {
- pdb_set_logon_script(sampass, logon_script, PDB_SET);
+ pstrcpy( tmpstring, logon_script );
+ standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ pdb_set_logon_script(sampass, tmpstring, PDB_SET);
}
if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
@@ -669,7 +672,9 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
talloc_sub_basic( sampass->mem_ctx, username, lp_logon_path()),
PDB_DEFAULT );
} else {
- pdb_set_profile_path(sampass, profile_path, PDB_SET);
+ pstrcpy( tmpstring, profile_path );
+ standard_sub_basic( username, tmpstring, sizeof(tmpstring) );
+ pdb_set_profile_path(sampass, tmpstring, PDB_SET);
}
if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
@@ -782,8 +787,6 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_hours_len(sampass, hours_len, PDB_SET);
pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
-/* pdb_set_munged_dial(sampass, munged_dial, PDB_SET); */
-
if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_BAD_PASSWORD_COUNT), temp)) {
/* leave as default */
@@ -1182,33 +1185,48 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
Connect to LDAP server for password enumeration.
*********************************************************************/
-static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
+static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
{
struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
int rc;
- pstring filter;
+ pstring filter, suffix;
char **attr_list;
+ BOOL machine_mask = False, user_mask = False;
pstr_sprintf( filter, "(&%s%s)", lp_ldap_filter(),
get_objclass_filter(ldap_state->schema_ver));
all_string_sub(filter, "%u", "*", sizeof(pstring));
+ machine_mask = ((acb_mask != 0) && (acb_mask & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)));
+ user_mask = ((acb_mask != 0) && (acb_mask & ACB_NORMAL));
+
+ if (machine_mask) {
+ pstrcpy(suffix, lp_ldap_machine_suffix());
+ } else if (user_mask) {
+ pstrcpy(suffix, lp_ldap_user_suffix());
+ } else {
+ pstrcpy(suffix, lp_ldap_suffix());
+ }
+
+ DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n",
+ acb_mask, suffix));
+
attr_list = get_userattr_list(ldap_state->schema_ver);
- rc = smbldap_search_suffix(ldap_state->smbldap_state, filter,
- attr_list, &ldap_state->result);
+ rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter,
+ attr_list, 0, &ldap_state->result);
free_attr_list( attr_list );
if (rc != LDAP_SUCCESS) {
DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
- DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", lp_ldap_suffix(), filter));
+ DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix, filter));
ldap_msgfree(ldap_state->result);
ldap_state->result = NULL;
return NT_STATUS_UNSUCCESSFUL;
}
- DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
- ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
- ldap_state->result)));
+ DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n",
+ ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
+ ldap_state->result), suffix));
ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
ldap_state->result);
@@ -1409,62 +1427,7 @@ static NTSTATUS ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT
static BOOL ldapsam_can_pwchange_exop(struct smbldap_state *ldap_state)
{
- LDAPMessage *msg = NULL;
- LDAPMessage *entry = NULL;
- char **values = NULL;
- char *attrs[] = { "supportedExtension", NULL };
- int rc, num_result, num_values, i;
- BOOL result = False;
-
- rc = smbldap_search(ldap_state, "", LDAP_SCOPE_BASE, "(objectclass=*)",
- attrs, 0, &msg);
-
- if (rc != LDAP_SUCCESS) {
- DEBUG(3, ("Could not search rootDSE\n"));
- return False;
- }
-
- num_result = ldap_count_entries(ldap_state->ldap_struct, msg);
-
- if (num_result != 1) {
- DEBUG(3, ("Expected one rootDSE, got %d\n", num_result));
- goto done;
- }
-
- entry = ldap_first_entry(ldap_state->ldap_struct, msg);
-
- if (entry == NULL) {
- DEBUG(3, ("Could not retrieve rootDSE\n"));
- goto done;
- }
-
- values = ldap_get_values(ldap_state->ldap_struct, entry,
- "supportedExtension");
-
- if (values == NULL) {
- DEBUG(9, ("LDAP Server does not support any extensions\n"));
- goto done;
- }
-
- num_values = ldap_count_values(values);
-
- if (num_values == 0) {
- DEBUG(9, ("LDAP Server does not support any extensions\n"));
- goto done;
- }
-
- for (i=0; i<num_values; i++) {
- if (strcmp(values[i], LDAP_EXOP_MODIFY_PASSWD) == 0)
- result = True;
- }
-
- done:
- if (values != NULL)
- ldap_value_free(values);
- if (msg != NULL)
- ldap_msgfree(msg);
-
- return result;
+ return smbldap_has_extension(ldap_state, LDAP_EXOP_MODIFY_PASSWD);
}
/********************************************************************
@@ -2267,7 +2230,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
if (!smbldap_get_single_attribute(conn->ldap_struct,
entry, "sambaSID",
str, sizeof(str)-1))
- goto done;
+ continue;
if (!string_to_sid(&sid, str))
goto done;
@@ -2275,7 +2238,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
if (!smbldap_get_single_attribute(conn->ldap_struct,
entry, "gidNumber",
str, sizeof(str)-1))
- goto done;
+ continue;
gid = strtoul(str, &end, 10);
@@ -2291,7 +2254,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
}
if (sid_compare(&global_sid_NULL, &(*sids)[0]) == 0) {
- DEBUG(3, ("primary group not found\n"));
+ DEBUG(3, ("primary group of [%s] not found\n", username));
goto done;
}
diff --git a/source/passdb/pdb_mysql.c b/source/passdb/pdb_mysql.c
index 0e6a11d9326..fbe44233245 100644
--- a/source/passdb/pdb_mysql.c
+++ b/source/passdb/pdb_mysql.c
@@ -120,7 +120,7 @@ static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u)
return NT_STATUS_OK;
}
-static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update)
+static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
{
struct pdb_mysql_data *data =
(struct pdb_mysql_data *) methods->private_data;
@@ -454,10 +454,9 @@ static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_metho
data->location = smb_xstrdup(location);
DEBUG(1,
- ("Connecting to database server, host: %s, user: %s, password: %s, database: %s, port: %ld\n",
+ ("Connecting to database server, host: %s, user: %s, database: %s, port: %ld\n",
config_value(data, "mysql host", CONFIG_HOST_DEFAULT),
config_value(data, "mysql user", CONFIG_USER_DEFAULT),
- config_value(data, "mysql password", CONFIG_PASS_DEFAULT),
config_value(data, "mysql database", CONFIG_DB_DEFAULT),
xatol(config_value(data, "mysql port", CONFIG_PORT_DEFAULT))));
diff --git a/source/passdb/pdb_pgsql.c b/source/passdb/pdb_pgsql.c
index 6578d3d192a..0955ea1881f 100644
--- a/source/passdb/pdb_pgsql.c
+++ b/source/passdb/pdb_pgsql.c
@@ -118,7 +118,7 @@ static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u )
return NT_STATUS_OK ;
}
-static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update)
+static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
{
struct pdb_pgsql_data *data ;
char *query ;
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index d75d0ed5c8c..edb578b1e74 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -1226,7 +1226,7 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
Functions to be implemented by the new passdb API
****************************************************************/
-static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update)
+static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
{
struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
diff --git a/source/passdb/pdb_sql.c b/source/passdb/pdb_sql.c
index 820280bcbf6..ee9ece2baf0 100644
--- a/source/passdb/pdb_sql.c
+++ b/source/passdb/pdb_sql.c
@@ -141,8 +141,14 @@ static const char * config_value_write(const char *location, const char *name, c
swrite = strrchr(v, ':');
/* Default to the same field as read field */
- if (!swrite)
+ if (!swrite) {
+
+ /* Updating NULL does not make much sense */
+ if (!strcmp(v, "NULL"))
+ return NULL;
+
return v;
+ }
swrite++;
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index c792d229b9a..755e33940b8 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -2,7 +2,7 @@
* Unix SMB/CIFS implementation.
* SMB parameters and setup
* Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Simo Sorce 2000-2002
+ * Copyright (C) Simo Sorce 2000-2003
* Copyright (C) Gerald Carter 2000
* Copyright (C) Jeremy Allison 2001
* Copyright (C) Andrew Bartlett 2002
@@ -42,6 +42,7 @@ static int tdbsam_debug_level = DBGC_ALL;
#define PASSDB_FILE_NAME "passdb.tdb"
#define USERPREFIX "USER_"
#define RIDPREFIX "RID_"
+#define PRIVPREFIX "PRIV_"
#define tdbsamver_t int32
struct tdbsam_privates {
@@ -293,7 +294,7 @@ static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data,
Save a list of user keys for iteration.
****************************************************************/
-static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
+static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
{
uint32 flags = update ? (O_RDWR|O_CREAT) : O_RDONLY;
@@ -704,6 +705,18 @@ static void free_private_data(void **vp)
}
+
+
+/**
+ * Init tdbsam backend
+ *
+ * @param pdb_context initialised passdb context
+ * @param pdb_method backend methods structure to be filled with function pointers
+ * @param location the backend tdb file location
+ *
+ * @return nt_status code
+ **/
+
static NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
NTSTATUS nt_status;
diff --git a/source/passdb/pdb_xml.c b/source/passdb/pdb_xml.c
index 6eb7761a3b4..2a21fc8c9f5 100644
--- a/source/passdb/pdb_xml.c
+++ b/source/passdb/pdb_xml.c
@@ -307,7 +307,7 @@ static xmlNodePtr parseSambaXMLFile(struct pdb_xml *data)
return cur;
}
-static NTSTATUS xmlsam_setsampwent(struct pdb_methods *methods, BOOL update)
+static NTSTATUS xmlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
{
pdb_xml *data;
diff --git a/source/passdb/privileges.c b/source/passdb/privileges.c
deleted file mode 100644
index 69fc75a618c..00000000000
--- a/source/passdb/privileges.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Unix SMB/CIFS implementation.
- *
- * default privileges backend for passdb
- *
- * Copyright (C) Andrew Tridgell 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"
-
-/*
- this is a local implementation of a privileges backend, with
- privileges stored in a tdb. Most passdb implementations will
- probably use this backend, although some (such as pdb_ldap) will
- store the privileges in another manner.
-
- The basic principle is that the backend should store a list of SIDs
- associated with each right, where a right is a string name such as
- 'SeTakeOwnershipPrivilege'. The SIDs can be of any type, and do not
- need to belong to the local domain.
-
- The way this is used is that certain places in the code which
- require access control will ask the privileges backend 'does this
- user have the following privilege'. The 'user' will be a NT_TOKEN,
- which is essentially just a list of SIDs. If any of those SIDs are
- listed in the list of SIDs for that privilege then the answer will
- be 'yes'. That will usually mean that the user gets unconditional
- access to that functionality, regradless of any ACLs. In this way
- privileges act in a similar fashion to unix setuid bits.
-*/
-
-/*
- The terms 'right' and 'privilege' are used interchangably in this
- file. This follows MSDN convention where the LSA calls are calls on
- 'rights', which really means privileges. My apologies for the
- confusion.
-*/
-
-
-/* 15 seconds seems like an ample time for timeouts on the privileges db */
-#define LOCK_TIMEOUT 15
-
-
-/* the tdb handle for the privileges database */
-static TDB_CONTEXT *tdb;
-
-
-/* initialise the privilege database */
-BOOL privilege_init(void)
-{
- tdb = tdb_open_log(lock_path("privilege.tdb"), 0, TDB_DEFAULT,
- O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open privilege database\n"));
- return False;
- }
-
- return True;
-}
-
-/*
- lock the record for a particular privilege (write lock)
-*/
-static NTSTATUS privilege_lock_right(const char *right)
-{
- if (tdb_lock_bystring(tdb, right, LOCK_TIMEOUT) != 0) {
- return NT_STATUS_INTERNAL_ERROR;
- }
- return NT_STATUS_OK;
-}
-
-/*
- unlock the record for a particular privilege (write lock)
-*/
-static void privilege_unlock_right(const char *right)
-{
- tdb_unlock_bystring(tdb, right);
-}
-
-
-/*
- return a list of SIDs that have a particular right
-*/
-NTSTATUS privilege_enum_account_with_right(const char *right,
- uint32 *count,
- DOM_SID **sids)
-{
- TDB_DATA data;
- char *p;
- int i;
-
- if (!tdb) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- data = tdb_fetch_bystring(tdb, right);
- if (!data.dptr) {
- *count = 0;
- *sids = NULL;
- return NT_STATUS_OK;
- }
-
- /* count them */
- for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) {
- p += strlen(p) + 1;
- }
- *count = i;
-
- /* allocate and parse */
- *sids = SMB_MALLOC_ARRAY(DOM_SID, *count);
- if (! *sids) {
- return NT_STATUS_NO_MEMORY;
- }
- for (i=0, p=data.dptr; p<data.dptr+data.dsize; i++) {
- if (!string_to_sid(&(*sids)[i], p)) {
- free(data.dptr);
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
- p += strlen(p) + 1;
- }
-
- free(data.dptr);
-
- return NT_STATUS_OK;
-}
-
-/*
- set what accounts have a given right - this is an internal interface
-*/
-static NTSTATUS privilege_set_accounts_with_right(const char *right,
- uint32 count,
- DOM_SID *sids)
-{
- TDB_DATA data;
- char *p;
- int i;
-
- if (!tdb) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- /* allocate the maximum size that we might use */
- data.dptr = SMB_MALLOC(count * ((MAXSUBAUTHS*11) + 30));
- if (!data.dptr) {
- return NT_STATUS_NO_MEMORY;
- }
-
- p = data.dptr;
-
- for (i=0;i<count;i++) {
- sid_to_string(p, &sids[i]);
- p += strlen(p) + 1;
- }
-
- data.dsize = PTR_DIFF(p, data.dptr);
-
- if (tdb_store_bystring(tdb, right, data, TDB_REPLACE) != 0) {
- free(data.dptr);
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- free(data.dptr);
- return NT_STATUS_OK;
-}
-
-
-/*
- add a SID to the list of SIDs for a right
-*/
-NTSTATUS privilege_add_account_right(const char *right,
- DOM_SID *sid)
-{
- NTSTATUS status;
- DOM_SID *current_sids;
- uint32 current_count;
- int i;
-
- status = privilege_lock_right(right);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = privilege_enum_account_with_right(right, &current_count, &current_sids);
- if (!NT_STATUS_IS_OK(status)) {
- privilege_unlock_right(right);
- return status;
- }
-
- /* maybe that SID is already listed? this is not an error */
- for (i=0;i<current_count;i++) {
- if (sid_equal(&current_sids[i], sid)) {
- privilege_unlock_right(right);
- free(current_sids);
- return NT_STATUS_OK;
- }
- }
-
- /* add it in */
- current_sids = SMB_REALLOC_ARRAY(current_sids, DOM_SID, current_count+1);
- if (!current_sids) {
- privilege_unlock_right(right);
- return NT_STATUS_NO_MEMORY;
- }
-
- sid_copy(&current_sids[current_count], sid);
- current_count++;
-
- status = privilege_set_accounts_with_right(right, current_count, current_sids);
-
- free(current_sids);
- privilege_unlock_right(right);
-
- return status;
-}
-
-
-/*
- remove a SID from the list of SIDs for a right
-*/
-NTSTATUS privilege_remove_account_right(const char *right,
- DOM_SID *sid)
-{
- NTSTATUS status;
- DOM_SID *current_sids;
- uint32 current_count;
- int i;
-
- status = privilege_lock_right(right);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = privilege_enum_account_with_right(right, &current_count, &current_sids);
- if (!NT_STATUS_IS_OK(status)) {
- privilege_unlock_right(right);
- return status;
- }
-
- for (i=0;i<current_count;i++) {
- if (sid_equal(&current_sids[i], sid)) {
- /* found it - so remove it */
- if (current_count-i > 1) {
- memmove(&current_sids[i], &current_sids[i+1],
- sizeof(current_sids[0]) * ((current_count-i)-1));
- }
- current_count--;
- status = privilege_set_accounts_with_right(right,
- current_count,
- current_sids);
- free(current_sids);
- privilege_unlock_right(right);
- return status;
- }
- }
-
- /* removing a right that you don't have is not an error */
-
- safe_free(current_sids);
- privilege_unlock_right(right);
- return NT_STATUS_OK;
-}
-
-
-/*
- an internal function for checking if a SID has a right
-*/
-static BOOL privilege_sid_has_right(DOM_SID *sid, const char *right)
-{
- NTSTATUS status;
- uint32 count;
- DOM_SID *sids;
- int i;
-
- status = privilege_enum_account_with_right(right, &count, &sids);
- if (!NT_STATUS_IS_OK(status)) {
- return False;
- }
- for (i=0;i<count;i++) {
- if (sid_equal(sid, &sids[i])) {
- free(sids);
- return True;
- }
- }
-
- safe_free(sids);
- return False;
-}
-
-/*
- list the rights for an account. This involves traversing the database
-*/
-NTSTATUS privilege_enum_account_rights(DOM_SID *sid,
- uint32 *count,
- char ***rights)
-{
- TDB_DATA key, nextkey;
- char *right;
-
- if (!tdb) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- *rights = NULL;
- *count = 0;
-
- for (key = tdb_firstkey(tdb); key.dptr; key = nextkey) {
- nextkey = tdb_nextkey(tdb, key);
-
- right = key.dptr;
-
- if (privilege_sid_has_right(sid, right)) {
- (*rights) = SMB_REALLOC_ARRAY(*rights,char *, (*count)+1);
- if (! *rights) {
- safe_free(nextkey.dptr);
- free(key.dptr);
- return NT_STATUS_NO_MEMORY;
- }
-
- (*rights)[*count] = SMB_STRDUP(right);
- (*count)++;
- }
-
- free(key.dptr);
- }
-
- return NT_STATUS_OK;
-}
diff --git a/source/passdb/util_sam_sid.c b/source/passdb/util_sam_sid.c
index c93c3400bd0..1fddfc79255 100644
--- a/source/passdb/util_sam_sid.c
+++ b/source/passdb/util_sam_sid.c
@@ -315,28 +315,4 @@ BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char
return False;
}
-void add_sid_to_array(const DOM_SID *sid, DOM_SID **sids, int *num)
-{
- *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1);
-
- if (*sids == NULL)
- return;
-
- sid_copy(&((*sids)[*num]), sid);
- *num += 1;
-
- return;
-}
-
-void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids)
-{
- int i;
-
- for (i=0; i<(*num_sids); i++) {
- if (sid_compare(sid, &(*sids)[i]) == 0)
- return;
- }
-
- add_sid_to_array(sid, sids, num_sids);
-}
diff --git a/source/printing/load.c b/source/printing/load.c
index 59306aa1047..a925a63e17f 100644
--- a/source/printing/load.c
+++ b/source/printing/load.c
@@ -22,44 +22,29 @@
/***************************************************************************
-auto-load printer services
-***************************************************************************/
-void add_all_printers(void)
-{
- int printers = lp_servicenumber(PRINTERS_NAME);
-
- if (printers < 0) return;
-
- pcap_printer_fn(lp_add_one_printer);
-}
-
-/***************************************************************************
auto-load some homes and printer services
***************************************************************************/
static void add_auto_printers(void)
{
const char *p;
- int printers;
- char *str = SMB_STRDUP(lp_auto_services());
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ char *str;
- if (!str) return;
-
- printers = lp_servicenumber(PRINTERS_NAME);
+ if (pnum < 0)
+ return;
- if (printers < 0) {
- SAFE_FREE(str);
+ if ((str = SMB_STRDUP(lp_auto_services())) == NULL)
return;
- }
-
- for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
- if (lp_servicenumber(p) >= 0) continue;
+
+ for (p = strtok(str, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
+ if (lp_servicenumber(p) >= 0)
+ continue;
- if (pcap_printername_ok(p,NULL)) {
- lp_add_printer(p,printers);
- }
+ if (pcap_printername_ok(p))
+ lp_add_printer(p, pnum);
}
- SAFE_FREE(str);
+ SAFE_FREE(str);
}
/***************************************************************************
@@ -67,7 +52,12 @@ load automatic printer services
***************************************************************************/
void load_printers(void)
{
+ if (!pcap_cache_loaded())
+ pcap_cache_reload();
+
add_auto_printers();
- if (lp_load_printers())
- add_all_printers();
+
+ /* load all printcap printers */
+ if (lp_load_printers() && lp_servicenumber(PRINTERS_NAME) >= 0)
+ pcap_printer_fn(lp_add_one_printer);
}
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index 3ffedcf1858..d5cf58f54d8 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -2046,17 +2046,32 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
handles are not affected.
****************************************************************************/
-uint32 del_a_printer(char *sharename)
+uint32 del_a_printer(const char *sharename)
{
pstring key;
TDB_DATA kbuf;
+ pstring printdb_path;
slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
-
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
+ tdb_delete(tdb_printers, kbuf);
+ slprintf(key, sizeof(key)-1, "%s%s", SECDESC_PREFIX, sharename);
+ kbuf.dptr=key;
+ kbuf.dsize=strlen(key)+1;
tdb_delete(tdb_printers, kbuf);
+
+ close_all_print_db();
+
+ if (geteuid() == 0) {
+ pstrcpy(printdb_path, lock_path("printing/"));
+ pstrcat(printdb_path, sharename);
+ pstrcat(printdb_path, ".tdb");
+
+ unlink(printdb_path);
+ }
+
return 0;
}
@@ -2899,7 +2914,8 @@ BOOL is_printer_published(Printer_entry *print_hnd, int snum,
return False;
}
- if (regval_size(guid_val) == sizeof(struct uuid))
+ /* fetching printer guids really ought to be a separate function.. */
+ if (guid && regval_size(guid_val) == sizeof(struct uuid))
memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
free_a_printer(&printer, 2);
@@ -4790,7 +4806,8 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
{
- SEC_ACE ace[3];
+ SEC_ACE ace[5]; /* max number of ace entries */
+ int i = 0;
SEC_ACCESS sa;
SEC_ACL *psa = NULL;
SEC_DESC_BUF *sdb = NULL;
@@ -4801,7 +4818,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
/* Create an ACE where Everyone is allowed to print */
init_sec_access(&sa, PRINTER_ACE_PRINT);
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
/* Make the security descriptor owned by the Administrators group
@@ -4820,20 +4837,38 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
}
init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
- init_sec_ace(&ace[1], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ init_sec_ace(&ace[i++], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
sa, SEC_ACE_FLAG_OBJECT_INHERIT |
SEC_ACE_FLAG_INHERIT_ONLY);
init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
- init_sec_ace(&ace[2], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ init_sec_ace(&ace[i++], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+ /* Add the domain admins group if we are a DC */
+
+ if ( IS_DC ) {
+ DOM_SID domadmins_sid;
+
+ sid_copy(&domadmins_sid, get_global_sam_sid());
+ sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
+
+ init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
+ init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ sa, SEC_ACE_FLAG_OBJECT_INHERIT |
+ SEC_ACE_FLAG_INHERIT_ONLY);
+
+ init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
+ init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+ }
+
/* The ACL revision number in rpc_secdesc.h differs from the one
created by NT when setting ACE entries in printer
descriptors. NT4 complains about the property being edited by a
NT5 machine. */
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) != NULL) {
+ if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
&owner_sid, NULL,
NULL, psa, &sd_size);
@@ -5018,6 +5053,11 @@ void map_printer_permissions(SEC_DESC *sd)
print_job_delete, print_job_pause, print_job_resume,
print_queue_purge
+ Try access control in the following order (for performance reasons):
+ 1) root ans SE_PRINT_OPERATOR can do anything (easy check)
+ 2) check security descriptor (bit comparisons in memory)
+ 3) "printer admins" (may result in numerous calls to winbind)
+
****************************************************************************/
BOOL print_access_check(struct current_user *user, int snum, int access_type)
{
@@ -5028,16 +5068,16 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
const char *pname;
TALLOC_CTX *mem_ctx = NULL;
extern struct current_user current_user;
+ SE_PRIV se_printop = SE_PRINT_OPERATOR;
/* If user is NULL then use the current_user structure */
if (!user)
user = &current_user;
- /* Always allow root or printer admins to do anything */
+ /* Always allow root or SE_PRINT_OPERATROR to do anything */
- if (user->uid == 0 ||
- user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups)) {
+ if ( user->uid == 0 || user_has_privileges(user->nt_user_token, &se_printop ) ) {
return True;
}
@@ -5086,6 +5126,13 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
+ /* see if we need to try the printer admin list */
+
+ if ( access_granted == 0 ) {
+ if ( user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups) )
+ return True;
+ }
+
talloc_destroy(mem_ctx);
if (!result)
diff --git a/source/printing/pcap.c b/source/printing/pcap.c
index a5fb53a320d..0495b6fc1fc 100644
--- a/source/printing/pcap.c
+++ b/source/printing/pcap.c
@@ -27,10 +27,8 @@
*/
/*
- * Parse printcap file.
- *
- * This module does exactly one thing - it looks into the printcap file
- * and tells callers if a specified string appears as a printer name.
+ * This module contains code to parse and cache printcap data, possibly
+ * in concert with the CUPS/SYSV/AIX-specific code found elsewhere.
*
* The way this module looks at the printcap file is very simplistic.
* Only the local printcap file is inspected (no searching of NIS
@@ -62,352 +60,194 @@
#include "includes.h"
-#ifdef AIX
-/* ******************************************
- Extend for AIX system and qconfig file
- from 'boulard@univ-rennes1.fr
- ****************************************** */
-static int strlocate(char *xpLine,char *xpS)
+
+typedef struct pcap_cache {
+ char *name;
+ char *comment;
+ struct pcap_cache *next;
+} pcap_cache_t;
+
+static pcap_cache_t *pcap_cache = NULL;
+
+BOOL pcap_cache_add(const char *name, const char *comment)
{
- int iS,iL,iRet;
- char *p;
- iS = strlen(xpS);
- iL = strlen(xpLine);
-
- iRet = 0;
- p = xpLine;
- while (iL >= iS)
- {
- if (strncmp(p,xpS,iS) == 0) {iRet =1;break;};
- p++;
- iL--;
- }
- /*DEBUG(3,(" strlocate %s in line '%s',ret=%d\n",xpS,xpLine,iRet));*/
-
- return(iRet);
+ pcap_cache_t *p;
+
+ if (name == NULL || ((p = SMB_MALLOC_P(pcap_cache_t)) == NULL))
+ return False;
+
+ p->name = SMB_STRDUP(name);
+ p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL;
+
+ p->next = pcap_cache;
+ pcap_cache = p;
+
+ return True;
}
-
-
-/* ******************************************************************* */
-/* * Scan qconfig and search all virtual printer (device printer) * */
-/* ******************************************************************* */
-static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
+
+static void pcap_cache_destroy(pcap_cache_t *cache)
{
- int iEtat;
- XFILE *pfile;
- char *line,*p;
- pstring name,comment;
- line = NULL;
- *name = 0;
- *comment = 0;
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- return;
- }
+ pcap_cache_t *p, *next;
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* locate an entry */
- if (*line == '\t' || *line == ' ') continue;
- if ((p=strchr_m(line,':')))
- {
- *p = '\0';
- p = strtok(line,":");
- if (strcmp(p,"bsh")!=0)
- {
- pstrcpy(name,p);
- iEtat = 1;
- continue;
- }
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
- break;
- }
+ for (p = cache; p != NULL; p = next) {
+ next = p->next;
+
+ SAFE_FREE(p->name);
+ SAFE_FREE(p->comment);
+ SAFE_FREE(p);
}
- x_fclose(pfile);
}
-/* Scan qconfig file and locate de printername */
-
-static BOOL ScanQconfig(char *psz,char *pszPrintername)
+BOOL pcap_cache_loaded(void)
{
- int iLg,iEtat;
- XFILE *pfile;
- char *pName;
- char *line;
-
- pName = NULL;
- line = NULL;
- if ((pszPrintername!= NULL) && ((iLg = strlen(pszPrintername)) > 0))
- pName = malloc(iLg+10);
- if (pName == NULL)
- {
- DEBUG(0,(" Unable to allocate memory for printer %s\n",pszPrintername));
- return(False);
- }
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- SAFE_FREE(pName);
- return(False);
- }
- slprintf(pName, iLg + 9, "%s:",pszPrintername);
- iLg = strlen(pName);
- /*DEBUG(3,( " Looking for entry %s\n",pName));*/
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* scanning entry */
- if (strncmp(line,pName,iLg) == 0)
- {
- iEtat = 1;
- continue;
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- free (line);
- SAFE_FREE(pName);
- x_fclose(pfile);
- return(True);
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- free (line);
- SAFE_FREE(pName);
- x_fclose(pfile);
- return(True);
- }
- break;
- }
- }
- free (pName);
- x_fclose(pfile);
- return(False);
+ return (pcap_cache != NULL);
}
-#endif /* AIX */
-
-/***************************************************************************
-Scan printcap file pszPrintcapname for a printer called pszPrintername.
-Return True if found, else False. Returns False on error, too, after logging
-the error at level 0. For generality, the printcap name may be passed - if
-passed as NULL, the configuration will be queried for the name.
-***************************************************************************/
-BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname)
+void pcap_cache_reload(void)
{
- char *line=NULL;
- const char *psz;
- char *p,*q;
- XFILE *pfile;
-
- if (pszPrintername == NULL || pszPrintername[0] == '\0')
- {
- DEBUG(0,( "Attempt to locate null printername! Internal error?\n"));
- return(False);
- }
-
- /* only go looking if no printcap name supplied */
- if ((psz = pszPrintcapname) == NULL || psz[0] == '\0')
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return(False);
- }
+ const char *pcap_name = lp_printcapname();
+ BOOL pcap_reloaded = False;
+ pcap_cache_t *tmp_cache = NULL;
+ XFILE *pcap_file;
+ char *pcap_line;
+
+ DEBUG(3, ("reloading printcap cache\n"));
+
+ /* only go looking if no printcap name supplied */
+ if (pcap_name == NULL || *pcap_name == 0) {
+ DEBUG(0, ("No printcap file name configured!\n"));
+ return;
+ }
+
+ tmp_cache = pcap_cache;
+ pcap_cache = NULL;
#ifdef HAVE_CUPS
- if (strequal(psz, "cups"))
- return (cups_printername_ok(pszPrintername));
-#endif /* HAVE_CUPS */
+ if (strequal(pcap_name, "cups")) {
+ pcap_reloaded = cups_cache_reload();
+ goto done;
+ }
+#endif
#ifdef SYSV
- if (strequal(psz, "lpstat"))
- return (sysv_printername_ok(pszPrintername));
+ if (strequal(pcap_name, "lpstat")) {
+ pcap_reloaded = sysv_cache_reload();
+ goto done;
+ }
#endif
#ifdef AIX
- if (strlocate(psz,"/qconfig"))
- return(ScanQconfig(psz,pszPrintername));
+ if (strstr_m(pcap_name, "/qconfig") != NULL) {
+ pcap_reloaded = aix_cache_reload();
+ goto done;
+ }
#endif
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return(False);
- }
+ /* handle standard printcap - moved from pcap_printer_fn() */
+
+ if ((pcap_file = x_fopen(pcap_name, O_RDONLY, 0)) == NULL) {
+ DEBUG(0, ("Unable to open printcap file %s for read!\n", pcap_name));
+ goto done;
+ }
+
+ for (; (pcap_line = fgets_slash(NULL, sizeof(pstring), pcap_file)) != NULL; safe_free(pcap_line)) {
+ pstring name, comment;
+ char *p, *q;
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
+ if (*pcap_line == '#' || *pcap_line == 0)
+ continue;
- /* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
- if (p) *p = 0;
+ /* now we have a real printer line - cut at the first : */
+ if ((p = strchr_m(pcap_line, ':')) != NULL)
+ *p = 0;
- /* now just check if the name is in the list */
- /* NOTE: I avoid strtok as the fn calling this one may be using it */
- for (p=line; p; p=q)
- {
- if ((q = strchr_m(p,'|'))) *q++ = 0;
-
- if (strequal(p,pszPrintername))
- {
- SAFE_FREE(line);
- x_fclose(pfile);
- return(True);
- }
- p = q;
+ /*
+ * now find the most likely printer name and comment
+ * this is pure guesswork, but it's better than nothing
+ */
+ for (*name = *comment = 0, p = pcap_line; p != NULL; p = q) {
+ BOOL has_punctuation;
+
+ if ((q = strchr_m(p, '|')) != NULL)
+ *q++ = 0;
+
+ has_punctuation = (strchr_m(p, ' ') ||
+ strchr_m(p, '\t') ||
+ strchr_m(p, '(') ||
+ strchr_m(p, ')'));
+
+ if (strlen(p) > strlen(comment) && has_punctuation) {
+ pstrcpy(comment, p);
+ continue;
+ }
+
+ if (strlen(p) <= MAXPRINTERLEN &&
+ strlen(p) > strlen(name) && !has_punctuation) {
+ if (!*comment)
+ pstrcpy(comment, name);
+
+ pstrcpy(name, p);
+ continue;
+ }
+
+ if (!strchr_m(comment, ' ') &&
+ strlen(p) > strlen(comment)) {
+ pstrcpy(comment, p);
+ continue;
+ }
+ }
+
+ comment[60] = 0;
+ name[MAXPRINTERLEN] = 0;
+
+ if (*name && !pcap_cache_add(name, comment)) {
+ x_fclose(pcap_file);
+ goto done;
+ }
}
- }
- x_fclose(pfile);
- return(False);
+ x_fclose(pcap_file);
+ pcap_reloaded = True;
+
+done:
+ DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error"));
+
+ if (pcap_reloaded)
+ pcap_cache_destroy(tmp_cache);
+ else {
+ pcap_cache_destroy(pcap_cache);
+ pcap_cache = tmp_cache;
+ }
+
+ return;
}
+BOOL pcap_printername_ok(const char *printername)
+{
+ pcap_cache_t *p;
+
+ for (p = pcap_cache; p != NULL; p = p->next)
+ if (strequal(p->name, printername))
+ return True;
+
+ return False;
+}
+
/***************************************************************************
run a function on each printer name in the printcap file. The function is
passed the primary name and the comment (if possible). Note the fn() takes
strings in DOS codepage. This means the xxx_printer_fn() calls must be fixed
to return DOS codepage. FIXME !! JRA.
+
+XXX: I'm not sure if this comment still applies.. Anyone? -Rob
***************************************************************************/
void pcap_printer_fn(void (*fn)(char *, char *))
{
- pstring name,comment;
- char *line;
- char *psz;
- char *p,*q;
- XFILE *pfile;
-
- /* only go looking if no printcap name supplied */
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return;
- }
-
-#ifdef HAVE_CUPS
- if (strequal(psz, "cups")) {
- cups_printer_fn(fn);
- return;
- }
-#endif /* HAVE_CUPS */
-
-#ifdef SYSV
- if (strequal(psz, "lpstat")) {
- sysv_printer_fn(fn);
- return;
- }
-#endif
-
-#ifdef AIX
- if (strlocate(psz,"/qconfig"))
- {
- ScanQconfig_fn(psz,fn);
- return;
- }
-#endif
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return;
- }
-
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
-
- /* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
- if (p) *p = 0;
-
- /* now find the most likely printer name and comment
- this is pure guesswork, but it's better than nothing */
- *name = 0;
- *comment = 0;
- for (p=line; p; p=q)
- {
- BOOL has_punctuation;
- if ((q = strchr_m(p,'|'))) *q++ = 0;
-
- has_punctuation = (strchr_m(p,' ') || strchr_m(p,'\t') || strchr_m(p,'(') || strchr_m(p,')'));
-
- if (strlen(p)>strlen(comment) && has_punctuation)
- {
- pstrcpy(comment,p);
- continue;
- }
-
- if (strlen(p) <= MAXPRINTERLEN && strlen(p)>strlen(name) && !has_punctuation)
- {
- if (!*comment) pstrcpy(comment,name);
- pstrcpy(name,p);
- continue;
- }
-
- if (!strchr_m(comment,' ') &&
- strlen(p) > strlen(comment))
- {
- pstrcpy(comment,p);
- continue;
- }
- }
+ pcap_cache_t *p;
- comment[60] = 0;
- name[MAXPRINTERLEN] = 0;
+ for (p = pcap_cache; p != NULL; p = p->next)
+ fn(p->name, p->comment);
- if (*name)
- fn(name,comment);
- }
- x_fclose(pfile);
+ return;
}
diff --git a/source/printing/print_aix.c b/source/printing/print_aix.c
new file mode 100644
index 00000000000..6ed3510ee41
--- /dev/null
+++ b/source/printing/print_aix.c
@@ -0,0 +1,111 @@
+/*
+ AIX-specific printcap loading
+ Copyright (C) Jean-Pierre.Boulard@univ-rennes1.fr 1996
+
+ 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 module implements AIX-specific printcap loading. Most of the code
+ * here was originally provided by Jean-Pierre.Boulard@univ-rennes1.fr in
+ * the Samba 1.9.14 release, and was formerly contained in pcap.c. It has
+ * been moved here and condensed as part of a larger effort to clean up and
+ * simplify the printcap code. -- Rob Foehl, 2004/12/06
+ */
+
+#include "includes.h"
+
+#ifdef AIX
+BOOL aix_cache_reload(void)
+{
+ int iEtat;
+ XFILE *pfile;
+ char *line = NULL, *p;
+ pstring name, comment;
+
+ *name = 0;
+ *comment = 0;
+
+ DEBUG(5, ("reloading aix printcap cache\n"));
+
+ if ((pfile = x_fopen(lp_printcapname(), O_RDONLY, 0)) == NULL) {
+ DEBUG(0,( "Unable to open qconfig file %s for read!\n", lp_printcapname()));
+ return False;
+ }
+
+ iEtat = 0;
+ /* scan qconfig file for searching <printername>: */
+ for (;(line = fgets_slash(NULL, sizeof(pstring), pfile)); safe_free(line)) {
+ if (*line == '*' || *line == 0)
+ continue;
+
+ switch (iEtat) {
+ case 0: /* locate an entry */
+ if (*line == '\t' || *line == ' ')
+ continue;
+
+ if ((p = strchr_m(line, ':'))) {
+ *p = '\0';
+ p = strtok(line, ":");
+ if (strcmp(p, "bsh") != 0) {
+ pstrcpy(name, p);
+ iEtat = 1;
+ continue;
+ }
+ }
+ break;
+
+ case 1: /* scanning device stanza */
+ if (*line == '*' || *line == 0)
+ continue;
+
+ if (*line != '\t' && *line != ' ') {
+ /* name is found without stanza device */
+ /* probably a good printer ??? */
+ iEtat = 0;
+ if (!pcap_cache_add(name, NULL)) {
+ safe_free(line);
+ x_fclose(pfile);
+ return False;
+ }
+ continue;
+ }
+
+ if (strstr_m(line, "backend")) {
+ /* it's a device, not a virtual printer */
+ iEtat = 0;
+ } else if (strstr_m(line, "device")) {
+ /* it's a good virtual printer */
+ iEtat = 0;
+ if (!pcap_cache_add(name, NULL)) {
+ safe_free(line);
+ x_fclose(pfile);
+ return False;
+ }
+ continue;
+ }
+ break;
+ }
+ }
+
+ x_fclose(pfile);
+ return True;
+}
+
+#else
+/* this keeps fussy compilers happy */
+ void print_aix_dummy(void);
+ void print_aix_dummy(void) {}
+#endif /* AIX */
diff --git a/source/printing/print_cups.c b/source/printing/print_cups.c
index 5cc36d6e170..90af10c3736 100644
--- a/source/printing/print_cups.c
+++ b/source/printing/print_cups.c
@@ -33,11 +33,11 @@
static const char * /* O - Password or NULL */
cups_passwd_cb(const char *prompt) /* I - Prompt */
{
- /*
- * Always return NULL to indicate that no password is available...
- */
+ /*
+ * Always return NULL to indicate that no password is available...
+ */
- return (NULL);
+ return (NULL);
}
static const char *cups_server(void)
@@ -52,19 +52,13 @@ static const char *cups_server(void)
return cupsServer();
}
-/*
- * 'cups_printer_fn()' - Call a function for every printer known to the
- * system.
- */
-
-void cups_printer_fn(void (*fn)(char *, char *))
+BOOL cups_cache_reload(void)
{
- /* I - Function to call */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
+ http_t *http = NULL; /* HTTP connection to server */
+ ipp_t *request = NULL, /* IPP Request */
+ *response = NULL; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
+ cups_lang_t *language = NULL; /* Default language */
char *name, /* printer-name attribute */
*info; /* printer-info attribute */
static const char *requested[] =/* Requested attributes */
@@ -72,9 +66,9 @@ void cups_printer_fn(void (*fn)(char *, char *))
"printer-name",
"printer-info"
};
+ BOOL ret = False;
-
- DEBUG(5,("cups_printer_fn(%p)\n", fn));
+ DEBUG(5, ("reloading cups printcap cache\n"));
/*
* Make sure we don't ask for passwords...
@@ -86,11 +80,10 @@ void cups_printer_fn(void (*fn)(char *, char *))
* Try to connect to the server...
*/
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
+ if ((http = httpConnect(cups_server(), ippPort())) == NULL) {
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cups_server(), strerror(errno)));
- return;
+ goto out;
}
/*
@@ -124,16 +117,13 @@ void cups_printer_fn(void (*fn)(char *, char *))
* Do the request and get back a response...
*/
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
+ if ((response = cupsDoRequest(http, request, "/")) == NULL) {
DEBUG(0,("Unable to get printer list - %s\n",
ippErrorString(cupsLastError())));
- httpClose(http);
- return;
+ goto out;
}
- for (attr = response->attrs; attr != NULL;)
- {
+ for (attr = response->attrs; attr != NULL;) {
/*
* Skip leading attributes until we hit a printer...
*/
@@ -151,8 +141,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
name = NULL;
info = NULL;
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
- {
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
if (strcmp(attr->name, "printer-name") == 0 &&
attr->value_tag == IPP_TAG_NAME)
name = attr->values[0].string.text;
@@ -171,11 +160,13 @@ void cups_printer_fn(void (*fn)(char *, char *))
if (name == NULL)
break;
- (*fn)(name, info);
+ if (!pcap_cache_add(name, info)) {
+ goto out;
+ }
}
ippDelete(response);
-
+ response = NULL;
/*
* Build a CUPS_GET_CLASSES request, which requires the following
@@ -191,8 +182,6 @@ void cups_printer_fn(void (*fn)(char *, char *))
request->request.op.operation_id = CUPS_GET_CLASSES;
request->request.op.request_id = 1;
- language = cupsLangDefault();
-
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
@@ -208,16 +197,13 @@ void cups_printer_fn(void (*fn)(char *, char *))
* Do the request and get back a response...
*/
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
+ if ((response = cupsDoRequest(http, request, "/")) == NULL) {
DEBUG(0,("Unable to get printer list - %s\n",
ippErrorString(cupsLastError())));
- httpClose(http);
- return;
+ goto out;
}
- for (attr = response->attrs; attr != NULL;)
- {
+ for (attr = response->attrs; attr != NULL;) {
/*
* Skip leading attributes until we hit a printer...
*/
@@ -235,8 +221,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
name = NULL;
info = NULL;
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
- {
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
if (strcmp(attr->name, "printer-name") == 0 &&
attr->value_tag == IPP_TAG_NAME)
name = attr->values[0].string.text;
@@ -255,110 +240,24 @@ void cups_printer_fn(void (*fn)(char *, char *))
if (name == NULL)
break;
- (*fn)(name, info);
+ if (!pcap_cache_add(name, info)) {
+ goto out;
+ }
}
- ippDelete(response);
-
- /*
- * Close the connection to the server...
- */
-
- httpClose(http);
-}
-
-
-/*
- * 'cups_printername_ok()' - Provide the equivalent of pcap_printername_ok()
- * for CUPS.
- * O - 1 if printer name OK
- * I - Name of printer
- */
-int cups_printername_ok(const char *name)
-{
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_printername_ok(\"%s\")\n", name));
+ ret = True;
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
- DEBUG(3,("Unable to connect to CUPS server %s - %s\n",
- cups_server(), strerror(errno)));
- return (0);
- }
-
- /*
- * Build an IPP_GET_PRINTER_ATTRS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes", NULL, "printer-uri");
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", name);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
+ out:
+ if (response)
+ ippDelete(response);
- /*
- * Do the request and get back a response...
- */
+ if (language)
+ cupsLangFree(language);
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
- ippErrorString(cupsLastError())));
+ if (http)
httpClose(http);
- return (0);
- }
- httpClose(http);
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
- ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- return (0);
- }
- else
- {
- ippDelete(response);
- return (1);
- }
+ return ret;
}
@@ -366,14 +265,13 @@ int cups_printername_ok(const char *name)
* 'cups_job_delete()' - Delete a job.
*/
-static int
-cups_job_delete(int snum, struct printjob *pjob)
+static int cups_job_delete(int snum, struct printjob *pjob)
{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
+ int ret = 1; /* Return value */
+ http_t *http = NULL; /* HTTP connection to server */
+ ipp_t *request = NULL, /* IPP Request */
+ *response = NULL; /* IPP Response */
+ cups_lang_t *language = NULL; /* Default language */
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
@@ -389,11 +287,10 @@ cups_job_delete(int snum, struct printjob *pjob)
* Try to connect to the server...
*/
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
+ if ((http = httpConnect(cups_server(), ippPort())) == NULL) {
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cups_server(), strerror(errno)));
- return (1);
+ goto out;
}
/*
@@ -430,25 +327,29 @@ cups_job_delete(int snum, struct printjob *pjob)
* Do the request and get back a response...
*/
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
+ if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) {
+ if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+ DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
+ ippErrorString(cupsLastError())));
+ } else {
+ ret = 0;
+ }
+ } else {
DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
+ ippErrorString(cupsLastError())));
}
- else
- DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- httpClose(http);
+ out:
+ if (response)
+ ippDelete(response);
- return (ret);
+ if (language)
+ cupsLangFree(language);
+
+ if (http)
+ httpClose(http);
+
+ return ret;
}
@@ -456,14 +357,13 @@ cups_job_delete(int snum, struct printjob *pjob)
* 'cups_job_pause()' - Pause a job.
*/
-static int
-cups_job_pause(int snum, struct printjob *pjob)
+static int cups_job_pause(int snum, struct printjob *pjob)
{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
+ int ret = 1; /* Return value */
+ http_t *http = NULL; /* HTTP connection to server */
+ ipp_t *request = NULL, /* IPP Request */
+ *response = NULL; /* IPP Response */
+ cups_lang_t *language = NULL; /* Default language */
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
@@ -479,11 +379,10 @@ cups_job_pause(int snum, struct printjob *pjob)
* Try to connect to the server...
*/
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
+ if ((http = httpConnect(cups_server(), ippPort())) == NULL) {
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cups_server(), strerror(errno)));
- return (1);
+ goto out;
}
/*
@@ -520,25 +419,29 @@ cups_job_pause(int snum, struct printjob *pjob)
* Do the request and get back a response...
*/
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
+ if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) {
+ if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+ DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
+ ippErrorString(cupsLastError())));
+ } else {
+ ret = 0;
+ }
+ } else {
DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
+ ippErrorString(cupsLastError())));
}
- else
- DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- httpClose(http);
+ out:
+ if (response)
+ ippDelete(response);
- return (ret);
+ if (language)
+ cupsLangFree(language);
+
+ if (http)
+ httpClose(http);
+
+ return ret;
}
@@ -546,14 +449,13 @@ cups_job_pause(int snum, struct printjob *pjob)
* 'cups_job_resume()' - Resume a paused job.
*/
-static int
-cups_job_resume(int snum, struct printjob *pjob)
+static int cups_job_resume(int snum, struct printjob *pjob)
{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
+ int ret = 1; /* Return value */
+ http_t *http = NULL; /* HTTP connection to server */
+ ipp_t *request = NULL, /* IPP Request */
+ *response = NULL; /* IPP Response */
+ cups_lang_t *language = NULL; /* Default language */
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
@@ -569,11 +471,10 @@ cups_job_resume(int snum, struct printjob *pjob)
* Try to connect to the server...
*/
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
+ if ((http = httpConnect(cups_server(), ippPort())) == NULL) {
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cups_server(), strerror(errno)));
- return (1);
+ goto out;
}
/*
@@ -610,25 +511,29 @@ cups_job_resume(int snum, struct printjob *pjob)
* Do the request and get back a response...
*/
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
+ if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) {
+ if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+ DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
+ ippErrorString(cupsLastError())));
+ } else {
+ ret = 0;
+ }
+ } else {
DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
+ ippErrorString(cupsLastError())));
}
- else
- DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- httpClose(http);
+ out:
+ if (response)
+ ippDelete(response);
- return (ret);
+ if (language)
+ cupsLangFree(language);
+
+ if (http)
+ httpClose(http);
+
+ return ret;
}
@@ -636,19 +541,18 @@ cups_job_resume(int snum, struct printjob *pjob)
* 'cups_job_submit()' - Submit a job for printing.
*/
-static int
-cups_job_submit(int snum, struct printjob *pjob)
+static int cups_job_submit(int snum, struct printjob *pjob)
{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
+ int ret = 1; /* Return value */
+ http_t *http = NULL; /* HTTP connection to server */
+ ipp_t *request = NULL, /* IPP Request */
+ *response = NULL; /* IPP Response */
+ cups_lang_t *language = NULL; /* Default language */
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- char *clientname; /* hostname of client for job-originating-host attribute */
+ char *clientname = NULL; /* hostname of client for job-originating-host attribute */
pstring new_jobname;
int num_options = 0;
- cups_option_t *options;
+ cups_option_t *options = NULL;
DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
@@ -662,11 +566,10 @@ cups_job_submit(int snum, struct printjob *pjob)
* Try to connect to the server...
*/
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
+ if ((http = httpConnect(cups_server(), ippPort())) == NULL) {
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cups_server(), strerror(errno)));
- return (1);
+ goto out;
}
/*
@@ -734,28 +637,33 @@ cups_job_submit(int snum, struct printjob *pjob)
slprintf(uri, sizeof(uri) - 1, "/printers/%s", PRINTERNAME(snum));
- ret = 1;
- if ((response = cupsDoFileRequest(http, request, uri,
- pjob->filename)) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
+ if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
+ if (response->request.status.status_code >= IPP_OK_CONFLICT) {
DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
ippErrorString(cupsLastError())));
- else
+ } else {
ret = 0;
-
- ippDelete(response);
- }
- else
+ }
+ } else {
DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
ippErrorString(cupsLastError())));
-
- httpClose(http);
+ }
if ( ret == 0 )
unlink(pjob->filename);
/* else print_job_end will do it for us */
+ out:
+ if (response)
+ ippDelete(response);
+
+ if (language)
+ cupsLangFree(language);
+
+ if (http)
+ httpClose(http);
+
+ return ret;
return (ret);
}
@@ -763,22 +671,21 @@ cups_job_submit(int snum, struct printjob *pjob)
* 'cups_queue_get()' - Get all the jobs in the print queue.
*/
-static int
-cups_queue_get(const char *printer_name,
+static int cups_queue_get(const char *printer_name,
enum printing_types printing_type,
char *lpq_command,
print_queue_struct **q,
print_status_struct *status)
{
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
+ http_t *http = NULL; /* HTTP connection to server */
+ ipp_t *request = NULL, /* IPP Request */
+ *response = NULL; /* IPP Response */
+ ipp_attribute_t *attr = NULL; /* Current attribute */
+ cups_lang_t *language = NULL; /* Default language */
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- int qcount, /* Number of active queue entries */
- qalloc; /* Number of queue entries allocated */
- print_queue_struct *queue, /* Queue entries */
+ int qcount = 0, /* Number of active queue entries */
+ qalloc = 0; /* Number of queue entries allocated */
+ print_queue_struct *queue = NULL, /* Queue entries */
*temp; /* Temporary pointer for queue */
const char *user_name, /* job-originating-user-name attribute */
*job_name; /* job-name attribute */
@@ -803,6 +710,7 @@ cups_queue_get(const char *printer_name,
"printer-state-message"
};
+ *q = NULL;
DEBUG(5,("cups_queue_get(%s, %p, %p)\n", printer_name, q, status));
@@ -816,11 +724,10 @@ cups_queue_get(const char *printer_name,
* Try to connect to the server...
*/
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
+ if ((http = httpConnect(cups_server(), ippPort())) == NULL) {
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cups_server(), strerror(errno)));
- return (0);
+ goto out;
}
/*
@@ -864,22 +771,16 @@ cups_queue_get(const char *printer_name,
* Do the request and get back a response...
*/
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
+ if ((response = cupsDoRequest(http, request, "/")) == NULL) {
DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
ippErrorString(cupsLastError())));
- httpClose(http);
- return (0);
+ goto out;
}
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
+ if (response->request.status.status_code >= IPP_OK_CONFLICT) {
DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- httpClose(http);
-
- return (0);
+ goto out;
}
/*
@@ -890,8 +791,7 @@ cups_queue_get(const char *printer_name,
qalloc = 0;
queue = NULL;
- for (attr = response->attrs; attr != NULL; attr = attr->next)
- {
+ for (attr = response->attrs; attr != NULL; attr = attr->next) {
/*
* Skip leading attributes until we hit a job...
*/
@@ -905,20 +805,16 @@ cups_queue_get(const char *printer_name,
/*
* Allocate memory as needed...
*/
- if (qcount >= qalloc)
- {
+ if (qcount >= qalloc) {
qalloc += 16;
temp = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc);
- if (temp == NULL)
- {
+ if (temp == NULL) {
DEBUG(0,("cups_queue_get: Not enough memory!"));
- ippDelete(response);
- httpClose(http);
-
+ qcount = 0;
SAFE_FREE(queue);
- return (0);
+ goto out;
}
queue = temp;
@@ -939,10 +835,8 @@ cups_queue_get(const char *printer_name,
user_name = NULL;
job_name = NULL;
- while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
- {
- if (attr->name == NULL)
- {
+ while (attr != NULL && attr->group_tag == IPP_TAG_JOB) {
+ if (attr->name == NULL) {
attr = attr->next;
break;
}
@@ -982,12 +876,11 @@ cups_queue_get(const char *printer_name,
* See if we have everything needed...
*/
- if (user_name == NULL || job_name == NULL || job_id == 0)
- {
- if (attr == NULL)
- break;
- else
- continue;
+ if (user_name == NULL || job_name == NULL || job_id == 0) {
+ if (attr == NULL)
+ break;
+ else
+ continue;
}
temp->job = job_id;
@@ -1004,10 +897,11 @@ cups_queue_get(const char *printer_name,
qcount ++;
if (attr == NULL)
- break;
+ break;
}
ippDelete(response);
+ response = NULL;
/*
* Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
@@ -1019,13 +913,9 @@ cups_queue_get(const char *printer_name,
* printer-uri
*/
- request = ippNew();
-
request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
request->request.op.request_id = 1;
- language = cupsLangDefault();
-
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
@@ -1044,31 +934,25 @@ cups_queue_get(const char *printer_name,
* Do the request and get back a response...
*/
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
+ if ((response = cupsDoRequest(http, request, "/")) == NULL) {
DEBUG(0,("Unable to get printer status for %s - %s\n", printer_name,
ippErrorString(cupsLastError())));
- httpClose(http);
*q = queue;
- return (qcount);
+ goto out;
}
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
+ if (response->request.status.status_code >= IPP_OK_CONFLICT) {
DEBUG(0,("Unable to get printer status for %s - %s\n", printer_name,
ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- httpClose(http);
*q = queue;
- return (qcount);
+ goto out;
}
/*
* Get the current printer status and convert it to the SAMBA values.
*/
- if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
- {
+ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) {
if (attr->values[0].integer == IPP_PRINTER_STOPPED)
status->status = LPSTAT_STOPPED;
else
@@ -1079,16 +963,23 @@ cups_queue_get(const char *printer_name,
IPP_TAG_TEXT)) != NULL)
fstrcpy(status->message, attr->values[0].string.text);
- ippDelete(response);
-
/*
* Return the job queue...
*/
- httpClose(http);
-
*q = queue;
- return (qcount);
+
+ out:
+ if (response)
+ ippDelete(response);
+
+ if (language)
+ cupsLangFree(language);
+
+ if (http)
+ httpClose(http);
+
+ return qcount;
}
@@ -1096,15 +987,14 @@ cups_queue_get(const char *printer_name,
* 'cups_queue_pause()' - Pause a print queue.
*/
-static int
-cups_queue_pause(int snum)
+static int cups_queue_pause(int snum)
{
extern userdom_struct current_user_info;
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
+ int ret = 1; /* Return value */
+ http_t *http = NULL; /* HTTP connection to server */
+ ipp_t *request = NULL, /* IPP Request */
+ *response = NULL; /* IPP Response */
+ cups_lang_t *language = NULL; /* Default language */
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
@@ -1120,11 +1010,10 @@ cups_queue_pause(int snum)
* Try to connect to the server...
*/
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
+ if ((http = httpConnect(cups_server(), ippPort())) == NULL) {
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cups_server(), strerror(errno)));
- return (1);
+ goto out;
}
/*
@@ -1162,25 +1051,29 @@ cups_queue_pause(int snum)
* Do the request and get back a response...
*/
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) {
+ if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+ DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
+ ippErrorString(cupsLastError())));
+ } else {
+ ret = 0;
+ }
+ } else {
DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
+ ippErrorString(cupsLastError())));
}
- else
- DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- httpClose(http);
+ out:
+ if (response)
+ ippDelete(response);
- return (ret);
+ if (language)
+ cupsLangFree(language);
+
+ if (http)
+ httpClose(http);
+
+ return ret;
}
@@ -1188,15 +1081,14 @@ cups_queue_pause(int snum)
* 'cups_queue_resume()' - Restart a print queue.
*/
-static int
-cups_queue_resume(int snum)
+static int cups_queue_resume(int snum)
{
extern userdom_struct current_user_info;
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
+ int ret = 1; /* Return value */
+ http_t *http = NULL; /* HTTP connection to server */
+ ipp_t *request = NULL, /* IPP Request */
+ *response = NULL; /* IPP Response */
+ cups_lang_t *language = NULL; /* Default language */
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
@@ -1212,11 +1104,10 @@ cups_queue_resume(int snum)
* Try to connect to the server...
*/
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
+ if ((http = httpConnect(cups_server(), ippPort())) == NULL) {
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cups_server(), strerror(errno)));
- return (1);
+ goto out;
}
/*
@@ -1254,25 +1145,29 @@ cups_queue_resume(int snum)
* Do the request and get back a response...
*/
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
+ if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) {
+ if (response->request.status.status_code >= IPP_OK_CONFLICT) {
+ DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
+ ippErrorString(cupsLastError())));
+ } else {
+ ret = 0;
+ }
+ } else {
DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
+ ippErrorString(cupsLastError())));
}
- else
- DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- httpClose(http);
+ out:
+ if (response)
+ ippDelete(response);
- return (ret);
+ if (language)
+ cupsLangFree(language);
+
+ if (http)
+ httpClose(http);
+
+ return ret;
}
/*******************************************************************
diff --git a/source/printing/print_svid.c b/source/printing/print_svid.c
index d9db500425e..3a7c9356344 100644
--- a/source/printing/print_svid.c
+++ b/source/printing/print_svid.c
@@ -35,23 +35,17 @@
#include "includes.h"
#ifdef SYSV
-
-typedef struct printer {
- char *name;
- struct printer *next;
-} printer_t;
-static printer_t *printers = NULL;
-
-static void populate_printers(void)
+BOOL sysv_cache_reload(void)
{
char **lines;
int i;
- lines = file_lines_pload("/usr/bin/lpstat -v", NULL);
- if (!lines) return;
+ DEBUG(5, ("reloading sysv printcap cache\n"));
- for (i=0;lines[i];i++) {
- printer_t *ptmp;
+ if ((lines = file_lines_pload("/usr/bin/lpstat -v", NULL)) == NULL)
+ return False;
+
+ for (i = 0; lines[i]; i++) {
char *name, *tmp;
char *buf = lines[i];
@@ -64,7 +58,7 @@ static void populate_printers(void)
* In case we're only at the "for ".
*/
- if(!strncmp("for ",++tmp,4)) {
+ if(!strncmp("for ", ++tmp, 4)) {
tmp=strchr_m(tmp, ' ');
tmp++;
}
@@ -78,7 +72,7 @@ static void populate_printers(void)
* On HPUX there is an extra line that can be ignored.
* d.thibadeau 2001/08/09
*/
- if(!strncmp("remote to",tmp,9))
+ if(!strncmp("remote to", tmp, 9))
continue;
name = tmp;
@@ -88,53 +82,14 @@ static void populate_printers(void)
*tmp = '\0';
/* add it to the cache */
- if ((ptmp = SMB_MALLOC_P(printer_t)) != NULL) {
- ZERO_STRUCTP(ptmp);
- if((ptmp->name = SMB_STRDUP(name)) == NULL)
- DEBUG(0,("populate_printers: malloc fail in strdup !\n"));
- ptmp->next = printers;
- printers = ptmp;
- } else {
- DEBUG(0,("populate_printers: malloc fail for ptmp\n"));
+ if (!pcap_cache_add(name, NULL)) {
+ file_lines_free(lines);
+ return False;
}
}
file_lines_free(lines);
-}
-
-
-/*
- * provide the equivalent of pcap_printer_fn() for SVID/XPG4 conforming
- * systems. It was unclear why pcap_printer_fn() was tossing names longer
- * than 8 characters. I suspect that its a protocol limit, but amazingly
- * names longer than 8 characters appear to work with my test
- * clients (Win95/NT).
- */
-void sysv_printer_fn(void (*fn)(char *, char *))
-{
- printer_t *tmp;
-
- if (printers == NULL)
- populate_printers();
- for (tmp = printers; tmp != NULL; tmp = tmp->next)
- (fn)(tmp->name, "");
-}
-
-
-/*
- * provide the equivalent of pcap_printername_ok() for SVID/XPG4 conforming
- * systems.
- */
-int sysv_printername_ok(const char *name)
-{
- printer_t *tmp;
-
- if (printers == NULL)
- populate_printers();
- for (tmp = printers; tmp != NULL; tmp = tmp->next)
- if (strcmp(tmp->name, name) == 0)
- return (True);
- return (False);
+ return True;
}
#else
diff --git a/source/printing/printing.c b/source/printing/printing.c
index b5785440aeb..b4d0f3a44b3 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -1077,6 +1077,7 @@ static void print_queue_update_internal( const char *sharename,
if ( !print_cache_expired(sharename, False) ) {
DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename));
+ release_print_db(pdb);
return;
}
@@ -2247,7 +2248,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
}
/* for autoloaded printers, check that the printcap entry still exists */
- if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
+ if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
release_print_db(pdb);
errno = ENOENT;
diff --git a/source/rpc_client/cli_dfs.c b/source/rpc_client/cli_dfs.c
index 2136b69df07..0975242b7d6 100644
--- a/source/rpc_client/cli_dfs.c
+++ b/source/rpc_client/cli_dfs.c
@@ -43,7 +43,7 @@ NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_dfs_q_dfs_exist(&q);
if (!dfs_io_q_dfs_exist("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, DFS_EXIST, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, DFS_EXIST, &qbuf, &rbuf)) {
goto done;
}
@@ -89,7 +89,7 @@ NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
flags);
if (!dfs_io_q_dfs_add("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, DFS_ADD, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, DFS_ADD, &qbuf, &rbuf)) {
goto done;
}
@@ -132,7 +132,7 @@ NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_dfs_q_dfs_remove(&q, entrypath, servername, sharename);
if (!dfs_io_q_dfs_remove("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, DFS_REMOVE, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, DFS_REMOVE, &qbuf, &rbuf)) {
goto done;
}
@@ -178,7 +178,7 @@ NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
info_level);
if (!dfs_io_q_dfs_get_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, DFS_GET_INFO, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, DFS_GET_INFO, &qbuf, &rbuf)) {
goto done;
}
@@ -223,7 +223,7 @@ NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_dfs_q_dfs_enum(&q, info_level, ctr);
if (!dfs_io_q_dfs_enum("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, DFS_ENUM, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, DFS_ENUM, &qbuf, &rbuf)) {
goto done;
}
diff --git a/source/rpc_client/cli_ds.c b/source/rpc_client/cli_ds.c
index 1a2174d58c6..7719f97034e 100644
--- a/source/rpc_client/cli_ds.c
+++ b/source/rpc_client/cli_ds.c
@@ -50,7 +50,7 @@ NTSTATUS cli_ds_getprimarydominfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
q.level = level;
if (!ds_io_q_getprimdominfo("", &qbuf, 0, &q)
- || !rpc_api_pipe_req(cli, DS_GETPRIMDOMINFO, &qbuf, &rbuf)) {
+ || !rpc_api_pipe_req(cli, PI_LSARPC_DS, DS_GETPRIMDOMINFO, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -110,7 +110,7 @@ NTSTATUS cli_ds_enum_domain_trusts(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_ds_enum_domain_trusts( &q, server, flags );
if (!ds_io_q_enum_domain_trusts("", &qbuf, 0, &q)
- || !rpc_api_pipe_req(cli, DS_ENUM_DOM_TRUSTS, &qbuf, &rbuf)) {
+ || !rpc_api_pipe_req(cli, PI_LSARPC_DS, DS_ENUM_DOM_TRUSTS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
diff --git a/source/rpc_client/cli_echo.c b/source/rpc_client/cli_echo.c
index 1ae7aaa8e70..cd7e21f918f 100644
--- a/source/rpc_client/cli_echo.c
+++ b/source/rpc_client/cli_echo.c
@@ -48,7 +48,7 @@ NTSTATUS cli_echo_add_one(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_echo_q_add_one(&q, request);
if (!echo_io_q_add_one("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, ECHO_ADD_ONE, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_ECHO, ECHO_ADD_ONE, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -94,7 +94,7 @@ NTSTATUS cli_echo_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_echo_q_echo_data(&q, size, in_data);
if (!echo_io_q_echo_data("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, ECHO_DATA, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_ECHO, ECHO_DATA, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -142,7 +142,7 @@ NTSTATUS cli_echo_sink_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_echo_q_sink_data(&q, size, in_data);
if (!echo_io_q_sink_data("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, ECHO_SINK_DATA, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_ECHO, ECHO_SINK_DATA, &qbuf, &rbuf)) {
goto done;
}
@@ -187,7 +187,7 @@ NTSTATUS cli_echo_source_data(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_echo_q_source_data(&q, size);
if (!echo_io_q_source_data("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, ECHO_SOURCE_DATA, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_ECHO, ECHO_SOURCE_DATA, &qbuf, &rbuf)) {
goto done;
}
diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c
index a8dfa93bd88..98c2475a658 100644
--- a/source/rpc_client/cli_lsarpc.c
+++ b/source/rpc_client/cli_lsarpc.c
@@ -71,7 +71,7 @@ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!lsa_io_q_open_pol("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_OPENPOLICY, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -135,7 +135,7 @@ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!lsa_io_q_open_pol2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_OPENPOLICY2, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_OPENPOLICY2, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -186,7 +186,7 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_lsa_q_close(&q, pol);
if (!lsa_io_q_close("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_CLOSE, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_CLOSE, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -241,7 +241,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1);
if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_LOOKUPSIDS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -358,7 +358,7 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_lookup_names(mem_ctx, &q, pol, num_names, names);
if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_LOOKUPNAMES, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -458,7 +458,7 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_query(&q, pol, info_class);
if (!lsa_io_q_query("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYINFOPOLICY, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -557,7 +557,7 @@ NTSTATUS cli_lsa_query_info_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_query2(&q, pol, info_class);
if (!lsa_io_q_query_info2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_QUERYINFO2, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYINFO2, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -655,7 +655,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_enum_trust_dom(&q, pol, *enum_ctx, 0x10000);
if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -747,7 +747,7 @@ NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_enum_privs(&q, pol, *enum_context, pref_max_length);
if (!lsa_io_q_enum_privs("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_ENUM_PRIVS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUM_PRIVS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -829,7 +829,7 @@ NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys);
if (!lsa_io_q_priv_get_dispname("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_PRIV_GET_DISPNAME, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_PRIV_GET_DISPNAME, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -882,7 +882,7 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length);
if (!lsa_io_q_enum_accounts("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_ENUM_ACCOUNTS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUM_ACCOUNTS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -928,6 +928,64 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
return result;
}
+/** Create a LSA user handle
+ *
+ * @param cli Handle on an initialised SMB connection
+ *
+ * FIXME: The code is actually identical to open account
+ * TODO: Check and code what the function should exactly do
+ *
+ * */
+
+NTSTATUS cli_lsa_create_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ POLICY_HND *dom_pol, DOM_SID *sid, uint32 desired_access,
+ POLICY_HND *user_pol)
+{
+ prs_struct qbuf, rbuf;
+ LSA_Q_CREATEACCOUNT q;
+ LSA_R_CREATEACCOUNT r;
+ NTSTATUS result;
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Initialise parse structures */
+
+ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* Initialise input parameters */
+
+ init_lsa_q_create_account(&q, dom_pol, sid, desired_access);
+
+ /* Marshall data and send request */
+
+ if (!lsa_io_q_create_account("", &q, &qbuf, 0) ||
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_CREATEACCOUNT, &qbuf, &rbuf)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Unmarshall response */
+
+ if (!lsa_io_r_create_account("", &r, &rbuf, 0)) {
+ result = NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ /* Return output parameters */
+
+ if (NT_STATUS_IS_OK(result = r.status)) {
+ *user_pol = r.pol;
+ }
+
+ done:
+ prs_mem_free(&qbuf);
+ prs_mem_free(&rbuf);
+
+ return result;
+}
+
/** Open a LSA user handle
*
* @param cli Handle on an initialised SMB connection */
@@ -956,7 +1014,7 @@ NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!lsa_io_q_open_account("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_OPENACCOUNT, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_OPENACCOUNT, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1009,7 +1067,7 @@ NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!lsa_io_q_enum_privsaccount("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_ENUMPRIVSACCOUNT, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUMPRIVSACCOUNT, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1037,9 +1095,9 @@ NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
for (i=0; i<r.count; i++) {
- (*set)[i].luid.low = r.set->set[i].luid.low;
- (*set)[i].luid.high = r.set->set[i].luid.high;
- (*set)[i].attr = r.set->set[i].attr;
+ (*set)[i].luid.low = r.set.set[i].luid.low;
+ (*set)[i].luid.high = r.set.set[i].luid.high;
+ (*set)[i].attr = r.set.set[i].attr;
}
*count=r.count;
@@ -1073,7 +1131,7 @@ NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_lsa_q_lookupprivvalue(&q, pol, name);
if (!lsa_io_q_lookupprivvalue("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_LOOKUPPRIVVALUE, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_LOOKUPPRIVVALUE, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1125,7 +1183,7 @@ NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_query_sec_obj(&q, pol, sec_info);
if (!lsa_io_q_query_sec_obj("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_QUERYSECOBJ, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_QUERYSECOBJ, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1159,14 +1217,16 @@ NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*/
NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *pol, DOM_SID sid,
- uint32 *count, char ***privs_name)
+ POLICY_HND *pol, DOM_SID *sid,
+ uint32 *count, char ***priv_names)
{
prs_struct qbuf, rbuf;
LSA_Q_ENUM_ACCT_RIGHTS q;
LSA_R_ENUM_ACCT_RIGHTS r;
NTSTATUS result;
int i;
+ fstring *privileges;
+ char **names;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
@@ -1177,10 +1237,10 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
/* Marshall data and send request */
- init_q_enum_acct_rights(&q, pol, 2, &sid);
+ init_q_enum_acct_rights(&q, pol, 2, sid);
if (!lsa_io_q_enum_acct_rights("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_ENUMACCTRIGHTS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ENUMACCTRIGHTS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1199,10 +1259,19 @@ NTSTATUS cli_lsa_enum_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
goto done;
}
- *privs_name = TALLOC_ARRAY(mem_ctx, char *, *count);
- for (i=0;i<*count;i++) {
- pull_ucs2_talloc(mem_ctx, &(*privs_name)[i], r.rights.strings[i].string.buffer);
+
+ privileges = TALLOC_ARRAY(mem_ctx, fstring, *count);
+ names = TALLOC_ARRAY(mem_ctx, char *, *count);
+ for ( i=0; i<*count; i++ ) {
+ /* ensure NULL termination ... what a hack */
+ pull_ucs2(NULL, privileges[i], r.rights.strings[i].string.buffer,
+ sizeof(fstring), r.rights.strings[i].string.uni_str_len*2 , 0);
+
+ /* now copy to the return array */
+ names[i] = talloc_strdup( mem_ctx, privileges[i] );
}
+
+ *priv_names = names;
done:
@@ -1232,7 +1301,7 @@ NTSTATUS cli_lsa_add_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_q_add_acct_rights(&q, pol, &sid, count, privs_name);
if (!lsa_io_q_add_acct_rights("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_ADDACCTRIGHTS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_ADDACCTRIGHTS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1274,7 +1343,7 @@ NTSTATUS cli_lsa_remove_account_rights(struct cli_state *cli, TALLOC_CTX *mem_ct
init_q_remove_acct_rights(&q, pol, &sid, removeall?1:0, count, privs_name);
if (!lsa_io_q_remove_acct_rights("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, LSA_REMOVEACCTRIGHTS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_LSARPC, LSA_REMOVEACCTRIGHTS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index b88753a7ed0..08b52fa7182 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -50,7 +50,7 @@ NTSTATUS cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal,
/* Marshall data and send request */
if (!net_io_q_req_chal("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_REQCHAL, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, NET_REQCHAL, &qbuf, &rbuf)) {
goto done;
}
@@ -116,7 +116,7 @@ NTSTATUS cli_net_auth2(struct cli_state *cli,
/* turn parameters into data stream */
if (!net_io_q_auth_2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_AUTH2, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, NET_AUTH2, &qbuf, &rbuf)) {
goto done;
}
@@ -192,7 +192,7 @@ NTSTATUS cli_net_auth3(struct cli_state *cli,
/* turn parameters into data stream */
if (!net_io_q_auth_3("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_AUTH3, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, NET_AUTH3, &qbuf, &rbuf)) {
goto done;
}
@@ -317,7 +317,7 @@ NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!net_io_q_logon_ctrl2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, NET_LOGON_CTRL2, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -363,7 +363,7 @@ NTSTATUS cli_netlogon_getdcname(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!net_io_q_getdcname("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_GETDCNAME, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, NET_GETDCNAME, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -437,7 +437,7 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_C
/* Marshall data and send request */
if (!net_io_q_sam_sync("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, NET_SAM_SYNC, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -498,7 +498,7 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!net_io_q_sam_deltas("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_SAM_DELTAS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, NET_SAM_DELTAS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -605,7 +605,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, NET_SAMLOGON, &qbuf, &rbuf)) {
goto done;
}
@@ -696,7 +696,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c
/* Marshall data and send request */
if (!net_io_q_sam_logon("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_NETLOGON, NET_SAMLOGON, &qbuf, &rbuf)) {
goto done;
}
@@ -776,7 +776,7 @@ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
/* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, NET_SRVPWSET, &qbuf, &rbuf))
+ if (rpc_api_pipe_req(cli, PI_NETLOGON, NET_SRVPWSET, &qbuf, &rbuf))
{
NET_R_SRV_PWSET r_s;
diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c
index 0720f872419..52cbae6326c 100644
--- a/source/rpc_client/cli_pipe.c
+++ b/source/rpc_client/cli_pipe.c
@@ -62,7 +62,7 @@ static uint32 get_rpc_call_id(void)
Use SMBreadX to get rest of one fragment's worth of rpc data.
********************************************************************/
-static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 *rdata_offset)
+static BOOL rpc_read(struct cli_state *cli, int pipe_idx, prs_struct *rdata, uint32 data_to_read, uint32 *rdata_offset)
{
size_t size = (size_t)cli->max_recv_frag;
int stream_offset = 0;
@@ -95,7 +95,7 @@ static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_re
if (size > (size_t)data_to_read)
size = (size_t)data_to_read;
- num_read = (int)cli_read(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size);
+ num_read = (int)cli_read(cli, cli->nt_pipe_fnum[pipe_idx], pdata, (off_t)stream_offset, size);
DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n",
num_read, stream_offset, data_to_read));
@@ -394,7 +394,7 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
****************************************************************************/
-static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rdata,
+static BOOL rpc_api_pipe(struct cli_state *cli, int pipe_idx, prs_struct *data, prs_struct *rdata,
uint8 expected_pkt_type)
{
uint32 len;
@@ -416,9 +416,9 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
/* Create setup parameters - must be in native byte order. */
setup[0] = TRANSACT_DCERPCCMD;
- setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */
+ setup[1] = cli->nt_pipe_fnum[pipe_idx]; /* Pipe file handle. */
- DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum));
+ DEBUG(5,("rpc_api_pipe: fnum:%x\n", (int)cli->nt_pipe_fnum[pipe_idx]));
/* Send the RPC request and receive a response. For short RPC
calls (about 1024 bytes or so) the RPC request and response
@@ -442,7 +442,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
if (prdata == NULL) {
DEBUG(0,("rpc_api_pipe: pipe %x failed to return data.\n",
- (int)cli->nt_pipe_fnum));
+ (int)cli->nt_pipe_fnum[pipe_idx]));
return False;
}
@@ -470,7 +470,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
}
if (rhdr.pkt_type == RPC_BINDNACK) {
- DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum));
+ DEBUG(3, ("Bind NACK received on pipe %x!\n", (int)cli->nt_pipe_fnum[pipe_idx]));
prs_mem_free(rdata);
return False;
}
@@ -485,7 +485,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
}
if (rhdr.pkt_type != expected_pkt_type) {
- DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum, rhdr.pkt_type, expected_pkt_type));
+ DEBUG(3, ("Connection to pipe %x got an unexpected RPC packet type - %d, not %d\n", (int)cli->nt_pipe_fnum[pipe_idx], rhdr.pkt_type, expected_pkt_type));
prs_mem_free(rdata);
return False;
}
@@ -502,7 +502,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
/* Read the remaining part of the first response fragment */
- if (!rpc_read(cli, rdata, len, &current_offset)) {
+ if (!rpc_read(cli, pipe_idx, rdata, len, &current_offset)) {
prs_mem_free(rdata);
return False;
}
@@ -557,7 +557,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
prs_init(&hps, 0, cli->mem_ctx, UNMARSHALL);
prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False);
- num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
+ num_read = cli_read(cli, cli->nt_pipe_fnum[pipe_idx], hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
if (cli_is_dos_error(cli)) {
cli_dos_error(cli, &eclass, &ecode);
if (eclass != ERRDOS && ecode != ERRmoredata) {
@@ -602,7 +602,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, prs_struct *data, prs_struct *rd
* Now read the rest of the PDU.
*/
- if (!rpc_read(cli, rdata, len, &current_offset)) {
+ if (!rpc_read(cli, pipe_idx, rdata, len, &current_offset)) {
prs_mem_free(rdata);
return False;
}
@@ -911,7 +911,7 @@ static BOOL create_auth_hdr(prs_struct *outgoing_packet,
* @param rdata Unparsed NDR response data.
**/
-BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
+BOOL rpc_api_pipe_req(struct cli_state *cli, int pipe_idx, uint8 op_num,
prs_struct *data, prs_struct *rdata)
{
uint32 auth_len, real_auth_len, auth_hdr_len, max_data, data_left, data_sent;
@@ -1090,10 +1090,10 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
prs_offset(&outgoing_packet)));
if (flags & RPC_FLG_LAST)
- ret = rpc_api_pipe(cli, &outgoing_packet,
+ ret = rpc_api_pipe(cli, pipe_idx, &outgoing_packet,
rdata, RPC_RESPONSE);
else {
- cli_write(cli, cli->nt_pipe_fnum, 0x0008,
+ cli_write(cli, cli->nt_pipe_fnum[pipe_idx], 0x0008,
prs_data_p(&outgoing_packet),
data_sent, data_len);
}
@@ -1113,7 +1113,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
Set the handle state.
****************************************************************************/
-static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, const char *pipe_name, uint16 device_state)
+static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, int pipe_idx, const char *pipe_name, uint16 device_state)
{
BOOL state_set = False;
char param[2];
@@ -1126,14 +1126,14 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, const char *pipe_name,
return False;
DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
- cli->nt_pipe_fnum, pipe_name, device_state));
+ cli->nt_pipe_fnum[pipe_idx], pipe_name, device_state));
/* create parameters: device state */
SSVAL(param, 0, device_state);
/* create setup parameters. */
setup[0] = 0x0001;
- setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */
+ setup[1] = cli->nt_pipe_fnum[pipe_idx]; /* pipe file handle. got this from an SMBOpenX. */
/* send the data on \PIPE\ */
if (cli_api_pipe(cli, "\\PIPE\\",
@@ -1276,7 +1276,7 @@ static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, const int pipe_idx, RPC_IFAC
Create and send the third packet in an RPC auth.
****************************************************************************/
-static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 rpc_call_id)
+static BOOL rpc_send_auth_reply(struct cli_state *cli, int pipe_idx, prs_struct *rdata, uint32 rpc_call_id)
{
prs_struct rpc_out;
ssize_t ret;
@@ -1289,7 +1289,7 @@ static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32
return False;
}
- if ((ret = cli_write(cli, cli->nt_pipe_fnum, 0x8, prs_data_p(&rpc_out),
+ if ((ret = cli_write(cli, cli->nt_pipe_fnum[pipe_idx], 0x8, prs_data_p(&rpc_out),
0, (size_t)prs_offset(&rpc_out))) != (ssize_t)prs_offset(&rpc_out)) {
DEBUG(0,("rpc_send_auth_reply: cli_write failed. Return was %d\n", (int)ret));
prs_mem_free(&rpc_out);
@@ -1316,7 +1316,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na
if ( (pipe_idx < 0) || (pipe_idx >= PI_MAX_PIPES) )
return False;
- DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_names[pipe_idx].client_pipe));
+ DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum[pipe_idx], pipe_names[pipe_idx].client_pipe));
if (!valid_pipe_name(pipe_idx, &abstract, &transfer))
return False;
@@ -1389,7 +1389,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na
prs_init(&rdata, 0, cli->mem_ctx, UNMARSHALL);
/* send data on \PIPE\. receive a response */
- if (rpc_api_pipe(cli, &rpc_out, &rdata, RPC_BINDACK)) {
+ if (rpc_api_pipe(cli, pipe_idx, &rpc_out, &rdata, RPC_BINDACK)) {
RPC_HDR_BA hdr_ba;
DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n"));
@@ -1416,7 +1416,7 @@ static BOOL rpc_pipe_bind(struct cli_state *cli, int pipe_idx, const char *my_na
*/
if ((cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP)
- && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) {
+ && !rpc_send_auth_reply(cli, pipe_idx, &rdata, rpc_call_id)) {
DEBUG(0,("rpc_pipe_bind: rpc_send_auth_reply failed.\n"));
prs_mem_free(&rdata);
return False;
@@ -1439,7 +1439,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
/* At the moment we can't have more than one pipe open over
a cli connection. )-: */
- SMB_ASSERT(cli->nt_pipe_fnum == 0);
+ SMB_ASSERT(cli->nt_pipe_fnum[pipe_idx] == 0);
/* The pipe index must fall within our array */
@@ -1452,7 +1452,7 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
return False;
}
- cli->nt_pipe_fnum = (uint16)fnum;
+ cli->nt_pipe_fnum[pipe_idx] = (uint16)fnum;
} else {
if ((fnum = cli_open(cli, pipe_names[pipe_idx].client_pipe, O_CREAT|O_RDWR, DENY_NONE)) == -1) {
DEBUG(1,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n",
@@ -1460,14 +1460,14 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
return False;
}
- cli->nt_pipe_fnum = (uint16)fnum;
+ cli->nt_pipe_fnum[pipe_idx] = (uint16)fnum;
/**************** Set Named Pipe State ***************/
- if (!rpc_pipe_set_hnd_state(cli, pipe_names[pipe_idx].client_pipe, 0x4300)) {
+ if (!rpc_pipe_set_hnd_state(cli, pipe_idx, pipe_names[pipe_idx].client_pipe, 0x4300)) {
DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n",
cli_errstr(cli)));
- cli_close(cli, cli->nt_pipe_fnum);
- cli->nt_pipe_fnum = 0;
+ cli_close(cli, cli->nt_pipe_fnum[pipe_idx]);
+ cli->nt_pipe_fnum[pipe_idx] = 0;
return False;
}
}
@@ -1477,8 +1477,8 @@ BOOL cli_nt_session_open(struct cli_state *cli, const int pipe_idx)
if (!rpc_pipe_bind(cli, pipe_idx, global_myname())) {
DEBUG(2,("cli_nt_session_open: rpc bind to %s failed\n",
get_pipe_name_from_index(pipe_idx)));
- cli_close(cli, cli->nt_pipe_fnum);
- cli->nt_pipe_fnum = 0;
+ cli_close(cli, cli->nt_pipe_fnum[pipe_idx]);
+ cli->nt_pipe_fnum[pipe_idx] = 0;
return False;
}
@@ -1554,7 +1554,7 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
memcpy(cli->auth_info.sess_key, cli->sess_key,
sizeof(cli->auth_info.sess_key));
- cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
+ cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum[PI_NETLOGON];
cli->pipe_auth_flags = AUTH_PIPE_NETSEC;
cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
@@ -1574,7 +1574,7 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
return NT_STATUS_UNSUCCESSFUL;
}
- cli->nt_pipe_fnum = (uint16)fnum;
+ cli->nt_pipe_fnum[PI_NETLOGON] = (uint16)fnum;
} else {
if ((fnum = cli_open(cli, PIPE_NETLOGON,
O_CREAT|O_RDWR, DENY_NONE)) == -1) {
@@ -1585,20 +1585,20 @@ NTSTATUS cli_nt_establish_netlogon(struct cli_state *cli, int sec_chan,
return NT_STATUS_UNSUCCESSFUL;
}
- cli->nt_pipe_fnum = (uint16)fnum;
+ cli->nt_pipe_fnum[PI_NETLOGON] = (uint16)fnum;
/**************** Set Named Pipe State ***************/
- if (!rpc_pipe_set_hnd_state(cli, PIPE_NETLOGON, 0x4300)) {
+ if (!rpc_pipe_set_hnd_state(cli, PI_NETLOGON, PIPE_NETLOGON, 0x4300)) {
DEBUG(0,("Pipe hnd state failed. Error was %s\n",
cli_errstr(cli)));
- cli_close(cli, cli->nt_pipe_fnum);
+ cli_close(cli, cli->nt_pipe_fnum[PI_NETLOGON]);
return NT_STATUS_UNSUCCESSFUL;
}
}
if (!rpc_pipe_bind(cli, PI_NETLOGON, global_myname())) {
DEBUG(2,("rpc bind to %s failed\n", PIPE_NETLOGON));
- cli_close(cli, cli->nt_pipe_fnum);
+ cli_close(cli, cli->nt_pipe_fnum[PI_NETLOGON]);
return NT_STATUS_UNSUCCESSFUL;
}
@@ -1645,8 +1645,8 @@ NTSTATUS cli_nt_setup_netsec(struct cli_state *cli, int sec_chan, int auth_flags
memcpy(cli->auth_info.sess_key, cli->sess_key,
sizeof(cli->auth_info.sess_key));
- cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum;
- cli->nt_pipe_fnum = 0;
+ cli->saved_netlogon_pipe_fnum = cli->nt_pipe_fnum[PI_NETLOGON];
+ cli->nt_pipe_fnum[PI_NETLOGON] = 0;
/* doing schannel, not per-user auth */
cli->pipe_auth_flags = auth_flags;
diff --git a/source/rpc_client/cli_reg.c b/source/rpc_client/cli_reg.c
index 5cfbf68fb34..25f56085bac 100644
--- a/source/rpc_client/cli_reg.c
+++ b/source/rpc_client/cli_reg.c
@@ -27,7 +27,7 @@
/* Shutdown a server */
-NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
+WERROR cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
const char *msg, uint32 timeout, BOOL do_reboot,
BOOL force)
{
@@ -35,9 +35,9 @@ NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
prs_struct rbuf;
REG_Q_SHUTDOWN q_s;
REG_R_SHUTDOWN r_s;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ WERROR result = WERR_GENERAL_FAILURE;
- if (msg == NULL) return NT_STATUS_INVALID_PARAMETER;
+ if (msg == NULL) return WERR_INVALID_PARAM;
ZERO_STRUCT (q_s);
ZERO_STRUCT (r_s);
@@ -50,7 +50,7 @@ NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx,
init_reg_q_shutdown(&q_s, msg, timeout, do_reboot, force);
if (!reg_io_q_shutdown("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, REG_SHUTDOWN, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_SHUTDOWN, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -68,13 +68,13 @@ done:
/* Abort a server shutdown */
-NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
+WERROR cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
{
prs_struct rbuf;
prs_struct qbuf;
REG_Q_ABORT_SHUTDOWN q_s;
REG_R_ABORT_SHUTDOWN r_s;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ WERROR result = WERR_GENERAL_FAILURE;
ZERO_STRUCT (q_s);
ZERO_STRUCT (r_s);
@@ -87,7 +87,7 @@ NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx)
init_reg_q_abort_shutdown(&q_s);
if (!reg_io_q_abort_shutdown("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, REG_ABORT_SHUTDOWN, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_WINREG, REG_ABORT_SHUTDOWN, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
diff --git a/source/rpc_client/cli_samr.c b/source/rpc_client/cli_samr.c
index 26c29474ead..03b3c2134b9 100644
--- a/source/rpc_client/cli_samr.c
+++ b/source/rpc_client/cli_samr.c
@@ -50,7 +50,7 @@ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_connect(&q, cli->desthost, access_mask);
if (!samr_io_q_connect("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CONNECT, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -99,7 +99,7 @@ NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_connect4(&q, cli->desthost, access_mask);
if (!samr_io_q_connect4("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CONNECT4, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CONNECT4, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -148,7 +148,7 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_close_hnd(&q, connect_pol);
if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CLOSE_HND, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -198,7 +198,7 @@ NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -248,7 +248,7 @@ NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_USER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -298,7 +298,7 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_GROUP, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -349,7 +349,7 @@ NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_create_dom_group(&q, domain_pol, group_name, access_mask);
if (!samr_io_q_create_dom_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -396,7 +396,7 @@ NTSTATUS cli_samr_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_add_groupmem(&q, group_pol, rid);
if (!samr_io_q_add_groupmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ADD_GROUPMEM, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_GROUPMEM, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -440,7 +440,7 @@ NTSTATUS cli_samr_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_del_groupmem(&q, group_pol, rid);
if (!samr_io_q_del_groupmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DEL_GROUPMEM, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_GROUPMEM, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -485,7 +485,7 @@ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_userinfo(&q, user_pol, switch_value);
if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -530,7 +530,7 @@ NTSTATUS cli_samr_set_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_set_groupinfo(&q, group_pol, ctr);
if (!samr_io_q_set_groupinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_SET_GROUPINFO, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_GROUPINFO, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -575,7 +575,7 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_groupinfo(&q, group_pol, info_level);
if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -622,7 +622,7 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_usergroups(&q, user_pol);
if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -669,7 +669,7 @@ NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_set_aliasinfo(&q, alias_pol, ctr);
if (!samr_io_q_set_aliasinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_SET_ALIASINFO, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_ALIASINFO, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -691,14 +691,15 @@ NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Query user aliases */
NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
- POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid,
+ POLICY_HND *dom_pol, uint32 num_sids, DOM_SID2 *sid,
uint32 *num_aliases, uint32 **als_rids)
{
prs_struct qbuf, rbuf;
SAMR_Q_QUERY_USERALIASES q;
SAMR_R_QUERY_USERALIASES r;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- unsigned int ptr=1;
+ int i;
+ uint32 *sid_ptrs;
DEBUG(10,("cli_samr_query_useraliases\n"));
@@ -710,12 +711,19 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx,
prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+ sid_ptrs = TALLOC_ARRAY(mem_ctx, uint32, num_sids);
+ if (sid_ptrs == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ for (i=0; i<num_sids; i++)
+ sid_ptrs[i] = 1;
+
/* Marshall data and send request */
- init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid);
+ init_samr_q_query_useraliases(&q, dom_pol, num_sids, sid_ptrs, sid);
if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -763,7 +771,7 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_groupmem(&q, group_pol);
if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -833,7 +841,7 @@ NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
goto done;
}
@@ -910,7 +918,7 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -989,7 +997,7 @@ NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
goto done;
}
@@ -1070,7 +1078,7 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_aliasmem(&q, alias_pol);
if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
goto done;
}
@@ -1136,7 +1144,7 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1190,7 +1198,7 @@ NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_create_dom_alias(&q, domain_pol, name);
if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1240,7 +1248,7 @@ NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_add_aliasmem(&q, alias_pol, member);
if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1286,7 +1294,7 @@ NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_del_aliasmem(&q, alias_pol, member);
if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
@@ -1333,7 +1341,7 @@ NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
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)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
goto done;
}
@@ -1384,7 +1392,7 @@ NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_dom_info(&q, domain_pol, switch_value);
if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
goto done;
}
@@ -1476,7 +1484,7 @@ NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
old_lanman_hash_enc);
if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
goto done;
}
@@ -1562,7 +1570,7 @@ NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
*start_idx, max_entries, max_size);
if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
goto done;
}
@@ -1629,7 +1637,7 @@ NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx,
num_rids, rids);
if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
goto done;
}
@@ -1700,7 +1708,7 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx,
num_names, names);
if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
goto done;
}
@@ -1764,7 +1772,7 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_USER, &qbuf, &rbuf)) {
goto done;
}
@@ -1827,7 +1835,7 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
ctr->info.id);
if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
goto done;
}
@@ -1881,7 +1889,7 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
goto done;
}
@@ -1929,7 +1937,7 @@ NTSTATUS cli_samr_delete_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_delete_dom_group(&q, group_pol);
if (!samr_io_q_delete_dom_group("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_GROUP, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_GROUP, &qbuf, &rbuf)) {
goto done;
}
@@ -1975,7 +1983,7 @@ NTSTATUS cli_samr_delete_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_delete_dom_alias(&q, alias_pol);
if (!samr_io_q_delete_dom_alias("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_ALIAS, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_ALIAS, &qbuf, &rbuf)) {
goto done;
}
@@ -2021,7 +2029,7 @@ NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_delete_dom_user(&q, user_pol);
if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
goto done;
}
@@ -2068,7 +2076,7 @@ NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_query_sec_obj(&q, user_pol, switch_value);
if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
goto done;
}
@@ -2115,7 +2123,7 @@ NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_get_dom_pwinfo(&q, cli->desthost);
if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2167,7 +2175,7 @@ NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_samr_q_lookup_domain(&q, user_pol, domain_name);
if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
diff --git a/source/rpc_client/cli_shutdown.c b/source/rpc_client/cli_shutdown.c
index 0bf6e90ad27..9ad0510d1db 100644
--- a/source/rpc_client/cli_shutdown.c
+++ b/source/rpc_client/cli_shutdown.c
@@ -51,7 +51,7 @@ NTSTATUS cli_shutdown_init(struct cli_state * cli, TALLOC_CTX *mem_ctx,
init_shutdown_q_init(&q_s, msg, timeout, do_reboot, force);
if (!shutdown_io_q_init("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SHUTDOWN_INIT, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SHUTDOWN, SHUTDOWN_INIT, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -88,7 +88,7 @@ NTSTATUS cli_shutdown_abort(struct cli_state * cli, TALLOC_CTX *mem_ctx)
init_shutdown_q_abort(&q_s);
if (!shutdown_io_q_abort("", &q_s, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SHUTDOWN_ABORT, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SHUTDOWN, SHUTDOWN_ABORT, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
diff --git a/source/rpc_client/cli_spoolss.c b/source/rpc_client/cli_spoolss.c
index 5030a97c006..8094b2bf087 100644
--- a/source/rpc_client/cli_spoolss.c
+++ b/source/rpc_client/cli_spoolss.c
@@ -320,7 +320,7 @@ WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -378,7 +378,7 @@ WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -449,7 +449,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -547,7 +547,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_enumports("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ENUMPORTS, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -618,7 +618,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_GETPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -701,7 +701,7 @@ WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_SETPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -772,7 +772,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli,
/* Marshall data and send request */
if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -855,7 +855,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli,
/* Marshall data and send request */
if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -941,7 +941,7 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli,
/* Marshall data and send request */
if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
+ !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_GETPRINTERDRIVERDIRECTORY,
&qbuf, &rbuf))
goto done;
@@ -1006,7 +1006,7 @@ WERROR cli_spoolss_addprinterdriver (struct cli_state *cli,
/* Marshall data and send request */
if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1064,7 +1064,7 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1114,7 +1114,7 @@ WERROR cli_spoolss_deleteprinterdriverex(struct cli_state *cli,
/* Marshall data and send request */
if (!spoolss_io_q_deleteprinterdriverex ("", &q, &qbuf, 0)
- || !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVEREX , &qbuf, &rbuf))
+ || !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDRIVEREX , &qbuf, &rbuf))
{
goto done;
}
@@ -1170,7 +1170,7 @@ WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli,
/* Marshall data and send request */
if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1224,7 +1224,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli,
/* Marshall data and send request */
if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_GETPRINTPROCESSORDIRECTORY,
&qbuf, &rbuf))
goto done;
@@ -1286,7 +1286,7 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_addform("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ADDFORM, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1342,7 +1342,7 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_setform("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_SETFORM, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1407,7 +1407,7 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_getform("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETFORM, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_GETFORM, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1475,7 +1475,7 @@ WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_DELETEFORM, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1549,7 +1549,7 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ENUMFORMS, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1631,7 +1631,7 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_enumjobs("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMJOBS, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ENUMJOBS, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1698,7 +1698,7 @@ WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_setjob("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_SETJOB, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1747,7 +1747,7 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_getjob("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_GETJOB, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1810,7 +1810,7 @@ WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1855,7 +1855,7 @@ WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1904,7 +1904,7 @@ WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1952,7 +1952,7 @@ WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -1998,7 +1998,7 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2053,7 +2053,7 @@ WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_getprinterdataex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATAEX, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_GETPRINTERDATAEX, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2108,7 +2108,7 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2154,7 +2154,7 @@ WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_setprinterdataex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATAEX, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_SETPRINTERDATAEX, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2202,7 +2202,7 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2264,7 +2264,7 @@ WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_enumprinterdataex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATAEX, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ENUMPRINTERDATAEX, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2327,7 +2327,7 @@ WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2375,7 +2375,7 @@ WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2419,7 +2419,7 @@ WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ct
/* Marshall data and send request */
if (!spoolss_io_q_deleteprinterdataex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATAEX, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_DELETEPRINTERDATAEX, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2464,7 +2464,7 @@ WERROR cli_spoolss_enumprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_enumprinterkey("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERKEY, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_ENUMPRINTERKEY, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -2519,7 +2519,7 @@ WERROR cli_spoolss_deleteprinterkey(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!spoolss_io_q_deleteprinterkey("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERKEY, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_DELETEPRINTERKEY, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
diff --git a/source/rpc_client/cli_spoolss_notify.c b/source/rpc_client/cli_spoolss_notify.c
index f4eda332bb1..d6bcc8ba9c0 100644
--- a/source/rpc_client/cli_spoolss_notify.c
+++ b/source/rpc_client/cli_spoolss_notify.c
@@ -55,7 +55,7 @@ WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx
/* Marshall data and send request */
if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -95,7 +95,7 @@ WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ct
/* Marshall data and send request */
if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -139,7 +139,7 @@ WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx
/* Marshall data and send request */
if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
+ !rpc_api_pipe_req (cli, PI_SPOOLSS, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -202,7 +202,7 @@ WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_RRPCN, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -254,7 +254,7 @@ WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if(!spoolss_io_q_rffpcnex("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SPOOLSS_RFFPCNEX, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SPOOLSS, SPOOLSS_RFFPCNEX, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
diff --git a/source/rpc_client/cli_srvsvc.c b/source/rpc_client/cli_srvsvc.c
index 3385fbe463e..dd12367e032 100644
--- a/source/rpc_client/cli_srvsvc.c
+++ b/source/rpc_client/cli_srvsvc.c
@@ -47,7 +47,7 @@ WERROR cli_srvsvc_net_srv_get_info(struct cli_state *cli,
/* Marshall data and send request */
if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -92,7 +92,7 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -249,7 +249,7 @@ WERROR cli_srvsvc_net_share_get_info(struct cli_state *cli,
/* Marshall data and send request */
if (!srv_io_q_net_share_get_info("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_SHARE_GET_INFO, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SHARE_GET_INFO, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -333,7 +333,7 @@ WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!srv_io_q_net_share_del("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SHARE_DEL, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -377,7 +377,7 @@ WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!srv_io_q_net_share_add("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_SHARE_ADD, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -417,7 +417,7 @@ WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_REMOTE_TOD, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -466,7 +466,7 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_FILE_ENUM, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
@@ -548,7 +548,7 @@ WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Marshall data and send request */
if (!srv_io_q_net_file_close("", &q, &qbuf, 0) ||
- !rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf))
+ !rpc_api_pipe_req(cli, PI_SRVSVC, SRV_NET_FILE_CLOSE, &qbuf, &rbuf))
goto done;
/* Unmarshall response */
diff --git a/source/rpc_client/cli_wkssvc.c b/source/rpc_client/cli_wkssvc.c
index 97b948bf628..636e0fa0188 100644
--- a/source/rpc_client/cli_wkssvc.c
+++ b/source/rpc_client/cli_wkssvc.c
@@ -61,7 +61,7 @@ NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
/* actual rpc call over \PIPE\wkssvc */
- if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) {
+ if (!rpc_api_pipe_req(cli, PI_SRVSVC, WKS_QUERY_INFO, &buf, &rbuf)) {
prs_mem_free(&buf);
prs_mem_free(&rbuf);
return NT_STATUS_UNSUCCESSFUL;
diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c
index e2cb94c8fe9..c4ff240cef8 100644
--- a/source/rpc_parse/parse_lsa.c
+++ b/source/rpc_parse/parse_lsa.c
@@ -1650,6 +1650,61 @@ BOOL lsa_io_r_unk_get_connuser(const char *desc, LSA_R_UNK_GET_CONNUSER *r_c, pr
return True;
}
+void init_lsa_q_create_account(LSA_Q_CREATEACCOUNT *trn, POLICY_HND *hnd, DOM_SID *sid, uint32 desired_access)
+{
+ memcpy(&trn->pol, hnd, sizeof(trn->pol));
+
+ init_dom_sid2(&trn->sid, sid);
+ trn->access = desired_access;
+}
+
+
+/*******************************************************************
+ Reads or writes an LSA_Q_CREATEACCOUNT structure.
+********************************************************************/
+
+BOOL lsa_io_q_create_account(const char *desc, LSA_Q_CREATEACCOUNT *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_q_create_account");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth))
+ return False;
+
+ if(!smb_io_dom_sid2("sid", &r_c->sid, ps, depth)) /* domain SID */
+ return False;
+
+ if(!prs_uint32("access", ps, depth, &r_c->access))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
+ Reads or writes an LSA_R_CREATEACCOUNT structure.
+********************************************************************/
+
+BOOL lsa_io_r_create_account(const char *desc, LSA_R_CREATEACCOUNT *r_c, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "lsa_io_r_open_account");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_pol_hnd("pol", &r_c->pol, ps, depth))
+ return False;
+
+ if(!prs_ntstatus("status", ps, depth, &r_c->status))
+ return False;
+
+ return True;
+}
+
+
void init_lsa_q_open_account(LSA_Q_OPENACCOUNT *trn, POLICY_HND *hnd, DOM_SID *sid, uint32 desired_access)
{
memcpy(&trn->pol, hnd, sizeof(trn->pol));
@@ -1804,13 +1859,15 @@ NTSTATUS init_lsa_r_enum_privsaccount(TALLOC_CTX *mem_ctx, LSA_R_ENUMPRIVSACCOUN
r_u->ptr = 1;
r_u->count = count;
- if (!NT_STATUS_IS_OK(ret = init_priv_with_ctx(mem_ctx, &(r_u->set))))
+ if ( !NT_STATUS_IS_OK(ret = privilege_set_init_by_ctx(mem_ctx, &(r_u->set))) )
return ret;
- if (!NT_STATUS_IS_OK(ret = dupalloc_luid_attr(r_u->set->mem_ctx, &(r_u->set->set), set)))
+ r_u->set.count = count;
+
+ if (!NT_STATUS_IS_OK(ret = dup_luid_attr(r_u->set.mem_ctx, &(r_u->set.set), set, count)))
return ret;
- DEBUG(10,("init_lsa_r_enum_privsaccount: %d %d privileges\n", r_u->count, r_u->set->count));
+ DEBUG(10,("init_lsa_r_enum_privsaccount: %d privileges\n", r_u->count));
return ret;
}
@@ -1837,15 +1894,15 @@ BOOL lsa_io_r_enum_privsaccount(const char *desc, LSA_R_ENUMPRIVSACCOUNT *r_c, p
/* malloc memory if unmarshalling here */
if (UNMARSHALLING(ps) && r_c->count != 0) {
- if (!NT_STATUS_IS_OK(init_priv_with_ctx(ps->mem_ctx, &(r_c->set))))
+ if (!NT_STATUS_IS_OK(privilege_set_init_by_ctx(ps->mem_ctx, &(r_c->set))))
return False;
- if (!(r_c->set->set = PRS_ALLOC_MEM(ps,LUID_ATTR,r_c->count)))
+ if (!(r_c->set.set = PRS_ALLOC_MEM(ps,LUID_ATTR,r_c->count)))
return False;
}
- if(!lsa_io_privilege_set(desc, r_c->set, ps, depth))
+ if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
return False;
}
@@ -2007,14 +2064,14 @@ BOOL lsa_io_q_addprivs(const char *desc, LSA_Q_ADDPRIVS *r_c, prs_struct *ps, in
return False;
if (UNMARSHALLING(ps) && r_c->count!=0) {
- if (!NT_STATUS_IS_OK(init_priv_with_ctx(ps->mem_ctx, &(r_c->set))))
+ if (!NT_STATUS_IS_OK(privilege_set_init_by_ctx(ps->mem_ctx, &(r_c->set))))
return False;
- if (!(r_c->set->set = PRS_ALLOC_MEM(ps, LUID_ATTR, r_c->count)))
+ if (!(r_c->set.set = PRS_ALLOC_MEM(ps, LUID_ATTR, r_c->count)))
return False;
}
- if(!lsa_io_privilege_set(desc, r_c->set, ps, depth))
+ if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
return False;
return True;
@@ -2069,14 +2126,14 @@ BOOL lsa_io_q_removeprivs(const char *desc, LSA_Q_REMOVEPRIVS *r_c, prs_struct *
return False;
if (UNMARSHALLING(ps) && r_c->count!=0) {
- if (!NT_STATUS_IS_OK(init_priv_with_ctx(ps->mem_ctx, &(r_c->set))))
+ if (!NT_STATUS_IS_OK(privilege_set_init_by_ctx(ps->mem_ctx, &(r_c->set))))
return False;
- if (!(r_c->set->set = PRS_ALLOC_MEM(ps, LUID_ATTR, r_c->count)))
+ if (!(r_c->set.set = PRS_ALLOC_MEM(ps, LUID_ATTR, r_c->count)))
return False;
}
- if(!lsa_io_privilege_set(desc, r_c->set, ps, depth))
+ if(!lsa_io_privilege_set(desc, &r_c->set, ps, depth))
return False;
}
@@ -2243,6 +2300,33 @@ void init_q_enum_acct_rights(LSA_Q_ENUM_ACCT_RIGHTS *q_q,
}
/*******************************************************************
+********************************************************************/
+NTSTATUS init_r_enum_acct_rights( LSA_R_ENUM_ACCT_RIGHTS *r_u, PRIVILEGE_SET *privileges )
+{
+ uint32 i;
+ char *privname;
+ const char **privname_array = NULL;
+ int num_priv = 0;
+
+ for ( i=0; i<privileges->count; i++ ) {
+ privname = luid_to_privilege_name( &privileges->set[i].luid );
+ if ( privname ) {
+ if ( !add_string_to_array( get_talloc_ctx(), privname, &privname_array, &num_priv ) )
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ if ( num_priv ) {
+ if ( !init_unistr2_array( &r_u->rights, num_priv, privname_array ) )
+ return NT_STATUS_NO_MEMORY;
+
+ r_u->count = num_priv;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
reads or writes a LSA_Q_ENUM_ACCT_RIGHTS structure.
********************************************************************/
BOOL lsa_io_q_enum_acct_rights(const char *desc, LSA_Q_ENUM_ACCT_RIGHTS *q_q, prs_struct *ps, int depth)
@@ -2302,7 +2386,7 @@ void init_q_add_acct_rights(LSA_Q_ADD_ACCT_RIGHTS *q_q,
q_q->pol = *hnd;
init_dom_sid2(&q_q->sid, sid);
init_unistr2_array(&q_q->rights, count, rights);
- q_q->count = 5;
+ q_q->count = count;
}
@@ -2320,7 +2404,7 @@ BOOL lsa_io_q_add_acct_rights(const char *desc, LSA_Q_ADD_ACCT_RIGHTS *q_q, prs_
if(!smb_io_dom_sid2("sid", &q_q->sid, ps, depth))
return False;
- if(!prs_uint32("count", ps, depth, &q_q->rights.count))
+ if(!prs_uint32("count", ps, depth, &q_q->count))
return False;
if(!smb_io_unistr2_array("rights", &q_q->rights, ps, depth))
@@ -2360,7 +2444,7 @@ void init_q_remove_acct_rights(LSA_Q_REMOVE_ACCT_RIGHTS *q_q,
init_dom_sid2(&q_q->sid, sid);
q_q->removeall = removeall;
init_unistr2_array(&q_q->rights, count, rights);
- q_q->count = 5;
+ q_q->count = count;
}
@@ -2381,7 +2465,7 @@ BOOL lsa_io_q_remove_acct_rights(const char *desc, LSA_Q_REMOVE_ACCT_RIGHTS *q_q
if(!prs_uint32("removeall", ps, depth, &q_q->removeall))
return False;
- if(!prs_uint32("count", ps, depth, &q_q->rights.count))
+ if(!prs_uint32("count", ps, depth, &q_q->count))
return False;
if(!smb_io_unistr2_array("rights", &q_q->rights, ps, depth))
diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c
index 0ebc16581b7..bca40a64c82 100644
--- a/source/rpc_parse/parse_misc.c
+++ b/source/rpc_parse/parse_misc.c
@@ -553,7 +553,6 @@ void init_unistr(UNISTR *str, const char *buf)
}
len = strlen(buf) + 1;
- len = MAX(len,MAX_UNISTRLEN);
str->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, len);
if (str->buffer == NULL)
@@ -585,14 +584,12 @@ BOOL smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
Allocate the BUFFER3 memory.
********************************************************************/
-static void create_buffer3(BUFFER3 *str, size_t len)
+static size_t create_buffer3(BUFFER3 *str, size_t len)
{
- len = MAX(len,MAX_BUFFERLEN);
-
str->buffer = TALLOC_ZERO(get_talloc_ctx(), len);
if (str->buffer == NULL)
smb_panic("create_buffer3: talloc fail\n");
-
+ return len;
}
/*******************************************************************
@@ -604,10 +601,7 @@ void init_buffer3_uint32(BUFFER3 *str, uint32 val)
ZERO_STRUCTP(str);
/* set up string lengths. */
- str->buf_max_len = sizeof(uint32);
- str->buf_len = sizeof(uint32);
-
- create_buffer3(str, sizeof(uint32));
+ str->buf_max_len = str->buf_len = create_buffer3(str, sizeof(uint32));
SIVAL(str->buffer, 0, val);
}
@@ -620,11 +614,7 @@ void init_buffer3_str(BUFFER3 *str, const char *buf, int len)
ZERO_STRUCTP(str);
/* set up string lengths. */
- str->buf_max_len = len * 2;
- str->buf_len = len * 2;
-
- create_buffer3(str, str->buf_max_len);
-
+ str->buf_max_len = str->buf_len = create_buffer3(str, len*2);
rpcstr_push(str->buffer, buf, str->buf_max_len, STR_TERMINATE);
}
@@ -636,24 +626,24 @@ void init_buffer3_str(BUFFER3 *str, const char *buf, int len)
void init_buffer3_hex(BUFFER3 *str, const char *buf)
{
ZERO_STRUCTP(str);
- create_buffer3(str, strlen(buf));
- str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, sizeof(str->buffer), buf);
+ str->buf_max_len = str->buf_len = create_buffer3(str, strlen(buf));
+ str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, str->buf_len, buf);
}
/*******************************************************************
Inits a BUFFER3 structure.
********************************************************************/
-void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len)
+void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, size_t len)
{
ZERO_STRUCTP(str);
/* max buffer size (allocated size) */
- str->buf_max_len = len;
if (buf != NULL) {
- create_buffer3(str, len);
+ len = create_buffer3(str, len);
memcpy(str->buffer, buf, len);
}
+ str->buf_max_len = len;
str->buf_len = buf != NULL ? len : 0;
}
@@ -730,11 +720,11 @@ void init_buffer2(BUFFER2 *str, const uint8 *buf, size_t len)
str->buf_len = buf != NULL ? len : 0;
if (buf != NULL) {
- len = MAX(len,MAX_BUFFERLEN);
- str->buffer = TALLOC_ZERO(get_talloc_ctx(), len);
+ SMB_ASSERT(str->buf_max_len >= str->buf_len);
+ str->buffer = TALLOC_ZERO(get_talloc_ctx(), str->buf_max_len);
if (str->buffer == NULL)
smb_panic("init_buffer2: talloc fail\n");
- memcpy(str->buffer, buf, MIN(str->buf_len, len));
+ memcpy(str->buffer, buf, str->buf_len);
}
}
@@ -802,19 +792,22 @@ void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
{
+ if (from->buffer == NULL) {
+ ZERO_STRUCTP(str);
+ return;
+ }
+
+ SMB_ASSERT(from->uni_max_len >= from->uni_str_len);
+
str->uni_max_len = from->uni_max_len;
str->offset = from->offset;
str->uni_str_len = from->uni_str_len;
- if (from->buffer == NULL)
- return;
-
/* the string buffer is allocated to the maximum size
(the the length of the source string) to prevent
reallocation of memory. */
if (str->buffer == NULL) {
- size_t alloc_len = MAX(from->uni_max_len,MAX_UNISTRLEN);
- str->buffer = (uint16 *)TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, alloc_len);
+ str->buffer = (uint16 *)TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, str->uni_max_len);
if ((str->buffer == NULL)) {
smb_panic("copy_unistr2: talloc fail\n");
return;
@@ -822,24 +815,25 @@ void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
}
/* copy the string */
- memcpy(str->buffer, from->buffer, from->uni_max_len*sizeof(uint16));
+ memcpy(str->buffer, from->buffer, str->uni_max_len*sizeof(uint16));
}
/*******************************************************************
Creates a STRING2 structure.
********************************************************************/
-void init_string2(STRING2 *str, const char *buf, int max_len, int str_len)
+void init_string2(STRING2 *str, const char *buf, size_t max_len, size_t str_len)
{
/* set up string lengths. */
+ SMB_ASSERT(max_len >= str_len);
+
str->str_max_len = max_len;
str->offset = 0;
str->str_str_len = str_len;
/* store the string */
if(str_len != 0) {
- int alloc_len = MAX(str_len, MAX_STRINGLEN);
- str->buffer = TALLOC_ZERO(get_talloc_ctx(), alloc_len);
+ str->buffer = TALLOC_ZERO(get_talloc_ctx(), str->str_max_len);
if (str->buffer == NULL)
smb_panic("init_string2: malloc fail\n");
memcpy(str->buffer, buf, str_len);
@@ -901,9 +895,15 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
if (buf) {
/* We always null terminate the copy. */
len = strlen(buf) + 1;
- }
+ } else {
+ /* no buffer -- nothing to do */
+ str->uni_max_len = 0;
+ str->offset = 0;
+ str->uni_str_len = 0;
- len = MAX(len,MAX_UNISTRLEN);
+ return;
+ }
+
str->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, len);
if (str->buffer == NULL) {
@@ -943,7 +943,6 @@ void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
{
uint32 len = strlen_w(buf);
- uint32 alloc_len;
ZERO_STRUCTP(str);
@@ -952,9 +951,7 @@ void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
str->offset = 0;
str->uni_str_len = len;
- alloc_len = MAX((len + 1), MAX_UNISTRLEN);
-
- str->buffer = TALLOC_ZERO_ARRAY(ctx, uint16, alloc_len);
+ str->buffer = TALLOC_ZERO_ARRAY(ctx, uint16, len + 1);
if (str->buffer == NULL) {
smb_panic("init_unistr2_w: malloc fail\n");
return;
@@ -1667,25 +1664,19 @@ BOOL smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth
void init_unistr3(UNISTR3 *str, const char *buf)
{
- size_t len, alloc_len;
-
if (buf == NULL) {
str->uni_str_len=0;
str->str.buffer = NULL;
return;
}
- len = strlen(buf) + 1;
-
- str->uni_str_len=len;
-
- alloc_len = MAX(len, MAX_UNISTRLEN);
+ str->uni_str_len = strlen(buf) + 1;
- str->str.buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, alloc_len);
+ str->str.buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, str->uni_str_len);
if (str->str.buffer == NULL)
smb_panic("init_unistr3: malloc fail\n");
- rpcstr_push((char *)str->str.buffer, buf, len * sizeof(uint16), STR_TERMINATE);
+ rpcstr_push((char *)str->str.buffer, buf, str->uni_str_len * sizeof(uint16), STR_TERMINATE);
}
/*******************************************************************
@@ -1750,8 +1741,8 @@ BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
depth++;
prs_align(ps);
- prs_uint32("size", ps, depth, &(hdr->size));
- prs_uint32("buffer", ps, depth, &(hdr->buffer));
+ prs_uint32("size", ps, depth, &hdr->size);
+ prs_uint32("buffer", ps, depth, &hdr->buffer);
return True;
}
@@ -1759,19 +1750,20 @@ BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
/*******************************************************************
reads or writes a BUFFER4 structure.
********************************************************************/
+
BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "smb_io_buffer4");
depth++;
prs_align(ps);
- prs_uint32("buf_len", ps, depth, &(buf4->buf_len));
-
- if (buf4->buf_len > MAX_BUFFERLEN)
- {
- buf4->buf_len = MAX_BUFFERLEN;
+ prs_uint32("buf_len", ps, depth, &buf4->buf_len);
+ if (UNMARSHALLING(ps)) {
+ buf4->buffer = PRS_ALLOC_MEM(ps, uint8, buf4->buf_len);
+ if (!buf4->buffer) {
+ return False;
+ }
}
-
prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
return True;
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index 67a9d96e19a..4b78d373bab 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -726,14 +726,14 @@ BOOL prs_uint8s(BOOL charmode, const char *name, prs_struct *ps, int depth, uint
SCVAL(q, i, data8s[i]);
}
- DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset ,name));
- if (charmode)
+ DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset ,name));
+ if (charmode)
print_asc(5, (unsigned char*)data8s, len);
else {
- for (i = 0; i < len; i++)
+ for (i = 0; i < len; i++)
DEBUG(5,("%02x ", data8s[i]));
}
- DEBUG(5,("\n"));
+ DEBUG(5,("\n"));
ps->data_offset += len;
@@ -776,7 +776,7 @@ BOOL prs_uint16s(BOOL charmode, const char *name, prs_struct *ps, int depth, uin
for (i = 0; i < len; i++)
DEBUG(5,("%04x ", data16s[i]));
}
- DEBUG(5,("\n"));
+ DEBUG(5,("\n"));
ps->data_offset += (len * sizeof(uint16));
@@ -818,7 +818,7 @@ static void dbg_rw_punival(BOOL charmode, const char *name, int depth, prs_struc
for (i = 0; i < len; i++)
DEBUG(5,("%04x ", out_buf[i]));
}
- DEBUG(5,("\n"));
+ DEBUG(5,("\n"));
}
/******************************************************************
@@ -873,7 +873,7 @@ BOOL prs_uint32s(BOOL charmode, const char *name, prs_struct *ps, int depth, uin
for (i = 0; i < len; i++)
DEBUG(5,("%08x ", data32s[i]));
}
- DEBUG(5,("\n"));
+ DEBUG(5,("\n"));
ps->data_offset += (len * sizeof(uint32));
@@ -924,8 +924,11 @@ BOOL prs_buffer2(BOOL charmode, const char *name, prs_struct *ps, int depth, BUF
return False;
if (UNMARSHALLING(ps)) {
- if ( str->buf_len ) {
- str->buffer = PRS_ALLOC_MEM(ps, uint16, str->buf_len);
+ if (str->buf_len > str->buf_max_len) {
+ return False;
+ }
+ if ( str->buf_max_len ) {
+ str->buffer = PRS_ALLOC_MEM(ps, uint16, str->buf_max_len);
if ( str->buffer == NULL )
return False;
}
@@ -947,11 +950,14 @@ BOOL prs_buffer2(BOOL charmode, const char *name, prs_struct *ps, int depth, BUF
BOOL prs_string2(BOOL charmode, const char *name, prs_struct *ps, int depth, STRING2 *str)
{
unsigned int i;
- char *q = prs_mem_get(ps, str->str_max_len);
+ char *q = prs_mem_get(ps, str->str_str_len);
if (q == NULL)
return False;
if (UNMARSHALLING(ps)) {
+ if (str->str_str_len > str->str_max_len) {
+ return False;
+ }
str->buffer = PRS_ALLOC_MEM(ps,unsigned char, str->str_max_len);
if (str->buffer == NULL)
return False;
@@ -965,14 +971,14 @@ BOOL prs_string2(BOOL charmode, const char *name, prs_struct *ps, int depth, STR
SCVAL(q, i, str->buffer[i]);
}
- DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
- if (charmode)
+ DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name));
+ if (charmode)
print_asc(5, (unsigned char*)str->buffer, str->str_str_len);
else {
- for (i = 0; i < str->str_str_len; i++)
+ for (i = 0; i < str->str_str_len; i++)
DEBUG(5,("%02x ", str->buffer[i]));
}
- DEBUG(5,("\n"));
+ DEBUG(5,("\n"));
ps->data_offset += str->str_str_len;
@@ -996,6 +1002,9 @@ BOOL prs_unistr2(BOOL charmode, const char *name, prs_struct *ps, int depth, UNI
return True;
if (UNMARSHALLING(ps)) {
+ if (str->uni_str_len > str->uni_max_len) {
+ return False;
+ }
str->buffer = PRS_ALLOC_MEM(ps,uint16,str->uni_max_len);
if (str->buffer == NULL)
return False;
@@ -1061,10 +1070,8 @@ BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str)
start = (uint8*)q;
- for(len = 0; str->buffer[len] != 0; len++)
- {
- if(ps->bigendian_data)
- {
+ for(len = 0; str->buffer[len] != 0; len++) {
+ if(ps->bigendian_data) {
/* swap bytes - p is little endian, q is big endian. */
q[0] = (char)p[1];
q[1] = (char)p[0];
@@ -1126,8 +1133,7 @@ BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str)
/* the (len < alloc_len) test is to prevent us from overwriting
memory that is not ours...if we get that far, we have a non-null
terminated string in the buffer and have messed up somewhere */
- while ((len < alloc_len) && (*(uint16 *)q != 0))
- {
+ while ((len < alloc_len) && (*(uint16 *)q != 0)) {
if(ps->bigendian_data)
{
/* swap bytes - q is big endian, p is little endian. */
@@ -1145,8 +1151,7 @@ BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str)
len++;
}
- if (len < alloc_len)
- {
+ if (len < alloc_len) {
/* NULL terminate the UNISTR */
str->buffer[len++] = '\0';
}
@@ -1326,6 +1331,7 @@ int tdb_prs_fetch(TDB_CONTEXT *tdb, char *keystr, prs_struct *ps, TALLOC_CTX *me
/*******************************************************************
hash a stream.
********************************************************************/
+
BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
{
char *q;
@@ -1347,11 +1353,11 @@ BOOL prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16], int len)
return True;
}
-
/*******************************************************************
Create a digest over the entire packet (including the data), and
MD5 it with the session key.
********************************************************************/
+
static void netsec_digest(struct netsec_auth_struct *a,
int auth_flags,
RPC_AUTH_NETSEC_CHK * verf,
@@ -1383,6 +1389,7 @@ static void netsec_digest(struct netsec_auth_struct *a,
/*******************************************************************
Calculate the key with which to encode the data payload
********************************************************************/
+
static void netsec_get_sealing_key(struct netsec_auth_struct *a,
RPC_AUTH_NETSEC_CHK *verf,
uchar sealing_key[16])
@@ -1410,6 +1417,7 @@ static void netsec_get_sealing_key(struct netsec_auth_struct *a,
/*******************************************************************
Encode or Decode the sequence number (which is symmetric)
********************************************************************/
+
static void netsec_deal_with_seq_num(struct netsec_auth_struct *a,
RPC_AUTH_NETSEC_CHK *verf)
{
@@ -1432,6 +1440,7 @@ static void netsec_deal_with_seq_num(struct netsec_auth_struct *a,
/*******************************************************************
creates an RPC_AUTH_NETSEC_CHK structure.
********************************************************************/
+
static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
const uchar sig[8],
const uchar packet_digest[8],
@@ -1448,13 +1457,13 @@ static BOOL init_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK * chk,
return True;
}
-
/*******************************************************************
Encode a blob of data using the netsec (schannel) alogrithm, also produceing
a checksum over the original data. We currently only support
signing and sealing togeather - the signing-only code is close, but not
quite compatible with what MS does.
********************************************************************/
+
void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
enum netsec_direction direction,
RPC_AUTH_NETSEC_CHK * verf,
diff --git a/source/rpc_parse/parse_reg.c b/source/rpc_parse/parse_reg.c
index 69c0dfc7548..a67a3973b95 100644
--- a/source/rpc_parse/parse_reg.c
+++ b/source/rpc_parse/parse_reg.c
@@ -107,7 +107,7 @@ BOOL reg_io_r_open_hkcr(const char *desc, REG_R_OPEN_HKCR *r_r, prs_struct *ps,
if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -176,7 +176,7 @@ BOOL reg_io_r_open_hklm(const char *desc, REG_R_OPEN_HKLM * r_r, prs_struct *ps,
if (!smb_io_pol_hnd("", &r_r->pol, ps, depth))
return False;
- if (!prs_ntstatus("status", ps, depth, &r_r->status))
+ if (!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -230,7 +230,7 @@ BOOL reg_io_r_flush_key(const char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -380,7 +380,7 @@ BOOL reg_io_r_create_key(const char *desc, REG_R_CREATE_KEY *r_r, prs_struct *p
if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -446,7 +446,7 @@ BOOL reg_io_r_delete_val(const char *desc, REG_R_DELETE_VALUE *r_r, prs_struct
if(!prs_align(ps))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -510,7 +510,7 @@ BOOL reg_io_r_delete_key(const char *desc, REG_R_DELETE_KEY *r_r, prs_struct *p
if(!prs_align(ps))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -597,7 +597,7 @@ BOOL reg_io_r_query_key(const char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps,
if(!smb_io_time("mod_time ", &r_r->mod_time, ps, depth))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -651,7 +651,7 @@ BOOL reg_io_r_unknown_1a(const char *desc, REG_R_UNKNOWN_1A *r_r, prs_struct *p
if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
return False;
- if(!prs_ntstatus("status" , ps, depth, &r_r->status))
+ if(!prs_werror("status" , ps, depth, &r_r->status))
return False;
return True;
@@ -702,7 +702,7 @@ BOOL reg_io_r_save_key(const char *desc, REG_R_SAVE_KEY *r_r, prs_struct *ps, i
if(!prs_align(ps))
return False;
- if(!prs_ntstatus("status" , ps, depth, &r_r->status))
+ if(!prs_werror("status" , ps, depth, &r_r->status))
return False;
return True;
@@ -768,7 +768,7 @@ BOOL reg_io_r_open_hku(const char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, i
if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -828,7 +828,7 @@ BOOL reg_io_r_close(const char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int dep
if(!prs_align(ps))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_u->status))
+ if(!prs_werror("status", ps, depth, &r_u->status))
return False;
return True;
@@ -893,7 +893,7 @@ BOOL reg_io_r_set_key_sec(const char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *
if(!prs_align(ps))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_q->status))
+ if(!prs_werror("status", ps, depth, &r_q->status))
return False;
return True;
@@ -991,7 +991,7 @@ BOOL reg_io_r_get_key_sec(const char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct
return False;
}
- if(!prs_ntstatus("status", ps, depth, &r_q->status))
+ if(!prs_werror("status", ps, depth, &r_q->status))
return False;
return True;
@@ -1092,7 +1092,7 @@ BOOL reg_io_q_info(const char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth
********************************************************************/
BOOL new_init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
- REGISTRY_VALUE *val, NTSTATUS status)
+ REGISTRY_VALUE *val, WERROR status)
{
uint32 buf_len = 0;
BUFFER2 buf2;
@@ -1136,7 +1136,7 @@ BOOL new_init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
********************************************************************/
BOOL init_reg_r_info(uint32 include_keyval, REG_R_INFO *r_r,
- BUFFER2* buf, uint32 type, NTSTATUS status)
+ BUFFER2* buf, uint32 type, WERROR status)
{
if(r_r == NULL)
return False;
@@ -1210,7 +1210,7 @@ BOOL reg_io_r_info(const char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
return False;
}
- if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -1394,7 +1394,7 @@ BOOL reg_io_r_enum_val(const char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps,
return False;
}
- if(!prs_ntstatus("status", ps, depth, &r_q->status))
+ if(!prs_werror("status", ps, depth, &r_q->status))
return False;
return True;
@@ -1469,7 +1469,7 @@ BOOL reg_io_r_create_val(const char *desc, REG_R_CREATE_VALUE *r_q, prs_struct
if(!prs_align(ps))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_q->status))
+ if(!prs_werror("status", ps, depth, &r_q->status))
return False;
return True;
@@ -1625,7 +1625,7 @@ BOOL reg_io_r_enum_key(const char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, i
return False;
}
- if(!prs_ntstatus("status", ps, depth, &r_q->status))
+ if(!prs_werror("status", ps, depth, &r_q->status))
return False;
return True;
@@ -1685,14 +1685,14 @@ BOOL reg_io_q_open_entry(const char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *p
********************************************************************/
void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
- POLICY_HND *pol, NTSTATUS status)
+ POLICY_HND *pol, WERROR werr)
{
- if (NT_STATUS_IS_OK(status)) {
+ if (W_ERROR_IS_OK(werr)) {
memcpy(&r_r->pol, pol, sizeof(r_r->pol));
} else {
ZERO_STRUCT(r_r->pol);
}
- r_r->status = status;
+ r_r->status = werr;
}
/*******************************************************************
@@ -1713,7 +1713,7 @@ BOOL reg_io_r_open_entry(const char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *p
if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_r->status))
+ if(!prs_werror("status", ps, depth, &r_r->status))
return False;
return True;
@@ -1794,7 +1794,7 @@ BOOL reg_io_r_shutdown(const char *desc, REG_R_SHUTDOWN * r_s, prs_struct *ps,
if(!prs_align(ps))
return False;
- if(!prs_ntstatus("status", ps, depth, &r_s->status))
+ if(!prs_werror("status", ps, depth, &r_s->status))
return False;
return True;
@@ -1849,7 +1849,7 @@ BOOL reg_io_r_abort_shutdown(const char *desc, REG_R_ABORT_SHUTDOWN * r_s,
if (!prs_align(ps))
return False;
- if (!prs_ntstatus("status", ps, depth, &r_s->status))
+ if (!prs_werror("status", ps, depth, &r_s->status))
return False;
return True;
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index 8d5fee68e0b..748ee1fb7c8 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -5207,6 +5207,44 @@ static BOOL sam_io_user_info12(const char *desc, SAM_USER_INFO_12 * u,
}
/*******************************************************************
+inits a SAM_USER_INFO_7 structure.
+********************************************************************/
+
+void init_sam_user_info7(SAM_USER_INFO_7 * usr, const char *name)
+{
+ DEBUG(5, ("init_sam_user_info7\n"));
+
+ init_unistr2(&usr->uni_name, name, UNI_FLAGS_NONE); /* unicode string for name */
+ init_uni_hdr(&usr->hdr_name, &usr->uni_name); /* unicode header for name */
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_user_info7(const char *desc, SAM_USER_INFO_7 * usr,
+ prs_struct *ps, int depth)
+{
+ if (usr == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_user_info7");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!smb_io_unihdr("unihdr", &usr->hdr_name, ps, depth))
+ return False;
+
+ if(!smb_io_unistr2("unistr2", &usr->uni_name, True, ps, depth))
+ return False;
+
+ return True;
+}
+
+/*******************************************************************
inits a SAM_USER_INFO_10 structure.
********************************************************************/
@@ -6277,7 +6315,7 @@ NTSTATUS make_samr_userinfo_ctr_usr21(TALLOC_CTX *ctx, SAM_USERINFO_CTR * ctr,
uint16 switch_value,
SAM_USER_INFO_21 * usr)
{
- DEBUG(5, ("init_samr_userinfo_ctr\n"));
+ DEBUG(5, ("make_samr_userinfo_ctr_usr21\n"));
ctr->switch_value = switch_value;
ctr->info.id = NULL;
@@ -6360,8 +6398,10 @@ static void init_samr_userinfo_ctr(SAM_USERINFO_CTR * ctr, DATA_BLOB *sess_key,
dump_data(100, (char *)sess_key->data, sess_key->length);
dump_data(100, (char *)ctr->info.id23->pass, 516);
break;
+ case 0x07:
+ break;
default:
- DEBUG(4,("init_samr_userinfo_ctr: unsupported switch level\n"));
+ DEBUG(4,("init_samr_userinfo_ctr: unsupported switch level: %d\n", switch_value));
}
}
@@ -6397,6 +6437,15 @@ static BOOL samr_io_userinfo_ctr(const char *desc, SAM_USERINFO_CTR **ppctr,
ret = False;
switch (ctr->switch_value) {
+ case 0x07:
+ if (UNMARSHALLING(ps))
+ ctr->info.id7 = PRS_ALLOC_MEM(ps,SAM_USER_INFO_7,1);
+ if (ctr->info.id7 == NULL) {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ ret = sam_io_user_info7("", ctr->info.id7, ps, depth);
+ break;
case 0x10:
if (UNMARSHALLING(ps))
ctr->info.id10 = PRS_ALLOC_MEM(ps,SAM_USER_INFO_10,1);
diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c
index 8656b8f5d84..f6fdf102928 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-2003.
+ * Copyright (C) Jeremy R. Allison 1995-2005.
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
* Copyright (C) Paul Ashton 1997-1998.
*
@@ -94,8 +94,24 @@ BOOL sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
return False;
}
+ /* Theorectically an ACE can have a size greater than the
+ sum of its components. When marshalling, pad with extra null bytes up to the
+ correct size. */
+
+ if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) {
+ uint32 extra_len = psa->size - (prs_offset(ps) - old_offset);
+ uint32 i;
+ uint8 c = 0;
+
+ for (i = 0; i < extra_len; i++) {
+ if (!prs_uint8("ace extra space", ps, depth, &c))
+ return False;
+ }
+ }
+
if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
return False;
+
return True;
}
@@ -165,6 +181,20 @@ BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
return False;
}
+ /* Theorectically an ACL can have a size greater than the
+ sum of its components. When marshalling, pad with extra null bytes up to the
+ correct size. */
+
+ if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) {
+ uint32 extra_len = psa->size - (prs_offset(ps) - old_offset);
+ uint8 c = 0;
+
+ for (i = 0; i < extra_len; i++) {
+ if (!prs_uint8("acl extra space", ps, depth, &c))
+ return False;
+ }
+ }
+
if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
return False;
@@ -181,7 +211,7 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
uint32 old_offset;
uint32 max_offset = 0; /* after we're done, move offset to end */
uint32 tmp_offset = 0;
-
+
SEC_DESC *psd;
if (ppsd == NULL)
@@ -203,16 +233,6 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
prs_debug(ps, depth, desc, "sec_io_desc");
depth++;
-#if 0
- /*
- * if alignment is needed, should be done by the the
- * caller. Not here. This caused me problems when marshalling
- * printer info into a buffer. --jerry
- */
- if(!prs_align(ps))
- return False;
-#endif
-
/* start of security descriptor stored for back-calc offset purposes */
old_offset = prs_offset(ps);
@@ -222,6 +242,42 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
if(!prs_uint16("type ", ps, depth, &psd->type))
return False;
+ if (MARSHALLING(ps)) {
+ uint32 offset = SEC_DESC_HEADER_SIZE;
+
+ /*
+ * Work out the offsets here, as we write it out.
+ */
+
+ if (psd->sacl != NULL) {
+ psd->off_sacl = offset;
+ offset += psd->sacl->size;
+ } else {
+ psd->off_sacl = 0;
+ }
+
+ if (psd->dacl != NULL) {
+ psd->off_dacl = offset;
+ offset += psd->dacl->size;
+ } else {
+ psd->off_dacl = 0;
+ }
+
+ if (psd->owner_sid != NULL) {
+ psd->off_owner_sid = offset;
+ offset += sid_size(psd->owner_sid);
+ } else {
+ psd->off_owner_sid = 0;
+ }
+
+ if (psd->grp_sid != NULL) {
+ psd->off_grp_sid = offset;
+ offset += sid_size(psd->grp_sid);
+ } else {
+ psd->off_grp_sid = 0;
+ }
+ }
+
if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
return False;
@@ -289,7 +345,6 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
return False;
}
-
if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
tmp_offset = prs_offset(ps);
if(!prs_set_offset(ps, old_offset + psd->off_dacl))
@@ -303,6 +358,7 @@ BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
if(!prs_set_offset(ps, max_offset))
return False;
+
return True;
}
diff --git a/source/rpc_server/srv_lsa.c b/source/rpc_server/srv_lsa.c
index 5d6c1551c91..e3c7832aacb 100644
--- a/source/rpc_server/srv_lsa.c
+++ b/source/rpc_server/srv_lsa.c
@@ -393,6 +393,37 @@ static BOOL api_lsa_unk_get_connuser(pipes_struct *p)
}
/***************************************************************************
+ api_lsa_create_user
+ ***************************************************************************/
+
+static BOOL api_lsa_create_account(pipes_struct *p)
+{
+ LSA_Q_CREATEACCOUNT q_u;
+ LSA_R_CREATEACCOUNT r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_create_account("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_create_account: failed to unmarshall LSA_Q_CREATEACCOUNT.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_create_account(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_create_account("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_create_account: Failed to marshall LSA_R_CREATEACCOUNT.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
api_lsa_open_user
***************************************************************************/
@@ -611,7 +642,100 @@ static BOOL api_lsa_query_secobj(pipes_struct *p)
}
/***************************************************************************
- api_lsa_query_dnsdomainfo
+ api_lsa_add_acct_rights
+ ***************************************************************************/
+
+static BOOL api_lsa_add_acct_rights(pipes_struct *p)
+{
+ LSA_Q_ADD_ACCT_RIGHTS q_u;
+ LSA_R_ADD_ACCT_RIGHTS r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_add_acct_rights("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_add_acct_rights: failed to unmarshall LSA_Q_ADD_ACCT_RIGHTS.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_add_acct_rights(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_add_acct_rights("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_add_acct_rights: Failed to marshall LSA_R_ADD_ACCT_RIGHTS.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ api_lsa_remove_acct_rights
+ ***************************************************************************/
+
+static BOOL api_lsa_remove_acct_rights(pipes_struct *p)
+{
+ LSA_Q_REMOVE_ACCT_RIGHTS q_u;
+ LSA_R_REMOVE_ACCT_RIGHTS r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_remove_acct_rights("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_remove_acct_rights: failed to unmarshall LSA_Q_REMOVE_ACCT_RIGHTS.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_remove_acct_rights(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_remove_acct_rights("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_remove_acct_rights: Failed to marshall LSA_R_REMOVE_ACCT_RIGHTS.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ api_lsa_enum_acct_rights
+ ***************************************************************************/
+
+static BOOL api_lsa_enum_acct_rights(pipes_struct *p)
+{
+ LSA_Q_ENUM_ACCT_RIGHTS q_u;
+ LSA_R_ENUM_ACCT_RIGHTS r_u;
+
+ prs_struct *data = &p->in_data.data;
+ prs_struct *rdata = &p->out_data.rdata;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if(!lsa_io_q_enum_acct_rights("", &q_u, data, 0)) {
+ DEBUG(0,("api_lsa_enum_acct_rights: failed to unmarshall LSA_Q_ENUM_ACCT_RIGHTS.\n"));
+ return False;
+ }
+
+ r_u.status = _lsa_enum_acct_rights(p, &q_u, &r_u);
+
+ /* store the response in the SMB stream */
+ if(!lsa_io_r_enum_acct_rights("", &r_u, rdata, 0)) {
+ DEBUG(0,("api_lsa_enum_acct_rights: Failed to marshall LSA_R_ENUM_ACCT_RIGHTS.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/***************************************************************************
+ api_lsa_query_info2
***************************************************************************/
static BOOL api_lsa_query_info2(pipes_struct *p)
@@ -659,12 +783,16 @@ static struct api_struct api_lsa_cmds[] =
{ "LSA_PRIV_GET_DISPNAME",LSA_PRIV_GET_DISPNAME,api_lsa_priv_get_dispname},
{ "LSA_ENUM_ACCOUNTS" , LSA_ENUM_ACCOUNTS , api_lsa_enum_accounts },
{ "LSA_UNK_GET_CONNUSER", LSA_UNK_GET_CONNUSER, api_lsa_unk_get_connuser },
+ { "LSA_CREATEACCOUNT" , LSA_CREATEACCOUNT , api_lsa_create_account },
{ "LSA_OPENACCOUNT" , LSA_OPENACCOUNT , api_lsa_open_account },
{ "LSA_ENUMPRIVSACCOUNT", LSA_ENUMPRIVSACCOUNT, api_lsa_enum_privsaccount},
{ "LSA_GETSYSTEMACCOUNT", LSA_GETSYSTEMACCOUNT, api_lsa_getsystemaccount },
{ "LSA_SETSYSTEMACCOUNT", LSA_SETSYSTEMACCOUNT, api_lsa_setsystemaccount },
{ "LSA_ADDPRIVS" , LSA_ADDPRIVS , api_lsa_addprivs },
{ "LSA_REMOVEPRIVS" , LSA_REMOVEPRIVS , api_lsa_removeprivs },
+ { "LSA_ADDACCTRIGHTS" , LSA_ADDACCTRIGHTS , api_lsa_add_acct_rights },
+ { "LSA_REMOVEACCTRIGHTS", LSA_REMOVEACCTRIGHTS, api_lsa_remove_acct_rights },
+ { "LSA_ENUMACCTRIGHTS" , LSA_ENUMACCTRIGHTS , api_lsa_enum_acct_rights },
{ "LSA_QUERYSECOBJ" , LSA_QUERYSECOBJ , api_lsa_query_secobj },
/* be careful of the adding of new RPC's. See commentrs below about
ADS DC capabilities */
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index fcd574971f7..13053d9877b 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -1,4 +1,4 @@
-/*
+/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
@@ -7,6 +7,7 @@
* Copyright (C) Jeremy Allison 2001,
* Copyright (C) Rafal Szczesniak 2002,
* Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
+ * Copyright (C) Simo Sorce 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
@@ -411,9 +412,12 @@ NTSTATUS _lsa_open_policy2(pipes_struct *p, LSA_Q_OPEN_POL2 *q_u, LSA_R_OPEN_POL
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;
}
+ /* This is needed for lsa_open_account and rpcclient .... :-) */
+
+ if (geteuid() == 0)
+ acc_granted = POLICY_ALL_ACCESS;
/* associate the domain SID with the (unique) handle. */
if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
@@ -758,49 +762,56 @@ NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIV
{
struct lsa_info *handle;
uint32 i;
+ uint32 enum_context = q_u->enum_context;
+ int num_privs = count_all_privileges();
+ LSA_PRIV_ENTRY *entries = NULL;
+ LUID_ATTR luid;
- uint32 enum_context=q_u->enum_context;
- LSA_PRIV_ENTRY *entry;
- LSA_PRIV_ENTRY *entries=NULL;
+ /* remember that the enum_context starts at 0 and not 1 */
- if (enum_context >= PRIV_ALL_INDEX)
+ if ( enum_context >= num_privs )
return NT_STATUS_NO_MORE_ENTRIES;
-
- entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, PRIV_ALL_INDEX);
- if (entries==NULL)
+
+ DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n",
+ enum_context, num_privs));
+
+ if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs + 1)))
return NT_STATUS_NO_MEMORY;
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
+ /* check if the user have enough rights
+ I don't know if it's the right one. not documented. */
- /*
- * I don't know if it's the right one. not documented.
- */
if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
- entry = entries;
-
- DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n", enum_context, PRIV_ALL_INDEX));
-
- for (i = 0; i < PRIV_ALL_INDEX; i++, entry++) {
- if( i<enum_context) {
- init_unistr2(&entry->name, NULL, UNI_FLAGS_NONE);
- init_uni_hdr(&entry->hdr_name, &entry->name);
- entry->luid_low = 0;
- entry->luid_high = 0;
+ if ( !(entries = TALLOC_ZERO_ARRAY(p->mem_ctx, LSA_PRIV_ENTRY, num_privs )) )
+ return NT_STATUS_NO_MEMORY;
+
+
+ for (i = 0; i < num_privs; i++) {
+ if( i < enum_context) {
+ init_unistr2(&entries[i].name, NULL, UNI_FLAGS_NONE);
+ init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
+
+ entries[i].luid_low = 0;
+ entries[i].luid_high = 0;
} else {
- init_unistr2(&entry->name, privs[i+1].priv, UNI_FLAGS_NONE);
- init_uni_hdr(&entry->hdr_name, &entry->name);
- entry->luid_low = privs[i+1].se_priv;
- entry->luid_high = 0;
+ init_unistr2(&entries[i].name, privs[i].name, UNI_FLAGS_NONE);
+ init_uni_hdr(&entries[i].hdr_name, &entries[i].name);
+
+ luid = get_privilege_luid( &privs[i].se_priv );
+
+ entries[i].luid_low = luid.luid.low;
+ entries[i].luid_high = luid.luid.high;
}
}
- enum_context = PRIV_ALL_INDEX;
- init_lsa_r_enum_privs(r_u, enum_context, PRIV_ALL_INDEX, entries);
+ enum_context = num_privs;
+
+ init_lsa_r_enum_privs(r_u, enum_context, num_privs, entries);
return NT_STATUS_OK;
}
@@ -813,7 +824,7 @@ NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, L
{
struct lsa_info *handle;
fstring name_asc;
- int i=1;
+ const char *description;
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
@@ -828,22 +839,25 @@ NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, L
unistr2_to_ascii(name_asc, &q_u->name, sizeof(name_asc));
- DEBUG(10,("_lsa_priv_get_dispname: %s", name_asc));
+ DEBUG(10,("_lsa_priv_get_dispname: name = %s\n", name_asc));
- while (privs[i].se_priv!=SE_PRIV_ALL && strcmp(name_asc, privs[i].priv))
- i++;
+ description = get_privilege_dispname( name_asc );
- if (privs[i].se_priv!=SE_PRIV_ALL) {
- DEBUG(10,(": %s\n", privs[i].description));
- init_unistr2(&r_u->desc, privs[i].description, UNI_FLAGS_NONE);
+ if ( description ) {
+ DEBUG(10,("_lsa_priv_get_dispname: display name = %s\n", description));
+
+ init_unistr2(&r_u->desc, description, UNI_FLAGS_NONE);
init_uni_hdr(&r_u->hdr_desc, &r_u->desc);
- r_u->ptr_info=0xdeadbeef;
- r_u->lang_id=q_u->lang_id;
+ r_u->ptr_info = 0xdeadbeef;
+ r_u->lang_id = q_u->lang_id;
+
return NT_STATUS_OK;
} else {
DEBUG(10,("_lsa_priv_get_dispname: doesn't exist\n"));
- r_u->ptr_info=0;
+
+ r_u->ptr_info = 0;
+
return NT_STATUS_NO_SUCH_PRIVILEGE;
}
}
@@ -855,32 +869,26 @@ _lsa_enum_accounts.
NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENUM_ACCOUNTS *r_u)
{
struct lsa_info *handle;
- GROUP_MAP *map=NULL;
- int num_entries=0;
+ DOM_SID *sid_list;
+ int i, j, num_entries;
LSA_SID_ENUM *sids=&r_u->sids;
- int i=0,j=0;
- BOOL ret;
+ NTSTATUS ret;
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
- /* check if the user have enough rights */
-
- /*
- * I don't know if it's the right one. not documented.
- */
if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
- /* get the list of mapped groups (domain, local, builtin) */
- become_root();
- ret = pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries, ENUM_ONLY_MAPPED);
- unbecome_root();
- if( !ret ) {
- DEBUG(3,("_lsa_enum_accounts: enumeration of groups failed!\n"));
- return NT_STATUS_OK;
+ sid_list = NULL;
+ num_entries = 0;
+
+ /* The only way we can currently find out all the SIDs that have been
+ privileged is to scan all privileges */
+
+ if (!NT_STATUS_IS_OK(ret = privilege_enumerate_accounts(&sid_list, &num_entries))) {
+ return ret;
}
-
if (q_u->enum_context >= num_entries)
return NT_STATUS_NO_MORE_ENTRIES;
@@ -889,19 +897,18 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU
sids->sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_entries-q_u->enum_context);
if (sids->ptr_sid==NULL || sids->sid==NULL) {
- SAFE_FREE(map);
+ SAFE_FREE(sid_list);
return NT_STATUS_NO_MEMORY;
}
- for (i=q_u->enum_context, j=0; i<num_entries; i++) {
- init_dom_sid2( &(*sids).sid[j], &map[i].sid);
- (*sids).ptr_sid[j]=1;
- j++;
+ for (i = q_u->enum_context, j = 0; i < num_entries; i++, j++) {
+ init_dom_sid2(&(*sids).sid[j], &sid_list[i]);
+ (*sids).ptr_sid[j] = 1;
}
- SAFE_FREE(map);
+ SAFE_FREE(sid_list);
- init_lsa_r_enum_accounts(r_u, j);
+ init_lsa_r_enum_accounts(r_u, num_entries);
return NT_STATUS_OK;
}
@@ -934,15 +941,61 @@ NTSTATUS _lsa_unk_get_connuser(pipes_struct *p, LSA_Q_UNK_GET_CONNUSER *q_u, LSA
}
/***************************************************************************
-
+ Lsa Create Account
***************************************************************************/
-NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
+NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CREATEACCOUNT *r_u)
{
struct lsa_info *handle;
struct lsa_info *info;
- r_u->status = NT_STATUS_OK;
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* check if the user have enough rights */
+
+ /*
+ * I don't know if it's the right one. not documented.
+ * but guessed with rpcclient.
+ */
+ if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
+ return NT_STATUS_ACCESS_DENIED;
+
+ /* check to see if the pipe_user is a Domain Admin since
+ account_pol.tdb was already opened as root, this is all we have */
+
+ if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ return NT_STATUS_ACCESS_DENIED;
+
+ if ( is_privileged_sid( &info->sid ) )
+ return NT_STATUS_OBJECT_NAME_COLLISION;
+
+ /* associate the user/group SID with the (unique) handle. */
+
+ if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ ZERO_STRUCTP(info);
+ info->sid = q_u->sid.sid;
+ info->access = q_u->access;
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ return privilege_create_account( &info->sid );
+}
+
+
+/***************************************************************************
+ Lsa Open Account
+ ***************************************************************************/
+
+NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENACCOUNT *r_u)
+{
+ struct lsa_info *handle;
+ struct lsa_info *info;
/* find the connection policy handle. */
if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
@@ -957,6 +1010,11 @@ NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENAC
if (!(handle->access & POLICY_GET_PRIVATE_INFORMATION))
return NT_STATUS_ACCESS_DENIED;
+ /* TODO: Fis the parsing routine before reenabling this check! */
+ #if 0
+ if (!lookup_sid(&handle->sid, dom_name, name, &type))
+ return NT_STATUS_ACCESS_DENIED;
+ #endif
/* associate the user/group SID with the (unique) handle. */
if ((info = SMB_MALLOC_P(struct lsa_info)) == NULL)
return NT_STATUS_NO_MEMORY;
@@ -969,7 +1027,7 @@ NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENAC
if (!create_policy_hnd(p, &r_u->pol, free_lsa_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
- return r_u->status;
+ return NT_STATUS_OK;
}
/***************************************************************************
@@ -979,42 +1037,29 @@ NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENAC
NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVSACCOUNT *q_u, LSA_R_ENUMPRIVSACCOUNT *r_u)
{
struct lsa_info *info=NULL;
- GROUP_MAP map;
- LUID_ATTR *set=NULL;
-
- r_u->status = NT_STATUS_OK;
+ SE_PRIV mask;
+ PRIVILEGE_SET privileges;
/* 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))
- return NT_STATUS_NO_SUCH_GROUP;
+ if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) )
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-#if 0 /* privileges currently not implemented! */
- DEBUG(10,("_lsa_enum_privsaccount: %d privileges\n", map.priv_set->count));
- if (map.priv_set->count!=0) {
-
- set=(LUID_ATTR *)talloc(map.priv_set->mem_ctx, map.priv_set.count*sizeof(LUID_ATTR));
- if (set == NULL) {
- destroy_privilege(&map.priv_set);
- return NT_STATUS_NO_MEMORY;
- }
+ privilege_set_init( &privileges );
- for (i = 0; i < map.priv_set.count; i++) {
- set[i].luid.low = map.priv_set->set[i].luid.low;
- set[i].luid.high = map.priv_set->set[i].luid.high;
- set[i].attr = map.priv_set->set[i].attr;
- DEBUG(10,("_lsa_enum_privsaccount: priv %d: %d:%d:%d\n", i,
- set[i].luid.high, set[i].luid.low, set[i].attr));
- }
- }
+ if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
- init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, set, map.priv_set->count, 0);
- destroy_privilege(&map.priv_set);
-#endif
+ DEBUG(10,("_lsa_enum_privsaccount: %s has %d privileges\n",
+ sid_string_static(&info->sid), privileges.count));
- init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, set, 0, 0);
+ r_u->status = init_lsa_r_enum_privsaccount(ps->mem_ctx, r_u, privileges.set, privileges.count, 0);
+ }
+ else
+ r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
+
+ privilege_set_free( &privileges );
return r_u->status;
}
@@ -1026,15 +1071,16 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVS
NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
{
struct lsa_info *info=NULL;
- GROUP_MAP map;
- r_u->status = NT_STATUS_OK;
+ fstring name, dom_name;
+ enum SID_NAME_USE type;
/* 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))
- return NT_STATUS_NO_SUCH_GROUP;
+ if (!lookup_sid(&info->sid, dom_name, name, &type))
+ return NT_STATUS_ACCESS_DENIED;
/*
0x01 -> Log on locally
@@ -1047,7 +1093,7 @@ NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA
r_u->access = PR_LOG_ON_LOCALLY | PR_ACCESS_FROM_NETWORK;
- return r_u->status;
+ return NT_STATUS_OK;
}
/***************************************************************************
@@ -1064,6 +1110,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;
+ /* check to see if the pipe_user is a Domain Admin since
+ account_pol.tdb was already opened as root, this is all we have */
+
+ if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ return NT_STATUS_ACCESS_DENIED;
+
if (!pdb_getgrsid(&map, info->sid))
return NT_STATUS_NO_SUCH_GROUP;
@@ -1079,44 +1131,34 @@ 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;
+ SE_PRIV mask;
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))
- return NT_STATUS_NO_SUCH_GROUP;
+
+ /* check to see if the pipe_user is a Domain Admin since
+ account_pol.tdb was already opened as root, this is all we have */
+
+ if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ return NT_STATUS_ACCESS_DENIED;
set = &q_u->set;
- for (i = 0; i < set->count; i++) {
- luid_attr = &set->set[i];
-
- /* check if the privilege is already there */
- if (check_priv_in_privilege(map.priv_set, *luid_attr)){
- destroy_privilege(&map.priv_set);
- }
-
- add_privilege(map.priv_set, *luid_attr);
- }
+ if ( !privilege_set_to_se_priv( &mask, set ) )
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
- if(!pdb_update_group_mapping_entry(&map))
- return NT_STATUS_NO_SUCH_GROUP;
-
- destroy_privilege(&map.priv_set);
+ if ( !grant_privilege( &info->sid, &mask ) ) {
+ DEBUG(3,("_lsa_addprivs: grant_privilege(%s) failed!\n",
+ sid_string_static(&info->sid) ));
+ DEBUG(3,("Privilege mask:\n"));
+ dump_se_priv( DBGC_ALL, 3, &mask );
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+ }
-#endif
- return r_u->status;
+ return NT_STATUS_OK;
}
/***************************************************************************
@@ -1125,57 +1167,34 @@ 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;
+ SE_PRIV mask;
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))
- return NT_STATUS_NO_SUCH_GROUP;
-
- if (q_u->allrights != 0) {
- /* log it and return, until I see one myself don't do anything */
- DEBUG(5,("_lsa_removeprivs: trying to remove all privileges ?\n"));
- return NT_STATUS_OK;
- }
-
- if (q_u->ptr == 0) {
- /* log it and return, until I see one myself don't do anything */
- DEBUG(5,("_lsa_removeprivs: no privileges to remove ?\n"));
- return NT_STATUS_OK;
- }
+ /* check to see if the pipe_user is a Domain Admin since
+ account_pol.tdb was already opened as root, this is all we have */
+
+ if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ return NT_STATUS_ACCESS_DENIED;
set = &q_u->set;
- for (i = 0; i < set->count; i++) {
- luid_attr = &set->set[i];
-
- /* if we don't have the privilege, we're trying to remove, give up */
- /* what else can we do ??? JFM. */
- if (!check_priv_in_privilege(map.priv_set, *luid_attr)){
- destroy_privilege(&map.priv_set);
- return NT_STATUS_NO_SUCH_PRIVILEGE;
- }
-
- remove_privilege(map.priv_set, *luid_attr);
+ if ( !privilege_set_to_se_priv( &mask, set ) )
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+
+ if ( !revoke_privilege( &info->sid, &mask ) ) {
+ DEBUG(3,("_lsa_removeprivs: revoke_privilege(%s) failed!\n",
+ sid_string_static(&info->sid) ));
+ DEBUG(3,("Privilege mask:\n"));
+ dump_se_priv( DBGC_ALL, 3, &mask );
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
}
- if(!pdb_update_group_mapping_entry(&map))
- return NT_STATUS_NO_SUCH_GROUP;
-
- destroy_privilege(&map.priv_set);
-#endif
- return r_u->status;
+ return NT_STATUS_OK;
}
/***************************************************************************
@@ -1231,6 +1250,8 @@ NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUER
return r_u->status;
}
+/***************************************************************************
+ ***************************************************************************/
NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_INFO2 *r_u)
{
@@ -1291,3 +1312,144 @@ NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_I
return r_u->status;
}
+
+/***************************************************************************
+ ***************************************************************************/
+
+NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R_ADD_ACCT_RIGHTS *r_u)
+{
+ struct lsa_info *info = NULL;
+ int i = 0;
+ DOM_SID sid;
+ fstring privname;
+ UNISTR2_ARRAY *uni_privnames = &q_u->rights;
+
+
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* check to see if the pipe_user is a Domain Admin since
+ account_pol.tdb was already opened as root, this is all we have */
+
+ if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ return NT_STATUS_ACCESS_DENIED;
+
+ /* according to an NT4 PDC, you can add privileges to SIDs even without
+ call_lsa_create_account() first. And you can use any arbitrary SID. */
+
+ sid_copy( &sid, &q_u->sid.sid );
+
+ /* just a little sanity check */
+
+ if ( q_u->count != uni_privnames->count ) {
+ DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ for ( i=0; i<q_u->count; i++ ) {
+ unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 );
+
+ /* only try to add non-null strings */
+
+ if ( *privname && !grant_privilege_by_name( &sid, privname ) ) {
+ DEBUG(2,("_lsa_add_acct_rights: Failed to add privilege [%s]\n", privname ));
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+/***************************************************************************
+ ***************************************************************************/
+
+NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u, LSA_R_REMOVE_ACCT_RIGHTS *r_u)
+{
+ struct lsa_info *info = NULL;
+ int i = 0;
+ DOM_SID sid;
+ fstring privname;
+ UNISTR2_ARRAY *uni_privnames = &q_u->rights;
+
+
+ /* find the connection policy handle. */
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* check to see if the pipe_user is a Domain Admin since
+ account_pol.tdb was already opened as root, this is all we have */
+
+ if ( !nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS ) )
+ return NT_STATUS_ACCESS_DENIED;
+
+ sid_copy( &sid, &q_u->sid.sid );
+
+ if ( q_u->removeall ) {
+ if ( !revoke_all_privileges( &sid ) )
+ return NT_STATUS_ACCESS_DENIED;
+
+ return NT_STATUS_OK;
+ }
+
+ /* just a little sanity check */
+
+ if ( q_u->count != uni_privnames->count ) {
+ DEBUG(0,("_lsa_add_acct_rights: count != number of UNISTR2 elements!\n"));
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ for ( i=0; i<q_u->count; i++ ) {
+ unistr2_to_ascii( privname, &uni_privnames->strings[i].string, sizeof(fstring)-1 );
+
+ /* only try to add non-null strings */
+
+ if ( *privname && !revoke_privilege_by_name( &sid, privname ) ) {
+ DEBUG(2,("_lsa_remove_acct_rights: Failed to revoke privilege [%s]\n", privname ));
+ return NT_STATUS_NO_SUCH_PRIVILEGE;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA_R_ENUM_ACCT_RIGHTS *r_u)
+{
+ struct lsa_info *info = NULL;
+ DOM_SID sid;
+ PRIVILEGE_SET privileges;
+ SE_PRIV mask;
+
+
+ /* find the connection policy handle. */
+
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
+ return NT_STATUS_INVALID_HANDLE;
+
+ /* according to an NT4 PDC, you can add privileges to SIDs even without
+ call_lsa_create_account() first. And you can use any arbitrary SID. */
+
+ sid_copy( &sid, &q_u->sid.sid );
+
+ if ( !get_privileges_for_sids( &mask, &sid, 1 ) )
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+ privilege_set_init( &privileges );
+
+ if ( se_priv_to_privilege_set( &privileges, &mask ) ) {
+
+ DEBUG(10,("_lsa_enum_acct_rights: %s has %d privileges\n",
+ sid_string_static(&sid), privileges.count));
+
+ r_u->status = init_r_enum_acct_rights( r_u, &privileges );
+ }
+ else
+ r_u->status = NT_STATUS_NO_SUCH_PRIVILEGE;
+
+ privilege_set_free( &privileges );
+
+ return r_u->status;
+}
+
+
diff --git a/source/rpc_server/srv_reg_nt.c b/source/rpc_server/srv_reg_nt.c
index dc9db47c663..c11e0d59a05 100644
--- a/source/rpc_server/srv_reg_nt.c
+++ b/source/rpc_server/srv_reg_nt.c
@@ -79,11 +79,11 @@ static REGISTRY_KEY *find_regkey_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
HK[LM|U]\<key>\<key>\...
*******************************************************************/
-static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *parent,
+static WERROR open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY *parent,
const char *subkeyname, uint32 access_granted )
{
REGISTRY_KEY *regkey = NULL;
- NTSTATUS result = NT_STATUS_OK;
+ WERROR result = WERR_OK;
REGSUBKEY_CTR subkeys;
pstring subkeyname2;
int subkey_len;
@@ -98,7 +98,7 @@ static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY
subkeyname2[subkey_len-1] = '\0';
if ((regkey=SMB_MALLOC_P(REGISTRY_KEY)) == NULL)
- return NT_STATUS_NO_MEMORY;
+ return WERR_NOMEM;
ZERO_STRUCTP( regkey );
@@ -126,7 +126,7 @@ static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY
if ( !(regkey->hook = reghook_cache_find( regkey->name )) ) {
DEBUG(0,("open_registry_key: Failed to assigned a REGISTRY_HOOK to [%s]\n",
regkey->name ));
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ return WERR_BADFILE;
}
/* check if the path really exists; failed is indicated by -1 */
@@ -139,7 +139,7 @@ static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY
if ( fetch_reg_keys( regkey, &subkeys ) == -1 ) {
/* don't really know what to return here */
- result = NT_STATUS_NO_SUCH_FILE;
+ result = WERR_BADFILE;
}
else {
/*
@@ -148,7 +148,7 @@ static NTSTATUS open_registry_key(pipes_struct *p, POLICY_HND *hnd, REGISTRY_KEY
*/
if ( !create_policy_hnd( p, hnd, free_regkey_info, regkey ) )
- result = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ result = WERR_BADFILE;
}
/* clean up */
@@ -276,22 +276,22 @@ static BOOL get_value_information( REGISTRY_KEY *key, uint32 *maxnum,
reg_close
********************************************************************/
-NTSTATUS _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
+WERROR _reg_close(pipes_struct *p, REG_Q_CLOSE *q_u, REG_R_CLOSE *r_u)
{
/* set up the REG unknown_1 response */
ZERO_STRUCT(r_u->pol);
/* close the policy handle */
if (!close_registry_key(p, &q_u->pol))
- return NT_STATUS_OBJECT_NAME_INVALID;
+ return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
- return NT_STATUS_OK;
+ return WERR_OK;
}
/*******************************************************************
********************************************************************/
-NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
+WERROR _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKLM, 0x0 );
}
@@ -299,7 +299,7 @@ NTSTATUS _reg_open_hklm(pipes_struct *p, REG_Q_OPEN_HKLM *q_u, REG_R_OPEN_HKLM *
/*******************************************************************
********************************************************************/
-NTSTATUS _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_u)
+WERROR _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKCR, 0x0 );
}
@@ -307,7 +307,7 @@ NTSTATUS _reg_open_hkcr(pipes_struct *p, REG_Q_OPEN_HKCR *q_u, REG_R_OPEN_HKCR *
/*******************************************************************
********************************************************************/
-NTSTATUS _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u)
+WERROR _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u)
{
return open_registry_key( p, &r_u->pol, NULL, KEY_HKU, 0x0 );
}
@@ -316,17 +316,17 @@ NTSTATUS _reg_open_hku(pipes_struct *p, REG_Q_OPEN_HKU *q_u, REG_R_OPEN_HKU *r_u
reg_reply_open_entry
********************************************************************/
-NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u)
+WERROR _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTRY *r_u)
{
POLICY_HND pol;
fstring name;
REGISTRY_KEY *key = find_regkey_index_by_hnd(p, &q_u->pol);
- NTSTATUS result;
+ WERROR result;
DEBUG(5,("reg_open_entry: Enter\n"));
if ( !key )
- return NT_STATUS_INVALID_HANDLE;
+ return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
rpcstr_pull(name,q_u->uni_name.buffer,sizeof(name),q_u->uni_name.uni_str_len*2,0);
@@ -343,9 +343,9 @@ NTSTATUS _reg_open_entry(pipes_struct *p, REG_Q_OPEN_ENTRY *q_u, REG_R_OPEN_ENTR
reg_reply_info
********************************************************************/
-NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
+WERROR _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
{
- NTSTATUS status = NT_STATUS_NO_SUCH_FILE;
+ WERROR status = WERR_BADFILE;
fstring name;
const char *value_ascii = "";
fstring value;
@@ -358,7 +358,7 @@ NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
DEBUG(5,("_reg_info: Enter\n"));
if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
+ return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
DEBUG(7,("_reg_info: policy key name = [%s]\n", regkey->name));
@@ -373,11 +373,22 @@ NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
/* couple of hard coded registry values */
if ( strequal(name, "RefusePasswordChange") ) {
+ uint32 dwValue;
+
if ( (val = SMB_MALLOC_P(REGISTRY_VALUE)) == NULL ) {
DEBUG(0,("_reg_info: malloc() failed!\n"));
- return NT_STATUS_NO_MEMORY;
+ return WERR_NOMEM;
}
- ZERO_STRUCTP( val );
+
+ if (!account_policy_get(AP_REFUSE_MACHINE_PW_CHANGE, &dwValue))
+ dwValue = 0;
+ regval_ctr_addvalue(&regvals, "RefusePasswordChange",
+ REG_DWORD,
+ (const char*)&dwValue, sizeof(dwValue));
+ val = dup_registry_value(
+ regval_ctr_specific_value( &regvals, 0 ) );
+
+ status = WERR_OK;
goto out;
}
@@ -407,7 +418,7 @@ NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
val = dup_registry_value( regval_ctr_specific_value( &regvals, 0 ) );
- status = NT_STATUS_OK;
+ status = WERR_OK;
goto out;
}
@@ -419,7 +430,7 @@ NTSTATUS _reg_info(pipes_struct *p, REG_Q_INFO *q_u, REG_R_INFO *r_u)
DEBUG(10,("_reg_info: Testing value [%s]\n", val->valuename));
if ( StrCaseCmp( val->valuename, name ) == 0 ) {
DEBUG(10,("_reg_info: Found match for value [%s]\n", name));
- status = NT_STATUS_OK;
+ status = WERR_OK;
break;
}
@@ -443,21 +454,21 @@ out:
Implementation of REG_QUERY_KEY
****************************************************************************/
-NTSTATUS _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_u)
+WERROR _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
+ WERROR status = WERR_OK;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
DEBUG(5,("_reg_query_key: Enter\n"));
if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
+ return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
if ( !get_subkey_information( regkey, &r_u->num_subkeys, &r_u->max_subkeylen ) )
- return NT_STATUS_ACCESS_DENIED;
+ return WERR_ACCESS_DENIED;
if ( !get_value_information( regkey, &r_u->num_values, &r_u->max_valnamelen, &r_u->max_valbufsize ) )
- return NT_STATUS_ACCESS_DENIED;
+ return WERR_ACCESS_DENIED;
r_u->sec_desc = 0x00000078; /* size for key's sec_desc */
@@ -477,15 +488,15 @@ NTSTATUS _reg_query_key(pipes_struct *p, REG_Q_QUERY_KEY *q_u, REG_R_QUERY_KEY *
Implementation of REG_UNKNOWN_1A
****************************************************************************/
-NTSTATUS _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1A *r_u)
+WERROR _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1A *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
+ WERROR status = WERR_OK;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
DEBUG(5,("_reg_unknown_1a: Enter\n"));
if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
+ return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
r_u->unknown = 0x00000005; /* seems to be consistent...no idea what it means */
@@ -499,9 +510,9 @@ NTSTATUS _reg_unknown_1a(pipes_struct *p, REG_Q_UNKNOWN_1A *q_u, REG_R_UNKNOWN_1
Implementation of REG_ENUM_KEY
****************************************************************************/
-NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u)
+WERROR _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
+ WERROR status = WERR_OK;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
char *subkey = NULL;
@@ -509,13 +520,13 @@ NTSTATUS _reg_enum_key(pipes_struct *p, REG_Q_ENUM_KEY *q_u, REG_R_ENUM_KEY *r_u
DEBUG(5,("_reg_enum_key: Enter\n"));
if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
+ return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
DEBUG(8,("_reg_enum_key: enumerating key [%s]\n", regkey->name));
if ( !fetch_reg_keys_specific( regkey, &subkey, q_u->key_index ) )
{
- status = NT_STATUS_NO_MORE_ENTRIES;
+ status = WERR_NO_MORE_ITEMS;
goto done;
}
@@ -536,9 +547,9 @@ done:
Implementation of REG_ENUM_VALUE
****************************************************************************/
-NTSTATUS _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE *r_u)
+WERROR _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALUE *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
+ WERROR status = WERR_OK;
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
REGISTRY_VALUE *val;
@@ -546,13 +557,13 @@ NTSTATUS _reg_enum_value(pipes_struct *p, REG_Q_ENUM_VALUE *q_u, REG_R_ENUM_VALU
DEBUG(5,("_reg_enum_value: Enter\n"));
if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
+ return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
DEBUG(8,("_reg_enum_key: enumerating values for key [%s]\n", regkey->name));
if ( !fetch_reg_values_specific( regkey, &val, q_u->val_index ) )
{
- status = NT_STATUS_NO_MORE_ENTRIES;
+ status = WERR_NO_MORE_ITEMS;
goto done;
}
@@ -580,9 +591,9 @@ done:
#define SHUTDOWN_F_STRING "-f"
-NTSTATUS _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u)
+WERROR _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
+ WERROR status = WERR_OK;
pstring shutdown_script;
UNISTR2 unimsg = q_u->uni_msg;
pstring message;
@@ -593,7 +604,7 @@ NTSTATUS _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u
/* message */
rpcstr_pull (message, unimsg.buffer, sizeof(message), unimsg.uni_str_len*2,0);
- /* security check */
+ /* security check */
alpha_strcpy (chkmsg, message, NULL, sizeof(message));
/* timeout */
fstr_sprintf(timeout, "%d", q_u->timeout);
@@ -606,12 +617,23 @@ NTSTATUS _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u
if(*shutdown_script) {
int shutdown_ret;
+ SE_PRIV se_shutdown = SE_REMOTE_SHUTDOWN;
+ BOOL can_shutdown;
+
+ can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_shutdown );
+
+ /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
+ if ( can_shutdown )
+ become_root();
all_string_sub(shutdown_script, "%m", chkmsg, sizeof(shutdown_script));
all_string_sub(shutdown_script, "%t", timeout, sizeof(shutdown_script));
all_string_sub(shutdown_script, "%r", r, sizeof(shutdown_script));
all_string_sub(shutdown_script, "%f", f, sizeof(shutdown_script));
shutdown_ret = smbrun(shutdown_script,NULL);
DEBUG(3,("_reg_shutdown: Running the command `%s' gave %d\n",shutdown_script,shutdown_ret));
+ if ( can_shutdown )
+ unbecome_root();
+ /********** END SeRemoteShutdownPrivilege BLOCK **********/
}
return status;
@@ -621,17 +643,29 @@ NTSTATUS _reg_shutdown(pipes_struct *p, REG_Q_SHUTDOWN *q_u, REG_R_SHUTDOWN *r_u
reg_abort_shutdwon
********************************************************************/
-NTSTATUS _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_ABORT_SHUTDOWN *r_u)
+WERROR _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_ABORT_SHUTDOWN *r_u)
{
- NTSTATUS status = NT_STATUS_OK;
+ WERROR status = WERR_OK;
pstring abort_shutdown_script;
pstrcpy(abort_shutdown_script, lp_abort_shutdown_script());
if(*abort_shutdown_script) {
int abort_shutdown_ret;
+ SE_PRIV se_shutdown = SE_REMOTE_SHUTDOWN;
+ BOOL can_shutdown;
+
+ can_shutdown = user_has_privileges( p->pipe_user.nt_user_token, &se_shutdown );
+
+ /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
+ if ( can_shutdown )
+ become_root();
abort_shutdown_ret = smbrun(abort_shutdown_script,NULL);
DEBUG(3,("_reg_abort_shutdown: Running the command `%s' gave %d\n",abort_shutdown_script,abort_shutdown_ret));
+ if ( can_shutdown )
+ unbecome_root();
+ /********** END SeRemoteShutdownPrivilege BLOCK **********/
+
}
return status;
@@ -641,7 +675,7 @@ NTSTATUS _reg_abort_shutdown(pipes_struct *p, REG_Q_ABORT_SHUTDOWN *q_u, REG_R_A
REG_SAVE_KEY (0x14)
********************************************************************/
-NTSTATUS _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u)
+WERROR _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_u)
{
REGISTRY_KEY *regkey = find_regkey_index_by_hnd( p, &q_u->pol );
@@ -653,12 +687,12 @@ NTSTATUS _reg_save_key(pipes_struct *p, REG_Q_SAVE_KEY *q_u, REG_R_SAVE_KEY *r_
*/
if ( !regkey )
- return NT_STATUS_INVALID_HANDLE;
+ return WERR_BADFID; /* This will be reported as an RPC fault anyway. */
DEBUG(8,("_reg_save_key: berifying backup of key [%s]\n", regkey->name));
- return NT_STATUS_OK;
+ return WERR_OK;
}
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index 820c8e7a3c2..462a6463293 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -1,14 +1,14 @@
/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997,
* Copyright (C) Marc Jacobsen 1999,
- * Copyright (C) Jeremy Allison 2001-2002,
- * Copyright (C) Jean François Micouleau 1998-2001,
+ * Copyright (C) Jeremy Allison 2001-2002,
+ * Copyright (C) Jean François Micouleau 1998-2001,
* Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002,
- * Copyright (C) Gerald (Jerry) Carter 2003,
+ * Copyright (C) Gerald (Jerry) Carter 2003-2004,
*
* 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
@@ -56,7 +56,7 @@ struct samr_info {
uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
uint32 acc_granted;
uint16 acb_mask;
- BOOL all_machines;
+ BOOL only_machines;
DISP_INFO disp_info;
TALLOC_CTX *mem_ctx;
@@ -75,7 +75,7 @@ static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
level of access for further checks.
********************************************************************/
-NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
+static NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
uint32 *acc_granted, const char *debug)
{
NTSTATUS status = NT_STATUS_ACCESS_DENIED;
@@ -100,7 +100,7 @@ NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, u
Checks if access to a function can be granted
********************************************************************/
-NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
+static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
{
DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
debug, acc_granted, acc_required));
@@ -209,34 +209,40 @@ static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
}
-static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
+static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL only_machines)
{
SAM_ACCOUNT *pwd = NULL;
SAM_ACCOUNT *pwd_array = NULL;
NTSTATUS nt_status = NT_STATUS_OK;
TALLOC_CTX *mem_ctx = info->mem_ctx;
+ uint16 query_acb_mask = acb_mask;
DEBUG(10,("load_sampwd_entries\n"));
/* if the snapshoot is already loaded, return */
if ((info->disp_info.user_dbloaded==True)
&& (info->acb_mask == acb_mask)
- && (info->all_machines == all_machines)) {
+ && (info->only_machines == only_machines)) {
DEBUG(10,("load_sampwd_entries: already in memory\n"));
return NT_STATUS_OK;
}
free_samr_users(info);
+
+ if (only_machines) {
+ query_acb_mask |= ACB_WSTRUST;
+ query_acb_mask |= ACB_SVRTRUST;
+ }
- if (!pdb_setsampwent(False)) {
+ if (!pdb_setsampwent(False, query_acb_mask)) {
DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
return NT_STATUS_ACCESS_DENIED;
}
for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
&& pdb_getsampwent(pwd) == True; pwd=NULL) {
-
- if (all_machines) {
+
+ if (only_machines) {
if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
|| (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
@@ -277,7 +283,7 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOO
/* the snapshoot is in memory, we're ready to enumerate fast */
info->acb_mask = acb_mask;
- info->all_machines = all_machines;
+ info->only_machines = only_machines;
info->disp_info.user_dbloaded=True;
DEBUG(10,("load_sampwd_entries: done\n"));
@@ -450,11 +456,10 @@ NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u,
static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
{
extern DOM_SID global_sid_World;
- DOM_SID adm_sid;
- DOM_SID act_sid;
-
- SEC_ACE ace[3];
+ DOM_SID adm_sid, act_sid, domadmin_sid;
+ SEC_ACE ace[4];
SEC_ACCESS mask;
+ size_t i = 0;
SEC_ACL *psa = NULL;
@@ -466,14 +471,24 @@ static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
/*basic access for every one*/
init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
/*full access for builtin aliases Administrators and Account Operators*/
+
init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
- init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ /* add domain admins if we are a DC */
+
+ if ( IS_DC ) {
+ sid_copy( &domadmin_sid, get_global_sam_sid() );
+ sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
+ init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ }
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
+ if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
return NT_STATUS_NO_MEMORY;
if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
@@ -489,10 +504,10 @@ static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
{
extern DOM_SID global_sid_World;
- DOM_SID adm_sid;
- DOM_SID act_sid;
+ DOM_SID adm_sid, act_sid, domadmin_sid;
+ size_t i = 0;
- SEC_ACE ace[4];
+ SEC_ACE ace[5];
SEC_ACCESS mask;
SEC_ACL *psa = NULL;
@@ -504,17 +519,28 @@ static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
/*basic access for every one*/
+
init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
/*full access for builtin aliases Administrators and Account Operators*/
+
init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
- init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
- init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+
+ /* add domain admins if we are a DC */
+
+ if ( IS_DC ) {
+ sid_copy( &domadmin_sid, get_global_sam_sid() );
+ sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
+ init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ }
/*extended access for the user*/
+
init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
- init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
+ init_sec_ace(&ace[i++], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
return NT_STATUS_NO_MEMORY;
@@ -2143,7 +2169,9 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
break;
case 0x0c:
account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
- u_lock_duration = account_policy_temp * 60;
+ u_lock_duration = account_policy_temp;
+ if (u_lock_duration != -1)
+ u_lock_duration *= 60;
account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
u_reset_time = account_policy_temp * 60;
@@ -2193,6 +2221,8 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
uint32 new_rid = 0;
/* check this, when giving away 'add computer to domain' privs */
uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
+ BOOL can_add_account;
+ SE_PRIV se_rights;
/* Get the domain SID stored in the domain policy */
if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
@@ -2216,7 +2246,7 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
strlower_m(account);
-
+
pdb_init_sam(&sam_pass);
become_root();
@@ -2229,41 +2259,6 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
}
pdb_free_sam(&sam_pass);
-
- /*
- * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
- * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
- * that only people with write access to the smbpasswd file will be able
- * to create a user. JRA.
- */
-
- /*
- * add the user in the /etc/passwd file or the unix authority system.
- * We don't check if the smb_create_user() function succed or not for 2 reasons:
- * a) local_password_change() checks for us if the /etc/passwd account really exists
- * b) smb_create_user() would return an error if the account already exists
- * and as it could return an error also if it can't create the account, it would be tricky.
- *
- * So we go the easy way, only check after if the account exists.
- * JFM (2/3/2001), to clear any possible bad understanding (-:
- *
- * We now have seperate script paramaters for adding users/machines so we
- * now have some sainity-checking to match.
- */
-
- DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
-
- /*
- * we used to have code here that made sure the acb_info flags
- * matched with the users named (e.g. an account flags as a machine
- * trust account ended in '$'). It has been ifdef'd out for a long
- * time, so I replaced it with this comment. --jerry
- */
-
- /* the passdb lookup has failed; check to see if we need to run the
- add user/machine script */
-
- pw = Get_Pwnam(account);
/*********************************************************************
* HEADS UP! If we have to create a new user account, we have to get
@@ -2276,21 +2271,39 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
* --jerry (2003-07-10)
*********************************************************************/
- if ( !pw ) {
- /*
- * we can't check both the ending $ and the acb_info.
- *
- * UserManager creates trust accounts (ending in $,
- * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
- * JFM, 11/29/2001
- */
- if (account[strlen(account)-1] == '$')
- pstrcpy(add_script, lp_addmachine_script());
- else
- pstrcpy(add_script, lp_adduser_script());
+ pw = Get_Pwnam(account);
+
+ /*
+ * we can't check both the ending $ and the acb_info.
+ *
+ * UserManager creates trust accounts (ending in $,
+ * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
+ * JFM, 11/29/2001
+ */
+ if (account[strlen(account)-1] == '$') {
+ se_priv_copy( &se_rights, &se_machine_account );
+ pstrcpy(add_script, lp_addmachine_script());
+ }
+ else {
+ se_priv_copy( &se_rights, &se_add_users );
+ pstrcpy(add_script, lp_adduser_script());
+ }
+
+ can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+ DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
+ p->pipe_user_name, can_add_account ? "True":"False" ));
+
+ /********** BEGIN Admin BLOCK **********/
+
+ if ( can_add_account )
+ become_root();
+
+ if ( !pw ) {
if (*add_script) {
int add_ret;
+
all_string_sub(add_script, "%u", account, sizeof(add_script));
add_ret = smbrun(add_script,NULL);
DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
@@ -2307,26 +2320,43 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
/* implicit call to getpwnam() next. we have a valid SID coming out of this call */
- if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
- return nt_status;
+ nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
+
+ /* this code is order such that we have no unnecessary retuns
+ out of the admin block of code */
+
+ if ( NT_STATUS_IS_OK(nt_status) ) {
+ pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
+
+ if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
+ pdb_free_sam(&sam_pass);
+ DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
+ account));
+ nt_status = NT_STATUS_ACCESS_DENIED;
+ }
+ }
- pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
+ if ( can_add_account )
+ unbecome_root();
+
+ /********** END Admin BLOCK **********/
- if (!pdb_add_sam_account(sam_pass)) {
- pdb_free_sam(&sam_pass);
- DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
- account));
- return NT_STATUS_ACCESS_DENIED;
- }
-
+ /* now check for failure */
+
+ if ( !NT_STATUS_IS_OK(nt_status) )
+ return nt_status;
+
/* Get the user's SID */
+
sid_copy(&sid, pdb_get_user_sid(sam_pass));
samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
se_map_generic(&des_access, &usr_generic_mapping);
- if (!NT_STATUS_IS_OK(nt_status =
- access_check_samr_object(psd, p->pipe_user.nt_user_token,
- des_access, &acc_granted, "_samr_create_user"))) {
+
+ nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ des_access, &acc_granted, "_samr_create_user");
+
+ if ( !NT_STATUS_IS_OK(nt_status) ) {
return nt_status;
}
@@ -2511,8 +2541,11 @@ NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_
if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
return NT_STATUS_INVALID_HANDLE;
+ /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
+ Reverted that change so we will work with RAS servers again */
+
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
- SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
+ SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain")))
{
return r_u->status;
}
@@ -3011,6 +3044,8 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
SAM_USERINFO_CTR *ctr = q_u->ctr;
uint32 acc_granted;
uint32 acc_required;
+ BOOL can_add_machines;
+ SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
@@ -3020,7 +3055,17 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
return NT_STATUS_INVALID_HANDLE;
- acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
+ /* the access mask depends on what the caller wants to do */
+
+ switch (switch_value) {
+ case 24:
+ acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
+ break;
+ default:
+ acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
+ break;
+ }
+
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
return r_u->status;
}
@@ -3032,23 +3077,36 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
return NT_STATUS_INVALID_INFO_CLASS;
}
+ /* check to see if we are a domain admin */
+
+ can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
+
+ DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
+ p->pipe_user_name, can_add_machines ? "" : " not"));
+
+ /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
+
+ if ( can_add_machines )
+ become_root();
+
/* ok! user info levels (lots: see MSDEV help), off we go... */
+
switch (switch_value) {
case 0x12:
if (!set_user_info_12(ctr->info.id12, &sid))
- return NT_STATUS_ACCESS_DENIED;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
break;
case 24:
if (!p->session_key.length) {
- return NT_STATUS_NO_USER_SESSION_KEY;
+ r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
}
SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
dump_data(100, (char *)ctr->info.id24->pass, 516);
if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
- return NT_STATUS_ACCESS_DENIED;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
break;
case 25:
@@ -3062,34 +3120,41 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
*/
if (!p->session_key.length) {
- return NT_STATUS_NO_USER_SESSION_KEY;
+ r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
}
SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
dump_data(100, (char *)ctr->info.id25->pass, 532);
if (!set_user_info_pw(ctr->info.id25->pass, &sid))
- return NT_STATUS_ACCESS_DENIED;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
break;
#endif
- return NT_STATUS_INVALID_INFO_CLASS;
+ r_u->status = NT_STATUS_INVALID_INFO_CLASS;
+ break;
case 23:
if (!p->session_key.length) {
- return NT_STATUS_NO_USER_SESSION_KEY;
+ r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
}
SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
dump_data(100, (char *)ctr->info.id23->pass, 516);
if (!set_user_info_23(ctr->info.id23, &sid))
- return NT_STATUS_ACCESS_DENIED;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
break;
default:
- return NT_STATUS_INVALID_INFO_CLASS;
+ r_u->status = NT_STATUS_INVALID_INFO_CLASS;
}
+
+ if ( can_add_machines )
+ unbecome_root();
+
+ /* ================ END SeMachineAccountPrivilege BLOCK ================ */
+
return r_u->status;
}
@@ -3105,6 +3170,8 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
uint16 switch_value = q_u->switch_value;
uint32 acc_granted;
uint32 acc_required;
+ BOOL can_add_machines;
+ SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
@@ -3128,7 +3195,20 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
switch_value=ctr->switch_value;
+ /* check to see if we are a domain admin */
+
+ can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
+
+ DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
+ p->pipe_user_name, can_add_machines ? "" : " not"));
+
+ /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
+
+ if ( can_add_machines )
+ become_root();
+
/* ok! user info levels (lots: see MSDEV help), off we go... */
+
switch (switch_value) {
case 21:
if (!set_user_info_21(ctr->info.id21, &sid))
@@ -3136,21 +3216,26 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
break;
case 20:
if (!set_user_info_20(ctr->info.id20, &sid))
- return NT_STATUS_ACCESS_DENIED;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
break;
case 16:
if (!set_user_info_10(ctr->info.id10, &sid))
- return NT_STATUS_ACCESS_DENIED;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
break;
case 18:
/* Used by AS/U JRA. */
if (!set_user_info_12(ctr->info.id12, &sid))
- return NT_STATUS_ACCESS_DENIED;
+ r_u->status = NT_STATUS_ACCESS_DENIED;
break;
default:
- return NT_STATUS_INVALID_INFO_CLASS;
+ r_u->status = NT_STATUS_INVALID_INFO_CLASS;
}
+ if ( can_add_machines )
+ unbecome_root();
+
+ /* ================ END SeMachineAccountPrivilege BLOCK ================ */
+
return r_u->status;
}
@@ -3434,6 +3519,10 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD
{
DOM_SID alias_sid;
uint32 acc_granted;
+ SE_PRIV se_rights;
+ BOOL can_add_accounts;
+ BOOL ret;
+
/* Find the policy handle. Open a policy on it. */
if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
@@ -3444,11 +3533,23 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD
}
DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
+
+ se_priv_copy( &se_rights, &se_add_users );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
- if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
- return NT_STATUS_ACCESS_DENIED;
-
- return NT_STATUS_OK;
+ /******** BEGIN SeAddUsers BLOCK *********/
+
+ if ( can_add_accounts )
+ become_root();
+
+ ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
+
+ if ( can_add_accounts )
+ unbecome_root();
+
+ /******** END SeAddUsers BLOCK *********/
+
+ return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
}
/*********************************************************************
@@ -3459,6 +3560,9 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE
{
DOM_SID alias_sid;
uint32 acc_granted;
+ SE_PRIV se_rights;
+ BOOL can_add_accounts;
+ BOOL ret;
/* Find the policy handle. Open a policy on it. */
if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
@@ -3471,10 +3575,22 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE
DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
sid_string_static(&alias_sid)));
- if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
- return NT_STATUS_ACCESS_DENIED;
+ se_priv_copy( &se_rights, &se_add_users );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+ /******** BEGIN SeAddUsers BLOCK *********/
- return NT_STATUS_OK;
+ if ( can_add_accounts )
+ become_root();
+
+ ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
+
+ if ( can_add_accounts )
+ unbecome_root();
+
+ /******** END SeAddUsers BLOCK *********/
+
+ return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
}
/*********************************************************************
@@ -3495,6 +3611,8 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
SAM_ACCOUNT *sam_user=NULL;
BOOL check;
uint32 acc_granted;
+ SE_PRIV se_rights;
+ BOOL can_add_accounts;
/* Find the policy handle. Open a policy on it. */
if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
@@ -3555,6 +3673,14 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
return NT_STATUS_MEMBER_IN_GROUP;
}
+ se_priv_copy( &se_rights, &se_add_users );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+ /******** BEGIN SeAddUsers BLOCK *********/
+
+ if ( can_add_accounts )
+ become_root();
+
/*
* ok, the group exist, the user exist, the user is not in the group,
*
@@ -3563,6 +3689,11 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD
smb_add_user_group(grp_name, pwd->pw_name);
+ if ( can_add_accounts )
+ unbecome_root();
+
+ /******** END SeAddUsers BLOCK *********/
+
/* check if the user has been added then ... */
if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
passwd_free(&pwd);
@@ -3586,6 +3717,8 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE
fstring grp_name;
struct group *grp;
uint32 acc_granted;
+ SE_PRIV se_rights;
+ BOOL can_add_accounts;
/*
* delete the group member named q_u->rid
@@ -3629,9 +3762,23 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE
pdb_free_sam(&sam_pass);
return NT_STATUS_MEMBER_NOT_IN_GROUP;
}
+
+
+ se_priv_copy( &se_rights, &se_add_users );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+ /******** BEGIN SeAddUsers BLOCK *********/
+
+ if ( can_add_accounts )
+ become_root();
+
smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
+ if ( can_add_accounts )
+ unbecome_root();
+
+ /******** END SeAddUsers BLOCK *********/
+
/* check if the user has been removed then ... */
if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
pdb_free_sam(&sam_pass);
@@ -3683,6 +3830,9 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
DOM_SID user_sid;
SAM_ACCOUNT *sam_pass=NULL;
uint32 acc_granted;
+ SE_PRIV se_rights;
+ BOOL can_add_accounts;
+ BOOL ret;
DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
@@ -3705,22 +3855,40 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM
pdb_free_sam(&sam_pass);
return NT_STATUS_NO_SUCH_USER;
}
+
+ se_priv_copy( &se_rights, &se_add_users );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
- /* First delete the samba side */
- if (!pdb_delete_sam_account(sam_pass)) {
+ /******** BEGIN SeAddUsers BLOCK *********/
+
+ if ( can_add_accounts )
+ become_root();
+
+ /* First delete the samba side....
+ code is order to prevent unnecessary returns out of the admin
+ block of code */
+
+ if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
+ /*
+ * Now delete the unix side ....
+ * note: we don't check if the delete really happened
+ * as the script is not necessary present
+ * and maybe the sysadmin doesn't want to delete the unix side
+ */
+ smb_delete_user( pdb_get_username(sam_pass) );
+ }
+
+ if ( can_add_accounts )
+ unbecome_root();
+
+ /******** END SeAddUsers BLOCK *********/
+
+ if ( !ret ) {
DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
pdb_free_sam(&sam_pass);
return NT_STATUS_CANNOT_DELETE;
}
- /* Now delete the unix side */
- /*
- * note: we don't check if the delete really happened
- * as the script is not necessary present
- * and maybe the sysadmin doesn't want to delete the unix side
- */
- smb_delete_user(pdb_get_username(sam_pass));
-
pdb_free_sam(&sam_pass);
@@ -3744,6 +3912,9 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S
struct group *grp;
GROUP_MAP map;
uint32 acc_granted;
+ SE_PRIV se_rights;
+ BOOL can_add_accounts;
+ BOOL ret;
DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
@@ -3776,17 +3947,33 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S
if ( (grp=getgrgid(gid)) == NULL)
return NT_STATUS_NO_SUCH_GROUP;
+ se_priv_copy( &se_rights, &se_add_users );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+ /******** BEGIN SeAddUsers BLOCK *********/
+
+ if ( can_add_accounts )
+ become_root();
+
/* delete mapping first */
- if(!pdb_delete_group_mapping_entry(group_sid))
- return NT_STATUS_ACCESS_DENIED;
-
- /* we can delete the UNIX group */
- smb_delete_group(grp->gr_name);
+
+ if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
+ smb_delete_group( grp->gr_name );
+ }
- /* check if the group has been successfully deleted */
- if ( (grp=getgrgid(gid)) != NULL)
+ if ( can_add_accounts )
+ unbecome_root();
+
+ /******** END SeAddUsers BLOCK *********/
+
+ if ( !ret ) {
+ DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n",
+ group_sid_str));
return NT_STATUS_ACCESS_DENIED;
-
+ }
+
+ /* don't check that the unix group has been deleted. Work like
+ _samr_delet_dom_user() */
if (!close_policy_hnd(p, &q_u->group_pol))
return NT_STATUS_OBJECT_NAME_INVALID;
@@ -3802,6 +3989,9 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S
{
DOM_SID alias_sid;
uint32 acc_granted;
+ SE_PRIV se_rights;
+ BOOL can_add_accounts;
+ BOOL ret;
DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
@@ -3820,8 +4010,23 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S
DEBUG(10, ("lookup on Local SID\n"));
+ se_priv_copy( &se_rights, &se_add_users );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+ /******** BEGIN SeAddUsers BLOCK *********/
+
+ if ( can_add_accounts )
+ become_root();
+
/* Have passdb delete the alias */
- if (!pdb_delete_alias(&alias_sid))
+ ret = pdb_delete_alias(&alias_sid);
+
+ if ( can_add_accounts )
+ unbecome_root();
+
+ /******** END SeAddUsers BLOCK *********/
+
+ if ( !ret )
return NT_STATUS_ACCESS_DENIED;
if (!close_policy_hnd(p, &q_u->alias_pol))
@@ -3844,6 +4049,9 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
struct samr_info *info;
uint32 acc_granted;
gid_t gid;
+ SE_PRIV se_rights;
+ BOOL can_add_accounts;
+ NTSTATUS result;
/* Find the policy handle. Open a policy on it. */
if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
@@ -3856,32 +4064,53 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
if (!sid_equal(&dom_sid, get_global_sam_sid()))
return NT_STATUS_ACCESS_DENIED;
- /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
-
unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
/* check if group already exist */
if ((grp=getgrnam(name)) != NULL)
return NT_STATUS_GROUP_EXISTS;
- /* we can create the UNIX group */
- if (smb_create_group(name, &gid) != 0)
- return NT_STATUS_ACCESS_DENIED;
-
- /* check if the group has been successfully created */
- if ((grp=getgrgid(gid)) == NULL)
- return NT_STATUS_ACCESS_DENIED;
-
- r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
+ se_priv_copy( &se_rights, &se_add_users );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
- /* add the group to the mapping table */
- sid_copy(&info_sid, get_global_sam_sid());
- sid_append_rid(&info_sid, r_u->rid);
- sid_to_string(sid_string, &info_sid);
+ /******** BEGIN SeAddUsers BLOCK *********/
+
+ if ( can_add_accounts )
+ become_root();
+
+ /* check that we successfully create the UNIX group */
+
+ result = NT_STATUS_ACCESS_DENIED;
+ if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
+
+ /* so far, so good */
+
+ result = NT_STATUS_OK;
+
+ r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
- if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
- return NT_STATUS_ACCESS_DENIED;
+ /* add the group to the mapping table */
+
+ sid_copy( &info_sid, get_global_sam_sid() );
+ sid_append_rid( &info_sid, r_u->rid );
+ sid_to_string( sid_string, &info_sid );
+
+ /* reset the error code if we fail to add the mapping entry */
+
+ if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
+ result = NT_STATUS_ACCESS_DENIED;
+ }
+ if ( can_add_accounts )
+ unbecome_root();
+
+ /******** END SeAddUsers BLOCK *********/
+
+ /* check if we should bail out here */
+
+ if ( !NT_STATUS_IS_OK(result) )
+ return result;
+
if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
return NT_STATUS_NO_MEMORY;
@@ -3906,6 +4135,8 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
uint32 acc_granted;
gid_t gid;
NTSTATUS result;
+ SE_PRIV se_rights;
+ BOOL can_add_accounts;
/* Find the policy handle. Open a policy on it. */
if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
@@ -3918,13 +4149,24 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
if (!sid_equal(&dom_sid, get_global_sam_sid()))
return NT_STATUS_ACCESS_DENIED;
- /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
-
unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
+ se_priv_copy( &se_rights, &se_add_users );
+ can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+ /******** BEGIN SeAddUsers BLOCK *********/
+
+ if ( can_add_accounts )
+ become_root();
+
/* Have passdb create the alias */
result = pdb_create_alias(name, &r_u->rid);
+ if ( can_add_accounts )
+ unbecome_root();
+
+ /******** END SeAddUsers BLOCK *********/
+
if (!NT_STATUS_IS_OK(result))
return result;
@@ -4396,7 +4638,9 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW
break;
case 0x0c:
account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
- u_lock_duration = account_policy_temp * 60;
+ u_lock_duration = account_policy_temp;
+ if (u_lock_duration != -1)
+ u_lock_duration *= 60;
account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
u_reset_time = account_policy_temp * 60;
@@ -4464,7 +4708,9 @@ NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R
case 0x07:
break;
case 0x0c:
- u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
+ u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
+ if (u_lock_duration != -1)
+ u_lock_duration /= 60;
u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index a3424fe73be..ed7a544d72d 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -379,29 +379,50 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
return WERR_ACCESS_DENIED;
}
#endif
-
+
+ /* this does not need a become root since the access check has been
+ done on the handle already */
+
if (del_a_printer( Printer->sharename ) != 0) {
DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
return WERR_BADFID;
}
+ /* the delete printer script shoudl be run as root if the user has perms */
+
if (*lp_deleteprinter_cmd()) {
char *cmd = lp_deleteprinter_cmd();
pstring command;
int ret;
-
+ SE_PRIV se_printop = SE_PRINT_OPERATOR;
+ BOOL is_print_op;
+
pstr_sprintf(command, "%s \"%s\"", cmd, Printer->sharename);
+ is_print_op = user_has_privileges( p->pipe_user.nt_user_token, &se_printop );
+
DEBUG(10,("Running [%s]\n", command));
- ret = smbrun(command, NULL);
- if (ret != 0) {
- return WERR_BADFID; /* What to return here? */
+
+ /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
+
+ if ( is_print_op )
+ become_root();
+
+ if ( (ret = smbrun(command, NULL)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
}
+
+ if ( is_print_op )
+ unbecome_root();
+
+ /********** END SePrintOperatorPrivlege BLOCK **********/
+
DEBUGADD(10,("returned [%d]\n", ret));
- /* Send SIGHUP to process group... is there a better way? */
- kill(0, SIGHUP);
+ if (ret != 0)
+ return WERR_BADFID; /* What to return here? */
/* go ahead and re-read the services immediately */
reload_services( False );
@@ -1684,15 +1705,19 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER )
{
+ SE_PRIV se_printop = SE_PRINT_OPERATOR;
+
if (!lp_ms_add_printer_wizard()) {
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
}
- /* if the user is not root and not a printer admin, then fail */
+ /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
+ and not a printer admin, then fail */
if ( user.uid != 0
- && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum), user.groups, user.ngroups) )
+ && !user_has_privileges( user.nt_user_token, &se_printop )
+ && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum), user.groups, user.ngroups) )
{
close_printer_handle(p, handle);
return WERR_ACCESS_DENIED;
@@ -5980,7 +6005,7 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
/****************************************************************************
****************************************************************************/
-static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
+static BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
{
extern userdom_struct current_user_info;
char *cmd = lp_addprinter_cmd();
@@ -5990,6 +6015,8 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
int ret;
int fd;
fstring remote_machine = "%m";
+ SE_PRIV se_printop = SE_PRINT_OPERATOR;
+ BOOL is_print_op;
standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
@@ -5998,8 +6025,25 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
printer->info_2->portname, printer->info_2->drivername,
printer->info_2->location, printer->info_2->comment, remote_machine);
+ is_print_op = user_has_privileges( token, &se_printop );
+
DEBUG(10,("Running [%s]\n", command));
- ret = smbrun(command, &fd);
+
+ /********* BEGIN SePrintOperatorPrivilege **********/
+
+ if ( is_print_op )
+ become_root();
+
+ if ( (ret = smbrun(command, &fd)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
+ }
+
+ if ( is_print_op )
+ unbecome_root();
+
+ /********* END SePrintOperatorPrivilege **********/
+
DEBUGADD(10,("returned [%d]\n", ret));
if ( ret != 0 ) {
@@ -6008,22 +6052,22 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
return False;
}
+ /* reload our services immediately */
+ reload_services( False );
+
numlines = 0;
/* Get lines and convert them back to dos-codepage */
qlines = fd_lines_load(fd, &numlines);
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
close(fd);
- if(numlines) {
+ /* Set the portname to what the script says the portname should be. */
+ /* but don't require anything to be return from the script exit a good error code */
+
+ if (numlines) {
/* Set the portname to what the script says the portname should be. */
strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
-
- /* Send SIGHUP to process group... is there a better way? */
- kill(0, SIGHUP);
-
- /* reload our services immediately */
- reload_services( False );
}
file_lines_free(qlines);
@@ -6118,7 +6162,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
|| !strequal(printer->info_2->portname, old_printer->info_2->portname)
|| !strequal(printer->info_2->location, old_printer->info_2->location)) )
{
- if ( !add_printer_hook(printer) ) {
+ if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
result = WERR_ACCESS_DENIED;
goto done;
}
@@ -7412,7 +7456,7 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
trying to add a printer like this --jerry */
if (*lp_addprinter_cmd() ) {
- if ( !add_printer_hook(printer) ) {
+ if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
free_a_printer(&printer,2);
return WERR_ACCESS_DENIED;
}
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index af4c94800a5..13e1971925a 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -1419,10 +1419,7 @@ WERROR _srv_net_share_get_info(pipes_struct *p, SRV_Q_NET_SHARE_GET_INFO *q_u, S
static char *valid_share_pathname(char *dos_pathname)
{
- pstring saved_pathname;
- pstring unix_pathname;
char *ptr;
- int ret;
/* Convert any '\' paths to '/' */
unix_format(dos_pathname);
@@ -1437,21 +1434,7 @@ static char *valid_share_pathname(char *dos_pathname)
if (*ptr != '/')
return NULL;
- /* Can we cd to it ? */
-
- /* First save our current directory. */
- if (getcwd(saved_pathname, sizeof(saved_pathname)) == NULL)
- return False;
-
- pstrcpy(unix_pathname, ptr);
-
- ret = chdir(unix_pathname);
-
- /* We *MUST* be able to chdir back. Abort if we can't. */
- if (chdir(saved_pathname) == -1)
- smb_panic("valid_share_pathname: Unable to restore current directory.\n");
-
- return (ret != -1) ? ptr : NULL;
+ return ptr;
}
/*******************************************************************
@@ -1468,8 +1451,10 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
int type;
int snum;
int ret;
- char *ptr;
+ char *path;
SEC_DESC *psd = NULL;
+ SE_PRIV se_diskop = SE_DISK_OPERATOR;
+ BOOL is_disk_op;
DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
@@ -1492,7 +1477,11 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
get_current_user(&user,p);
- if (user.uid != sec_initial_uid())
+ is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
+
+ /* fail out now if you are not root and not a disk op */
+
+ if ( user.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
switch (q_u->info_level) {
@@ -1563,35 +1552,48 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
return WERR_ACCESS_DENIED;
/* Check if the pathname is valid. */
- if (!(ptr = valid_share_pathname( pathname )))
+ if (!(path = valid_share_pathname( pathname )))
return WERR_OBJECT_PATH_INVALID;
/* Ensure share name, pathname and comment don't contain '"' characters. */
string_replace(share_name, '"', ' ');
- string_replace(ptr, '"', ' ');
+ string_replace(path, '"', ' ');
string_replace(comment, '"', ' ');
DEBUG(10,("_srv_net_share_set_info: change share command = %s\n",
lp_change_share_cmd() ? lp_change_share_cmd() : "NULL" ));
/* Only call modify function if something changed. */
-
- if (strcmp(ptr, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) ) {
- if (!lp_change_share_cmd() || !*lp_change_share_cmd())
+
+ if (strcmp(path, lp_pathname(snum)) || strcmp(comment, lp_comment(snum)) )
+ {
+ if (!lp_change_share_cmd() || !*lp_change_share_cmd())
return WERR_ACCESS_DENIED;
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
- lp_change_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
+ lp_change_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
DEBUG(10,("_srv_net_share_set_info: Running [%s]\n", command ));
- if ((ret = smbrun(command, NULL)) != 0) {
- DEBUG(0,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
- return WERR_ACCESS_DENIED;
+
+ /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
+
+ if ( is_disk_op )
+ become_root();
+
+ if ( (ret = smbrun(command, NULL)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
}
+
+ if ( is_disk_op )
+ unbecome_root();
+
+ /********* END SeDiskOperatorPrivilege BLOCK *********/
- /* Tell everyone we updated smb.conf. */
- message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
-
+ DEBUG(3,("_srv_net_share_set_info: Running [%s] returned (%d)\n", command, ret ));
+
+ if ( ret != 0 )
+ return WERR_ACCESS_DENIED;
} else {
DEBUG(10,("_srv_net_share_set_info: No change to share name (%s)\n", share_name ));
}
@@ -1609,7 +1611,7 @@ WERROR _srv_net_share_set_info(pipes_struct *p, SRV_Q_NET_SHARE_SET_INFO *q_u, S
share_name ));
}
}
-
+
DEBUG(5,("_srv_net_share_set_info: %d\n", __LINE__));
return WERR_OK;
@@ -1629,8 +1631,10 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
int type;
int snum;
int ret;
- char *ptr;
+ char *path;
SEC_DESC *psd = NULL;
+ SE_PRIV se_diskop = SE_DISK_OPERATOR;
+ BOOL is_disk_op;
DEBUG(5,("_srv_net_share_add: %d\n", __LINE__));
@@ -1638,16 +1642,16 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
get_current_user(&user,p);
- if (user.uid != sec_initial_uid()) {
- DEBUG(10,("_srv_net_share_add: uid != sec_initial_uid(). Access denied.\n"));
+ is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
+
+ if (user.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
- }
if (!lp_add_share_cmd() || !*lp_add_share_cmd()) {
DEBUG(10,("_srv_net_share_add: No add share command\n"));
return WERR_ACCESS_DENIED;
}
-
+
switch (q_u->info_level) {
case 0:
/* No path. Not enough info in a level 0 to do anything. */
@@ -1703,32 +1707,45 @@ WERROR _srv_net_share_add(pipes_struct *p, SRV_Q_NET_SHARE_ADD *q_u, SRV_R_NET_S
return WERR_ACCESS_DENIED;
/* Check if the pathname is valid. */
- if (!(ptr = valid_share_pathname( pathname )))
+ if (!(path = valid_share_pathname( pathname )))
return WERR_OBJECT_PATH_INVALID;
/* Ensure share name, pathname and comment don't contain '"' characters. */
string_replace(share_name, '"', ' ');
- string_replace(ptr, '"', ' ');
+ string_replace(path, '"', ' ');
string_replace(comment, '"', ' ');
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\"",
- lp_add_share_cmd(), dyn_CONFIGFILE, share_name, ptr, comment);
-
+ lp_add_share_cmd(), dyn_CONFIGFILE, share_name, path, comment);
+
DEBUG(10,("_srv_net_share_add: Running [%s]\n", command ));
- if ((ret = smbrun(command, NULL)) != 0) {
- DEBUG(0,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
- return WERR_ACCESS_DENIED;
+
+ /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
+
+ if ( is_disk_op )
+ become_root();
+
+ if ( (ret = smbrun(command, NULL)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
}
+ if ( is_disk_op )
+ unbecome_root();
+
+ /********* END SeDiskOperatorPrivilege BLOCK *********/
+
+ DEBUG(3,("_srv_net_share_add: Running [%s] returned (%d)\n", command, ret ));
+
+ if ( ret != 0 )
+ return WERR_ACCESS_DENIED;
+
if (psd) {
- if (!set_share_security(p->mem_ctx, share_name, psd))
- DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n",
- share_name ));
+ if (!set_share_security(p->mem_ctx, share_name, psd)) {
+ DEBUG(0,("_srv_net_share_add: Failed to add security info to share %s.\n", share_name ));
+ }
}
- /* Tell everyone we updated smb.conf. */
- message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
-
/*
* We don't call reload_services() here, the message will
* cause this to be done before the next packet is read
@@ -1752,6 +1769,8 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
fstring share_name;
int ret;
int snum;
+ SE_PRIV se_diskop = SE_DISK_OPERATOR;
+ BOOL is_disk_op;
DEBUG(5,("_srv_net_share_del: %d\n", __LINE__));
@@ -1771,27 +1790,42 @@ WERROR _srv_net_share_del(pipes_struct *p, SRV_Q_NET_SHARE_DEL *q_u, SRV_R_NET_S
get_current_user(&user,p);
- if (user.uid != sec_initial_uid())
+ is_disk_op = user_has_privileges( p->pipe_user.nt_user_token, &se_diskop );
+
+ if (user.uid != sec_initial_uid() && !is_disk_op )
return WERR_ACCESS_DENIED;
if (!lp_delete_share_cmd() || !*lp_delete_share_cmd())
return WERR_ACCESS_DENIED;
-
+
slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"",
lp_delete_share_cmd(), dyn_CONFIGFILE, lp_servicename(snum));
DEBUG(10,("_srv_net_share_del: Running [%s]\n", command ));
- if ((ret = smbrun(command, NULL)) != 0) {
- DEBUG(0,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
- return WERR_ACCESS_DENIED;
+
+ /********* BEGIN SeDiskOperatorPrivilege BLOCK *********/
+
+ if ( is_disk_op )
+ become_root();
+
+ if ( (ret = smbrun(command, NULL)) == 0 ) {
+ /* Tell everyone we updated smb.conf. */
+ message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
}
+ if ( is_disk_op )
+ unbecome_root();
+
+ /********* END SeDiskOperatorPrivilege BLOCK *********/
+
+ DEBUG(3,("_srv_net_share_del: Running [%s] returned (%d)\n", command, ret ));
+
+ if ( ret != 0 )
+ return WERR_ACCESS_DENIED;
+
/* Delete the SD in the database. */
delete_share_security(snum);
- /* Tell everyone we updated smb.conf. */
- message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
-
lp_killservice(snum);
return WERR_OK;
diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c
index 2b8279ccd2e..7d60749ae2f 100644
--- a/source/rpcclient/cmd_lsarpc.c
+++ b/source/rpcclient/cmd_lsarpc.c
@@ -445,6 +445,48 @@ static NTSTATUS cmd_lsa_enum_sids(struct cli_state *cli,
return result;
}
+/* Create a new account */
+
+static NTSTATUS cmd_lsa_create_account(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
+{
+ POLICY_HND dom_pol;
+ POLICY_HND user_pol;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 des_access = 0x000f000f;
+
+ DOM_SID sid;
+
+ if (argc != 2 ) {
+ printf("Usage: %s SID\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ result = name_to_sid(cli, mem_ctx, &sid, argv[1]);
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &dom_pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ result = cli_lsa_create_account(cli, mem_ctx, &dom_pol, &sid, des_access, &user_pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ printf("Account for SID %s successfully created\n\n", argv[1]);
+ result = NT_STATUS_OK;
+
+ done:
+ return result;
+}
+
+
/* Enumerate the privileges of an SID */
static NTSTATUS cmd_lsa_enum_privsaccounts(struct cli_state *cli,
@@ -531,7 +573,7 @@ static NTSTATUS cmd_lsa_enum_acct_rights(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- result = cli_lsa_enum_account_rights(cli, mem_ctx, &dom_pol, sid, &count, &rights);
+ result = cli_lsa_enum_account_rights(cli, mem_ctx, &dom_pol, &sid, &count, &rights);
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -708,8 +750,13 @@ struct cmd_set lsarpc_commands[] = {
{ "enumprivs", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privilege, NULL, PI_LSARPC, "Enumerate privileges", "" },
{ "getdispname", RPC_RTYPE_NTSTATUS, cmd_lsa_get_dispname, NULL, PI_LSARPC, "Get the privilege name", "" },
{ "lsaenumsid", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_sids, NULL, PI_LSARPC, "Enumerate the LSA SIDS", "" },
+ { "lsacreateaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_create_account, NULL, PI_LSARPC, "Create a new lsa account", "" },
{ "lsaenumprivsaccount", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_privsaccounts, NULL, PI_LSARPC, "Enumerate the privileges of an SID", "" },
{ "lsaenumacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_enum_acct_rights, NULL, PI_LSARPC, "Enumerate the rights of an SID", "" },
+#if 0
+ { "lsaaddpriv", RPC_RTYPE_NTSTATUS, cmd_lsa_add_priv, NULL, PI_LSARPC, "Assign a privilege to a SID", "" },
+ { "lsadelpriv", RPC_RTYPE_NTSTATUS, cmd_lsa_del_priv, NULL, PI_LSARPC, "Revoke a privilege from a SID", "" },
+#endif
{ "lsaaddacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_add_acct_rights, NULL, PI_LSARPC, "Add rights to an account", "" },
{ "lsaremoveacctrights", RPC_RTYPE_NTSTATUS, cmd_lsa_remove_acct_rights, NULL, PI_LSARPC, "Remove rights from an account", "" },
{ "lsalookupprivvalue", RPC_RTYPE_NTSTATUS, cmd_lsa_lookupprivvalue, NULL, PI_LSARPC, "Get a privilege value given its name", "" },
@@ -717,3 +764,4 @@ struct cmd_set lsarpc_commands[] = {
{ NULL }
};
+
diff --git a/source/rpcclient/cmd_reg.c b/source/rpcclient/cmd_reg.c
index bf85d217160..8ec50b894f4 100644
--- a/source/rpcclient/cmd_reg.c
+++ b/source/rpcclient/cmd_reg.c
@@ -935,7 +935,7 @@ static NTSTATUS cmd_reg_shutdown(struct cli_state *cli, TALLOC_CTX *mem_ctx,
}
/* create an entry */
- result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, reboot, force);
+ result = werror_to_ntstatus(cli_reg_shutdown(cli, mem_ctx, msg, timeout, reboot, force));
if (NT_STATUS_IS_OK(result))
DEBUG(5,("cmd_reg_shutdown: query succeeded\n"));
@@ -954,7 +954,7 @@ static NTSTATUS cmd_reg_abort_shutdown(struct cli_state *cli,
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- result = cli_reg_abort_shutdown(cli, mem_ctx);
+ result = werror_to_ntstatus(cli_reg_abort_shutdown(cli, mem_ctx));
if (NT_STATUS_IS_OK(result))
DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index 91296a49678..a69a0cb73a7 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -28,6 +28,17 @@
extern DOM_SID domain_sid;
/****************************************************************************
+ display sam_user_info_7 structure
+ ****************************************************************************/
+static void display_sam_user_info_7(SAM_USER_INFO_7 *usr)
+{
+ fstring temp;
+
+ unistr2_to_ascii(temp, &usr->uni_name, sizeof(temp)-1);
+ printf("\tUser Name :\t%s\n", temp);
+}
+
+/****************************************************************************
display sam_user_info_21 structure
****************************************************************************/
static void display_sam_user_info_21(SAM_USER_INFO_21 *usr)
@@ -336,7 +347,17 @@ static NTSTATUS cmd_samr_query_user(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- display_sam_user_info_21(user_ctr->info.id21);
+ switch (user_ctr->switch_value) {
+ case 21:
+ display_sam_user_info_21(user_ctr->info.id21);
+ break;
+ case 7:
+ display_sam_user_info_7(user_ctr->info.id7);
+ break;
+ default:
+ printf("Unsupported infolevel: %d\n", info_level);
+ break;
+ }
done:
return result;
@@ -658,14 +679,17 @@ static NTSTATUS cmd_samr_enum_dom_users(struct cli_state *cli,
uint16 acb_mask = ACB_NORMAL;
BOOL got_connect_pol = False, got_domain_pol = False;
- if ((argc < 1) || (argc > 2)) {
- printf("Usage: %s [access_mask]\n", argv[0]);
+ if ((argc < 1) || (argc > 3)) {
+ printf("Usage: %s [access_mask] [acb_mask]\n", argv[0]);
return NT_STATUS_OK;
}
if (argc > 1)
sscanf(argv[1], "%x", &access_mask);
+ if (argc > 2)
+ sscanf(argv[2], "%x", &acb_mask);
+
/* Get sam policy handle */
result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
@@ -1212,6 +1236,57 @@ static NTSTATUS cmd_samr_create_dom_user(struct cli_state *cli,
return result;
}
+/* Create domain group */
+
+static NTSTATUS cmd_samr_create_dom_group(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ POLICY_HND connect_pol, domain_pol, group_pol;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ const char *grp_name;
+ uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
+
+ if ((argc < 2) || (argc > 3)) {
+ printf("Usage: %s groupname [access mask]\n", argv[0]);
+ return NT_STATUS_OK;
+ }
+
+ grp_name = argv[1];
+
+ if (argc > 2)
+ sscanf(argv[2], "%x", &access_mask);
+
+ /* Get sam policy handle */
+
+ result = try_samr_connects(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ /* Get domain policy handle */
+
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ access_mask,
+ &domain_sid, &domain_pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ /* Create domain user */
+
+ result = cli_samr_create_dom_group(cli, mem_ctx, &domain_pol,
+ grp_name, MAXIMUM_ALLOWED_ACCESS,
+ &group_pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ done:
+ return result;
+}
+
/* Lookup sam names */
static NTSTATUS cmd_samr_lookup_names(struct cli_state *cli,
@@ -1572,6 +1647,7 @@ struct cmd_set samr_commands[] = {
{ "enumalsgroups", RPC_RTYPE_NTSTATUS, cmd_samr_enum_als_groups, NULL, PI_SAMR, "Enumerate alias groups", "" },
{ "createdomuser", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_user, NULL, PI_SAMR, "Create domain user", "" },
+ { "createdomgroup", RPC_RTYPE_NTSTATUS, cmd_samr_create_dom_group, NULL, PI_SAMR, "Create domain group", "" },
{ "samlookupnames", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_names, NULL, PI_SAMR, "Look up names", "" },
{ "samlookuprids", RPC_RTYPE_NTSTATUS, cmd_samr_lookup_rids, NULL, PI_SAMR, "Look up names", "" },
{ "deletedomuser", RPC_RTYPE_NTSTATUS, cmd_samr_delete_dom_user, NULL, PI_SAMR, "Delete domain user", "" },
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index e003b86e67b..acb65b7f7ce 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -24,6 +24,7 @@
#include "rpcclient.h"
DOM_SID domain_sid;
+static int pipe_idx;
/* List to hold groups of commands.
@@ -315,7 +316,7 @@ static NTSTATUS cmd_sign(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* still have session, just need to use it again */
cli->pipe_auth_flags = AUTH_PIPE_NTLMSSP;
cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
- if (cli->nt_pipe_fnum != 0)
+ if (cli->nt_pipe_fnum[cli->pipe_idx] != 0)
cli_nt_session_close(cli);
}
@@ -332,7 +333,7 @@ static NTSTATUS cmd_seal(struct cli_state *cli, TALLOC_CTX *mem_ctx,
cli->pipe_auth_flags = AUTH_PIPE_NTLMSSP;
cli->pipe_auth_flags |= AUTH_PIPE_SIGN;
cli->pipe_auth_flags |= AUTH_PIPE_SEAL;
- if (cli->nt_pipe_fnum != 0)
+ if (cli->nt_pipe_fnum[cli->pipe_idx] != 0)
cli_nt_session_close(cli);
}
return NT_STATUS_OK;
@@ -346,7 +347,7 @@ static NTSTATUS cmd_none(struct cli_state *cli, TALLOC_CTX *mem_ctx,
} else {
/* still have session, just need to use it again */
cli->pipe_auth_flags = 0;
- if (cli->nt_pipe_fnum != 0)
+ if (cli->nt_pipe_fnum[cli->pipe_idx] != 0)
cli_nt_session_close(cli);
}
cli->pipe_auth_flags = 0;
@@ -381,13 +382,13 @@ static NTSTATUS setup_schannel(struct cli_state *cli, int pipe_auth_flags,
/* schannel is setup, just need to use it again with new flags */
cli->pipe_auth_flags = pipe_auth_flags;
- if (cli->nt_pipe_fnum != 0)
+ if (cli->nt_pipe_fnum[cli->pipe_idx] != 0)
cli_nt_session_close(cli);
return NT_STATUS_OK;
}
}
- if (cli->nt_pipe_fnum != 0)
+ if (cli->nt_pipe_fnum[cli->pipe_idx] != 0)
cli_nt_session_close(cli);
if (!secrets_fetch_trust_account_password(lp_workgroup(),
@@ -523,7 +524,7 @@ static NTSTATUS do_cmd(struct cli_state *cli,
if (cmd_entry->pipe_idx != -1
&& cmd_entry->pipe_idx != cli->pipe_idx) {
- if (cli->nt_pipe_fnum != 0)
+ if (cli->nt_pipe_fnum[cli->pipe_idx] != 0)
cli_nt_session_close(cli);
if (!cli_nt_session_open(cli, cmd_entry->pipe_idx)) {
@@ -558,6 +559,7 @@ static NTSTATUS do_cmd(struct cli_state *cli,
/* Run command */
+ pipe_idx = cmd_entry->pipe_idx;
if ( cmd_entry->returntype == RPC_RTYPE_NTSTATUS ) {
ntresult = cmd_entry->ntfn(cli, mem_ctx, argc, (const char **) argv);
if (!NT_STATUS_IS_OK(ntresult)) {
@@ -656,6 +658,7 @@ out_free:
struct cmd_set **cmd_set;
struct in_addr server_ip;
NTSTATUS nt_status;
+ static int opt_port = 0;
/* make sure the vars that get altered (4th field) are in
a fixed location or certain compilers complain */
@@ -664,6 +667,7 @@ out_free:
POPT_AUTOHELP
{"command", 'c', POPT_ARG_STRING, &cmdstr, 'c', "Execute semicolon separated cmds", "COMMANDS"},
{"dest-ip", 'I', POPT_ARG_STRING, &opt_ipaddr, 'I', "Specify destination IP address", "IP"},
+ {"port", 'p', POPT_ARG_INT, &opt_port, 'p', "Specify port number", "PORT"},
POPT_COMMON_SAMBA
POPT_COMMON_CONNECTION
POPT_COMMON_CREDENTIALS
@@ -737,7 +741,7 @@ out_free:
}
nt_status = cli_full_connection(&cli, global_myname(), server,
- opt_ipaddr ? &server_ip : NULL, 0,
+ opt_ipaddr ? &server_ip : NULL, opt_port,
"IPC$", "IPC",
cmdline_auth_info.username,
lp_workgroup(),
diff --git a/source/sam/idmap_rid.c b/source/sam/idmap_rid.c
index e1e45514435..d0cbcd71862 100644
--- a/source/sam/idmap_rid.c
+++ b/source/sam/idmap_rid.c
@@ -24,8 +24,6 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_IDMAP
-#define IDMAP_RID_SUPPORT_TRUSTED_DOMAINS 0
-
NTSTATUS init_module(void);
struct dom_entry {
@@ -271,12 +269,16 @@ static NTSTATUS rid_idmap_get_domains(uint32 *num_domains, fstring **domain_name
i, trusted_domain_names[i], sid_str));
}
+ int own_domains = 2;
+ if (!sid_equal(domain_sid, get_global_sam_sid()))
+ ++own_domains;
+
/* put the results together */
- *num_domains = trusted_num_domains + 2;
+ *num_domains = trusted_num_domains + own_domains;
*domain_names = (fstring *) realloc(*domain_names, sizeof(fstring) * *num_domains);
*domain_sids = (DOM_SID *) realloc(*domain_sids, sizeof(DOM_SID) * *num_domains);
- /* first add myself */
+ /* first add mydomain */
fstrcpy((*domain_names)[0], domain_name);
sid_copy(&(*domain_sids)[0], domain_sid);
@@ -285,10 +287,16 @@ static NTSTATUS rid_idmap_get_domains(uint32 *num_domains, fstring **domain_name
fstrcpy((*domain_names)[1], "BUILTIN");
sid_copy(&(*domain_sids)[1], &builtin_sid);
+ /* then add my local sid */
+ if (!sid_equal(domain_sid, get_global_sam_sid())) {
+ fstrcpy((*domain_names)[2], global_myname());
+ sid_copy(&(*domain_sids)[2], get_global_sam_sid());
+ }
+
/* add trusted domains */
for (i=0; i<trusted_num_domains; i++) {
- fstrcpy((*domain_names)[i+2], trusted_domain_names[i]);
- sid_copy(&((*domain_sids)[i+2]), &(trusted_domain_sids[i]));
+ fstrcpy((*domain_names)[i+own_domains], trusted_domain_names[i]);
+ sid_copy(&((*domain_sids)[i+own_domains]), &(trusted_domain_sids[i]));
}
/* show complete domain list */
@@ -477,11 +485,15 @@ static NTSTATUS rid_idmap_get_id_from_sid(unid_t *unid, int *id_type, const DOM_
unid->uid = rid + trust.dom[i].min_id;
if (unid->uid > trust.dom[i].max_id) {
- DEBUG(0,("rid_idmap_get_id_from_sid: rid: %d too high for mapping of domain: %s\n", rid, trust.dom[i].name));
+ DEBUG(0,("rid_idmap_get_id_from_sid: rid: %d (%s: %d) too high for mapping of domain: %s (%d-%d)\n",
+ rid, (*id_type == ID_GROUPID) ? "GID" : "UID", unid->uid, trust.dom[i].name,
+ trust.dom[i].min_id, trust.dom[i].max_id));
return NT_STATUS_INVALID_PARAMETER;
}
if (unid->uid < trust.dom[i].min_id) {
- DEBUG(0,("rid_idmap_get_id_from_sid: rid: %d too low for mapping of domain: %s\n", rid, trust.dom[i].name));
+ DEBUG(0,("rid_idmap_get_id_from_sid: rid: %d (%s: %d) too low for mapping of domain: %s (%d-%d)\n",
+ rid, (*id_type == ID_GROUPID) ? "GID" : "UID", unid->uid,
+ trust.dom[i].name, trust.dom[i].min_id, trust.dom[i].max_id));
return NT_STATUS_INVALID_PARAMETER;
}
diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk
index 4edc7abc63a..45cc0821aa8 100644
--- a/source/script/mkproto.awk
+++ b/source/script/mkproto.awk
@@ -132,7 +132,7 @@ END {
gotstart = 1;
}
- if( $0 ~ /^WINBINDD_PW|^WINBINDD_GR|^NT_PRINTER_INFO_LEVEL_2|^LOGIN_CACHE|^krb5_error_code|^LDAP|^u32/ ) {
+ if( $0 ~ /^WINBINDD_PW|^WINBINDD_GR|^NT_PRINTER_INFO_LEVEL_2|^LOGIN_CACHE|^krb5_error_code|^LDAP|^u32|^LUID_ATTR/ ) {
gotstart = 1;
}
diff --git a/source/smbd/conn.c b/source/smbd/conn.c
index 6b5942f7f66..26529c77a1f 100644
--- a/source/smbd/conn.c
+++ b/source/smbd/conn.c
@@ -250,6 +250,10 @@ void conn_free(connection_struct *conn)
conn->ngroups = 0;
}
+ if (conn->nt_user_token) {
+ delete_nt_token(&(conn->nt_user_token));
+ }
+
free_namearray(conn->veto_list);
free_namearray(conn->hide_list);
free_namearray(conn->veto_oplock_list);
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index 9fcd39b5002..3f21a2ac6ad 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -269,7 +269,7 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
/* First find out the name of this file. */
if (suwcnt != 2) {
DEBUG(0,("Unexpected named pipe transaction.\n"));
- return(-1);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
/* Get the file handle and hence the file name. */
@@ -290,7 +290,7 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
}
DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
- return api_no_reply(outbuf, mdrcnt);
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE);
}
DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)\n", subcommand, p->name, pnum));
@@ -315,6 +315,8 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
/* Set Named Pipe Handle state */
reply = api_SNPHS(outbuf, p, params, tpscnt);
break;
+ default:
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
if (!reply)
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index 4af11da7844..9f2cd214259 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -1874,7 +1874,7 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
/* Open the passgrp file - not for update. */
become_root();
- if(!pdb_setsampwent(False)) {
+ if(!pdb_setsampwent(False, 0)) {
DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
unbecome_root();
return False;
diff --git a/source/smbd/message.c b/source/smbd/message.c
index f853a914753..5af7d3e451e 100644
--- a/source/smbd/message.c
+++ b/source/smbd/message.c
@@ -127,8 +127,8 @@ int reply_sends(connection_struct *conn,
outsize = set_message(outbuf,0,0,True);
p = smb_buf(inbuf)+1;
- p += srvstr_pull_buf(inbuf, msgfrom, p, sizeof(msgfrom), STR_TERMINATE) + 1;
- p += srvstr_pull_buf(inbuf, msgto, p, sizeof(msgto), STR_TERMINATE) + 1;
+ p += srvstr_pull_buf(inbuf, msgfrom, p, sizeof(msgfrom), STR_ASCII|STR_TERMINATE) + 1;
+ p += srvstr_pull_buf(inbuf, msgto, p, sizeof(msgto), STR_ASCII|STR_TERMINATE) + 1;
msg = p;
@@ -169,8 +169,8 @@ int reply_sendstrt(connection_struct *conn,
msgpos = 0;
p = smb_buf(inbuf)+1;
- p += srvstr_pull_buf(inbuf, msgfrom, p, sizeof(msgfrom), STR_TERMINATE) + 1;
- p += srvstr_pull_buf(inbuf, msgto, p, sizeof(msgto), STR_TERMINATE) + 1;
+ p += srvstr_pull_buf(inbuf, msgfrom, p, sizeof(msgfrom), STR_ASCII|STR_TERMINATE) + 1;
+ p += srvstr_pull_buf(inbuf, msgto, p, sizeof(msgto), STR_ASCII|STR_TERMINATE) + 1;
DEBUG( 3, ( "SMBsendstrt (from %s to %s)\n", msgfrom, msgto ) );
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 1372ebbf458..54837c3b9ae 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -1282,7 +1282,7 @@ static int setup_select_timeout(void)
void check_reload(int t)
{
static time_t last_smb_conf_reload_time = 0;
- static time_t last_load_printers_reload_time = 0;
+ static time_t last_printer_reload_time = 0;
time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
if(last_smb_conf_reload_time == 0) {
@@ -1291,9 +1291,9 @@ void check_reload(int t)
Then no printer is available till the first printers check
is performed. A lower initial interval circumvents this. */
if ( printcap_cache_time > 60 )
- last_load_printers_reload_time = t - printcap_cache_time + 60;
+ last_printer_reload_time = t - printcap_cache_time + 60;
else
- last_load_printers_reload_time = t;
+ last_printer_reload_time = t;
}
if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
@@ -1308,13 +1308,12 @@ void check_reload(int t)
{
/* see if it's time to reload or if the clock has been set back */
- if ( (t >= last_load_printers_reload_time+printcap_cache_time)
- || (t-last_load_printers_reload_time < 0) )
+ if ( (t >= last_printer_reload_time+printcap_cache_time)
+ || (t-last_printer_reload_time < 0) )
{
DEBUG( 3,( "Printcap cache time expired.\n"));
- remove_stale_printers();
- load_printers();
- last_load_printers_reload_time = t;
+ reload_printers();
+ last_printer_reload_time = t;
}
}
}
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 724a49321a2..7f7d55c7e3a 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -464,6 +464,39 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
}
/****************************************************************************
+ Reload printers
+**************************************************************************/
+void reload_printers(void)
+{
+ int snum;
+ int n_services = lp_numservices();
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ const char *pname;
+
+ pcap_cache_reload();
+
+ /* remove stale printers */
+ for (snum = 0; snum < n_services; snum++) {
+ /* avoid removing PRINTERS_NAME or non-autoloaded printers */
+ if (snum == pnum || !(lp_snum_ok(snum) && lp_print_ok(snum) &&
+ lp_autoloaded(snum)))
+ continue;
+
+ pname = lp_printername(snum);
+ if (!pcap_printername_ok(pname)) {
+ DEBUG(3, ("removing stale printer %s\n", pname));
+
+ if (is_printer_published(NULL, snum, NULL))
+ nt_printer_publish(NULL, snum, SPOOL_DS_UNPUBLISH);
+ del_a_printer(pname);
+ lp_killservice(snum);
+ }
+ }
+
+ load_printers();
+}
+
+/****************************************************************************
Reload the services file.
**************************************************************************/
@@ -490,8 +523,7 @@ BOOL reload_services(BOOL test)
ret = lp_load(dyn_CONFIGFILE, False, False, True);
- remove_stale_printers();
- load_printers();
+ reload_printers();
/* perhaps the config filename is now set */
if (!test)
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 3dcd803a7ce..2e60adc6366 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -152,10 +152,8 @@ int find_service(fstring service)
int iPrinterService;
if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
- const char *pszTemp = lp_printcapname();
-
DEBUG(3,("checking whether %s is a valid printer name...\n", service));
- if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp)) {
+ if (pcap_printername_ok(service)) {
DEBUG(3,("%s is a valid printer name\n", service));
DEBUG(3,("adding %s as a printer service\n", service));
lp_add_printer(service, iPrinterService);
@@ -863,36 +861,3 @@ void close_cnum(connection_struct *conn, uint16 vuid)
conn_free(conn);
}
-
-/****************************************************************************
- Remove stale printers
-****************************************************************************/
-
-void remove_stale_printers( void )
-{
- int snum, iNumServices, printersServiceNum;
- const char *pname;
-
- iNumServices = lp_numservices();
- printersServiceNum = lp_servicenumber( PRINTERS_NAME);
- for( snum = 0; snum < iNumServices; snum++) {
-
- /* Never remove PRINTERS_NAME */
-
- if ( snum == printersServiceNum)
- continue;
- pname = lp_printername( snum);
-
- /* Is snum an autoloaded print service and still
- in the printing subsystem? */
-
- if ( lp_snum_ok(snum)
- && lp_print_ok(snum)
- && lp_autoloaded(snum)
- && !pcap_printername_ok( pname, NULL))
- {
- DEBUG( 3, ( "Removing printer: %s\n", pname));
- lp_killservice( snum);
- }
- }
-}
diff --git a/source/torture/rpctorture.c b/source/torture/rpctorture.c
index d95c0cee0fe..98e36983b09 100644
--- a/source/torture/rpctorture.c
+++ b/source/torture/rpctorture.c
@@ -285,7 +285,11 @@ enum client_action
ZERO_STRUCT(cli_info.dom.level5_sid);
pstrcpy(cli_info.dom.level5_dom, "");
- smb_cli->nt_pipe_fnum = 0xffff;
+ {
+ int i;
+ for (i=0; i<PI_MAX_PIPES; i++)
+ smb_cli->nt_pipe_fnum[i] = 0xffff;
+ }
setup_logging(pname, True);
diff --git a/source/torture/vfstest.c b/source/torture/vfstest.c
index 48556aa2570..3296a660960 100644
--- a/source/torture/vfstest.c
+++ b/source/torture/vfstest.c
@@ -418,6 +418,11 @@ int smbd_server_fd(void)
return server_fd;
}
+void reload_printers(void)
+{
+ return;
+}
+
/****************************************************************************
Reload the services file.
**************************************************************************/
@@ -445,8 +450,6 @@ BOOL reload_services(BOOL test)
ret = lp_load(dyn_CONFIGFILE, False, False, True);
- load_printers();
-
/* perhaps the config filename is now set */
if (!test)
reload_services(True);
diff --git a/source/utils/net.c b/source/utils/net.c
index 251e94db906..cfbc8aca512 100644
--- a/source/utils/net.c
+++ b/source/utils/net.c
@@ -602,8 +602,8 @@ static uint32 get_maxrid(void)
int num_entries = 0;
int i;
- if (!pdb_setsampwent(False)) {
- DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
+ if (!pdb_setsampwent(False, 0)) {
+ DEBUG(0, ("get_maxrid: Unable to open passdb.\n"));
return 0;
}
diff --git a/source/utils/net.h b/source/utils/net.h
index 5e65ca0d4cd..2d9fbd16448 100644
--- a/source/utils/net.h
+++ b/source/utils/net.h
@@ -17,8 +17,21 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+/*
+ * A function of this type is passed to the '
+ * run_rpc_command' wrapper. Must go before the net_proto.h
+ * include
+ */
+
+typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, const char *,
+ struct cli_state *, TALLOC_CTX *, int, const char **);
+
+/* INCLUDE FILES */
+
#include "utils/net_proto.h"
+/* MACROS & DEFINES */
+
#define NET_FLAGS_MASTER 1
#define NET_FLAGS_DMB 2
diff --git a/source/utils/net_help.c b/source/utils/net_help.c
index 8286e853216..328e1344591 100644
--- a/source/utils/net_help.c
+++ b/source/utils/net_help.c
@@ -76,6 +76,9 @@ int net_help_user(int argc, const char **argv)
d_printf("\nnet [<method>] user ADD <name> [password] [-c container] "\
"[-F user flags] [misc. options]"\
" [targets]\n\tAdd specified user\n");
+ d_printf("\nnet [<method>] user RENAME <oldusername> <newusername>"\
+ " [targets]\n\tRename specified user\n\n");
+
net_common_methods_usage(argc, argv);
net_common_flags_usage(argc, argv);
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index 4c5544aa973..430649d81bb 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -37,10 +37,6 @@
**/
-/* A function of this type is passed to the 'run_rpc_command' wrapper */
-typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, const char *,
- struct cli_state *, TALLOC_CTX *, int, const char **);
-
/**
* Many of the RPC functions need the domain sid. This function gets
* it at the start of every run
@@ -100,7 +96,7 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem
* @return A shell status integer (0 for success)
*/
-static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flags,
+int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int conn_flags,
rpc_command_fn fn,
int argc, const char **argv)
{
@@ -145,7 +141,7 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co
}
if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
- if (cli->nt_pipe_fnum)
+ if (cli->nt_pipe_fnum[cli->pipe_idx])
cli_nt_session_close(cli);
}
@@ -674,6 +670,133 @@ static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid,
}
/**
+ * Rename a user on a remote RPC server
+ *
+ * All parameters are provided by the run_rpc_command function, except for
+ * argc, argv which are passes through.
+ *
+ * @param domain_sid The domain sid acquired from the remote server
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on completion of the function.
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return Normal NTSTATUS return.
+ **/
+
+static NTSTATUS rpc_user_rename_internals(const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv) {
+
+ POLICY_HND connect_pol, domain_pol, user_pol;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ uint32 info_level = 7;
+ const char *old_name, *new_name;
+ uint32 *user_rid;
+ uint32 flags = 0x000003e8; /* Unknown */
+ uint32 num_rids, *name_types;
+ uint32 num_names = 1;
+ const char **names;
+ SAM_USERINFO_CTR *user_ctr;
+ SAM_USERINFO_CTR ctr;
+ SAM_USER_INFO_7 info7;
+
+ if (argc != 2) {
+ d_printf("New and old username must be specified\n");
+ rpc_user_usage(argc, argv);
+ return NT_STATUS_OK;
+ }
+
+ old_name = argv[0];
+ new_name = argv[1];
+
+ ZERO_STRUCT(ctr);
+ ZERO_STRUCT(user_ctr);
+
+ /* Get sam policy handle */
+
+ result = cli_samr_connect(cli, mem_ctx, MAXIMUM_ALLOWED_ACCESS,
+ &connect_pol);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ /* Get domain policy handle */
+
+ result = cli_samr_open_domain(cli, mem_ctx, &connect_pol,
+ MAXIMUM_ALLOWED_ACCESS,
+ domain_sid, &domain_pol);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ names = TALLOC_ARRAY(mem_ctx, const char *, num_names);
+ names[0] = old_name;
+ result = cli_samr_lookup_names(cli, mem_ctx, &domain_pol,
+ flags, num_names, names,
+ &num_rids, &user_rid, &name_types);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ /* Open domain user */
+ result = cli_samr_open_user(cli, mem_ctx, &domain_pol,
+ MAXIMUM_ALLOWED_ACCESS, user_rid[0], &user_pol);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ /* Query user info */
+ result = cli_samr_query_userinfo(cli, mem_ctx, &user_pol,
+ info_level, &user_ctr);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ ctr.switch_value = info_level;
+ ctr.info.id7 = &info7;
+
+ init_sam_user_info7(&info7, new_name);
+
+ /* Set new name */
+ result = cli_samr_set_userinfo(cli, mem_ctx, &user_pol,
+ info_level, &cli->user_session_key, &ctr);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
+ done:
+ if (!NT_STATUS_IS_OK(result)) {
+ d_printf("Failed to rename user from %s to %s - %s\n", old_name, new_name,
+ nt_errstr(result));
+ } else {
+ d_printf("Renamed user from %s to %s\n", old_name, new_name);
+ }
+ return result;
+}
+
+
+/**
+ * Rename a user on a remote RPC server
+ *
+ * @param argc Standard main() style argc
+ * @param argv Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return A shell status integer (0 for success)
+ **/
+
+static int rpc_user_rename(int argc, const char **argv)
+{
+ return run_rpc_command(NULL, PI_SAMR, 0, rpc_user_rename_internals,
+ argc, argv);
+}
+
+/**
* Delete a user from a remote RPC server
*
* @param argc Standard main() style argc
@@ -1015,6 +1138,7 @@ int net_rpc_user(int argc, const char **argv)
{"info", rpc_user_info},
{"delete", rpc_user_delete},
{"password", rpc_user_password},
+ {"rename", rpc_user_rename},
{NULL, NULL}
};
@@ -4008,7 +4132,7 @@ static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid,
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- result = cli_reg_abort_shutdown(cli, mem_ctx);
+ result = werror_to_ntstatus(cli_reg_abort_shutdown(cli, mem_ctx));
if (NT_STATUS_IS_OK(result)) {
d_printf("\nShutdown successfully aborted\n");
@@ -4149,7 +4273,7 @@ static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
}
/* create an entry */
- result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force);
+ result = werror_to_ntstatus(cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force));
if (NT_STATUS_IS_OK(result)) {
d_printf("\nShutdown of remote machine succeeded\n");
@@ -4437,7 +4561,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
return -1;
}
- if (cli->nt_pipe_fnum)
+ if (cli->nt_pipe_fnum[cli->pipe_idx])
cli_nt_session_close(cli);
@@ -4504,7 +4628,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
return -1;
}
- if (cli->nt_pipe_fnum)
+ if (cli->nt_pipe_fnum[cli->pipe_idx])
cli_nt_session_close(cli);
talloc_destroy(mem_ctx);
@@ -5260,10 +5384,10 @@ int net_rpc_usage(int argc, const char **argv)
d_printf(" net rpc getsid \t\tfetch the domain sid into the local secrets.tdb\n");
d_printf(" net rpc vampire \t\tsyncronise an NT PDC's users and groups into the local passdb\n");
d_printf(" net rpc samdump \t\tdiplay an NT PDC's users, groups and other data\n");
- d_printf(" net rpc trustdom \t\tto create trusting domain's account\n"
- "\t\t\t\t\tor establish trust\n");
+ d_printf(" net rpc trustdom \t\tto create trusting domain's account or establish trust\n");
d_printf(" net rpc abortshutdown \tto abort the shutdown of a remote server\n");
d_printf(" net rpc shutdown \t\tto shutdown a remote server\n");
+ d_printf(" net rpc rights\t\tto manage privileges assigned to SIDs\n");
d_printf("\n");
d_printf("'net rpc shutdown' also accepts the following miscellaneous options:\n"); /* misc options */
d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n");
@@ -5332,6 +5456,7 @@ int net_rpc(int argc, const char **argv)
{"samdump", rpc_samdump},
{"vampire", rpc_vampire},
{"getsid", net_rpc_getsid},
+ {"rights", net_rpc_rights},
{"help", net_rpc_help},
{NULL, NULL}
};
diff --git a/source/utils/net_rpc_join.c b/source/utils/net_rpc_join.c
index 79c632f8314..f1a41c7c99c 100644
--- a/source/utils/net_rpc_join.c
+++ b/source/utils/net_rpc_join.c
@@ -78,7 +78,7 @@ static int net_rpc_join_ok(const char *domain)
done:
/* Close down pipe - this will clean up open policy handles */
- if (cli->nt_pipe_fnum)
+ if (cli->nt_pipe_fnum[cli->pipe_idx])
cli_nt_session_close(cli);
cli_shutdown(cli);
@@ -347,7 +347,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
done:
/* Close down pipe - this will clean up open policy handles */
- if (cli->nt_pipe_fnum)
+ if (cli->nt_pipe_fnum[cli->pipe_idx])
cli_nt_session_close(cli);
/* Display success or failure */
diff --git a/source/utils/net_rpc_rights.c b/source/utils/net_rpc_rights.c
new file mode 100644
index 00000000000..feb50b457a8
--- /dev/null
+++ b/source/utils/net_rpc_rights.c
@@ -0,0 +1,413 @@
+/*
+ Samba Unix/Linux SMB client library
+ Distributed SMB/CIFS Server Management Utility
+ Copyright (C) Gerald (Jerry) Carter 2004
+
+ 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"
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS sid_to_name(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ DOM_SID *sid, fstring name)
+{
+ POLICY_HND pol;
+ uint32 *sid_types;
+ NTSTATUS result;
+ char **domains, **names;
+
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
+
+ if ( !NT_STATUS_IS_OK(result) )
+ return result;
+
+ result = cli_lsa_lookup_sids(cli, mem_ctx, &pol, 1, sid, &domains, &names, &sid_types);
+
+ if ( NT_STATUS_IS_OK(result) ) {
+ if ( *domains[0] )
+ fstr_sprintf( name, "%s\\%s", domains[0], names[0] );
+ else
+ fstrcpy( name, names[0] );
+ }
+
+ cli_lsa_close(cli, mem_ctx, &pol);
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS name_to_sid(struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ DOM_SID *sid, const char *name)
+{
+ POLICY_HND pol;
+ uint32 *sid_types;
+ NTSTATUS result;
+ DOM_SID *sids;
+
+ /* maybe its a raw SID */
+ if ( strncmp(name, "S-", 2) == 0 && string_to_sid(sid, name) )
+ {
+ return NT_STATUS_OK;
+ }
+
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
+
+ if ( !NT_STATUS_IS_OK(result) )
+ return result;
+
+ result = cli_lsa_lookup_names(cli, mem_ctx, &pol, 1, &name, &sids, &sid_types);
+
+ if ( NT_STATUS_IS_OK(result) )
+ sid_copy( sid, &sids[0] );
+
+ cli_lsa_close(cli, mem_ctx, &pol);
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS enum_privileges( TALLOC_CTX *ctx, struct cli_state *cli,
+ POLICY_HND *pol )
+{
+ NTSTATUS result;
+ uint32 enum_context = 0;
+ uint32 pref_max_length=0x1000;
+ uint32 count=0;
+ char **privs_name;
+ uint32 *privs_high;
+ uint32 *privs_low;
+ int i;
+ uint16 lang_id=0;
+ uint16 lang_id_sys=0;
+ uint16 lang_id_desc;
+ fstring description;
+
+ result = cli_lsa_enum_privilege(cli, ctx, pol, &enum_context,
+ pref_max_length, &count, &privs_name, &privs_high, &privs_low);
+
+ if ( !NT_STATUS_IS_OK(result) )
+ return result;
+
+ /* Print results */
+
+ for (i = 0; i < count; i++) {
+ d_printf("%30s ", privs_name[i] ? privs_name[i] : "*unknown*" );
+
+ /* try to get the description */
+
+ if ( !NT_STATUS_IS_OK(cli_lsa_get_dispname(cli, ctx, pol,
+ privs_name[i], lang_id, lang_id_sys, description, &lang_id_desc)) )
+ {
+ d_printf("??????\n");
+ continue;
+ }
+
+ d_printf("%s\n", description );
+ }
+
+ return NT_STATUS_OK;
+
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS enum_privileges_for_user( TALLOC_CTX *ctx, struct cli_state *cli,
+ POLICY_HND *pol, DOM_SID *sid )
+{
+ NTSTATUS result;
+ uint32 count;
+ char **rights;
+ int i;
+
+ result = cli_lsa_enum_account_rights(cli, ctx, pol, sid, &count, &rights);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ if ( count == 0 )
+ d_printf("No privileges assigned\n");
+
+ for (i = 0; i < count; i++) {
+ printf("%s\n", rights[i]);
+ }
+
+ return NT_STATUS_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS enum_privileges_for_accounts( TALLOC_CTX *ctx, struct cli_state *cli,
+ POLICY_HND *pol )
+{
+ NTSTATUS result;
+ uint32 enum_context=0;
+ uint32 pref_max_length=0x1000;
+ DOM_SID *sids;
+ uint32 count=0;
+ int i;
+ fstring name;
+
+ result = cli_lsa_enum_sids(cli, ctx, pol, &enum_context,
+ pref_max_length, &count, &sids);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ for ( i=0; i<count; i++ ) {
+
+ /* try to convert the SID to a name. Fall back to
+ printing the raw SID if necessary */
+
+ result = sid_to_name( cli, ctx, &sids[i], name );
+ if ( !NT_STATUS_IS_OK (result) )
+ fstrcpy( name, sid_string_static(&sids[i]) );
+
+ d_printf("%s\n", name);
+
+ result = enum_privileges_for_user( ctx, cli, pol, &sids[i] );
+
+ if ( !NT_STATUS_IS_OK(result) )
+ return result;
+
+ d_printf("\n");
+ }
+
+ return NT_STATUS_OK;
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_rights_list_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ POLICY_HND pol;
+ NTSTATUS result;
+ DOM_SID sid;
+
+ result = cli_lsa_open_policy(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
+
+ if ( !NT_STATUS_IS_OK(result) )
+ return result;
+
+ switch (argc) {
+ case 0:
+ result = enum_privileges( mem_ctx, cli, &pol );
+ break;
+
+ case 1:
+ /* special case to enuemrate all privileged SIDs
+ with associated rights */
+
+ if ( strequal( argv[0], "accounts" ) ) {
+ result = enum_privileges_for_accounts( mem_ctx, cli, &pol );
+ }
+ else {
+
+ result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+ result = enum_privileges_for_user( mem_ctx, cli, &pol, &sid );
+ }
+ break;
+
+ default:
+ if ( argc > 1 ) {
+ d_printf("Usage: net rpc rights list [name|SID]\n");
+ result = NT_STATUS_OK;
+ }
+ }
+
+
+
+
+done:
+ cli_lsa_close(cli, mem_ctx, &pol);
+
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_rights_grant_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ POLICY_HND dom_pol;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ DOM_SID sid;
+
+ if (argc < 2 ) {
+ d_printf("Usage: net rpc rights grant <name|SID> <rights...>\n");
+ return NT_STATUS_OK;
+ }
+
+ result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &dom_pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ result = cli_lsa_add_account_rights(cli, mem_ctx, &dom_pol, sid,
+ argc-1, argv+1);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ d_printf("Successfully granted rights.\n");
+
+ done:
+ if ( !NT_STATUS_IS_OK(result) ) {
+ d_printf("Failed to grant privileges for %s (%s)\n",
+ argv[0], nt_errstr(result));
+ }
+
+ cli_lsa_close(cli, mem_ctx, &dom_pol);
+
+ return result;
+}
+
+/********************************************************************
+********************************************************************/
+
+static NTSTATUS rpc_rights_revoke_internal( const DOM_SID *domain_sid, const char *domain_name,
+ struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv )
+{
+ POLICY_HND dom_pol;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ DOM_SID sid;
+
+ if (argc < 2 ) {
+ d_printf("Usage: net rpc rights revoke <name|SID> <rights...>\n");
+ return NT_STATUS_OK;
+ }
+
+ result = name_to_sid(cli, mem_ctx, &sid, argv[0]);
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ result = cli_lsa_open_policy2(cli, mem_ctx, True,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &dom_pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ result = cli_lsa_remove_account_rights(cli, mem_ctx, &dom_pol, sid,
+ False, argc-1, argv+1);
+
+ if (!NT_STATUS_IS_OK(result))
+ goto done;
+
+ d_printf("Successfully revoked rights.\n");
+
+done:
+ if ( !NT_STATUS_IS_OK(result) ) {
+ d_printf("Failed to revoke privileges for %s (%s)",
+ argv[0], nt_errstr(result));
+ }
+
+ cli_lsa_close(cli, mem_ctx, &dom_pol);
+
+ return result;
+}
+
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_rights_list( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_LSARPC, 0,
+ rpc_rights_list_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_rights_grant( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_LSARPC, 0,
+ rpc_rights_grant_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int rpc_rights_revoke( int argc, const char **argv )
+{
+ return run_rpc_command( NULL, PI_LSARPC, 0,
+ rpc_rights_revoke_internal, argc, argv );
+}
+
+/********************************************************************
+********************************************************************/
+
+static int net_help_rights( int argc, const char **argv )
+{
+ d_printf("net rpc rights list [accounts|username] View available or assigned privileges\n");
+ d_printf("net rpc rights grant <name|SID> <right> Assign privilege[s]\n");
+ d_printf("net rpc rights revoke <name|SID> <right> Revoke privilege[s]\n");
+
+ d_printf("\nBoth 'grant' and 'revoke' require a SID and a list of privilege names.\n");
+ d_printf("For example\n");
+ d_printf("\n net rpc grant 'VALE\\biddle' SePrintOperatorPrivilege SeDiskOperatorPrivlege\n");
+ d_printf("\nwould grant the printer admin and disk manager rights to the user 'VALE\\biddle'\n\n");
+
+
+ return -1;
+}
+
+/********************************************************************
+********************************************************************/
+
+int net_rpc_rights(int argc, const char **argv)
+{
+ struct functable func[] = {
+ {"list", rpc_rights_list},
+ {"grant", rpc_rights_grant},
+ {"revoke", rpc_rights_revoke},
+ {NULL, NULL}
+ };
+
+ if ( argc )
+ return net_run_function( argc, argv, func, net_help_rights );
+
+ return net_help_rights( argc, argv );
+}
+
+
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index fccdc5f5ba5..320341ec050 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -445,6 +445,9 @@ sam_account_from_delta(SAM_ACCOUNT *account, SAM_ACCOUNT_INFO *delta)
stored_time = pdb_get_pass_last_set_time(account);
if (stored_time != unix_time)
pdb_set_pass_last_set_time(account, unix_time, PDB_CHANGED);
+ } else {
+ /* no last set time, make it now */
+ pdb_set_pass_last_set_time(account, time(NULL), PDB_CHANGED);
}
#if 0
@@ -1018,7 +1021,10 @@ static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta)
if (!account_policy_set(AP_RESET_COUNT_TIME, (uint32)u_lockoutreset/60))
return nt_status;
- if (!account_policy_set(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime/60))
+ if (u_lockouttime != -1)
+ u_lockouttime /= 60;
+
+ if (!account_policy_set(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime))
return nt_status;
if (!account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, delta->logon_chgpass))
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index ff08642f407..ea2faebdff4 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -64,7 +64,7 @@ static int export_database (struct pdb_context *in, struct pdb_context
DEBUG(3, ("called with username=\"%s\"\n", username));
- if (NT_STATUS_IS_ERR(in->pdb_setsampwent(in, 0))) {
+ if (NT_STATUS_IS_ERR(in->pdb_setsampwent(in, 0, 0))) {
fprintf(stderr, "Can't sampwent!\n");
return 1;
}
@@ -237,7 +237,7 @@ static int print_users_list (struct pdb_context *in, BOOL verbosity, BOOL smbpwd
SAM_ACCOUNT *sam_pwent=NULL;
BOOL check, ret;
- check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False));
+ check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False, 0));
if (!check) {
return 1;
}
@@ -266,7 +266,7 @@ static int fix_users_list (struct pdb_context *in)
SAM_ACCOUNT *sam_pwent=NULL;
BOOL check, ret;
- check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False));
+ check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False, 0));
if (!check) {
return 1;
}
diff --git a/source/utils/smbfilter.c b/source/utils/smbfilter.c
index 5d67c8fc7cf..3665647905d 100644
--- a/source/utils/smbfilter.c
+++ b/source/utils/smbfilter.c
@@ -34,7 +34,7 @@
static char *netbiosname;
static char packet[BUFFER_SIZE];
-static void save_file(const char *fname, void *packet, size_t length)
+static void save_file(const char *fname, void *ppacket, size_t length)
{
int fd;
fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644);
@@ -42,7 +42,7 @@ static void save_file(const char *fname, void *packet, size_t length)
perror(fname);
return;
}
- if (write(fd, packet, length) != length) {
+ if (write(fd, ppacket, length) != length) {
fprintf(stderr,"Failed to write %s\n", fname);
return;
}
diff --git a/source/utils/testprns.c b/source/utils/testprns.c
index 7e52b86afb6..1525ab11d0f 100644
--- a/source/utils/testprns.c
+++ b/source/utils/testprns.c
@@ -32,14 +32,17 @@
#include "includes.h"
+/*
+ * NOTE: this code is likely to be removed, and no longer supports
+ * checking against non-configured printcap files. -Rob
+ */
+
int main(int argc, char *argv[])
{
- const char *pszTemp;
-
setup_logging(argv[0],True);
- if (argc < 2 || argc > 3)
- printf("Usage: testprns printername [printcapfile]\n");
+ if (argc != 2)
+ printf("Usage: testprns printername\n");
else
{
dbf = x_fopen("test.log", O_WRONLY|O_CREAT|O_TRUNC, 0644);
@@ -47,10 +50,9 @@ int main(int argc, char *argv[])
printf("Unable to open logfile.\n");
} else {
DEBUGLEVEL = 3;
- pszTemp = (argc < 3) ? PRINTCAP_NAME : argv[2];
- printf("Looking for printer %s in printcap file %s\n",
- argv[1], pszTemp);
- if (!pcap_printername_ok(argv[1], pszTemp))
+ printf("Looking for printer %s\n", argv[1]);
+ load_printers();
+ if (!pcap_printername_ok(argv[1]))
printf("Printer name %s is not valid.\n", argv[1]);
else
printf("Printer name %s is valid.\n", argv[1]);
diff --git a/source/web/cgi.c b/source/web/cgi.c
index 937e603f8cd..5d52ad62793 100644
--- a/source/web/cgi.c
+++ b/source/web/cgi.c
@@ -30,12 +30,12 @@
extern void print_title(char *fmt, ...);
#endif
-struct var {
+struct cgi_var {
char *name;
char *value;
};
-static struct var variables[MAX_VARIABLES];
+static struct cgi_var variables[MAX_VARIABLES];
static int num_variables;
static int content_length;
static int request_post;