From 95bf60b39d003bea6f9f5ad2bc63d5f2a8b8b2af Mon Sep 17 00:00:00 2001 From: todd stecher Date: Mon, 23 Feb 2009 10:24:33 -0800 Subject: S3: Add in profile counters for new vfs and syscall entries. --- source3/include/smbprofile.h | 28 ++++++++++++++++++++++++++++ source3/modules/onefs_acl.c | 11 ++++++++++- source3/modules/onefs_cbrl.c | 26 ++++++++++++++++++++++++-- source3/modules/onefs_streams.c | 16 +++++++++++++--- source3/modules/onefs_system.c | 18 ++++++++++++++++++ source3/profile/profile.c | 7 +++++++ 6 files changed, 100 insertions(+), 6 deletions(-) diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index 131416b685..f9a0436546 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -75,6 +75,10 @@ enum profile_stats_values #define syscall_open_count __profile_stats_value(PR_VALUE_SYSCALL_OPEN, count) #define syscall_open_time __profile_stats_value(PR_VALUE_SYSCALL_OPEN, time) + PR_VALUE_SYSCALL_CREATEFILE, +#define syscall_createfile_count __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, count) +#define syscall_createfile_time __profile_stats_value(PR_VALUE_SYSCALL_CREATEFILE, time) + PR_VALUE_SYSCALL_CLOSE, #define syscall_close_count __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, count) #define syscall_close_time __profile_stats_value(PR_VALUE_SYSCALL_CLOSE, time) @@ -111,6 +115,10 @@ enum profile_stats_values #define syscall_rename_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME, count) #define syscall_rename_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME, time) + PR_VALUE_SYSCALL_RENAME_AT, +#define syscall_rename_at_count __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, count) +#define syscall_rename_at_time __profile_stats_value(PR_VALUE_SYSCALL_RENAME_AT, time) + PR_VALUE_SYSCALL_FSYNC, #define syscall_fsync_count __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, count) #define syscall_fsync_time __profile_stats_value(PR_VALUE_SYSCALL_FSYNC, time) @@ -215,6 +223,26 @@ enum profile_stats_values #define syscall_set_quota_count __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, count) #define syscall_set_quota_time __profile_stats_value(PR_VALUE_SYSCALL_SET_QUOTA, time) + PR_VALUE_SYSCALL_GET_SD, +#define syscall_get_sd_count __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, count) +#define syscall_get_sd_time __profile_stats_value(PR_VALUE_SYSCALL_GET_SD, time) + + PR_VALUE_SYSCALL_SET_SD, +#define syscall_set_sd_count __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, count) +#define syscall_set_sd_time __profile_stats_value(PR_VALUE_SYSCALL_SET_SD, time) + + PR_VALUE_SYSCALL_BRL_LOCK, +#define syscall_brl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, count) +#define syscall_brl_lock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_LOCK, time) + + PR_VALUE_SYSCALL_BRL_UNLOCK, +#define syscall_brl_unlock_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, count) +#define syscall_brl_unlock_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_UNLOCK, time) + + PR_VALUE_SYSCALL_BRL_CANCEL, +#define syscall_brl_cancel_count __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, count) +#define syscall_brl_cancel_time __profile_stats_value(PR_VALUE_SYSCALL_BRL_CANCEL, time) + /* counters for individual SMB types */ PR_VALUE_SMBMKDIR, #define SMBmkdir_count __profile_stats_value(PR_VALUE_SMBMKDIR, count) diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 7bc4a1728f..b463722e61 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -614,6 +614,8 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, bool fopened = false; NTSTATUS status = NT_STATUS_OK; + START_PROFILE(syscall_get_sd); + *ppdesc = NULL; DEBUG(5, ("Getting sd for file %s. security_info=%u\n", @@ -753,6 +755,9 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, DEBUG(5, ("Finished retrieving/canonicalizing SD!\n")); /* FALLTHROUGH */ out: + + END_PROFILE(syscall_get_sd); + if (alloced && sd) { if (new_aces_alloced && sd->dacl->aces) SAFE_FREE(sd->dacl->aces); @@ -892,6 +897,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, bool fopened = false; NTSTATUS status; + START_PROFILE(syscall_set_sd); + DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name )); status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd, @@ -899,7 +906,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("SD initialization failure: %s", nt_errstr(status))); - return status; + goto out; } fd = fsp->fh->fd; @@ -938,6 +945,8 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, /* FALLTHROUGH */ out: + END_PROFILE(syscall_set_sd); + if (fopened) close(fd); diff --git a/source3/modules/onefs_cbrl.c b/source3/modules/onefs_cbrl.c index a860023764..2c5e39c359 100644 --- a/source3/modules/onefs_cbrl.c +++ b/source3/modules/onefs_cbrl.c @@ -255,6 +255,8 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, struct onefs_cbrl_blr_state *bs; NTSTATUS status; + START_PROFILE(syscall_brl_lock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type != UNLOCK_LOCK); @@ -301,10 +303,13 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, /* ASYNC still in progress: The process_* calls will keep * calling even if we haven't gotten the lock. Keep erroring * without calling ifs_cbrl, or getting/setting an id. */ - if (bs->state == ONEFS_CBRL_ASYNC) + if (bs->state == ONEFS_CBRL_ASYNC) { goto failure; - else if (bs->state == ONEFS_CBRL_ERROR) + } + else if (bs->state == ONEFS_CBRL_ERROR) { + END_PROFILE(syscall_brl_lock); return NT_STATUS_NO_MEMORY; + } SMB_ASSERT(bs->state == ONEFS_CBRL_NONE); async = true; @@ -343,6 +348,9 @@ NTSTATUS onefs_brl_lock_windows(vfs_handle_struct *handle, } failure: + + END_PROFILE(syscall_brl_lock); + /* Failure - error or async. */ plock->context.smbpid = (uint32) ONEFS_BLOCKING_PID; @@ -355,6 +363,9 @@ failure: return status; success: + + END_PROFILE(syscall_brl_lock); + /* Success. */ onefs_cbrl_enumerate_blq("onefs_brl_unlock_windows"); DEBUG(10, ("returning NT_STATUS_OK.\n")); @@ -371,6 +382,8 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, int error; int fd = br_lck->fsp->fh->fd; + START_PROFILE(syscall_brl_unlock); + SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(plock->lock_type == UNLOCK_LOCK); @@ -378,6 +391,9 @@ bool onefs_brl_unlock_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_UNLOCK, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, 0, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_unlock); + if (error) { DEBUG(10, ("returning false.\n")); return false; @@ -404,6 +420,8 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, int fd = br_lck->fsp->fh->fd; struct onefs_cbrl_blr_state *bs; + START_PROFILE(syscall_brl_cancel); + SMB_ASSERT(plock); SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK); SMB_ASSERT(blr); @@ -416,6 +434,7 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, if (bs->state == ONEFS_CBRL_DONE) { /* No-op. */ DEBUG(10, ("State=DONE, returning true\n")); + END_PROFILE(syscall_brl_cancel); return true; } @@ -427,6 +446,9 @@ bool onefs_brl_cancel_windows(vfs_handle_struct *handle, error = ifs_cbrl(fd, CBRL_OP_CANCEL, CBRL_NOTYPE, plock->start, plock->size, CBRL_NOTYPE, bs->id, plock->context.smbpid, plock->context.tid, plock->fnum); + + END_PROFILE(syscall_brl_cancel); + if (error) { DEBUG(10, ("returning false\n")); bs->state = ONEFS_CBRL_ERROR; diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c index 9616ca48d5..2dcd8891eb 100644 --- a/source3/modules/onefs_streams.c +++ b/source3/modules/onefs_streams.c @@ -160,18 +160,26 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, char *nbase = NULL; char *nsname = NULL; + START_PROFILE(syscall_rename_at); + frame = talloc_stackframe(); ret = onefs_is_stream(oldname, &obase, &osname, &old_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } ret = onefs_is_stream(newname, &nbase, &nsname, &new_is_stream); - if (ret) + if (ret) { + END_PROFILE(syscall_rename_at); return ret; + } if (!old_is_stream && !new_is_stream) { - return SMB_VFS_NEXT_RENAME(handle, oldname, newname); + ret = SMB_VFS_NEXT_RENAME(handle, oldname, newname); + END_PROFILE(syscall_rename_at); + return ret; } dir_fd = get_stream_dir_fd(handle->conn, obase, NULL); @@ -192,6 +200,8 @@ int onefs_rename(vfs_handle_struct *handle, const char *oldname, } done: + END_PROFILE(syscall_rename_at); + saved_errno = errno; if (dir_fd >= 0) { close(dir_fd); diff --git a/source3/modules/onefs_system.c b/source3/modules/onefs_system.c index 76df006d82..518a398154 100644 --- a/source3/modules/onefs_system.c +++ b/source3/modules/onefs_system.c @@ -95,6 +95,8 @@ int onefs_sys_create_file(connection_struct *conn, uint32_t onefs_dos_attributes; struct ifs_createfile_flags cf_flags = CF_FLAGS_NONE; + START_PROFILE(syscall_createfile); + /* Setup security descriptor and get secinfo. */ if (sd != NULL) { NTSTATUS status; @@ -196,6 +198,7 @@ int onefs_sys_create_file(connection_struct *conn, } out: + END_PROFILE(syscall_createfile); aclu_free_sd(pifs_sd, false); return ret_fd; @@ -307,6 +310,8 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, bool atomic = false; ssize_t ret = 0; + START_PROFILE_BYTES(syscall_sendfile, count); + if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_ATOMIC_SENDFILE, PARM_ATOMIC_SENDFILE_DEFAULT)) { @@ -320,6 +325,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* If the sendfile wasn't atomic, we're done. */ if (!atomic) { DEBUG(10, ("non-atomic sendfile read %ul bytes", ret)); + END_PROFILE(syscall_sendfile); return ret; } @@ -391,6 +397,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, /* Handle case 1: short read -> truncated file. */ if (ret == 0) { + END_PROFILE(syscall_sendfile); return ret; } @@ -402,6 +409,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, PARM_SENDFILE_LARGE_READS_DEFAULT)) { DEBUG(3, ("Not attempting non-atomic large sendfile: " "%lu bytes\n", count)); + END_PROFILE(syscall_sendfile); return 0; } @@ -421,6 +429,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, DEBUG(1, ("error on non-atomic large sendfile " "(%lu bytes): %s\n", count, strerror(errno))); + END_PROFILE(syscall_sendfile); return ret; } @@ -439,9 +448,11 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE, PARM_SENDFILE_SAFE, PARM_SENDFILE_SAFE_DEFAULT)) { + END_PROFILE(syscall_sendfile); return -1; } + END_PROFILE(syscall_sendfile); return ret; } @@ -455,6 +466,7 @@ ssize_t onefs_sys_sendfile(connection_struct *conn, int tofd, int fromfd, count, strerror(errno))); } + END_PROFILE(syscall_sendfile); return ret; } @@ -509,10 +521,13 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, off_t rbytes; off_t wbytes; + START_PROFILE_BYTES(syscall_recvfile, count); + DEBUG(10,("onefs_recvfile: from = %d, to = %d, offset=%llu, count = " "%lu\n", fromfd, tofd, offset, count)); if (count == 0) { + END_PROFILE(syscall_recvfile); return 0; } @@ -624,6 +639,9 @@ ssize_t onefs_sys_recvfile(int fromfd, int tofd, SMB_OFF_T offset, ret = total_wbytes; out: + + END_PROFILE(syscall_recvfile); + /* Make sure we always try to drain the socket. */ if (!socket_drained && count - total_rbytes) { int saved_errno = errno; diff --git a/source3/profile/profile.c b/source3/profile/profile.c index bdbd805718..6d2d5ae06d 100644 --- a/source3/profile/profile.c +++ b/source3/profile/profile.c @@ -290,6 +290,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_rmdir", /* PR_VALUE_SYSCALL_RMDIR */ "syscall_closedir", /* PR_VALUE_SYSCALL_CLOSEDIR */ "syscall_open", /* PR_VALUE_SYSCALL_OPEN */ + "syscall_createfile", /* PR_VALUE_SYSCALL_CREATEFILE */ "syscall_close", /* PR_VALUE_SYSCALL_CLOSE */ "syscall_read", /* PR_VALUE_SYSCALL_READ */ "syscall_pread", /* PR_VALUE_SYSCALL_PREAD */ @@ -299,6 +300,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_sendfile", /* PR_VALUE_SYSCALL_SENDFILE */ "syscall_recvfile", /* PR_VALUE_SYSCALL_RECVFILE */ "syscall_rename", /* PR_VALUE_SYSCALL_RENAME */ + "syscall_rename_at", /* PR_VALUE_SYSCALL_RENAME_AT */ "syscall_fsync", /* PR_VALUE_SYSCALL_FSYNC */ "syscall_stat", /* PR_VALUE_SYSCALL_STAT */ "syscall_fstat", /* PR_VALUE_SYSCALL_FSTAT */ @@ -323,6 +325,11 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly) "syscall_realpath", /* PR_VALUE_SYSCALL_REALPATH */ "syscall_get_quota", /* PR_VALUE_SYSCALL_GET_QUOTA */ "syscall_set_quota", /* PR_VALUE_SYSCALL_SET_QUOTA */ + "syscall_get_sd", /* PR_VALUE_SYSCALL_GET_SD */ + "syscall_set_sd", /* PR_VALUE_SYSCALL_SET_SD */ + "syscall_brl_lock", /* PR_VALUE_SYSCALL_BRL_LOCK */ + "syscall_brl_unlock", /* PR_VALUE_SYSCALL_BRL_UNLOCK */ + "syscall_brl_cancel", /* PR_VALUE_SYSCALL_BRL_CANCEL */ "SMBmkdir", /* PR_VALUE_SMBMKDIR */ "SMBrmdir", /* PR_VALUE_SMBRMDIR */ "SMBopen", /* PR_VALUE_SMBOPEN */ -- cgit From 4e024b3f87ee1ccb0d7c83dfc6a4b5a6b2c47c13 Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Tue, 24 Feb 2009 14:12:48 -0800 Subject: s3: onefs_acl.c cleanup Remove some duplicate code. Add a \n to a debugging statement --- source3/modules/onefs_acl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index b463722e61..b8097b6455 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -273,9 +273,6 @@ onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl, if (aclu_initialize_acl(acl, aces, num_aces)) goto err_free; - if (aclu_initialize_acl(acl, aces, num_aces)) - goto err_free; - /* Currently aclu_initialize_acl should copy the aces over, allowing * us to immediately free */ free(aces); @@ -905,7 +902,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, SNUM(handle->conn)); if (!NT_STATUS_IS_OK(status)) { - DEBUG(3, ("SD initialization failure: %s", nt_errstr(status))); + DEBUG(3, ("SD initialization failure: %s\n", nt_errstr(status))); goto out; } -- cgit From aeab22b55cb1484ff6da7242bd525e30b69e5752 Mon Sep 17 00:00:00 2001 From: Dan Sledz Date: Mon, 23 Feb 2009 23:21:13 -0800 Subject: s3: Rename auth_onefs_wb and pdb_onefs_sam auth_onefs_wb.c -> auth_wbc.c pdb_onefs_sam.c -> pdb_wbc_sam.c No changes to functionality --- source3/Makefile.in | 10 +- source3/auth/auth_onefs_wb.c | 134 ------------ source3/auth/auth_wbc.c | 150 ++++++++++++++ source3/configure.in | 8 +- source3/passdb/pdb_onefs_sam.c | 433 --------------------------------------- source3/passdb/pdb_wbc_sam.c | 448 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 607 insertions(+), 576 deletions(-) delete mode 100644 source3/auth/auth_onefs_wb.c create mode 100644 source3/auth/auth_wbc.c delete mode 100644 source3/passdb/pdb_onefs_sam.c create mode 100644 source3/passdb/pdb_wbc_sam.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 73b2989421..8f1d1a5b77 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -689,7 +689,7 @@ AUTH_SAM_OBJ = auth/auth_sam.o AUTH_SERVER_OBJ = auth/auth_server.o AUTH_UNIX_OBJ = auth/auth_unix.o AUTH_WINBIND_OBJ = auth/auth_winbind.o -AUTH_ONEFS_WB_OBJ = auth/auth_onefs_wb.o +AUTH_WBC_OBJ = auth/auth_wbc.o AUTH_SCRIPT_OBJ = auth/auth_script.o AUTH_NETLOGOND_OBJ = auth/auth_netlogond.o @@ -2355,9 +2355,9 @@ bin/winbind.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WINBIND_OBJ) @echo "Building plugin $@" @$(SHLD_MODULE) $(AUTH_WINBIND_OBJ) -bin/onefs_wb.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_ONEFS_WB_OBJ) +bin/wbc.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_WBC_OBJ) @echo "Building plugin $@" - @$(SHLD_MODULE) $(AUTH_ONEFS_WB_OBJ) + @$(SHLD_MODULE) $(AUTH_WBC_OBJ) bin/unix.@SHLIBEXT@: $(BINARY_PREREQS) $(AUTH_UNIX_OBJ) @echo "Building plugin $@" @@ -2375,9 +2375,9 @@ bin/tdbsam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_tdb.o @echo "Building plugin $@" @$(SHLD_MODULE) passdb/pdb_tdb.o -bin/onefs_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_onefs_sam.o +bin/wbc_sam.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_wbc_sam.o @echo "Building plugin $@" - @$(SHLD_MODULE) passdb/pdb_onefs_sam.o + @$(SHLD_MODULE) passdb/pdb_wbc_sam.o bin/smbpasswd.@SHLIBEXT@: $(BINARY_PREREQS) passdb/pdb_smbpasswd.o @echo "Building plugin $@" diff --git a/source3/auth/auth_onefs_wb.c b/source3/auth/auth_onefs_wb.c deleted file mode 100644 index 49de6966b0..0000000000 --- a/source3/auth/auth_onefs_wb.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Winbind authentication mechnism, customized for onefs - - Copyright (C) Tim Potter 2000 - Copyright (C) Andrew Bartlett 2001 - 2002 - Copyright (C) Dan Sledz 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - -/* Authenticate a user with a challenge/response */ - -static NTSTATUS check_onefs_wb_security(const struct auth_context *auth_context, - void *my_private_data, - TALLOC_CTX *mem_ctx, - const auth_usersupplied_info *user_info, - auth_serversupplied_info **server_info) -{ - NTSTATUS nt_status; - wbcErr wbc_status; - struct wbcAuthUserParams params; - struct wbcAuthUserInfo *info = NULL; - struct wbcAuthErrorInfo *err = NULL; - - if (!user_info || !auth_context || !server_info) { - return NT_STATUS_INVALID_PARAMETER; - } - /* Send off request */ - - params.account_name = user_info->smb_name; - params.domain_name = user_info->domain; - params.workstation_name = user_info->wksta_name; - - params.flags = 0; - params.parameter_control= user_info->logon_parameters; - - /* Handle plaintext */ - if (!user_info->encrypted) { - DEBUG(3,("Checking plaintext password for %s.\n", - user_info->internal_username)); - params.level = WBC_AUTH_USER_LEVEL_PLAIN; - - params.password.plaintext = user_info->plaintext_password.data; - } else { - DEBUG(3,("Checking encrypted password for %s.\n", - user_info->internal_username)); - params.level = WBC_AUTH_USER_LEVEL_RESPONSE; - - memcpy(params.password.response.challenge, - auth_context->challenge.data, - sizeof(params.password.response.challenge)); - - params.password.response.nt_length = user_info->nt_resp.length; - params.password.response.nt_data = user_info->nt_resp.data; - params.password.response.lm_length = user_info->lm_resp.length; - params.password.response.lm_data = user_info->lm_resp.data; - - } - - /* we are contacting the privileged pipe */ - become_root(); - wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); - unbecome_root(); - - if (!WBC_ERROR_IS_OK(wbc_status)) { - DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n", - wbc_status, wbcErrorString(wbc_status))); - } - - if (wbc_status == WBC_ERR_NO_MEMORY) { - return NT_STATUS_NO_MEMORY; - } - - if (wbc_status == WBC_ERR_AUTH_ERROR) { - nt_status = NT_STATUS(err->nt_status); - wbcFreeMemory(err); - return nt_status; - } - - if (!WBC_ERROR_IS_OK(wbc_status)) { - return NT_STATUS_LOGON_FAILURE; - } - - DEBUG(10,("wbcAuthenticateUserEx succeeded\n")); - - nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, - user_info->smb_name, - user_info->domain, - info, server_info); - wbcFreeMemory(info); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - - (*server_info)->nss_token |= user_info->was_mapped; - - return nt_status; -} - -/* module initialisation */ -static NTSTATUS auth_init_onefs_wb(struct auth_context *auth_context, const char *param, auth_methods **auth_method) -{ - if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; - } - - (*auth_method)->name = "onefs_wb"; - (*auth_method)->auth = check_onefs_wb_security; - - return NT_STATUS_OK; -} - -NTSTATUS auth_onefs_wb_init(void) -{ - return smb_register_auth(AUTH_INTERFACE_VERSION, "onefs_wb", auth_init_onefs_wb); -} diff --git a/source3/auth/auth_wbc.c b/source3/auth/auth_wbc.c new file mode 100644 index 0000000000..b0af9ffb1d --- /dev/null +++ b/source3/auth/auth_wbc.c @@ -0,0 +1,150 @@ +/* + Unix SMB/CIFS implementation. + + Winbind client authentication mechanism designed to defer all + authentication to the winbind daemon. + + Copyright (C) Tim Potter 2000 + Copyright (C) Andrew Bartlett 2001 - 2002 + Copyright (C) Dan Sledz 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* This auth module is very similar to auth_winbind with 3 distinct + * differences. + * + * 1) Does not fallback to another auth module if winbindd is unavailable + * 2) Does not validate the domain of the user + * 3) Handles unencrypted passwords + * + * The purpose of this module is to defer all authentication decisions (ie: + * local user vs NIS vs LDAP vs AD; encrypted vs plaintext) to the wbc + * compatible daemon. This centeralizes all authentication decisions to a + * single provider. + * + * This auth backend is most useful when used in conjunction with pdb_wbc_sam. + */ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +/* Authenticate a user with a challenge/response */ + +static NTSTATUS check_wbc_security(const struct auth_context *auth_context, + void *my_private_data, + TALLOC_CTX *mem_ctx, + const auth_usersupplied_info *user_info, + auth_serversupplied_info **server_info) +{ + NTSTATUS nt_status; + wbcErr wbc_status; + struct wbcAuthUserParams params; + struct wbcAuthUserInfo *info = NULL; + struct wbcAuthErrorInfo *err = NULL; + + if (!user_info || !auth_context || !server_info) { + return NT_STATUS_INVALID_PARAMETER; + } + /* Send off request */ + + params.account_name = user_info->smb_name; + params.domain_name = user_info->domain; + params.workstation_name = user_info->wksta_name; + + params.flags = 0; + params.parameter_control= user_info->logon_parameters; + + /* Handle plaintext */ + if (!user_info->encrypted) { + DEBUG(3,("Checking plaintext password for %s.\n", + user_info->internal_username)); + params.level = WBC_AUTH_USER_LEVEL_PLAIN; + + params.password.plaintext = user_info->plaintext_password.data; + } else { + DEBUG(3,("Checking encrypted password for %s.\n", + user_info->internal_username)); + params.level = WBC_AUTH_USER_LEVEL_RESPONSE; + + memcpy(params.password.response.challenge, + auth_context->challenge.data, + sizeof(params.password.response.challenge)); + + params.password.response.nt_length = user_info->nt_resp.length; + params.password.response.nt_data = user_info->nt_resp.data; + params.password.response.lm_length = user_info->lm_resp.length; + params.password.response.lm_data = user_info->lm_resp.data; + + } + + /* we are contacting the privileged pipe */ + become_root(); + wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); + unbecome_root(); + + if (!WBC_ERROR_IS_OK(wbc_status)) { + DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n", + wbc_status, wbcErrorString(wbc_status))); + } + + if (wbc_status == WBC_ERR_NO_MEMORY) { + return NT_STATUS_NO_MEMORY; + } + + if (wbc_status == WBC_ERR_AUTH_ERROR) { + nt_status = NT_STATUS(err->nt_status); + wbcFreeMemory(err); + return nt_status; + } + + if (!WBC_ERROR_IS_OK(wbc_status)) { + return NT_STATUS_LOGON_FAILURE; + } + + DEBUG(10,("wbcAuthenticateUserEx succeeded\n")); + + nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, + user_info->smb_name, + user_info->domain, + info, server_info); + wbcFreeMemory(info); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + (*server_info)->nss_token |= user_info->was_mapped; + + return nt_status; +} + +/* module initialisation */ +static NTSTATUS auth_init_wbc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +{ + if (!make_auth_methods(auth_context, auth_method)) { + return NT_STATUS_NO_MEMORY; + } + + (*auth_method)->name = "wbc"; + (*auth_method)->auth = check_wbc_security; + + return NT_STATUS_OK; +} + +NTSTATUS auth_wbc_init(void) +{ + return smb_register_auth(AUTH_INTERFACE_VERSION, "wbc", auth_init_wbc); +} diff --git a/source3/configure.in b/source3/configure.in index bd3d4af40b..d67feccb9b 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -414,7 +414,7 @@ AC_SUBST(DYNEXP) dnl Add modules that have to be built by default here dnl These have to be built static: -default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" +default_static_modules="pdb_smbpasswd pdb_tdbsam pdb_wbc_sam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl rpc_ntsvcs rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss2 rpc_eventlog auth_sam auth_unix auth_winbind auth_wbc auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_streams_depot vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer" @@ -1088,7 +1088,7 @@ echo $samba_cv_HAVE_ONEFS if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS]) default_shared_modules="$default_shared_modules vfs_onefs vfs_onefs_shadow_copy perfcount_onefs" - default_static_modules="$default_static_modules auth_onefs_wb pdb_onefs_sam" + default_static_modules="$default_static_modules" ONEFS_LIBS="-lisi_acl -lisi_ecs -lisi_event -lisi_util" # Need to also add general libs for oplocks support save_LIBS="$save_LIBS -lisi_ecs -lisi_event -lisi_util -ldevstat" @@ -6130,7 +6130,7 @@ SMB_MODULE(pdb_ldap, passdb/pdb_ldap.o passdb/pdb_nds.o, "bin/ldapsam.$SHLIBEXT" [ PASSDB_LIBS="$PASSDB_LIBS $LDAP_LIBS" ] ) SMB_MODULE(pdb_smbpasswd, passdb/pdb_smbpasswd.o, "bin/smbpasswd.$SHLIBEXT", PDB) SMB_MODULE(pdb_tdbsam, passdb/pdb_tdb.o, "bin/tdbsam.$SHLIBEXT", PDB) -SMB_MODULE(pdb_onefs_sam, passdb/pdb_onefs_sam.o, "bin/onefs_sam.$SHLIBEXT", PDB) +SMB_MODULE(pdb_wbc_sam, passdb/pdb_wbc_sam.o, "bin/wbc_sam.$SHLIBEXT", PDB) SMB_SUBSYSTEM(PDB,passdb/pdb_interface.o) @@ -6173,7 +6173,7 @@ SMB_SUBSYSTEM(CHARSET,lib/iconv.o) SMB_MODULE(auth_sam, \$(AUTH_SAM_OBJ), "bin/sam.$SHLIBEXT", AUTH) SMB_MODULE(auth_unix, \$(AUTH_UNIX_OBJ), "bin/unix.$SHLIBEXT", AUTH) SMB_MODULE(auth_winbind, \$(AUTH_WINBIND_OBJ), "bin/winbind.$SHLIBEXT", AUTH) -SMB_MODULE(auth_onefs_wb, \$(AUTH_ONEFS_WB_OBJ), "bin/onefs_wb.$SHLIBEXT", AUTH) +SMB_MODULE(auth_wbc, \$(AUTH_WBC_OBJ), "bin/wbc.$SHLIBEXT", AUTH) SMB_MODULE(auth_server, \$(AUTH_SERVER_OBJ), "bin/smbserver.$SHLIBEXT", AUTH) SMB_MODULE(auth_domain, \$(AUTH_DOMAIN_OBJ), "bin/domain.$SHLIBEXT", AUTH) SMB_MODULE(auth_builtin, \$(AUTH_BUILTIN_OBJ), "bin/builtin.$SHLIBEXT", AUTH) diff --git a/source3/passdb/pdb_onefs_sam.c b/source3/passdb/pdb_onefs_sam.c deleted file mode 100644 index 51b8618aad..0000000000 --- a/source3/passdb/pdb_onefs_sam.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling for wbclient - Copyright (C) Andrew Bartlett 2002 - Copyright (C) Jelmer Vernooij 2002 - Copyright (C) Simo Sorce 2003 - Copyright (C) Volker Lendecke 2006 - Copyright (C) Dan Sledz 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -/*************************************************************************** - Default implementations of some functions. - ****************************************************************************/ -static NTSTATUS _pdb_onefs_sam_getsampw(struct pdb_methods *methods, - struct samu *user, - const struct passwd *pwd) -{ - NTSTATUS result = NT_STATUS_OK; - - if (pwd == NULL) - return NT_STATUS_NO_SUCH_USER; - - memset(user, 0, sizeof(user)); - - /* Can we really get away with this little of information */ - user->methods = methods; - result = samu_set_unix(user, pwd); - - return result; -} - -static NTSTATUS pdb_onefs_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) -{ - return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwnam(sname)); -} - -static NTSTATUS pdb_onefs_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) -{ - return _pdb_onefs_sam_getsampw(methods, user, winbind_getpwsid(sid)); -} - -static bool pdb_onefs_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, - DOM_SID *sid) -{ - return winbind_uid_to_sid(sid, uid); -} - -static bool pdb_onefs_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, - DOM_SID *sid) -{ - return winbind_gid_to_sid(sid, gid); -} - -static bool pdb_onefs_sam_sid_to_id(struct pdb_methods *methods, - const DOM_SID *sid, - union unid_t *id, enum lsa_SidType *type) -{ - if (winbind_sid_to_uid(&id->uid, sid)) { - *type = SID_NAME_USER; - } else if (winbind_sid_to_gid(&id->gid, sid)) { - /* We assume all gids are groups, not aliases */ - *type = SID_NAME_DOM_GRP; - } else { - return false; - } - - return true; -} - -static NTSTATUS pdb_onefs_sam_enum_group_members(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - const DOM_SID *group, - uint32 **pp_member_rids, - size_t *p_num_members) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_enum_group_memberships(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - struct samu *user, - DOM_SID **pp_sids, - gid_t **pp_gids, - size_t *p_num_groups) -{ - size_t i; - const char *username = pdb_get_username(user); - - if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { - return NT_STATUS_NO_SUCH_USER; - } - - if (*p_num_groups == 0) { - smb_panic("primary group missing"); - } - - *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups); - - if (*pp_sids == NULL) { - TALLOC_FREE(*pp_gids); - return NT_STATUS_NO_MEMORY; - } - - for (i=0; i < *p_num_groups; i++) { - gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]); - } - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_onefs_sam_lookup_rids(struct pdb_methods *methods, - const DOM_SID *domain_sid, - int num_rids, - uint32 *rids, - const char **names, - enum lsa_SidType *attrs) -{ - NTSTATUS result = NT_STATUS_OK; - char *domain = NULL; - char **account_names = NULL; - char name[256]; - enum lsa_SidType *attr_list = NULL; - int i; - - if (!winbind_lookup_rids(talloc_tos(), domain_sid, num_rids, rids, - (const char **)&domain, - (const char ***)&account_names, &attr_list)) - { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - - memcpy(attrs, attr_list, num_rids * sizeof(enum lsa_SidType)); - - for (i=0; int_name, sizeof(map->nt_name), "%s%c%s", - domain, *lp_winbind_separator(), name); - map->sid_name_use = name_type; - map->sid = *sid; - map->gid = gid; - return true; -} - -static NTSTATUS pdb_onefs_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, - DOM_SID sid) -{ - NTSTATUS result = NT_STATUS_OK; - char *name = NULL; - char *domain = NULL; - enum lsa_SidType name_type; - gid_t gid; - - if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, - (const char **) &name, &name_type)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if ((name_type != SID_NAME_DOM_GRP) && - (name_type != SID_NAME_DOMAIN) && - (name_type != SID_NAME_ALIAS) && - (name_type != SID_NAME_WKN_GRP)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!winbind_sid_to_gid(&gid, &sid)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - -done: - TALLOC_FREE(name); - TALLOC_FREE(domain); - return result; -} - -static NTSTATUS pdb_onefs_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, - gid_t gid) -{ - NTSTATUS result = NT_STATUS_OK; - char *name = NULL; - char *domain = NULL; - DOM_SID sid; - enum lsa_SidType name_type; - - if (!winbind_gid_to_sid(&sid, gid)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, - (const char **)&name, &name_type)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if ((name_type != SID_NAME_DOM_GRP) && - (name_type != SID_NAME_DOMAIN) && - (name_type != SID_NAME_ALIAS) && - (name_type != SID_NAME_WKN_GRP)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - -done: - TALLOC_FREE(name); - TALLOC_FREE(domain); - - return result; -} - -static NTSTATUS pdb_onefs_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, - const char *name) -{ - NTSTATUS result = NT_STATUS_OK; - char *user_name = NULL; - char *domain = NULL; - DOM_SID sid; - gid_t gid; - enum lsa_SidType name_type; - - if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if ((name_type != SID_NAME_DOM_GRP) && - (name_type != SID_NAME_DOMAIN) && - (name_type != SID_NAME_ALIAS) && - (name_type != SID_NAME_WKN_GRP)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!winbind_sid_to_gid(&gid, &sid)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - - if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { - result = NT_STATUS_NO_SUCH_GROUP; - goto done; - } - -done: - - return result; -} - -static NTSTATUS pdb_onefs_sam_enum_group_mapping(struct pdb_methods *methods, - const DOM_SID *sid, enum lsa_SidType sid_name_use, - GROUP_MAP **pp_rmap, size_t *p_num_entries, - bool unix_only) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_get_aliasinfo(struct pdb_methods *methods, - const DOM_SID *sid, - struct acct_info *info) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_enum_aliasmem(struct pdb_methods *methods, - const DOM_SID *alias, DOM_SID **pp_members, - size_t *p_num_members) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -static NTSTATUS pdb_onefs_sam_alias_memberships(struct pdb_methods *methods, - TALLOC_CTX *mem_ctx, - const DOM_SID *domain_sid, - const DOM_SID *members, - size_t num_members, - uint32 **pp_alias_rids, - size_t *p_num_alias_rids) -{ - if (!winbind_get_sid_aliases(mem_ctx, domain_sid, - members, num_members, pp_alias_rids, p_num_alias_rids)) - return NT_STATUS_UNSUCCESSFUL; - - return NT_STATUS_OK; -} - -static NTSTATUS pdb_init_onefs_sam(struct pdb_methods **pdb_method, const char *location) -{ - NTSTATUS result; - - if (!NT_STATUS_IS_OK(result = make_pdb_method( pdb_method))) { - return result; - } - - (*pdb_method)->name = "onefs_sam"; - - (*pdb_method)->getsampwnam = pdb_onefs_sam_getsampwnam; - (*pdb_method)->getsampwsid = pdb_onefs_sam_getsampwsid; - - (*pdb_method)->getgrsid = pdb_onefs_sam_getgrsid; - (*pdb_method)->getgrgid = pdb_onefs_sam_getgrgid; - (*pdb_method)->getgrnam = pdb_onefs_sam_getgrnam; - (*pdb_method)->enum_group_mapping = pdb_onefs_sam_enum_group_mapping; - (*pdb_method)->enum_group_members = pdb_onefs_sam_enum_group_members; - (*pdb_method)->enum_group_memberships = pdb_onefs_sam_enum_group_memberships; - (*pdb_method)->get_aliasinfo = pdb_onefs_sam_get_aliasinfo; - (*pdb_method)->enum_aliasmem = pdb_onefs_sam_enum_aliasmem; - (*pdb_method)->enum_alias_memberships = pdb_onefs_sam_alias_memberships; - (*pdb_method)->lookup_rids = pdb_onefs_sam_lookup_rids; - (*pdb_method)->get_account_policy = pdb_onefs_sam_get_account_policy; - (*pdb_method)->set_account_policy = pdb_onefs_sam_set_account_policy; - (*pdb_method)->uid_to_sid = pdb_onefs_sam_uid_to_sid; - (*pdb_method)->gid_to_sid = pdb_onefs_sam_gid_to_sid; - (*pdb_method)->sid_to_id = pdb_onefs_sam_sid_to_id; - - (*pdb_method)->search_groups = pdb_onefs_sam_search_groups; - (*pdb_method)->search_aliases = pdb_onefs_sam_search_aliases; - - (*pdb_method)->get_trusteddom_pw = pdb_onefs_sam_get_trusteddom_pw; - (*pdb_method)->set_trusteddom_pw = pdb_onefs_sam_set_trusteddom_pw; - (*pdb_method)->del_trusteddom_pw = pdb_onefs_sam_del_trusteddom_pw; - (*pdb_method)->enum_trusteddoms = pdb_onefs_sam_enum_trusteddoms; - - (*pdb_method)->private_data = NULL; - (*pdb_method)->free_private_data = NULL; - - return NT_STATUS_OK; -} - -NTSTATUS pdb_onefs_sam_init(void) -{ - return smb_register_passdb(PASSDB_INTERFACE_VERSION, "onefs_sam", pdb_init_onefs_sam); -} diff --git a/source3/passdb/pdb_wbc_sam.c b/source3/passdb/pdb_wbc_sam.c new file mode 100644 index 0000000000..33dc03fe4c --- /dev/null +++ b/source3/passdb/pdb_wbc_sam.c @@ -0,0 +1,448 @@ +/* + Unix SMB/CIFS implementation. + + Password and authentication handling by wbclient + + Copyright (C) Andrew Bartlett 2002 + Copyright (C) Jelmer Vernooij 2002 + Copyright (C) Simo Sorce 2003 + Copyright (C) Volker Lendecke 2006 + Copyright (C) Dan Sledz 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* This passdb module retrieves full passdb information for local users and + * groups from a wbclient compatible daemon. + * + * The purpose of this module is to defer all SAM authorization information + * storage and retrieval to a wbc compatible daemon. + * + * This passdb backend is most useful when used in conjunction with auth_wbc. + * + * A few current limitations of this module are: + * - read only interface + * - no privileges + */ + +#include "includes.h" + +/*************************************************************************** + Default implementations of some functions. + ****************************************************************************/ +static NTSTATUS _pdb_wbc_sam_getsampw(struct pdb_methods *methods, + struct samu *user, + const struct passwd *pwd) +{ + NTSTATUS result = NT_STATUS_OK; + + if (pwd == NULL) + return NT_STATUS_NO_SUCH_USER; + + memset(user, 0, sizeof(user)); + + /* Can we really get away with this little of information */ + user->methods = methods; + result = samu_set_unix(user, pwd); + + return result; +} + +static NTSTATUS pdb_wbc_sam_getsampwnam(struct pdb_methods *methods, struct samu *user, const char *sname) +{ + return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwnam(sname)); +} + +static NTSTATUS pdb_wbc_sam_getsampwsid(struct pdb_methods *methods, struct samu *user, const DOM_SID *sid) +{ + return _pdb_wbc_sam_getsampw(methods, user, winbind_getpwsid(sid)); +} + +static bool pdb_wbc_sam_uid_to_sid(struct pdb_methods *methods, uid_t uid, + DOM_SID *sid) +{ + return winbind_uid_to_sid(sid, uid); +} + +static bool pdb_wbc_sam_gid_to_sid(struct pdb_methods *methods, gid_t gid, + DOM_SID *sid) +{ + return winbind_gid_to_sid(sid, gid); +} + +static bool pdb_wbc_sam_sid_to_id(struct pdb_methods *methods, + const DOM_SID *sid, + union unid_t *id, enum lsa_SidType *type) +{ + if (winbind_sid_to_uid(&id->uid, sid)) { + *type = SID_NAME_USER; + } else if (winbind_sid_to_gid(&id->gid, sid)) { + /* We assume all gids are groups, not aliases */ + *type = SID_NAME_DOM_GRP; + } else { + return false; + } + + return true; +} + +static NTSTATUS pdb_wbc_sam_enum_group_members(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + const DOM_SID *group, + uint32 **pp_member_rids, + size_t *p_num_members) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_enum_group_memberships(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + struct samu *user, + DOM_SID **pp_sids, + gid_t **pp_gids, + size_t *p_num_groups) +{ + size_t i; + const char *username = pdb_get_username(user); + + if (!winbind_get_groups(mem_ctx, username, p_num_groups, pp_gids)) { + return NT_STATUS_NO_SUCH_USER; + } + + if (*p_num_groups == 0) { + smb_panic("primary group missing"); + } + + *pp_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *p_num_groups); + + if (*pp_sids == NULL) { + TALLOC_FREE(*pp_gids); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i < *p_num_groups; i++) { + gid_to_sid(&(*pp_sids)[i], (*pp_gids)[i]); + } + + return NT_STATUS_OK; +} + +static NTSTATUS pdb_wbc_sam_lookup_rids(struct pdb_methods *methods, + const DOM_SID *domain_sid, + int num_rids, + uint32 *rids, + const char **names, + enum lsa_SidType *attrs) +{ + NTSTATUS result = NT_STATUS_OK; + char *domain = NULL; + char **account_names = NULL; + char name[256]; + enum lsa_SidType *attr_list = NULL; + int i; + + if (!winbind_lookup_rids(talloc_tos(), domain_sid, num_rids, rids, + (const char **)&domain, + (const char ***)&account_names, &attr_list)) + { + result = NT_STATUS_NONE_MAPPED; + goto done; + } + + memcpy(attrs, attr_list, num_rids * sizeof(enum lsa_SidType)); + + for (i=0; int_name, sizeof(map->nt_name), "%s%c%s", + domain, *lp_winbind_separator(), name); + map->sid_name_use = name_type; + map->sid = *sid; + map->gid = gid; + return true; +} + +static NTSTATUS pdb_wbc_sam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map, + DOM_SID sid) +{ + NTSTATUS result = NT_STATUS_OK; + char *name = NULL; + char *domain = NULL; + enum lsa_SidType name_type; + gid_t gid; + + if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, + (const char **) &name, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_sid_to_gid(&gid, &sid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + TALLOC_FREE(name); + TALLOC_FREE(domain); + return result; +} + +static NTSTATUS pdb_wbc_sam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map, + gid_t gid) +{ + NTSTATUS result = NT_STATUS_OK; + char *name = NULL; + char *domain = NULL; + DOM_SID sid; + enum lsa_SidType name_type; + + if (!winbind_gid_to_sid(&sid, gid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_lookup_sid(talloc_tos(), &sid, (const char **)&domain, + (const char **)&name, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + TALLOC_FREE(name); + TALLOC_FREE(domain); + + return result; +} + +static NTSTATUS pdb_wbc_sam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map, + const char *name) +{ + NTSTATUS result = NT_STATUS_OK; + char *user_name = NULL; + char *domain = NULL; + DOM_SID sid; + gid_t gid; + enum lsa_SidType name_type; + + if (!winbind_lookup_name(domain, user_name, &sid, &name_type)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if ((name_type != SID_NAME_DOM_GRP) && + (name_type != SID_NAME_DOMAIN) && + (name_type != SID_NAME_ALIAS) && + (name_type != SID_NAME_WKN_GRP)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!winbind_sid_to_gid(&gid, &sid)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + + if (!_make_group_map(methods, domain, user_name, name_type, gid, &sid, map)) { + result = NT_STATUS_NO_SUCH_GROUP; + goto done; + } + +done: + + return result; +} + +static NTSTATUS pdb_wbc_sam_enum_group_mapping(struct pdb_methods *methods, + const DOM_SID *sid, enum lsa_SidType sid_name_use, + GROUP_MAP **pp_rmap, size_t *p_num_entries, + bool unix_only) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_get_aliasinfo(struct pdb_methods *methods, + const DOM_SID *sid, + struct acct_info *info) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_enum_aliasmem(struct pdb_methods *methods, + const DOM_SID *alias, DOM_SID **pp_members, + size_t *p_num_members) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +static NTSTATUS pdb_wbc_sam_alias_memberships(struct pdb_methods *methods, + TALLOC_CTX *mem_ctx, + const DOM_SID *domain_sid, + const DOM_SID *members, + size_t num_members, + uint32 **pp_alias_rids, + size_t *p_num_alias_rids) +{ + if (!winbind_get_sid_aliases(mem_ctx, domain_sid, + members, num_members, pp_alias_rids, p_num_alias_rids)) + return NT_STATUS_UNSUCCESSFUL; + + return NT_STATUS_OK; +} + +static NTSTATUS pdb_init_wbc_sam(struct pdb_methods **pdb_method, const char *location) +{ + NTSTATUS result; + + if (!NT_STATUS_IS_OK(result = make_pdb_method( pdb_method))) { + return result; + } + + (*pdb_method)->name = "wbc_sam"; + + (*pdb_method)->getsampwnam = pdb_wbc_sam_getsampwnam; + (*pdb_method)->getsampwsid = pdb_wbc_sam_getsampwsid; + + (*pdb_method)->getgrsid = pdb_wbc_sam_getgrsid; + (*pdb_method)->getgrgid = pdb_wbc_sam_getgrgid; + (*pdb_method)->getgrnam = pdb_wbc_sam_getgrnam; + (*pdb_method)->enum_group_mapping = pdb_wbc_sam_enum_group_mapping; + (*pdb_method)->enum_group_members = pdb_wbc_sam_enum_group_members; + (*pdb_method)->enum_group_memberships = pdb_wbc_sam_enum_group_memberships; + (*pdb_method)->get_aliasinfo = pdb_wbc_sam_get_aliasinfo; + (*pdb_method)->enum_aliasmem = pdb_wbc_sam_enum_aliasmem; + (*pdb_method)->enum_alias_memberships = pdb_wbc_sam_alias_memberships; + (*pdb_method)->lookup_rids = pdb_wbc_sam_lookup_rids; + (*pdb_method)->get_account_policy = pdb_wbc_sam_get_account_policy; + (*pdb_method)->set_account_policy = pdb_wbc_sam_set_account_policy; + (*pdb_method)->uid_to_sid = pdb_wbc_sam_uid_to_sid; + (*pdb_method)->gid_to_sid = pdb_wbc_sam_gid_to_sid; + (*pdb_method)->sid_to_id = pdb_wbc_sam_sid_to_id; + + (*pdb_method)->search_groups = pdb_wbc_sam_search_groups; + (*pdb_method)->search_aliases = pdb_wbc_sam_search_aliases; + + (*pdb_method)->get_trusteddom_pw = pdb_wbc_sam_get_trusteddom_pw; + (*pdb_method)->set_trusteddom_pw = pdb_wbc_sam_set_trusteddom_pw; + (*pdb_method)->del_trusteddom_pw = pdb_wbc_sam_del_trusteddom_pw; + (*pdb_method)->enum_trusteddoms = pdb_wbc_sam_enum_trusteddoms; + + (*pdb_method)->private_data = NULL; + (*pdb_method)->free_private_data = NULL; + + return NT_STATUS_OK; +} + +NTSTATUS pdb_wbc_sam_init(void) +{ + return smb_register_passdb(PASSDB_INTERFACE_VERSION, "wbc_sam", pdb_init_wbc_sam); +} -- cgit From cde5724780c0e52705e0f6e7cd41e0c884afbb40 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 17:32:22 -0800 Subject: Added torture test from a usage case from the Apple OS/X client. Setting an attribute on a stream fnum must change the attribute on the base file. Jeremy. --- source4/torture/raw/streams.c | 119 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c index 0622e0809d..bf87bd224f 100644 --- a/source4/torture/raw/streams.c +++ b/source4/torture/raw/streams.c @@ -1535,6 +1535,121 @@ static bool test_stream_large_streaminfo(struct torture_context *tctx, return ret; } +/* Test the effect of setting attributes on a stream. */ +static bool test_stream_attributes(struct torture_context *tctx, + struct smbcli_state *cli, + TALLOC_CTX *mem_ctx) +{ + bool ret = true; + NTSTATUS status; + union smb_open io; + const char *fname = BASEDIR "\\stream_attr.txt"; + const char *stream = "Stream One:$DATA"; + const char *fname_stream; + int fnum = -1; + union smb_fileinfo finfo; + union smb_setfileinfo sfinfo; + time_t basetime = (time(NULL) - 86400) & ~1; + + printf ("(%s) testing attribute setting on stream\n", __location__); + + fname_stream = talloc_asprintf(mem_ctx, "%s:%s", fname, stream); + + /* Create a file with a stream with attribute FILE_ATTRIBUTE_ARCHIVE. */ + ret = create_file_with_stream(tctx, cli, mem_ctx, fname, + fname_stream); + if (!ret) { + goto done; + } + + ZERO_STRUCT(finfo); + finfo.generic.level = RAW_FILEINFO_BASIC_INFO; + finfo.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + CHECK_STATUS(status, NT_STATUS_OK); + + if (finfo.basic_info.out.attrib != FILE_ATTRIBUTE_ARCHIVE) { + printf("(%s) Incorrect attrib %x - should be %x\n", \ + __location__, (unsigned int)finfo.basic_info.out.attrib, + (unsigned int)FILE_ATTRIBUTE_ARCHIVE); + ret = false; + goto done; + } + + /* Now open the stream name. */ + + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA| + SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL|SEC_FILE_WRITE_ATTRIBUTE); + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.file_attr = 0; + io.ntcreatex.in.share_access = 0; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname_stream; + + status = smb_raw_open(cli->tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + fnum = io.ntcreatex.out.file.fnum; + + /* Change the attributes + time on the stream fnum. */ + ZERO_STRUCT(sfinfo); + sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY; + unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime); + + sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION; + sfinfo.generic.in.file.fnum = fnum; + status = smb_raw_setfileinfo(cli->tree, &sfinfo); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { + printf("(%s) %s - %s (should be %s)\n", __location__, "SETATTR", + nt_errstr(status), nt_errstr(NT_STATUS_OK)); + ret = false; + goto done; + } + + smbcli_close(cli->tree, fnum); + fnum = -1; + + ZERO_STRUCT(finfo); + finfo.generic.level = RAW_FILEINFO_ALL_INFO; + finfo.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (!NT_STATUS_IS_OK(status)) { + printf("(%s) %s pathinfo - %s\n", __location__, "SETATTRE", nt_errstr(status)); + ret = false; + goto done; + } + + if (finfo.all_info.out.attrib != FILE_ATTRIBUTE_READONLY) { + printf("(%s) attrib incorrect. Was 0x%x, should be 0x%x\n", + __location__, + (unsigned int)finfo.all_info.out.attrib, + (unsigned int)FILE_ATTRIBUTE_READONLY); + ret = false; + goto done; + } + + if (nt_time_to_unix(finfo.all_info.out.write_time) != basetime) { + printf("(%s) time incorrect.\n", + __location__); + ret = false; + goto done; + } + + done: + + if (fnum != -1) { + smbcli_close(cli->tree, fnum); + } + smbcli_unlink(cli->tree, fname); + return ret; +} + /* basic testing of streams calls */ @@ -1566,6 +1681,10 @@ bool torture_raw_streams(struct torture_context *torture, smb_raw_exit(cli->session); ret &= test_stream_create_disposition(torture, cli, torture); smb_raw_exit(cli->session); + + ret &= test_stream_attributes(torture, cli, torture); + smb_raw_exit(cli->session); + /* ret &= test_stream_large_streaminfo(torture, cli, torture); */ /* smb_raw_exit(cli->session); */ -- cgit From ebe1aa9340d190b2ebcfd2c96f68c7771cccdf01 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 18:03:49 -0800 Subject: Allow set attributes on a stream fnum to be redirected to the base filename. Fixes the new RAW-STREAMS torture test. Jeremy. --- source3/smbd/trans2.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 759e520866..433b8a008d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4972,6 +4972,7 @@ NTSTATUS smb_set_file_time(connection_struct *conn, ****************************************************************************/ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, + files_struct *fsp, const char *fname, SMB_STRUCT_STAT *psbuf, uint32 dosmode) @@ -4980,6 +4981,14 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + if (fsp) { + if (fsp->base_fsp) { + fname = fsp->base_fsp->fsp_name; + } else { + fname = fsp->fsp_name; + } + } + if (dosmode) { if (S_ISDIR(psbuf->st_mode)) { dosmode |= aDIR; @@ -5723,12 +5732,11 @@ static NTSTATUS smb_set_file_basic_info(connection_struct *conn, /* Set the attributes */ dosmode = IVAL(pdata,32); - status = smb_set_file_dosmode(conn, fname, psbuf, dosmode); + status = smb_set_file_dosmode(conn, fsp, fname, psbuf, dosmode); if (!NT_STATUS_IS_OK(status)) { return status; } - /* access time */ ft.atime = interpret_long_date(pdata+8); -- cgit