#!/bin/sh
-# Run this script to build samba from CVS.
+# Run this script to build samba from SVN.
## insert all possible names (only works with
## autoconf 2.x
-#TESTAUTOHEADER="autoheader autoheader-2.53"
-TESTAUTOCONF="autoconf autoconf-2.53"
+TESTAUTOHEADER="autoheader autoheader-2.53 autoheader2.50"
+TESTAUTOCONF="autoconf autoconf-2.53 autoconf2.50"
-#AUTOHEADERFOUND="0"
+AUTOHEADERFOUND="0"
AUTOCONFFOUND="0"
##
## Look for autoheader
##
-#for i in $TESTAUTOHEADER; do
-# if which $i > /dev/null 2>&1; then
-# if [ `$i --version | head -n 1 | cut -d. -f 2` -ge 53 ]; then
-# AUTOHEADER=$i
-# AUTOHEADERFOUND="1"
-# break
-# fi
-# fi
-#done
+for i in $TESTAUTOHEADER; do
+ if which $i > /dev/null 2>&1; then
+ if [ `$i --version | head -n 1 | cut -d. -f 2 | tr -d [:alpha:]` -ge 53 ]; then
+ AUTOHEADER=$i
+ AUTOHEADERFOUND="1"
+ break
+ fi
+ fi
+done
##
## Look for autoconf
for i in $TESTAUTOCONF; do
if which $i > /dev/null 2>&1; then
- if [ `$i --version | head -n 1 | cut -d. -f 2` -ge 53 ]; then
+ if [ `$i --version | head -n 1 | cut -d. -f 2 | tr -d [:alpha:]` -ge 53 ]; then
AUTOCONF=$i
AUTOCONFFOUND="1"
break
## do we have it?
##
if [ "$AUTOCONFFOUND" = "0" -o "$AUTOHEADERFOUND" = "0" ]; then
- echo "$0: need autoconf 2.53 or later to build samba from CVS" >&2
+ echo "$0: need autoconf 2.53 or later to build samba from SVN" >&2
exit 1
fi
+echo "$0: running script/mkversion.sh"
+./script/mkversion.sh || exit 1
+rm -rf autom4te*.cache
-#echo "$0: running $AUTOHEADER"
-#$AUTOHEADER || exit 1
+echo "$0: running $AUTOHEADER"
+$AUTOHEADER || exit 1
echo "$0: running $AUTOCONF"
$AUTOCONF || exit 1
+rm -rf autom4te*.cache
+
echo "Now run ./configure and then make."
exit 0
return vfswrap_opendir(NULL, conn, fname);
}
-static struct dirent *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
return vfswrap_readdir(NULL, conn, dirp);
}
+static void skel_seekdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp, long offset)
+{
+ return vfswrap_seekdir(NULL, conn, dirp, offset);
+}
+
+static long skel_telldir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ return vfswrap_telldir(NULL, conn, dirp);
+}
+
+static void skel_rewinddir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ return vfswrap_rewinddir(NULL, conn, dirp);
+}
+
static int skel_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
return vfswrap_mkdir(NULL, conn, path, mode);
{SMB_VFS_OP(skel_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(skel_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(skel_seekdir), SMB_VFS_OP_SEEKDIR, SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(skel_telldir), SMB_VFS_OP_TELLDIR, SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(skel_rewinddir), SMB_VFS_OP_REWINDDIR, SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(skel_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(skel_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(skel_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_OPAQUE},
return SMB_VFS_NEXT_OPENDIR(handle, conn, fname);
}
-static struct dirent *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+static SMB_STRUCT_DIRENT *skel_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
return SMB_VFS_NEXT_READDIR(handle, conn, dirp);
}
+static void skel_seekdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp, long offset)
+{
+ return SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset);
+}
+
+static long skel_telldir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ return SMB_VFS_NEXT_TELLDIR(handle, conn, dirp);
+}
+
+static void skel_rewinddir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ return SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp);
+}
+
static int skel_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
return SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
{SMB_VFS_OP(skel_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(skel_readdir), SMB_VFS_OP_READDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(skel_seekdir), SMB_VFS_OP_SEEKDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(skel_telldir), SMB_VFS_OP_TELLDIR, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(skel_rewinddir), SMB_VFS_OP_REWINDDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(skel_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(skel_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(skel_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_TRANSPARENT},
echo f none lib/libsmbclient.so 0755 root other
echo f none include/libsmbclient.h 0644 root other
- echo "#\n# smbwrapper\n#"
- echo f none lib/smbwrapper.so 0755 root other
- echo f none bin/smbsh 0755 root other
+ if [ -f lib/smbwrapper.so -a -f bin/smbsh ]; then
+ echo "#\n# smbwrapper\n#"
+ echo f none lib/smbwrapper.so 0755 root other
+ echo f none bin/smbsh 0755 root other
+ fi
echo "#\n# nss_winbind.so\n#"
echo f none /lib/nss_winbind.so.1=lib/nss_winbind.so.1 0755 root other
## BEGIN MAIN
#####################################################################
-TMPINSTALLDIR=/export/build
-
# Try to guess the distribution base..
-CURR_DIR=`pwd`
-DISTR_BASE=`echo $CURR_DIR | sed 's|\(.*\)/packaging.*|\1|'`
-echo "Assuming Samba distribution is rooted at $DISTR_BASE.."
+DISTR_BASE=`dirname \`pwd\` |sed -e 's@/packaging$@@'`
+echo "Distribution base: $DISTR_BASE"
+
+TMPINSTALLDIR="/tmp/`basename $DISTR_BASE`-build"
+echo "Temp install dir: $TMPINSTALLDIR"
+echo "Install directory: $INSTALL_BASE"
##
## first build the source
cd $DISTR_BASE/source
if [ "x$1" != "xnobuild" ]; then
- ./configure --prefix=$INSTALL_DIR \
+ ./configure --prefix=$INSTALL_BASE \
--with-acl-support \
--with-included-popt \
--localstatedir=/var/lib/samba \
fi
fi
+mkdir $TMPINSTALLDIR
make DESTDIR=$TMPINSTALLDIR install
## clear out *.old
-( cd $TMPINSTALLDIR; du -a | grep \.old$ | awk '{print "rm -rf "$2}' | sh )
-
+find $TMPINSTALLDIR -name \*.old |while read x; do rm -rf "$x"; done
##
## Now get the install locations
if [ -f nsswitch/pam_winbind.so ]; then
cp -fp nsswitch/pam_winbind.so $TMPINSTALLDIR/$LIBDIR/pam_winbind.so
fi
-
-cp -p bin/smbwrapper.so $TMPINSTALLDIR/$INSTALL_BASE/lib
-cp -p bin/smbsh $TMPINSTALLDIR/$INSTALL_BASE/bin
+if [ -f bin/smbwrapper.so ]; then
+ cp -fp bin/smbwrapper.so $TMPINSTALLDIR/$INSTALL_BASE/lib
+fi
+if [ -f bin/smbsh ]; then
+ cp -fp bin/smbsh $TMPINSTALLDIR/$INSTALL_BASE/bin
+fi
mkdir -p $TMPINSTALLDIR/$INSTALL_BASE/docs
cp -p ../docs/*pdf $TMPINSTALLDIR/$INSTALL_BASE/docs
lib/module.o lib/ldap_escape.o @CHARSET_STATIC@ \
lib/privileges.o lib/secdesc.o lib/secace.o lib/secacl.o
-LIB_SMBD_OBJ = lib/system_smbd.o lib/util_smbd.o
-
LIB_NONSMBD_OBJ = $(LIB_OBJ) lib/dummysmbd.o
READLINE_OBJ = lib/readline.o
PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
passdb/util_sam_sid.o passdb/pdb_compat.o \
passdb/privileges.o passdb/lookup_sid.o \
- passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o
+ passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o \
+ lib/system_smbd.o
XML_OBJ = passdb/pdb_xml.o
MYSQL_OBJ = passdb/pdb_mysql.o
$(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \
$(LIBMSRPC_OBJ) \
$(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \
- $(LIB_SMBD_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
+ $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(BUILDOPT_OBJ) $(SMBLDAP_OBJ)
PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
$(PRINTING_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) $(NOTIFY_OBJ) \
$(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(READLINE_OBJ) $(PROFILE_OBJ) $(LIBADS_OBJ) $(LIBADS_SERVER_OBJ) \
- $(LIB_SMBD_OBJ) $(AUTH_SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
+ $(AUTH_SAM_OBJ) $(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(RPC_LSA_OBJ) $(RPC_NETLOG_OBJ) $(RPC_SAMR_OBJ) $(RPC_REG_OBJ) $(RPC_LSA_DS_OBJ) \
$(RPC_SVC_OBJ) $(RPC_WKS_OBJ) $(RPC_DFS_OBJ) $(RPC_SPOOLSS_OBJ) \
$(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ)
########################################################
SAMBA_VERSION_MAJOR=3
SAMBA_VERSION_MINOR=0
-SAMBA_VERSION_RELEASE=10
+SAMBA_VERSION_RELEASE=11
########################################################
# For 'pre' releases the version will be #
# e.g. SAMBA_VERSION_PRE_RELEASE=1 #
# -> "2.2.9pre1" #
########################################################
-SAMBA_VERSION_PRE_RELEASE=
+SAMBA_VERSION_PRE_RELEASE=1
########################################################
# For 'rc' releases the version will be #
*n_groups = 0;
*groups = NULL;
-
- /* Try winbind first */
- if ( strchr(username, *lp_winbind_separator()) ) {
- n_unix_groups = winbind_getgroups( username, unix_groups );
+ if (strchr(username, *lp_winbind_separator()) == NULL) {
+ NTSTATUS result;
- DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n", username,
- n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
-
- if ( n_unix_groups == -1 )
- return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
+ become_root();
+ result = pdb_enum_group_memberships(username, gid, groups,
+ unix_groups, n_groups);
+ unbecome_root();
+ return result;
}
- else {
- /* fallback to getgrouplist() */
-
- n_unix_groups = groups_max();
-
- if ((*unix_groups = SMB_MALLOC_ARRAY( gid_t, n_unix_groups ) ) == NULL) {
- DEBUG(0, ("get_user_groups: Out of memory allocating unix group list\n"));
- return NT_STATUS_NO_MEMORY;
- }
+
+ /* We have the separator, this must be winbind */
- if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
-
- gid_t *groups_tmp;
-
- groups_tmp = SMB_REALLOC_ARRAY(*unix_groups, gid_t, n_unix_groups);
-
- if (!groups_tmp) {
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_MEMORY;
- }
- *unix_groups = groups_tmp;
+ n_unix_groups = winbind_getgroups( username, unix_groups );
- if (sys_getgrouplist(username, gid, *unix_groups, &n_unix_groups) == -1) {
- DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
- SAFE_FREE(*unix_groups);
- return NT_STATUS_NO_SUCH_USER; /* what should this return value be? */
- }
- }
- }
+ DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n",
+ username, n_unix_groups == -1 ? "FAIL" : "SUCCESS"));
+
+ if ( n_unix_groups == -1 )
+ return NT_STATUS_NO_SUCH_USER; /* what should this return
+ * value be? */
debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups);
Make (and fill) a user_info struct for a guest login.
***************************************************************************/
-NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
+static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
SAM_ACCOUNT *sampass = NULL;
return nt_status;
}
+static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
+{
+ auth_serversupplied_info *dst;
+
+ if (!NT_STATUS_IS_OK(make_server_info(&dst)))
+ return NULL;
+
+ dst->guest = src->guest;
+ dst->uid = src->uid;
+ dst->gid = src->gid;
+ dst->n_groups = src->n_groups;
+ if (src->n_groups != 0)
+ dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups);
+ else
+ dst->groups = NULL;
+ dst->ptok = dup_nt_token(src->ptok);
+ dst->user_session_key = data_blob(src->user_session_key.data,
+ src->user_session_key.length);
+ dst->lm_session_key = data_blob(src->lm_session_key.data,
+ src->lm_session_key.length);
+ pdb_copy_sam_account(src->sam_account, &dst->sam_account);
+ dst->pam_handle = NULL;
+ dst->unix_name = smb_xstrdup(src->unix_name);
+
+ return dst;
+}
+
+static auth_serversupplied_info *guest_info = NULL;
+
+BOOL init_guest_info(void)
+{
+ if (guest_info != NULL)
+ return True;
+
+ return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
+}
+
+NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
+{
+ *server_info = copy_serverinfo(guest_info);
+ return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
+}
+
/***************************************************************************
Purely internal function for make_server_info_info3
Fill the sam account from getpwnam
(*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));
}
- if (memcmp(info3->padding, zeros, sizeof(zeros)) == 0) {
+ if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
(*server_info)->lm_session_key = data_blob(NULL, 0);
} else {
- (*server_info)->lm_session_key = data_blob(info3->padding, 16);
- }
+ (*server_info)->lm_session_key = data_blob(info3->lm_sess_key, sizeof(info3->lm_sess_key));
+ }
+
return NT_STATUS_OK;
}
request.flags = WBFLAG_PAM_INFO3_NDR;
- push_utf8_fstring(request.data.auth_crap.user,
+ fstrcpy(request.data.auth_crap.user,
user_info->smb_name.str);
- push_utf8_fstring(request.data.auth_crap.domain,
+ fstrcpy(request.data.auth_crap.domain,
user_info->domain.str);
- push_utf8_fstring(request.data.auth_crap.workstation,
+ fstrcpy(request.data.auth_crap.workstation,
user_info->wksta_name.str);
memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
/*
* Macros to help make life easy
*/
-#define COPY_STRING(s) (s) ? strdup(s) : NULL
+#define COPY_STRING(s) (s) ? SMB_STRDUP(s) : NULL
/*******************************************************************
PAM error handler.
return s;
}
+/****************************************************************************
+ Utility function for UNIX getfacl.
+****************************************************************************/
+
+static char *perms_to_string(fstring permstr, unsigned char perms)
+{
+ fstrcpy(permstr, "---");
+ if (perms & SMB_POSIX_ACL_READ) {
+ permstr[0] = 'r';
+ }
+ if (perms & SMB_POSIX_ACL_WRITE) {
+ permstr[1] = 'w';
+ }
+ if (perms & SMB_POSIX_ACL_EXECUTE) {
+ permstr[2] = 'x';
+ }
+ return permstr;
+}
+
+/****************************************************************************
+ UNIX getfacl.
+****************************************************************************/
+
+static int cmd_getfacl(void)
+{
+ pstring src, name;
+ uint16 major, minor;
+ uint32 caplow, caphigh;
+ char *retbuf = NULL;
+ size_t rb_size = 0;
+ SMB_STRUCT_STAT sbuf;
+ uint16 num_file_acls = 0;
+ uint16 num_dir_acls = 0;
+ uint16 i;
+
+ if (!SERVER_HAS_UNIX_CIFS(cli)) {
+ d_printf("Server doesn't support UNIX CIFS calls.\n");
+ return 1;
+ }
+
+ if (!cli_unix_extensions_version(cli, &major, &minor, &caplow, &caphigh)) {
+ d_printf("Can't get UNIX CIFS version from server.\n");
+ return 1;
+ }
+
+ if (!(caplow & CIFS_UNIX_POSIX_ACLS_CAP)) {
+ d_printf("This server supports UNIX extensions but doesn't support POSIX ACLs.\n");
+ return 1;
+ }
+
+ pstrcpy(src,cur_dir);
+
+ if (!next_token_nr(NULL,name,NULL,sizeof(name))) {
+ d_printf("stat file\n");
+ return 1;
+ }
+
+ pstrcat(src,name);
+
+ if (!cli_unix_stat(cli, src, &sbuf)) {
+ d_printf("%s getfacl doing a stat on file %s\n",
+ cli_errstr(cli), src);
+ return 1;
+ }
+
+ if (!cli_unix_getfacl(cli, src, &rb_size, &retbuf)) {
+ d_printf("%s getfacl file %s\n",
+ cli_errstr(cli), src);
+ return 1;
+ }
+
+ /* ToDo : Print out the ACL values. */
+ if (SVAL(retbuf,0) != SMB_POSIX_ACL_VERSION || rb_size < 6) {
+ d_printf("getfacl file %s, unknown POSIX acl version %u.\n",
+ src, (unsigned int)CVAL(retbuf,0) );
+ SAFE_FREE(retbuf);
+ return 1;
+ }
+
+ num_file_acls = SVAL(retbuf,2);
+ num_dir_acls = SVAL(retbuf,4);
+ if (rb_size != SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)) {
+ d_printf("getfacl file %s, incorrect POSIX acl buffer size (should be %u, was %u).\n",
+ src,
+ (unsigned int)(SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls)),
+ (unsigned int)rb_size);
+
+ SAFE_FREE(retbuf);
+ return 1;
+ }
+
+ d_printf("# file: %s\n", src);
+ d_printf("# owner: %u\n# group: %u\n", (unsigned int)sbuf.st_uid, (unsigned int)sbuf.st_gid);
+
+ if (num_file_acls == 0 && num_dir_acls == 0) {
+ d_printf("No acls found.\n");
+ }
+
+ for (i = 0; i < num_file_acls; i++) {
+ uint32 uorg;
+ fstring permstring;
+ unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE));
+ unsigned char perms = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+1);
+
+ switch(tagtype) {
+ case SMB_POSIX_ACL_USER_OBJ:
+ d_printf("user::");
+ break;
+ case SMB_POSIX_ACL_USER:
+ uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ d_printf("user:%u:", uorg);
+ break;
+ case SMB_POSIX_ACL_GROUP_OBJ:
+ d_printf("group::");
+ break;
+ case SMB_POSIX_ACL_GROUP:
+ uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ d_printf("group:%u", uorg);
+ break;
+ case SMB_POSIX_ACL_MASK:
+ d_printf("mask::");
+ break;
+ case SMB_POSIX_ACL_OTHER:
+ d_printf("other::");
+ break;
+ default:
+ d_printf("getfacl file %s, incorrect POSIX acl tagtype (%u).\n",
+ src, (unsigned int)tagtype );
+ SAFE_FREE(retbuf);
+ return 1;
+ }
+
+ d_printf("%s\n", perms_to_string(permstring, perms));
+ }
+
+ for (i = 0; i < num_dir_acls; i++) {
+ uint32 uorg;
+ fstring permstring;
+ unsigned char tagtype = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE));
+ unsigned char perms = CVAL(retbuf, SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+1);
+
+ switch(tagtype) {
+ case SMB_POSIX_ACL_USER_OBJ:
+ d_printf("default:user::");
+ break;
+ case SMB_POSIX_ACL_USER:
+ uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ d_printf("default:user:%u:", uorg);
+ break;
+ case SMB_POSIX_ACL_GROUP_OBJ:
+ d_printf("default:group::");
+ break;
+ case SMB_POSIX_ACL_GROUP:
+ uorg = IVAL(retbuf,SMB_POSIX_ACL_HEADER_SIZE+((i+num_file_acls)*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ d_printf("default:group:%u", uorg);
+ break;
+ case SMB_POSIX_ACL_MASK:
+ d_printf("default:mask::");
+ break;
+ case SMB_POSIX_ACL_OTHER:
+ d_printf("default:other::");
+ break;
+ default:
+ d_printf("getfacl file %s, incorrect POSIX acl tagtype (%u).\n",
+ src, (unsigned int)tagtype );
+ SAFE_FREE(retbuf);
+ return 1;
+ }
+
+ d_printf("%s\n", perms_to_string(permstring, perms));
+ }
+
+ SAFE_FREE(retbuf);
+ return 0;
+}
+
/****************************************************************************
UNIX stat.
****************************************************************************/
{"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}},
{"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
{"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}},
+ {"getfacl",cmd_getfacl,"<file name> get the POSIX ACL on a file (UNIX extensions only)",{COMPL_REMOTE,COMPL_LOCAL}},
{"hardlink",cmd_hardlink,"<src> <dest> create a Windows hard link",{COMPL_REMOTE,COMPL_REMOTE}},
{"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
{"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
return NULL;
} else {
char **matches;
- int i, len, samelen, count=1;
+ int i, len, samelen = 0, count=1;
matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
- if (!matches) return NULL;
+ if (!matches) {
+ return NULL;
+ }
matches[0] = NULL;
len = strlen(text);
struct tree_data *make_tree_data(guint32 type, const char *name)
{
- struct tree_data *p = (struct tree_data *)malloc(sizeof(struct tree_data));
+ struct tree_data *p = SMB_MALLOC_P(struct tree_data);
if (p) {
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-timestamp='2003-01-10'
+timestamp='2004-06-11'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit 0 ;;
+ amd64:OpenBSD:*:*)
+ echo x86_64-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
+ cats:OpenBSD:*:*)
+ echo arm-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
+ luna88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
- *:MicroBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE}
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:MirBSD:*:*)
+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
exit 0 ;;
alpha:OSF1:*:*)
- if test $UNAME_RELEASE = "V4.0"; then
+ case $UNAME_RELEASE in
+ *4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- fi
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- eval $set_cc_for_build
- cat <<EOF >$dummy.s
- .data
-\$Lformat:
- .byte 37,100,45,37,120,10,0 # "%d-%x\n"
-
- .text
- .globl main
- .align 4
- .ent main
-main:
- .frame \$30,16,\$26,0
- ldgp \$29,0(\$27)
- .prologue 1
- .long 0x47e03d80 # implver \$0
- lda \$2,-1
- .long 0x47e20c21 # amask \$2,\$1
- lda \$16,\$Lformat
- mov \$0,\$17
- not \$1,\$18
- jsr \$26,printf
- ldgp \$29,0(\$26)
- mov 0,\$16
- jsr \$26,exit
- .end main
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null
- if test "$?" = 0 ; then
- case `$dummy` in
- 0-0)
- UNAME_MACHINE="alpha"
- ;;
- 1-0)
- UNAME_MACHINE="alphaev5"
- ;;
- 1-1)
- UNAME_MACHINE="alphaev56"
- ;;
- 1-101)
- UNAME_MACHINE="alphapca56"
- ;;
- 2-303)
- UNAME_MACHINE="alphaev6"
- ;;
- 2-307)
- UNAME_MACHINE="alphaev67"
- ;;
- 2-1307)
- UNAME_MACHINE="alphaev68"
- ;;
- 3-1307)
- UNAME_MACHINE="alphaev7"
- ;;
- esac
- fi
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha*:OpenVMS:*:*)
+ echo alpha-hp-vms
exit 0 ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
*:OS/390:*:*)
echo i370-ibm-openedition
exit 0 ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit 0 ;;
DRS?6000:UNIX_SV:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7 && exit 0 ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
*:UNICOS/mp:*:*)
- echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+ # GNU/KFreeBSD systems have a "k" prefix to indicate we are using
+ # FreeBSD's kernel, but not the complete OS.
+ case ${LIBC} in gnu) kernel_only='k' ;; esac
+ echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
exit 0 ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit 0 ;;
- x86:Interix*:3*)
- echo i586-pc-interix3
+ x86:Interix*:[34]*)
+ echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
exit 0 ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
+ # the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit 0 ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit 0 ;;
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit 0 ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit 0 ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
LIBC=gnuaout
#endif
#endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit 0 ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit 0 ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
exit 0 ;;
- M68*:*:R3V[567]*:*)
+ M68*:*:R3V[5678]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0)
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
- NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+ NSR-?:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
*:NonStop-UX:*:*)
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit 0 ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-timestamp='2001-12-03'
+timestamp='2004-03-12'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
- | d10v | d30v | dsp16xx \
- | fr30 \
+ | d10v | d30v | dlx | dsp16xx \
+ | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
- | m32r | m68000 | m68k | m88k | mcore \
- | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
- | mips64vr4100 | mips64vr4100el | mips64vr4300 \
- | mips64vr4300el | mips64vr5000 | mips64vr5000el \
- | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
- | mipsisa32 \
+ | ip2k | iq2000 \
+ | m32r | m32rle | m68000 | m68k | m88k | mcore \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64vr | mips64vrel \
+ | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
| mn10200 | mn10300 \
+ | msp430 \
| ns16k | ns32k \
- | openrisc \
+ | openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
- | sh | sh[34] | sh[34]eb | shbe | shle \
- | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
+ | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
| strongarm \
- | tahoe | thumb | tic80 | tron \
+ | tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alphapca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armv*-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c54x-* \
- | clipper-* | cray2-* | cydra-* \
- | d10v-* | d30v-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | clipper-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
| elxsi-* \
- | f30[01]-* | f700-* | fr30-* | fx80-* \
+ | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
- | m32r-* \
- | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
+ | ip2k-* | iq2000-* \
+ | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
- | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
- | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
- | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | msp430-* \
+ | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
- | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
- | sparc-* | sparc64-* | sparc86x-* | sparclite-* \
- | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \
- | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+ | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | tahoe-* | thumb-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* | xstormy16-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
basic_machine=a29k-amd
os=-udi
;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
basic_machine=a29k-none
os=-bsd
;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
amdahl)
basic_machine=580-amdahl
os=-sysv
basic_machine=ns32k-sequent
os=-dynix
;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
basic_machine=c38-convex
os=-bsd
;;
- cray | ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- cray2)
- basic_machine=cray2-cray
+ cray | j90)
+ basic_machine=j90-cray
os=-unicos
;;
- [cjt]90)
- basic_machine=${basic_machine}-cray
- os=-unicos
+ cr16c)
+ basic_machine=cr16c-unknown
+ os=-elf
;;
crds | unos)
basic_machine=m68k-crds
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
basic_machine=m68k-atari
os=-mint
;;
- mipsel*-linux*)
- basic_machine=mipsel-unknown
- os=-linux-gnu
- ;;
- mips*-linux*)
- basic_machine=mips-unknown
- os=-linux-gnu
- ;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
basic_machine=m68k-rom68k
os=-coff
;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
msdos)
basic_machine=i386-pc
os=-msdos
np1)
basic_machine=np1-gould
;;
+ nv1)
+ basic_machine=nv1-cray
+ os=-unicosmp
+ ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
basic_machine=hppa1.1-oki
os=-proelf
;;
+ or32 | or32-*)
+ basic_machine=or32-unknown
+ os=-coff
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
pbb)
basic_machine=m68k-tti
;;
- pc532 | pc532-*)
+ pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
- pentiumpro | p6 | 6x86 | athlon)
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
- pentiumii | pentium2)
+ pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
- pentiumii-* | pentium2-*)
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
- ;;
+ ;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
- ;;
+ ;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
- ;;
+ ;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
- ;;
+ ;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
basic_machine=a29k-amd
os=-udi
;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
sequent)
basic_machine=i386-sequent
;;
basic_machine=sh-hitachi
os=-hms
;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
os=-dynix
;;
t3e)
- basic_machine=t3e-cray
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
+ tic55x | c55x*)
+ basic_machine=tic55x-unknown
+ os=-coff
+ ;;
+ tic6x | c6x*)
+ basic_machine=tic6x-unknown
+ os=-coff
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
tower | tower-32)
basic_machine=m68k-ncr
;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
udi29k)
basic_machine=a29k-amd
os=-udi
os=-vms
;;
vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
+ basic_machine=f301-fujitsu
+ ;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
basic_machine=hppa1.1-winbond
os=-proelf
;;
- windows32)
- basic_machine=i386-pc
- os=-windows32-msvcrt
+ xps | xps100)
+ basic_machine=xps100-honeywell
;;
- xmp)
- basic_machine=xmp-cray
+ ymp)
+ basic_machine=ymp-cray
os=-unicos
;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
op60c)
basic_machine=hppa1.1-oki
;;
- mips)
- if [ x$os = x-linux-gnu ]; then
- basic_machine=mips-unknown
- else
- basic_machine=mips-mips
- fi
- ;;
romp)
basic_machine=romp-ibm
;;
we32k)
basic_machine=we32k-att
;;
- sh3 | sh4 | sh3eb | sh4eb)
+ sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
- sparc | sparcv9 | sparcv9b)
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
- cydra)
+ cydra)
basic_machine=cydra-cydrome
;;
orion)
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
- c4x*)
- basic_machine=c4x-none
- os=-coff
- ;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus*)
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
;;
esac
;;
+ -nto-qnx*)
+ ;;
-nto*)
- os=-nto-qnx
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-opened*)
os=-openedition
;;
+ -os400*)
+ os=-os400
+ ;;
-wince*)
os=-wince
;;
-atheos*)
os=-atheos
;;
+ -syllable*)
+ os=-syllable
+ ;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
-ns2 )
- os=-nextstep2
+ os=-nextstep2
;;
-nsk*)
os=-nsk
-sinix*)
os=-sysv4
;;
+ -tpf*)
+ os=-tpf
+ ;;
-triton*)
os=-sysv3
;;
-xenix)
os=-xenix
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
;;
-none)
;;
arm*-semi)
os=-aout
;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
- pdp11-*)
+ pdp11-*)
os=-none
;;
*-dec | vax-*)
mips*-*)
os=-elf
;;
+ or32-*)
+ os=-coff
+ ;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
*-next)
os=-nextstep3
;;
- *-gould)
+ *-gould)
os=-sysv
;;
- *-highlevel)
+ *-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
- *-sgi)
+ *-sgi)
os=-irix
;;
- *-siemens)
+ *-siemens)
os=-sysv4
;;
*-masscomp)
-mvs* | -opened*)
vendor=ibm
;;
+ -os400*)
+ vendor=ibm
+ ;;
-ptx*)
vendor=sequent
;;
- -vxsim* | -vxworks*)
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
AC_ARG_ENABLE(developer, [ --enable-developer Turn on developer warnings and debugging (default=no)],
[if eval "test x$enable_developer = xyes"; then
developer=yes
- CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER"
+ CFLAGS="${CFLAGS} -gstabs -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -DDEBUG_PASSWORD -DDEVELOPER -O1"
fi])
AC_ARG_ENABLE(krb5developer, [ --enable-krb5developer Turn on developer warnings and debugging, except -Wstrict-prototypes (default=no)],
krb5_keytab keytab;
krb5_init_context(&context);
- if (krb5_kt_resolve(context, "WRFILE:api", &keytab))
- exit(0);
- exit(1);
+ return krb5_kt_resolve(context, "WRFILE:api", &keytab);
}],
- samba_cv_HAVE_WRFILE_KEYTAB=no,
- samba_cv_HAVE_WRFILE_KEYTAB=yes)])
+ samba_cv_HAVE_WRFILE_KEYTAB=yes,
+ samba_cv_HAVE_WRFILE_KEYTAB=no)])
if test x"$samba_cv_HAVE_WRFILE_KEYTAB" = x"yes"; then
AC_DEFINE(HAVE_WRFILE_KEYTAB,1,
AC_MSG_RESULT(no);
fi
;;
+ *aix*)
+ AC_CACHE_CHECK([for AIX send_file support],samba_cv_HAVE_SENDFILE,[
+ AC_TRY_LINK([\
+#include <sys/socket.h>],
+[\
+ int fromfd, tofd;
+ size_t total=0;
+ struct sf_parms hdtrl;
+ ssize_t nwritten;
+ off64_t offset;
+
+ hdtrl.header_data = 0;
+ hdtrl.header_length = 0;
+ hdtrl.file_descriptor = fromfd;
+ hdtrl.file_offset = 0;
+ hdtrl.file_bytes = 0;
+ hdtrl.trailer_data = 0;
+ hdtrl.trailer_length = 0;
+ nwritten = send_file(&tofd, &hdtrl, 0);
+],
+samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)])
+ if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then
+ AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available])
+ AC_DEFINE(AIX_SENDFILE_API,1,[Whether the AIX send_file() API is available])
+ AC_DEFINE(WITH_SENDFILE,1,[Whether to include sendfile() support])
+ else
+ AC_MSG_RESULT(no);
+ fi
+ ;;
*)
;;
esac
/* This operation happens on session setup, so it should better be fast. We
* store a list of aliases a SID is member of hanging off MEMBEROF/SID. */
-static NTSTATUS alias_memberships(const DOM_SID *sid, DOM_SID **sids, int *num)
+static NTSTATUS one_alias_membership(const DOM_SID *member,
+ DOM_SID **sids, int *num)
{
fstring key, string_sid;
TDB_DATA kbuf, dbuf;
const char *p;
- *num = 0;
- *sids = NULL;
-
if (!init_group_mapping()) {
DEBUG(0,("failed to initialize group mapping\n"));
return NT_STATUS_ACCESS_DENIED;
}
- sid_to_string(string_sid, sid);
+ sid_to_string(string_sid, member);
slprintf(key, sizeof(key), "%s%s", MEMBEROF_PREFIX, string_sid);
kbuf.dsize = strlen(key)+1;
if (!string_to_sid(&alias, string_sid))
continue;
- add_sid_to_array(&alias, sids, num);
+ add_sid_to_array_unique(&alias, sids, num);
if (sids == NULL)
return NT_STATUS_NO_MEMORY;
return NT_STATUS_OK;
}
+static NTSTATUS alias_memberships(const DOM_SID *members, int num_members,
+ DOM_SID **sids, int *num)
+{
+ int i;
+
+ *num = 0;
+ *sids = NULL;
+
+ for (i=0; i<num_members; i++) {
+ NTSTATUS status = one_alias_membership(&members[i], sids, num);
+ if (!NT_STATUS_IS_OK(status))
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
static BOOL is_aliasmem(const DOM_SID *alias, const DOM_SID *member)
{
DOM_SID *sids;
/* This feels the wrong way round, but the on-disk data structure
* dictates it this way. */
- if (!NT_STATUS_IS_OK(alias_memberships(member, &sids, &num)))
+ if (!NT_STATUS_IS_OK(alias_memberships(member, 1, &sids, &num)))
return False;
for (i=0; i<num; i++) {
pstring key;
fstring sid_string;
- result = alias_memberships(member, &sids, &num);
+ result = alias_memberships(member, 1, &sids, &num);
if (!NT_STATUS_IS_OK(result))
return result;
}
NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods,
- const DOM_SID *sid,
+ const DOM_SID *members,
+ int num_members,
DOM_SID **aliases, int *num)
{
- return alias_memberships(sid, aliases, num);
+ return alias_memberships(members, num_members, aliases, num);
}
/**********************************************************************
overlap on the wire. This size gives us a nice read/write size, which
will be a multiple of the page size on almost any system */
#define CLI_BUFFER_SIZE (0xFFFF)
-
+#define CLI_MAX_LARGE_READX_SIZE (127*1024)
/*
* These definitions depend on smb.h
#define LOG_DEBUG 7 /* debug-level messages */
#endif
-/* NetBSD doesn't have these */
-#ifndef SHM_R
-#define SHM_R 0400
-#endif
-
-#ifndef SHM_W
-#define SHM_W 0200
-#endif
-
#if HAVE_KERNEL_SHARE_MODES
#ifndef LOCK_MAND
#define LOCK_MAND 32 /* This is a mandatory flock */
GROUP_MAP **rmap, int *num_entries,
BOOL unix_only);
+ NTSTATUS (*pdb_enum_group_memberships)(struct pdb_context *context,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups);
+
NTSTATUS (*pdb_find_alias)(struct pdb_context *context,
const char *name, DOM_SID *sid);
DOM_SID **members, int *num_members);
NTSTATUS (*pdb_enum_alias_memberships)(struct pdb_context *context,
- const DOM_SID *alias,
+ const DOM_SID *members,
+ int num_members,
DOM_SID **aliases,
- int *num);
+ int *num_aliases);
void (*free_fn)(struct pdb_context **);
GROUP_MAP **rmap, int *num_entries,
BOOL unix_only);
+ NTSTATUS (*enum_group_memberships)(struct pdb_methods *methods,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups);
+
NTSTATUS (*find_alias)(struct pdb_methods *methods,
const char *name, DOM_SID *sid);
const DOM_SID *alias, DOM_SID **members,
int *num_members);
NTSTATUS (*enum_alias_memberships)(struct pdb_methods *methods,
- const DOM_SID *sid,
+ const DOM_SID *members,
+ int num_members,
DOM_SID **aliases, int *num);
void *private_data; /* Private data of some kind */
}
BUFHDR2;
+/* BUFHDR4 - another buffer header */
+typedef struct bufhdr4_info
+{
+ uint32 size;
+ uint32 buffer;
+
+}
+BUFHDR4;
+
/* BUFFER4 - simple length and buffer */
typedef struct buffer4_info
{
UNIHDR hdr_logon_dom; /* logon domain unicode string header */
uint32 buffer_dom_id; /* undocumented logon domain id pointer */
- uint8 padding[40]; /* unused padding bytes. expansion room */
+ uint8 lm_sess_key[8]; /* lm session key */
+ uint32 acct_flags; /* account flags */
+ uint32 unknown[7]; /* unknown */
uint32 num_other_sids; /* number of foreign/trusted domain sids */
uint32 buffer_other_sids;
} SAM_DELTA_HDR;
+/* LOCKOUT_STRING */
+typedef struct account_lockout_string {
+ uint32 array_size;
+ uint32 offset;
+ uint32 length;
+/* uint16 *bindata; */
+ UINT64_S lockout_duration;
+ UINT64_S reset_count;
+ uint32 bad_attempt_lockout;
+ uint32 dummy;
+
+} LOCKOUT_STRING;
+
+/* HDR_LOCKOUT_STRING */
+typedef struct hdr_account_lockout_string {
+ uint16 size;
+ uint16 length;
+ uint32 buffer;
+
+} HDR_LOCKOUT_STRING;
+
/* SAM_DOMAIN_INFO (0x1) */
typedef struct sam_domain_info_info
{
UINT64_S min_pwd_age;
UINT64_S dom_mod_count;
NTTIME creation_time;
+ uint32 security_information;
- BUFHDR2 hdr_sec_desc; /* security descriptor */
- UNIHDR hdr_unknown;
- uint8 reserved[40];
+ BUFHDR4 hdr_sec_desc; /* security descriptor */
+
+ HDR_LOCKOUT_STRING hdr_account_lockout;
+
+ UNIHDR hdr_unknown2;
+ UNIHDR hdr_unknown3;
+ UNIHDR hdr_unknown4;
UNISTR2 uni_dom_name;
- UNISTR2 buf_oem_info; /* never seen */
+ UNISTR2 buf_oem_info;
BUFFER4 buf_sec_desc;
- UNISTR2 buf_unknown;
+
+ LOCKOUT_STRING account_lockout;
+
+ UNISTR2 buf_unknown2;
+ UNISTR2 buf_unknown3;
+ UNISTR2 buf_unknown4;
+
+ uint32 logon_chgpass;
+ uint32 unknown6;
+ uint32 unknown7;
+ uint32 unknown8;
+
} SAM_DOMAIN_INFO;
} SAM_UNK_INFO_7;
+typedef struct sam_unknown_info_8_info
+{
+ UINT64_S seq_num;
+ NTTIME domain_create_time;
+
+} SAM_UNK_INFO_8;
+
typedef struct sam_unknown_info_12_inf
{
NTTIME duration;
typedef struct sam_unknown_info_2_inf
{
- uint32 unknown_0; /* 0x0000 0000 */
- uint32 unknown_1; /* 0x8000 0000 */
- uint32 unknown_2; /* 0x0000 0000 */
-
- uint32 ptr_0; /* pointer to unknown structure */
+ NTTIME logout; /* whether users are forcibly disconnected when logon hours expire */
+ UNIHDR hdr_comment; /* comment according to samba4 idl */
UNIHDR hdr_domain; /* domain name unicode header */
UNIHDR hdr_server; /* server name unicode header */
pointer is referring to
*/
- uint32 seq_num; /* some sort of incrementing sequence number? */
- uint32 unknown_3; /* 0x0000 0000 */
+ UINT64_S seq_num;
uint32 unknown_4; /* 0x0000 0001 */
uint32 unknown_5; /* 0x0000 0003 */
uint8 padding[12]; /* 12 bytes zeros */
+ UNISTR2 uni_comment; /* comment unicode string */
UNISTR2 uni_domain; /* domain name unicode string */
UNISTR2 uni_server; /* server name unicode string */
SAM_UNK_INFO_5 inf5;
SAM_UNK_INFO_6 inf6;
SAM_UNK_INFO_7 inf7;
+ SAM_UNK_INFO_8 inf8;
SAM_UNK_INFO_12 inf12;
} info;
struct smbldap_state {
LDAP *ldap_struct;
+ pid_t pid;
time_t last_ping;
/* retrive-once info */
const char *uri;
#define PROF_SHMEM_KEY ((key_t)0x07021999)
#define PROF_SHM_MAGIC 0x6349985
-#define PROF_SHM_VERSION 9
+#define PROF_SHM_VERSION 10
/* time values in the following structure are in microseconds */
unsigned syscall_opendir_time;
unsigned syscall_readdir_count;
unsigned syscall_readdir_time;
+ unsigned syscall_seekdir_count;
+ unsigned syscall_seekdir_time;
+ unsigned syscall_telldir_count;
+ unsigned syscall_telldir_time;
+ unsigned syscall_rewinddir_count;
+ unsigned syscall_rewinddir_time;
unsigned syscall_mkdir_count;
unsigned syscall_mkdir_time;
unsigned syscall_rmdir_count;
#define SMB_FS_FULL_SIZE_INFORMATION 1007
#define SMB_FS_OBJECTID_INFORMATION 1008
+/* flags on trans2 findfirst/findnext that control search */
+#define FLAG_TRANS2_FIND_CLOSE 0x1
+#define FLAG_TRANS2_FIND_CLOSE_IF_END 0x2
+#define FLAG_TRANS2_FIND_REQUIRE_RESUME 0x4
+#define FLAG_TRANS2_FIND_CONTINUE 0x8
+#define FLAG_TRANS2_FIND_BACKUP_INTENT 0x10
+
/* UNIX CIFS Extensions - created by HP */
/*
* UNIX CIFS Extensions have the range 0x200 - 0x2FF reserved.
/* ... more as we think of them :-). */
+/* SMB POSIX ACL definitions. */
+/* Wire format is (all little endian) :
+
+[2 bytes] - Version number.
+[2 bytes] - Number of ACE entries to follow.
+[2 bytes] - Number of default ACE entries to follow.
+-------------------------------------
+^
+|
+ACE entries
+|
+v
+-------------------------------------
+^
+|
+Default ACE entries
+|
+v
+-------------------------------------
+
+Where an ACE entry looks like :
+
+[1 byte] - Entry type.
+
+Entry types are :
+
+ACL_USER_OBJ 0x01
+ACL_USER 0x02
+ACL_GROUP_OBJ 0x04
+ACL_GROUP 0x08
+ACL_MASK 0x10
+ACL_OTHER 0x20
+
+[1 byte] - permissions (perm_t)
+
+perm_t types are :
+
+ACL_READ 0x04
+ACL_WRITE 0x02
+ACL_EXECUTE 0x01
+
+[8 bytes] - uid/gid to apply this permission to.
+
+In the same format as the uid/gid fields in the other
+UNIX extensions definitions. Use 0xFFFFFFFFFFFFFFFF for
+the MASK and OTHER entry types.
+
+If the Number of ACE entries for either file or default ACE's
+is set to 0xFFFF this means ignore this kind of ACE (and the
+number of entries sent will be zero.
+
+*/
+
+/* The query/set info levels for POSIX ACLs. */
+#define SMB_QUERY_POSIX_ACL 0x204
+#define SMB_SET_POSIX_ACL 0x204
+
+/* Current on the wire ACL version. */
+#define SMB_POSIX_ACL_VERSION 1
+
+/* ACE entry type. */
+#define SMB_POSIX_ACL_USER_OBJ 0x01
+#define SMB_POSIX_ACL_USER 0x02
+#define SMB_POSIX_ACL_GROUP_OBJ 0x04
+#define SMB_POSIX_ACL_GROUP 0x08
+#define SMB_POSIX_ACL_MASK 0x10
+#define SMB_POSIX_ACL_OTHER 0x20
+
+/* perm_t types. */
+#define SMB_POSIX_ACL_READ 0x04
+#define SMB_POSIX_ACL_WRITE 0x02
+#define SMB_POSIX_ACL_EXECUTE 0x01
+
+#define SMB_POSIX_ACL_HEADER_SIZE 6
+#define SMB_POSIX_ACL_ENTRY_SIZE 10
+
+#define SMB_POSIX_IGNORE_ACE_ENTRIES 0xFFFF
#endif
/*
Unix SMB/CIFS implementation.
VFS structures and parameters
- Copyright (C) Jeremy Allison 1999-2003
+ Copyright (C) Jeremy Allison 1999-2004
Copyright (C) Tim Potter 1999
Copyright (C) Alexander Bokovoy 2002
Copyright (C) Stefan (metze) Metzmacher 2003
/* Changed to version 8 includes EA calls. JRA. */
/* Changed to version 9 to include the get_shadow_data call. --metze */
/* Changed to version 10 to include pread/pwrite calls. */
-#define SMB_VFS_INTERFACE_VERSION 10
+/* Changed to version 11 to include seekdir/telldir/rewinddir calls. JRA */
+#define SMB_VFS_INTERFACE_VERSION 11
/* to bug old modules witch are trying to compile with the old functions */
SMB_VFS_OP_OPENDIR,
SMB_VFS_OP_READDIR,
+ SMB_VFS_OP_SEEKDIR,
+ SMB_VFS_OP_TELLDIR,
+ SMB_VFS_OP_REWINDDIR,
SMB_VFS_OP_MKDIR,
SMB_VFS_OP_RMDIR,
SMB_VFS_OP_CLOSEDIR,
/* Directory operations */
DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname);
- struct dirent *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+ SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+ void (*seekdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp, long offset);
+ long (*telldir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
+ void (*rewind_dir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dirp);
int (*mkdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode);
int (*rmdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
int (*closedir)(struct vfs_handle_struct *handle, struct connection_struct *conn, DIR *dir);
struct vfs_handle_struct *opendir;
struct vfs_handle_struct *readdir;
+ struct vfs_handle_struct *seekdir;
+ struct vfs_handle_struct *telldir;
+ struct vfs_handle_struct *rewind_dir;
struct vfs_handle_struct *mkdir;
struct vfs_handle_struct *rmdir;
struct vfs_handle_struct *closedir;
/* Directory operations */
#define SMB_VFS_OPENDIR(conn, fname) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname)))
#define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (conn), (dirp)))
+#define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (conn), (dirp), (offset)))
+#define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (conn), (dirp)))
+#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewinddir((conn)->vfs.handles.rewinddir, (conn), (dirp)))
#define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(conn), (path), (mode)))
#define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (conn), (path)))
#define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, (conn), dir))
/* Directory operations */
#define SMB_VFS_OPAQUE_OPENDIR(conn, fname) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname)))
#define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (conn), (dirp)))
+#define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (conn), (dirp), (offset)))
+#define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (conn), (dirp)))
+#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewinddir((conn)->vfs_opaque.handles.rewinddir, (conn), (dirp)))
#define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(conn), (path), (mode)))
#define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (conn), (path)))
#define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, (conn), dir))
/* Directory operations */
#define SMB_VFS_NEXT_OPENDIR(handle, conn, fname) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname)))
#define SMB_VFS_NEXT_READDIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp)))
+#define SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset) ((handle)->vfs_next.ops.seekdir((handle)->vfs_next.handles.seekdir, (conn), (dirp), (offset)))
+#define SMB_VFS_NEXT_TELLDIR(handle, conn, dirp) ((handle)->vfs_next.ops.telldir((handle)->vfs_next.handles.telldir, (conn), (dirp)))
+#define SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp) ((handle)->vfs_next.ops.rewind_dir((handle)->vfs_next.handles.rewind_dir, (conn), (dirp)))
+#define SMB_VFS_NEXT_DIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp)))
#define SMB_VFS_NEXT_MKDIR(handle, conn, path, mode) ((handle)->vfs_next.ops.mkdir((handle)->vfs_next.handles.mkdir,(conn), (path), (mode)))
#define SMB_VFS_NEXT_RMDIR(handle, conn, path) ((handle)->vfs_next.ops.rmdir((handle)->vfs_next.handles.rmdir, (conn), (path)))
#define SMB_VFS_NEXT_CLOSEDIR(handle, conn, dir) ((handle)->vfs_next.ops.closedir((handle)->vfs_next.handles.closedir, (conn), dir))
return False;
}
if (!tdb_fetch_uint32(tdb, name, value)) {
- DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for efild %d (%s), returning 0", field, name));
+ DEBUG(1, ("account_policy_get: tdb_fetch_uint32 failed for field %d (%s), returning 0\n", field, name));
return False;
}
DEBUG(10,("account_policy_get: %s:%d\n", name, *value));
p += 8;
- /* Ticket lifetime. We fake everything here, so go as long as
- possible. This is in 5-minute intervals, so 255 is 21 hours
- and 15 minutes.*/
+ /* This is a kerberos 4 life time. The life time is expressed
+ * in units of 5 minute intervals up to 38400 seconds, after
+ * that a table is used up to lifetime 0xBF. Values between
+ * 0xC0 and 0xFF is undefined. 0xFF is defined to be the
+ * infinite time that never expire.
+ *
+ * So here we cheat and use the infinite time */
*p = 255;
p += 1;
SIVAL(p, 0, now);
ct->BeginTimestamp = now;
- ct->EndTimestamp = now + (255*60*5);
+ if(lp_afs_token_lifetime() == 0)
+ ct->EndTimestamp = NEVERDATE;
+ else
+ ct->EndTimestamp = now + lp_afs_token_lifetime();
+
if (((ct->EndTimestamp - ct->BeginTimestamp) & 1) == 1) {
ct->BeginTimestamp += 1; /* Lifetime must be even */
}
DATA_BLOB blob;
struct ClearToken result_ct;
- char *s = strdup(string);
+ char *s = SMB_STRDUP(string);
char *t;
return False;
}
- *cell = strdup(t);
+ *cell = SMB_STRDUP(t);
if ((t = strtok(NULL, "\n")) == NULL) {
DEBUG(10, ("strtok failed\n"));
}
ret = ln;
}
+#ifdef HAVE_SETLOCALE
+ /* We set back the locale to C to get ASCII-compatible toupper/lower functions.
+ For now we do not need any other POSIX localisations anyway. When we should
+ really need localized string functions one day we need to write our own
+ ascii_tolower etc.
+ */
+ setlocale(LC_ALL, "C");
+ #endif
+
#endif
if (!ret || !*ret) ret = "ASCII";
unsigned char *q = (unsigned char *)dest;
size_t slen = srclen;
size_t dlen = destlen;
- unsigned char lastp;
+ unsigned char lastp = '\0';
size_t retval = 0;
/* If all characters are ascii, fast path here. */
size_t retval = 0;
size_t slen = srclen;
size_t dlen = destlen;
- unsigned char lastp;
+ unsigned char lastp = '\0';
/* If all characters are ascii, fast path here. */
while (((slen == (size_t)-1) || (slen >= 2)) && dlen) {
size_t retval = 0;
size_t slen = srclen;
size_t dlen = destlen;
- unsigned char lastp;
+ unsigned char lastp = '\0';
/* If all characters are ascii, fast path here. */
while (slen && (dlen >= 2)) {
*/
handle = sys_dlopen(module_name, RTLD_LAZY);
+ /* This call should reset any possible non-fatal errors that
+ occured since last call to dl* functions */
+ error = sys_dlerror();
+
if(!handle) {
int level = is_probe ? 3 : 0;
- error = sys_dlerror();
DEBUG(level, ("Error loading module '%s': %s\n", module_name, error ? error : ""));
return NT_STATUS_UNSUCCESSFUL;
}
}
}
- pstrcpy_wa(p, pattern);
- pstrcpy_wa(s, string);
+ if (push_ucs2(NULL, p, pattern, sizeof(p), STR_TERMINATE) == (size_t)-1) {
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ return -1;
+ }
+
+ if (push_ucs2(NULL, s, string, sizeof(s), STR_TERMINATE) == (size_t)-1) {
+ /* Not quite the right answer, but finding the right one
+ under this failure case is expensive, and it's pretty close */
+ return -1;
+ }
if (protocol <= PROTOCOL_LANMAN2) {
/*
struct group *g;
char *gr;
- if((grouplst = (gid_t *)malloc(sizeof(gid_t) * max_gr)) == NULL) {
+ if((grouplst = SMB_MALLOC_ARRAY(gid_t, max_gr)) == NULL) {
DEBUG(0,("initgroups: malloc fail !\n"));
return -1;
}
/****************************************************************************
duplicate a string
****************************************************************************/
+
+#ifdef strdup
+#undef strdup
+#endif
+
char *strdup(const char *s)
{
size_t len;
if (!s) return(NULL);
len = strlen(s)+1;
- ret = (char *)malloc(len);
+ ret = (char *)SMB_MALLOC(len);
if (!ret) return(NULL);
memcpy(ret,s,len);
return(ret);
#ifndef HAVE_VSYSLOG
#ifdef HAVE_SYSLOG
- void vsyslog (int facility_priority, char *format, va_list arglist)
+ void vsyslog (int facility_priority, const char *format, va_list arglist)
{
char *msg = NULL;
vasprintf(&msg, format, arglist);
nwritten = sendfile(tofd, fromfd, &offset, total);
#endif
} while (nwritten == -1 && errno == EINTR);
- if (nwritten == -1)
+ if (nwritten == -1) {
+ if (errno == ENOSYS) {
+ /* Ok - we're in a world of pain here. We just sent
+ * the header, but the sendfile failed. We have to
+ * emulate the sendfile at an upper layer before we
+ * disable it's use. So we do something really ugly.
+ * We set the errno to a strange value so we can detect
+ * this at the upper level and take care of it without
+ * layer violation. JRA.
+ */
+ errno = EINTR; /* Normally we can never return this. */
+ }
return -1;
+ }
if (nwritten == 0)
return -1; /* I think we're at EOF here... */
total -= nwritten;
do {
nwritten = sendfile(tofd, fromfd, &small_offset, small_total);
} while (nwritten == -1 && errno == EINTR);
- if (nwritten == -1)
+ if (nwritten == -1) {
+ if (errno == ENOSYS) {
+ /* Ok - we're in a world of pain here. We just sent
+ * the header, but the sendfile failed. We have to
+ * emulate the sendfile at an upper layer before we
+ * disable it's use. So we do something really ugly.
+ * We set the errno to a strange value so we can detect
+ * this at the upper level and take care of it without
+ * layer violation. JRA.
+ */
+ errno = EINTR; /* Normally we can never return this. */
+ }
return -1;
+ }
if (nwritten == 0)
return -1; /* I think we're at EOF here... */
small_total -= nwritten;
hdtrl[0].iov_len = hdr_len = 0;
}
hdtrl[1].iov_base = NULL;
- hdtrl[1].iov_base = 0;
+ hdtrl[1].iov_len = 0;
total = count;
while (total + hdtrl[0].iov_len) {
return count + hdr_len;
}
+#elif defined(AIX_SENDFILE_API)
+
+/* BEGIN AIX SEND_FILE */
+
+/* Contributed by William Jojo <jojowil@hvcc.edu> */
+#include <sys/socket.h>
+
+ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count)
+{
+ size_t total=0;
+ struct sf_parms hdtrl;
+
+ /* Set up the header/trailer struct params. */
+ if (header) {
+ hdtrl.header_data = header->data;
+ hdtrl.header_length = header->length;
+ } else {
+ hdtrl.header_data = NULL;
+ hdtrl.header_length = 0;
+ }
+ hdtrl.trailer_data = NULL;
+ hdtrl.trailer_length = 0;
+
+ hdtrl.file_descriptor = fromfd;
+ hdtrl.file_offset = offset;
+ hdtrl.file_bytes = count;
+
+ while ( hdtrl.file_bytes + hdtrl.header_length ) {
+ ssize_t ret;
+
+ /*
+ Return Value
+
+ There are three possible return values from send_file:
+
+ Value Description
+
+ -1 an error has occurred, errno contains the error code.
+
+ 0 the command has completed successfully.
+
+ 1 the command was completed partially, some data has been
+ transmitted but the command has to return for some reason,
+ for example, the command was interrupted by signals.
+ */
+ do {
+ ret = send_file(&tofd, &hdtrl, 0);
+ } while ( (ret == 1) || (ret == -1 && errno == EINTR) );
+ if ( ret == -1 )
+ return -1;
+ }
+
+ return count + header->length;
+}
+/* END AIX SEND_FILE */
+
#else /* No sendfile implementation. Return error. */
ssize_t sys_sendfile(int tofd, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count)
ldap_state->last_ping = time(NULL);
+ ldap_state->pid = sys_getpid();
DEBUG(4,("The LDAP server is succesfully connected\n"));
return LDAP_SUCCESS;
got_alarm = False;
old_handler = CatchSignal(SIGALRM, gotalarm_sig);
alarm(endtime - now);
+
+ if (ldap_state->pid != sys_getpid())
+ smbldap_close(ldap_state);
}
while (1) {
*attempts += 1;
+ smbldap_close(ldap_state);
open_rc = smbldap_open(ldap_state);
if (open_rc == LDAP_SUCCESS) {
*/
len = 0;
maxlen = 20 * acl_d->count;
- if ((text = malloc(maxlen)) == NULL) {
+ if ((text = SMB_MALLOC(maxlen)) == NULL) {
errno = ENOMEM;
return NULL;
}
maxlen += nbytes + 20 * (acl_d->count - i);
- if ((text = Realloc(oldtext, maxlen)) == NULL) {
+ if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) {
SAFE_FREE(oldtext);
errno = ENOMEM;
return NULL;
* acl[] array, this actually allocates an ACL with room
* for (count+1) entries
*/
- if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
+ if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
errno = ENOMEM;
return NULL;
}
* allocate a temporary buffer for the complete ACL
*/
acl_count = acc_acl->count + def_acl->count;
- acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
+ acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
if (acl_buf == NULL) {
sys_acl_free_acl(tmp_acl);
*/
len = 0;
maxlen = 20 * acl_d->count;
- if ((text = malloc(maxlen)) == NULL) {
+ if ((text = SMB_MALLOC(maxlen)) == NULL) {
errno = ENOMEM;
return NULL;
}
maxlen += nbytes + 20 * (acl_d->count - i);
- if ((text = Realloc(oldtext, maxlen)) == NULL) {
+ if ((text = SMB_REALLOC(oldtext, maxlen)) == NULL) {
free(oldtext);
errno = ENOMEM;
return NULL;
* acl[] array, this actually allocates an ACL with room
* for (count+1) entries
*/
- if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) {
+ if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + count * sizeof(struct acl))) == NULL) {
errno = ENOMEM;
return NULL;
}
* allocate a temporary buffer for the complete ACL
*/
acl_count = acc_acl->count + def_acl->count;
- acl_p = acl_buf = malloc(acl_count * sizeof(acl_buf[0]));
+ acl_p = acl_buf = SMB_MALLOC_ARRAY(struct acl, acl_count);
if (acl_buf == NULL) {
sys_acl_free_acl(tmp_acl);
{
SMB_ACL_T a;
- if ((a = malloc(sizeof(*a))) == NULL) {
+ if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
errno = ENOMEM;
return NULL;
}
{
SMB_ACL_T a;
- if ((a = malloc(sizeof(*a))) == NULL) {
+ if ((a = SMB_MALLOC_P(struct SMB_ACL_T)) == NULL) {
errno = ENOMEM;
return NULL;
}
return NULL;
}
- if ((a = malloc(sizeof(*a) + sizeof(struct acl))) == NULL) {
+ if ((a = SMB_MALLOC(sizeof(struct SMB_ACL_T) + sizeof(struct acl))) == NULL) {
errno = ENOMEM;
return NULL;
}
DEBUG(10,("Entering sys_acl_get_file\n"));
DEBUG(10,("path_p is %s\n",path_p));
- file_acl = (struct acl *)malloc(BUFSIZ);
+ file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
if(file_acl == NULL) {
errno=ENOMEM;
if(acl_entry_link_head == NULL)
return(NULL);
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
* and already has entryp allocated. */
if(acl_entry_link_head->count != 0) {
- acl_entry_link->nextp = (struct acl_entry_link *)
- malloc(sizeof(struct acl_entry_link));
+ acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entry_link->nextp == NULL) {
SAFE_FREE(file_acl);
acl_entry_link->nextp->prevp = acl_entry_link;
acl_entry_link = acl_entry_link->nextp;
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
for( i = 1; i < 4; i++) {
DEBUG(10,("i is %d\n",i));
if(acl_entry_link_head->count != 0) {
- acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entry_link->nextp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
acl_entry_link->nextp->prevp = acl_entry_link;
acl_entry_link = acl_entry_link->nextp;
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(10,("Entering sys_acl_get_fd\n"));
DEBUG(10,("fd is %d\n",fd));
- file_acl = (struct acl *)malloc(BUFSIZ);
+ file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
if(file_acl == NULL) {
errno=ENOMEM;
return(NULL);
}
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
errno = ENOMEM;
* and already has entryp allocated. */
if(acl_entry_link_head->count != 0) {
- acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entry_link->nextp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
}
acl_entry_link->nextp->prevp = acl_entry_link;
acl_entry_link = acl_entry_link->nextp;
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
for( i = 1; i < 4; i++) {
DEBUG(10,("i is %d\n",i));
if(acl_entry_link_head->count != 0){
- acl_entry_link->nextp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ acl_entry_link->nextp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entry_link->nextp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_get_fd is %d\n",errno));
acl_entry_link->nextp->prevp = acl_entry_link;
acl_entry_link = acl_entry_link->nextp;
- acl_entry_link->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ acl_entry_link->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(acl_entry_link->entryp == NULL) {
SAFE_FREE(file_acl);
DEBUG(10,("Entering sys_acl_init\n"));
- theacl = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ theacl = SMB_MALLOC_P(struct acl_entry_link);
if(theacl == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_init is %d\n",errno));
}
if(theacl->count != 0){
- temp_entry->nextp = acl_entryp = (struct acl_entry_link *)malloc(sizeof(struct acl_entry_link));
+ temp_entry->nextp = acl_entryp = SMB_MALLOC_P(struct acl_entry_link);
if(acl_entryp == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
DEBUG(10,("The acl_entryp->prevp is %d\n",acl_entryp->prevp));
}
- *pentry = acl_entryp->entryp = (struct new_acl_entry *)malloc(sizeof(struct new_acl_entry));
+ *pentry = acl_entryp->entryp = SMB_MALLOC_P(struct new_acl_entry);
if(*pentry == NULL) {
errno = ENOMEM;
DEBUG(0,("Error in sys_acl_create_entry is %d\n",errno));
return(0);
acl_length = BUFSIZ;
- file_acl = (struct acl *)malloc(BUFSIZ);
+ file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
if(file_acl == NULL) {
errno = ENOMEM;
if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
acl_length += sizeof(struct acl_entry);
- file_acl_temp = (struct acl *)malloc(acl_length);
+ file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
if(file_acl_temp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
DEBUG(10,("Entering sys_acl_set_fd\n"));
acl_length = BUFSIZ;
- file_acl = (struct acl *)malloc(BUFSIZ);
+ file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
if(file_acl == NULL) {
errno = ENOMEM;
if((file_acl->acl_len + sizeof(struct acl_entry)) > acl_length) {
acl_length += sizeof(struct acl_entry);
- file_acl_temp = (struct acl *)malloc(acl_length);
+ file_acl_temp = (struct acl *)SMB_MALLOC(acl_length);
if(file_acl_temp == NULL) {
SAFE_FREE(file_acl);
errno = ENOMEM;
continue ;
if (S.st_dev == devno) {
- (*mntpath) = strdup(mnt->mnt_dir);
- (*bdev) = strdup(mnt->mnt_fsname);
- (*fs) = strdup(mnt->mnt_type);
+ (*mntpath) = SMB_STRDUP(mnt->mnt_dir);
+ (*bdev) = SMB_STRDUP(mnt->mnt_fsname);
+ (*fs) = SMB_STRDUP(mnt->mnt_type);
if ((*mntpath)&&(*bdev)&&(*fs)) {
ret = 0;
} else {
* but I don't know how
* --metze
*/
- (*mntpath) = strdup(path);
- (*bdev) = strdup(dev_disk);
+ (*mntpath) = SMB_STRDUP(path);
+ (*bdev) = SMB_STRDUP(dev_disk);
if ((*mntpath)&&(*bdev)) {
ret = 0;
} else {
(*bdev) = NULL;
(*fs) = NULL;
- (*mntpath) = strdup(path);
+ (*mntpath) = SMB_STRDUP(path);
if (*mntpath) {
ret = 0;
} else {
#endif
}
+/*******************************************************************
+ An opendir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+DIR *sys_opendir(const char *name)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
+ return opendir64(name);
+#else
+ return opendir(name);
+#endif
+}
+
/*******************************************************************
A readdir wrapper that will deal with 64 bit filesizes.
********************************************************************/
#endif
}
+/*******************************************************************
+ A seekdir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+void sys_seekdir(DIR *dirp, long offset)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
+ seekdir64(dirp, offset);
+#else
+ seekdir(dirp, offset);
+#endif
+}
+
+/*******************************************************************
+ A telldir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+long sys_telldir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
+ return (long)telldir64(dirp);
+#else
+ return (long)telldir(dirp);
+#endif
+}
+
+/*******************************************************************
+ A rewinddir wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+void sys_rewinddir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
+ rewinddir64(dirp);
+#else
+ rewinddir(dirp);
+#endif
+}
+
+/*******************************************************************
+ A close wrapper that will deal with 64 bit filesizes.
+********************************************************************/
+
+int sys_closedir(DIR *dirp)
+{
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
+ return closedir64(dirp);
+#else
+ return closedir(dirp);
+#endif
+}
+
/*******************************************************************
An mknod() wrapper that will deal with 64 bit filesizes.
********************************************************************/
}
#endif
-int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
+static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
{
char *p;
int retval;
return retval;
}
+
+BOOL getgroups_user(const char *user, gid_t primary_gid,
+ gid_t **ret_groups, int *ngroups)
+{
+ int ngrp, max_grp;
+ gid_t *temp_groups;
+ gid_t *groups;
+ int i;
+
+ max_grp = groups_max();
+ temp_groups = SMB_MALLOC_ARRAY(gid_t, max_grp);
+ if (! temp_groups) {
+ return False;
+ }
+
+ if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
+
+ gid_t *groups_tmp;
+
+ groups_tmp = SMB_REALLOC_ARRAY(temp_groups, gid_t, max_grp);
+
+ if (!groups_tmp) {
+ SAFE_FREE(temp_groups);
+ return False;
+ }
+ temp_groups = groups_tmp;
+
+ if (sys_getgrouplist(user, primary_gid,
+ temp_groups, &max_grp) == -1) {
+ DEBUG(0, ("get_user_groups: failed to get the unix "
+ "group list\n"));
+ SAFE_FREE(temp_groups);
+ return False;
+ }
+ }
+
+ ngrp = 0;
+ groups = NULL;
+
+ /* Add in primary group first */
+ add_gid_to_array_unique(primary_gid, &groups, &ngrp);
+
+ for (i=0; i<max_grp; i++)
+ add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
+
+ *ngroups = ngrp;
+ *ret_groups = groups;
+ SAFE_FREE(temp_groups);
+ return True;
+}
+
+NTSTATUS pdb_default_enum_group_memberships(struct pdb_methods *methods,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids,
+ gid_t **gids,
+ int *num_groups)
+{
+ int i;
+
+ if (!getgroups_user(username, primary_gid, gids, num_groups)) {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if (*num_groups == 0) {
+ smb_panic("primary group missing");
+ }
+
+ *sids = SMB_MALLOC_ARRAY(DOM_SID, *num_groups);
+
+ if (*sids == NULL) {
+ SAFE_FREE(gids);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<*num_groups; i++) {
+ if (!NT_STATUS_IS_OK(gid_to_sid(&(*sids)[i], (*gids)[i]))) {
+ DEBUG(1, ("get_user_groups: failed to convert "
+ "gid %ld to a sid!\n",
+ (long int)(*gids)[i+1]));
+ SAFE_FREE(*sids);
+ SAFE_FREE(*gids);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+ }
+
+ return NT_STATUS_OK;
+}
#endif /* WITH_NISPLUS_HOME */
#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
-int Protocol = PROTOCOL_COREPLUS;
+enum protocol_types Protocol = PROTOCOL_COREPLUS;
/* a default finfo structure to ensure all fields are sensible */
file_info def_finfo = {-1,0,0,0,0,0,0,"",""};
/****************************************************************************
Type-safe realloc.
****************************************************************************/
-
+
void *realloc_array(void *p,size_t el_size, unsigned int count)
{
if (count >= MAX_ALLOC_SIZE/el_size) {
if (!s1)
smb_panic("smb_xstrdup: malloc fail\n");
return s1;
+
}
/**
SAFE_FREE(*buf);
}
+#define PWNAMCACHE_SIZE 4
+static struct passwd *pwnam_cache[PWNAMCACHE_SIZE];
+static BOOL pwnam_cache_initialized = False;
+
+static void init_pwnam_cache(void)
+{
+ int i;
+
+ if (pwnam_cache_initialized)
+ return;
+
+ for (i=0; i<PWNAMCACHE_SIZE; i++)
+ pwnam_cache[i] = NULL;
+
+ pwnam_cache_initialized = True;
+ return;
+}
+
struct passwd *getpwnam_alloc(const char *name)
{
+ int i;
+
struct passwd *temp;
+ init_pwnam_cache();
+
+ for (i=0; i<PWNAMCACHE_SIZE; i++) {
+ if ((pwnam_cache[i] != NULL) &&
+ (strcmp(name, pwnam_cache[i]->pw_name) == 0)) {
+ DEBUG(10, ("Got %s from pwnam_cache\n", name));
+ return alloc_copy_passwd(pwnam_cache[i]);
+ }
+ }
+
temp = sys_getpwnam(name);
if (!temp) {
return NULL;
}
+ for (i=0; i<PWNAMCACHE_SIZE; i++) {
+ if (pwnam_cache[i] == NULL)
+ break;
+ }
+
+ if (i == PWNAMCACHE_SIZE)
+ i = rand() % PWNAMCACHE_SIZE;
+
+ if (pwnam_cache[i] != NULL)
+ passwd_free(&pwnam_cache[i]);
+
+ pwnam_cache[i] = alloc_copy_passwd(temp);
+
return alloc_copy_passwd(temp);
}
NOTE! uses become_root() to gain correct priviages on systems
that lack a native getgroups() call (uses initgroups and getgroups)
*/
-BOOL getgroups_user(const char *user, gid_t **ret_groups, int *ngroups)
+BOOL getgroups_user(const char *user, gid_t primary_gid, gid_t **ret_groups, int *ngroups)
{
- struct passwd *pwd;
int ngrp, max_grp;
gid_t *temp_groups;
gid_t *groups;
int i;
- pwd = getpwnam_alloc(user);
- if (!pwd) return False;
-
max_grp = groups_max();
temp_groups = SMB_MALLOC_ARRAY(gid_t, max_grp);
if (! temp_groups) {
- passwd_free(&pwd);
return False;
}
- if (sys_getgrouplist(user, pwd->pw_gid, temp_groups, &max_grp) == -1) {
+ if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
gid_t *groups_tmp;
}
temp_groups = groups_tmp;
- if (sys_getgrouplist(user, pwd->pw_gid, temp_groups, &max_grp) == -1) {
+ if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
- passwd_free(&pwd);
SAFE_FREE(temp_groups);
return False;
}
groups = NULL;
/* Add in primary group first */
- add_gid_to_array_unique(pwd->pw_gid, &groups, &ngrp);
-
- passwd_free(&pwd);
+ add_gid_to_array_unique(primary_gid, &groups, &ngrp);
for (i=0; i<max_grp; i++)
add_gid_to_array_unique(temp_groups[i], &groups, &ngrp);
return res;
}
+/****************************************************************************
+ Create an outgoing TCP socket to any of the addrs. This is for
+ simultaneous connects to port 445 and 139 of a host or even a variety
+ of DC's all of which are equivalent for our purposes.
+**************************************************************************/
+
+BOOL open_any_socket_out(struct sockaddr_in *addrs, int num_addrs,
+ int timeout, int *fd_index, int *fd)
+{
+ int i, resulting_index, res;
+ int *sockets;
+ BOOL good_connect;
+
+ fd_set r_fds, wr_fds;
+ struct timeval tv;
+ int maxfd;
+
+ int connect_loop = 10000; /* 10 milliseconds */
+
+ timeout *= 1000; /* convert to microseconds */
+
+ sockets = SMB_MALLOC_ARRAY(int, num_addrs);
+
+ if (sockets == NULL)
+ return False;
+
+ resulting_index = -1;
+
+ for (i=0; i<num_addrs; i++)
+ sockets[i] = -1;
+
+ for (i=0; i<num_addrs; i++) {
+ sockets[i] = socket(PF_INET, SOCK_STREAM, 0);
+ if (sockets[i] < 0)
+ goto done;
+ set_blocking(sockets[i], False);
+ }
+
+ connect_again:
+ good_connect = False;
+
+ for (i=0; i<num_addrs; i++) {
+
+ if (sockets[i] == -1)
+ continue;
+
+ if (connect(sockets[i], (struct sockaddr *)&(addrs[i]),
+ sizeof(*addrs)) == 0) {
+ /* Rather unlikely as we are non-blocking, but it
+ * might actually happen. */
+ resulting_index = i;
+ goto done;
+ }
+
+ if (errno == EINPROGRESS || errno == EALREADY ||
+ errno == EAGAIN) {
+ /* These are the error messages that something is
+ progressing. */
+ good_connect = True;
+ } else if (errno != 0) {
+ /* There was a direct error */
+ close(sockets[i]);
+ sockets[i] = -1;
+ }
+ }
+
+ if (!good_connect) {
+ /* All of the connect's resulted in real error conditions */
+ goto done;
+ }
+
+ /* Lets see if any of the connect attempts succeeded */
+
+ maxfd = 0;
+ FD_ZERO(&wr_fds);
+ FD_ZERO(&r_fds);
+
+ for (i=0; i<num_addrs; i++) {
+ if (sockets[i] == -1)
+ continue;
+ FD_SET(sockets[i], &wr_fds);
+ FD_SET(sockets[i], &r_fds);
+ if (sockets[i]>maxfd)
+ maxfd = sockets[i];
+ }
+
+ tv.tv_sec = 0;
+ tv.tv_usec = connect_loop;
+
+ res = sys_select(maxfd+1, &r_fds, &wr_fds, NULL, &tv);
+
+ if (res < 0)
+ goto done;
+
+ if (res == 0)
+ goto next_round;
+
+ for (i=0; i<num_addrs; i++) {
+
+ if (sockets[i] == -1)
+ continue;
+
+ /* Stevens, Network Programming says that if there's a
+ * successful connect, the socket is only writable. Upon an
+ * error, it's both readable and writable. */
+
+ if (FD_ISSET(sockets[i], &r_fds) &&
+ FD_ISSET(sockets[i], &wr_fds)) {
+ /* readable and writable, so it's an error */
+ close(sockets[i]);
+ sockets[i] = -1;
+ continue;
+ }
+
+ if (!FD_ISSET(sockets[i], &r_fds) &&
+ FD_ISSET(sockets[i], &wr_fds)) {
+ /* Only writable, so it's connected */
+ resulting_index = i;
+ goto done;
+ }
+ }
+
+ next_round:
+
+ timeout -= connect_loop;
+ if (timeout <= 0)
+ goto done;
+ connect_loop *= 1.5;
+ if (connect_loop > timeout)
+ connect_loop = timeout;
+ goto connect_again;
+
+ done:
+ for (i=0; i<num_addrs; i++) {
+ if (i == resulting_index)
+ continue;
+ if (sockets[i] >= 0)
+ close(sockets[i]);
+ }
+
+ if (resulting_index >= 0) {
+ *fd_index = resulting_index;
+ *fd = sockets[*fd_index];
+ set_blocking(*fd, True);
+ }
+
+ free(sockets);
+
+ return (resulting_index >= 0);
+}
/****************************************************************************
Open a connected UDP socket to host on port
**************************************************************************/
/**
Some platforms don't have strndup.
**/
+#if defined(PARANOID_MALLOC_CHECKER)
+#undef strndup
+#endif
char *strndup(const char *s, size_t n)
{
return ret;
}
+
+#if defined(PARANOID_MALLOC_CHECKER)
+#define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
+#endif
+
#endif
#if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
The char* arguments must NOT be multibyte - to be completely sure
of this only pass string constants */
-
-void pstrcpy_wa(smb_ucs2_t *dest, const char *src)
-{
- int i;
- for (i=0;i<PSTRING_LEN;i++) {
- dest[i] = UCS2_CHAR(src[i]);
- if (src[i] == 0) return;
- }
-}
-
int strcmp_wa(const smb_ucs2_t *a, const char *b)
{
while (*b && *a == UCS2_CHAR(*b)) { a++; b++; }
*/
const char *ads_errstr(ADS_STATUS status)
{
- uint32 msg_ctx;
static char *ret;
SAFE_FREE(ret);
- msg_ctx = 0;
switch (status.error_type) {
case ENUM_ADS_ERROR_SYSTEM:
#ifdef HAVE_GSSAPI
case ENUM_ADS_ERROR_GSS:
{
+ uint32 msg_ctx;
uint32 minor;
-
gss_buffer_desc msg1, msg2;
+
+ msg_ctx = 0;
+
msg1.value = NULL;
msg2.value = NULL;
gss_display_status(&minor, status.err.rc, GSS_C_GSS_CODE,
krb5_auth_context auth_context = NULL;
krb5_error_code err = 0;
+ ZERO_STRUCT(creds);
+
asprintf(&machine_account, "%s$@%s", global_myname(), lp_realm());
if (machine_account == NULL) {
goto out;
ticket to ourselves. */
/* Set up the enctype and client and server principal fields for krb5_get_credentials. */
- memset(&creds, '\0', sizeof(creds));
kerberos_set_creds_enctype(&creds, enctype);
if ((err = krb5_cc_get_principal(ctx, ccache, &creds.client))) {
return ldp;
}
+static int ldap_search_with_timeout(LDAP *ld,
+ LDAP_CONST char *base,
+ int scope,
+ LDAP_CONST char *filter,
+ char **attrs,
+ int attrsonly,
+ LDAPControl **sctrls,
+ LDAPControl **cctrls,
+ struct timeval *timeout,
+ int sizelimit,
+ LDAPMessage **res )
+{
+ int result;
+
+ /* Setup timeout */
+ gotalarm = 0;
+ CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+ alarm(lp_ldap_timeout());
+ /* End setup timeout. */
+
+ result = ldap_search_ext_s(ld, base, scope, filter, attrs,
+ attrsonly, sctrls, cctrls, timeout,
+ sizelimit, res);
+
+ /* Teardown timeout. */
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
+ alarm(0);
+
+ if (gotalarm != 0)
+ return LDAP_TIMELIMIT_EXCEEDED;
+
+ return result;
+}
+
/*
try a connection to a given ldap server, returning True and setting the servers IP
in the ads struct if successful
*/
ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
- rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr,
- search_attrs, 0, controls,
- NULL, NULL, LDAP_NO_LIMIT, (LDAPMessage **)res);
+ rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr,
+ search_attrs, 0, controls,
+ NULL, NULL, LDAP_NO_LIMIT,
+ (LDAPMessage **)res);
ber_free(cookie_be, 1);
ber_bvfree(cookie_bv);
if (rc) {
- DEBUG(3,("ldap_search_ext_s(%s) -> %s\n", expr, ldap_err2string(rc)));
+ DEBUG(3,("ldap_search_with_timeout(%s) -> %s\n", expr,
+ ldap_err2string(rc)));
goto done;
}
/* see the note in ads_do_paged_search - we *must* disable referrals */
ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
- rc = ldap_search_ext_s(ads->ld, utf8_path, scope, utf8_expr,
- search_attrs, 0, NULL, NULL,
- &timeout, LDAP_NO_LIMIT, (LDAPMessage **)res);
+ rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr,
+ search_attrs, 0, NULL, NULL,
+ &timeout, LDAP_NO_LIMIT,
+ (LDAPMessage **)res);
if (rc == LDAP_SIZELIMIT_EXCEEDED) {
DEBUG(3,("Warning! sizelimit exceeded in ldap. Truncating.\n"));
failed:
SAFE_FREE(service_principal);
SAFE_FREE(password);
- SAFE_FREE(new_password);
return ret;
}
#endif
if (cli->use_level_II_oplocks)
capabilities |= CAP_LEVEL_II_OPLOCKS;
- if (cli->capabilities & CAP_UNICODE)
- capabilities |= CAP_UNICODE;
-
- if (cli->capabilities & CAP_LARGE_FILES)
- capabilities |= CAP_LARGE_FILES;
-
+ capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX));
return capabilities;
}
cli->sign_info.negotiated_smb_signing = True;
}
+ if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
+ SAFE_FREE(cli->outbuf);
+ SAFE_FREE(cli->inbuf);
+ cli->outbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN);
+ cli->inbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN);
+ cli->bufsize = CLI_MAX_LARGE_READX_SIZE;
+ }
+
} else if (cli->protocol >= PROTOCOL_LANMAN1) {
cli->use_spnego = False;
cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
}
}
+/****************************************************************************
+ Do a POSIX getfacl (UNIX extensions).
+****************************************************************************/
+
+BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf)
+{
+ unsigned int param_len = 0;
+ unsigned int data_len = 0;
+ uint16 setup = TRANSACT2_QPATHINFO;
+ char param[sizeof(pstring)+6];
+ char *rparam=NULL, *rdata=NULL;
+ char *p;
+
+ p = param;
+ memset(p, 0, 6);
+ SSVAL(p, 0, SMB_QUERY_POSIX_ACL);
+ p += 6;
+ p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE);
+ param_len = PTR_DIFF(p, param);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ NULL, 0, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, ¶m_len,
+ &rdata, &data_len)) {
+ return False;
+ }
+
+ if (data_len < 6) {
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+ return False;
+ }
+
+ SAFE_FREE(rparam);
+ *retbuf = rdata;
+ *prb_size = (size_t)data_len;
+
+ return True;
+}
+
/****************************************************************************
Stat a file (UNIX extensions).
****************************************************************************/
#include "includes.h"
+/****************************************************************************
+ Get UNIX extensions version info.
+****************************************************************************/
+
+BOOL cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor,
+ uint32 *pcaplow, uint32 *pcaphigh)
+{
+ BOOL ret = False;
+ uint16 setup;
+ char param[2];
+ char *rparam=NULL, *rdata=NULL;
+ unsigned int rparam_count=0, rdata_count=0;
+
+ setup = TRANSACT2_QFSINFO;
+
+ SSVAL(param,0,SMB_QUERY_CIFS_UNIX_INFO);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL,
+ 0, 0,
+ &setup, 1, 0,
+ param, 2, 0,
+ NULL, 0, 560)) {
+ goto cleanup;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &rparam_count,
+ &rdata, &rdata_count)) {
+ goto cleanup;
+ }
+
+ if (cli_is_error(cli)) {
+ ret = False;
+ goto cleanup;
+ } else {
+ ret = True;
+ }
+
+ if (rdata_count < 12) {
+ goto cleanup;
+ }
+
+ *pmajor = SVAL(rdata,0);
+ *pminor = SVAL(rdata,2);
+ *pcaplow = IVAL(rdata,4);
+ *pcaphigh = IVAL(rdata,8);
+
+ /* todo: but not yet needed
+ * return the other stuff
+ */
+
+cleanup:
+ SAFE_FREE(rparam);
+ SAFE_FREE(rdata);
+
+ return ret;
+}
BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr)
{
void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt)
{
#if defined(HAVE_KRB5_TKT_ENC_PART2)
- if (tkt->enc_part2)
+ if (tkt->enc_part2 && tkt->enc_part2->authorization_data && tkt->enc_part2->authorization_data[0] && tkt->enc_part2->authorization_data[0]->length)
*auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents,
tkt->enc_part2->authorization_data[0]->length);
#else
return -1;
}
- sa = malloc( sizeof(struct sockaddr) * num_kdcs );
+ sa = SMB_MALLOC_ARRAY( struct sockaddr, num_kdcs );
if (!sa) {
DEBUG(0, ("krb5_locate_kdc: malloc failed\n"));
krb5_krbhst_free(ctx, hnd);
return -1;
}
- *addr_pp = malloc(sizeof(struct sockaddr) * num_kdcs);
- memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs );
+ memset(sa, '\0', sizeof(struct sockaddr) * num_kdcs );
for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) {
SIVAL(cli->outbuf,smb_vwv3,offset);
SSVAL(cli->outbuf,smb_vwv5,size);
SSVAL(cli->outbuf,smb_vwv6,size);
+ SSVAL(cli->outbuf,smb_vwv7,((size >> 16) & 1));
SSVAL(cli->outbuf,smb_mid,cli->mid + i);
if (bigoffset)
* rounded down to a multiple of 1024.
*/
- readsize = (cli->max_xmit - (smb_size+32)) & ~1023;
+ if (cli->capabilities & CAP_LARGE_READX) {
+ readsize = CLI_MAX_LARGE_READX_SIZE;
+ } else {
+ readsize = (cli->max_xmit - (smb_size+32)) & ~1023;
+ }
while (total < size) {
readsize = MIN(readsize, size-total);
}
size2 = SVAL(cli->inbuf, smb_vwv5);
+ size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7) & 1)) << 16);
if (size2 > readsize) {
DEBUG(5,("server returned more than we wanted!\n"));
size_t size, int i)
{
char *p;
- BOOL bigoffset = False;
+ BOOL large_writex = False;
if (size > cli->bufsize) {
cli->outbuf = SMB_REALLOC(cli->outbuf, size + 1024);
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
- if ((SMB_BIG_UINT)offset >> 32)
- bigoffset = True;
+ if (((SMB_BIG_UINT)offset >> 32) || (size > 0xFFFF)) {
+ large_writex = True;
+ }
- if (bigoffset)
+ if (large_writex)
set_message(cli->outbuf,14,0,True);
else
set_message(cli->outbuf,12,0,True);
SSVAL(cli->outbuf,smb_vwv11,
smb_buf(cli->outbuf) - smb_base(cli->outbuf));
- if (bigoffset)
+ if (large_writex)
SIVAL(cli->outbuf,smb_vwv12,(offset>>32) & 0xffffffff);
p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11);
struct smbc_dir_list *dir_list;
struct smbc_dirent *dirent;
int dirent_type;
- int remove = 0;
+ int do_remove = 0;
dirent_type = dir->dir_type;
for (dir_list = dir->dir_list;
dir_list != dir->dir_end;
dir_list = dir_list->next) {
- if (! remove &&
+ if (! do_remove &&
strcmp(dir_list->dirent->name, dirent->name) == 0) {
/* Duplicate. End end of list need to be removed. */
- remove = 1;
+ do_remove = 1;
}
- if (remove && dir_list->next == dir->dir_end) {
+ if (do_remove && dir_list->next == dir->dir_end) {
/* Found the end of the list. Remove it. */
dir->dir_end = dir_list;
free(dir_list->next);
resolve_hosts() when looking up DC's via SRV RR entries in DNS
**********************************************************************/
-static BOOL internal_resolve_name(const char *name, int name_type,
- struct ip_service **return_iplist,
- int *return_count, const char *resolve_order)
+BOOL internal_resolve_name(const char *name, int name_type,
+ struct ip_service **return_iplist,
+ int *return_count, const char *resolve_order)
{
pstring name_resolve_list;
fstring tok;
recv_sign_const = CLI_SIGN;
recv_seal_const = CLI_SEAL;
break;
+ default:
+ send_sign_const = "unknown role";
+ send_seal_const = "unknown role";
+ recv_sign_const = "unknown role";
+ recv_seal_const = "unknown role";
+ break;
}
calc_ntlmv2_hash(ntlmssp_state->send_sign_hash,
/* so we fill it in since winbindd_getpwnam() makes use of it */
if ( !user->uni_user_name.buffer ) {
- init_unistr2( &user->uni_user_name, username, STR_TERMINATE );
+ init_unistr2( &user->uni_user_name, username, UNI_STR_TERMINATE );
init_uni_hdr( &user->hdr_user_name, &user->uni_user_name );
}
BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
uint16 smbpid, pid_t pid, uint16 tid,
br_off start, br_off size,
- enum brl_type lock_type, int check_self)
+ enum brl_type lock_type)
{
TDB_DATA kbuf, dbuf;
int count, i;
locks = (struct lock_struct *)dbuf.dptr;
count = dbuf.dsize / sizeof(*locks);
for (i=0; i<count; i++) {
- if (check_self) {
- if (brl_conflict(&locks[i], &lock))
- goto fail;
- } else {
- /*
- * Our own locks don't conflict.
- */
- if (brl_conflict_other(&locks[i], &lock))
- goto fail;
- }
+ /*
+ * Our own locks don't conflict.
+ */
+ if (brl_conflict_other(&locks[i], &lock))
+ goto fail;
}
}
/****************************************************************************
Utility function called to see if a file region is locked.
- If check_self is True, then checks on our own fd with the same locking context
- are still made. If check_self is False, then checks are not made on our own fd
- with the same locking context are not made.
****************************************************************************/
BOOL is_locked(files_struct *fsp,connection_struct *conn,
SMB_BIG_UINT count,SMB_BIG_UINT offset,
- enum brl_type lock_type, BOOL check_self)
+ enum brl_type lock_type)
{
int snum = SNUM(conn);
+ int strict_locking = lp_strict_locking(snum);
BOOL ret;
if (count == 0)
return(False);
- if (!lp_locking(snum) || !lp_strict_locking(snum))
+ if (!lp_locking(snum) || !strict_locking)
return(False);
- ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
- global_smbpid, sys_getpid(), conn->cnum,
- offset, count, lock_type, check_self);
+ if (strict_locking == Auto) {
+ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
+ DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
+ ret = 0;
+ } else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK)) {
+ DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
+ ret = 0;
+ } else {
+ ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
+ global_smbpid, sys_getpid(), conn->cnum,
+ offset, count, lock_type);
+ }
+ } else {
+ ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
+ global_smbpid, sys_getpid(), conn->cnum,
+ offset, count, lock_type);
+ }
DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
(double)offset, (double)count, ret ? "locked" : "unlocked",
BOOL share_modes_identical( share_mode_entry *e1, share_mode_entry *e2)
{
+#if 1 /* JRA PARANOIA TEST - REMOVE LATER */
+ if (e1->pid == e2->pid &&
+ e1->share_file_id == e2->share_file_id &&
+ e1->dev == e2->dev &&
+ e1->inode == e2->inode &&
+ (e1->share_mode & ~DELETE_ON_CLOSE_FLAG) != (e2->share_mode & ~DELETE_ON_CLOSE_FLAG)) {
+ DEBUG(0,("PANIC: share_modes_identical: share_mode missmatch (e1 = %u, e2 = %u). Logic error.\n",
+ (unsigned int)(e1->share_mode & ~DELETE_ON_CLOSE_FLAG),
+ (unsigned int)(e2->share_mode & ~DELETE_ON_CLOSE_FLAG) ));
+ smb_panic("PANIC: share_modes_identical logic error.\n");
+ }
+#endif
+
return (e1->pid == e2->pid &&
(e1->share_mode & ~DELETE_ON_CLOSE_FLAG) == (e2->share_mode & ~DELETE_ON_CLOSE_FLAG) &&
e1->dev == e2->dev &&
}
}
+
/*******************************************************************
Form a static deferred open locking key for a dev/inode pair.
******************************************************************/
extern DOM_SID global_sid_Authenticated_Users;
extern DOM_SID global_sid_NULL;
+static char space_replacement = '%';
+
extern int afs_syscall(int, char *, int, char *, int);
struct afs_ace {
static struct afs_ace *clone_afs_ace(TALLOC_CTX *mem_ctx, struct afs_ace *ace)
{
- struct afs_ace *result = talloc(mem_ctx, sizeof(struct afs_ace));
+ struct afs_ace *result = TALLOC_P(mem_ctx, struct afs_ace);
if (result == NULL)
return NULL;
}
}
- result = talloc(mem_ctx, sizeof(struct afs_ace));
+ result = TALLOC_P(mem_ctx, struct afs_ace);
if (result == NULL) {
DEBUG(0, ("Could not talloc AFS ace\n"));
for (aces = nplus+nminus; aces > 0; aces--)
{
- const char *name;
+ const char *namep;
+ fstring name;
uint32 rights;
+ char *space;
- name = p;
+ namep = p;
if ((p = strchr(p, '\t')) == NULL)
return False;
return False;
p += 1;
+ fstrcpy(name, namep);
+
+ while ((space = strchr_m(name, space_replacement)) != NULL)
+ *space = ' ';
+
add_afs_ace(acl, nplus>0, name, rights);
nplus -= 1;
{ 0, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT,
0x00120089, 8 /* l */ },
+ /* some stupid workaround for preventing fallbacks */
+ { 0, 0x3, 0x0012019F, 9 /* rl */ },
+ { 0, 0x13, PERMS_FULL, 127 /* full */ },
+
+ /* read, delete and execute access plus synchronize */
+ { 0, 0x3, 0x001300A9, 9 /* should be rdl, set to rl */},
+ /* classical read list */
+ { 0, 0x13, 0x001200A9, 9 /* rl */},
+ /* almost full control, no delete */
+ { 0, 0x13, PERMS_CHANGE, 63 /* rwidlk */},
+
/* List folder */
{ 0, SEC_ACE_FLAG_CONTAINER_INHERIT,
PERMS_READ, 8 /* l */ },
return m->afs_rights;
}
- DEBUG(1, ("AFSACL FALLBACK: 0x%X 0x%X 0x%X %s\n",
- ace->type, ace->flags, ace->info.mask, filename));
+ DEBUG(1, ("AFSACL FALLBACK: 0x%X 0x%X 0x%X %s %X\n",
+ ace->type, ace->flags, ace->info.mask, filename, rights));
if (rights & (GENERIC_ALL_ACCESS|WRITE_DAC_ACCESS)) {
result |= PRSFS_READ | PRSFS_WRITE | PRSFS_INSERT |
uid_to_sid(&owner_sid, sbuf.st_uid);
gid_to_sid(&group_sid, sbuf.st_gid);
- nt_ace_list = (SEC_ACE *)malloc(afs_acl->num_aces * sizeof(SEC_ACE));
+ nt_ace_list = SMB_MALLOC_ARRAY(SEC_ACE, afs_acl->num_aces);
if (nt_ace_list == NULL)
return 0;
fstring dom_name;
fstring name;
enum SID_NAME_USE name_type;
+ char *p;
if (ace->type != SEC_ACE_TYPE_ACCESS_ALLOWED) {
/* First cut: Only positive ACEs */
}
}
+ while ((p = strchr_m(name, ' ')) != NULL)
+ *p = space_replacement;
+
add_afs_ace(afs_acl, True, name,
nt_to_afs_rights(filename, ace));
}
return afs_set_nt_acl(handle, fsp, security_info_sent, psd);
}
+static int afsacl_connect(vfs_handle_struct *handle,
+ connection_struct *conn,
+ const char *service,
+ const char *user)
+{
+ char *spc;
+
+ spc = lp_parm_const_string(SNUM(handle->conn), "afsacl", "space", "%");
+
+ if (spc != NULL)
+ space_replacement = spc[0];
+
+ return SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
+}
+
/* VFS operations structure */
static vfs_op_tuple afsacl_ops[] = {
+ {SMB_VFS_OP(afsacl_connect), SMB_VFS_OP_CONNECT,
+ SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(afsacl_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(afsacl_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
return SMB_VFS_NEXT_OPENDIR(handle, conn, capname);
}
-static struct dirent *cap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
- struct dirent *result;
+ SMB_STRUCT_DIRENT *result;
DEBUG(3,("cap: cap_readdir\n"));
result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
if (result) {
SMB_DISK_QUOTA *qt);
static DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn,
const char *fname);
-static struct dirent *smb_full_audit_readdir(vfs_handle_struct *handle,
+static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle,
connection_struct *conn, DIR *dirp);
+static void smb_full_audit_seekdir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp, long offset);
+static long smb_full_audit_telldir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp);
+static void smb_full_audit_rewinddir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp);
static int smb_full_audit_mkdir(vfs_handle_struct *handle, connection_struct *conn,
const char *path, mode_t mode);
static int smb_full_audit_rmdir(vfs_handle_struct *handle, connection_struct *conn,
SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_readdir), SMB_VFS_OP_READDIR,
SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(smb_full_audit_seekdir), SMB_VFS_OP_SEEKDIR,
+ SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(smb_full_audit_telldir), SMB_VFS_OP_TELLDIR,
+ SMB_VFS_LAYER_LOGGER},
+ {SMB_VFS_OP(smb_full_audit_rewinddir), SMB_VFS_OP_REWINDDIR,
+ SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_mkdir), SMB_VFS_OP_MKDIR,
SMB_VFS_LAYER_LOGGER},
{SMB_VFS_OP(smb_full_audit_rmdir), SMB_VFS_OP_RMDIR,
return result;
}
-static struct dirent *smb_full_audit_readdir(vfs_handle_struct *handle,
+static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle,
connection_struct *conn, DIR *dirp)
{
- struct dirent *result;
+ SMB_STRUCT_DIRENT *result;
result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
return result;
}
+static void smb_full_audit_seekdir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp, long offset)
+{
+ SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset);
+
+ do_log(SMB_VFS_OP_SEEKDIR, True, handle, "");
+ return;
+}
+
+static long smb_full_audit_telldir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp)
+{
+ long result;
+
+ result = SMB_VFS_NEXT_TELLDIR(handle, conn, dirp);
+
+ do_log(SMB_VFS_OP_OPENDIR, True, handle, "");
+
+ return result;
+}
+
+static void smb_full_audit_rewinddir(vfs_handle_struct *handle, connection_struct *conn,
+ DIR *dirp)
+{
+ SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp);
+
+ do_log(SMB_VFS_OP_REWINDDIR, True, handle, "");
+ return;
+}
+
static int smb_full_audit_mkdir(vfs_handle_struct *handle, connection_struct *conn,
const char *path, mode_t mode)
{
static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
{
char *dpath;
- struct dirent *dent = 0;
+ SMB_STRUCT_DIRENT *dent = 0;
DIR *dir;
if (!path) return;
dir = opendir(path);
if (!dir) return;
- while (NULL != (dent = readdir(dir))) {
+ while (NULL != (dent = sys_readdir(dir))) {
if (strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0)
continue;
typedef struct {
int pos;
int num;
- struct dirent *dirs;
+ SMB_STRUCT_DIRENT *dirs;
} shadow_copy_Dir;
static BOOL shadow_copy_match_name(const char *name)
ZERO_STRUCTP(dirp);
while (True) {
- struct dirent *d;
- struct dirent *r;
+ SMB_STRUCT_DIRENT *d;
+ SMB_STRUCT_DIRENT *r;
d = SMB_VFS_NEXT_READDIR(handle, conn, p);
DEBUG(10,("shadow_copy_opendir: not hide [%s]\n",d->d_name));
- r = SMB_REALLOC_ARRAY(dirp->dirs, struct dirent, dirp->num+1);
+ r = SMB_REALLOC_ARRAY(dirp->dirs,SMB_STRUCT_DIRENT, dirp->num+1);
if (!r) {
DEBUG(0,("shadow_copy_opendir: Out of memory\n"));
break;
return((DIR *)dirp);
}
-struct dirent *shadow_copy_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp)
+SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *_dirp)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
while (True) {
SHADOW_COPY_LABEL *tlabels;
- struct dirent *d;
+ SMB_STRUCT_DIRENT *d;
d = SMB_VFS_NEXT_READDIR(handle, fsp->conn, p);
if (d == NULL) {
plus the broadcast sockets.
***************************************************************************/
-static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number)
+static BOOL create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
{
int *sock_array = NULL;
struct subnet_record *subrec = NULL;
/* Add in the broadcast socket on 137. */
FD_SET(ClientNMB,pset);
sock_array[num++] = ClientNMB;
+ *maxfd = MAX( *maxfd, ClientNMB);
/* Add in the 137 sockets on all the interfaces. */
for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
FD_SET(subrec->nmb_sock,pset);
sock_array[num++] = subrec->nmb_sock;
+ *maxfd = MAX( *maxfd, subrec->nmb_sock);
}
/* Add in the broadcast socket on 138. */
FD_SET(ClientDGRAM,pset);
sock_array[num++] = ClientDGRAM;
+ *maxfd = MAX( *maxfd, ClientDGRAM);
/* Add in the 138 sockets on all the interfaces. */
for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
FD_SET(subrec->dgram_sock,pset);
sock_array[num++] = subrec->dgram_sock;
+ *maxfd = MAX( *maxfd, subrec->dgram_sock);
}
*listen_number = (count*2) + 2;
static int listen_number = 0;
static int *sock_array = NULL;
int i;
+ static int maxfd = 0;
fd_set fds;
int selrtn;
#endif
if(listen_set == NULL || rescan_listen_set) {
- if(create_listen_fdset(&listen_set, &sock_array, &listen_number)) {
+ if(create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {
DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
return True;
}
dns_fd = asyncdns_fd();
if (dns_fd != -1) {
FD_SET(dns_fd, &fds);
+ maxfd = MAX( maxfd, dns_fd);
}
#endif
BlockSignals(False, SIGTERM);
- selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
+ selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&timeout);
/* We can only take signals when we are in the select - block them again here. */
return retval;
default:
/* we don't know anything about this return value */
- _pam_log(LOG_ERR, "internal module error (retval = %d, user = `%s'",
+ _pam_log(LOG_ERR, "internal module error (retval = %d, user = `%s')",
retval, user);
return retval;
}
void *private;
+ /* A working DC */
+ fstring dcname;
+ struct sockaddr_in dcaddr;
+
/* Sequence number stuff */
time_t last_seq_check;
return True;
}
-/* Open a connction to the remote server, cache failures for 30 seconds */
+/************************************************************************
+ Given a fd with a just-connected TCP connection to a DC, open a connection
+ to the pipe.
+************************************************************************/
-static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const int pipe_index,
- struct winbindd_cm_conn *new_conn)
+static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
+ const int sockfd,
+ const int pipe_index,
+ const char *controller,
+ struct cli_state **cli,
+ BOOL *retry)
{
- NTSTATUS result;
- char *machine_password;
- char *machine_krb5_principal, *ipc_username, *ipc_domain, *ipc_password;
- struct in_addr dc_ip;
- int i;
- BOOL retry = True;
+ char *machine_password, *machine_krb5_principal;
+ char *ipc_username, *ipc_domain, *ipc_password;
+ struct ntuser_creds creds;
- ZERO_STRUCT(dc_ip);
+ BOOL got_mutex;
+ BOOL add_failed_connection = True;
- fstrcpy(new_conn->domain, domain->name);
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- if (!get_dc_name_via_netlogon(domain, new_conn->controller, &dc_ip)) {
+ struct sockaddr peeraddr;
+ socklen_t peeraddr_len;
- /* connection failure cache has been moved inside of
- get_dc_name so we can deal with half dead DC's --jerry */
+ struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
- if (!get_dc_name(domain->name, domain->alt_name[0] ?
- domain->alt_name : NULL,
- new_conn->controller, &dc_ip)) {
- result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
- add_failed_connection_entry(domain->name, "", result);
- return result;
- }
- }
-
- /* Initialise SMB connection */
- fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));
-
- /* grab stored passwords */
+ machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
+ NULL);
- machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
-
- if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(), lp_realm()) == -1) {
+ if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
+ lp_realm()) == -1) {
SAFE_FREE(machine_password);
return NT_STATUS_NO_MEMORY;
}
cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
- for (i = 0; retry && (i < 3); i++) {
- BOOL got_mutex;
- if (!(got_mutex = secrets_named_mutex(new_conn->controller, WINBIND_SERVER_MUTEX_WAIT_TIME))) {
- DEBUG(0,("cm_open_connection: mutex grab failed for %s\n", new_conn->controller));
- result = NT_STATUS_POSSIBLE_DEADLOCK;
- continue;
+ *retry = True;
+
+ got_mutex = secrets_named_mutex(controller,
+ WINBIND_SERVER_MUTEX_WAIT_TIME);
+
+ if (!got_mutex) {
+ DEBUG(0,("cm_open_connection: mutex grab failed for %s\n",
+ controller));
+ result = NT_STATUS_POSSIBLE_DEADLOCK;
+ goto done;
+ }
+
+ if ((*cli = cli_initialise(NULL)) == NULL) {
+ DEBUG(1, ("Could not cli_initialize\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ (*cli)->timeout = 10000; /* 10 seconds */
+ (*cli)->fd = sockfd;
+ fstrcpy((*cli)->desthost, controller);
+ (*cli)->use_kerberos = True;
+
+ peeraddr_len = sizeof(peeraddr);
+
+ if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
+ (peeraddr_len != sizeof(struct sockaddr_in)) ||
+ (peeraddr_in->sin_family != PF_INET))
+ goto done;
+
+ if (ntohs(peeraddr_in->sin_port) == 139) {
+ struct nmb_name calling;
+ struct nmb_name called;
+
+ make_nmb_name(&calling, global_myname(), 0x0);
+ make_nmb_name(&called, "*SMBSERVER", 0x20);
+
+ if (!cli_session_request(*cli, &calling, &called)) {
+ DEBUG(8, ("cli_session_request failed for %s\n",
+ controller));
+ goto done;
}
-
- new_conn->cli = NULL;
- result = cli_start_connection(&new_conn->cli, global_myname(),
- new_conn->controller,
- &dc_ip, 0, Undefined,
- CLI_FULL_CONNECTION_USE_KERBEROS,
- &retry);
+ }
- if (NT_STATUS_IS_OK(result)) {
+ cli_setup_signing_state(*cli, Undefined);
- /* reset the error code */
- result = NT_STATUS_UNSUCCESSFUL;
+ if (!cli_negprot(*cli)) {
+ DEBUG(1, ("cli_negprot failed\n"));
+ cli_shutdown(*cli);
+ goto done;
+ }
- /* Krb5 session */
+ /* Krb5 session */
- if ((lp_security() == SEC_ADS)
- && (new_conn->cli->protocol >= PROTOCOL_NT1 && new_conn->cli->capabilities & CAP_EXTENDED_SECURITY)) {
- ADS_STATUS ads_status;
- new_conn->cli->use_kerberos = True;
- DEBUG(5, ("connecting to %s from %s with kerberos principal [%s]\n",
- new_conn->controller, global_myname(), machine_krb5_principal));
-
- ads_status = cli_session_setup_spnego(new_conn->cli, machine_krb5_principal,
- machine_password,
- lp_workgroup());
- if (!ADS_ERR_OK(ads_status)) {
- DEBUG(4,("failed kerberos session setup with %s\n", ads_errstr(ads_status)));
- result = ads_ntstatus(ads_status);
- } else {
- result = NT_STATUS_OK;
- }
- }
- new_conn->cli->use_kerberos = False;
-
- /* only do this is we have a username/password for thr IPC$ connection */
-
- if ( !NT_STATUS_IS_OK(result)
- && new_conn->cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE
- && strlen(ipc_username) )
- {
- DEBUG(5, ("connecting to %s from %s with username [%s]\\[%s]\n",
- new_conn->controller, global_myname(), ipc_domain, ipc_username));
-
- result = NT_STATUS_OK;
-
- if (!cli_session_setup(new_conn->cli, ipc_username,
- ipc_password, strlen(ipc_password)+1,
- ipc_password, strlen(ipc_password)+1,
- ipc_domain)) {
- result = cli_nt_error(new_conn->cli);
- DEBUG(4,("failed authenticated session setup with %s\n", nt_errstr(result)));
- if (NT_STATUS_IS_OK(result))
- result = NT_STATUS_UNSUCCESSFUL;
- }
- }
-
- /* anonymous is all that is left if we get to here */
-
- if (!NT_STATUS_IS_OK(result)) {
-
- DEBUG(5, ("anonymous connection attempt to %s from %s\n",
- new_conn->controller, global_myname()));
-
- result = NT_STATUS_OK;
-
- if (!cli_session_setup(new_conn->cli, "", NULL, 0, NULL, 0, ""))
- {
- result = cli_nt_error(new_conn->cli);
- DEBUG(4,("failed anonymous session setup with %s\n", nt_errstr(result)));
- if (NT_STATUS_IS_OK(result))
- result = NT_STATUS_UNSUCCESSFUL;
- }
-
- }
+ if ((lp_security() == SEC_ADS)
+ && ((*cli)->protocol >= PROTOCOL_NT1 &&
+ (*cli)->capabilities & CAP_EXTENDED_SECURITY)) {
+
+ ADS_STATUS ads_status;
+ (*cli)->use_kerberos = True;
+ DEBUG(5, ("connecting to %s from %s with kerberos principal "
+ "[%s]\n", controller, global_myname(),
+ machine_krb5_principal));
+
+ ads_status = cli_session_setup_spnego(*cli,
+ machine_krb5_principal,
+ machine_password,
+ lp_workgroup());
+
+ if (!ADS_ERR_OK(ads_status))
+ DEBUG(4,("failed kerberos session setup with %s\n",
+ ads_errstr(ads_status)));
+
+ result = ads_ntstatus(ads_status);
+ }
- if (NT_STATUS_IS_OK(result) && !cli_send_tconX(new_conn->cli, "IPC$", "IPC",
- "", 0)) {
- result = cli_nt_error(new_conn->cli);
- DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
- cli_shutdown(new_conn->cli);
- if (NT_STATUS_IS_OK(result)) {
- result = NT_STATUS_UNSUCCESSFUL;
- }
- }
- }
+ if (NT_STATUS_IS_OK(result))
+ goto session_setup_done;
- if (NT_STATUS_IS_OK(result)) {
- struct ntuser_creds creds;
- init_creds(&creds, ipc_username, ipc_domain, ipc_password);
- cli_init_creds(new_conn->cli, &creds);
+ /* Fall back to non-kerberos session setup */
+
+ (*cli)->use_kerberos = False;
+
+ if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
+ (strlen(ipc_username) > 0)) {
+
+ /* Only try authenticated if we have a username */
+
+ DEBUG(5, ("connecting to %s from %s with username "
+ "[%s]\\[%s]\n", controller, global_myname(),
+ ipc_domain, ipc_username));
+
+ if (cli_session_setup(*cli, ipc_username,
+ ipc_password, strlen(ipc_password)+1,
+ ipc_password, strlen(ipc_password)+1,
+ ipc_domain)) {
+ DEBUG(5, ("authenticated session setup failed\n"));
+ goto session_setup_done;
}
+ }
+
+ /* Fall back to anonymous connection, this might fail later */
+
+ if (cli_session_setup(*cli, "", NULL, 0, NULL, 0, "")) {
+ DEBUG(5, ("Connected anonymously\n"));
+ goto session_setup_done;
+ }
- if (got_mutex)
- secrets_named_mutex_release(new_conn->controller);
+ result = cli_nt_error(*cli);
+
+ if (NT_STATUS_IS_OK(result))
+ result = NT_STATUS_UNSUCCESSFUL;
+
+ /* We can't session setup */
+
+ goto done;
+
+ session_setup_done:
+
+ if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
+
+ result = cli_nt_error(*cli);
+
+ DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
if (NT_STATUS_IS_OK(result))
- break;
+ result = NT_STATUS_UNSUCCESSFUL;
+
+ cli_shutdown(*cli);
+ goto done;
}
- /* try and use schannel if possible, but continue anyway if it
- failed. This allows existing setups to continue working,
- while solving the win2003 '100 user' limit for systems that
- are joined properly.
-
- Only do this for our own domain or perhaps a trusted domain
- if we are on a Samba DC */
+ init_creds(&creds, ipc_username, ipc_domain, ipc_password);
+ cli_init_creds(*cli, &creds);
- if (NT_STATUS_IS_OK(result) && (domain->primary || IS_DC) ) {
- NTSTATUS status = setup_schannel( new_conn->cli, domain->name );
+ secrets_named_mutex_release(controller);
+ got_mutex = False;
+ *retry = False;
+
+ if (domain->primary || IS_DC) {
+ NTSTATUS status = setup_schannel( *cli, domain->name );
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3,("schannel refused - continuing without schannel (%s)\n",
- nt_errstr(status)));
+ DEBUG(3,("schannel refused - continuing without "
+ "schannel (%s)\n", nt_errstr(status)));
}
}
+ /* set the domain if empty; needed for schannel connections */
+ if ( !*(*cli)->domain )
+ fstrcpy( (*cli)->domain, domain->name );
+
+ if ( !cli_nt_session_open (*cli, pipe_index) ) {
+
+ result = NT_STATUS_PIPE_NOT_AVAILABLE;
+
+ /* This might be a NT4 DC */
+ if ( is_win2k_pipe(pipe_index) )
+ add_failed_connection = False;
+
+ cli_shutdown(*cli);
+ goto done;
+ }
+
+ result = NT_STATUS_OK;
+ add_failed_connection = False;
+
+ done:
+ if (got_mutex)
+ secrets_named_mutex_release(controller);
+
+ SAFE_FREE(machine_password);
+ SAFE_FREE(machine_krb5_principal);
SAFE_FREE(ipc_username);
SAFE_FREE(ipc_domain);
SAFE_FREE(ipc_password);
- SAFE_FREE(machine_password);
- SAFE_FREE(machine_krb5_principal);
- if (!NT_STATUS_IS_OK(result)) {
- add_failed_connection_entry(domain->name, new_conn->controller, result);
- return result;
+ if (add_failed_connection)
+ add_failed_connection_entry(domain->name, controller, result);
+
+ return result;
+}
+
+struct dc_name_ip {
+ fstring name;
+ struct in_addr ip;
+};
+
+static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
+ const char *dcname, struct in_addr ip,
+ struct dc_name_ip **dcs, int *num)
+{
+ if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname)))
+ return False;
+
+ *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
+
+ if (*dcs == NULL)
+ return False;
+
+ fstrcpy((*dcs)[*num].name, dcname);
+ (*dcs)[*num].ip = ip;
+ *num += 1;
+ return True;
+}
+
+static BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
+ const char *str, char ***array, int *num)
+{
+ char *dup_str = talloc_strdup(mem_ctx, str);
+
+ *array = TALLOC_REALLOC_ARRAY(mem_ctx, *array, char *, (*num)+1);
+
+ if ((*array == NULL) || (dup_str == NULL))
+ return False;
+
+ (*array)[*num] = dup_str;
+ *num += 1;
+ return True;
+}
+
+static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
+ struct in_addr ip, uint16 port,
+ struct sockaddr_in **addrs, int *num)
+{
+ *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
+
+ if (*addrs == NULL)
+ return False;
+
+ (*addrs)[*num].sin_family = PF_INET;
+ putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
+ (*addrs)[*num].sin_port = htons(port);
+
+ *num += 1;
+ return True;
+}
+
+static BOOL get_dcs_1c(TALLOC_CTX *mem_ctx,
+ const struct winbindd_domain *domain,
+ struct dc_name_ip **dcs, int *num_dcs)
+{
+ struct ip_service *iplist = NULL;
+ int i, num = 0;
+
+ if (!internal_resolve_name(domain->name, 0x1c, &iplist, &num,
+ lp_name_resolve_order()))
+ return False;
+
+ /* Now try to find the server names of at least one IP address, hosts
+ * not replying are cached as such */
+
+ for (i=0; i<num; i++) {
+
+ fstring dcname;
+
+ if (!name_status_find(domain->name, 0x1c, 0x20, iplist[i].ip,
+ dcname))
+ continue;
+
+ if (add_one_dc_unique(mem_ctx, domain->name, dcname,
+ iplist[i].ip, dcs, num_dcs)) {
+ /* One DC responded, so we assume that he will also
+ work on 139/445 */
+ break;
+ }
}
-
- /* set the domain if empty; needed for schannel connections */
- if ( !*new_conn->cli->domain )
- fstrcpy( new_conn->cli->domain, domain->name );
-
-
- if ( !cli_nt_session_open (new_conn->cli, pipe_index) ) {
- result = NT_STATUS_PIPE_NOT_AVAILABLE;
- /*
- * only cache a failure if we are not trying to open the
- * **win2k** specific lsarpc UUID. This could be an NT PDC
- * and therefore a failure is normal. This should probably
- * be abstracted to a check for 2k specific pipes and wondering
- * if the PDC is an NT4 box. but since there is only one 2k
- * specific UUID right now, i'm not going to bother. --jerry
- */
- if ( !is_win2k_pipe(pipe_index) )
- add_failed_connection_entry(domain->name, new_conn->controller, result);
- cli_shutdown(new_conn->cli);
- return result;
+
+ return True;
+}
+
+static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
+ struct dc_name_ip **dcs, int *num_dcs)
+{
+ fstring dcname;
+ struct in_addr ip;
+ BOOL is_our_domain;
+
+ const char *p;
+
+ is_our_domain = strequal(domain->name, lp_workgroup());
+
+ if (!is_our_domain && get_dc_name_via_netlogon(domain, dcname, &ip) &&
+ add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs))
+ return True;
+
+ if (!is_our_domain) {
+ /* NETLOGON to our own domain could not give us a DC name
+ * (which is an error), fall back to looking up domain#1c */
+ return get_dcs_1c(mem_ctx, domain, dcs, num_dcs);
}
- return NT_STATUS_OK;
+ if (must_use_pdc(domain->name) && get_pdc_ip(domain->name, &ip)) {
+
+ if (!name_status_find(domain->name, 0x1b, 0x20, ip, dcname))
+ return False;
+
+ if (add_one_dc_unique(mem_ctx, domain->name,
+ dcname, ip, dcs, num_dcs))
+ return True;
+ }
+
+ p = lp_passwordserver();
+
+ if (*p == 0)
+ return get_dcs_1c(mem_ctx, domain, dcs, num_dcs);
+
+ while (next_token(&p, dcname, LIST_SEP, sizeof(dcname))) {
+
+ if (strequal(dcname, "*")) {
+ get_dcs_1c(mem_ctx, domain, dcs, num_dcs);
+ continue;
+ }
+
+ if (!resolve_name(dcname, &ip, 0x20))
+ continue;
+
+ add_one_dc_unique(mem_ctx, domain->name, dcname, ip,
+ dcs, num_dcs);
+ }
+
+ return True;
+}
+
+static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
+ const struct winbindd_domain *domain,
+ fstring dcname, struct sockaddr_in *addr, int *fd)
+{
+ struct dc_name_ip *dcs = NULL;
+ int num_dcs = 0;
+
+ char **dcnames = NULL;
+ int num_dcnames = 0;
+
+ struct sockaddr_in *addrs = NULL;
+ int num_addrs = 0;
+
+ int i, fd_index;
+
+ if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
+ return False;
+
+ for (i=0; i<num_dcs; i++) {
+
+ add_string_to_array(mem_ctx, dcs[i].name,
+ &dcnames, &num_dcnames);
+ add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
+ &addrs, &num_addrs);
+
+ add_string_to_array(mem_ctx, dcs[i].name,
+ &dcnames, &num_dcnames);
+ add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
+ &addrs, &num_addrs);
+ }
+
+ if ((num_dcnames == 0) || (num_dcnames != num_addrs))
+ return False;
+
+ if (!open_any_socket_out(addrs, num_addrs, 10000, &fd_index, fd)) {
+ for (i=0; i<num_dcs; i++) {
+ add_failed_connection_entry(domain->name,
+ dcs[i].name,
+ NT_STATUS_UNSUCCESSFUL);
+ }
+ return False;
+ }
+
+ fstrcpy(dcname, dcnames[fd_index]);
+ *addr = addrs[fd_index];
+
+ return True;
+}
+
+static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
+ const int pipe_index,
+ struct winbindd_cm_conn *new_conn)
+{
+ TALLOC_CTX *mem_ctx;
+ NTSTATUS result;
+
+ int retries;
+
+ if ((mem_ctx = talloc_init("cm_open_connection")) == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ for (retries = 0; retries < 3; retries++) {
+
+ int fd = -1;
+ BOOL retry;
+
+ result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
+
+ if ((strlen(domain->dcname) > 0) &&
+ NT_STATUS_IS_OK(check_negative_conn_cache(domain->name,
+ domain->dcname))) {
+ int dummy;
+ if (!open_any_socket_out(&domain->dcaddr, 1, 10000,
+ &dummy, &fd)) {
+ fd = -1;
+ }
+ }
+
+ if ((fd == -1) &&
+ !find_new_dc(mem_ctx, domain, domain->dcname,
+ &domain->dcaddr, &fd))
+ break;
+
+ new_conn->cli = NULL;
+
+ result = cm_prepare_connection(domain, fd, pipe_index,
+ domain->dcname,
+ &new_conn->cli, &retry);
+
+ if (NT_STATUS_IS_OK(result)) {
+ fstrcpy(new_conn->domain, domain->name);
+ /* Initialise SMB connection */
+ fstrcpy(new_conn->pipe_name,
+ get_pipe_name_from_index(pipe_index));
+ break;
+ }
+
+ if (!retry)
+ break;
+ }
+
+ talloc_destroy(mem_ctx);
+ return result;
}
/************************************************************************
/* Add nested group memberships */
- if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases))
+ if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases))
return;
for (j=0; j<num_aliases; j++) {
if (!winbindd_lookup_sid_by_name(domain, domain->name, name_user, &user_sid,
&name_type)) {
- DEBUG(1, ("user '%s' does not exist\n", name_user));
+ DEBUG(4, ("user '%s' does not exist\n", name_user));
goto done;
}
add_gids_from_group_sid(&info3->other_sids[i].sid,
&gid_list, &num_gids);
-
- if (gid_list == NULL)
- goto done;
}
for (i = 0; i < info3->num_groups2; i++) {
add_gids_from_group_sid(&group_sid, &gid_list,
&num_gids);
-
- if (gid_list == NULL)
- goto done;
}
SAFE_FREE(info3);
for (i = 0; i < num_groups; i++) {
add_gids_from_group_sid(user_grpsids[i],
&gid_list, &num_gids);
-
- if (gid_list == NULL)
- goto done;
}
}
+ /* We want at least one group... */
+ if (gid_list == NULL)
+ goto done;
+
remove_duplicate_gids( &num_gids, gid_list );
/* Send data back to client */
return result;
}
-static void add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+static void add_sid_to_parray_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
DOM_SID ***sids, int *num_sids)
{
int i;
DOM_SID *aliases = NULL;
int i, num_aliases = 0;
- if (!pdb_enum_alias_memberships(sid, &aliases, &num_aliases))
+ if (!pdb_enum_alias_memberships(sid, 1, &aliases, &num_aliases))
return;
if (num_aliases == 0)
return;
for (i=0; i<num_aliases; i++)
- add_sid_to_array_unique(mem_ctx, &aliases[i], user_grpsids,
- num_groups);
+ add_sid_to_parray_unique(mem_ctx, &aliases[i], user_grpsids,
+ num_groups);
SAFE_FREE(aliases);
Copyright (C) Tim Potter 2000
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
+ You are free to use this interface definition in any way you see
+ fit, including without restriction, using this header in your own
+ products. You do not need to give any attribution.
*/
#ifndef SAFE_FREE
memcpy(state->response.data.auth.user_session_key, info3.user_sess_key, sizeof(state->response.data.auth.user_session_key) /* 16 */);
}
if (state->request.flags & WBFLAG_PAM_LMKEY) {
- memcpy(state->response.data.auth.first_8_lm_hash, info3.padding, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */);
+ memcpy(state->response.data.auth.first_8_lm_hash, info3.lm_sess_key, sizeof(state->response.data.auth.first_8_lm_hash) /* 8 */);
}
}
TALLOC_CTX *mem_ctx;
CLI_POLICY_HND *hnd;
SAM_UNK_CTR ctr;
- uint16 switch_value = 2;
NTSTATUS result;
POLICY_HND dom_pol;
BOOL got_dom_pol = False;
+ BOOL got_seq_num = False;
uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
int retry;
/* Query domain info */
result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
- switch_value, &ctr);
+ 8, &ctr);
if (NT_STATUS_IS_OK(result)) {
- *seq = ctr.info.inf2.seq_num;
+ *seq = ctr.info.inf8.seq_num.low;
+ got_seq_num = True;
+ goto seq_num;
+ }
+
+ /* retry with info-level 2 in case the dc does not support info-level 8
+ * (like all older samba2 and samba3 dc's - Guenther */
+
+ result = cli_samr_query_dom_info(hnd->cli, mem_ctx, &dom_pol,
+ 2, &ctr);
+
+ if (NT_STATUS_IS_OK(result)) {
+ *seq = ctr.info.inf2.seq_num.low;
+ got_seq_num = True;
+ }
+
+ seq_num:
+ if (got_seq_num) {
DEBUG(10,("domain_sequence_number: for domain %s is %u\n", domain->name, (unsigned)*seq));
} else {
DEBUG(10,("domain_sequence_number: failed to get sequence number (%u) for domain %s\n",
*/
void fill_domain_username(fstring name, const char *domain, const char *user)
{
- strlower_m( name );
+ strlower_m( user );
if (assume_domain(domain)) {
strlcpy(name, user, sizeof(fstring));
{
int fd;
struct ip_service *ret = NULL;
- struct in_addr *return_ip;
+ struct in_addr *return_ip = NULL;
int j, i, flags = 0;
*count = 0;
j--) {
struct in_addr *bcast = iface_n_bcast(j);
return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
- if (return_ip) break;
+ if (return_ip) {
+ break;
+ }
}
close(fd);
char *szSocketOptions;
char *szRealm;
char *szAfsUsernameMap;
+ int iAfsTokenLifetime;
char *szUsernameMap;
char *szLogonScript;
char *szLogonPath;
BOOL bMap_archive;
BOOL bStoreDosAttributes;
BOOL bLocking;
- BOOL bStrictLocking;
+ int iStrictLocking;
BOOL bPosixLocking;
BOOL bShareModes;
BOOL bOpLocks;
True, /* bMap_archive */
False, /* bStoreDosAttributes */
True, /* bLocking */
- True, /* bStrictLocking */
+ True, /* iStrictLocking */
True, /* bPosixLocking */
True, /* bShareModes */
True, /* bOpLocks */
{"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
{"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
{"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED},
- {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
- {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED},
+ {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_DEPRECATED},
+ {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_DEPRECATED},
{"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
{"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
{"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
{"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
{"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
- {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
+ {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
{N_("Ldap Options"), P_SEP, P_SEPARATOR},
{"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
{"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
{"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
+ {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
{"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
{"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
{"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
string_set(&pService->szLpresumecommand, "");
string_set(&pService->szQueuepausecommand, "");
string_set(&pService->szQueueresumecommand, "");
-
- string_set(&Globals.szPrintcapname, "cups");
#else
string_set(&pService->szLpqcommand, "/usr/bin/lpstat -o '%p'");
string_set(&pService->szLprmcommand, "/usr/bin/cancel '%p-%j'");
string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
string_set(&pService->szQueuepausecommand, "/usr/bin/disable '%p'");
string_set(&pService->szQueueresumecommand, "/usr/bin/enable '%p'");
- string_set(&Globals.szPrintcapname, "lpstat");
#endif /* HAVE_CUPS */
break;
string_set(&Globals.szWorkgroup, lp_workgroup());
string_set(&Globals.szPasswdProgram, "");
- string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
string_set(&Globals.szPidDir, dyn_PIDDIR);
string_set(&Globals.szLockDir, dyn_LOCKDIR);
string_set(&Globals.szSocketAddress, "0.0.0.0");
/* Discovered by 2 days of pain by Don McCall @ HP :-). */
Globals.max_xmit = 0x4104;
Globals.max_mux = 50; /* This is *needed* for profile support. */
- Globals.lpqcachetime = 10;
+ Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
Globals.bDisableSpoolss = False;
Globals.iMaxSmbdProcesses = 0;/* no limit specified */
Globals.pwordlevel = 0;
Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
+ /* This is what we tell the afs client. in reality we set the token
+ * to never expire, though, when this runs out the afs client will
+ * forget the token. Set to 0 to get NEVERDATE.*/
+ Globals.iAfsTokenLifetime = 604800;
+
/* these parameters are set to defaults that are more appropriate
for the increasing samba install base:
FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
-FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
+FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
FN_LOCAL_BOOL(lp_locking, bLocking)
-FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
+FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking)
FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
FN_LOCAL_BOOL(lp_share_modes, bShareModes)
FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
time_t mod_time;
pstrcpy(n2, f->name);
- standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
+ standard_sub_basic( username, n2, sizeof(n2) );
DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
f->name, n2, ctime(&f->modtime)));
return maxjobs;
}
+const char *lp_printcapname(void)
+{
+ if ((Globals.szPrintcapname != NULL) &&
+ (Globals.szPrintcapname[0] != '\0'))
+ return Globals.szPrintcapname;
+
+ if (sDefault.iPrinting == PRINT_CUPS) {
+#ifdef HAVE_CUPS
+ return "cups";
+#else
+ return "lpstat";
+#endif
+ }
+
+ if (sDefault.iPrinting == PRINT_BSD)
+ return "/etc/printcap";
+
+ return PRINTCAP_NAME;
+}
+
/*******************************************************************
Ensure we don't use sendfile if server smb signing is active.
********************************************************************/
BOOL lp_use_sendfile(int snum)
{
- extern int Protocol;
+ extern enum protocol_types Protocol;
/* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
if (Protocol < PROTOCOL_NT1) {
return False;
/* Check if this is our own sid. This should perhaps be done by
winbind? For the moment handle it here. */
+ if (sid->num_auths == 4 && sid_equal(get_global_sam_sid(), sid)) {
+ DOM_SID tmp_sid;
+ sid_copy(&tmp_sid, sid);
+ return map_domain_sid_to_name(&tmp_sid, dom_name) &&
+ local_lookup_sid(sid, name, name_type);
+ }
+
if (sid->num_auths == 5) {
DOM_SID tmp_sid;
uint32 rid;
or we are dead in the water */
if ( !winbind_sid_to_gid(pgid, psid) ) {
- DEBUG(10,("sid_to_uid: winbind failed to allocate a new gid for sid %s\n",
+ DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid for sid %s\n",
sid_to_string(sid_str, psid) ));
return NT_STATUS_UNSUCCESSFUL;
}
GROUP_MAP map;
BOOL ret;
+ if (sid_equal(get_global_sam_sid(), sid)) {
+ *psid_name_use = SID_NAME_DOMAIN;
+ fstrcpy(name, "");
+ DEBUG(5,("local_lookup_sid: SID is our own domain-sid: %s.\n",
+ sid_string_static(sid)));
+ return True;
+ }
+
if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n",
sid_string_static(&map.sid)));
return (buflen);
}
+BOOL pdb_copy_sam_account(const SAM_ACCOUNT *src, SAM_ACCOUNT **dst)
+{
+ BOOL result;
+ uint8 *buf;
+ int len;
+
+ if ((*dst == NULL) && (!NT_STATUS_IS_OK(pdb_init_sam(dst))))
+ return False;
+
+ len = init_buffer_from_sam_v2(&buf, src, False);
+
+ if (len == -1)
+ return False;
+
+ result = init_sam_from_buffer_v2(*dst, buf, len);
+ (*dst)->methods = src->methods;
+
+ free(buf);
+
+ return result;
+}
+
/**********************************************************************
**********************************************************************/
num_entries, unix_only);
}
+static NTSTATUS context_enum_group_memberships(struct pdb_context *context,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups)
+{
+ NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
+
+ if ((!context) || (!context->pdb_methods)) {
+ DEBUG(0, ("invalid pdb_context specified!\n"));
+ return ret;
+ }
+
+ return context->pdb_methods->
+ enum_group_memberships(context->pdb_methods, username,
+ primary_gid, sids, gids, num_groups);
+}
+
static NTSTATUS context_find_alias(struct pdb_context *context,
const char *name, DOM_SID *sid)
{
}
static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
- const DOM_SID *sid,
+ const DOM_SID *members,
+ int num_members,
DOM_SID **aliases, int *num)
{
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
}
return context->pdb_methods->
- enum_alias_memberships(context->pdb_methods, sid, aliases,
- num);
+ enum_alias_memberships(context->pdb_methods, members,
+ num_members, aliases, num);
}
/******************************************************************
(*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry;
(*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry;
(*context)->pdb_enum_group_mapping = context_enum_group_mapping;
+ (*context)->pdb_enum_group_memberships = context_enum_group_memberships;
(*context)->pdb_find_alias = context_find_alias;
(*context)->pdb_create_alias = context_create_alias;
return NT_STATUS_IS_OK(pdb_context->pdb_getsampwent(pdb_context, user));
}
+static SAM_ACCOUNT *sam_account_cache = NULL;
+
BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
return False;
}
- return NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username));
+ if (!NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context,
+ sam_acct, username)))
+ return False;
+
+ if (sam_account_cache != NULL) {
+ pdb_free_sam(&sam_account_cache);
+ sam_account_cache = NULL;
+ }
+
+ pdb_copy_sam_account(sam_acct, &sam_account_cache);
+ return True;
}
BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
return False;
}
+ if ((sam_account_cache != NULL) &&
+ (sid_equal(sid, pdb_get_user_sid(sam_account_cache))))
+ return pdb_copy_sam_account(sam_account_cache, &sam_acct);
+
return NT_STATUS_IS_OK(pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid));
}
return False;
}
+ if (sam_account_cache != NULL) {
+ pdb_free_sam(&sam_account_cache);
+ sam_account_cache = NULL;
+ }
+
return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct));
}
return False;
}
+ if (sam_account_cache != NULL) {
+ pdb_free_sam(&sam_account_cache);
+ sam_account_cache = NULL;
+ }
+
return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct));
}
rmap, num_entries, unix_only));
}
+NTSTATUS pdb_enum_group_memberships(const char *username, gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups)
+{
+ struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+ if (!pdb_context) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return pdb_context->pdb_enum_group_memberships(pdb_context, username,
+ primary_gid, sids, gids,
+ num_groups);
+}
+
BOOL pdb_find_alias(const char *name, DOM_SID *sid)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
members, num_members));
}
-BOOL pdb_enum_alias_memberships(const DOM_SID *sid,
+BOOL pdb_enum_alias_memberships(const DOM_SID *members, int num_members,
DOM_SID **aliases, int *num)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
}
return NT_STATUS_IS_OK(pdb_context->
- pdb_enum_alias_memberships(pdb_context, sid,
+ pdb_enum_alias_memberships(pdb_context, members,
+ num_members,
aliases, num));
}
(*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
(*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
(*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
+ (*methods)->enum_group_memberships = pdb_default_enum_group_memberships;
(*methods)->find_alias = pdb_default_find_alias;
(*methods)->create_alias = pdb_default_create_alias;
(*methods)->delete_alias = pdb_default_delete_alias;
return ldapsam_getgroup(methods, filter, map);
}
+static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
+ const char *username,
+ gid_t primary_gid,
+ DOM_SID **sids, gid_t **gids,
+ int *num_groups)
+{
+ struct ldapsam_privates *ldap_state =
+ (struct ldapsam_privates *)methods->private_data;
+ struct smbldap_state *conn = ldap_state->smbldap_state;
+ pstring filter;
+ char *attrs[] = { "gidNumber", "sambaSID", NULL };
+ char *escape_name;
+ int rc;
+ LDAPMessage *msg = NULL;
+ LDAPMessage *entry;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ int num_sids, num_gids;
+ extern DOM_SID global_sid_NULL;
+
+ if (!lp_parm_bool(-1, "ldapsam", "trusted", False))
+ return pdb_default_enum_group_memberships(methods, username,
+ primary_gid, sids,
+ gids, num_groups);
+
+ *sids = NULL;
+ num_sids = 0;
+
+ escape_name = escape_ldap_string_alloc(username);
+
+ if (escape_name == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ pstr_sprintf(filter, "(&(objectClass=posixGroup)"
+ "(|(memberUid=%s)(gidNumber=%d)))",
+ username, primary_gid);
+
+ rc = smbldap_search(conn, lp_ldap_group_suffix(),
+ LDAP_SCOPE_SUBTREE, filter, attrs, 0, &msg);
+
+ if (rc != LDAP_SUCCESS)
+ goto done;
+
+ num_gids = 0;
+ *gids = NULL;
+
+ num_sids = 0;
+ *sids = NULL;
+
+ /* We need to add the primary group as the first gid/sid */
+
+ add_gid_to_array_unique(primary_gid, gids, &num_gids);
+
+ /* This sid will be replaced later */
+
+ add_sid_to_array_unique(&global_sid_NULL, sids, &num_sids);
+
+ for (entry = ldap_first_entry(conn->ldap_struct, msg);
+ entry != NULL;
+ entry = ldap_next_entry(conn->ldap_struct, entry))
+ {
+ fstring str;
+ DOM_SID sid;
+ gid_t gid;
+ char *end;
+
+ if (!smbldap_get_single_attribute(conn->ldap_struct,
+ entry, "sambaSID",
+ str, sizeof(str)-1))
+ goto done;
+
+ if (!string_to_sid(&sid, str))
+ goto done;
+
+ if (!smbldap_get_single_attribute(conn->ldap_struct,
+ entry, "gidNumber",
+ str, sizeof(str)-1))
+ goto done;
+
+ gid = strtoul(str, &end, 10);
+
+ if (PTR_DIFF(end, str) != strlen(str))
+ goto done;
+
+ if (gid == primary_gid) {
+ sid_copy(&(*sids)[0], &sid);
+ } else {
+ add_gid_to_array_unique(gid, gids, &num_gids);
+ add_sid_to_array_unique(&sid, sids, &num_sids);
+ }
+ }
+
+ if (sid_compare(&global_sid_NULL, &(*sids)[0]) == 0) {
+ DEBUG(3, ("primary group not found\n"));
+ goto done;
+ }
+
+ *num_groups = num_sids;
+
+ result = NT_STATUS_OK;
+
+ done:
+
+ SAFE_FREE(escape_name);
+ if (msg != NULL)
+ ldap_msgfree(msg);
+
+ return result;
+}
+
/**********************************************************************
*********************************************************************/
}
static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods,
- const DOM_SID *sid,
- DOM_SID **aliases, int *num)
+ const DOM_SID *members,
+ int num_members,
+ DOM_SID **aliases, int *num_aliases)
{
struct ldapsam_privates *ldap_state =
(struct ldapsam_privates *)methods->private_data;
+ LDAP *ldap_struct;
- fstring sid_string;
- const char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
+ char *attrs[] = { LDAP_ATTRIBUTE_SID, NULL };
LDAPMessage *result = NULL;
LDAPMessage *entry = NULL;
- int count;
+ int i;
int rc;
- pstring filter;
+ char *filter;
+ TALLOC_CTX *mem_ctx;
- sid_to_string(sid_string, sid);
- pstr_sprintf(filter, "(&(|(objectclass=%s)(objectclass=%s))(%s=%s))",
- LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY,
- get_attr_key2string(groupmap_attr_list,
- LDAP_ATTR_SID_LIST), sid_string);
+ mem_ctx = talloc_init("ldapsam_alias_memberships");
+
+ if (mem_ctx == NULL)
+ return NT_STATUS_NO_MEMORY;
+
+ /* This query could be further optimized by adding a
+ (&(sambaSID=<domain-sid>*)) so that only those aliases that are
+ asked for in the getuseraliases are returned. */
+
+ filter = talloc_asprintf(mem_ctx,
+ "(&(|(objectclass=%s)(objectclass=%s))(|",
+ LDAP_OBJ_GROUPMAP, LDAP_OBJ_IDMAP_ENTRY);
+
+ for (i=0; i<num_members; i++)
+ filter = talloc_asprintf(mem_ctx, "%s(sambaSIDList=%s)",
+ filter,
+ sid_string_static(&members[i]));
+
+ filter = talloc_asprintf(mem_ctx, "%s))", filter);
rc = smbldap_search(ldap_state->smbldap_state, lp_ldap_group_suffix(),
LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
+ talloc_destroy(mem_ctx);
+
if (rc != LDAP_SUCCESS)
return NT_STATUS_UNSUCCESSFUL;
*aliases = NULL;
- *num = 0;
-
- count = ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
- result);
-
- if (count < 1) {
- ldap_msgfree(result);
- return NT_STATUS_OK;
- }
+ *num_aliases = 0;
+ ldap_struct = ldap_state->smbldap_state->ldap_struct;
- for (entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
- result);
+ for (entry = ldap_first_entry(ldap_struct, result);
entry != NULL;
- entry = ldap_next_entry(ldap_state->smbldap_state->ldap_struct,
- entry))
+ entry = ldap_next_entry(ldap_struct, entry))
{
- DOM_SID alias;
- char **vals;
- vals = ldap_get_values(ldap_state->smbldap_state->ldap_struct,
- entry, LDAP_ATTRIBUTE_SID);
+ fstring sid_str;
+ DOM_SID sid;
- if (vals == NULL)
+ if (!smbldap_get_single_attribute(ldap_struct, entry,
+ LDAP_ATTRIBUTE_SID,
+ sid_str,
+ sizeof(sid_str)-1))
continue;
- if (vals[0] == NULL) {
- ldap_value_free(vals);
+ if (!string_to_sid(&sid, sid_str))
continue;
- }
-
- if (!string_to_sid(&alias, vals[0])) {
- ldap_value_free(vals);
- continue;
- }
- add_sid_to_array(&alias, aliases, num);
- ldap_value_free(vals);
+ add_sid_to_array_unique(&sid, aliases, num_aliases);
}
ldap_msgfree(result);
(*pdb_method)->update_group_mapping_entry = ldapsam_update_group_mapping_entry;
(*pdb_method)->delete_group_mapping_entry = ldapsam_delete_group_mapping_entry;
(*pdb_method)->enum_group_mapping = ldapsam_enum_group_mapping;
+ (*pdb_method)->enum_group_memberships = ldapsam_enum_group_memberships;
/* TODO: Setup private data and free */
pdb_set_plaintext_passwd(u, row[22]);
pdb_set_acct_ctrl(u, xatol(row[23]), PDB_SET);
- pdb_set_logon_divs(u, xatol(row[25]), PDB_SET);
- pdb_set_hours_len(u, xatol(row[26]), PDB_SET);
- pdb_set_bad_password_count(u, xatol(row[27]), PDB_SET);
- pdb_set_logon_count(u, xatol(row[28]), PDB_SET);
- pdb_set_unknown_6(u, xatol(row[29]), PDB_SET);
+ pdb_set_logon_divs(u, xatol(row[24]), PDB_SET);
+ pdb_set_hours_len(u, xatol(row[25]), PDB_SET);
+ pdb_set_bad_password_count(u, xatol(row[26]), PDB_SET);
+ pdb_set_logon_count(u, xatol(row[27]), PDB_SET);
+ pdb_set_unknown_6(u, xatol(row[28]), PDB_SET);
return NT_STATUS_OK;
}
pdb_set_munged_dial ( u, PQgetvalue( r, row, 17 ), PDB_SET ) ;
pdb_set_acct_ctrl ( u, PQgetlong ( r, row, 23 ), PDB_SET ) ;
- pdb_set_logon_divs ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ;
- pdb_set_hours_len ( u, PQgetlong ( r, row, 26 ), PDB_SET ) ;
+ pdb_set_logon_divs ( u, PQgetlong ( r, row, 24 ), PDB_SET ) ;
+ pdb_set_hours_len ( u, PQgetlong ( r, row, 25 ), PDB_SET ) ;
+ pdb_set_bad_password_count ( u, PQgetlong (r, row, 26 ), PDB_SET ) ;
pdb_set_logon_count ( u, PQgetlong ( r, row, 27 ), PDB_SET ) ;
pdb_set_unknown_6 ( u, PQgetlong ( r, row, 28 ), PDB_SET ) ;
field_string = config_value_read(data, "username column",
CONFIG_USERNAME_DEFAULT);
break;
+ default:
+ field_string = "unknown";
+ break;
}
asprintf(&query,
*/
-#define XML_URL "http://samba.org/~jelmer/sambapdb.dtd"
+#define XML_URL "http://samba.org/samba/DTD/passdb"
#include "includes.h"
BOOL secrets_init(void)
{
pstring fname;
- char dummy;
+ unsigned char dummy;
if (tdb)
return True;
return;
}
+
+
+void add_sid_to_array_unique(const DOM_SID *sid, DOM_SID **sids, int *num_sids)
+{
+ int i;
+
+ for (i=0; i<(*num_sids); i++) {
+ if (sid_compare(sid, &(*sids)[i]) == 0)
+ return;
+ }
+
+ add_sid_to_array(sid, sids, num_sids);
+}
#: ../web/swat.c:117
#, c-format
msgid "ERROR: Can't open %s"
-msgstr "ERRORE: Kann %s nicht öffnen"
+msgstr "ERROR: Kann %s nicht öffnen"
#: ../web/swat.c:200
msgid "Help"
#: ../web/swat.c:206 ../web/swat.c:220 ../web/swat.c:235 ../web/swat.c:243 ../web/swat.c:252 ../web/swat.c:261 ../web/swat.c:267 ../web/swat.c:273 ../web/swat.c:286
msgid "Set Default"
-msgstr "Setze Standardwerte"
+msgstr "Standardwert"
#: ../web/swat.c:408
#, c-format
msgid "failed to open %s for writing"
-msgstr ""
+msgstr "konnte %s nicht schreiben"
#: ../web/swat.c:431
#, c-format
#: ../web/swat.c:510
msgid "Wizard"
-msgstr ""
+msgstr "Assistent"
#: ../web/swat.c:513
msgid "Status"
#: ../web/swat.c:527 ../web/swat.c:530
msgid "Basic"
-msgstr "Basis Ansicht"
+msgstr "Einfache Ansicht"
#: ../web/swat.c:528 ../web/swat.c:531
msgid "Advanced"
#: ../web/swat.c:529
msgid "Change View To"
-msgstr "Ändere Passwort"
+msgstr "Ansicht anpassen"
#: ../web/swat.c:554
msgid "Current Config"
#: ../web/swat.c:608
msgid "Note: smb.conf file has been read and rewritten"
-msgstr ""
+msgstr "Hinweis: smb.conf wurde gelesen und überschrieben"
#. Here we go ...
#: ../web/swat.c:716
msgid "Samba Configuration Wizard"
-msgstr ""
+msgstr "Samba Konfigurations-Assistent"
#: ../web/swat.c:720
msgid "The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."
-msgstr ""
+msgstr "Der Button \"Passe smb.conf an\" wird alle Kommentare und Standardwerte aus der smb.conf löschen."
#: ../web/swat.c:721
msgid "The same will happen if you press the commit button."
-msgstr ""
+msgstr "Das gleiche passiert bei \"übernehmen\"."
#: ../web/swat.c:724
msgid "Rewrite smb.conf file"
-msgstr ""
+msgstr "Schreibe smb.conf neu"
#: ../web/swat.c:725
msgid "Commit"
-msgstr "Kommentar"
+msgstr "übernehmen"
#: ../web/swat.c:726
msgid "Edit Parameter Values"
-msgstr "Drucker Parameter"
+msgstr "Bearbeite Parameter"
#: ../web/swat.c:732
msgid "Server Type"
-msgstr ""
+msgstr "Server-Typ"
#: ../web/swat.c:733
msgid "Stand Alone"
-msgstr ""
+msgstr "Einzelserver"
#: ../web/swat.c:734
msgid "Domain Member"
-msgstr "Domänen master"
+msgstr "Domänen-Mitglied"
#: ../web/swat.c:735
msgid "Domain Controller"
-msgstr "Domänen master"
+msgstr "Domänen-Controller"
#: ../web/swat.c:738
msgid "Unusual Type in smb.conf - Please Select New Mode"
#: ../web/swat.c:740
msgid "Configure WINS As"
-msgstr ""
+msgstr "Konfiguriere WINS"
#: ../web/swat.c:741
msgid "Not Used"
-msgstr "nicht hinabsteigen"
+msgstr "nicht benutzt"
#: ../web/swat.c:742
msgid "Server for client use"
-msgstr ""
+msgstr "WINS-Server"
#: ../web/swat.c:743
msgid "Client of another WINS server"
-msgstr ""
+msgstr "WINS-Client an anderem Server"
#: ../web/swat.c:745
msgid "Remote WINS Server"
-msgstr ""
+msgstr "Zuständiger WINS-Server:"
#: ../web/swat.c:756
msgid "Error: WINS Server Mode and WINS Support both set in smb.conf"
-msgstr ""
+msgstr "Fehler: WINS-Server und WINS-Client zugleich in smb.conf gesetzt"
#: ../web/swat.c:757
msgid "Please Select desired WINS mode above."
-msgstr ""
+msgstr "Bitte wählen Sie den WINS-Modus."
#: ../web/swat.c:759
msgid "Expose Home Directories"
-msgstr ""
+msgstr "Home-Verzeichnisse freigeben"
#: ../web/swat.c:774
msgid "The above configuration options will set multiple parameters and will generally assist with rapid Samba deployment."
-msgstr ""
+msgstr "Diese Konfigurationsoptionen bearbeiten mehrere Parameter und dienen als Hilfe zur schnellen Samba-Einrichtung."
#: ../web/swat.c:787
msgid "Global Parameters"
-msgstr "Globale Variablen"
+msgstr "Globale Parameter"
#: ../web/swat.c:815 ../web/swat.c:916 ../web/swat.c:1265
msgid "Commit Changes"
-msgstr "Speichere Änderungen"
+msgstr "Änderungen speichern"
#: ../web/swat.c:819 ../web/swat.c:919 ../web/swat.c:1267
msgid "Reset Values"
-msgstr "Setze Werte zurück"
+msgstr "Werte zurücksetzen"
#: ../web/swat.c:844
msgid "Share Parameters"
#: ../web/swat.c:999
msgid " Must specify \"Old Password\" "
-msgstr " \"Altes Passwort\" muß angegeben werden "
+msgstr " \"Altes Passwort\" muss angegeben werden "
#: ../web/swat.c:1005
msgid " Must specify \"Remote Machine\" "
-msgstr " \"Remote Maschine\" muß angegeben werden "
+msgstr " \"Remote-Server\" muss angegeben werden "
#: ../web/swat.c:1012
msgid " Must specify \"New, and Re-typed Passwords\" "
-msgstr " \"Neues/Bestätige Passwort\" muß angegeben werden "
+msgstr " \"Neues/wiederholtes Passwort\" müssen angegeben werden "
#: ../web/swat.c:1018
msgid " Re-typed password didn't match new password "
-msgstr " Das bestätigte Passwort stimmt nicht mit dem neuen Passwort überein"
+msgstr " Das wiederholte Passwort stimmt nicht mit dem neuen Passwort überein"
#: ../web/swat.c:1048
#, c-format
#: ../web/swat.c:1051
#, c-format
msgid " The passwd for '%s' has NOT been changed."
-msgstr " Das Passwort für '%s' wurde nicht geändert."
+msgstr " Das Passwort für '%s' wurde NICHT geändert."
#: ../web/swat.c:1076
msgid "Server Password Management"
#: ../web/swat.c:1093 ../web/swat.c:1138
msgid "Re-type New Password"
-msgstr "Bestätige neues Passwort"
+msgstr "Wiederhole neues Passwort"
#: ../web/swat.c:1101 ../web/swat.c:1149
msgid "Change Password"
#: ../web/swat.c:1140
msgid "Remote Machine"
-msgstr "Remote Maschine"
+msgstr "Remote-Server"
#: ../web/swat.c:1179
msgid "Printer Parameters"
#: ../web/swat.c:1181
msgid "Important Note:"
-msgstr "Wichtige Hinweise:"
+msgstr "Wichtiger Hinweis:"
#: ../web/swat.c:1182
msgid "Printer names marked with [*] in the Choose Printer drop-down box "
-msgstr "Mit [*] gekennzeichnete Druckername in der Druckerauswahlliste"
+msgstr "Mit [*] gekennzeichnete Drucker in der Druckerauswahlliste"
#: ../web/swat.c:1183
msgid "are autoloaded printers from "
-msgstr "wurde automatisch geladen von :"
+msgstr "wurden automatisch geladen von :"
#: ../web/swat.c:1184
msgid "Printcap Name"
#: ../web/statuspage.c:309
msgid "Server Status"
-msgstr "Server Status"
+msgstr "Server-Status"
#: ../web/statuspage.c:314
msgid "Auto Refresh"
#: ../web/statuspage.c:319
msgid "Stop Refreshing"
-msgstr "Stop Aktualisierung"
+msgstr "Stoppe Aktualisierung"
#: ../web/statuspage.c:334
msgid "version:"
#: ../web/statuspage.c:341
msgid "Stop smbd"
-msgstr "Stopp smbd"
+msgstr "Stoppe smbd"
#: ../web/statuspage.c:343
msgid "Start smbd"
-msgstr "Start smbd"
+msgstr "Starte smbd"
#: ../web/statuspage.c:345
msgid "Restart smbd"
#: ../web/statuspage.c:354
msgid "Stop nmbd"
-msgstr "Stopp nmbd"
+msgstr "Stoppe nmbd"
#: ../web/statuspage.c:356
msgid "Start nmbd"
-msgstr "Start nmbd"
+msgstr "Starte nmbd"
#: ../web/statuspage.c:358
msgid "Restart nmbd"
#: ../web/statuspage.c:368
msgid "Stop winbindd"
-msgstr "Stopp winbindd"
+msgstr "Stoppe winbindd"
#: ../web/statuspage.c:370
msgid "Start winbindd"
-msgstr "Start winbindd"
+msgstr "Starte winbindd"
#: ../web/statuspage.c:372
msgid "Restart winbindd"
#. stop, restart all
#: ../web/statuspage.c:381
msgid "Stop All"
-msgstr ""
+msgstr "Alle Stoppen"
#: ../web/statuspage.c:382
msgid "Restart All"
-msgstr "Neustart Alle"
+msgstr "Alle neu starten"
#. start all
#: ../web/statuspage.c:386
msgid "Start All"
-msgstr "Start Alle"
+msgstr "Alle Starten"
#: ../web/statuspage.c:393
msgid "Active Connections"
#: ../web/statuspage.c:395
msgid "IP address"
-msgstr "IP Adresse"
+msgstr "IP-Adresse"
#: ../web/statuspage.c:395 ../web/statuspage.c:408 ../web/statuspage.c:416
msgid "Date"
#: ../web/statuspage.c:397
msgid "Kill"
-msgstr "Kill"
+msgstr "Killen"
#: ../web/statuspage.c:405
msgid "Active Shares"
#: ../web/statuspage.c:416
msgid "File"
-msgstr ""
+msgstr "Datei"
#: ../web/statuspage.c:425
msgid "Show Client in col 1"
unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
for (n=0; n<*count; n++) {
- if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
- DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
+ if ( strequal((*list)[n].name, form_name) ) {
update=True;
break;
}
(*list)[n].right=form->right;
(*list)[n].bottom=form->bottom;
+ DEBUG(6,("add_a_form: Successfully %s form [%s]\n",
+ update ? "updated" : "added", form_name));
+
return True;
}
printer->info_2->sharename);
/* publish it */
- ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
- if (LDAP_ALREADY_EXISTS == ads_rc.err.rc)
- ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
+ ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
+ if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT)
+ ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
+
+ if (!ADS_ERR_OK(ads_rc))
+ DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc)));
talloc_destroy(ctx);
{
ADS_STATUS ads_rc;
ADS_STRUCT *ads = NULL;
- void *res = NULL;
int snum;
int n_services = lp_numservices();
NT_PRINTER_INFO_LEVEL *printer = NULL;
- WERROR win_rc;
ads = ads_init(NULL, NULL, NULL);
if (!ads) {
if (!(lp_snum_ok(snum) && lp_print_ok(snum)))
continue;
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
- lp_servicename(snum))) ||
- !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
- goto next;
-
- DEBUG(5, ("checking directory for printer %s\n", printer->info_2->printername));
- ads_rc = ads_find_printer_on_server(ads, &res,
- printer->info_2->sharename, global_myname());
- if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
- DEBUG(5, ("printer %s is in directory\n", printer->info_2->printername));
- goto next;
- }
+ if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
+ lp_servicename(snum))) &&
+ (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
+ nt_printer_publish_ads(ads, printer);
- win_rc = nt_printer_publish_ads(ads, printer);
- if (!W_ERROR_IS_OK(win_rc))
- DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, dos_errstr(win_rc)));
-
- next:
free_a_printer(&printer, 2);
- ads_msgfree(ads, res);
- res = NULL;
}
ads_destroy(&ads);
ipp_attribute_t *attr; /* Current attribute */
cups_lang_t *language; /* Default language */
char *name, /* printer-name attribute */
- *make_model, /* printer-make-and-model attribute */
*info; /* printer-info attribute */
static const char *requested[] =/* Requested attributes */
{
"printer-name",
- "printer-make-and-model",
"printer-info"
};
*/
name = NULL;
- make_model = NULL;
info = NULL;
while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
attr->value_tag == IPP_TAG_NAME)
name = attr->values[0].string.text;
- if (strcmp(attr->name, "printer-make-and-model") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- make_model = attr->values[0].string.text;
-
if (strcmp(attr->name, "printer-info") == 0 &&
attr->value_tag == IPP_TAG_TEXT)
info = attr->values[0].string.text;
if (name == NULL)
break;
- if (info == NULL || !info[0])
- (*fn)(name, make_model);
- else
- (*fn)(name, info);
-
-
+ (*fn)(name, info);
}
ippDelete(response);
*/
name = NULL;
- make_model = NULL;
info = NULL;
while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
attr->value_tag == IPP_TAG_NAME)
name = attr->values[0].string.text;
- if (strcmp(attr->name, "printer-make-and-model") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- make_model = attr->values[0].string.text;
-
if (strcmp(attr->name, "printer-info") == 0 &&
attr->value_tag == IPP_TAG_TEXT)
info = attr->values[0].string.text;
if (name == NULL)
break;
- if (info == NULL || !info[0])
- (*fn)(name, make_model);
- else
- (*fn)(name, info);
-
-
+ (*fn)(name, info);
}
ippDelete(response);
*tmp = '\0';
/* add it to the cache */
- if ((ptmp = malloc(sizeof (*ptmp))) != NULL) {
+ if ((ptmp = SMB_MALLOC_P(printer_t)) != NULL) {
ZERO_STRUCTP(ptmp);
- if((ptmp->name = strdup(name)) == NULL)
+ if((ptmp->name = SMB_STRDUP(name)) == NULL)
DEBUG(0,("populate_printers: malloc fail in strdup !\n"));
ptmp->next = printers;
printers = ptmp;
jobids are assigned when a job starts spooling.
*/
-/***************************************************************************
- Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
- bit RPC jobids.... JRA.
-***************************************************************************/
+struct print_queue_update_context {
+ char* sharename;
+ enum printing_types printing_type;
+ char* lpqcommand;
+};
+
static TDB_CONTEXT *rap_tdb;
static uint16 next_rap_jobid;
uint32 jobid;
};
+/***************************************************************************
+ Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
+ bit RPC jobids.... JRA.
+***************************************************************************/
+
uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
{
uint16 rap_jobid;
in the tdb.
****************************************************************************/
-static void set_updating_pid(const fstring sharename, BOOL delete)
+static void set_updating_pid(const fstring sharename, BOOL updating)
{
fstring keystr;
TDB_DATA key;
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
key.dptr = keystr;
key.dsize = strlen(keystr);
+
+ DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
+ updating ? "" : "not ",
+ sharename ));
- if (delete) {
+ if ( !updating ) {
tdb_delete(pdb->tdb, key);
release_print_db(pdb);
return;
}
}
-struct print_queue_update_context {
- fstring sharename;
- enum printing_types printing_type;
- pstring lpqcommand;
-};
+/****************************************************************************
+ Check if the print queue has been updated recently enough.
+****************************************************************************/
+
+static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
+{
+ fstring key;
+ time_t last_qscan_time, time_now = time(NULL);
+ struct tdb_print_db *pdb = get_print_db_byname(sharename);
+ BOOL result = False;
+
+ if (!pdb)
+ return False;
+
+ snprintf(key, sizeof(key), "CACHE/%s", sharename);
+ last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
+
+ /*
+ * Invalidate the queue for 3 reasons.
+ * (1). last queue scan time == -1.
+ * (2). Current time - last queue scan time > allowed cache time.
+ * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
+ * This last test picks up machines for which the clock has been moved
+ * forward, an lpq scan done and then the clock moved back. Otherwise
+ * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
+ */
+
+ if (last_qscan_time == ((time_t)-1)
+ || (time_now - last_qscan_time) >= lp_lpqcachetime()
+ || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
+ {
+ time_t msg_pending_time;
+
+ DEBUG(4, ("print_cache_expired: cache expired for queue %s "
+ "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
+ sharename, (int)last_qscan_time, (int)time_now,
+ (int)lp_lpqcachetime() ));
+
+ /* check if another smbd has already sent a message to update the
+ queue. Give the pending message one minute to clear and
+ then send another message anyways. Make sure to check for
+ clocks that have been run forward and then back again. */
+
+ snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
+
+ if ( check_pending
+ && tdb_fetch_uint32( pdb->tdb, key, &msg_pending_time )
+ && msg_pending_time > 0
+ && msg_pending_time <= time_now
+ && (time_now - msg_pending_time) < 60 )
+ {
+ DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
+ sharename));
+ goto done;
+ }
+
+ result = True;
+ }
+
+done:
+ release_print_db(pdb);
+ return result;
+}
/****************************************************************************
main work for updating the lpq cahe for a printer queue
fstring keystr, cachestr;
struct tdb_print_db *pdb = get_print_db_byname(sharename);
+ DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
+ sharename, current_printif->type, lpq_command));
+
+ if ( !print_cache_expired(sharename, False) ) {
+ DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename));
+ return;
+ }
+
/*
* Update the cache time FIRST ! Stops others even
* attempting to get the lock and doing this
* if the lpq takes a long time.
*/
-
+
slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
current_printif->type,
lpq_command, &queue, &status);
- DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
- "s" : "", sharename));
+ DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
+ qcount, (qcount != 1) ? "s" : "", sharename));
/* Sort the queue by submission time otherwise they are displayed
in hash order. */
SAFE_FREE(tstruct.queue);
- DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
+ DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
sharename, tstruct.total_jobs ));
tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
get_queue_status(sharename, &old_status);
if (old_status.qcount != qcount)
- DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
+ DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
old_status.qcount, qcount, sharename));
/* store the new queue status structure */
slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
+ /* clear the msg pending record for this queue */
+
+ snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
+
+ if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
+ /* log a message but continue on */
+
+ DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
+ sharename));
+ }
+
+ release_print_db( pdb );
+
+ return;
}
/****************************************************************************
struct printif *current_printif = get_printer_fns( snum );
fstrcpy(sharename, lp_const_servicename(snum));
+
+ DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
pdb = get_print_db_byname(sharename);
if (!pdb)
return;
slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
/* Only wait 10 seconds for this. */
if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
- DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", sharename));
+ DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
release_print_db(pdb);
return;
}
*/
/* Tell others we're doing the update. */
- set_updating_pid(sharename, False);
+ set_updating_pid(sharename, True);
/*
* Allow others to enter and notice we're doing
print_queue_update_internal( sharename, current_printif, lpq_command );
/* Delete our pid from the db. */
- set_updating_pid(sharename, True);
+ set_updating_pid(sharename, False);
release_print_db(pdb);
}
/****************************************************************************
this is the receive function of the background lpq updater
****************************************************************************/
-static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
+static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen)
{
- struct print_queue_update_context *ctx;
+ struct print_queue_update_context ctx;
+ fstring sharename;
+ pstring lpqcommand;
+ size_t len;
+
+ len = tdb_unpack( buf, msglen, "fdP",
+ sharename,
+ &ctx.printing_type,
+ lpqcommand );
- if (len != sizeof(struct print_queue_update_context)) {
- DEBUG(1, ("Got invalid print queue update message\n"));
+ if ( len == -1 ) {
+ DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
return;
}
- ctx = (struct print_queue_update_context*)buf;
- print_queue_update_internal(ctx->sharename,
- get_printer_fns_from_type(ctx->printing_type),
- ctx->lpqcommand );
+ ctx.sharename = sharename;
+ ctx.lpqcommand = lpqcommand;
+
+ print_queue_update_internal(ctx.sharename,
+ get_printer_fns_from_type(ctx.printing_type),
+ ctx.lpqcommand );
+
+ return;
}
static pid_t background_lpq_updater_pid = -1;
static void print_queue_update(int snum)
{
struct print_queue_update_context ctx;
+ fstring key;
+ fstring sharename;
+ pstring lpqcommand;
+ char *buffer = NULL;
+ size_t len = 0;
+ size_t newlen;
+ struct tdb_print_db *pdb;
/*
* Make sure that the background queue process exists.
* Otherwise just do the update ourselves
*/
-
- if ( background_lpq_updater_pid != -1 ) {
- fstrcpy(ctx.sharename, lp_const_servicename(snum));
- ctx.printing_type = lp_printing(snum);
-
- pstrcpy(ctx.lpqcommand, lp_lpqcommand(snum));
- pstring_sub( ctx.lpqcommand, "%p", PRINTERNAME(snum) );
- standard_sub_snum( snum, ctx.lpqcommand, sizeof(ctx.lpqcommand) );
- become_root();
- message_send_pid(background_lpq_updater_pid,
- MSG_PRINTER_UPDATE, &ctx, sizeof(ctx),
- False);
- unbecome_root();
- } else
+ if ( background_lpq_updater_pid == -1 ) {
print_queue_update_with_lock( snum );
+ return;
+ }
+
+ fstrcpy( sharename, lp_const_servicename(snum));
+
+ ctx.printing_type = lp_printing(snum);
+
+ pstrcpy( lpqcommand, lp_lpqcommand(snum));
+ pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) );
+ standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
+
+ ctx.sharename = SMB_STRDUP( sharename );
+ ctx.lpqcommand = SMB_STRDUP( lpqcommand );
+
+ /* get the length */
+
+ len = tdb_pack( buffer, len, "fdP",
+ ctx.sharename,
+ ctx.printing_type,
+ ctx.lpqcommand );
+
+ buffer = SMB_XMALLOC_ARRAY( char, len );
+
+ /* now pack the buffer */
+ newlen = tdb_pack( buffer, len, "fdP",
+ ctx.sharename,
+ ctx.printing_type,
+ ctx.lpqcommand );
+
+ SMB_ASSERT( newlen == len );
+
+ DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
+ "type = %d, lpq command = [%s]\n",
+ ctx.sharename, ctx.printing_type, ctx.lpqcommand ));
+
+ /* here we set a msg pending record for other smbd processes
+ to throttle the number of duplicate print_queue_update msgs
+ sent. */
+
+ pdb = get_print_db_byname(sharename);
+ snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
+
+ if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
+ /* log a message but continue on */
+
+ DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
+ sharename));
+ }
+
+ release_print_db( pdb );
+
+ /* finally send the message */
+
+ become_root();
+ message_send_pid(background_lpq_updater_pid,
+ MSG_PRINTER_UPDATE, buffer, len, False);
+ unbecome_root();
+
+ SAFE_FREE( ctx.sharename );
+ SAFE_FREE( ctx.lpqcommand );
+ SAFE_FREE( buffer );
+
+ return;
}
/****************************************************************************
return return_code;
}
-/****************************************************************************
- Check if the print queue has been updated recently enough.
-****************************************************************************/
-
-static BOOL print_cache_expired(int snum)
-{
- fstring key;
- time_t last_qscan_time, time_now = time(NULL);
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return False;
-
- slprintf(key, sizeof(key), "CACHE/%s", printername);
- last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
-
- /*
- * Invalidate the queue for 3 reasons.
- * (1). last queue scan time == -1.
- * (2). Current time - last queue scan time > allowed cache time.
- * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
- * This last test picks up machines for which the clock has been moved
- * forward, an lpq scan done and then the clock moved back. Otherwise
- * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
- */
-
- if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
- last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
- DEBUG(3, ("print cache expired for queue %s \
-(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
- (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
- release_print_db(pdb);
- return True;
- }
- release_print_db(pdb);
- return False;
-}
-
/****************************************************************************
Get the queue status - do not update if db is out of date.
****************************************************************************/
int len;
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
/* also fetch the queue status */
pjob_store(sharename, jobid, pjob);
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
return True;
const char* sharename = lp_servicename(snum);
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
*pcount = 0;
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
/* return if we are done */
}
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum), True))
print_queue_update(snum);
/* Send a printer notify message */
#include "includes.h"
#ifdef WITH_PROFILE
-#define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6))
+#define IPC_PERMS ((S_IRUSR | S_IWUSR) | S_IRGRP | S_IROTH)
#endif /* WITH_PROFILE */
#ifdef WITH_PROFILE
password_obj = PyDict_GetItemString(creds, "password");
if (!username_obj) {
- *errstr = strdup("no username field in credential");
+ *errstr = SMB_STRDUP("no username field in credential");
return False;
}
if (!domain_obj) {
- *errstr = strdup("no domain field in credential");
+ *errstr = SMB_STRDUP("no domain field in credential");
return False;
}
if (!password_obj) {
- *errstr = strdup("no password field in credential");
+ *errstr = SMB_STRDUP("no password field in credential");
return False;
}
/* Check type of required fields */
if (!PyString_Check(username_obj)) {
- *errstr = strdup("username field is not string type");
+ *errstr = SMB_STRDUP("username field is not string type");
return False;
}
if (!PyString_Check(domain_obj)) {
- *errstr = strdup("domain field is not string type");
+ *errstr = SMB_STRDUP("domain field is not string type");
return False;
}
if (!PyString_Check(password_obj)) {
- *errstr = strdup("password field is not string type");
+ *errstr = SMB_STRDUP("password field is not string type");
return False;
}
username, domain, password, 0, Undefined, NULL);
if (!NT_STATUS_IS_OK(result)) {
- *errstr = strdup("error connecting to IPC$ pipe");
+ *errstr = SMB_STRDUP("error connecting to IPC$ pipe");
return NULL;
}
char *workstation_name_slash;
uint8 netlogon_sess_key[16];
static uint8 zeros[16];
+ int i;
ZERO_STRUCT(q);
ZERO_STRUCT(r);
memset(info3->user_sess_key, '\0', 16);
}
- if (memcmp(zeros, info3->padding, 16) != 0) {
- SamOEMhash(info3->padding, netlogon_sess_key, 16);
+ if (memcmp(zeros, info3->lm_sess_key, 8) != 0) {
+ SamOEMhash(info3->lm_sess_key, netlogon_sess_key, 8);
} else {
- memset(info3->padding, '\0', 16);
+ memset(info3->lm_sess_key, '\0', 8);
+ }
+
+ memset(&info3->acct_flags, '\0', 4);
+ for (i=0; i < 7; i++) {
+ memset(&info3->unknown[i], '\0', 4);
}
/* Return results */
if (buf) {
rpcstr_push((char *)str->buffer, buf, len, STR_TERMINATE);
num_chars = strlen_w(str->buffer);
- if (flags == STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
+ if (flags == UNI_STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
num_chars++;
}
}
return True;
}
+BOOL smb_io_lockout_string_hdr(const char *desc, HDR_LOCKOUT_STRING *hdr_account_lockout, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_lockout_string_hdr");
+ depth++;
+
+ if(!prs_align(ps))
+ return False;
+
+ if(!prs_uint16("size", ps, depth, &hdr_account_lockout->size))
+ return False;
+ if(!prs_uint16("length", ps, depth, &hdr_account_lockout->length))
+ return False;
+ if(!prs_uint32("buffer", ps, depth, &hdr_account_lockout->buffer))
+ return False;
+
+ return True;
+}
+
+BOOL smb_io_account_lockout_str(const char *desc, LOCKOUT_STRING *account_lockout, uint32 buffer, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_account_lockout_string");
+ depth++;
+
+ if(!prs_uint32("array_size", ps, depth, &account_lockout->array_size))
+ return False;
+
+ if(!prs_uint32("offset", ps, depth, &account_lockout->offset))
+ return False;
+ if(!prs_uint32("length", ps, depth, &account_lockout->length))
+ return False;
+
+ if (!prs_uint64("lockout_duration", ps, depth, &account_lockout->lockout_duration))
+ return False;
+ if (!prs_uint64("reset_count", ps, depth, &account_lockout->reset_count))
+ return False;
+ if (!prs_uint32("bad_attempt_lockout", ps, depth, &account_lockout->bad_attempt_lockout))
+ return False;
+ if (!prs_uint32("dummy", ps, depth, &account_lockout->dummy))
+ return False;
+#if 0
+ if(!prs_uint16s (False, "bindata", ps, depth, &account_lockout->bindata, length))
+ return False;
+#endif
+
+ return True;
+}
+
/*******************************************************************
Reads or writes a UNISTR2_ARRAY structure.
********************************************************************/
return True;
}
+/*******************************************************************
+reads or writes a BUFHDR4 structure.
+********************************************************************/
+BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "smb_io_bufhdr4");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("size", ps, depth, &(hdr->size));
+ prs_uint32("buffer", ps, depth, &(hdr->buffer));
+
+ return True;
+}
+
/*******************************************************************
reads or writes a BUFFER4 structure.
********************************************************************/
usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
- memset((char *)usr->padding, '\0', sizeof(usr->padding));
+ memset((char *)usr->lm_sess_key, '\0', sizeof(usr->lm_sess_key));
+ memset(&usr->acct_flags, '\0', sizeof(usr->acct_flags));
-#if 0 /* JRATEST - exchange auth test. */
- if (lm_session_key != NULL)
- memcpy(usr->padding, lm_session_key, sizeof(usr->user_sess_key));
-#endif
+ for (i=0; i<7; i++) {
+ memset(&usr->unknown[i], '\0', sizeof(usr->unknown));
+ }
+
+ if (lm_session_key != NULL) {
+ memcpy(usr->lm_sess_key, lm_session_key, sizeof(usr->lm_sess_key));
+ }
num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
return False;
- if(!prs_uint8s (False, "padding ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
+
+ if(!prs_uint8s(False, "lm_sess_key", ps, depth, usr->lm_sess_key, 8)) /* lm session key */
return False;
+ if(!prs_uint32("acct_flags ", ps, depth, &usr->acct_flags)) /* Account flags */
+ return False;
+
+ for (i = 0; i < 7; i++)
+ {
+ if (!prs_uint32("unkown", ps, depth, &usr->unknown[i])) /* unknown */
+ return False;
+ }
+
if (validation_level == 3) {
if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
return False;
return False;
if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
return False;
-
- if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
- return False;
- if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth))
- return False;
-
- if (ps->data_offset + 40 > ps->buffer_size)
- return False;
- ps->data_offset += 40;
+ if (!prs_uint32("security_information", ps, depth, &info->security_information))
+ return False;
+ if (!smb_io_bufhdr4("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
+ return False;
+ if (!smb_io_lockout_string_hdr("hdr_account_lockout_string", &info->hdr_account_lockout, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown2", &info->hdr_unknown2, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown3", &info->hdr_unknown3, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_unknown4", &info->hdr_unknown4, ps, depth))
+ return False;
+ if (!prs_uint32("logon_chgpass", ps, depth, &info->logon_chgpass))
+ return False;
+ if (!prs_uint32("unknown6", ps, depth, &info->unknown6))
+ return False;
+ if (!prs_uint32("unknown7", ps, depth, &info->unknown7))
+ return False;
+ if (!prs_uint32("unknown8", ps, depth, &info->unknown8))
+ return False;
if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
info->hdr_dom_name.buffer, ps, depth))
if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
info->hdr_sec_desc.buffer, ps, depth))
return False;
- if (!smb_io_unistr2("buf_unknown", &info->buf_unknown,
- info->hdr_unknown.buffer, ps, depth))
- return False;
+
+ if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout,
+ info->hdr_account_lockout.buffer, ps, depth))
+ return False;
+
+ if (!smb_io_unistr2("buf_unknown2", &info->buf_unknown2,
+ info->hdr_unknown2.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("buf_unknown3", &info->buf_unknown3,
+ info->hdr_unknown3.buffer, ps, depth))
+ return False;
+ if (!smb_io_unistr2("buf_unknown4", &info->buf_unknown4,
+ info->hdr_unknown4.buffer, ps, depth))
+ return False;
return True;
}
return True;
}
+/*******************************************************************
+inits a structure.
+********************************************************************/
+
+void init_unk_info8(SAM_UNK_INFO_8 * u_8, uint32 seq_num)
+{
+ unix_to_nt_time(&u_8->domain_create_time, 0);
+ u_8->seq_num.low = seq_num;
+ u_8->seq_num.high = 0x0000;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_unk_info8(const char *desc, SAM_UNK_INFO_8 * u_8,
+ prs_struct *ps, int depth)
+{
+ if (u_8 == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info8");
+ depth++;
+
+ if (!prs_uint64("seq_num", ps, depth, &u_8->seq_num))
+ return False;
+
+ if(!smb_io_time("domain_create_time", &u_8->domain_create_time, ps, depth))
+ return False;
+
+ return True;
+}
+
+
/*******************************************************************
inits a structure.
********************************************************************/
********************************************************************/
void init_unk_info2(SAM_UNK_INFO_2 * u_2,
- const char *domain, const char *server,
- uint32 seq_num, uint32 num_users, uint32 num_groups, uint32 num_alias)
+ const char *comment, const char *domain, const char *server,
+ uint32 seq_num, uint32 num_users, uint32 num_groups, uint32 num_alias, NTTIME nt_logout)
{
- u_2->unknown_0 = 0x00000000;
- u_2->unknown_1 = 0x80000000;
- u_2->unknown_2 = 0x00000000;
+ u_2->logout.low = nt_logout.low;
+ u_2->logout.high = nt_logout.high;
- u_2->ptr_0 = 1;
+ u_2->seq_num.low = seq_num;
+ u_2->seq_num.high = 0x00000000;
- u_2->seq_num = seq_num;
- u_2->unknown_3 = 0x00000000;
u_2->unknown_4 = 0x00000001;
u_2->unknown_5 = 0x00000003;
memset(u_2->padding, 0, sizeof(u_2->padding)); /* 12 bytes zeros */
+ init_unistr2(&u_2->uni_comment, comment, UNI_FLAGS_NONE);
+ init_uni_hdr(&u_2->hdr_comment, &u_2->uni_comment);
init_unistr2(&u_2->uni_domain, domain, UNI_FLAGS_NONE);
init_uni_hdr(&u_2->hdr_domain, &u_2->uni_domain);
init_unistr2(&u_2->uni_server, server, UNI_FLAGS_NONE);
prs_debug(ps, depth, desc, "sam_io_unk_info2");
depth++;
- if(!prs_uint32("unknown_0", ps, depth, &u_2->unknown_0)) /* 0x0000 0000 */
+ if(!smb_io_time("logout", &u_2->logout, ps, depth))
return False;
- if(!prs_uint32("unknown_1", ps, depth, &u_2->unknown_1)) /* 0x8000 0000 */
- return False;
- if(!prs_uint32("unknown_2", ps, depth, &u_2->unknown_2)) /* 0x0000 0000 */
- return False;
-
- if(!prs_uint32("ptr_0", ps, depth, &u_2->ptr_0))
+ if(!smb_io_unihdr("hdr_comment", &u_2->hdr_comment, ps, depth))
return False;
if(!smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth))
return False;
pointer is referring to
*/
- if(!prs_uint32("seq_num ", ps, depth, &u_2->seq_num)) /* 0x0000 0099 or 0x1000 0000 */
- return False;
- if(!prs_uint32("unknown_3 ", ps, depth, &u_2->unknown_3)) /* 0x0000 0000 */
+ if(!prs_uint64("seq_num ", ps, depth, &u_2->seq_num))
return False;
if(!prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4)) /* 0x0000 0001 */
if(!prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps))
return False;
- if (u_2->ptr_0) {
- /* this was originally marked as 'padding'. It isn't
- padding, it is some sort of optional 12 byte
- structure. When it is present it contains zeros
- !? */
- if(!prs_uint8s(False, "unknown", ps, depth, u_2->padding,sizeof(u_2->padding)))
- return False;
- }
-
+ if(!smb_io_unistr2("uni_comment", &u_2->uni_comment, u_2->hdr_comment.buffer, ps, depth))
+ return False;
if(!smb_io_unistr2("uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth))
return False;
if(!smb_io_unistr2("uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth))
if(!sam_io_unk_info12("unk_inf12", &r_u->ctr->info.inf12, ps, depth))
return False;
break;
+ case 0x08:
+ if(!sam_io_unk_info8("unk_inf8",&r_u->ctr->info.inf8, ps,depth))
+ return False;
+ break;
case 0x07:
if(!sam_io_unk_info7("unk_inf7",&r_u->ctr->info.inf7, ps,depth))
return False;
}
init_unistr2(&sam->str[i].uni_srv_name, username, UNI_FLAGS_NONE);
- init_unistr2(&sam->str[i].uni_srv_desc, pdb_get_acct_desc(pwd), UNI_FLAGS_NONE);
+ init_unistr2(&sam->str[i].uni_srv_desc, acct_desc, UNI_FLAGS_NONE);
init_sam_entry2(&sam->sam[i], start_idx + i + 1,
&sam->str[i].uni_srv_name, &sam->str[i].uni_srv_desc,
DISK_INFO *dinfo;
if(!(dinfo = PRS_ALLOC_MEM(ps, DISK_INFO, entries_read3)))
- return False;
+ return False;
r_n->disk_enum_ctr.disk_info = dinfo;
}
}
dom_idx = init_dom_ref(ref, dom_name, &find_sid);
- DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
- "referenced list.\n", dom_name, name ));
+ DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' (%d) to referenced list.\n",
+ sid_type_lookup(sid_name_use), dom_name, name, sid_name_use ));
}
NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
{
SAM_ACCOUNT *sam_pass=NULL;
+ struct passwd *passwd;
DOM_SID sid;
+ DOM_SID *sids;
DOM_GID *gids = NULL;
int num_groups = 0;
+ gid_t *unix_gids;
+ int i, num_gids, num_sids;
uint32 acc_granted;
BOOL ret;
+ NTSTATUS result;
/*
* from the SID in the request:
pdb_free_sam(&sam_pass);
return NT_STATUS_NO_SUCH_USER;
}
-
- if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
+
+ passwd = getpwnam_alloc(pdb_get_username(sam_pass));
+ if (passwd == NULL) {
pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_SUCH_GROUP;
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ sids = NULL;
+ num_sids = 0;
+
+ become_root();
+ result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
+ passwd->pw_gid,
+ &sids, &unix_gids, &num_groups);
+ unbecome_root();
+
+ pdb_free_sam(&sam_pass);
+ passwd_free(&passwd);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ SAFE_FREE(unix_gids);
+
+ gids = NULL;
+ num_gids = 0;
+
+ for (i=0; i<num_groups; i++) {
+ uint32 rid;
+
+ if (!sid_peek_check_rid(get_global_sam_sid(),
+ &(sids[i]), &rid))
+ continue;
+
+ gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
+ gids[num_gids].attr=7;
+ gids[num_gids].g_rid = rid;
+ num_gids += 1;
}
+ SAFE_FREE(sids);
/* construct the response. lkclXXXX: gids are not copied! */
init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
- pdb_free_sam(&sam_pass);
-
return r_u->status;
}
}
num_groups=info->disp_info.num_group_account;
free_samr_db(info);
-
+
+ account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
+ u_logout = account_policy_temp;
+
+ unix_to_nt_time_abs(&nt_logout, u_logout);
+
/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
- init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
- num_users, num_groups, num_aliases);
+ init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
+ num_users, num_groups, num_aliases, nt_logout);
break;
case 0x03:
account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
case 0x07:
init_unk_info7(&ctr->info.inf7);
break;
+ case 0x08:
+ init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
+ break;
case 0x0c:
account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp * 60;
NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
{
- int num_groups = 0, tmp_num_groups=0;
- uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
+ int num_groups = 0;
+ uint32 *rids=NULL;
struct samr_info *info = NULL;
- int i,j;
+ int i;
NTSTATUS ntstatus1;
NTSTATUS ntstatus2;
- /* until i see a real useraliases query, we fack one up */
+ DOM_SID *members;
+ DOM_SID *aliases;
+ int num_aliases;
+ BOOL res;
- /* I have seen one, JFM 2/12/2001 */
- /*
- * Explanation of what this call does:
- * for all the SID given in the request:
- * return a list of alias (local groups)
- * that have those SID as members.
- *
- * and that's the alias in the domain specified
- * in the policy_handle
- *
- * if the policy handle is on an incorrect sid
- * for example a user's sid
- * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
- */
-
r_u->status = NT_STATUS_OK;
DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
!sid_check_is_builtin(&info->sid))
return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
- for (i=0; i<q_u->num_sids1; i++) {
+ if (members == NULL)
+ return NT_STATUS_NO_MEMORY;
- r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
+ for (i=0; i<q_u->num_sids1; i++)
+ sid_copy(&members[i], &q_u->sid[i].sid);
- /*
- * if there is an error, we just continue as
- * it can be an unfound user or group
- */
- if (!NT_STATUS_IS_OK(r_u->status)) {
- DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
- continue;
- }
+ become_root();
+ res = pdb_enum_alias_memberships(members,
+ q_u->num_sids1, &aliases,
+ &num_aliases);
+ unbecome_root();
+
+ if (!res)
+ return NT_STATUS_UNSUCCESSFUL;
+
+ rids = NULL;
+ num_groups = 0;
- if (tmp_num_groups==0) {
- DEBUG(10,("_samr_query_useraliases: no groups found\n"));
+ for (i=0; i<num_aliases; i++) {
+ uint32 rid;
+
+ if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
continue;
- }
- new_rids=TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+tmp_num_groups);
- if (new_rids==NULL) {
- DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
+ rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
+
+ if (rids == NULL)
return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
- for (j=0; j<tmp_num_groups; j++)
- rids[j+num_groups]=tmp_rids[j];
-
- safe_free(tmp_rids);
-
- num_groups+=tmp_num_groups;
+ rids[num_groups] = rid;
+ num_groups += 1;
}
-
+ SAFE_FREE(aliases);
+
init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
return NT_STATUS_OK;
}
num_groups=info->disp_info.num_group_account;
free_samr_db(info);
+ account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
+ u_logout = account_policy_temp;
+
+ unix_to_nt_time_abs(&nt_logout, u_logout);
+
/* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
- init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
- num_users, num_groups, num_aliases);
+ init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
+ num_users, num_groups, num_aliases, nt_logout);
break;
case 0x03:
account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
case 0x07:
init_unk_info7(&ctr->info.inf7);
break;
+ case 0x08:
+ init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
+ break;
case 0x0c:
account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
u_lock_duration = account_policy_temp * 60;
/* Search all sharenames first as this is easier than pulling
the printer_info_2 off of disk */
-
- for (snum=0; !found && snum<n_services; snum++) {
-
- if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
- continue;
-
- /* ------ sharename ------ */
-
- fstrcpy(sname, lp_servicename(snum));
-
- DEBUGADD(10, ("share: %s\n",sname));
-
- if ( strequal(sname, aprinter) ) {
- found = True;
- }
+
+ snum = find_service(aprinter);
+
+ if ( lp_snum_ok(snum) && lp_print_ok(snum) ) {
+ found = True;
+ fstrcpy( sname, aprinter );
}
-
/* do another loop to look for printernames */
for (snum=0; !found && snum<n_services; snum++) {
pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
{
SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
- struct current_user user;
WERROR result;
int snum;
result = WERR_BADFID;
goto done;
}
+
+ /* Check the user has permissions to change the security
+ descriptor. By experimentation with two NT machines, the user
+ requires Full Access to the printer to change security
+ information. */
+
+ if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
+ DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
+ result = WERR_ACCESS_DENIED;
+ goto done;
+ }
/* NT seems to like setting the security descriptor even though
nothing may have actually changed. */
goto done;
}
- /* Work out which user is performing the operation */
-
- get_current_user(&user, p);
-
- /* Check the user has permissions to change the security
- descriptor. By experimentation with two NT machines, the user
- requires Full Access to the printer to change security
- information. */
-
- if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
- result = WERR_ACCESS_DENIED;
- goto done;
- }
-
result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
done:
static void init_srv_share_info_501(pipes_struct *p, SRV_SHARE_INFO_501 *sh501, int snum)
{
- int len_net_name;
pstring remark;
- char *net_name = lp_servicename(snum);
+ const char *net_name = lp_servicename(snum);
pstrcpy(remark, lp_comment(snum));
standard_sub_conn(p->conn, remark, sizeof(remark));
- len_net_name = strlen(net_name);
-
init_srv_share_info501(&sh501->info_501, net_name, get_share_type(snum), remark, (lp_csc_policy(snum) << 4));
init_srv_share_info501_str(&sh501->info_501_str, net_name, remark);
}
static void init_srv_share_info_502(pipes_struct *p, SRV_SHARE_INFO_502 *sh502, int snum)
{
- int len_net_name;
pstring net_name;
pstring remark;
pstring path;
string_replace(path, '/', '\\');
pstrcpy(passwd, "");
- len_net_name = strlen(net_name);
sd = get_share_security(ctx, snum, &sd_size);
r_u->disk_enum_ctr.unknown = 0;
if(!(r_u->disk_enum_ctr.disk_info = TALLOC_ARRAY(ctx, DISK_INFO, MAX_SERVER_DISK_ENTRIES))) {
- return WERR_NOMEM;
- }
+ return WERR_NOMEM;
+ }
r_u->disk_enum_ctr.disk_info_ptr = r_u->disk_enum_ctr.disk_info ? 1 : 0;
{ 0 , NULL }
};
-/*******************************************************************
- gets a domain user's groups
- ********************************************************************/
-NTSTATUS get_alias_user_groups(TALLOC_CTX *ctx, DOM_SID *sid, int *numgroups, uint32 **prids, DOM_SID *q_sid)
-{
- SAM_ACCOUNT *sam_pass=NULL;
- int i, cur_rid=0;
- gid_t gid;
- gid_t *groups = NULL;
- int num_groups;
- GROUP_MAP map;
- DOM_SID tmp_sid;
- fstring user_name;
- fstring str_domsid, str_qsid;
- uint32 rid,grid;
- uint32 *rids=NULL, *new_rids=NULL;
- gid_t winbind_gid_low, winbind_gid_high;
- BOOL ret;
- BOOL winbind_groups_exist;
-
- *prids=NULL;
- *numgroups=0;
-
- winbind_groups_exist = lp_idmap_gid(&winbind_gid_low, &winbind_gid_high);
-
-
- DEBUG(10,("get_alias_user_groups: looking if SID %s is a member of groups in the SID domain %s\n",
- sid_to_string(str_qsid, q_sid), sid_to_string(str_domsid, sid)));
-
- pdb_init_sam(&sam_pass);
- become_root();
- ret = pdb_getsampwsid(sam_pass, q_sid);
- unbecome_root();
- if (ret == False) {
- pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_SUCH_USER;
- }
-
- fstrcpy(user_name, pdb_get_username(sam_pass));
- grid=pdb_get_group_rid(sam_pass);
- if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sam_pass), &gid))) {
- /* this should never happen */
- DEBUG(2,("get_alias_user_groups: sid_to_gid failed!\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- ret = getgroups_user(user_name, &groups, &num_groups);
- if (!ret) {
- /* this should never happen */
- DEBUG(2,("get_alias_user_groups: getgroups_user failed\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- for (i=0;i<num_groups;i++) {
-
- become_root();
- ret = get_group_from_gid(groups[i], &map);
- unbecome_root();
-
- if ( !ret ) {
- DEBUG(10,("get_alias_user_groups: gid %d. not found\n", (int)groups[i]));
- continue;
- }
-
- /* if it's not an alias, continue */
- if (map.sid_name_use != SID_NAME_ALIAS) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name));
- continue;
- }
-
- sid_copy(&tmp_sid, &map.sid);
- sid_split_rid(&tmp_sid, &rid);
-
- /* if the sid is not in the correct domain, continue */
- if (!sid_equal(&tmp_sid, sid)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not in the domain SID.\n", map.nt_name));
- continue;
- }
-
- /* Don't return winbind groups as they are not local! */
- if (winbind_groups_exist && (groups[i] >= winbind_gid_low) && (groups[i] <= winbind_gid_high)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name));
- continue;
- }
-
- /* Don't return user private groups... */
- if (Get_Pwnam(map.nt_name) != 0) {
- DEBUG(10,("get_alias_user_groups: not returing %s, clashes with user.\n", map.nt_name));
- continue;
- }
-
- new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1));
- if (new_rids==NULL) {
- DEBUG(10,("get_alias_user_groups: could not realloc memory\n"));
- pdb_free_sam(&sam_pass);
- free(groups);
- return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
-
- sid_peek_rid(&map.sid, &(rids[cur_rid]));
- cur_rid++;
- break;
- }
-
- if(num_groups)
- free(groups);
-
- /* now check for the user's gid (the primary group rid) */
- for (i=0; i<cur_rid && grid!=rids[i]; i++)
- ;
-
- /* the user's gid is already there */
- if (i!=cur_rid) {
- DEBUG(10,("get_alias_user_groups: user is already in the list. good.\n"));
- goto done;
- }
-
- DEBUG(10,("get_alias_user_groups: looking for gid %d of user %s\n", (int)gid, user_name));
-
- if(!get_group_from_gid(gid, &map)) {
- DEBUG(0,("get_alias_user_groups: gid of user %s doesn't exist. Check your "
- "/etc/passwd and /etc/group files\n", user_name));
- goto done;
- }
-
- /* the primary group isn't an alias */
- if (map.sid_name_use!=SID_NAME_ALIAS) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not an ALIAS group.\n", map.nt_name));
- goto done;
- }
-
- sid_copy(&tmp_sid, &map.sid);
- sid_split_rid(&tmp_sid, &rid);
-
- /* if the sid is not in the correct domain, continue */
- if (!sid_equal(&tmp_sid, sid)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not in the domain SID.\n", map.nt_name));
- goto done;
- }
-
- /* Don't return winbind groups as they are not local! */
- if (winbind_groups_exist && (gid >= winbind_gid_low) && (gid <= winbind_gid_high)) {
- DEBUG(10,("get_alias_user_groups: not returing %s, not local.\n", map.nt_name ));
- goto done;
- }
-
- /* Don't return user private groups... */
- if (Get_Pwnam(map.nt_name) != 0) {
- DEBUG(10,("get_alias_user_groups: not returing %s, clashes with user.\n", map.nt_name ));
- goto done;
- }
-
- new_rids=(uint32 *)Realloc(rids, sizeof(uint32)*(cur_rid+1));
- if (new_rids==NULL) {
- DEBUG(10,("get_alias_user_groups: could not realloc memory\n"));
- pdb_free_sam(&sam_pass);
- return NT_STATUS_NO_MEMORY;
- }
- rids=new_rids;
-
- sid_peek_rid(&map.sid, &(rids[cur_rid]));
- cur_rid++;
-
-done:
- *prids=rids;
- *numgroups=cur_rid;
- pdb_free_sam(&sam_pass);
-
- return NT_STATUS_OK;
-}
-
-
-/*******************************************************************
- gets a domain user's groups
- ********************************************************************/
-BOOL get_domain_user_groups(TALLOC_CTX *ctx, int *numgroups, DOM_GID **pgids, SAM_ACCOUNT *sam_pass)
-{
-
- const char *username = pdb_get_username(sam_pass);
- int n_unix_groups;
- int i,j;
- gid_t *unix_groups;
-
- *numgroups = 0;
- *pgids = NULL;
-
- if (!getgroups_user(username, &unix_groups, &n_unix_groups)) {
- return False;
- }
-
- /* now setup the space for storing the SIDS */
-
- if (n_unix_groups > 0) {
-
- *pgids = TALLOC_ARRAY(ctx, DOM_GID, n_unix_groups);
-
- if (!*pgids) {
- DEBUG(0, ("get_user_group: malloc() failed for DOM_GID list!\n"));
- SAFE_FREE(unix_groups);
- return False;
- }
- }
-
- become_root();
- j = 0;
- for (i = 0; i < n_unix_groups; i++) {
- GROUP_MAP map;
- uint32 rid;
-
- if (!pdb_getgrgid(&map, unix_groups[i])) {
- DEBUG(3, ("get_user_groups: failed to convert gid %ld to a domain group!\n",
- (long int)unix_groups[i+1]));
- if (i == 0) {
- DEBUG(1,("get_domain_user_groups: primary gid of user [%s] is not a Domain group !\n", username));
- DEBUGADD(1,("get_domain_user_groups: You should fix it, NT doesn't like that\n"));
- }
- } else if ((map.sid_name_use == SID_NAME_DOM_GRP)
- && sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)) {
- (*pgids)[j].attr=7;
- (*pgids)[j].g_rid=rid;
- j++;
- }
- }
- unbecome_root();
-
- *numgroups = j;
-
- SAFE_FREE(unix_groups);
-
- return True;
-}
/*******************************************************************
gets a domain user's groups from their already-calculated NT_USER_TOKEN
unistr2_to_ascii(name, &info2->uni_server, sizeof(name) - 1);
printf("Server:\t%s\n", name);
+ unistr2_to_ascii(name, &info2->uni_comment, sizeof(name) - 1);
+ printf("Comment:\t%s\n", name);
+
printf("Total Users:\t%d\n", info2->num_domain_usrs);
printf("Total Groups:\t%d\n", info2->num_domain_grps);
printf("Total Aliases:\t%d\n", info2->num_local_grps);
- printf("Sequence No:\t%d\n", info2->seq_num);
-
- printf("Unknown 0:\t0x%x\n", info2->unknown_0);
- printf("Unknown 1:\t0x%x\n", info2->unknown_1);
- printf("Unknown 2:\t0x%x\n", info2->unknown_2);
- printf("Unknown 3:\t0x%x\n", info2->unknown_3);
+ printf("Sequence No:\t%d\n", info2->seq_num.low);
+
+ printf("Force Logoff:\t%d\n", (int)nt_time_to_unix_abs(&info2->logout));
+
printf("Unknown 4:\t0x%x\n", info2->unknown_4);
printf("Unknown 5:\t0x%x\n", info2->unknown_5);
printf("Unknown 6:\t0x%x\n", info2->unknown_6);
}
+static void display_sam_unk_info_8(SAM_UNK_INFO_8 *info8)
+{
+ printf("Sequence No:\t%d\n", info8->seq_num.low);
+ printf("Domain Create Time:\t%s\n",
+ http_timestring(nt_time_to_unix(&info8->domain_create_time)));
+
+}
+
+static void display_sam_unk_info_12(SAM_UNK_INFO_12 *info12)
+{
+ printf("Bad password lockout duration: %s\n", display_time(info12->duration));
+ printf("Reset Lockout after: %s\n", display_time(info12->reset_count));
+ printf("Lockout after bad attempts: %d\n", info12->bad_attempt_lockout);
+}
+
static void display_sam_info_1(SAM_ENTRY1 *e1, SAM_STR1 *s1)
{
fstring tmp;
case 2:
display_sam_unk_info_2(&ctr.info.inf2);
break;
+ case 8:
+ display_sam_unk_info_8(&ctr.info.inf8);
+ break;
+ case 12:
+ display_sam_unk_info_12(&ctr.info.inf12);
+ break;
default:
printf("cannot display domain info for switch value %d\n",
switch_level);
asprintf(&printername, "%s\\%s", servername, argv[1]);
werror = cli_spoolss_open_printer_ex(cli, mem_ctx, printername, "",
- MAXIMUM_ALLOWED_ACCESS,
+ PRINTER_ALL_ACCESS,
servername, cli->user_name, &handle);
if (!W_ERROR_IS_OK(werror))
ldap_mods_free( mods, True );
if (rc != LDAP_SUCCESS) {
- DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
+ DEBUG(1,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n",
type));
goto out;
}
char **trusted_domain_names;
DOM_SID *trusted_domain_sids;
uint32 enum_ctx = 0;
+ DOM_SID builtin_sid;
/* put the results together */
*num_domains = 1;
}
/* put the results together */
- *num_domains = trusted_num_domains + 1;
- *domain_names = (fstring *) realloc(domain_names, sizeof(fstring) * *num_domains);
- *domain_sids = (DOM_SID *) realloc(domain_sids, sizeof(DOM_SID) * *num_domains);
+ *num_domains = trusted_num_domains + 2;
+ *domain_names = (fstring *) realloc(*domain_names, sizeof(fstring) * *num_domains);
+ *domain_sids = (DOM_SID *) realloc(*domain_sids, sizeof(DOM_SID) * *num_domains);
- /* first add myself at the end*/
+ /* first add myself */
fstrcpy((*domain_names)[0], domain_name);
sid_copy(&(*domain_sids)[0], domain_sid);
+ /* then add BUILTIN */
+ string_to_sid(&builtin_sid, "S-1-5-32");
+ fstrcpy((*domain_names)[1], "BUILTIN");
+ sid_copy(&(*domain_sids)[1], &builtin_sid);
+
/* add trusted domains */
for (i=0; i<trusted_num_domains; i++) {
- fstrcpy((*domain_names)[i+1], trusted_domain_names[i]);
- sid_copy(&((*domain_sids)[i+1]), &(trusted_domain_sids[i]));
+ fstrcpy((*domain_names)[i+2], trusted_domain_names[i]);
+ sid_copy(&((*domain_sids)[i+2]), &(trusted_domain_sids[i]));
}
/* show complete domain list */
uint16 acct_ctrl;
uint32 new_pw_len;
uchar new_nt_hash[16];
- uchar old_nt_hash_plain[16];
uchar new_lm_hash[16];
- uchar old_lm_hash_plain[16];
+ uchar verifier[16];
char no_pw[2];
BOOL ret;
return NT_STATUS_ACCOUNT_DISABLED;
}
- if (acct_ctrl & ACB_PWNOTREQ && lp_null_passwords()) {
+ if ((acct_ctrl & ACB_PWNOTREQ) && lp_null_passwords()) {
/* construct a null password (in case one is needed */
no_pw[0] = 0;
no_pw[1] = 0;
pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
} else if (lm_pass_set) {
- DEBUG(1, ("LM password change supplied for user %s, but we have no LanMan password to check it with\n",
- user));
- pdb_free_sam(&sampass);
+ if (lp_lanman_auth()) {
+ DEBUG(1, ("LM password change supplied for user %s, but we have no LanMan password to check it with\n",
+ user));
+ } else {
+ DEBUG(1, ("LM password change supplied for user %s, but we have disabled LanMan authentication\n",
+ user));
+ }
+ pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
} else {
DEBUG(1, ("password change requested for user %s, but no password supplied!\n",
if (nt_pw) {
/*
- * Now use new_nt_hash as the key to see if the old
- * password matches.
+ * check the NT verifier
*/
- D_P16(new_nt_hash, old_nt_hash_encrypted, old_nt_hash_plain);
-
- if (memcmp(nt_pw, old_nt_hash_plain, 16)) {
+ E_old_pw_hash(new_nt_hash, nt_pw, verifier);
+ if (memcmp(verifier, old_nt_hash_encrypted, 16)) {
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
if (lanman_pw) {
/*
- * Now use new_nt_hash as the key to see if the old
- * LM password matches.
+ * check the lm verifier
*/
- D_P16(new_nt_hash, old_lm_hash_encrypted, old_lm_hash_plain);
-
- if (memcmp(lanman_pw, old_lm_hash_plain, 16)) {
+ E_old_pw_hash(new_nt_hash, lanman_pw, verifier);
+ if (memcmp(verifier, old_lm_hash_encrypted, 16)) {
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
E_deshash(new_passwd, new_lm_hash);
/*
- * Now use new_lm_hash as the key to see if the old
- * password matches.
+ * check the lm verifier
*/
- D_P16(new_lm_hash, old_lm_hash_encrypted, old_lm_hash_plain);
-
- if (memcmp(lanman_pw, old_lm_hash_plain, 16)) {
+ E_old_pw_hash(new_lm_hash, lanman_pw, verifier);
+ if (memcmp(verifier, old_lm_hash_encrypted, 16)) {
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
pdb_free_sam(&sampass);
return NT_STATUS_WRONG_PASSWORD;
dbuf = tdb_fetch(tdb, kbuf);
if (!dbuf.dptr) {
- DEBUG(0,("register_message_flags: tdb_fetch failed\n"));
+ DEBUG(0,("register_message_flags: tdb_fetch failed: %s\n",
+ tdb_errorstr(tdb)));
return False;
}
pcrec->bcast_msg_flags &= ~msg_flags;
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) {
- DEBUG(0,("register_message_flags: tdb_store failed with error %s.\n",
+ DEBUG(0,("register_message_flags: tdb_store failed: %s.\n",
tdb_errorstr(tdb) ));
SAFE_FREE(dbuf.dptr);
return False;
/****************************************************************************
Change a dos mode to a unix mode.
Base permission for files:
- if inheriting
+ if creating file and inheriting
apply read/write bits from parent directory.
else
everybody gets read bit set
}
****************************************************************************/
-mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname)
+mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL creating_file)
{
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
result &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
}
- if (fname && lp_inherit_perms(SNUM(conn))) {
+ if (fname && creating_file && lp_inherit_perms(SNUM(conn))) {
char *dname;
SMB_STRUCT_STAT sbuf;
chmod a file - but preserve some bits.
********************************************************************/
-int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st)
+int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode, SMB_STRUCT_STAT *st, BOOL creating_file)
{
SMB_STRUCT_STAT st1;
int mask=0;
int ret = -1;
DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname));
- if (!st) {
+ if (!st || (st && !VALID_STAT(*st))) {
st = &st1;
if (SMB_VFS_STAT(conn,fname,st))
return(-1);
return 0;
}
- unixmode = unix_mode(conn,dosmode,fname);
+ unixmode = unix_mode(conn,dosmode,fname, creating_file);
/* preserve the s bits */
mask |= (S_ISUID | S_ISGID);
if (ret != -1) {
fsp->pos += ret;
+ /*
+ * It turns out that setting the last write time from a Windows
+ * client stops any subsequent writes from updating the write time.
+ * Doing this after the write gives a race condition here where
+ * a stat may see the changed write time before we reset it here,
+ * but it's cheaper than having to store the write time in shared
+ * memory and look it up using dev/inode across all running smbd's.
+ * The 99% solution will hopefully be good enough in this case. JRA.
+ */
+
+ if (fsp->pending_modtime) {
+ set_filetime(fsp->conn, fsp->fsp_name, fsp->pending_modtime);
+ }
+
/* Yes - this is correct - writes don't update this. JRA. */
/* Found by Samba4 tests. */
#if 0
int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
fsp->size = (SMB_BIG_UINT)st.st_size;
if ((lp_store_dos_attributes(SNUM(fsp->conn)) || MAP_ARCHIVE(fsp->conn)) && !IS_DOS_ARCHIVE(dosmode)) {
- file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
+ file_set_dosmode(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st, False);
}
/*
goto bad_param;
if (pcnt) {
- if (pdisp+pcnt >= tpscnt)
+ if (pdisp+pcnt > tpscnt)
goto bad_param;
if ((pdisp+pcnt < pdisp) || (pdisp+pcnt < pcnt))
goto bad_param;
}
if (dcnt) {
- if (ddisp+dcnt >= tdscnt)
+ if (ddisp+dcnt > tdscnt)
goto bad_param;
if ((ddisp+dcnt < ddisp) || (ddisp+dcnt < dcnt))
goto bad_param;
return(True);
}
- snum = lp_servicenumber(QueueName);
- if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(QueueName,pnum);
- snum = lp_servicenumber(QueueName);
- }
- }
-
- if (snum < 0 || !VALID_SNUM(snum))
- return(False);
-
+ snum = find_service(QueueName);
+ if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
+ return False;
+
if (uLevel==52) {
count = get_printerdrivernumber(snum);
DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
data_len = fixed_len = string_len = 0;
for (i=0;i<count;i++) {
fstring servicename_dos;
+ if (!(lp_browseable(i) && lp_snum_ok(i)))
+ continue;
push_ascii_fstring(servicename_dos, lp_servicename(i));
if( lp_browseable( i )
&& lp_snum_ok( i )
for( i = 0; i < count; i++ )
{
fstring servicename_dos;
+ if (!(lp_browseable(i) && lp_snum_ok(i)))
+ continue;
push_ascii_fstring(servicename_dos, lp_servicename(i));
if( lp_browseable( i )
&& lp_snum_ok( i )
int count=0;
SAM_ACCOUNT *sampw = NULL;
BOOL ret = False;
- DOM_GID *gids = NULL;
- int num_groups = 0;
+ DOM_SID *sids;
+ gid_t *gids;
+ int num_groups;
int i;
fstring grp_domain;
fstring grp_name;
enum SID_NAME_USE grp_type;
- DOM_SID sid, dom_sid;
+ struct passwd *passwd;
+ NTSTATUS result;
*rparam_len = 8;
*rparam = SMB_REALLOC_LIMIT(*rparam,*rparam_len);
/* Lookup the user information; This should only be one of
our accounts (not remote domains) */
+
+ passwd = getpwnam_alloc(UserName);
+
+ if (passwd == NULL)
+ return False;
pdb_init_sam( &sampw );
if ( !pdb_getsampwnam(sampw, UserName) )
goto out;
- /* this next set of code is horribly inefficient, but since
- it is rarely called, I'm going to leave it like this since
- it easier to follow --jerry */
-
- /* get the list of group SIDs */
-
- if ( !get_domain_user_groups(conn->mem_ctx, &num_groups, &gids, sampw) ) {
- DEBUG(1,("api_NetUserGetGroups: get_domain_user_groups() failed!\n"));
+ sids = NULL;
+ num_groups = 0;
+
+ result = pdb_enum_group_memberships(pdb_get_username(sampw),
+ passwd->pw_gid,
+ &sids, &gids, &num_groups);
+
+ if (!NT_STATUS_IS_OK(result))
goto out;
- }
- /* convert to names (we don't support universal groups so the domain
- can only be ours) */
-
- sid_copy( &dom_sid, get_global_sam_sid() );
for (i=0; i<num_groups; i++) {
- /* make the DOM_GID into a DOM_SID and then lookup
- the name */
-
- sid_copy( &sid, &dom_sid );
- sid_append_rid( &sid, gids[i].g_rid );
-
- if ( lookup_sid(&sid, grp_domain, grp_name, &grp_type) ) {
+ if ( lookup_sid(&sids[i], grp_domain, grp_name, &grp_type) ) {
pstrcpy(p, grp_name);
p += 21;
count++;
}
}
+
+ SAFE_FREE(sids);
*rdata_len = PTR_DIFF(p,*rdata);
unbecome_root(); /* END ROOT BLOCK */
pdb_free_sam( &sampw );
+ passwd_free(&passwd);
return ret;
}
goto out;
}
+ snum = lp_servicenumber( sharename);
+ if (snum == -1) {
+ errcode = NERR_DestNotFound;
+ goto out;
+ }
+
errcode = NERR_notsupported;
switch (function) {
if(!rap_to_pjobid(SVAL(p,0), sharename, &jobid))
return False;
+ snum = lp_servicenumber( sharename);
if (snum < 0 || !VALID_SNUM(snum)) return(False);
count = print_queue_status(snum,&queue,&status);
DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
/* check it's a supported variant */
- if (strcmp(str1,"zWrLeh") != 0) return False;
- if (uLevel > 2) return False; /* defined only for uLevel 0,1,2 */
- if (!check_printjob_info(&desc,uLevel,str2)) return False;
-
- snum = lp_servicenumber(name);
- if (snum < 0 && pcap_printername_ok(name,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(name,pnum);
- snum = lp_servicenumber(name);
- }
- }
+ if (strcmp(str1,"zWrLeh") != 0)
+ return False;
+
+ if (uLevel > 2)
+ return False; /* defined only for uLevel 0,1,2 */
+
+ if (!check_printjob_info(&desc,uLevel,str2))
+ return False;
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
+ snum = find_service(name);
+ if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
+ return False;
count = print_queue_status(snum,&queue,&status);
if (mdrcnt > 0) *rdata = SMB_REALLOC_LIMIT(*rdata,mdrcnt);
if (strcmp(str1,"zWrLh") != 0) return False;
if (!check_printdest_info(&desc,uLevel,str2)) return False;
- snum = lp_servicenumber(PrinterName);
- if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(PrinterName,pnum);
- snum = lp_servicenumber(PrinterName);
- }
- }
-
- if (snum < 0) {
+ snum = find_service(PrinterName);
+ if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) {
*rdata_len = 0;
desc.errcode = NERR_DestNotFound;
desc.neededlen = 0;
#include "includes.h"
-extern int Protocol;
+extern enum protocol_types Protocol;
extern int max_recv;
BOOL global_encrypted_passwords_negotiated = False;
BOOL global_spnego_negotiated = False;
/* possibly reload - change of architecture */
reload_services(True);
+
+ /* moved from the netbios session setup code since we don't have that
+ when the client connects to port 445. Of course there is a small
+ window where we are listening to messages -- jerry */
+
+ claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
/* Check for protocols, most desirable first */
for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
#include "includes.h"
-extern int Protocol;
+extern enum protocol_types Protocol;
extern int smb_read_error;
extern int global_oplock_break;
extern struct current_user current_user;
static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
pstring fname;
char *params = *ppparams;
/* Grrr. We have to do this as open_file_shared1 adds aARCH when it
creates the file. This isn't the correct thing to do in the copy case. JRA */
- file_set_dosmode(conn, newname, fmode, &sbuf2);
+ file_set_dosmode(conn, newname, fmode, &sbuf2, True);
if (ret < (SMB_OFF_T)sbuf1.st_size) {
return NT_STATUS_DISK_FULL;
static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
char *setup = *ppsetup;
files_struct *fsp;
static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
char *params = *ppparams;
pstring new_name;
static int call_nt_transact_query_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
char *params = *ppparams;
char *data = *ppdata;
prs_struct pd;
static int call_nt_transact_set_security_desc(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
char *params= *ppparams;
char *data = *ppdata;
static int call_nt_transact_ioctl(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
uint32 function;
uint16 fidnum;
* Allocate the correct amount and return the pointer to let
* it be deallocated when we return.
*/
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
SHADOW_COPY_DATA *shadow_data = NULL;
TALLOC_CTX *shadow_mem_ctx = NULL;
BOOL labels = False;
static int call_nt_transact_get_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
NTSTATUS nt_status = NT_STATUS_OK;
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
char *params = *ppparams;
char *pdata = *ppdata;
char *entry;
static int call_nt_transact_set_user_quota(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
char **ppsetup, uint32 setup_count,
char **ppparams, uint32 parameter_count,
- char **ppdata, uint32 data_count)
+ char **ppdata, uint32 data_count, uint32 max_data_count)
{
char *params = *ppparams;
char *pdata = *ppdata;
char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
+ uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
#if 0 /* Not used. */
uint16 max_setup_count = CVAL(inbuf, smb_nt_MaxSetupCount);
uint32 max_parameter_count = IVAL(inbuf, smb_nt_MaxParameterCount);
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
#endif /* Not used. */
uint32 total_parameter_count = IVAL(inbuf, smb_nt_TotalParameterCount);
uint32 total_data_count = IVAL(inbuf, smb_nt_TotalDataCount);
CVAL(inbuf, smb_wct), 19 + (setup_count/2)));
goto bad_param;
}
-
+
/* Don't allow more than 128mb for each value. */
if ((total_parameter_count > (1024*1024*128)) || (total_data_count > (1024*1024*128))) {
END_PROFILE(SMBnttrans);
}
if (parameter_count) {
- if (parameter_displacement + parameter_count >= total_parameter_count)
+ if (parameter_displacement + parameter_count > total_parameter_count)
goto bad_param;
if ((parameter_displacement + parameter_count < parameter_displacement) ||
(parameter_displacement + parameter_count < parameter_count))
}
if (data_count) {
- if (data_displacement + data_count >= total_data_count)
+ if (data_displacement + data_count > total_data_count)
goto bad_param;
if ((data_displacement + data_count < data_displacement) ||
(data_displacement + data_count < data_count))
length, bufsize,
&setup, setup_count,
¶ms, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_create);
break;
case NT_TRANSACT_IOCTL:
length, bufsize,
&setup, setup_count,
¶ms, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_ioctl);
break;
case NT_TRANSACT_SET_SECURITY_DESC:
length, bufsize,
&setup, setup_count,
¶ms, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_set_security_desc);
break;
case NT_TRANSACT_NOTIFY_CHANGE:
length, bufsize,
&setup, setup_count,
¶ms, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_notify_change);
break;
case NT_TRANSACT_RENAME:
length, bufsize,
&setup, setup_count,
¶ms, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_rename);
break;
length, bufsize,
&setup, setup_count,
¶ms, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_query_security_desc);
break;
#ifdef HAVE_SYS_QUOTAS
length, bufsize,
&setup, setup_count,
¶ms, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_get_user_quota);
break;
case NT_TRANSACT_SET_USER_QUOTA:
length, bufsize,
&setup, setup_count,
¶ms, total_parameter_count,
- &data, total_data_count);
+ &data, total_data_count, max_data_count);
END_PROFILE_NESTED(NT_transact_set_user_quota);
break;
#endif /* HAVE_SYS_QUOTAS */
struct pending_message_list *pml = NULL;
uint16 mid = get_current_mid();
/* We add aARCH to this as this mode is only used if the file is created new. */
- mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname);
+ mode_t mode = unix_mode(conn,new_dos_mode | aARCH,fname, True);
if (oplock_request == INTERNAL_OPEN_ONLY) {
internal_only_open = True;
(*Access) = open_mode;
}
+ action = 0;
+
if (file_existed && !(flags2 & O_TRUNC))
action = FILE_WAS_OPENED;
if (file_existed && (flags2 & O_TRUNC))
if (action == FILE_WAS_OVERWRITTEN || action == FILE_WAS_CREATED) {
/* Files should be initially set as archive */
if (lp_map_archive(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
- file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL);
+ file_set_dosmode(conn, fname, new_dos_mode | aARCH, NULL, True);
}
}
return NULL;
}
- if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname)) < 0) {
+ if(vfs_MkDir(conn,fname, unix_mode(conn,aDIR, fname, True)) < 0) {
DEBUG(2,("open_directory: unable to create %s. Error was %s\n",
fname, strerror(errno) ));
file_free(fsp);
DEBUG(3,("readX-IPC pnum=%04x min=%d max=%d nread=%d\n",
p->pnum, smb_mincnt, smb_maxcnt, nread));
+ /* Ensure we set up the message length to include the data length read. */
+ set_message_bcc(outbuf,nread);
return chain_reply(inbuf,outbuf,length,bufsize);
}
int snum = SNUM(fsp->conn);
mode_t and_bits = (mode_t)0;
mode_t or_bits = (mode_t)0;
- mode_t mode = interitable_mode ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name) : S_IRUSR;
+ mode_t mode = interitable_mode ? unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name, False) : S_IRUSR;
if (fsp->is_directory)
mode |= (S_IWUSR|S_IXUSR);
size_t sd_size = 0;
SEC_ACL *psa = NULL;
size_t num_acls = 0;
- size_t num_dir_acls = 0;
+ size_t num_def_acls = 0;
size_t num_aces = 0;
SMB_ACL_T posix_acl = NULL;
- SMB_ACL_T dir_acl = NULL;
+ SMB_ACL_T def_acl = NULL;
canon_ace *file_ace = NULL;
canon_ace *dir_ace = NULL;
size_t num_profile_acls = 0;
*/
if(fsp->is_directory) {
- dir_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
- dir_acl = free_empty_sys_acl(conn, dir_acl);
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ def_acl = free_empty_sys_acl(conn, def_acl);
}
} else {
DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n",
posix_acl ? "present" : "absent",
- dir_acl ? "present" : "absent" ));
+ def_acl ? "present" : "absent" ));
pal = load_inherited_info(fsp);
return 0;
}
- if (fsp->is_directory && dir_acl) {
- dir_ace = canonicalise_acl(fsp, dir_acl, &sbuf,
+ if (fsp->is_directory && def_acl) {
+ dir_ace = canonicalise_acl(fsp, def_acl, &sbuf,
&global_sid_Creator_Owner,
&global_sid_Creator_Group, pal, SMB_ACL_TYPE_DEFAULT );
}
}
num_acls = count_canon_ace_list(file_ace);
- num_dir_acls = count_canon_ace_list(dir_ace);
+ num_def_acls = count_canon_ace_list(dir_ace);
/* Allocate the ace list. */
- if ((nt_ace_list = SMB_MALLOC_ARRAY(SEC_ACE, num_acls + num_profile_acls + num_dir_acls)) == NULL) {
+ if ((nt_ace_list = SMB_MALLOC_ARRAY(SEC_ACE,num_acls + num_profile_acls + num_def_acls)) == NULL) {
DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n"));
goto done;
}
- memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) );
+ memset(nt_ace_list, '\0', (num_acls + num_def_acls) * sizeof(SEC_ACE) );
/*
* Create the NT ACE list from the canonical ace lists.
ace = dir_ace;
- for (i = 0; i < num_dir_acls; i++, ace = ace->next) {
+ for (i = 0; i < num_def_acls; i++, ace = ace->next) {
SEC_ACCESS acc;
acc = map_canon_ace_perms(&nt_acl_type, &owner_sid, ace );
* inherited at file create time, so ACLs never contain
* any ACEs that are inherited dynamically. The DACL_PROTECTED
* flag doesn't seem to bother Windows NT.
+ * Always set this if map acl inherit is turned off.
*/
- if (get_protected_flag(pal))
+ if (get_protected_flag(pal) || !lp_map_acl_inherit(SNUM(conn))) {
psd->type |= SE_DESC_DACL_PROTECTED;
+ }
}
if (psd->dacl)
if (posix_acl)
SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl);
- if (dir_acl)
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl)
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
free_inherited_info(pal);
BOOL directory_has_default_acl(connection_struct *conn, const char *fname)
{
- SMB_ACL_T dir_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
- BOOL has_acl = False;
- SMB_ACL_ENTRY_T entry;
+ SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_DEFAULT);
+ BOOL has_acl = False;
+ SMB_ACL_ENTRY_T entry;
- if (dir_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1))
- has_acl = True;
+ if (def_acl != NULL && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, def_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) {
+ has_acl = True;
+ }
- if (dir_acl)
- SMB_VFS_SYS_ACL_FREE_ACL(conn, dir_acl);
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
return has_acl;
}
+
+/****************************************************************************
+ Map from wire type to permset.
+****************************************************************************/
+
+static BOOL unix_ex_wire_to_permset(connection_struct *conn, unsigned char wire_perm, SMB_ACL_PERMSET_T *p_permset)
+{
+ if (wire_perm & ~(SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE)) {
+ return False;
+ }
+
+ if (SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, *p_permset) == -1) {
+ return False;
+ }
+
+ if (wire_perm & SMB_POSIX_ACL_READ) {
+ if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_READ) == -1) {
+ return False;
+ }
+ }
+ if (wire_perm & SMB_POSIX_ACL_WRITE) {
+ if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_WRITE) == -1) {
+ return False;
+ }
+ }
+ if (wire_perm & SMB_POSIX_ACL_EXECUTE) {
+ if (SMB_VFS_SYS_ACL_ADD_PERM(conn, *p_permset, SMB_ACL_EXECUTE) == -1) {
+ return False;
+ }
+ }
+ return True;
+}
+
+/****************************************************************************
+ Map from wire type to tagtype.
+****************************************************************************/
+
+static BOOL unix_ex_wire_to_tagtype(unsigned char wire_tt, SMB_ACL_TAG_T *p_tt)
+{
+ switch (wire_tt) {
+ case SMB_POSIX_ACL_USER_OBJ:
+ *p_tt = SMB_ACL_USER_OBJ;
+ break;
+ case SMB_POSIX_ACL_USER:
+ *p_tt = SMB_ACL_USER;
+ break;
+ case SMB_POSIX_ACL_GROUP_OBJ:
+ *p_tt = SMB_ACL_GROUP_OBJ;
+ break;
+ case SMB_POSIX_ACL_GROUP:
+ *p_tt = SMB_ACL_GROUP;
+ break;
+ case SMB_POSIX_ACL_MASK:
+ *p_tt = SMB_ACL_MASK;
+ break;
+ case SMB_POSIX_ACL_OTHER:
+ *p_tt = SMB_ACL_OTHER;
+ break;
+ default:
+ return False;
+ }
+ return True;
+}
+
+/****************************************************************************
+ Create a new POSIX acl from wire permissions.
+ FIXME ! How does the share mask/mode fit into this.... ?
+****************************************************************************/
+
+static SMB_ACL_T create_posix_acl_from_wire(connection_struct *conn, uint16 num_acls, const char *pdata)
+{
+ unsigned int i;
+ SMB_ACL_T the_acl = SMB_VFS_SYS_ACL_INIT(conn, num_acls);
+
+ if (the_acl == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < num_acls; i++) {
+ SMB_ACL_ENTRY_T the_entry;
+ SMB_ACL_PERMSET_T the_permset;
+ SMB_ACL_TAG_T tag_type;
+
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &the_acl, &the_entry) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to create entry %u. (%s)\n",
+ i, strerror(errno) ));
+ goto fail;
+ }
+
+ if (!unix_ex_wire_to_tagtype(CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)), &tag_type)) {
+ DEBUG(0,("create_posix_acl_from_wire: invalid wire tagtype %u on entry %u.\n",
+ CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)), i ));
+ goto fail;
+ }
+
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, the_entry, tag_type) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to set tagtype on entry %u. (%s)\n",
+ i, strerror(errno) ));
+ goto fail;
+ }
+
+ /* Get the permset pointer from the new ACL entry. */
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, the_entry, &the_permset) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to get permset on entry %u. (%s)\n",
+ i, strerror(errno) ));
+ goto fail;
+ }
+
+ /* Map from wire to permissions. */
+ if (!unix_ex_wire_to_permset(conn, CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+1), &the_permset)) {
+ DEBUG(0,("create_posix_acl_from_wire: invalid permset %u on entry %u.\n",
+ CVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE) + 1), i ));
+ goto fail;
+ }
+
+ /* Now apply to the new ACL entry. */
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, the_entry, the_permset) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to add permset on entry %u. (%s)\n",
+ i, strerror(errno) ));
+ goto fail;
+ }
+
+ if (tag_type == SMB_ACL_USER) {
+ uint32 uidval = IVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ uid_t uid = (uid_t)uidval;
+ if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&uid) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to set uid %u on entry %u. (%s)\n",
+ (unsigned int)uid, i, strerror(errno) ));
+ goto fail;
+ }
+ }
+
+ if (tag_type == SMB_ACL_GROUP) {
+ uint32 gidval = IVAL(pdata,(i*SMB_POSIX_ACL_ENTRY_SIZE)+2);
+ gid_t gid = (uid_t)gidval;
+ if (SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, the_entry,(void *)&gid) == -1) {
+ DEBUG(0,("create_posix_acl_from_wire: Failed to set gid %u on entry %u. (%s)\n",
+ (unsigned int)gid, i, strerror(errno) ));
+ goto fail;
+ }
+ }
+ }
+
+ return the_acl;
+
+ fail:
+
+ if (the_acl != NULL) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, the_acl);
+ }
+ return NULL;
+}
+
+/****************************************************************************
+ Calls from UNIX extensions - Default POSIX ACL set.
+ If num_def_acls == 0 and not a directory just return. If it is a directory
+ and num_def_acls == 0 then remove the default acl. Else set the default acl
+ on the directory.
+****************************************************************************/
+
+BOOL set_unix_posix_default_acl(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf,
+ uint16 num_def_acls, const char *pdata)
+{
+ SMB_ACL_T def_acl = NULL;
+
+ if (num_def_acls && !S_ISDIR(psbuf->st_mode)) {
+ DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname ));
+ errno = EISDIR;
+ return False;
+ }
+
+ if (!num_def_acls) {
+ /* Remove the default ACL. */
+ if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fname) == -1) {
+ DEBUG(5,("set_unix_posix_default_acl: acl_delete_def_file failed on directory %s (%s)\n",
+ fname, strerror(errno) ));
+ return False;
+ }
+ return True;
+ }
+
+ if ((def_acl = create_posix_acl_from_wire(conn, num_def_acls, pdata)) == NULL) {
+ return False;
+ }
+
+ if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT, def_acl) == -1) {
+ DEBUG(5,("set_unix_posix_default_acl: acl_set_file failed on directory %s (%s)\n",
+ fname, strerror(errno) ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ return False;
+ }
+
+ DEBUG(10,("set_unix_posix_default_acl: set default acl for file %s\n", fname ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ return True;
+}
+
+/****************************************************************************
+ Remove an ACL from a file. As we don't have acl_delete_entry() available
+ we must read the current acl and copy all entries except MASK, USER and GROUP
+ to a new acl, then set that. This (at least on Linux) causes any ACL to be
+ removed.
+ FIXME ! How does the share mask/mode fit into this.... ?
+****************************************************************************/
+
+static BOOL remove_posix_acl(connection_struct *conn, files_struct *fsp, const char *fname)
+{
+ SMB_ACL_T file_acl = NULL;
+ int entry_id = SMB_ACL_FIRST_ENTRY;
+ SMB_ACL_ENTRY_T entry;
+ BOOL ret = False;
+ /* Create a new ACL with only 3 entries, u/g/w. */
+ SMB_ACL_T new_file_acl = SMB_VFS_SYS_ACL_INIT(conn, 3);
+ SMB_ACL_ENTRY_T user_ent = NULL;
+ SMB_ACL_ENTRY_T group_ent = NULL;
+ SMB_ACL_ENTRY_T other_ent = NULL;
+
+ if (new_file_acl == NULL) {
+ DEBUG(5,("remove_posix_acl: failed to init new ACL with 3 entries for file %s.\n", fname));
+ return False;
+ }
+
+ /* Now create the u/g/w entries. */
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &user_ent) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to create user entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, user_ent, SMB_ACL_USER_OBJ) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to set user entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &group_ent) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to create group entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, group_ent, SMB_ACL_GROUP_OBJ) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to set group entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ if (SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, &new_file_acl, &other_ent) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to create other entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+ if (SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, other_ent, SMB_ACL_OTHER) == -1) {
+ DEBUG(5,("remove_posix_acl: Failed to set other entry for file %s. (%s)\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ /* Get the current file ACL. */
+ if (fsp && fsp->fd != -1) {
+ file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
+ } else {
+ file_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_ACCESS);
+ }
+
+ if (file_acl == NULL) {
+ /* This is only returned if an error occurred. Even for a file with
+ no acl a u/g/w acl should be returned. */
+ DEBUG(5,("remove_posix_acl: failed to get ACL from file %s (%s).\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ while ( SMB_VFS_SYS_ACL_GET_ENTRY(conn, file_acl, entry_id, &entry) == 1) {
+ SMB_ACL_TAG_T tagtype;
+ SMB_ACL_PERMSET_T permset;
+
+ /* get_next... */
+ if (entry_id == SMB_ACL_FIRST_ENTRY)
+ entry_id = SMB_ACL_NEXT_ENTRY;
+
+ if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to get tagtype from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to get permset from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ goto done;
+ }
+
+ if (tagtype == SMB_ACL_USER_OBJ) {
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, user_ent, permset) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ }
+ } else if (tagtype == SMB_ACL_GROUP_OBJ) {
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, group_ent, permset) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ }
+ } else if (tagtype == SMB_ACL_OTHER) {
+ if (SMB_VFS_SYS_ACL_SET_PERMSET(conn, other_ent, permset) == -1) {
+ DEBUG(5,("remove_posix_acl: failed to set permset from ACL on file %s (%s).\n",
+ fname, strerror(errno) ));
+ }
+ }
+ }
+
+ ret = True;
+
+ done:
+
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (new_file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, new_file_acl);
+ }
+ return ret;
+}
+
+/****************************************************************************
+ Calls from UNIX extensions - POSIX ACL set.
+ If num_def_acls == 0 then read/modify/write acl after removing all entries
+ except SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER.
+****************************************************************************/
+
+BOOL set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char *fname, uint16 num_acls, const char *pdata)
+{
+ SMB_ACL_T file_acl = NULL;
+
+ if (!num_acls) {
+ /* Remove the ACL from the file. */
+ return remove_posix_acl(conn, fsp, fname);
+ }
+
+ if ((file_acl = create_posix_acl_from_wire(conn, num_acls, pdata)) == NULL) {
+ return False;
+ }
+
+ if (fsp && fsp->fd != -1) {
+ /* The preferred way - use an open fd. */
+ if (SMB_VFS_SYS_ACL_SET_FD(fsp, fsp->fd, file_acl) == -1) {
+ DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
+ fname, strerror(errno) ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ return False;
+ }
+ } else {
+ if (SMB_VFS_SYS_ACL_SET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS, file_acl) == -1) {
+ DEBUG(5,("set_unix_posix_acl: acl_set_file failed on %s (%s)\n",
+ fname, strerror(errno) ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ return False;
+ }
+ }
+
+ DEBUG(10,("set_unix_posix_acl: set acl for file %s\n", fname ));
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ return True;
+}
int outsize2;
char inbuf_saved[smb_wct];
char outbuf_saved[smb_wct];
- int wct = CVAL(outbuf,smb_wct);
- int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
+ int outsize = smb_len(outbuf) + 4;
/* maybe its not chained */
if (smb_com2 == 0xFF) {
len=strcspn(mnttype, ":");
pathname=strstr(mnttype, ":");
- cutstr = (char *) malloc(len+1);
+ cutstr = (char *) SMB_MALLOC(len+1);
if (!cutstr)
return False;
len=strcspn(mnttype, ":");
pathname=strstr(mnttype, ":");
- cutstr = (char *) malloc(len+1);
+ cutstr = (char *) SMB_MALLOC(len+1);
if (!cutstr)
return False;
#include "includes.h"
/* look in server.c for some explanation of these variables */
-extern int Protocol;
+extern enum protocol_types Protocol;
extern int max_send;
extern int max_recv;
extern char magic_char;
extern int global_oplock_break;
unsigned int smb_echo_count = 0;
+extern uint32 global_client_caps;
extern BOOL global_encrypted_passwords_negotiated;
reload_services(True);
reopen_logs();
- claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
-
already_got_session = True;
break;
mode &= ~aDIR;
if (check_name(fname,conn)) {
- ok = (file_set_dosmode(conn,fname,mode,NULL) == 0);
+ ok = (file_set_dosmode(conn,fname,mode,&sbuf,False) == 0);
}
} else {
ok = True;
Fail for readbraw.
****************************************************************************/
-void fail_readraw(void)
+static void fail_readraw(void)
{
pstring errstr;
slprintf(errstr, sizeof(errstr)-1, "FAIL ! reply_readbraw: socket write fail (%s)",
exit_server(errstr);
}
+#if defined(WITH_SENDFILE)
+/****************************************************************************
+ Fake (read/write) sendfile. Returns -1 on read or write fail.
+****************************************************************************/
+
+static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, int bufsize)
+{
+ ssize_t ret=0;
+
+ /* Paranioa check... */
+ if (nread > bufsize) {
+ fail_readraw();
+ }
+
+ if (nread > 0) {
+ ret = read_file(fsp,buf,startpos,nread);
+ if (ret == -1) {
+ return -1;
+ }
+ }
+
+ /* If we had a short read, fill with zeros. */
+ if (ret < nread) {
+ memset(buf, '\0', nread - ret);
+ }
+
+ if (write_data(smbd_server_fd(),buf,nread) != nread) {
+ return -1;
+ }
+
+ return (ssize_t)nread;
+}
+#endif
+
/****************************************************************************
Use sendfile in readbraw.
****************************************************************************/
void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
- ssize_t mincount, char *outbuf)
+ ssize_t mincount, char *outbuf, int out_buffsize)
{
ssize_t ret=0;
header.free = NULL;
if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
+ /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
+ if (errno == ENOSYS) {
+ goto normal_readbraw;
+ }
+
/*
- * Special hack for broken Linux with no 64 bit clean sendfile. If we
- * return ENOSYS then pretend we just got a normal read.
+ * Special hack for broken Linux with no working sendfile. If we
+ * return EINTR we sent the header but not the rest of the data.
+ * Fake this up by doing read/write calls.
*/
- if (errno == ENOSYS) {
+ if (errno == EINTR) {
+ /* Ensure we don't do this again. */
set_use_sendfile(SNUM(conn), False);
- goto normal_read;
+ DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
+
+ if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) {
+ DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
+ fsp->fsp_name, strerror(errno) ));
+ exit_server("send_file_readbraw fake_sendfile failed");
+ }
+ return;
}
DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
}
- normal_read:
+ normal_readbraw:
+
#endif
if (nread > 0) {
Reply to a readbraw (core+ protocol).
****************************************************************************/
-int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
+int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
{
extern struct current_user current_user;
ssize_t maxcount,mincount;
/* ensure we don't overrun the packet size */
maxcount = MIN(65535,maxcount);
- if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ if (!is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
SMB_OFF_T size = fsp->size;
SMB_OFF_T sizeneeded = startpos + maxcount;
DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n", fsp->fnum, (double)startpos,
(int)maxcount, (int)mincount, (int)nread ) );
- send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf);
+ send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
DEBUG(5,("readbraw finished\n"));
END_PROFILE(SMBreadbraw);
data = smb_buf(outbuf) + 3;
- if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBread);
return ERROR_DOS(ERRDOS,ERRlock);
}
Reply to a read and X - possibly using sendfile.
****************************************************************************/
-int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length,
+int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, int len_outbuf,
files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
{
+ int outsize = 0;
ssize_t nread = -1;
char *data = smb_buf(outbuf);
SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
SSVAL(outbuf,smb_vwv5,smb_maxcnt);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
+ SSVAL(outbuf,smb_vwv7,((smb_maxcnt >> 16) & 1));
SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
SCVAL(outbuf,smb_vwv0,0xFF);
set_message(outbuf,12,smb_maxcnt,False);
header.length = data - outbuf;
header.free = NULL;
- if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
+ if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt)) == -1) {
+ /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
+ if (errno == ENOSYS) {
+ goto normal_read;
+ }
+
/*
- * Special hack for broken Linux with no 64 bit clean sendfile. If we
- * return ENOSYS then pretend we just got a normal read.
+ * Special hack for broken Linux with no working sendfile. If we
+ * return EINTR we sent the header but not the rest of the data.
+ * Fake this up by doing read/write calls.
*/
- if (errno == ENOSYS) {
+
+ if (errno == EINTR) {
+ /* Ensure we don't do this again. */
set_use_sendfile(SNUM(conn), False);
- goto normal_read;
+ DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
+
+ if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
+ len_outbuf - (data-outbuf))) == -1) {
+ DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
+ fsp->fsp_name, strerror(errno) ));
+ exit_server("send_file_readX: fake_sendfile failed");
+ }
+ DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
+ fsp->fnum, (int)smb_maxcnt, (int)nread ) );
+ /* Returning -1 here means successful sendfile. */
+ return -1;
}
DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
+ /* Returning -1 here means successful sendfile. */
return -1;
}
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
+ outsize = set_message(outbuf,12,nread,False);
SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
SSVAL(outbuf,smb_vwv5,nread);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
+ SSVAL(outbuf,smb_vwv7,((nread >> 16) & 1));
SSVAL(smb_buf(outbuf),-2,nread);
DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
- return nread;
+ /* Returning the number of bytes we want to send back - including header. */
+ return outsize;
}
/****************************************************************************
set_message(outbuf,12,0,True);
+ if (global_client_caps & CAP_LARGE_READX) {
+ if (SVAL(inbuf,smb_vwv7) == 1) {
+ smb_maxcnt |= (1<<16);
+ }
+ if (smb_maxcnt > BUFFER_SIZE) {
+ DEBUG(0,("reply_read_and_X - read too large (%u) for reply buffer %u\n",
+ (unsigned int)smb_maxcnt, (unsigned int)BUFFER_SIZE));
+ END_PROFILE(SMBreadX);
+ return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ }
+ }
+
if(CVAL(inbuf,smb_wct) == 12) {
#ifdef LARGE_SMB_OFF_T
/*
}
- if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBreadX);
return ERROR_DOS(ERRDOS,ERRlock);
}
- nread = send_file_readX(conn, inbuf, outbuf, length, fsp, startpos, smb_maxcnt);
+ nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
if (nread != -1)
nread = chain_reply(inbuf,outbuf,length,bufsize);
SCVAL(inbuf,smb_com,SMBwritec);
SCVAL(outbuf,smb_com,SMBwritec);
- if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwritebraw);
return(ERROR_DOS(ERRDOS,ERRlock));
}
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos,
- WRITE_LOCK,False)) {
+ if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteunlock);
return ERROR_DOS(ERRDOS,ERRlock);
}
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwrite);
return ERROR_DOS(ERRDOS,ERRlock);
}
#endif /* LARGE_SMB_OFF_T */
}
- if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteX);
return ERROR_DOS(ERRDOS,ERRlock);
}
mtime = make_unix_date3(inbuf+smb_vwv4);
data = smb_buf(inbuf) + 1;
- if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK,False)) {
+ if (numtowrite && is_locked(fsp,conn,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteclose);
return ERROR_DOS(ERRDOS,ERRlock);
}
}
if (check_name(directory, conn))
- ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
+ ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
if (ret == -1) {
if(errno == ENOENT) {
/* we don't support these - and CANCEL_LOCK makes w2k
and XP reboot so I don't really want to be
compatible! (tridge) */
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
}
if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
tcount = maxcount;
total_read = 0;
- if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBreadBmpx);
return ERROR_DOS(ERRDOS,ERRlock);
}
not an SMBwritebmpx - set this up now so we don't forget */
SCVAL(outbuf,smb_com,SMBwritec);
- if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK,False)) {
+ if (is_locked(fsp,conn,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
END_PROFILE(SMBwriteBmpx);
return(ERROR_DOS(ERRDOS,ERRlock));
}
int fd_listenset[FD_SETSIZE];
fd_set listen_set;
int s;
+ int maxfd = 0;
int i;
char *ports;
for (ptr=ports; next_token(&ptr, tok, NULL, sizeof(tok)); ) {
unsigned port = atoi(tok);
- if (port == 0) continue;
+ if (port == 0) {
+ continue;
+ }
s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
if(s == -1)
return False;
return False;
}
FD_SET(s,&listen_set);
+ maxfd = MAX( maxfd, s);
num_sockets++;
if (num_sockets >= FD_SETSIZE) {
fd_listenset[num_sockets] = s;
FD_SET(s,&listen_set);
+ maxfd = MAX( maxfd, s);
num_sockets++;
memcpy((char *)&lfds, (char *)&listen_set,
sizeof(listen_set));
- num = sys_select(FD_SETSIZE,&lfds,NULL,NULL,NULL);
+ num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL);
if (num == -1 && errno == EINTR) {
if (got_sig_term) {
return(True);
lp_killunused(conn_snum_used);
-
+
ret = lp_load(dyn_CONFIGFILE, False, False, True);
+ remove_stale_printers();
load_printers();
/* perhaps the config filename is now set */
init_structs();
+ if (!init_guest_info())
+ return -1;
+
#ifdef WITH_PROFILE
if (!profile_setup(False)) {
DEBUG(0,("ERROR: failed to setup profiling\n"));
smbd is launched via inetd and we fork a copy of
ourselves here */
- if ( is_daemon )
+ if ( is_daemon && !interactive )
start_background_queue();
if (!open_sockets_smbd(is_daemon, interactive, ports))
int iPrinterService;
if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
- char *pszTemp;
+ const char *pszTemp = lp_printcapname();
DEBUG(3,("checking whether %s is a valid printer name...\n", service));
- pszTemp = lp_printcapname();
if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp)) {
DEBUG(3,("%s is a valid printer name\n", service));
DEBUG(3,("adding %s as a printer service\n", service));
iNumServices = lp_numservices();
printersServiceNum = lp_servicenumber( PRINTERS_NAME);
for( snum = 0; snum < iNumServices; snum++) {
+
/* Never remove PRINTERS_NAME */
+
if ( snum == printersServiceNum)
continue;
pname = lp_printername( snum);
- /* Is snum a print service and still in the printing subsystem? */
- if ( lp_print_ok( snum) && !pcap_printername_ok( pname, NULL)) {
+
+ /* Is snum an autoloaded print service and still
+ in the printing subsystem? */
+
+ if ( lp_snum_ok(snum)
+ && lp_print_ok(snum)
+ && lp_autoloaded(snum)
+ && !pcap_printername_ok( pname, NULL))
+ {
DEBUG( 3, ( "Removing printer: %s\n", pname));
lp_killservice( snum);
}
static BOOL done_sesssetup = False;
extern BOOL global_encrypted_passwords_negotiated;
extern BOOL global_spnego_negotiated;
- extern int Protocol;
+ extern enum protocol_types Protocol;
extern int max_send;
auth_usersupplied_info *user_info = NULL;
#include "includes.h"
-extern int Protocol;
+extern enum protocol_types Protocol;
extern int smb_read_error;
extern fstring local_machine;
extern int global_oplock_break;
****************************************************************************/
static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
int16 open_mode;
adate &= ~1;
}
- if(mode & aDIR)
+ if(mode & aDIR) {
+ /* This is necessary, as otherwise the
+ * desktop.ini file in this folder is
+ * ignored */
+ mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
file_size = 0;
+ }
DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
****************************************************************************/
static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outbuf, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
/* We must be careful here that we don't return more than the
allowed number of data bytes. If this means returning fewer than
maxentries then so be it. We assume that the redirector has
enough room for the fixed number of parameter bytes it has
requested. */
- uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
int dirtype = SVAL(params,0);
int maxentries = SVAL(params,2);
- BOOL close_after_first = BITSETW(params+4,0);
- BOOL close_if_end = BITSETW(params+4,1);
- BOOL requires_resume_key = BITSETW(params+4,2);
+ uint16 findfirst_flags = SVAL(params,4);
+ BOOL close_after_first = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE);
+ BOOL close_if_end = (findfirst_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
+ BOOL requires_resume_key = (findfirst_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
int info_level = SVAL(params,6);
pstring directory;
pstring mask;
****************************************************************************/
static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
/* We must be careful here that we don't return more than the
allowed number of data bytes. If this means returning fewer than
maxentries then so be it. We assume that the redirector has
enough room for the fixed number of parameter bytes it has
requested. */
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
int dptr_num = SVAL(params,0);
int maxentries = SVAL(params,2);
uint16 info_level = SVAL(params,4);
uint32 resume_key = IVAL(params,6);
- BOOL close_after_request = BITSETW(params+10,0);
- BOOL close_if_end = BITSETW(params+10,1);
- BOOL requires_resume_key = BITSETW(params+10,2);
- BOOL continue_bit = BITSETW(params+10,3);
+ uint16 findnext_flags = SVAL(params,10);
+ BOOL close_after_request = (findnext_flags & FLAG_TRANS2_FIND_CLOSE);
+ BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
+ BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
+ BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
pstring resume_name;
pstring mask;
pstring directory;
Reply to a TRANS2_QFSINFO (query filesystem info).
****************************************************************************/
-static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf,
- int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *pdata = *ppdata;
char *params = *pparams;
uint16 info_level = SVAL(params,0);
data_len = 12;
SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
- SBIG_UINT(pdata,4,((SMB_BIG_UINT)0)); /* No capabilities for now... */
+ SBIG_UINT(pdata,4,((SMB_BIG_UINT)CIFS_UNIX_POSIX_ACLS_CAP)); /* We have POSIX ACLs. */
break;
case SMB_MAC_QUERY_FS_INFO:
Reply to a TRANS2_SETFSINFO (set filesystem info).
****************************************************************************/
-static int call_trans2setfsinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2setfsinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *pdata = *ppdata;
char *params = *pparams;
#endif /* HAVE_SYS_QUOTAS */
/****************************************************************************
- * Utility function to set bad path error.
- ****************************************************************************/
+ Utility function to set bad path error.
+****************************************************************************/
int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
{
return UNIXERROR(def_class,def_code);
}
+/****************************************************************************
+ Utility function to count the number of entries in a POSIX acl.
+****************************************************************************/
+
+static unsigned int count_acl_entries(connection_struct *conn, SMB_ACL_T posix_acl)
+{
+ unsigned int ace_count = 0;
+ int entry_id = SMB_ACL_FIRST_ENTRY;
+ SMB_ACL_ENTRY_T entry;
+
+ while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
+ /* get_next... */
+ if (entry_id == SMB_ACL_FIRST_ENTRY) {
+ entry_id = SMB_ACL_NEXT_ENTRY;
+ }
+ ace_count++;
+ }
+ return ace_count;
+}
+
+/****************************************************************************
+ Utility function to marshall a POSIX acl into wire format.
+****************************************************************************/
+
+static BOOL marshall_posix_acl(connection_struct *conn, char *pdata, SMB_STRUCT_STAT *pst, SMB_ACL_T posix_acl)
+{
+ int entry_id = SMB_ACL_FIRST_ENTRY;
+ SMB_ACL_ENTRY_T entry;
+
+ while ( posix_acl && (SMB_VFS_SYS_ACL_GET_ENTRY(conn, posix_acl, entry_id, &entry) == 1)) {
+ SMB_ACL_TAG_T tagtype;
+ SMB_ACL_PERMSET_T permset;
+ unsigned char perms = 0;
+ unsigned int own_grp;
+
+ /* get_next... */
+ if (entry_id == SMB_ACL_FIRST_ENTRY) {
+ entry_id = SMB_ACL_NEXT_ENTRY;
+ }
+
+ if (SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry, &tagtype) == -1) {
+ DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_TAG_TYPE failed.\n"));
+ return False;
+ }
+
+ if (SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry, &permset) == -1) {
+ DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_PERMSET failed.\n"));
+ return False;
+ }
+
+ perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_READ) ? SMB_POSIX_ACL_READ : 0);
+ perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_WRITE) ? SMB_POSIX_ACL_WRITE : 0);
+ perms |= (SMB_VFS_SYS_ACL_GET_PERM(conn, permset, SMB_ACL_EXECUTE) ? SMB_POSIX_ACL_EXECUTE : 0);
+
+ SCVAL(pdata,1,perms);
+
+ switch (tagtype) {
+ case SMB_ACL_USER_OBJ:
+ SCVAL(pdata,0,SMB_POSIX_ACL_USER_OBJ);
+ own_grp = (unsigned int)pst->st_uid;
+ SIVAL(pdata,2,own_grp);
+ SIVAL(pdata,6,0);
+ break;
+ case SMB_ACL_USER:
+ {
+ uid_t *puid = (uid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
+ if (!puid) {
+ DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
+ }
+ own_grp = (unsigned int)*puid;
+ SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)puid,tagtype);
+ SCVAL(pdata,0,SMB_POSIX_ACL_USER);
+ SIVAL(pdata,2,own_grp);
+ SIVAL(pdata,6,0);
+ break;
+ }
+ case SMB_ACL_GROUP_OBJ:
+ SCVAL(pdata,0,SMB_POSIX_ACL_GROUP_OBJ);
+ own_grp = (unsigned int)pst->st_gid;
+ SIVAL(pdata,2,own_grp);
+ SIVAL(pdata,6,0);
+ break;
+ case SMB_ACL_GROUP:
+ {
+ gid_t *pgid= (gid_t *)SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry);
+ if (!pgid) {
+ DEBUG(0,("marshall_posix_acl: SMB_VFS_SYS_ACL_GET_QUALIFIER failed.\n"));
+ }
+ own_grp = (unsigned int)*pgid;
+ SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, (void *)pgid,tagtype);
+ SCVAL(pdata,0,SMB_POSIX_ACL_GROUP);
+ SIVAL(pdata,2,own_grp);
+ SIVAL(pdata,6,0);
+ break;
+ }
+ case SMB_ACL_MASK:
+ SCVAL(pdata,0,SMB_POSIX_ACL_MASK);
+ SIVAL(pdata,2,0xFFFFFFFF);
+ SIVAL(pdata,6,0xFFFFFFFF);
+ break;
+ case SMB_ACL_OTHER:
+ SCVAL(pdata,0,SMB_POSIX_ACL_OTHER);
+ SIVAL(pdata,2,0xFFFFFFFF);
+ SIVAL(pdata,6,0xFFFFFFFF);
+ break;
+ default:
+ DEBUG(0,("marshall_posix_acl: unknown tagtype.\n"));
+ return False;
+ }
+ pdata += SMB_POSIX_ACL_ENTRY_SIZE;
+ }
+
+ return True;
+}
+
/****************************************************************************
Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
file name or file id).
****************************************************************************/
-static int call_trans2qfilepathinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
uint16 tran_call = SVAL(inbuf, smb_setup0);
fullpathname = fname;
file_size = get_file_size(sbuf);
allocation_size = get_allocation_size(fsp,&sbuf);
- if (mode & aDIR)
+ if (mode & aDIR) {
+ /* This is necessary, as otherwise the desktop.ini file in
+ * this folder is ignored */
+ mode |= (lp_profile_acls(SNUM(conn)) ? aRONLY : 0);
file_size = 0;
+ }
params = SMB_REALLOC(*pparams,2);
if (params == NULL)
c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ if (fsp && fsp->pending_modtime) {
+ /* the pending modtime overrides the current modtime */
+ sbuf.st_mtime = fsp->pending_modtime;
+ }
+
if (lp_dos_filetime_resolution(SNUM(conn))) {
c_time &= ~1;
sbuf.st_atime &= ~1;
break;
}
+ case SMB_QUERY_POSIX_ACL:
+ {
+ SMB_ACL_T file_acl = NULL;
+ SMB_ACL_T def_acl = NULL;
+ uint16 num_file_acls = 0;
+ uint16 num_def_acls = 0;
+
+ if (fsp && !fsp->is_directory && (fsp->fd != -1)) {
+ file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, fsp->fd);
+ } else {
+ file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS);
+ }
+
+ if (file_acl == NULL && no_acl_syscall_error(errno)) {
+ DEBUG(5,("call_trans2qfilepathinfo: ACLs not implemented on filesystem containing %s\n",
+ fname ));
+ return ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
+ }
+
+ if (S_ISDIR(sbuf.st_mode)) {
+ if (fsp && fsp->is_directory) {
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fsp->fsp_name, SMB_ACL_TYPE_DEFAULT);
+ } else {
+ def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_DEFAULT);
+ }
+ def_acl = free_empty_sys_acl(conn, def_acl);
+ }
+
+ num_file_acls = count_acl_entries(conn, file_acl);
+ num_def_acls = count_acl_entries(conn, def_acl);
+
+ if ( data_size < (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE) {
+ DEBUG(5,("call_trans2qfilepathinfo: data_size too small (%u) need %u\n",
+ data_size,
+ (unsigned int)((num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE +
+ SMB_POSIX_ACL_HEADER_SIZE) ));
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
+ return ERROR_NT(NT_STATUS_BUFFER_TOO_SMALL);
+ }
+
+ SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
+ SSVAL(pdata,2,num_file_acls);
+ SSVAL(pdata,4,num_def_acls);
+ if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
+ return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
+ }
+ if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
+ return ERROR_NT(NT_STATUS_INTERNAL_ERROR);
+ }
+
+ if (file_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
+ }
+ if (def_acl) {
+ SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl);
+ }
+ data_size = (num_file_acls + num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE + SMB_POSIX_ACL_HEADER_SIZE;
+ break;
+ }
+
default:
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
Reply to a TRANS2_SETFILEINFO (set file info by fileid).
****************************************************************************/
-static int call_trans2setfilepathinfo(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
char *pdata = *ppdata;
SSVAL(params,0,0);
- if (fsp) {
+ if (fsp && fsp->pending_modtime) {
/* the pending modtime overrides the current modtime */
sbuf.st_mtime = fsp->pending_modtime;
}
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);
}
+
+ case SMB_SET_POSIX_ACL:
+ {
+ uint16 posix_acl_version;
+ uint16 num_file_acls;
+ uint16 num_def_acls;
+ BOOL valid_file_acls = True;
+ BOOL valid_def_acls = True;
+
+ if (total_data < SMB_POSIX_ACL_HEADER_SIZE) {
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ }
+ posix_acl_version = SVAL(pdata,0);
+ num_file_acls = SVAL(pdata,2);
+ num_def_acls = SVAL(pdata,4);
+
+ if (num_file_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
+ valid_file_acls = False;
+ num_file_acls = 0;
+ }
+
+ if (num_def_acls == SMB_POSIX_IGNORE_ACE_ENTRIES) {
+ valid_def_acls = False;
+ num_def_acls = 0;
+ }
+
+ if (posix_acl_version != SMB_POSIX_ACL_VERSION) {
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ }
+
+ if (total_data < SMB_POSIX_ACL_HEADER_SIZE +
+ (num_file_acls+num_def_acls)*SMB_POSIX_ACL_ENTRY_SIZE) {
+ return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+ }
+
+ if (valid_file_acls && !set_unix_posix_acl(conn, fsp, fname, num_file_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE)) {
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ if (valid_def_acls && !set_unix_posix_default_acl(conn, fname, &sbuf, num_def_acls,
+ pdata + SMB_POSIX_ACL_HEADER_SIZE +
+ (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE))) {
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ SSVAL(params,0,0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ return(-1);
+ }
+
default:
return ERROR_DOS(ERRDOS,ERRunknownlevel);
}
if(fsp != NULL) {
/*
* This was a setfileinfo on an open file.
- * NT does this a lot. It's actually pointless
- * setting the time here, as it will be overwritten
- * on the next write, so we save the request
- * away and will set it on file close. JRA.
+ * NT does this a lot. We also need to
+ * set the time here, as it can be read by
+ * FindFirst/FindNext and with the patch for bug #2045
+ * in smbd/fileio.c it ensures that this timestamp is
+ * kept sticky even after a write. We save the request
+ * away and will set it on file close and after a write. JRA.
*/
if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
fsp->pending_modtime = tvs.modtime;
}
- } else {
-
DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
- if(file_utime(conn, fname, &tvs)!=0)
+ if(file_utime(conn, fname, &tvs)!=0) {
return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
}
}
DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n", fname, dosmode ));
- if(file_set_dosmode(conn, fname, dosmode, NULL)) {
+ if(file_set_dosmode(conn, fname, dosmode, &sbuf, False)) {
DEBUG(2,("file_set_dosmode of %s failed (%s)\n", fname, strerror(errno)));
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
Reply to a TRANS2_MKDIR (make directory with extended attributes).
****************************************************************************/
-static int call_trans2mkdir(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
pstring directory;
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
}
if (check_name(directory,conn))
- ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
+ ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory,True));
if(ret < 0) {
DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
We don't actually do this - we just send a null response.
****************************************************************************/
-static int call_trans2findnotifyfirst(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
static uint16 fnf_handle = 257;
char *params = *pparams;
changes). Currently this does nothing.
****************************************************************************/
-static int call_trans2findnotifynext(connection_struct *conn,
- char *inbuf, char *outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
Reply to a TRANS2_GET_DFS_REFERRAL - Shirish Kalele <kalele@veritas.com>.
****************************************************************************/
-static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf,
- char* outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *params = *pparams;
pstring pathname;
Reply to a TRANS2_IOCTL - used for OS/2 printing.
****************************************************************************/
-static int call_trans2ioctl(connection_struct *conn, char* inbuf,
- char* outbuf, int length, int bufsize,
- char **pparams, int total_params, char **ppdata, int total_data)
+static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf, int length, int bufsize,
+ char **pparams, int total_params, char **ppdata, int total_data,
+ unsigned int max_data_bytes)
{
char *pdata = *ppdata;
files_struct *fsp = file_fsp(inbuf,smb_vwv15);
int outsize = 0;
unsigned int total_params = SVAL(inbuf, smb_tpscnt);
unsigned int total_data =SVAL(inbuf, smb_tdscnt);
+ unsigned int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
#if 0
unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
- unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
BOOL close_tid = BITSETW(inbuf+smb_flags,0);
BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
goto bad_param;
if (num_params) {
- if (param_disp + num_params >= total_params)
+ if (param_disp + num_params > total_params)
goto bad_param;
if ((param_disp + num_params < param_disp) ||
(param_disp + num_params < num_params))
memcpy( ¶ms[param_disp], smb_base(inbuf) + param_off, num_params);
}
if (num_data) {
- if (data_disp + num_data >= total_data)
+ if (data_disp + num_data > total_data)
goto bad_param;
if ((data_disp + num_data < data_disp) ||
(data_disp + num_data < num_data))
case TRANSACT2_OPEN:
START_PROFILE_NESTED(Trans2_open);
outsize = call_trans2open(conn, inbuf, outbuf, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_open);
break;
case TRANSACT2_FINDFIRST:
START_PROFILE_NESTED(Trans2_findfirst);
outsize = call_trans2findfirst(conn, inbuf, outbuf, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_findfirst);
break;
case TRANSACT2_FINDNEXT:
START_PROFILE_NESTED(Trans2_findnext);
outsize = call_trans2findnext(conn, inbuf, outbuf, length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_findnext);
break;
case TRANSACT2_QFSINFO:
START_PROFILE_NESTED(Trans2_qfsinfo);
outsize = call_trans2qfsinfo(conn, inbuf, outbuf, length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_qfsinfo);
break;
case TRANSACT2_SETFSINFO:
START_PROFILE_NESTED(Trans2_setfsinfo);
outsize = call_trans2setfsinfo(conn, inbuf, outbuf, length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_setfsinfo);
break;
#endif
case TRANSACT2_QFILEINFO:
START_PROFILE_NESTED(Trans2_qpathinfo);
outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf, length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_qpathinfo);
break;
case TRANSACT2_SETPATHINFO:
case TRANSACT2_SETFILEINFO:
START_PROFILE_NESTED(Trans2_setpathinfo);
outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf, length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_setpathinfo);
break;
case TRANSACT2_FINDNOTIFYFIRST:
START_PROFILE_NESTED(Trans2_findnotifyfirst);
outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf, length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_findnotifyfirst);
break;
case TRANSACT2_FINDNOTIFYNEXT:
START_PROFILE_NESTED(Trans2_findnotifynext);
outsize = call_trans2findnotifynext(conn, inbuf, outbuf, length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_findnotifynext);
break;
case TRANSACT2_MKDIR:
START_PROFILE_NESTED(Trans2_mkdir);
outsize = call_trans2mkdir(conn, inbuf, outbuf, length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_mkdir);
break;
case TRANSACT2_GET_DFS_REFERRAL:
START_PROFILE_NESTED(Trans2_get_dfs_referral);
outsize = call_trans2getdfsreferral(conn,inbuf,outbuf,length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_get_dfs_referral);
break;
case TRANSACT2_IOCTL:
START_PROFILE_NESTED(Trans2_ioctl);
outsize = call_trans2ioctl(conn,inbuf,outbuf,length, bufsize,
- ¶ms, total_params, &data, total_data);
+ ¶ms, total_params, &data, total_data, max_data_bytes);
END_PROFILE_NESTED(Trans2_ioctl);
break;
default:
DIR *result;
START_PROFILE(syscall_opendir);
- result = opendir(fname);
+ result = sys_opendir(fname);
END_PROFILE(syscall_opendir);
return result;
}
-struct dirent *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
{
- struct dirent *result;
+ SMB_STRUCT_DIRENT *result;
START_PROFILE(syscall_readdir);
- result = readdir(dirp);
+ result = sys_readdir(dirp);
END_PROFILE(syscall_readdir);
return result;
}
+void vfswrap_seekdir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp, long offset)
+{
+ START_PROFILE(syscall_seekdir);
+ sys_seekdir(dirp, offset);
+ END_PROFILE(syscall_seekdir);
+}
+
+long vfswrap_telldir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ long result;
+ START_PROFILE(syscall_telldir);
+ result = sys_telldir(dirp);
+ END_PROFILE(syscall_telldir);
+ return result;
+}
+
+void vfswrap_rewinddir(vfs_handle_struct *handle, connection_struct *conn, DIR *dirp)
+{
+ START_PROFILE(syscall_rewinddir);
+ sys_rewinddir(dirp);
+ END_PROFILE(syscall_rewinddir);
+}
+
int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
{
int result;
int result;
START_PROFILE(syscall_closedir);
- result = closedir(dirp);
+ result = sys_closedir(dirp);
END_PROFILE(syscall_closedir);
return result;
}
vfswrap_opendir,
vfswrap_readdir,
+ vfswrap_seekdir,
+ vfswrap_telldir,
+ vfswrap_rewinddir,
vfswrap_mkdir,
vfswrap_rmdir,
vfswrap_closedir,
char *vfs_readdirname(connection_struct *conn, void *p)
{
- struct dirent *ptr= NULL;
+ SMB_STRUCT_DIRENT *ptr= NULL;
char *dname;
if (!p)
return(NULL);
- ptr = (struct dirent *)SMB_VFS_READDIR(conn,p);
+ ptr = SMB_VFS_READDIR(conn,p);
if (!ptr)
return(NULL);
}
default:
DEBUG(1,("reduce_name: couldn't get realpath for %s\n", fname));
- errno = saved_errno;
+ /* Don't restore the saved errno. We need to return the error that
+ realpath caused here as it was not one of the cases we handle. JRA. */
return False;
}
}
DEBUG(4,(" tconx ok\n"));
- srv = (struct smbw_server *)malloc(sizeof(*srv));
+ srv = SMB_MALLOC_P(struct smbw_server);
if (!srv) {
errno = ENOMEM;
goto failed;
srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
- srv->server_name = strdup(server);
+ srv->server_name = SMB_STRDUP(server);
if (!srv->server_name) {
errno = ENOMEM;
goto failed;
}
- srv->share_name = strdup(share);
+ srv->share_name = SMB_STRDUP(share);
if (!srv->share_name) {
errno = ENOMEM;
goto failed;
}
- srv->workgroup = strdup(workgroup);
+ srv->workgroup = SMB_STRDUP(workgroup);
if (!srv->workgroup) {
errno = ENOMEM;
goto failed;
}
- srv->username = strdup(username);
+ srv->username = SMB_STRDUP(username);
if (!srv->username) {
errno = ENOMEM;
goto failed;
return fd;
}
- file = (struct smbw_file *)malloc(sizeof(*file));
+ file = SMB_MALLOC_P(struct smbw_file);
if (!file) {
errno = ENOMEM;
goto failed;
ZERO_STRUCTP(file);
- file->f = (struct smbw_filedes *)malloc(sizeof(*(file->f)));
+ file->f = SMB_MALLOC_P(struct smbw_filedes);
if (!file->f) {
errno = ENOMEM;
goto failed;
ZERO_STRUCTP(file->f);
file->f->cli_fd = fd;
- file->f->fname = strdup(path);
+ file->f->fname = SMB_STRDUP(path);
if (!file->f->fname) {
errno = ENOMEM;
goto failed;
goto failed;
}
- file2 = (struct smbw_file *)malloc(sizeof(*file2));
+ file2 = SMB_MALLOC_P(struct smbw_file);
if (!file2) {
close(fd2);
errno = ENOMEM;
goto failed;
}
- file2 = (struct smbw_file *)malloc(sizeof(*file2));
+ file2 = SMB_MALLOC_P(struct smbw_file);
if (!file2) {
close(fd2);
errno = ENOMEM;
struct name_list **name_list = (struct name_list **)state;
struct name_list *new_name;
- new_name = (struct name_list *)malloc(sizeof(struct name_list));
+ new_name = SMB_MALLOC_P(struct name_list);
if (!new_name) return;
ZERO_STRUCTP(new_name);
- new_name->name = strdup(name);
+ new_name->name = SMB_STRDUP(name);
new_name->stype = stype;
- new_name->comment = strdup(comment);
+ new_name->comment = SMB_STRDUP(comment);
DLIST_ADD(*name_list, new_name);
}
/* No names cached for this workgroup */
if (names == NULL) {
- new_names = (struct cached_names *)
- malloc(sizeof(struct cached_names));
+ new_names = SMB_MALLOC_P(struct cached_names);
ZERO_STRUCTP(new_names);
DLIST_ADD(cached_names, new_names);
new_names->cache_timeout = now;
new_names->result = result;
- new_names->key = strdup(key);
+ new_names->key = SMB_STRDUP(key);
names = new_names;
}
/* No names cached for this server */
if (names == NULL) {
- new_names = (struct cached_names *)
- malloc(sizeof(struct cached_names));
+ new_names = SMB_MALLOC_P(struct cached_names);
ZERO_STRUCTP(new_names);
DLIST_ADD(cached_names, new_names);
&new_names->name_list);
new_names->cache_timeout = now;
- new_names->key = strdup(key);
+ new_names->key = SMB_STRDUP(key);
names = new_names;
}
}
vfs->files[fd] = (struct files_struct *)malloc(sizeof(struct files_struct));
- vfs->files[fd]->fsp_name = strdup(argv[1]);
+ vfs->files[fd]->fsp_name = SMB_STRDUP(argv[1]);
vfs->files[fd]->fd = fd;
vfs->files[fd]->conn = vfs->conn;
printf("open: fd=%d\n", fd);
int shmid;
void *ret;
- shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
+ shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
if (shmid == -1) {
printf("can't get shared memory\n");
exit(1);
lock_timeout = (1 + (random() % 20));
printf("Testing lock timeout with timeout=%u\n", lock_timeout);
t1 = time(NULL);
- if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 500, WRITE_LOCK)) {
+ if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
printf("lock3 succeeded! This is a locking bug\n");
return False;
} else {
*************************************************************************/
+#ifdef STANDALONE
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#define False 0
#define True 1
+#else /* STANDALAONE */
+#include "includes.h"
+#endif /* STANDALONE */
+
#define REG_KEY_LIST_SIZE 10
/*
return 0;
}
- new_path = (char *)malloc(path_len + 1 + strlen(key_tree->name) + 1);
+ new_path = (char *)SMB_MALLOC(path_len + 1 + strlen(key_tree->name) + 1);
if (!new_path) return 0; /* Errors? */
new_path[0] = '\0';
strcat(new_path, path);
if (!tree || !key || !*key) return NULL;
- lname = strdup(key);
+ lname = SMB_STRDUP(key);
if (!lname) return NULL;
/*
return (void *)val;
case REG_TYPE_DWORD:
- dwordp = (unsigned int *)malloc(sizeof(unsigned int));
+ dwordp = SMB_MALLOC_P(unsigned int);
if (!dwordp) return NULL;
/* Allow for ddddd and 0xhhhhh and 0ooooo */
if (strncmp(val, "0x", 2) == 0 || strncmp(val, "0X", 2) == 0) {
* If we get here, the name was not found, so insert it
*/
- tmp = (VAL_KEY *)malloc(sizeof(VAL_KEY));
+ tmp = SMB_MALLOC_P(VAL_KEY);
if (!tmp) goto error;
memset(tmp, 0, sizeof(VAL_KEY));
- tmp->name = strdup(name);
+ tmp->name = SMB_STRDUP(name);
tmp->has_name = True;
if (!tmp->name) goto error;
tmp->data_type = type;
* Allocate some more space
*/
- if ((key->values = (VAL_LIST *)realloc(key->values, sizeof(VAL_LIST) +
+ if ((key->values = (VAL_LIST *)SMB_REALLOC_ARRAY(key->values, sizeof(VAL_LIST) +
key->values->val_count - 1 +
REG_KEY_LIST_SIZE))) {
key->values->max_vals += REG_KEY_LIST_SIZE;
int i = 0, auth;
const char *lstr;
- *sid = (sid_t *)malloc(sizeof(sid_t));
+ *sid = SMB_MALLOC_P(sid_t);
if (!*sid) return 0;
memset(*sid, 0, sizeof(sid_t));
{
ACE *ace;
- ace = (ACE *)malloc(sizeof(ACE));
+ ace = SMB_MALLOC_P(ACE);
if (!ace) goto error;
ace->type = type;
ace->flags = flags;
{
ACL *acl;
- acl = (ACL *)malloc(sizeof(ACL) + 7*sizeof(ACE *));
+ acl = (ACL *)SMB_MALLOC(sizeof(ACL) + 7*sizeof(ACE *));
if (!acl) goto error;
acl->rev = 2;
{
SEC_DESC *tmp;
- tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC));
+ tmp = SMB_MALLOC_P(SEC_DESC);
if (!tmp) return NULL;
tmp->rev = 1;
{
KEY_SEC_DESC *tsec = NULL;
- tsec = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
+ tsec = SMB_MALLOC_P(KEY_SEC_DESC);
if (!tsec) return NULL;
tsec->ref_cnt = 1;
list = key->sub_keys;
if (!list) { /* Create an empty list */
- list = (KEY_LIST *)malloc(sizeof(KEY_LIST) + (REG_KEY_LIST_SIZE - 1) * sizeof(REG_KEY *));
+ list = (KEY_LIST *)SMB_MALLOC(sizeof(KEY_LIST) + (REG_KEY_LIST_SIZE - 1) * sizeof(REG_KEY *));
list->key_count = 0;
list->max_keys = REG_KEY_LIST_SIZE;
}
- lname = strdup(name);
+ lname = SMB_STRDUP(name);
if (!lname) return NULL;
c1 = lname;
list->key_count++;
}
else { /* Create more space in the list ... */
- if (!(list = (KEY_LIST *)realloc(list, sizeof(KEY_LIST) +
+ if (!(list = (KEY_LIST *)SMB_REALLOC(list, sizeof(KEY_LIST) +
(list->max_keys + REG_KEY_LIST_SIZE - 1)
* sizeof(REG_KEY *))))
goto error;
* We want to create the key, and then do the rest
*/
- tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
+ tmp = SMB_MALLOC_P(REG_KEY);
memset(tmp, 0, sizeof(REG_KEY));
- tmp->name = strdup(c1);
+ tmp->name = SMB_STRDUP(c1);
if (!tmp->name) goto error;
tmp->owner = key;
tmp->type = REG_SUB_KEY;
*/
if (!regf || !name || !*name) return NULL;
- lname = strdup(name);
+ lname = SMB_STRDUP(name);
if (!lname) return NULL;
c1 = lname;
if (!regf->root) {
- tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
+ tmp = SMB_MALLOC_P(REG_KEY);
if (!tmp) goto error;
memset(tmp, 0, sizeof(REG_KEY));
- tmp->name = strdup(c1);
+ tmp->name = SMB_STRDUP(c1);
if (!tmp->name) goto error;
tmp->security = nt_create_init_sec(regf);
if (!tmp->security) goto error;
static
int nt_set_regf_input_file(REGF *regf, char *filename)
{
- return ((regf->regfile_name = strdup(filename)) != NULL);
+ return ((regf->regfile_name = SMB_STRDUP(filename)) != NULL);
}
static
int nt_set_regf_output_file(REGF *regf, char *filename)
{
- return ((regf->outfile_name = strdup(filename)) != NULL);
+ return ((regf->outfile_name = SMB_STRDUP(filename)) != NULL);
}
/* Create a regf structure and init it */
static
REGF *nt_create_regf(void)
{
- REGF *tmp = (REGF *)malloc(sizeof(REGF));
+ REGF *tmp = SMB_MALLOC_P(REGF);
if (!tmp) return tmp;
memset(tmp, 0, sizeof(REGF));
tmp->owner_sid_str = def_owner_sid_str;
SK_MAP *alloc_sk_map_entry(REGF *regf, KEY_SEC_DESC *tmp, int sk_off)
{
if (!regf->sk_map) { /* Allocate a block of 10 */
- regf->sk_map = (SK_MAP *)malloc(sizeof(SK_MAP) * 10);
+ regf->sk_map = SMB_MALLOC_ARRAY(SK_MAP, 10);
if (!regf->sk_map) {
free(tmp);
return NULL;
else { /* Simply allocate a new slot, unless we have to expand the list */
int ndx = regf->sk_count;
if (regf->sk_count >= regf->sk_map_size) {
- regf->sk_map = (SK_MAP *)realloc(regf->sk_map,
+ regf->sk_map = (SK_MAP *)SMB_REALLOC(regf->sk_map,
(regf->sk_map_size + 10)*sizeof(SK_MAP));
if (!regf->sk_map) {
free(tmp);
return tmp;
}
else { /* Allocate a new one */
- tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
+ tmp = SMB_MALLOC_P(KEY_SEC_DESC);
if (!tmp) {
return NULL;
}
static
sid_t *dup_sid(sid_t *sid)
{
- sid_t *tmp = (sid_t *)malloc(sizeof(sid_t));
+ sid_t *tmp = SMB_MALLOC_P(sid_t);
int i;
if (!tmp) return NULL;
{
ACE *tmp = NULL;
- tmp = (ACE *)malloc(sizeof(ACE));
+ tmp = SMB_MALLOC_P(ACE);
if (!tmp) return NULL;
num_aces = IVAL(&acl->num_aces);
- tmp = (ACL *)malloc(sizeof(ACL) + (num_aces - 1)*sizeof(ACE *));
+ tmp = (ACL *)SMB_MALLOC(sizeof(ACL) + (num_aces - 1)*sizeof(ACE *));
if (!tmp) return NULL;
tmp->num_aces = num_aces;
{
SEC_DESC *tmp = NULL;
- tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC));
+ tmp = SMB_MALLOC_P(SEC_DESC);
if (!tmp) {
return NULL;
*/
if (!tmp) {
- tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
+ tmp = SMB_MALLOC_P(KEY_SEC_DESC);
if (!tmp) return NULL;
memset(tmp, 0, sizeof(KEY_SEC_DESC));
dat_len = IVAL(&vk_hdr->dat_len); /* If top bit, offset contains data */
dat_off = IVAL(&vk_hdr->dat_off);
- tmp = (VAL_KEY *)malloc(sizeof(VAL_KEY));
+ tmp = SMB_MALLOC_P(VAL_KEY);
if (!tmp) {
goto error;
}
if (flag & 0x01) {
strncpy(val_name, vk_hdr->dat_name, nam_len);
- tmp->name = strdup(val_name);
+ tmp->name = SMB_STRDUP(val_name);
if (!tmp->name) {
goto error;
}
if (dat_len) {
- char *dtmp = (char *)malloc(dat_len&0x7FFFFFFF);
+ char *dtmp = (char *)SMB_MALLOC(dat_len&0x7FFFFFFF);
if (!dtmp) {
goto error;
return NULL;
}
- tmp = (VAL_LIST *)malloc(sizeof(VAL_LIST) + (count - 1) * sizeof(VAL_KEY *));
+ tmp = (VAL_LIST *)SMB_MALLOC(sizeof(VAL_LIST) + (count - 1) * sizeof(VAL_KEY *));
if (!tmp) {
goto error;
}
/* Now, we should allocate a KEY_LIST struct and fill it in ... */
- tmp = (KEY_LIST *)malloc(sizeof(KEY_LIST) + (count - 1) * sizeof(REG_KEY *));
+ tmp = (KEY_LIST *)SMB_MALLOC(sizeof(KEY_LIST) + (count - 1) * sizeof(REG_KEY *));
if (!tmp) {
goto error;
}
assert(name_len < sizeof(key_name));
/* Allocate the key struct now */
- tmp = (REG_KEY *)malloc(sizeof(REG_KEY));
+ tmp = SMB_MALLOC_P(REG_KEY);
if (!tmp) return tmp;
memset(tmp, 0, sizeof(REG_KEY));
if (verbose) fprintf(stdout, "Key name: %s\n", key_name);
- tmp->name = strdup(key_name);
+ tmp->name = SMB_STRDUP(key_name);
if (!tmp->name) {
goto error;
}
* XXX: FIXME
*/
- tmp->class_name = strdup(cls_name);
+ tmp->class_name = SMB_STRDUP(cls_name);
if (!tmp->class_name) {
goto error;
}
size = (size + (REGF_HDR_BLKSIZ - 1)) & ~(REGF_HDR_BLKSIZ - 1);
- tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK));
+ tmp = (HBIN_BLK *)SMB_MALLOC_P(HBIN_BLK);
memset(tmp, 0, sizeof(HBIN_BLK));
- tmp->data = malloc(size);
+ tmp->data = SMB_MALLOC(size);
if (!tmp->data) goto error;
memset(tmp->data, 0, size); /* Make it pristine */
{
HBIN_BLK *tmp = NULL;
- tmp = (HBIN_BLK *)malloc(sizeof(HBIN_BLK));
+ tmp = SMB_MALLOC_P(HBIN_BLK);
if (!tmp) return 0;
memset(tmp, 0, sizeof(HBIN_BLK));
tmp->type = REG_OUTBLK_HDR;
tmp->size = REGF_HDR_BLKSIZ;
- tmp->data = malloc(REGF_HDR_BLKSIZ);
+ tmp->data = SMB_MALLOC(REGF_HDR_BLKSIZ);
if (!tmp->data) goto error;
memset(tmp->data, 0, REGF_HDR_BLKSIZ); /* Make it pristine, unlike Windows */
if (!cl) return;
- if ((pl = malloc(cl->line_len + 1)) == NULL) {
+ if ((pl = SMB_MALLOC(cl->line_len + 1)) == NULL) {
fprintf(stderr, "Unable to allocate space to print line: %s\n",
strerror(errno));
exit(1);
static
struct cmd_line *get_cmd_line(int fd)
{
- struct cmd_line *cl = (CMD_LINE *)malloc(sizeof(CMD_LINE));
+ struct cmd_line *cl = SMB_MALLOC_P(CMD_LINE);
int i = 0, rc;
unsigned char ch;
* Allocate some space for the line. We extend later if needed.
*/
- if ((cl->line = (char *)malloc(INIT_ALLOC)) == NULL) {
+ if ((cl->line = (char *)SMB_MALLOC(INIT_ALLOC)) == NULL) {
fprintf(stderr, "Unable to allocate initial space for line: %s\n",
strerror(errno));
exit(1);
/*
* Allocate some more memory
*/
- if ((cl->line = realloc(cl->line, cl->len + INIT_ALLOC)) == NULL) {
+ if ((cl->line = SMB_REALLOC(cl->line, cl->len + INIT_ALLOC)) == NULL) {
fprintf(stderr, "Unable to realloc space for line: %s\n",
strerror(errno));
exit(1);
char *dup_str(char *s, int len)
{
char *nstr;
- nstr = (char *)malloc(len + 1);
+ nstr = (char *)SMB_MALLOC(len + 1);
if (nstr) {
memcpy(nstr, s, len);
nstr[len] = 0;
start = 2;
*cmd = CMD_DEL_KEY;
}
- tmp = malloc(cl->line_len - 1 - start + 1);
+ tmp = SMB_MALLOC(cl->line_len - 1 - start + 1);
if (!tmp) return tmp; /* Bail out on no mem ... FIXME */
strncpy(tmp, &cl->line[start], cl->line_len - 1 - start);
tmp[cl->line_len - 1 - start] = 0;
struct cmd_line *cl = NULL;
struct val_spec_list *vl = NULL;
- if ((cmd = (struct command_s *)malloc(sizeof(struct command_s))) == NULL) {
+ if ((cmd = SMB_MALLOC_P(struct command_s)) == NULL) {
fprintf(stderr, "Unable to malloc space for command: %s\n",
strerror(errno));
exit(1);
* There could be a \ on the end which we need to
* handle at some time
*/
- vl = (struct val_spec_list *)malloc(sizeof(struct val_spec_list));
+ vl = SMB_MALLOC_P(struct val_spec_list);
if (!vl) goto error;
vl->next = NULL;
vl->val = NULL;
return NULL;
}
- tmp = (CMD_FILE *)malloc(sizeof(CMD_FILE));
+ tmp = SMB_MALLOC_P(CMD_FILE);
if (!tmp) {
return NULL;
}
* Let's fill in some of the fields;
*/
- tmp->name = strdup(file);
+ tmp->name = SMB_STRDUP(file);
if ((tmp->fd = open(file, O_RDONLY, 666)) < 0) {
free(tmp);
break;
case 'O':
- def_owner_sid_str = strdup(optarg);
+ def_owner_sid_str = SMB_STRDUP(optarg);
regf_opt += 2;
if (!sid_string_to_sid(&lsid, def_owner_sid_str)) {
fprintf(stderr, "Default Owner SID: %s is incorrectly formatted\n",
int i;
fstring ntgroup = "";
fstring sid_string = "";
+
+ if (opt_verbose || opt_long_list_entries)
+ long_list = True;
/* get the options */
for ( i=0; i<argc; i++ ) {
return -1;
}
- if (!pdb_enum_alias_memberships(&member, &aliases, &num)) {
+ if (!pdb_enum_alias_memberships(&member, 1, &aliases, &num)) {
d_printf("Could not list memberships for sid %s: %s\n",
argv[0], nt_errstr(result));
return -1;
net_common_flags_usage(argc, argv);
d_printf("\t-C or --comment=<comment>\tdescriptive comment (for add only)\n");
d_printf("\t-c or --container=<container>\tLDAP container, defaults to cn=Users (for add in ADS only)\n");
+ d_printf("\t-L or --localgroup\t\tWhen adding groups, create a local group (alias)\n");
return -1;
}
return NT_STATUS_IS_OK(net_idmap_fixup_hwm()) ? 0 : -1;
}
+/***********************************************************
+ Delete a SID mapping from a winbindd_idmap.tdb
+ **********************************************************/
+static int net_idmap_delete(int argc, const char **argv)
+{
+ TDB_CONTEXT *idmap_tdb;
+ TDB_DATA key, data;
+ fstring sid;
+
+ if (argc != 2)
+ return net_help_idmap(argc, argv);
+
+ idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDWR, 0);
+
+ if (idmap_tdb == NULL) {
+ d_printf("Could not open idmap: %s\n", argv[0]);
+ return -1;
+ }
+
+ fstrcpy(sid, argv[1]);
+
+ if (strncmp(sid, "S-1-5-", strlen("S-1-5-")) != 0) {
+ d_printf("Can only delete SIDs, %s is does not start with "
+ "S-1-5-\n", sid);
+ return -1;
+ }
+
+ key.dptr = sid;
+ key.dsize = strlen(key.dptr)+1;
+
+ data = tdb_fetch(idmap_tdb, key);
+
+ if (data.dptr == NULL) {
+ d_printf("Could not find sid %s\n", argv[1]);
+ return -1;
+ }
+
+ if (tdb_delete(idmap_tdb, key) != 0) {
+ d_printf("Could not delete key %s\n", argv[1]);
+ return -1;
+ }
+
+ if (tdb_delete(idmap_tdb, data) != 0) {
+ d_printf("Could not delete key %s\n", data.dptr);
+ return -1;
+ }
+
+ return 0;
+}
+
+
int net_help_idmap(int argc, const char **argv)
{
d_printf("net idmap dump filename"\
d_printf("net idmap restore"\
"\n Restore entries from stdin to current local idmap\n");
+ /* Deliberately *not* document net idmap delete */
+
return -1;
}
struct functable func[] = {
{"dump", net_idmap_dump},
{"restore", net_idmap_restore},
+ {"delete", net_idmap_delete},
{"help", net_help_idmap},
{NULL, NULL}
};
result = cli_shutdown_abort(cli, mem_ctx);
- if (NT_STATUS_IS_OK(result))
+ if (NT_STATUS_IS_OK(result)) {
+ d_printf("\nShutdown successfully aborted\n");
DEBUG(5,("cmd_shutdown_abort: query succeeded\n"));
- else
+ } else
DEBUG(5,("cmd_shutdown_abort: query failed\n"));
return result;
result = cli_reg_abort_shutdown(cli, mem_ctx);
- if (NT_STATUS_IS_OK(result))
+ if (NT_STATUS_IS_OK(result)) {
+ d_printf("\nShutdown successfully aborted\n");
DEBUG(5,("cmd_reg_abort_shutdown: query succeeded\n"));
- else
+ } else
DEBUG(5,("cmd_reg_abort_shutdown: query failed\n"));
return result;
}
/**
- * Shut down a remote RPC Server
+ * Shut down a remote RPC Server via initshutdown pipe
*
* All parameters are provided by the run_rpc_command function, except for
* argc, argv which are passes through.
* @return Normal NTSTATUS return.
**/
-static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid,
- const char *domain_name,
- struct cli_state *cli, TALLOC_CTX *mem_ctx,
- int argc, const char **argv)
+static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
+{
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ const char *msg = "This machine will be shutdown shortly";
+ uint32 timeout = 20;
+
+ if (opt_comment) {
+ msg = opt_comment;
+ }
+ if (opt_timeout) {
+ timeout = opt_timeout;
+ }
+
+ /* create an entry */
+ result = cli_shutdown_init(cli, mem_ctx, msg, timeout, opt_reboot,
+ opt_force);
+
+ if (NT_STATUS_IS_OK(result)) {
+ d_printf("\nShutdown of remote machine succeeded\n");
+ DEBUG(5,("Shutdown of remote machine succeeded\n"));
+ } else
+ DEBUG(0,("Shutdown of remote machine failed!\n"));
+
+ return result;
+}
+
+/**
+ * Shut down a remote RPC Server via winreg pipe
+ *
+ * All parameters are provided by the run_rpc_command function, except for
+ * argc, argv which are passes through.
+ *
+ * @param domain_sid The domain sid aquired from the remote server
+ * @param cli A cli_state connected to the server.
+ * @param mem_ctx Talloc context, destoyed on compleation of the function.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped
+ *
+ * @return Normal NTSTATUS return.
+ **/
+
+static NTSTATUS rpc_reg_shutdown_internals(const DOM_SID *domain_sid,
+ const char *domain_name,
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ int argc, const char **argv)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
const char *msg = "This machine will be shutdown shortly";
/* create an entry */
result = cli_reg_shutdown(cli, mem_ctx, msg, timeout, opt_reboot, opt_force);
- if (NT_STATUS_IS_OK(result))
+ if (NT_STATUS_IS_OK(result)) {
+ d_printf("\nShutdown of remote machine succeeded\n");
DEBUG(5,("Shutdown of remote machine succeeded\n"));
+ }
else
DEBUG(0,("Shutdown of remote machine failed!\n"));
static int rpc_shutdown(int argc, const char **argv)
{
- return run_rpc_command(NULL, PI_WINREG, 0, rpc_shutdown_internals,
+ int rc = run_rpc_command(NULL, PI_SHUTDOWN, 0,
+ rpc_init_shutdown_internals,
+ argc, argv);
+ if (rc == 0)
+ return rc;
+
+ DEBUG(1, ("initshutdown pipe didn't work, trying winreg pipe\n"));
+
+ return run_rpc_command(NULL, PI_WINREG, 0, rpc_reg_shutdown_internals,
argc, argv);
}
int fnum_dst = 0;
SEC_DESC *sd = NULL;
uint16 attr;
- time_t atime, ctime, mtime;
+ time_t f_atime, f_ctime, f_mtime;
if (!copy_timestamps && !copy_acls && !copy_attrs)
/* get file attributes */
if (!cli_getattrE(cli_share_src, fnum_src, &attr, NULL,
- &ctime, &atime, &mtime)) {
+ &f_ctime, &f_atime, &f_mtime)) {
DEBUG(0,("failed to get file-attrs: %s\n",
cli_errstr(cli_share_src)));
nt_status = cli_nt_error(cli_share_src);
if (copy_timestamps) {
/* set timestamps */
- if (!cli_setattrE(cli_share_dst, fnum_dst, ctime, atime, mtime)) {
+ if (!cli_setattrE(cli_share_dst, fnum_dst, f_ctime, f_atime, f_mtime)) {
DEBUG(0,("failed to set file-attrs (timestamps): %s\n",
cli_errstr(cli_share_dst)));
nt_status = cli_nt_error(cli_share_dst);
POLICY_HND hnd;
BOOL got_hnd = False;
WERROR result;
- char *action_str;
+ const char *action_str;
if (!get_printer_info(cli, mem_ctx, 2, argc, argv, &num_printers, &ctr))
return nt_status;
action_str = "unpublished";
break;
default:
+ action_str = "unknown action";
printf("unkown action: %d\n", action);
break;
}
d_printf("\n");
}
+
+static const char *display_time(NTTIME *nttime)
+{
+ static fstring string;
+
+ float high;
+ float low;
+ int sec;
+ int days, hours, mins, secs;
+ int offset = 1;
+
+ if (nttime->high==0 && nttime->low==0)
+ return "Now";
+
+ if (nttime->high==0x80000000 && nttime->low==0)
+ return "Never";
+
+ high = 65536;
+ high = high/10000;
+ high = high*65536;
+ high = high/1000;
+ high = high * (~nttime->high);
+
+ low = ~nttime->low;
+ low = low/(1000*1000*10);
+
+ sec=high+low;
+ sec+=offset;
+
+ days=sec/(60*60*24);
+ hours=(sec - (days*60*60*24)) / (60*60);
+ mins=(sec - (days*60*60*24) - (hours*60*60) ) / 60;
+ secs=sec - (days*60*60*24) - (hours*60*60) - (mins*60);
+
+ fstr_sprintf(string, "%u days, %u hours, %u minutes, %u seconds", days, hours, mins, secs);
+ return (string);
+}
+
+
static void display_alias_info(uint32 rid, SAM_ALIAS_INFO *a)
{
d_printf("Alias '%s' ", unistr2_static(&a->uni_als_name));
static void display_domain_info(SAM_DOMAIN_INFO *a)
{
+ time_t u_logout;
+
+ u_logout = nt_time_to_unix_abs((NTTIME *)&a->force_logoff);
+
d_printf("Domain name: %s\n", unistr2_static(&a->uni_dom_name));
+
+ d_printf("Minimal Password Length: %d\n", a->min_pwd_len);
+ d_printf("Password History Length: %d\n", a->pwd_history_len);
+
+ d_printf("Force Logoff: %d\n", (int)u_logout);
+
+ d_printf("Max Password Age: %s\n", display_time((NTTIME *)&a->max_pwd_age));
+ d_printf("Min Password Age: %s\n", display_time((NTTIME *)&a->min_pwd_age));
+
+ d_printf("Lockout Time: %s\n", display_time((NTTIME *)&a->account_lockout.lockout_duration));
+ d_printf("Lockout Reset Time: %s\n", display_time((NTTIME *)&a->account_lockout.reset_count));
+
+ d_printf("Bad Attempt Lockout: %d\n", a->account_lockout.bad_attempt_lockout);
+ d_printf("User must logon to change password: %d\n", a->logon_chgpass);
}
static void display_group_info(uint32 rid, SAM_GROUP_INFO *a)
pdb_set_profile_path(account, new_string, PDB_CHANGED);
}
+ if (delta->hdr_parameters.buffer) {
+ old_string = pdb_get_munged_dial(account);
+ new_string = unistr2_static(&delta->uni_parameters);
+
+ if (STRING_CHANGED)
+ pdb_set_munged_dial(account, new_string, PDB_CHANGED);
+ }
+
/* User and group sid */
if (pdb_get_user_rid(account) != delta->user_rid)
pdb_set_user_sid_from_rid(account, delta->user_rid, PDB_CHANGED);
pdb_set_logon_divs(account, delta->logon_divs, PDB_CHANGED);
/* TODO: logon hours */
- /* TODO: bad password count */
- /* TODO: logon count */
+ if (pdb_get_bad_password_count(account) != delta->bad_pwd_count)
+ pdb_set_bad_password_count(account, delta->bad_pwd_count, PDB_CHANGED);
+
+ if (pdb_get_logon_count(account) != delta->logon_count)
+ pdb_set_logon_count(account, delta->logon_count, PDB_CHANGED);
if (!nt_time_is_zero(&delta->pwd_last_set_time)) {
unix_time = nt_time_to_unix(&delta->pwd_last_set_time);
return NT_STATUS_NO_MEMORY;
}
- nt_members = talloc_zero(t, sizeof(char *) * delta->num_members);
+ nt_members = TALLOC_ZERO_ARRAY(t, char *, delta->num_members);
for (i=0; i<delta->num_members; i++) {
NTSTATUS nt_status;
return NT_STATUS_OK;
}
+static NTSTATUS fetch_domain_info(uint32 rid, SAM_DOMAIN_INFO *delta)
+{
+ time_t u_max_age, u_min_age, u_logout, u_lockoutreset, u_lockouttime;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ pstring domname;
+
+ u_max_age = nt_time_to_unix_abs((NTTIME *)&delta->max_pwd_age);
+ u_min_age = nt_time_to_unix_abs((NTTIME *)&delta->min_pwd_age);
+ u_logout = nt_time_to_unix_abs((NTTIME *)&delta->force_logoff);
+ u_lockoutreset = nt_time_to_unix_abs((NTTIME *)&delta->account_lockout.reset_count);
+ u_lockouttime = nt_time_to_unix_abs((NTTIME *)&delta->account_lockout.lockout_duration);
+
+ unistr2_to_ascii(domname, &delta->uni_dom_name, sizeof(domname) - 1);
+
+ /* we don't handle BUILTIN account policies */
+ if (!strequal(domname, get_global_sam_name())) {
+ printf("skipping SAM_DOMAIN_INFO delta for '%s' (is not my domain)\n", domname);
+ return NT_STATUS_OK;
+ }
+
+
+ if (!account_policy_set(AP_PASSWORD_HISTORY, delta->pwd_history_len))
+ return nt_status;
+
+ if (!account_policy_set(AP_MIN_PASSWORD_LEN, delta->min_pwd_len))
+ return nt_status;
+
+ if (!account_policy_set(AP_MAX_PASSWORD_AGE, (uint32)u_max_age))
+ return nt_status;
+
+ if (!account_policy_set(AP_MIN_PASSWORD_AGE, (uint32)u_min_age))
+ return nt_status;
+
+ if (!account_policy_set(AP_TIME_TO_LOGOUT, (uint32)u_logout))
+ return nt_status;
+
+ if (!account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, delta->account_lockout.bad_attempt_lockout))
+ return nt_status;
+
+ if (!account_policy_set(AP_RESET_COUNT_TIME, (uint32)u_lockoutreset/60))
+ return nt_status;
+
+ if (!account_policy_set(AP_LOCK_ACCOUNT_DURATION, (uint32)u_lockouttime/60))
+ return nt_status;
+
+ if (!account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, delta->logon_chgpass))
+ return nt_status;
+
+ return NT_STATUS_OK;
+}
+
+
static void
fetch_sam_entry(SAM_DELTA_HDR *hdr_delta, SAM_DELTA_CTR *delta,
DOM_SID dom_sid)
fetch_alias_mem(hdr_delta->target_rid,
&delta->als_mem_info, dom_sid);
break;
- /* The following types are recognised but not handled */
case SAM_DELTA_DOMAIN_INFO:
- d_printf("SAM_DELTA_DOMAIN_INFO not handled\n");
+ fetch_domain_info(hdr_delta->target_rid,
+ &delta->domain_info);
break;
+ /* The following types are recognised but not handled */
case SAM_DELTA_RENAME_GROUP:
d_printf("SAM_DELTA_RENAME_GROUP not handled\n");
break;
/* Server negTokenInit (mech offerings) */
spnego.type = SPNEGO_NEG_TOKEN_INIT;
- spnego.negTokenInit.mechTypes = SMB_XMALLOC_ARRAY(char *, 3);
+ spnego.negTokenInit.mechTypes = SMB_XMALLOC_ARRAY(const char *, 3);
#ifdef HAVE_KRB5
spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD);
spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP);
#define BIT_BACKEND 0x00000004
#define BIT_VERBOSE 0x00000008
#define BIT_SPSTYLE 0x00000010
-#define BIT_RESERV_1 0x00000020
-#define BIT_RESERV_2 0x00000040
+#define BIT_CAN_CHANGE 0x00000020
+#define BIT_MUST_CHANGE 0x00000040
#define BIT_RESERV_3 0x00000080
#define BIT_FULLNAME 0x00000100
#define BIT_HOMEDIR 0x00000200
#define BIT_LOGONHOURS 0x10000000
#define MASK_ALWAYS_GOOD 0x0000001F
-#define MASK_USER_GOOD 0x00401F00
+#define MASK_USER_GOOD 0x00401F60
/*********************************************************
Add all currently available users to another db
const char *drive, const char *script,
const char *profile, const char *account_control,
const char *user_sid, const char *group_sid,
- const BOOL badpw, const BOOL hours)
+ const BOOL badpw, const BOOL hours,
+ time_t pwd_can_change, time_t pwd_must_change)
{
BOOL updated_autolock = False, updated_badpw = False;
SAM_ACCOUNT *sam_pwent=NULL;
pdb_set_hours(sam_pwent, hours_array, PDB_CHANGED);
}
-
+
+ if (pwd_can_change != -1) {
+ pdb_set_pass_can_change_time(sam_pwent, pwd_can_change, PDB_CHANGED);
+ }
+
+ if (pwd_must_change != -1) {
+ pdb_set_pass_must_change_time(sam_pwent, pwd_must_change, PDB_CHANGED);
+ }
+
if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
DEBUG(2,("pdb_update_autolock_flag failed.\n"));
}
BOOL account_policy_value_set = False;
static BOOL badpw_reset = False;
static BOOL hours_reset = False;
+ static char *pwd_can_change_time = NULL;
+ static char *pwd_must_change_time = NULL;
+ static char *pwd_time_format = NULL;
struct pdb_context *bin;
struct pdb_context *bout;
{"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL},
{"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL},
{"logon-hours-reset", 'Z', POPT_ARG_NONE, &hours_reset, 0, "reset logon hours", NULL},
+ {"pwd-can-change-time", 0, POPT_ARG_STRING, &pwd_can_change_time, 0, "Set password can change time (unix time if time format no provided)", NULL },
+ {"pwd-must-change-time", 0, POPT_ARG_STRING, &pwd_must_change_time, 0, "Set password can change time (unix time if time format no provided)", NULL },
+ {"time-format", 0, POPT_ARG_STRING, &pwd_time_format, 0, "The time format for time parameters", NULL },
POPT_COMMON_SAMBA
POPT_TABLEEND
};
(backend_in ? BIT_IMPORT : 0) +
(backend_out ? BIT_EXPORT : 0) +
(badpw_reset ? BIT_BADPWRESET : 0) +
- (hours_reset ? BIT_LOGONHOURS : 0);
+ (hours_reset ? BIT_LOGONHOURS : 0) +
+ (pwd_can_change_time ? BIT_CAN_CHANGE: 0) +
+ (pwd_must_change_time ? BIT_MUST_CHANGE: 0);
if (setparms & BIT_BACKEND) {
if (!NT_STATUS_IS_OK(make_pdb_context_string(&bdef, backend))) {
/* account modification operations */
if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) {
+ time_t pwd_can_change = -1;
+ time_t pwd_must_change = -1;
+ char *errstr;
+
+ if (pwd_can_change_time) {
+ errstr = "can";
+ if (pwd_time_format) {
+ struct tm tm;
+ char *ret;
+
+ memset(&tm, 0, sizeof(struct tm));
+ ret = strptime(pwd_can_change_time, pwd_time_format, &tm);
+ if (ret == NULL || *ret != '\0') {
+ goto error;
+ }
+
+ pwd_can_change = mktime(&tm);
+
+ if (pwd_can_change == -1) {
+ goto error;
+ }
+ } else { /* assume it is unix time */
+ errno = 0;
+ pwd_can_change = strtol(pwd_can_change_time, NULL, 10);
+ if (errno) {
+ goto error;
+ }
+ }
+ }
+ if (pwd_must_change_time) {
+ errstr = "must";
+ if (pwd_time_format) {
+ struct tm tm;
+ char *ret;
+
+ memset(&tm, 0, sizeof(struct tm));
+ ret = strptime(pwd_must_change_time, pwd_time_format, &tm);
+ if (ret == NULL || *ret != '\0') {
+ goto error;
+ }
+
+ pwd_must_change = mktime(&tm);
+
+ if (pwd_must_change == -1) {
+ goto error;
+ }
+ } else { /* assume it is unix time */
+ errno = 0;
+ pwd_must_change = strtol(pwd_must_change_time, NULL, 10);
+ if (errno) {
+ goto error;
+ }
+ }
+ }
return set_user_info (bdef, user_name, full_name,
home_dir,
home_drive,
logon_script,
profile_path, account_control,
user_sid, group_sid,
- badpw_reset, hours_reset);
+ badpw_reset, hours_reset,
+ pwd_can_change, pwd_must_change);
+error:
+ fprintf (stderr, "Error parsing the time in pwd-%s-change-time!\n", errstr);
+ return -1;
}
}
}
}
+ if (sd->owner_sid) {
+ old->owner_sid = sd->owner_sid;
+ }
+
+ if (sd->grp_sid) {
+ old->grp_sid = sd->grp_sid;
+ }
+
break;
case SMB_ACL_ADD:
sort_acl(old->dacl);
/* Create new security descriptor and set it */
- sd = make_sec_desc(ctx,old->revision, old->type, NULL, NULL,
+ sd = make_sec_desc(ctx,old->revision, old->type, old->owner_sid, old->grp_sid,
NULL, old->dacl, &sd_size);
fnum = cli_nt_create(cli, filename, WRITE_DAC_ACCESS);
ctx=talloc_init("main");
- /* set default debug level to 0 regardless of what smb.conf sets */
+ /* set default debug level to 1 regardless of what smb.conf sets */
setup_logging( "smbcacls", True );
DEBUGLEVEL_CLASS[DBGC_ALL] = 1;
dbf = x_stderr;
while(*relname == '/')relname++;
mkdir(relname, 0755);
- tmpname = strdup(name);
+ tmpname = SMB_STRDUP(name);
while((dirent = smbc_readdir(dirhandle))) {
char *newname;
int required = strlen(name), available = columns - len - strlen("[] ");
if(required > available) asprintf(&filename, "...%s", name + required - available + 3);
else filename = strndup(name, available);
- } else filename = strdup(name);
+ } else filename = SMB_STRDUP(name);
fprintf(stderr, "\r[%s] %s", filename, status);
offset_check = 0;
}
- readbuf = malloc(blocksize);
+ readbuf = SMB_MALLOC(blocksize);
/* Now, download all bytes from offset_download to the end */
for(curpos = offset_download; curpos < remotestat.st_size; curpos+=blocksize) {
break;
case POPT_ARG_STRING:
stringdata = (char **)long_options[i].arg;
- *stringdata = strdup(val);
+ *stringdata = SMB_STRDUP(val);
break;
default:
fprintf(stderr, "Invalid variable %s at line %d in %s\n", var, lineno, name);
pdb_init_sam(&sampass);
ret = pdb_getsampwnam(sampass, user_name);
- if((sampass != False) && (pdb_get_lanman_passwd(sampass) == NULL)) {
+ if((ret) &&
+ (pdb_get_lanman_passwd(sampass) == NULL)) {
local_flags |= LOCAL_SET_PASSWORD;
}
pdb_free_sam(&sampass);
#include "includes.h"
#define SMB_MAXPIDS 2048
-static pstring Ucrit_username = ""; /* added by OH */
+static uid_t Ucrit_uid = 0; /* added by OH */
static pid_t Ucrit_pid[SMB_MAXPIDS]; /* Ugly !!! */ /* added by OH */
static int Ucrit_MaxPid=0; /* added by OH */
static unsigned int Ucrit_IsActive = 0; /* added by OH */
static int locks_only = 0; /* Added by RJS */
static BOOL processes_only=False;
static int show_brl;
+static BOOL numeric_only = False;
const char *username = NULL;
/* added by OH */
-static void Ucrit_addUsername(const char *username)
+static void Ucrit_addUid(uid_t uid)
{
- pstrcpy(Ucrit_username, username);
-
- if ( strlen(Ucrit_username) > 0 )
- Ucrit_IsActive = 1;
+ Ucrit_uid = uid;
+ Ucrit_IsActive = 1;
}
-static unsigned int Ucrit_checkUsername(const char *username)
+static unsigned int Ucrit_checkUid(uid_t uid)
{
if ( !Ucrit_IsActive )
return 1;
- if ( strcmp(Ucrit_username,username) == 0 )
+ if ( uid == Ucrit_uid )
return 1;
return 0;
if ( Ucrit_MaxPid >= SMB_MAXPIDS ) {
d_printf("ERROR: More than %d pids for user %s!\n",
- SMB_MAXPIDS, Ucrit_username);
+ SMB_MAXPIDS, uidtoname(Ucrit_uid));
return False;
}
if (crec.cnum == -1)
return 0;
- if (!process_exists(crec.pid) || !Ucrit_checkUsername(uidtoname(crec.uid))) {
+ if (!process_exists(crec.pid) || !Ucrit_checkUid(crec.uid)) {
return 0;
}
static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
{
struct sessionid sessionid;
+ fstring uid_str, gid_str;
if (dbuf.dsize != sizeof(sessionid))
return 0;
memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
- if (!process_exists(sessionid.pid) || !Ucrit_checkUsername(uidtoname(sessionid.uid))) {
+ if (!process_exists(sessionid.pid) || !Ucrit_checkUid(sessionid.uid)) {
return 0;
}
Ucrit_addPid( sessionid.pid );
+ fstr_sprintf(uid_str, "%d", sessionid.uid);
+ fstr_sprintf(gid_str, "%d", sessionid.gid);
+
d_printf("%5d %-12s %-12s %-12s (%s)\n",
- (int)sessionid.pid, uidtoname(sessionid.uid), gidtoname(sessionid.gid),
- sessionid.remote_machine, sessionid.hostname);
+ (int)sessionid.pid,
+ numeric_only ? uid_str : uidtoname(sessionid.uid),
+ numeric_only ? gid_str : gidtoname(sessionid.gid),
+ sessionid.remote_machine, sessionid.hostname);
return 0;
}
{"profile", 'P', POPT_ARG_NONE, &profile_only, 'P', "Do profiling" },
#endif /* WITH_PROFILE */
{"byterange", 'B', POPT_ARG_NONE, &show_brl, 'B', "Include byte range locks"},
+ {"numeric", 'n', POPT_ARG_NONE, &numeric_only, 'n', "Numeric uid/gid"},
POPT_COMMON_SAMBA
POPT_TABLEEND
};
while ((c = poptGetNextOpt(pc)) != -1) {
switch (c) {
case 'u':
- Ucrit_addUsername(poptGetOptArg(pc));
+ Ucrit_addUid(nametouid(poptGetOptArg(pc)));
break;
}
}
show_shares = !(processes_only || locks_only || profile_only) || shares_only;
if ( username )
- Ucrit_addUsername( username );
+ Ucrit_addUid( nametouid(username) );
if (verbose) {
d_printf("using configfile = %s\n", dyn_CONFIGFILE);
plus the broadcast sockets.
***************************************************************************/
-static BOOL create_listen_fdset(void)
+static BOOL create_listen_fdset( int *maxfd)
{
int i;
int num_interfaces = iface_count();
}
add_fd_to_sock_array(s);
FD_SET(s, listen_set);
+ *maxfd = MAX( *maxfd, s);
}
} else {
/* Just bind to 0.0.0.0 - accept connections from anywhere. */
add_fd_to_sock_array(s);
FD_SET(s, listen_set);
+ *maxfd = MAX( *maxfd, s);
}
return True;
int num_interfaces = iface_count();
fd_set fds;
int i, num, s, new_s;
+ static int maxfd = 0;
struct timeval timeout;
if(listen_set == NULL) {
- if(!create_listen_fdset()) {
+ if(!create_listen_fdset( &maxfd)) {
DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
return True;
}
BlockSignals(False, SIGTERM);
- num = sys_select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+ num = sys_select(maxfd+1, &fds, NULL, NULL, &timeout);
/* We can only take signals when we are in the select - block them again here. */
set_socket_options(new_s, user_socket_options);
FD_SET(new_s, listen_set);
add_fd_to_sock_array(new_s);
+ maxfd = MAX( maxfd, new_s);
}
}