summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-01-26 21:06:48 +0000
committerGerald Carter <jerry@samba.org>2005-01-26 21:06:48 +0000
commitd9abdd45339e2d65445a1fd685cb0294729ac4e7 (patch)
treeef5e8cff95f9ffda2e7c29ff1790dd705c250fd7
parent4b3500c58d177e2b48e6e04e027efffd4d079d8a (diff)
downloadsamba-d9abdd45339e2d65445a1fd685cb0294729ac4e7.tar.gz
r5021: Starting to look at final code for 3.0.11rc1.
Set VERSION and merged important and/or low risk fixes from 3_0 svn merge -r4905:4907 $SVNURL/branches/SAMBA_3_0 svn merge -r4907:4913 $SVNURL/branches/SAMBA_3_0 svn merge -r4932:4933 $SVNURL/branches/SAMBA_3_0 svn merge -r4933:4946 $SVNURL/branches/SAMBA_3_0 svn merge -r4946:4963 $SVNURL/branches/SAMBA_3_0 svn merge -r4963:4964 $SVNURL/branches/SAMBA_3_0 svn merge -r4964:4965 $SVNURL/branches/SAMBA_3_0 svn merge -r4965:4966 $SVNURL/branches/SAMBA_3_0 svn merge -r4966:4967 $SVNURL/branches/SAMBA_3_0 svn merge -r4967:4970 $SVNURL/branches/SAMBA_3_0 svn merge -r4972:4976 $SVNURL/branches/SAMBA_3_0 svn merge -r4970:4972 $SVNURL/branches/SAMBA_3_0 svn merge -r4976:4988 $SVNURL/branches/SAMBA_3_0 svn merge -r4988:4989 $SVNURL/branches/SAMBA_3_0 svn merge -r4994:4995 $SVNURL/branches/SAMBA_3_0 svn merge -r4995:4996 $SVNURL/branches/SAMBA_3_0 svn merge -r5000:5002 $SVNURL/branches/SAMBA_3_0 svn merge -r5002:5012 $SVNURL/branches/SAMBA_3_0 svn merge -r5012:5014 $SVNURL/branches/SAMBA_3_0 svn merge -r5014:5015 $SVNURL/branches/SAMBA_3_0
-rw-r--r--examples/LDAP/samba.schema21
-rwxr-xr-xpackaging/Fedora/filter-requires-samba.sh3
-rwxr-xr-xpackaging/RedHat/filter-requires-samba_rh9.sh4
-rw-r--r--source/VERSION4
-rw-r--r--source/auth/auth_sam.c2
-rw-r--r--source/configure.in14
-rw-r--r--source/include/auth.h4
-rw-r--r--source/include/client.h1
-rw-r--r--source/include/libsmbclient.h6
-rw-r--r--source/include/rpc_netlogon.h3
-rw-r--r--source/include/rpc_secdes.h5
-rw-r--r--source/lib/privileges.c81
-rw-r--r--source/lib/smbldap.c3
-rw-r--r--source/libsmb/cliconnect.c8
-rw-r--r--source/libsmb/libsmbclient.c12
-rw-r--r--source/nsswitch/winbindd_cache.c2
-rw-r--r--source/passdb/passdb.c15
-rw-r--r--source/passdb/pdb_get_set.c2
-rw-r--r--source/passdb/pdb_interface.c1
-rw-r--r--source/printing/print_cups.c3
-rw-r--r--source/rpc_parse/parse_net.c45
-rw-r--r--source/rpc_server/srv_samr_nt.c743
-rw-r--r--source/rpcclient/cmd_lsarpc.c38
-rw-r--r--source/rpcclient/cmd_spoolss.c12
-rw-r--r--source/smbd/open.c2
-rw-r--r--source/smbd/oplock.c109
-rw-r--r--source/utils/net_help.c2
-rw-r--r--source/utils/net_idmap.c2
-rw-r--r--source/utils/net_rpc.c8
29 files changed, 700 insertions, 455 deletions
diff --git a/examples/LDAP/samba.schema b/examples/LDAP/samba.schema
index 7dc4de54b34..213aa34613f 100644
--- a/examples/LDAP/samba.schema
+++ b/examples/LDAP/samba.schema
@@ -376,13 +376,13 @@ attributetype ( 1.3.6.1.4.1.7165.2.1.46 NAME 'sambaStringListOption'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-attributetype ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaPrivName'
- SUP name )
+##attributetype ( 1.3.6.1.4.1.7165.2.1.50 NAME 'sambaPrivName'
+## SUP name )
-attributetype ( 1.3.6.1.4.1.7165.2.1.52 NAME 'sambaPrivilegeList'
- DESC 'Privileges List'
- EQUALITY caseIgnoreIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
+##attributetype ( 1.3.6.1.4.1.7165.2.1.52 NAME 'sambaPrivilegeList'
+## DESC 'Privileges List'
+## EQUALITY caseIgnoreIA5Match
+## SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{64} )
attributetype ( 1.3.6.1.4.1.7165.2.1.53 NAME 'sambaTrustFlags'
DESC 'Trust Password Flags'
@@ -473,8 +473,9 @@ objectclass ( 1.3.6.1.4.1.7165.2.2.12 NAME 'sambaConfigOption' SUP top STRUCTURA
sambaStringListoption $ description ) )
-objectclass ( 1.3.6.1.4.1.7165.2.2.13 NAME 'sambaPrivilege' SUP top AUXILIARY
- DESC 'Samba Privilege'
- MUST ( sambaSID )
- MAY ( sambaPrivilegeList ) )
+## retired during privilege rewrite
+##objectclass ( 1.3.6.1.4.1.7165.2.2.13 NAME 'sambaPrivilege' SUP top AUXILIARY
+## DESC 'Samba Privilege'
+## MUST ( sambaSID )
+## MAY ( sambaPrivilegeList ) )
diff --git a/packaging/Fedora/filter-requires-samba.sh b/packaging/Fedora/filter-requires-samba.sh
index 1ba10a0ee3d..5545cf6c858 100755
--- a/packaging/Fedora/filter-requires-samba.sh
+++ b/packaging/Fedora/filter-requires-samba.sh
@@ -1,3 +1,4 @@
#!/bin/sh
-/usr/lib/rpm/perl.req $* | grep -v "Net::LDAP"
+/usr/lib/rpm/perl.req $* | grep -E -v '(Net::LDAP|Crypt::SmbHash|CGI)'
+
diff --git a/packaging/RedHat/filter-requires-samba_rh9.sh b/packaging/RedHat/filter-requires-samba_rh9.sh
index 8378523bceb..5545cf6c858 100755
--- a/packaging/RedHat/filter-requires-samba_rh9.sh
+++ b/packaging/RedHat/filter-requires-samba_rh9.sh
@@ -1,2 +1,4 @@
#!/bin/sh
-/usr/lib/rpm/perl.req $* | egrep -v '(Net::LDAP|CGI)'
+
+/usr/lib/rpm/perl.req $* | grep -E -v '(Net::LDAP|Crypt::SmbHash|CGI)'
+
diff --git a/source/VERSION b/source/VERSION
index aad6252e56a..3784ff146c2 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=2
+SAMBA_VERSION_PRE_RELEASE=
########################################################
# For 'rc' releases the version will be #
@@ -39,7 +39,7 @@ SAMBA_VERSION_PRE_RELEASE=2
# e.g. SAMBA_VERSION_RC_RELEASE=1 #
# -> "3.0.0rc1" #
########################################################
-SAMBA_VERSION_RC_RELEASE=
+SAMBA_VERSION_RC_RELEASE=1
########################################################
# To mark SVN snapshots this should be set to 'yes' #
diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c
index 4d2fb230027..2633cc92c37 100644
--- a/source/auth/auth_sam.c
+++ b/source/auth/auth_sam.c
@@ -241,7 +241,7 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
unbecome_root();
if (ret == False) {
- DEBUG(3,("check_sam_security: Couldn't find user '%s' in passdb file.\n", user_info->internal_username.str));
+ DEBUG(3,("check_sam_security: Couldn't find user '%s' in passdb.\n", user_info->internal_username.str));
pdb_free_sam(&sampass);
return NT_STATUS_NO_SUCH_USER;
}
diff --git a/source/configure.in b/source/configure.in
index 330eed79f12..0dcfd9ab1e0 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -2655,7 +2655,7 @@ if test x"$with_ads_support" != x"no"; then
KRB5_LDFLAGS="-L$withval/lib"
FOUND_KRB5=yes
if test -x "$withval/bin/krb5-config"; then
- KRB5_CONFIG=$withval/bin/krb5-config
+ KRB5CONFIG=$withval/bin/krb5-config
fi
;;
esac ],
@@ -2665,17 +2665,17 @@ if test x"$with_ads_support" != x"no"; then
#################################################
# check for krb5-config from recent MIT and Heimdal kerberos 5
- AC_PATH_PROG(KRB5_CONFIG, krb5-config)
+ AC_PATH_PROG(KRB5CONFIG, krb5-config)
AC_MSG_CHECKING(for working krb5-config)
- if test -x "$KRB5_CONFIG"; then
+ if test -x "$KRB5CONFIG"; then
ac_save_CFLAGS=$CFLAGS
CFLAGS="";export CFLAGS
ac_save_LDFLAGS=$LDFLAGS
LDFLAGS="";export LDFLAGS
- KRB5_LIBS="`$KRB5_CONFIG --libs gssapi`"
- KRB5_LDFLAGS="`$KRB5_CONFIG --libs gssapi | sed s/-lgss.*//`"
- KRB5_CFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
- KRB5_CPPFLAGS="`$KRB5_CONFIG --cflags | sed s/@INCLUDE_des@//`"
+ KRB5_LIBS="`$KRB5CONFIG --libs gssapi`"
+ KRB5_LDFLAGS="`$KRB5CONFIG --libs gssapi | sed s/-lgss.*//`"
+ KRB5_CFLAGS="`$KRB5CONFIG --cflags | sed s/@INCLUDE_des@//`"
+ KRB5_CPPFLAGS="`$KRB5CONFIG --cflags | sed s/@INCLUDE_des@//`"
CFLAGS=$ac_save_CFLAGS;export CFLAGS
LDFLAGS=$ac_save_LDFLAGS;export LDFLAGS
FOUND_KRB5=yes
diff --git a/source/include/auth.h b/source/include/auth.h
index 188cf58643d..91751e71804 100644
--- a/source/include/auth.h
+++ b/source/include/auth.h
@@ -112,6 +112,10 @@ typedef struct auth_methods
const struct auth_usersupplied_info *user_info,
auth_serversupplied_info **server_info);
+ /* If you are using this interface, then you are probably
+ * getting something wrong. This interface is only for
+ * security=server, and makes a number of compromises to allow
+ * that. It is not compatible with being a PDC. */
DATA_BLOB (*get_chal)(const struct auth_context *auth_context,
void **my_private_data,
TALLOC_CTX *mem_ctx);
diff --git a/source/include/client.h b/source/include/client.h
index c182544362f..8ae8faf90dc 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -144,6 +144,7 @@ struct cli_state {
uint16 max_recv_frag;
BOOL use_kerberos;
+ BOOL fallback_after_kerberos;
BOOL use_spnego;
BOOL use_oplocks; /* should we use oplocks? */
diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h
index aaa19cb191b..efb04285a7f 100644
--- a/source/include/libsmbclient.h
+++ b/source/include/libsmbclient.h
@@ -455,9 +455,15 @@ struct _SMBCCTX {
* do _NOT_ touch this from your program !
*/
struct smbc_internal_data * internal;
+
+ int flags;
};
+/* Flags for SMBCCTX->flags */
+#define SMB_CTX_FLAG_USE_KERBEROS (1 << 0)
+#define SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS (1 << 1)
+#define SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON (1 << 2) /* don't try to do automatic anon login */
/**@ingroup misc
* Create a new SBMCCTX (a context).
diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h
index b865d05b340..3ba1ce6465b 100644
--- a/source/include/rpc_netlogon.h
+++ b/source/include/rpc_netlogon.h
@@ -190,9 +190,8 @@ typedef struct net_user_info_3
DOM_SID2 dom_sid; /* domain SID */
- uint32 num_other_groups; /* other groups */
- DOM_GID *other_gids; /* group info */
DOM_SID2 *other_sids; /* foreign/trusted domain SIDs */
+ uint32 *other_sids_attrib;
} NET_USER_INFO_3;
diff --git a/source/include/rpc_secdes.h b/source/include/rpc_secdes.h
index 56145ac024c..1279007220c 100644
--- a/source/include/rpc_secdes.h
+++ b/source/include/rpc_secdes.h
@@ -401,7 +401,10 @@ typedef struct standard_mapping {
#define GENERIC_RIGHTS_USER_WRITE \
(STANDARD_RIGHTS_WRITE_ACCESS | \
SA_RIGHT_USER_CHANGE_PASSWORD | \
- SA_RIGHT_USER_SET_LOC_COM) /* 0x00020044 */
+ SA_RIGHT_USER_SET_LOC_COM | \
+ SA_RIGHT_USER_SET_ATTRIBUTES | \
+ SA_RIGHT_USER_SET_PASSWORD | \
+ SA_RIGHT_USER_CHANGE_GROUP_MEM) /* 0x000204e4 */
#define GENERIC_RIGHTS_USER_EXECUTE \
(STANDARD_RIGHTS_EXECUTE_ACCESS | \
diff --git a/source/lib/privileges.c b/source/lib/privileges.c
index 628b2dd3251..4feb730feeb 100644
--- a/source/lib/privileges.c
+++ b/source/lib/privileges.c
@@ -114,7 +114,7 @@ BOOL se_priv_copy( SE_PRIV *dst, const SE_PRIV *src )
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 )
+void se_priv_add( SE_PRIV *mask, const SE_PRIV *addpriv )
{
int i;
@@ -128,7 +128,7 @@ static void se_priv_add( SE_PRIV *mask, const SE_PRIV *addpriv )
in mew_mask
****************************************************************************/
-static void se_priv_remove( SE_PRIV *mask, const SE_PRIV *removepriv )
+void se_priv_remove( SE_PRIV *mask, const SE_PRIV *removepriv )
{
int i;
@@ -159,6 +159,23 @@ static BOOL se_priv_equal( const SE_PRIV *mask1, const SE_PRIV *mask2 )
return ( memcmp(mask1, mask2, sizeof(SE_PRIV)) == 0 );
}
+/***************************************************************************
+ check if a SE_PRIV has any assigned privileges
+****************************************************************************/
+
+static BOOL se_priv_empty( const SE_PRIV *mask )
+{
+ SE_PRIV p1;
+ int i;
+
+ se_priv_copy( &p1, mask );
+
+ for ( i=0; i<SE_PRIV_MASKSIZE; i++ ) {
+ p1.mask[i] &= se_priv_all.mask[i];
+ }
+
+ return se_priv_equal( &p1, &se_priv_none );
+}
/***************************************************************************
dump an SE_PRIV structure to the log files
@@ -228,6 +245,9 @@ static BOOL set_privileges( const DOM_SID *sid, SE_PRIV *mask )
fstring keystr;
TDB_DATA key, data;
+ if ( !lp_enable_privileges() )
+ return False;
+
if ( !tdb )
return False;
@@ -249,13 +269,20 @@ static BOOL set_privileges( const DOM_SID *sid, SE_PRIV *mask )
check if the privilege is in the privilege list
****************************************************************************/
-static BOOL is_privilege_assigned( SE_PRIV *privileges, SE_PRIV *check )
+static BOOL is_privilege_assigned( SE_PRIV *privileges, const SE_PRIV *check )
{
SE_PRIV p1, p2;
if ( !privileges || !check )
return False;
+ /* everyone has privileges if you aren't checking for any */
+
+ if ( se_priv_empty( check ) ) {
+ DEBUG(1,("is_privilege_assigned: no privileges in check_mask!\n"));
+ return True;
+ }
+
se_priv_copy( &p1, check );
/* invert the SE_PRIV we want to check for and remove that from the
@@ -270,6 +297,39 @@ static BOOL is_privilege_assigned( SE_PRIV *privileges, SE_PRIV *check )
}
/****************************************************************************
+ check if the privilege is in the privilege list
+****************************************************************************/
+
+static BOOL is_any_privilege_assigned( SE_PRIV *privileges, const SE_PRIV *check )
+{
+ SE_PRIV p1, p2;
+
+ if ( !privileges || !check )
+ return False;
+
+ /* everyone has privileges if you aren't checking for any */
+
+ if ( se_priv_empty( check ) ) {
+ DEBUG(1,("is_any_privilege_assigned: no privileges in check_mask!\n"));
+ return True;
+ }
+
+ 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 );
+
+ /* see if we have any bits left */
+
+ return !se_priv_empty( &p2 );
+}
+
+/****************************************************************************
add a privilege to a privilege array
****************************************************************************/
@@ -630,7 +690,7 @@ NTSTATUS dup_luid_attr(TALLOC_CTX *mem_ctx, LUID_ATTR **new_la, LUID_ATTR *old_l
at a time here.
*****************************************************************************/
-BOOL user_has_privileges(NT_USER_TOKEN *token, SE_PRIV *privilege)
+BOOL user_has_privileges(NT_USER_TOKEN *token, const SE_PRIV *privilege)
{
if ( !token )
return False;
@@ -639,6 +699,19 @@ BOOL user_has_privileges(NT_USER_TOKEN *token, SE_PRIV *privilege)
}
/****************************************************************************
+ Does the user have any of the specified privileges ? We only deal with one privilege
+ at a time here.
+*****************************************************************************/
+
+BOOL user_has_any_privilege(NT_USER_TOKEN *token, const SE_PRIV *privilege)
+{
+ if ( !token )
+ return False;
+
+ return is_any_privilege_assigned( &token->privileges, privilege );
+}
+
+/****************************************************************************
Convert a LUID to a named string
****************************************************************************/
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index 7908bc254da..7aeecb89d6f 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -846,7 +846,8 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_
ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,
&ld_error);
DEBUG(ldap_state->num_failures ? 2 : 0,
- ("failed to bind to server with dn= %s Error: %s\n\t%s\n",
+ ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",
+ ldap_state->uri,
ldap_dn ? ldap_dn : "(unknown)", ldap_err2string(rc),
ld_error ? ld_error : "(unknown)"));
SAFE_FREE(ld_error);
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 29a9533bd24..78cf9028c68 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -757,13 +757,17 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
if (ret){
SAFE_FREE(principal);
DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
+ if (cli->fallback_after_kerberos)
+ goto ntlmssp;
return ADS_ERROR_KRB5(ret);
}
}
rc = cli_session_setup_kerberos(cli, principal, domain);
- SAFE_FREE(principal);
- return rc;
+ if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
+ SAFE_FREE(principal);
+ return rc;
+ }
}
#endif
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index df9c4ddcadc..8eeadc8a783 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -584,6 +584,13 @@ SMBCSRV *smbc_server(SMBCCTX *context,
return NULL;
}
+ if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) {
+ c.use_kerberos = True;
+ }
+ if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) {
+ c.fallback_after_kerberos = True;
+ }
+
c.timeout = context->timeout;
/* Force use of port 139 for first try, so browse lists can work */
@@ -648,8 +655,9 @@ SMBCSRV *smbc_server(SMBCCTX *context,
password, strlen(password),
password, strlen(password),
workgroup) &&
- /* try an anonymous login if it failed */
- !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) {
+ /* Try an anonymous login if it failed and this was allowed by flags. */
+ ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
+ !cli_session_setup(&c, "", "", 1,"", 0, workgroup))) {
cli_shutdown(&c);
errno = EPERM;
return NULL;
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index 460ce934cb7..3fc62df005f 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -1243,7 +1243,7 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
(*alias_rids) = TALLOC_ARRAY(mem_ctx, uint32, *num_aliases);
- if (!(*alias_rids))
+ if ((*num_aliases != 0) && ((*alias_rids) == NULL))
return NT_STATUS_NO_MEMORY;
for (i=0; i<(*num_aliases); i++)
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index 1f5e4be6cf6..c7cd59a4c5f 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -759,24 +759,11 @@ BOOL local_lookup_sid(const DOM_SID *sid, char *name, enum SID_NAME_USE *psid_na
DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid));
- if (rid == DOMAIN_USER_RID_ADMIN) {
- const char **admin_list = lp_admin_users(-1);
- *psid_name_use = SID_NAME_USER;
- if (admin_list) {
- const char *p = *admin_list;
- if(!next_token(&p, name, NULL, sizeof(fstring)))
- fstrcpy(name, "Administrator");
- } else {
- fstrcpy(name, "Administrator");
- }
- return True;
- }
+ /* see if the passdb can help us with the name of the user */
if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
return False;
}
-
- /* see if the passdb can help us with the name of the user */
/* BEING ROOT BLLOCK */
become_root();
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
index 92e2cee7100..4b59b5fdf95 100644
--- a/source/passdb/pdb_get_set.c
+++ b/source/passdb/pdb_get_set.c
@@ -514,7 +514,7 @@ BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum p
DEBUG(0,("Can't set flag: %d in set_flags.\n",element));
return False;
}
- DEBUG(10, ("element %d -> now SET\n", element));
+ DEBUG(11, ("element %d -> now SET\n", element));
break;
case PDB_DEFAULT:
default:
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index ea097c10f69..c8710097525 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -3,6 +3,7 @@
Password and authentication handling
Copyright (C) Andrew Bartlett 2002
Copyright (C) Jelmer Vernooij 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
diff --git a/source/printing/print_cups.c b/source/printing/print_cups.c
index 90af10c3736..59ab41b9f67 100644
--- a/source/printing/print_cups.c
+++ b/source/printing/print_cups.c
@@ -664,7 +664,6 @@ static int cups_job_submit(int snum, struct printjob *pjob)
httpClose(http);
return ret;
- return (ret);
}
/*
@@ -913,6 +912,8 @@ static int 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;
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index 5f1d4b622e3..b26083b89e9 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -1646,31 +1646,52 @@ BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps,
if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth)) /* domain SID */
return False;
- if (usr->num_other_sids) {
+ if (usr->buffer_other_sids) {
+
+ uint32 num_other_sids = usr->num_other_sids;
+
+ if (!prs_uint32("num_other_sids", ps, depth,
+ &num_other_sids))
+ return False;
+
+ if (num_other_sids != usr->num_other_sids)
+ return False;
if (UNMARSHALLING(ps)) {
usr->other_sids = PRS_ALLOC_MEM(ps, DOM_SID2, usr->num_other_sids);
- if (usr->other_sids == NULL)
+ usr->other_sids_attrib =
+ PRS_ALLOC_MEM(ps, uint32, usr->num_other_sids);
+
+ if ((num_other_sids != 0) &&
+ ((usr->other_sids == NULL) ||
+ (usr->other_sids_attrib == NULL)))
return False;
}
-
- if(!prs_uint32("num_other_groups", ps, depth, &usr->num_other_groups))
- return False;
- if (UNMARSHALLING(ps) && usr->num_other_groups > 0) {
- usr->other_gids = PRS_ALLOC_MEM(ps, DOM_GID, usr->num_other_groups);
- if (usr->other_gids == NULL)
+ /* First the pointers to the SIDS and attributes */
+
+ depth++;
+
+ for (i=0; i<usr->num_other_sids; i++) {
+ uint32 ptr = 1;
+
+ if (!prs_uint32("sid_ptr", ps, depth, &ptr))
return False;
- }
-
- for (i = 0; i < usr->num_other_groups; i++) {
- if(!smb_io_gid("", &usr->other_gids[i], ps, depth)) /* other GIDs */
+
+ if (UNMARSHALLING(ps) && (ptr == 0))
+ return False;
+
+ if (!prs_uint32("attribute", ps, depth,
+ &usr->other_sids_attrib[i]))
return False;
}
+
for (i = 0; i < usr->num_other_sids; i++) {
if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
return False;
}
+
+ depth--;
}
return True;
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index 462a6463293..ec52f55b4e3 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -68,31 +68,240 @@ struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_
struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
-static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
+/*******************************************************************
+ samr_make_dom_obj_sd
+ ********************************************************************/
+
+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, act_sid, domadmin_sid;
+ SEC_ACE ace[4];
+ SEC_ACCESS mask;
+ size_t i = 0;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+ /*basic access for every one*/
+ init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
+ 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[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, 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)
+ return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ samr_make_usr_obj_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, act_sid, domadmin_sid;
+ size_t i = 0;
+
+ SEC_ACE ace[5];
+ SEC_ACCESS mask;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ 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[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[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[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;
+
+ if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ samr_make_grp_obj_sd
+ ********************************************************************/
+
+static NTSTATUS samr_make_grp_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];
+ SEC_ACCESS mask;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+ /*basic access for every one*/
+ init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
+ init_sec_ace(&ace[0], &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_GROUP_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);
+
+ if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, 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)
+ return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ samr_make_ali_obj_sd
+ ********************************************************************/
+
+static NTSTATUS samr_make_ali_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];
+ SEC_ACCESS mask;
+
+ SEC_ACL *psa = NULL;
+
+ sid_copy(&adm_sid, &global_sid_Builtin);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&act_sid, &global_sid_Builtin);
+ sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
+
+ /*basic access for every one*/
+ init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
+ init_sec_ace(&ace[0], &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_ALIAS_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);
+
+ if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, 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)
+ return NT_STATUS_NO_MEMORY;
+
+ return NT_STATUS_OK;
+}
/*******************************************************************
Checks if access to an object should be granted, and returns that
level of access for further checks.
********************************************************************/
-static NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access,
- uint32 *acc_granted, const char *debug)
+static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
+ SE_PRIV *rights, uint32 rights_mask,
+ uint32 des_access, uint32 *acc_granted,
+ const char *debug )
{
NTSTATUS status = NT_STATUS_ACCESS_DENIED;
+ uint32 saved_mask = 0;
- if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
+ /* check privileges; certain SAM access bits should be overridden
+ by privileges (mostly having to do with creating/modifying/deleting
+ users and groups) */
+
+ if ( rights && user_has_any_privilege( token, rights ) ) {
+
+ saved_mask = (des_access & rights_mask);
+ des_access &= ~saved_mask;
+
+ DEBUG(4,("access_check_samr_object: user rights saved access mask [0x%x]\n",
+ saved_mask));
+ }
+
+
+ /* check the security descriptor first */
+
+ if ( se_access_check(psd, token, des_access, acc_granted, &status) )
+ goto done;
+
+ /* give root a free pass */
+
+ if ( geteuid() == sec_initial_uid() ) {
+
+ DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
+ DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
+
*acc_granted = des_access;
- if (geteuid() == sec_initial_uid()) {
- DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n",
- debug, des_access));
- DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
- status = NT_STATUS_OK;
- }
- else {
- DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
- debug, des_access));
- }
+
+ status = NT_STATUS_OK;
+ goto done;
}
+
+
+ DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n", debug, des_access));
+
+done:
+ /* add in any bits saved during the privilege check (only
+ matters is syayus is ok) */
+
+ *acc_granted |= saved_mask;
+
return status;
}
@@ -102,20 +311,29 @@ static NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_t
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));
- if ((acc_granted & acc_required) != acc_required) {
- if (geteuid() == sec_initial_uid()) {
- DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
- debug, acc_granted, acc_required));
- DEBUGADD(4,("but overwritten by euid == 0\n"));
- return NT_STATUS_OK;
- }
- DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
+ DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
+ debug, acc_granted, acc_required));
+
+ /* check the security descriptor first */
+
+ if ( (acc_granted&acc_required) == acc_required )
+ return NT_STATUS_OK;
+
+ /* give root a free pass */
+
+ if (geteuid() == sec_initial_uid()) {
+
+ DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
debug, acc_granted, acc_required));
- return NT_STATUS_ACCESS_DENIED;
+ DEBUGADD(4,("but overwritten by euid == 0\n"));
+
+ return NT_STATUS_OK;
}
- return NT_STATUS_OK;
+
+ DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
+ debug, acc_granted, acc_required));
+
+ return NT_STATUS_ACCESS_DENIED;
}
@@ -385,26 +603,35 @@ NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN
uint32 des_access = q_u->flags;
size_t sd_size;
NTSTATUS status;
+ SE_PRIV se_rights;
r_u->status = NT_STATUS_OK;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
+
+ if ( !find_policy_by_hnd(p, &q_u->pol, (void**)&info) )
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
+ status = access_check_samr_function( info->acc_granted,
+ SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_open_domain" );
+
+ if ( !NT_STATUS_IS_OK(status) )
return status;
- }
/*check if access can be granted as requested by client. */
- samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
- se_map_generic(&des_access,&dom_generic_mapping);
+
+ samr_make_dom_obj_sd( p->mem_ctx, &psd, &sd_size );
+ se_map_generic( &des_access, &dom_generic_mapping );
+
+ se_priv_copy( &se_rights, &se_machine_account );
+ se_priv_add( &se_rights, &se_add_users );
- if (!NT_STATUS_IS_OK(status =
- access_check_samr_object(psd, p->pipe_user.nt_user_token,
- des_access, &acc_granted, "_samr_open_domain"))) {
+ status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
+ &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
+ &acc_granted, "_samr_open_domain" );
+
+ if ( !NT_STATUS_IS_OK(status) )
return status;
- }
/* associate the domain SID with the (unique) handle. */
if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
@@ -449,187 +676,23 @@ NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u,
return r_u->status;
}
-/*******************************************************************
- samr_make_dom_obj_sd
- ********************************************************************/
-
-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, act_sid, domadmin_sid;
- SEC_ACE ace[4];
- SEC_ACCESS mask;
- size_t i = 0;
-
- SEC_ACL *psa = NULL;
-
- sid_copy(&adm_sid, &global_sid_Builtin);
- sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
-
- sid_copy(&act_sid, &global_sid_Builtin);
- sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
-
- /*basic access for every one*/
- init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
- 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[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, 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)
- return NT_STATUS_NO_MEMORY;
-
- return NT_STATUS_OK;
-}
/*******************************************************************
- samr_make_usr_obj_sd
+ _samr_set_sec_obj
********************************************************************/
-static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
+NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
{
- extern DOM_SID global_sid_World;
- DOM_SID adm_sid, act_sid, domadmin_sid;
- size_t i = 0;
-
- SEC_ACE ace[5];
- SEC_ACCESS mask;
-
- SEC_ACL *psa = NULL;
-
- sid_copy(&adm_sid, &global_sid_Builtin);
- sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
-
- sid_copy(&act_sid, &global_sid_Builtin);
- 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[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[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[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;
-
- if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- return NT_STATUS_OK;
+ DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
+ return NT_STATUS_NOT_IMPLEMENTED;
}
-/*******************************************************************
- samr_make_grp_obj_sd
- ********************************************************************/
-
-static NTSTATUS samr_make_grp_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];
- SEC_ACCESS mask;
-
- SEC_ACL *psa = NULL;
-
- sid_copy(&adm_sid, &global_sid_Builtin);
- sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
-
- sid_copy(&act_sid, &global_sid_Builtin);
- sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
-
- /*basic access for every one*/
- init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
- init_sec_ace(&ace[0], &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_GROUP_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);
-
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, 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)
- return NT_STATUS_NO_MEMORY;
-
- return NT_STATUS_OK;
-}
/*******************************************************************
- samr_make_ali_obj_sd
- ********************************************************************/
-
-static NTSTATUS samr_make_ali_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];
- SEC_ACCESS mask;
-
- SEC_ACL *psa = NULL;
-
- sid_copy(&adm_sid, &global_sid_Builtin);
- sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
-
- sid_copy(&act_sid, &global_sid_Builtin);
- sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
-
- /*basic access for every one*/
- init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
- init_sec_ace(&ace[0], &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_ALIAS_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);
-
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, 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)
- return NT_STATUS_NO_MEMORY;
-
- return NT_STATUS_OK;
-}
+********************************************************************/
-static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
+static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
+ DOM_SID *sid, uint32 *acc_granted)
{
struct samr_info *info = NULL;
@@ -646,17 +709,6 @@ static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *s
}
/*******************************************************************
- _samr_set_sec_obj
- ********************************************************************/
-
-NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
-{
- DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-
-/*******************************************************************
_samr_query_sec_obj
********************************************************************/
@@ -1646,34 +1698,45 @@ NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USE
size_t sd_size;
BOOL ret;
NTSTATUS nt_status;
+ SE_PRIV se_rights;
r_u->status = NT_STATUS_OK;
/* find the domain policy handle and get domain SID / access bits in the domain policy. */
- if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
+
+ if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
+ nt_status = access_check_samr_function( acc_granted,
+ SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" );
+
+ if ( !NT_STATUS_IS_OK(nt_status) )
return nt_status;
- }
nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
- if (!NT_STATUS_IS_OK(nt_status)) {
+
+ if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
- }
/* append the user's RID to it */
+
if (!sid_append_rid(&sid, q_u->user_rid))
return NT_STATUS_NO_SUCH_USER;
/* check if access can be granted as requested by client. */
+
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_open_user"))) {
+
+ se_priv_copy( &se_rights, &se_machine_account );
+ se_priv_add( &se_rights, &se_add_users );
+
+ nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
+ &acc_granted, "_samr_open_user");
+
+ if ( !NT_STATUS_IS_OK(nt_status) )
return nt_status;
- }
become_root();
ret=pdb_getsampwsid(sampass, &sid);
@@ -2354,7 +2417,8 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
se_map_generic(&des_access, &usr_generic_mapping);
nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
- des_access, &acc_granted, "_samr_create_user");
+ &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
+ &acc_granted, "_samr_create_user");
if ( !NT_STATUS_IS_OK(nt_status) ) {
return nt_status;
@@ -2452,11 +2516,12 @@ NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u
samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
se_map_generic(&des_access, &sam_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_connect"))) {
+
+ nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ NULL, 0, des_access, &acc_granted, "_samr_connect");
+
+ if ( !NT_STATUS_IS_OK(nt_status) )
return nt_status;
- }
r_u->status = NT_STATUS_OK;
@@ -2502,11 +2567,12 @@ NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *
samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
se_map_generic(&des_access, &sam_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_connect"))) {
+
+ nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ NULL, 0, des_access, &acc_granted, "_samr_connect4");
+
+ if ( !NT_STATUS_IS_OK(nt_status) )
return nt_status;
- }
r_u->status = NT_STATUS_OK;
@@ -2651,29 +2717,40 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
uint32 des_access = q_u->access_mask;
size_t sd_size;
NTSTATUS status;
+ SE_PRIV se_rights;
r_u->status = NT_STATUS_OK;
/* find the domain policy and get the SID / access bits stored in the domain policy */
- if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
+
+ if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
return NT_STATUS_INVALID_HANDLE;
+
+ status = access_check_samr_function(acc_granted,
+ SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
- if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
+ if ( !NT_STATUS_IS_OK(status) )
return status;
- }
/* append the alias' RID to it */
+
if (!sid_append_rid(&sid, alias_rid))
return NT_STATUS_NO_SUCH_USER;
/*check if access can be granted as requested by client. */
+
samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
se_map_generic(&des_access,&ali_generic_mapping);
- if (!NT_STATUS_IS_OK(status =
- access_check_samr_object(psd, p->pipe_user.nt_user_token,
- des_access, &acc_granted, "_samr_open_alias"))) {
+
+ se_priv_add( &se_rights, &se_add_users );
+
+
+ status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
+ &acc_granted, "_samr_open_alias");
+
+ if ( !NT_STATUS_IS_OK(status) )
return status;
- }
/*
* we should check if the rid really exist !!!
@@ -2697,20 +2774,8 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
set_user_info_10
********************************************************************/
-static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
+static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, SAM_ACCOUNT *pwd)
{
- SAM_ACCOUNT *pwd =NULL;
- BOOL ret;
-
- pdb_init_sam(&pwd);
-
- ret = pdb_getsampwsid(pwd, sid);
-
- if(ret==False) {
- pdb_free_sam(&pwd);
- return False;
- }
-
if (id10 == NULL) {
DEBUG(5, ("set_user_info_10: NULL id10\n"));
pdb_free_sam(&pwd);
@@ -2737,16 +2802,8 @@ static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
set_user_info_12
********************************************************************/
-static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
+static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, SAM_ACCOUNT *pwd)
{
- SAM_ACCOUNT *pwd = NULL;
-
- pdb_init_sam(&pwd);
-
- if(!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
- return False;
- }
if (id12 == NULL) {
DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
@@ -2816,22 +2873,13 @@ static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
set_user_info_20
********************************************************************/
-static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
+static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, SAM_ACCOUNT *pwd)
{
- SAM_ACCOUNT *pwd = NULL;
-
if (id20 == NULL) {
DEBUG(5, ("set_user_info_20: NULL id20\n"));
return False;
}
- pdb_init_sam(&pwd);
-
- if (!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
- return False;
- }
-
copy_id20_to_sam_passwd(pwd, id20);
/* write the change out */
@@ -2848,22 +2896,14 @@ static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
set_user_info_21
********************************************************************/
-static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
+static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
{
- SAM_ACCOUNT *pwd = NULL;
if (id21 == NULL) {
DEBUG(5, ("set_user_info_21: NULL id21\n"));
return False;
}
- pdb_init_sam(&pwd);
-
- if (!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
- return False;
- }
-
copy_id21_to_sam_passwd(pwd, id21);
/*
@@ -2891,9 +2931,8 @@ static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
set_user_info_23
********************************************************************/
-static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
+static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
{
- SAM_ACCOUNT *pwd = NULL;
pstring plaintext_buf;
uint32 len;
uint16 acct_ctrl;
@@ -2903,13 +2942,6 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
return False;
}
- pdb_init_sam(&pwd);
-
- if (!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
- return False;
- }
-
DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
pdb_get_username(pwd)));
@@ -2966,20 +2998,12 @@ static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
set_user_info_pw
********************************************************************/
-static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
+static BOOL set_user_info_pw(char *pass, SAM_ACCOUNT *pwd)
{
- SAM_ACCOUNT *pwd = NULL;
uint32 len;
pstring plaintext_buf;
uint16 acct_ctrl;
- pdb_init_sam(&pwd);
-
- if (!pdb_getsampwsid(pwd, sid)) {
- pdb_free_sam(&pwd);
- return False;
- }
-
DEBUG(5, ("Attempting administrator password change for user %s\n",
pdb_get_username(pwd)));
@@ -3038,14 +3062,16 @@ static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
{
+ SAM_ACCOUNT *pwd = NULL;
DOM_SID sid;
POLICY_HND *pol = &q_u->pol;
uint16 switch_value = q_u->switch_value;
SAM_USERINFO_CTR *ctr = q_u->ctr;
uint32 acc_granted;
uint32 acc_required;
- BOOL can_add_machines;
- SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
+ BOOL ret;
+ BOOL has_enough_rights;
+ SE_PRIV se_rights;
DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
@@ -3076,24 +3102,42 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
return NT_STATUS_INVALID_INFO_CLASS;
}
+
+ pdb_init_sam(&pwd);
+
+ become_root();
+ ret = pdb_getsampwsid(pwd, &sid);
+ unbecome_root();
+
+ if ( !ret ) {
+ pdb_free_sam(&pwd);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ /* deal with machine password changes differently from userinfo changes */
+
+ if ( pdb_get_acct_ctrl(pwd) & ACB_WSTRUST )
+ se_priv_copy( &se_rights, &se_machine_account );
+ else
+ se_priv_copy( &se_rights, &se_add_users );
- /* check to see if we are a domain admin */
+ /* check to see if we have the sufficient rights */
- can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
+ has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
- DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
- p->pipe_user_name, can_add_machines ? "" : " not"));
+ DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
+ p->pipe_user_name, has_enough_rights ? "" : " not"));
/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
- if ( can_add_machines )
- become_root();
-
+ if ( has_enough_rights )
+ 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))
+ case 18:
+ if (!set_user_info_12(ctr->info.id12, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
@@ -3105,7 +3149,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
dump_data(100, (char *)ctr->info.id24->pass, 516);
- if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
+ if (!set_user_info_pw((char *)ctr->info.id24->pass, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
@@ -3141,7 +3185,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
dump_data(100, (char *)ctr->info.id23->pass, 516);
- if (!set_user_info_23(ctr->info.id23, &sid))
+ if (!set_user_info_23(ctr->info.id23, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
@@ -3150,7 +3194,7 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
}
- if ( can_add_machines )
+ if ( has_enough_rights )
unbecome_root();
/* ================ END SeMachineAccountPrivilege BLOCK ================ */
@@ -3164,14 +3208,16 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
{
+ SAM_ACCOUNT *pwd = NULL;
DOM_SID sid;
SAM_USERINFO_CTR *ctr = q_u->ctr;
POLICY_HND *pol = &q_u->pol;
uint16 switch_value = q_u->switch_value;
uint32 acc_granted;
uint32 acc_required;
- BOOL can_add_machines;
- SE_PRIV se_machineop = SE_MACHINE_ACCOUNT;
+ BOOL ret;
+ BOOL has_enough_rights;
+ SE_PRIV se_rights;
DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
@@ -3195,43 +3241,61 @@ 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 */
+ pdb_init_sam(&pwd);
- can_add_machines = user_has_privileges( p->pipe_user.nt_user_token, &se_machineop );
+ become_root();
+ ret = pdb_getsampwsid(pwd, &sid);
+ unbecome_root();
- DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
- p->pipe_user_name, can_add_machines ? "" : " not"));
+ if ( !ret ) {
+ pdb_free_sam(&pwd);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ /* deal with machine password changes differently from userinfo changes */
+
+ if ( pdb_get_acct_ctrl(pwd) & ACB_WSTRUST )
+ se_priv_copy( &se_rights, &se_machine_account );
+ else
+ se_priv_copy( &se_rights, &se_add_users );
+
+ /* check to see if we have the sufficient rights */
+
+ has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
+
+ DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
+ p->pipe_user_name, has_enough_rights ? "" : " not"));
/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
- if ( can_add_machines )
- become_root();
-
+ if ( has_enough_rights )
+ 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))
+ if (!set_user_info_21(ctr->info.id21, pwd))
return NT_STATUS_ACCESS_DENIED;
break;
case 20:
- if (!set_user_info_20(ctr->info.id20, &sid))
+ if (!set_user_info_20(ctr->info.id20, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
case 16:
- if (!set_user_info_10(ctr->info.id10, &sid))
+ if (!set_user_info_10(ctr->info.id10, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
case 18:
/* Used by AS/U JRA. */
- if (!set_user_info_12(ctr->info.id12, &sid))
+ if (!set_user_info_12(ctr->info.id12, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
default:
r_u->status = NT_STATUS_INVALID_INFO_CLASS;
}
- if ( can_add_machines )
+ if ( has_enough_rights )
unbecome_root();
/* ================ END SeMachineAccountPrivilege BLOCK ================ */
@@ -4371,25 +4435,32 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G
NTSTATUS status;
fstring sid_string;
BOOL ret;
+ SE_PRIV se_rights;
if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
return NT_STATUS_INVALID_HANDLE;
- if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
+ status = access_check_samr_function(acc_granted,
+ SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group");
+
+ if ( !NT_STATUS_IS_OK(status) )
return status;
- }
/*check if access can be granted as requested by client. */
samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
se_map_generic(&des_access,&grp_generic_mapping);
- if (!NT_STATUS_IS_OK(status =
- access_check_samr_object(psd, p->pipe_user.nt_user_token,
- des_access, &acc_granted, "_samr_open_group"))) {
- return status;
- }
+ se_priv_copy( &se_rights, &se_add_users );
+
+ status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
+ &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
+ &acc_granted, "_samr_open_group");
+
+ if ( !NT_STATUS_IS_OK(status) )
+ return status;
/* this should not be hard-coded like this */
+
if (!sid_equal(&sid, get_global_sam_sid()))
return NT_STATUS_ACCESS_DENIED;
diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c
index 7d60749ae2f..597c950a241 100644
--- a/source/rpcclient/cmd_lsarpc.c
+++ b/source/rpcclient/cmd_lsarpc.c
@@ -278,23 +278,29 @@ static NTSTATUS cmd_lsa_enum_trust_dom(struct cli_state *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
- /* Lookup list of trusted domains */
-
- result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
- &num_domains,
- &domain_names, &domain_sids);
- if (!NT_STATUS_IS_OK(result) &&
- !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
- !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
- goto done;
-
- /* Print results: list of names and sids returned in this response. */
- for (i = 0; i < num_domains; i++) {
- fstring sid_str;
+ result = STATUS_MORE_ENTRIES;
+
+ while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
- sid_to_string(sid_str, &domain_sids[i]);
- printf("%s %s\n", domain_names[i] ? domain_names[i] :
- "*unknown*", sid_str);
+ /* Lookup list of trusted domains */
+
+ result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx,
+ &num_domains,
+ &domain_names, &domain_sids);
+ if (!NT_STATUS_IS_OK(result) &&
+ !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
+ !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
+ goto done;
+
+ /* Print results: list of names and sids returned in this
+ * response. */
+ for (i = 0; i < num_domains; i++) {
+ fstring sid_str;
+
+ sid_to_string(sid_str, &domain_sids[i]);
+ printf("%s %s\n", domain_names[i] ? domain_names[i] :
+ "*unknown*", sid_str);
+ }
}
done:
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
index 0b0d015238e..fa77af4145d 100644
--- a/source/rpcclient/cmd_spoolss.c
+++ b/source/rpcclient/cmd_spoolss.c
@@ -31,6 +31,13 @@ struct table_node {
int version;
};
+/* The version int is used by getdrivers. Note that
+ all architecture strings that support mutliple
+ versions must be grouped together since enumdrivers
+ uses this property to prevent issuing multiple
+ enumdriver calls for the same arch */
+
+
static const struct table_node archi_table[]= {
{"Windows 4.0", "WIN40", 0 },
@@ -1134,6 +1141,11 @@ static WERROR cmd_spoolss_enum_drivers(struct cli_state *cli,
{
uint32 needed;
+ /* check to see if we already asked for this architecture string */
+
+ if ( i>0 && strequal(archi_table[i].long_archi, archi_table[i-1].long_archi) )
+ continue;
+
werror = cli_spoolss_enumprinterdrivers(
cli, mem_ctx, 0, &needed, info_level,
archi_table[i].long_archi, &returned, &ctr);
diff --git a/source/smbd/open.c b/source/smbd/open.c
index bf3fbf7fecd..70632a20eb7 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -665,7 +665,7 @@ dev = %x, inode = %.0f\n", *p_oplock_request, share_entry->op_type, fname, (unsi
/* Oplock break - unlock to request it. */
unlock_share_entry(conn, dev, inode);
- opb_ret = request_oplock_break(share_entry, False);
+ opb_ret = request_oplock_break(share_entry);
/* Now relock. */
lock_share_entry(conn, dev, inode);
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index 3ebf93e5608..a55d5443d56 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -598,13 +598,13 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, un
/****************************************************************************
Process a level II oplock break directly.
+ We must call this function with the share mode entry locked.
****************************************************************************/
-BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token)
+static BOOL oplock_break_level2(files_struct *fsp, BOOL local_request)
{
extern uint32 global_client_caps;
char outbuf[128];
- BOOL got_lock = False;
SMB_DEV_T dev = fsp->dev;
SMB_INO_T inode = fsp->inode;
@@ -644,25 +644,16 @@ BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token)
/*
* Now we must update the shared memory structure to tell
* everyone else we no longer have a level II oplock on
- * this open file. If local_request is true then token is
- * the existing lock on the shared memory area.
+ * this open file. We must call this function with the share mode
+ * entry locked so we can change the entry directly.
*/
- if(!local_request && lock_share_entry_fsp(fsp) == False) {
- DEBUG(0,("oplock_break_level2: unable to lock share entry for file %s\n", fsp->fsp_name ));
- } else {
- got_lock = True;
- }
-
if(remove_share_oplock(fsp)==False) {
DEBUG(0,("oplock_break_level2: unable to remove level II oplock for file %s\n", fsp->fsp_name ));
}
release_file_oplock(fsp);
- if (!local_request && got_lock)
- unlock_share_entry_fsp(fsp);
-
if(level_II_oplocks_open < 0) {
DEBUG(0,("oplock_break_level2: level_II_oplocks_open < 0 (%d). PANIC ERROR\n",
level_II_oplocks_open));
@@ -680,6 +671,7 @@ BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token)
/****************************************************************************
Process an oplock break directly.
+ This is always called with the share mode lock *NOT* held.
****************************************************************************/
static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id, BOOL local_request)
@@ -708,8 +700,18 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
* Deal with a level II oplock going break to none separately.
*/
- if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
- return oplock_break_level2(fsp, local_request, -1);
+ if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
+ BOOL ret;
+ /* We must always call oplock_break_level2() with
+ the share mode entry locked. */
+ if (lock_share_entry_fsp(fsp) == False) {
+ DEBUG(0,("oplock_break: unable to lock share entry for file %s\n", fsp->fsp_name ));
+ return False;
+ }
+ ret = oplock_break_level2(fsp, local_request);
+ unlock_share_entry_fsp(fsp);
+ return ret;
+ }
/* Mark the oplock break as sent - we don't want to send twice! */
if (fsp->sent_oplock_break) {
@@ -942,11 +944,12 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id,
}
/****************************************************************************
-Send an oplock break message to another smbd process. If the oplock is held
-by the local smbd then call the oplock break function directly.
+ Send an oplock break message to another smbd process. If the oplock is held
+ by the local smbd then call the oplock break function directly.
+ This function is called with no share locks held.
****************************************************************************/
-BOOL request_oplock_break(share_mode_entry *share_entry, BOOL async)
+BOOL request_oplock_break(share_mode_entry *share_entry)
{
char op_break_msg[OPLOCK_BREAK_MSG_LEN];
struct sockaddr_in addr_out;
@@ -987,7 +990,7 @@ dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n",
/* We need to send a OPLOCK_BREAK_CMD message to the port in the share mode entry. */
if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- break_cmd_type = async ? ASYNC_LEVEL_II_OPLOCK_BREAK_CMD : LEVEL_II_OPLOCK_BREAK_CMD;
+ break_cmd_type = LEVEL_II_OPLOCK_BREAK_CMD;
} else {
break_cmd_type = OPLOCK_BREAK_CMD;
}
@@ -1005,7 +1008,7 @@ dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n",
addr_out.sin_family = AF_INET;
if( DEBUGLVL( 3 ) ) {
- dbgtext( "request_oplock_break: sending a %s oplock break message to ", async ? "asynchronous" : "synchronous" );
+ dbgtext( "request_oplock_break: sending a synchronous oplock break message to " );
dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
(unsigned int)dev, (double)inode, file_id );
@@ -1025,16 +1028,6 @@ dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n",
}
/*
- * If we just sent a message to a level II oplock share entry in async mode then
- * we are done and may return.
- */
-
- if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type) && async) {
- DEBUG(3,("request_oplock_break: sent async break message to level II entry.\n"));
- return True;
- }
-
- /*
* Now we must await the oplock broken message coming back
* from the target smbd process. Timeout if it fails to
* return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
@@ -1147,6 +1140,57 @@ BOOL attempt_close_oplocked_file(files_struct *fsp)
}
/****************************************************************************
+ Send an asynchronous oplock break message to another smbd process.
+****************************************************************************/
+
+static BOOL request_remote_level2_async_oplock_break(share_mode_entry *share_entry)
+{
+ char op_break_msg[OPLOCK_BREAK_MSG_LEN];
+ struct sockaddr_in addr_out;
+ pid_t pid = sys_getpid();
+ SMB_DEV_T dev = share_entry->dev;
+ SMB_INO_T inode = share_entry->inode;
+ unsigned long file_id = share_entry->share_file_id;
+
+ /* We need to send a ASYNC_LEVEL_II_OPLOCK_BREAK_CMD message to the port in the share mode entry. */
+
+ SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,ASYNC_LEVEL_II_OPLOCK_BREAK_CMD);
+ memcpy(op_break_msg+OPLOCK_BREAK_PID_OFFSET,(char *)&pid,sizeof(pid));
+ memcpy(op_break_msg+OPLOCK_BREAK_DEV_OFFSET,(char *)&dev,sizeof(dev));
+ memcpy(op_break_msg+OPLOCK_BREAK_INODE_OFFSET,(char *)&inode,sizeof(inode));
+ memcpy(op_break_msg+OPLOCK_BREAK_FILEID_OFFSET,(char *)&file_id,sizeof(file_id));
+
+ /* Set the address and port. */
+ memset((char *)&addr_out,'\0',sizeof(addr_out));
+ addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ addr_out.sin_port = htons( share_entry->op_port );
+ addr_out.sin_family = AF_INET;
+
+ if( DEBUGLVL( 3 ) ) {
+ dbgtext( "request_remote_level2_async_oplock_break: sending an asynchronous oplock break message to ");
+ dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
+ (unsigned int)dev, (double)inode, file_id );
+ }
+
+ if(sys_sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
+ (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0) {
+ if( DEBUGLVL( 0 ) ) {
+ dbgtext( "request_remote_level2_async_oplock_break: failed when sending a oplock " );
+ dbgtext( "break message to pid %d ", (int)share_entry->pid );
+ dbgtext( "on port %d ", share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f, file_id = %lu\n",
+ (unsigned int)dev, (double)inode, file_id );
+ dbgtext( "Error was %s\n", strerror(errno) );
+ }
+ return False;
+ }
+
+ DEBUG(3,("request_remote_level2_async_oplock_break: sent async break message to level II entry.\n"));
+ return True;
+}
+
+/****************************************************************************
This function is called on any file modification or lock request. If a file
is level 2 oplocked then it must tell all other level 2 holders to break to none.
****************************************************************************/
@@ -1155,7 +1199,6 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
{
share_mode_entry *share_list = NULL;
pid_t pid = sys_getpid();
- int token = -1;
int num_share_modes = 0;
int i;
@@ -1222,7 +1265,7 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
DEBUG(10,("release_level_2_oplocks_on_change: breaking our own oplock.\n"));
- oplock_break_level2(new_fsp, True, token);
+ oplock_break_level2(new_fsp, True);
} else {
@@ -1232,7 +1275,7 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
*/
DEBUG(10,("release_level_2_oplocks_on_change: breaking remote oplock (async).\n"));
- request_oplock_break(share_entry, True);
+ request_remote_level2_async_oplock_break(share_entry);
}
}
diff --git a/source/utils/net_help.c b/source/utils/net_help.c
index 328e1344591..60206429b7e 100644
--- a/source/utils/net_help.c
+++ b/source/utils/net_help.c
@@ -132,7 +132,7 @@ int net_help_share(int argc, const char **argv)
"[misc. options] [targets]"
"\n\tshows a list of all shares together with all users allowed to"
"\n\taccess them. This needs the output of 'net usersidlist' on"
- "\n\tstdin or in <filename>.\n"
+ "\n\tstdin or in <filename>.\n\n"
"net [<method>] share MIGRATE FILES <sharename> [misc. options] [targets]"
"\n\tMigrates files from remote to local server\n\n"
"net [<method>] share MIGRATE SHARES <sharename> [misc. options] [targets]"
diff --git a/source/utils/net_idmap.c b/source/utils/net_idmap.c
index f7ebd94f346..7abb31ab3d9 100644
--- a/source/utils/net_idmap.c
+++ b/source/utils/net_idmap.c
@@ -288,7 +288,7 @@ static int net_idmap_delete(int argc, const char **argv)
int net_help_idmap(int argc, const char **argv)
{
- d_printf("net idmap dump filename"\
+ d_printf("net idmap dump <tdbfile>"\
"\n Dump current id mapping\n");
d_printf("net idmap restore"\
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index 430649d81bb..76b53d61136 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -404,7 +404,7 @@ rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name,
TALLOC_CTX *ctx = talloc_init("rpc_info_internals");
d_printf("Domain Name: %s\n", unistr2_tdup(ctx, &ctr.info.inf2.uni_domain));
d_printf("Domain SID: %s\n", sid_str);
- d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num);
+ d_printf("Sequence number: %u\n", ctr.info.inf2.seq_num.low);
d_printf("Num users: %u\n", ctr.info.inf2.num_domain_usrs);
d_printf("Num domain groups: %u\n", ctr.info.inf2.num_domain_grps);
d_printf("Num local groups: %u\n", ctr.info.inf2.num_local_grps);
@@ -1428,7 +1428,7 @@ rpc_alias_add_internals(const DOM_SID *domain_sid, const char *domain_name,
ALIAS_INFO_CTR alias_info;
if (argc != 1) {
- d_printf("Group name must be specified\n");
+ d_printf("Alias name must be specified\n");
rpc_group_usage(argc, argv);
return NT_STATUS_OK;
}
@@ -1465,9 +1465,9 @@ rpc_alias_add_internals(const DOM_SID *domain_sid, const char *domain_name,
done:
if (NT_STATUS_IS_OK(result))
- DEBUG(5, ("add group succeeded\n"));
+ DEBUG(5, ("add alias succeeded\n"));
else
- d_printf("add group failed: %s\n", nt_errstr(result));
+ d_printf("add alias failed: %s\n", nt_errstr(result));
return result;
}