summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2009-07-14 11:25:45 -0700
committerJeremy Allison <jra@samba.org>2009-07-14 11:25:45 -0700
commitd57e67f9eb5a6a05f0e173d48e86dd1fe050635e (patch)
tree4afa76c7ebeb407d9a7178f1747aafe413a9e5b7
parent73e96935c3604d21552ba93dfd561eaf7606f52d (diff)
downloadsamba-d57e67f9eb5a6a05f0e173d48e86dd1fe050635e.tar.gz
samba-d57e67f9eb5a6a05f0e173d48e86dd1fe050635e.tar.bz2
samba-d57e67f9eb5a6a05f0e173d48e86dd1fe050635e.zip
Revert this commit :
s3: Make smbd aware of permission change of usershare. Since usershare are relatively volatile and non-previledge users must disconnect from smbd and reconnect to it to make share permission in effect. For now. This is a feature request and I think we need to design it a little differently so as not to touch core change_to_user() code. Jeremy.
-rw-r--r--source3/include/proto.h7
-rw-r--r--source3/include/smb.h6
-rw-r--r--source3/param/loadparm.c11
-rw-r--r--source3/smbd/conn.c1
-rw-r--r--source3/smbd/notify_inotify.c4
-rw-r--r--source3/smbd/process.c58
-rw-r--r--source3/smbd/service.c80
-rw-r--r--source3/smbd/uid.c96
8 files changed, 39 insertions, 224 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d141de44cf..0dd1e98c86 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -4296,7 +4296,6 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
char **pp_comment,
SEC_DESC **ppsd,
bool *pallow_guest);
-bool am_usershare(int iService);
int load_usershare_service(const char *servicename);
int load_usershare_shares(void);
void gfree_loadparm(void);
@@ -7064,8 +7063,7 @@ void reply_transs2(struct smb_request *req);
bool change_to_guest(void);
void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid);
-bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid,
- bool recheck, NTSTATUS *pstatus);
+bool change_to_user(connection_struct *conn, uint16 vuid);
bool change_to_root_user(void);
bool become_authenticated_pipe_user(pipes_struct *p);
bool unbecome_authenticated_pipe_user(void);
@@ -7074,9 +7072,6 @@ void unbecome_root(void);
bool become_user(connection_struct *conn, uint16 vuid);
bool unbecome_user(void);
-#define change_to_user(conn, vuid) \
- change_to_user_force_recheck(conn, vuid, 0, NULL)
-
/* The following definitions come from smbd/utmp.c */
void sys_utmp_claim(const char *username, const char *hostname,
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 44216f856a..2e9cf1b54a 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -550,7 +550,6 @@ typedef struct connection_struct {
unsigned cnum; /* an index passed over the wire */
struct share_params *params;
bool force_user;
- bool force_recheck_perm;
struct vuid_cache vuid_cache;
struct dptr_struct *dirptr;
bool printer;
@@ -1399,11 +1398,6 @@ struct bitmap {
#define FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200
#define FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400
#define FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800
-#define FILE_NOTIFY_CHANGE_FILE_CONTENT \
- (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME \
- | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE \
- | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA \
- | FILE_NOTIFY_CHANGE_SECURITY)
#define FILE_NOTIFY_CHANGE_NAME \
(FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME)
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 4415804a2d..5d3ac9207e 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -8741,6 +8741,17 @@ bool am_usershare(int iService)
}
/***************************************************************************
+Am I a usershare service?
+***************************************************************************/
+bool am_usershare(int iService)
+{
+ if (iService >= 0) {
+ return (ServicePtrs[iService]->usershare == USERSHARE_VALID);
+ }
+ return false;
+}
+
+/***************************************************************************
Checks if a usershare entry has been modified since last load.
***************************************************************************/
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 3ddb4c094f..af6e0919a4 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -155,7 +155,6 @@ find_again:
return NULL;
}
conn->cnum = i;
- conn->force_recheck_perm = false;
conn->force_group_gid = (gid_t)-1;
bitmap_set(sconn->smb1.tcons.bmap, i);
diff --git a/source3/smbd/notify_inotify.c b/source3/smbd/notify_inotify.c
index b6be69c8fd..26570a2216 100644
--- a/source3/smbd/notify_inotify.c
+++ b/source3/smbd/notify_inotify.c
@@ -316,9 +316,7 @@ static const struct {
{FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB},
{FILE_NOTIFY_CHANGE_LAST_ACCESS, IN_ATTRIB},
{FILE_NOTIFY_CHANGE_EA, IN_ATTRIB},
- {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB},
- {FILE_NOTIFY_CHANGE_FILE_CONTENT, IN_MODIFY|IN_DELETE|IN_CREATE|IN_DELETE_SELF
- |IN_MOVE_SELF|IN_MOVED_FROM|IN_MOVED_TO},
+ {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB}
};
static uint32_t inotify_map(struct notify_entry *e)
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 5b8a325d22..b26bc150db 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1286,6 +1286,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
}
}
}
+
/* Does this call need to be run as the connected user? */
if (flags & AS_USER) {
@@ -1302,67 +1303,12 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
}
return NULL;
}
-#ifdef HAVE_INOTIFY
- if (conn->force_recheck_perm) {
- int old;
- int iService = -1;
- const char *service = NULL;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- conn->force_recheck_perm = false;
- DEBUG(5, ("switch_message: rechecking permission for connection %x\n",
- (unsigned int)conn));
- old = SNUM(conn);
- service = lp_servicename(old);
- conn->read_only = False;
- if (lp_snum_ok(old) && am_usershare(old)) {
- iService = load_usershare_service(service);
- if (iService < 0 || old != iService) {
- /* non-exist service */
- DEBUG(5, ("switch_message: deleting connection %x\n",
- (unsigned int)conn));
- DEBUG(5, ("snum %d, sname %s\n",
- old, service ? service : "NULL"));
- delete_share_security(service);
- set_current_service(NULL, 0, True);
- close_cnum(smbd_server_conn, conn, conn->vuid);
- lp_killservice(old);
- reply_nterror(req, NT_STATUS_BAD_NETWORK_NAME);
- return NULL;
- }
-
- /*
- * Don't have to reauthentication here, but
- * need to check share permissions.....
- * the vuid cache is a problem..
- */
-
- if (!change_to_root_user()) {
- smb_panic("cann't change to root user!\n");
- }
-
- if (!change_to_user_force_recheck(conn, session_tag,
- True, &status)) {
- reply_nterror(req, status);
- remove_deferred_open_smb_message(req->mid);
- return conn;
- }
- }
- } else {
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- if (!change_to_user_force_recheck(conn, session_tag,
- False, &status)) {
- reply_nterror(req, status);
- remove_deferred_open_smb_message(req->mid);
- return conn;
- }
- }
-#else
+
if (!change_to_user(conn,session_tag)) {
reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
remove_deferred_open_smb_message(req->mid);
return conn;
}
-#endif
/* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 8ae13b14f3..0124b2b047 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -630,33 +630,6 @@ static NTSTATUS create_connection_server_info(struct smbd_server_connection *sco
return NT_STATUS_ACCESS_DENIED;
}
-#ifdef HAVE_INOTIFY
-static void share_perm_changed(struct sys_notify_context *ctx,
- void *ptr, struct notify_event *ev)
-{
- connection_struct *conn = talloc_get_type_abort(ptr, connection_struct);
- const char *service = NULL;
- service = lp_servicename(SNUM(conn));
- if (strequal(ev->path, service)) {
- conn->force_recheck_perm = true;
- DEBUG(0, ("share_perm_changed: set recheck flag for connection %x\n",
- (unsigned int)conn));
- }
-}
-
-struct notify_context {
- struct db_context *db_recursive;
- struct db_context *db_onelevel;
- struct server_id server;
- struct messaging_context *messaging_ctx;
- struct notify_list *list;
- struct notify_array *array;
- int seqnum;
- struct sys_notify_context *sys_notify_ctx;
- TDB_DATA key;
-};
-#endif
-
/****************************************************************************
Make a connection, given the snum to connect to, and the vuser of the
@@ -894,64 +867,11 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn,
}
if ((!conn->printer) && (!conn->ipc)) {
-#ifdef HAVE_INOTIFY
- struct sys_notify_context *sys_ctx = NULL;
- struct notify_entry e;
- struct inotify_watch_context *w = NULL;
-#endif
conn->notify_ctx = notify_init(conn, server_id_self(),
smbd_messaging_context(),
smbd_event_context(),
conn);
-#ifdef HAVE_INOTIFY
- /*
- * here is the start of monitoring share permissions change.
- * For usershares, we have to watch on both
- * get_dyn_STATDIR()/servicename and get_dyn_STATDIR()/share_info.tdb.
- * For shares in smb.conf, we just watch on
- * get_dyn_STATDIR()/share_info.tdb
- */
- if (!conn->notify_ctx) {
- DEBUG(1, ("change notify is not enabled??\n"));
- goto nonotify;
- }
- sys_ctx = conn->notify_ctx->sys_notify_ctx;
- if (!sys_ctx) {
- DEBUG(1, ("change notify: out of memory!!\n"));
- *pstatus = NT_STATUS_NO_MEMORY;
- conn_free(sconn, conn);
- return NULL;
- }
- ZERO_STRUCT(e);
- if (am_usershare(SNUM(conn))) {
- const char *usershare_path = lp_usershare_path();
- /* This is usershare service. */
- e.path = talloc_strdup(conn, usershare_path);
- } else {
- goto nonotify;
- /* watch normal shares' permission? */
- }
- if (!e.path) {
- DEBUG(1, ("setting up usershare notify: out of memory!\n"));
- *pstatus = status;
- conn_free(sconn, conn);
- return NULL;
- }
- e.path_len = strlen(e.path);
- e.filter = FILE_NOTIFY_CHANGE_FILE_CONTENT;
- status = inotify_watch(sys_ctx, &e, share_perm_changed,
- (void *)conn, (void *)&w);
- if (NT_STATUS_IS_ERR(status)) {
- DEBUG(1, ("add inotify for usershare permission failed!\n"));
- *pstatus = status;
- conn_free(sconn, conn);
- return NULL;
- }
-#endif
}
-#ifdef HAVE_INOTIFY
-nonotify:
-#endif
/* ROOT Activities: */
/*
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 8e5a386a2d..2ec50cd4d8 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -82,17 +82,12 @@ static void free_conn_server_info_if_unused(connection_struct *conn)
static bool check_user_ok(connection_struct *conn,
uint16_t vuid,
const struct auth_serversupplied_info *server_info,
- int snum, bool recheck, NTSTATUS *pstatus)
+ int snum)
{
bool valid_vuid = (vuid != UID_FIELD_INVALID);
unsigned int i;
bool readonly_share;
bool admin_user;
- struct vuid_cache_entry *ent0;
-
- if (pstatus) {
- *pstatus = NT_STATUS_OK;
- }
if (valid_vuid) {
struct vuid_cache_entry *ent;
@@ -101,27 +96,18 @@ static bool check_user_ok(connection_struct *conn,
ent = &conn->vuid_cache.array[i];
if (ent->vuid == vuid) {
free_conn_server_info_if_unused(conn);
- ent0 = ent;
- if (!recheck) {
- conn->server_info = ent->server_info;
- conn->read_only = ent->read_only;
- conn->admin_user = ent->admin_user;
- return(True);
- } else {
- break;
- }
+ conn->server_info = ent->server_info;
+ conn->read_only = ent->read_only;
+ conn->admin_user = ent->admin_user;
+ return(True);
}
}
}
if (!user_ok_token(server_info->unix_name,
pdb_get_domain(server_info->sam_account),
- server_info->ptok, snum)) {
- if (pstatus) {
- *pstatus = NT_STATUS_ACCESS_DENIED;
- }
+ server_info->ptok, snum))
return(False);
- }
readonly_share = is_share_read_only_for_token(
server_info->unix_name,
@@ -142,9 +128,6 @@ static bool check_user_ok(connection_struct *conn,
if (!share_access_check(server_info->ptok, lp_servicename(snum),
readonly_share ?
FILE_READ_DATA : FILE_WRITE_DATA)) {
- if (pstatus) {
- *pstatus = NT_STATUS_ACCESS_DENIED;
- }
return False;
}
@@ -154,26 +137,13 @@ static bool check_user_ok(connection_struct *conn,
NULL, server_info->ptok, lp_admin_users(snum));
if (valid_vuid) {
- struct vuid_cache_entry *ent = NULL;
-
- if (!recheck || i == VUID_CACHE_SIZE) {
- /* find a new entry and fill it. */
- ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry];
+ struct vuid_cache_entry *ent =
+ &conn->vuid_cache.array[conn->vuid_cache.next_entry];
- conn->vuid_cache.next_entry =
- (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE;
+ conn->vuid_cache.next_entry =
+ (conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE;
- TALLOC_FREE(ent->server_info);
- } else if (recheck && (i < VUID_CACHE_SIZE) && (ent0->vuid == vuid)) {
- /* she perform forced recheck, replace the old one. */
- ent = ent0;
- } else {
- /* must not happen */
- DEBUG(0, ("check_user_ok: recheck %s\n", recheck ? "true" : "false"));
- DEBUG(0, ("check_user_ok: vuid cache %d -- %d\n", i, VUID_CACHE_SIZE));
- DEBUG(0, ("check_user_ok: vuid %d -- %d\n", ent0->vuid, vuid));
- smb_panic("should not happen");
- }
+ TALLOC_FREE(ent->server_info);
/*
* If force_user was set, all server_info's are based on the same
@@ -185,9 +155,6 @@ static bool check_user_ok(connection_struct *conn,
if (ent->server_info == NULL) {
ent->vuid = UID_FIELD_INVALID;
- if (pstatus) {
- *pstatus = NT_STATUS_NO_MEMORY;
- }
return false;
}
@@ -254,8 +221,7 @@ void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid)
stack, but modify the current_user entries.
****************************************************************************/
-bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid,
- bool recheck, NTSTATUS *pstatus)
+bool change_to_user(connection_struct *conn, uint16 vuid)
{
const struct auth_serversupplied_info *server_info = NULL;
struct smbd_server_connection *sconn = smbd_server_conn;
@@ -269,9 +235,6 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid,
if (!conn) {
DEBUG(2,("change_to_user: Connection not open\n"));
- if (pstatus) {
- *pstatus = NT_STATUS_INVALID_HANDLE;
- }
return(False);
}
@@ -282,19 +245,17 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid,
* SMB's - this hurts performance - Badly.
*/
- if (!recheck) {
- if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
- (current_user.ut.uid == conn->server_info->utok.uid)) {
- DEBUG(4,("change_to_user: Skipping user change - already "
- "user\n"));
- return(True);
- } else if ((current_user.conn == conn) &&
- (vuser != NULL) && (current_user.vuid == vuid) &&
- (current_user.ut.uid == vuser->server_info->utok.uid)) {
- DEBUG(4,("change_to_user: Skipping user change - already "
- "user\n"));
- return(True);
- }
+ if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
+ (current_user.ut.uid == conn->server_info->utok.uid)) {
+ DEBUG(4,("change_to_user: Skipping user change - already "
+ "user\n"));
+ return(True);
+ } else if ((current_user.conn == conn) &&
+ (vuser != NULL) && (current_user.vuid == vuid) &&
+ (current_user.ut.uid == vuser->server_info->utok.uid)) {
+ DEBUG(4,("change_to_user: Skipping user change - already "
+ "user\n"));
+ return(True);
}
snum = SNUM(conn);
@@ -305,13 +266,10 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid,
/* Invalid vuid sent - even with security = share. */
DEBUG(2,("change_to_user: Invalid vuid %d used on "
"share %s.\n",vuid, lp_servicename(snum) ));
- if (pstatus) {
- *pstatus = NT_STATUS_ACCESS_VIOLATION;
- }
return false;
}
- if (!check_user_ok(conn, vuid, server_info, snum, recheck, pstatus)) {
+ if (!check_user_ok(conn, vuid, server_info, snum)) {
DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) "
"not permitted access to share %s.\n",
server_info->sanitized_username,
@@ -338,9 +296,6 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid,
} else {
DEBUG(2,("change_to_user: Invalid vuid used %d in accessing "
"share %s.\n",vuid, lp_servicename(snum) ));
- if (pstatus) {
- *pstatus = NT_STATUS_DOS(ERRSRV, ERRbaduid);
- }
return False;
}
@@ -398,9 +353,6 @@ bool change_to_user_force_recheck(connection_struct *conn, uint16 vuid,
DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n",
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
- if (pstatus) {
- *pstatus = NT_STATUS_OK;
- }
return(True);
}