summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-08-02 02:11:55 +0000
committerJeremy Allison <jra@samba.org>2000-08-02 02:11:55 +0000
commit17dcd9a834fc915fb1ff2d8042a23000eeb7acfa (patch)
tree18a9a8cfa2883baf163da29265fd08b8a3b81c9f
parent7f36df301e28dc8ca0e5bfadc109d6e907d9ba2b (diff)
downloadsamba-17dcd9a834fc915fb1ff2d8042a23000eeb7acfa.tar.gz
samba-17dcd9a834fc915fb1ff2d8042a23000eeb7acfa.tar.bz2
samba-17dcd9a834fc915fb1ff2d8042a23000eeb7acfa.zip
Started to canonicalize our handling of uid -> sid code in order to
get ready and fix se_access_check(). Added cannonical lookup_name(), lookup_sid(), uid_to_sid(), gid_to_sid() functions that look via winbind first the fall back on local lookup. All Samba should use these rather than trying to call winbindd code directly. Added NT_USER_TOKEN struct in user_struct, contains list of NT sids associated with this user. se_access_check() should use this (cached) value rather than attempting to do the same thing itself when given a uid/gid pair. More work needs to be done to preserve these things accross security context changes (especially with the tricky pipe problem) but I'm beginning to see how this will be done..... probably by registering a new vuid for an authenticated RPC pipe and not treating the pipe calls specially. More thoughts needed - but we're almost there... Jeremy. (This used to be commit 5e5cc6efe2e4687be59085f562caea1e2e05d0a8)
-rw-r--r--source3/include/proto.h20
-rw-r--r--source3/include/smb.h20
-rw-r--r--source3/lib/util_seaccess.c46
-rw-r--r--source3/nsswitch/wb_client.c106
-rw-r--r--source3/passdb/passdb.c86
-rw-r--r--source3/rpc_server/srv_lsa.c2
-rw-r--r--source3/rpc_server/srv_samr.c4
-rw-r--r--source3/smbd/password.c113
-rw-r--r--source3/smbd/process.c3
-rw-r--r--source3/smbd/sec_ctx.c34
-rw-r--r--source3/smbd/service.c4
-rw-r--r--source3/smbd/uid.c23
-rw-r--r--source3/smbd/unix_acls.c8
13 files changed, 251 insertions, 218 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 85ea676736..321f3098e9 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1278,8 +1278,12 @@ void expire_workgroups_and_servers(time_t t);
BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type);
BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
uint8 *name_type);
-BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid);
-BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid);
+BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid);
+BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid);
+BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type);
+BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type);
+DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid);
+DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid);
/*The following definitions come from nsswitch/wb_common.c */
@@ -1622,9 +1626,10 @@ gid_t pdb_user_rid_to_gid(uint32 user_rid);
uint32 pdb_uid_to_user_rid(uid_t uid);
uint32 pdb_gid_to_group_rid(gid_t gid);
BOOL pdb_rid_is_user(uint32 rid);
-BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use);
-BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use);
-BOOL setup_user_sids(user_struct *vuser);
+BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use);
+BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use);
+DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid);
+DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid);
/*The following definitions come from passdb/secrets.c */
@@ -3540,8 +3545,8 @@ user_struct *get_valid_user_struct(uint16 vuid);
void invalidate_vuid(uint16 vuid);
char *validated_username(uint16 vuid);
char *validated_domain(uint16 vuid);
-int setup_groups(char *user, char *domain,
- uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups);
+int initialize_groups(char *user, uid_t uid, gid_t gid);
+void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups);
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
char *domain,BOOL guest);
void add_session_user(char *user);
@@ -3667,6 +3672,7 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
/*The following definitions come from smbd/sec_ctx.c */
+int get_current_groups(int *p_ngroups, gid_t **p_groups);
BOOL push_sec_ctx(void);
void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups);
void set_root_sec_ctx(void);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index bc9f17544c..aaebe56f33 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -399,6 +399,15 @@ typedef struct sid_info
} DOM_SID;
+/*
+ * The complete list of SIDS belonging to this user.
+ * Created when a vuid is registered.
+ */
+
+typedef struct _nt_user_token {
+ size_t num_sids;
+ DOM_SID *user_sids;
+} NT_USER_TOKEN;
/*** query a local group, get a list of these: shows who is in that group ***/
@@ -556,8 +565,8 @@ typedef struct connection_struct
char *connectpath;
char *origpath;
- struct vfs_ops vfs_ops; /* Filesystem operations */
- struct vfs_connection_struct *vfs_conn; /* VFS specific connection stuff */
+ struct vfs_ops vfs_ops; /* Filesystem operations */
+ struct vfs_connection_struct *vfs_conn; /* VFS specific connection stuff */
char *user; /* name of user who *opened* this connection */
uid_t uid; /* uid of user who *opened* this connection */
@@ -1663,12 +1672,7 @@ typedef struct
int n_groups;
gid_t *groups;
-#if 0
- NET_USER_INFO_3 usr; /* This should not be here. */
-#else
- DOM_SID user_sid;
- DOM_SID *group_sids;
-#endif
+ NT_USER_TOKEN nt_user_token;
/* per-user authentication information on NT RPCs */
/* lkclXXXX - THIS SHOULD NOT BE HERE! */
diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c
index 05a7a30635..52696d2d30 100644
--- a/source3/lib/util_seaccess.c
+++ b/source3/lib/util_seaccess.c
@@ -99,12 +99,12 @@ static BOOL check_ace(SEC_ACE *ace, BOOL is_owner, DOM_SID *sid,
sid_to_string(sid_str, sid);
sid_to_string(ace_sid_str, &ace->sid);
- if (!winbind_lookup_sid(sid, name_dom, name, &name_type)) {
+ if (!lookup_sid(sid, name_dom, name, &name_type)) {
fstrcpy(name_dom, "UNKNOWN");
fstrcpy(name, "UNKNOWN");
}
- if (!winbind_lookup_sid(&ace->sid, ace_name_dom, ace_name,
+ if (!lookup_sid(&ace->sid, ace_name_dom, ace_name,
&name_type)) {
fstrcpy(ace_name_dom, "UNKNOWN");
fstrcpy(ace_name, "UNKNOWN");
@@ -208,6 +208,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
uint32 acc_desired, uint32 *acc_granted, uint32 *status)
{
DOM_SID user_sid, group_sid;
+ DOM_SID owner_sid;
DOM_SID **group_sids = NULL;
int i, j;
uint ngroup_sids = 0;
@@ -215,25 +216,30 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
uint8 check_ace_type;
fstring sid_str;
- if (!status || !acc_granted) return False;
+ if (!status || !acc_granted)
+ return False;
*status = NT_STATUS_ACCESS_DENIED;
*acc_granted = 0;
- /* No security descriptor allows all access */
+ /*
+ * No security descriptor or security descriptor with no DACL
+ * present allows all access.
+ */
- if (!sd) {
+ if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) {
*status = NT_STATUS_NOPROBLEMO;
*acc_granted = acc_desired;
acc_desired = 0;
- DEBUG(3, ("no sd, access allowed\n"));
-
- goto done;
+ DEBUG(3, ("se_access_check: no sd or blank DACL, access allowed\n"));
+ goto done;
}
/* If desired access mask is empty then no access is allowed */
if (acc_desired == 0) {
+ *status = NT_STATUS_ACCESS_DENIED;
+ *acc_granted = 0;
goto done;
}
@@ -246,12 +252,12 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
/* Create user sid */
- if (!winbind_uid_to_sid(user->uid, &user_sid)) {
+ if (!uid_to_sid(&user_sid, user->uid)) {
DEBUG(3, ("could not lookup sid for uid %d\n", user->uid));
+ goto done;
}
- sid_to_string(sid_str, &user_sid);
- DEBUG(3, ("user sid is %s\n", sid_str));
+ DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &user_sid) ));
/* If we're the owner, then we can do anything */
@@ -266,8 +272,9 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
/* Create group sid */
- if (!winbind_gid_to_sid(user->gid, &group_sid)) {
+ if (!gid_to_sid(&group_sid, user->gid)) {
DEBUG(3, ("could not lookup sid for gid %d\n", user->gid));
+ goto done;
}
sid_to_string(sid_str, &group_sid);
@@ -279,7 +286,7 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
for (i = 0; i < user->ngroups; i++) {
if (user->groups[i] != user->gid) {
- if (winbind_gid_to_sid(user->groups[i], &group_sid)) {
+ if (gid_to_sid(&group_sid, user->groups[i])) {
/* If we're a group member then we can also
do anything */
@@ -310,18 +317,18 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
acl = sd->dacl;
- if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) {
+ if (acl == NULL || acl->ace == NULL || acl->num_aces == 0) {
/* Checks against a NULL ACL succeed and return access
- granted = access requested. */
+ granted = access requested. */
*status = NT_STATUS_NOPROBLEMO;
*acc_granted = acc_desired;
acc_desired = 0;
DEBUG(3, ("null ace, access allowed\n"));
- goto done;
- }
+ goto done;
+ }
/* Check each ACE in ACL. We break out of the loop if an ACE is
either explicitly denied or explicitly allowed by the
@@ -370,7 +377,8 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
}
done:
- free_sid_array(ngroup_sids, group_sids);
+
+ free_sid_array(ngroup_sids, group_sids);
/* If any access desired bits are still on, return access denied
and turn off any bits already granted. */
@@ -380,5 +388,5 @@ BOOL se_access_check(SEC_DESC *sd, struct current_user *user,
*status = NT_STATUS_ACCESS_DENIED;
}
- return *status == NT_STATUS_NOPROBLEMO;
+ return *status == NT_STATUS_NOPROBLEMO;
}
diff --git a/source3/nsswitch/wb_client.c b/source3/nsswitch/wb_client.c
index 78de466636..47f1520efa 100644
--- a/source3/nsswitch/wb_client.c
+++ b/source3/nsswitch/wb_client.c
@@ -29,7 +29,6 @@
BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type)
{
- extern pstring global_myname;
struct winbindd_request request;
struct winbindd_response response;
enum nss_status result;
@@ -47,14 +46,6 @@ BOOL winbind_lookup_name(char *name, DOM_SID *sid, uint8 *name_type)
&response)) == NSS_STATUS_SUCCESS) {
string_to_sid(sid, response.data.sid.sid);
*name_type = response.data.sid.type;
- } else {
-
- /*
- * Try a local lookup - winbindd may not
- * be running.
- */
-
- return lookup_local_name(global_myname, name, sid, name_type);
}
return result == NSS_STATUS_SUCCESS;
@@ -85,7 +76,7 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
if (sid_equal(&global_sam_sid, &tmp_sid)) {
return map_domain_sid_to_name(&tmp_sid, dom_name) &&
- lookup_local_rid(rid, name, name_type);
+ local_lookup_rid(rid, name, name_type);
}
}
@@ -106,15 +97,6 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
if (result == NSS_STATUS_SUCCESS) {
parse_domain_user(response.data.name.name, dom_name, name);
*name_type = response.data.name.type;
- } else {
-
- DEBUG(10,("winbind_lookup_sid: winbind lookup for %s failed - trying builtin.\n",
- sid_str));
-
- sid_copy(&tmp_sid, sid);
- sid_split_rid(&tmp_sid, &rid);
- return map_domain_sid_to_name(&tmp_sid, dom_name) &&
- lookup_known_rid(&tmp_sid, rid, name, name_type);
}
return (result == NSS_STATUS_SUCCESS);
@@ -122,13 +104,14 @@ BOOL winbind_lookup_sid(DOM_SID *sid, fstring dom_name, fstring name,
/* Call winbindd to convert uid to sid */
-BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid)
+BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
- if (!sid) return False;
+ if (!sid)
+ return False;
/* Initialise request */
@@ -154,13 +137,14 @@ BOOL winbind_uid_to_sid(uid_t uid, DOM_SID *sid)
/* Call winbindd to convert uid to sid */
-BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid)
+BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
{
struct winbindd_request request;
struct winbindd_response response;
int result;
- if (!sid) return False;
+ if (!sid)
+ return False;
/* Initialise request */
@@ -183,3 +167,79 @@ BOOL winbind_gid_to_sid(gid_t gid, DOM_SID *sid)
return (result == NSS_STATUS_SUCCESS);
}
+
+
+
+/*****************************************************************
+ *THE CANNONICAL* convert name to SID function.
+ Tries winbind first - then uses local lookup.
+*****************************************************************/
+
+BOOL lookup_name(char *name, DOM_SID *psid, uint8 *name_type)
+{
+ extern pstring global_myname;
+
+ if (!winbind_lookup_name(name, psid, name_type)) {
+
+ DEBUG(10,("lookup_name: winbind lookup for %s failed - trying local\n", name ));
+
+ return local_lookup_name(global_myname, name, psid, name_type);
+ }
+ return True;
+}
+
+/*****************************************************************
+ *THE CANNONICAL* convert SID to name function.
+ Tries winbind first - then uses local lookup.
+*****************************************************************/
+
+BOOL lookup_sid(DOM_SID *sid, fstring dom_name, fstring name, uint8 *name_type)
+{
+ if (!winbind_lookup_sid(sid, dom_name, name, name_type)) {
+ fstring sid_str;
+ DOM_SID tmp_sid;
+ uint32 rid;
+
+ DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying local.\n", sid_to_string(sid_str, sid) ));
+
+ sid_copy(&tmp_sid, sid);
+ sid_split_rid(&tmp_sid, &rid);
+ return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+ lookup_known_rid(&tmp_sid, rid, name, name_type);
+ }
+ return True;
+}
+
+/*****************************************************************
+ *THE CANNONICAL* convert uid_t to SID function.
+ Tries winbind first - then uses local lookup.
+ Returns SID pointer.
+*****************************************************************/
+
+DOM_SID *uid_to_sid(DOM_SID *psid, uid_t uid)
+{
+ if (!winbind_uid_to_sid(psid, uid)) {
+ DEBUG(10,("uid_to_sid: winbind lookup for uid %u failed - trying local.\n", (unsigned int)uid ));
+
+ return local_uid_to_sid(psid, uid);
+ }
+
+ return psid;
+}
+
+/*****************************************************************
+ *THE CANNONICAL* convert gid_t to SID function.
+ Tries winbind first - then uses local lookup.
+ Returns SID pointer.
+*****************************************************************/
+
+DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid)
+{
+ if (!winbind_gid_to_sid(psid, gid)) {
+ DEBUG(10,("gid_to_sid: winbind lookup for gid %u failed - trying local.\n", (unsigned int)gid ));
+
+ return local_gid_to_sid(psid, gid);
+ }
+
+ return psid;
+}
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 04f02e3704..f0fe2499df 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -1091,12 +1091,12 @@ BOOL pdb_rid_is_user(uint32 rid)
Convert a rid into a name. Used in the lookup SID rpc.
********************************************************************/
-BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
+BOOL local_lookup_rid(uint32 rid, char *name, uint8 *psid_name_use)
{
BOOL is_user = pdb_rid_is_user(rid);
- DEBUG(5,("lookup_local_rid: looking up %s RID %u.\n", is_user ? "user" :
+ DEBUG(5,("local_lookup_rid: looking up %s RID %u.\n", is_user ? "user" :
"group", (unsigned int)rid));
if(is_user) {
@@ -1118,7 +1118,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
*psid_name_use = SID_NAME_USER;
- DEBUG(5,("lookup_local_rid: looking up uid %u %s\n", (unsigned int)uid,
+ DEBUG(5,("local_lookup_rid: looking up uid %u %s\n", (unsigned int)uid,
pass ? "succeeded" : "failed" ));
if(!pass) {
@@ -1128,7 +1128,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
fstrcpy(name, pass->pw_name);
- DEBUG(5,("lookup_local_rid: found user %s for rid %u\n", name,
+ DEBUG(5,("local_lookup_rid: found user %s for rid %u\n", name,
(unsigned int)rid ));
}
@@ -1138,7 +1138,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
*psid_name_use = SID_NAME_ALIAS;
- DEBUG(5,("lookup_local_rid: looking up gid %u %s\n", (unsigned int)gid,
+ DEBUG(5,("local_local_rid: looking up gid %u %s\n", (unsigned int)gid,
gr ? "succeeded" : "failed" ));
if(!gr) {
@@ -1148,7 +1148,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
fstrcpy( name, gr->gr_name);
- DEBUG(5,("lookup_local_rid: found group %s for rid %u\n", name,
+ DEBUG(5,("local_lookup_rid: found group %s for rid %u\n", name,
(unsigned int)rid ));
}
@@ -1159,7 +1159,7 @@ BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
Convert a name into a SID. Used in the lookup name rpc.
********************************************************************/
-BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use)
+BOOL local_lookup_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use)
{
extern DOM_SID global_sid_World_Domain;
struct passwd *pass = NULL;
@@ -1206,71 +1206,29 @@ BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name
}
/****************************************************************************
- Create a list of SIDS for a user - primary and group.
- This is really the wrong way to do this and needs to go via winbind. JRA.
+ Convert a uid to SID - locally.
****************************************************************************/
-BOOL setup_user_sids(user_struct *vuser)
+DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
{
extern DOM_SID global_sam_sid;
- sid_copy(&vuser->user_sid, &global_sam_sid);
- sid_append_rid( &vuser->user_sid, pdb_uid_to_user_rid(vuser->uid));
+ sid_copy(psid, &global_sam_sid);
+ sid_append_rid(psid, pdb_uid_to_user_rid(uid));
- if (vuser->n_groups != 0) {
- int i;
+ return psid;
+}
- vuser->group_sids = (DOM_SID *)malloc(sizeof(DOM_SID) * vuser->n_groups);
+/****************************************************************************
+ Convert a gid to SID - locally.
+****************************************************************************/
- if (vuser->group_sids == NULL)
- return False;
+DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
+{
+ extern DOM_SID global_sam_sid;
- for (i = 0; i < vuser->n_groups; i++) {
- sid_copy(&vuser->group_sids[i], &global_sam_sid);
- sid_append_rid( &vuser->group_sids[i], pdb_gid_to_group_rid(vuser->groups[i]));
- }
- }
+ sid_copy(psid, &global_sam_sid);
+ sid_append_rid(psid, pdb_gid_to_group_rid(gid));
- return True;
-#if 0
- /* Luke's code. */
- if (usr == NULL)
- {
- int i;
- extern DOM_SID global_sam_sid;
-
- DEBUG(0,("vuser struct usr being filled in with trash, today\n"));
- DEBUG(0,("this needs to be replaced with a proper surs impl.\n"));
- DEBUG(0,("e.g. the one used in winbindd. in fact, all\n"));
- DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n"));
- DEBUG(0,("as soon as possible.\n"));
- vuser->usr.user_id = pdb_uid_to_user_rid(uid);
- vuser->usr.group_id = pdb_gid_to_group_rid(gid);
- vuser->usr.num_groups = vuser->n_groups;
- if (vuser->n_groups != 0)
- {
- vuser->usr.gids = g_new(DOM_GID, vuser->usr.num_groups);
- if (vuser->usr.gids == NULL)
- return UID_FIELD_INVALID;
- }
-
- for (i = 0; i < vuser->usr.num_groups; i++)
- {
- DOM_GID *ntgid = &vuser->usr.gids[i];
- ntgid->attr = 0x7;
- ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]);
- }
-
- /* this is possibly the worst thing to do, ever. it assumes */
- /* that all users of this system are in the local SAM database */
- /* however, because there is no code to do anything otherwise, */
- /* we have no choice */
-
- init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid);
- }
- else
- {
- vuser->usr = *usr;
- }
-#endif
+ return psid;
}
diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c
index bfb671d167..dc97d6db44 100644
--- a/source3/rpc_server/srv_lsa.c
+++ b/source3/rpc_server/srv_lsa.c
@@ -238,7 +238,7 @@ static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
if (map_domain_name_to_sid(&dom_sid, dom_name)) {
dom_idx = init_dom_ref(ref, dom_name, &dom_sid);
- if (lookup_local_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid))
+ if (local_lookup_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid))
status = True;
}
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
index 5a0f049ba7..e80175f71d 100644
--- a/source3/rpc_server/srv_samr.c
+++ b/source3/rpc_server/srv_samr.c
@@ -978,7 +978,7 @@ static BOOL samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
if(alias_rid == 0xffffffff)
r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
- if(!lookup_local_rid(alias_rid, alias, &type))
+ if(!local_lookup_rid(alias_rid, alias, &type))
{
r_e.status = 0xC0000000 | NT_STATUS_NO_SUCH_ALIAS;
}
@@ -1151,7 +1151,7 @@ static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
if(sid_equal(&pol_sid, &global_sam_sid))
{
DOM_SID sid;
- if(lookup_local_name(global_myname, name,
+ if(local_lookup_name(global_myname, name,
&sid, &type[i]))
{
sid_split_rid( &sid, &rid[i]);
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index f9291b8705..0372e7a0f9 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -113,6 +113,16 @@ user_struct *get_valid_user_struct(uint16 vuid)
}
/****************************************************************************
+ Delete the SID list for this user.
+****************************************************************************/
+
+static void delete_nt_token(NT_USER_TOKEN *token)
+{
+ safe_free( token->user_sids );
+ ZERO_STRUCTP(token);
+}
+
+/****************************************************************************
invalidate a uid
****************************************************************************/
void invalidate_vuid(uint16 vuid)
@@ -133,8 +143,7 @@ void invalidate_vuid(uint16 vuid)
vuser->groups = NULL;
- if (vuser->group_sids != NULL)
- free (vuser->group_sids);
+ delete_nt_token(&vuser->nt_user_token);
}
@@ -162,61 +171,54 @@ char *validated_domain(uint16 vuid)
/****************************************************************************
-Setup the groups a user belongs to.
+ Initialize the groups a user belongs to.
****************************************************************************/
-int setup_groups(char *user, char *domain,
- uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
-{
- int i,ngroups;
- gid_t grp = 0;
- gid_t *groups = NULL;
- if (-1 == initgroups(user,gid))
- {
+int initialize_groups(char *user, uid_t uid, gid_t gid)
+{
+ if (initgroups(user,gid) == -1) {
DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) ));
- if (getuid() == 0)
- {
- if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767)
- {
+ if (getuid() == 0) {
+ if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) {
DEBUG(0,("This is probably a problem with the account %s\n", user));
}
}
return -1;
}
+ return 0;
+}
- ngroups = sys_getgroups(0,&grp);
- if (ngroups <= 0)
- {
- ngroups = groups_max();
- }
+/****************************************************************************
+ Create the SID list for this user.
+****************************************************************************/
- if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
- {
- DEBUG(0,("setup_groups malloc fail !\n"));
- return -1;
- }
+void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups)
+{
+ DOM_SID *psids;
+ int i;
- ngroups = sys_getgroups(ngroups,groups);
+ ZERO_STRUCTP(token);
- (*p_ngroups) = ngroups;
- (*p_groups) = groups;
+ if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL)
+ return;
- DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) );
- for (i = 0; i < ngroups; i++ )
- {
- DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
- }
- DEBUG( 3, ( "\n" ) );
+ psids = token->user_sids;
- return 0;
-}
+ token->num_sids = ngroups + 2;
+
+ uid_to_sid( &psids[0], uid);
+ gid_to_sid( &psids[1], gid);
+ for (i = 0; i < ngroups; i++)
+ gid_to_sid( &psids[i+2], groups[i]);
+}
/****************************************************************************
register a uid/name pair as being valid and that a valid password
has been given. vuid is biased by an offset. This allows us to
tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
+
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
char *domain,BOOL guest)
{
@@ -227,37 +229,15 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
if(lp_security() == SEC_SHARE)
return UID_FIELD_INVALID;
-#if 0
- /*
- * After observing MS-Exchange services writing to a Samba share
- * I belive this code is incorrect. Each service does its own
- * sessionsetup_and_X for the same user, and as each service shuts
- * down, it does a user_logoff_and_X. As we are consolidating multiple
- * sessionsetup_and_X's onto the same vuid here, when the first service
- * shuts down, it invalidates all the open files for the other services.
- * Hence I am removing this code and forcing each sessionsetup_and_X
- * to get a new vuid.
- * Jeremy Allison. (jallison@whistle.com).
- */
-
- int i;
- for(i = 0; i < num_validated_users; i++) {
- vuser = &validated_users[i];
- if ( vuser->uid == uid )
- return (uint16)(i + VUID_OFFSET); /* User already validated */
- }
-#endif
-
validated_users = (user_struct *)Realloc(validated_users,
sizeof(user_struct)*
(num_validated_users+1));
- if (!validated_users)
- {
+ if (!validated_users) {
DEBUG(0,("Failed to realloc users struct!\n"));
num_validated_users = 0;
return UID_FIELD_INVALID;
- }
+ }
vuser = &validated_users[num_validated_users];
num_validated_users++;
@@ -274,22 +254,21 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
/* Find all the groups this uid is in and store them.
Used by become_user() */
- setup_groups(unix_name,domain,uid,gid,
- &vuser->n_groups,
- &vuser->groups);
+ initialize_groups(unix_name, uid, gid);
+ get_current_groups( &vuser->n_groups, &vuser->groups);
- setup_user_sids(vuser);
+ /* Create an NT_USER_TOKEN struct for this user. */
+ setup_nt_token(&vuser->nt_user_token, uid,gid, vuser->n_groups, vuser->groups);
DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
DEBUG(3, ("Clearing default real name\n"));
fstrcpy(vuser->user.full_name, "<Full Name>");
if (lp_unix_realname()) {
- if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL)
- {
+ if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) {
DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos));
fstrcpy(vuser->user.full_name, pwfile->pw_gecos);
- }
+ }
}
memset(&vuser->dc, '\0', sizeof(vuser->dc));
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 2662db5896..37d8f8dd73 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -561,8 +561,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
}
/* load service specific parameters */
- if (conn &&
- !become_service(conn,(flags & AS_USER)?True:False)) {
+ if (conn && !become_service(conn,(flags & AS_USER)?True:False)) {
return(ERROR(ERRSRV,ERRaccess));
}
diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c
index f7ea1e2d86..432cb223e2 100644
--- a/source3/smbd/sec_ctx.c
+++ b/source3/smbd/sec_ctx.c
@@ -125,17 +125,37 @@ static void gain_root(void)
/* Get the list of current groups */
-static void get_current_groups(int *ngroups, gid_t **groups)
+int get_current_groups(int *p_ngroups, gid_t **p_groups)
{
- *ngroups = getgroups(0, NULL);
- *groups = (gid_t *)malloc(*ngroups * sizeof(gid_t));
+ int i;
+ gid_t grp;
+ int ngroups = sys_getgroups(0,&grp);
+ gid_t *groups;
+
+ (*p_ngroups) = 0;
+ (*p_groups) = NULL;
+
+ if (ngroups <= 0)
+ return -1;
+
+ if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) {
+ DEBUG(0,("setup_groups malloc fail !\n"));
+ return -1;
+ }
+
+ if ((ngroups = sys_getgroups(ngroups,groups)) == -1)
+ return -1;
+
+ (*p_ngroups) = ngroups;
+ (*p_groups) = groups;
- if (!groups) {
- DEBUG(0, ("Out of memory in get_current_groups\n"));
- return;
+ DEBUG( 3, ( "get_current_groups: uid %u is in %u groups: ", (unsigned int)getuid() , ngroups ) );
+ for (i = 0; i < ngroups; i++ ) {
+ DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
}
+ DEBUG( 3, ( "\n" ) );
- getgroups(*ngroups, *groups);
+ return ngroups;
}
/* Create a new security context on the stack. It is the same as the old
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 2eab50c482..d4760ca92d 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -511,8 +511,8 @@ connection_struct *make_connection(char *service,char *user,char *password, int
if (!IS_IPC(conn)) {
/* Find all the groups this uid is in and
store them. Used by become_user() */
- setup_groups(conn->user,validated_domain(vuid),conn->uid,conn->gid,
- &conn->ngroups,&conn->groups);
+ initialize_groups(conn->user, conn->uid, conn->gid);
+ get_current_groups(&conn->ngroups,&conn->groups);
/* check number of connections */
if (!claim_connection(conn,
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 172e872020..4cb2c512b6 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -38,7 +38,8 @@ BOOL become_guest(void)
if (!pass)
pass = Get_Pwnam(lp_guestaccount(-1),True);
- if (!pass) return(False);
+ if (!pass)
+ return(False);
#ifdef AIX
/* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
@@ -60,19 +61,21 @@ BOOL become_guest(void)
static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
{
- int i;
- for (i=0;i<conn->uid_cache.entries;i++)
- if (conn->uid_cache.list[i] == vuser->uid) return(True);
+ int i;
+ for (i=0;i<conn->uid_cache.entries;i++)
+ if (conn->uid_cache.list[i] == vuser->uid)
+ return(True);
- if (!user_ok(vuser->user.unix_name,snum)) return(False);
+ if (!user_ok(vuser->user.unix_name,snum))
+ return(False);
- i = conn->uid_cache.entries % UID_CACHE_SIZE;
- conn->uid_cache.list[i] = vuser->uid;
+ i = conn->uid_cache.entries % UID_CACHE_SIZE;
+ conn->uid_cache.list[i] = vuser->uid;
- if (conn->uid_cache.entries < UID_CACHE_SIZE)
- conn->uid_cache.entries++;
+ if (conn->uid_cache.entries < UID_CACHE_SIZE)
+ conn->uid_cache.entries++;
- return(True);
+ return(True);
}
/****************************************************************************
diff --git a/source3/smbd/unix_acls.c b/source3/smbd/unix_acls.c
index 7a2dc6ab6e..46c57af5de 100644
--- a/source3/smbd/unix_acls.c
+++ b/source3/smbd/unix_acls.c
@@ -28,12 +28,8 @@
static void create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SID *pgroup_sid)
{
- extern DOM_SID global_sam_sid;
-
- sid_copy(powner_sid, &global_sam_sid);
- sid_copy(pgroup_sid, &global_sam_sid);
- sid_append_rid(powner_sid, pdb_uid_to_user_rid(psbuf->st_uid));
- sid_append_rid(pgroup_sid, pdb_gid_to_group_rid(psbuf->st_gid));
+ uid_to_sid( powner_sid, psbuf->st_uid );
+ gid_to_sid( pgroup_sid, psbuf->st_gid );
}
/****************************************************************************