diff options
-rw-r--r-- | source3/acconfig.h | 2 | ||||
-rwxr-xr-x | source3/configure | 69 | ||||
-rw-r--r-- | source3/configure.in | 41 | ||||
-rw-r--r-- | source3/include/config.h.in | 2 | ||||
-rw-r--r-- | source3/include/proto.h | 24 | ||||
-rw-r--r-- | source3/include/rpc_client_proto.h | 3 | ||||
-rw-r--r-- | source3/include/smb_acls.h | 36 | ||||
-rw-r--r-- | source3/lib/sysacls.c | 536 | ||||
-rw-r--r-- | source3/rpc_client/cli_netlogon.c | 3 |
9 files changed, 670 insertions, 46 deletions
diff --git a/source3/acconfig.h b/source3/acconfig.h index 7656aa898f..0f8cf580ce 100644 --- a/source3/acconfig.h +++ b/source3/acconfig.h @@ -138,4 +138,6 @@ #undef MIPS_SPINLOCKS #undef POWERPC_SPINLOCKS #undef HAVE_POSIX_ACLS +#undef HAVE_UNIXWARE_ACLS +#undef HAVE_SOLARIS_ACLS #undef HAVE_NO_ACLS diff --git a/source3/configure b/source3/configure index 35ed71f6bb..3010936deb 100755 --- a/source3/configure +++ b/source3/configure @@ -89,8 +89,8 @@ ac_help="$ac_help ac_help="$ac_help --with-spinlocks use spin locks instead of fcntl locks " ac_help="$ac_help - --with-posix-acls Include POSIX ACL support - --without-posix-acls Don't include POSIX ACL support (default)" + --with-acl-support Include ACL support + --without-acl-support Don't include ACL support (default)" # Initialize some variables set by options. # The variables have the same names as the options, with @@ -11470,18 +11470,34 @@ EOF fi ################################################# -# check for POSIX ACL support +# check for ACL support -echo $ac_n "checking whether to support POSIX ACLs""... $ac_c" 1>&6 -echo "configure:11477: checking whether to support POSIX ACLs" >&5 -# Check whether --with-posix-acls or --without-posix-acls was given. -if test "${with_posix_acls+set}" = set; then - withval="$with_posix_acls" +echo $ac_n "checking whether to support ACLs""... $ac_c" 1>&6 +echo "configure:11477: checking whether to support ACLs" >&5 +# Check whether --with-acl-support or --without-acl-support was given. +if test "${with_acl_support+set}" = set; then + withval="$with_acl_support" case "$withval" in yes) - echo $ac_n "checking for acl_get_file in -lacl""... $ac_c" 1>&6 -echo "configure:11485: checking for acl_get_file in -lacl" >&5 + case "$host_os" in + *unixware*) + echo "$ac_t""Using SVR4 ACLs" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_UNIXWARE_ACLS 1 +EOF + + ;; + *solaris*) + echo "$ac_t""Using solaris ACLs" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_SOLARIS_ACLS 1 +EOF + + ;; + *) + echo $ac_n "checking for acl_get_file in -lacl""... $ac_c" 1>&6 +echo "configure:11501: checking for acl_get_file in -lacl" >&5 ac_lib_var=`echo acl'_'acl_get_file | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -11489,7 +11505,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lacl $LIBS" cat > conftest.$ac_ext <<EOF -#line 11493 "configure" +#line 11509 "configure" #include "confdefs.h" /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 @@ -11500,7 +11516,7 @@ int main() { acl_get_file() ; return 0; } EOF -if { (eval echo configure:11504: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:11520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -11527,14 +11543,14 @@ else echo "$ac_t""no" 1>&6 fi -echo $ac_n "checking for POSIX ACL support""... $ac_c" 1>&6 -echo "configure:11532: checking for POSIX ACL support" >&5 + echo $ac_n "checking for ACL support""... $ac_c" 1>&6 +echo "configure:11548: checking for ACL support" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_POSIX_ACLS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else -cat > conftest.$ac_ext <<EOF -#line 11538 "configure" + cat > conftest.$ac_ext <<EOF +#line 11554 "configure" #include "confdefs.h" #include <sys/types.h> #include <sys/acl.h> @@ -11542,7 +11558,7 @@ int main() { acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p); ; return 0; } EOF -if { (eval echo configure:11546: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:11562: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_POSIX_ACLS=yes else @@ -11555,14 +11571,16 @@ rm -f conftest* fi echo "$ac_t""$samba_cv_HAVE_POSIX_ACLS" 1>&6 -if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then - echo "$ac_t""yes" 1>&6 - cat >> confdefs.h <<\EOF + if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then + echo "$ac_t""Using posix ACLs" 1>&6 + cat >> confdefs.h <<\EOF #define HAVE_POSIX_ACLS 1 EOF -fi - ;; + fi + ;; + esac + ;; *) echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF @@ -11572,25 +11590,24 @@ EOF ;; esac else - echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_NO_ACLS 1 EOF + echo "$ac_t""no" 1>&6 fi - echo "checking configure summary" if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext <<EOF -#line 11590 "configure" +#line 11607 "configure" #include "confdefs.h" #include "${srcdir-.}/tests/summary.c" EOF -if { (eval echo configure:11594: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:11611: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "configure OK"; else diff --git a/source3/configure.in b/source3/configure.in index 7eba74d710..2ad8b2d937 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -1924,35 +1924,46 @@ if test "x$with_spinlocks" = "xyes"; then fi ################################################# -# check for POSIX ACL support +# check for ACL support -AC_MSG_CHECKING(whether to support POSIX ACLs) -AC_ARG_WITH(posix-acls, -[ --with-posix-acls Include POSIX ACL support - --without-posix-acls Don't include POSIX ACL support (default)], +AC_MSG_CHECKING(whether to support ACLs) +AC_ARG_WITH(acl-support, +[ --with-acl-support Include ACL support + --without-acl-support Don't include ACL support (default)], [ case "$withval" in yes) - AC_CHECK_LIB(acl,acl_get_file) -AC_CACHE_CHECK([for POSIX ACL support],samba_cv_HAVE_POSIX_ACLS,[ -AC_TRY_COMPILE([#include <sys/types.h> + case "$host_os" in + *unixware*) + AC_MSG_RESULT(Using SVR4 ACLs) + AC_DEFINE(HAVE_UNIXWARE_ACLS) + ;; + *solaris*) + AC_MSG_RESULT(Using solaris ACLs) + AC_DEFINE(HAVE_SOLARIS_ACLS) + ;; + *) + AC_CHECK_LIB(acl,acl_get_file) + AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[ + AC_TRY_COMPILE([#include <sys/types.h> #include <sys/acl.h>], [ acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);], samba_cv_HAVE_POSIX_ACLS=yes,samba_cv_HAVE_POSIX_ACLS=no)]) -if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_POSIX_ACLS) -fi - ;; + if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then + AC_MSG_RESULT(Using posix ACLs) + AC_DEFINE(HAVE_POSIX_ACLS) + fi + ;; + esac + ;; *) AC_MSG_RESULT(no) AC_DEFINE(HAVE_NO_ACLS) ;; esac ], - AC_MSG_RESULT(no) AC_DEFINE(HAVE_NO_ACLS) + AC_MSG_RESULT(no) ) - echo "checking configure summary" AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"], echo "configure OK";, diff --git a/source3/include/config.h.in b/source3/include/config.h.in index dd8e8dca88..82fd2910ca 100644 --- a/source3/include/config.h.in +++ b/source3/include/config.h.in @@ -201,6 +201,8 @@ #undef MIPS_SPINLOCKS #undef POWERPC_SPINLOCKS #undef HAVE_POSIX_ACLS +#undef HAVE_UNIXWARE_ACLS +#undef HAVE_SOLARIS_ACLS #undef HAVE_NO_ACLS /* The number of bytes in a int. */ diff --git a/source3/include/proto.h b/source3/include/proto.h index 4f703dedb1..764fcf0e62 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -276,6 +276,26 @@ int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d); int sys_acl_set_fd(int fd, SMB_ACL_T acl_d); int sys_acl_free_text(char *text); int sys_acl_free_acl(SMB_ACL_T acl_d) ; +int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p); +int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p); +int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); +void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d); +SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type); +SMB_ACL_T sys_acl_get_fd(int fd); +int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d); +int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm); +int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm); +char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p); +SMB_ACL_T sys_acl_init(int count); +int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p); +int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type); +int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p); +int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d); +int sys_acl_valid(SMB_ACL_T acl_d); +int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d); +int sys_acl_set_fd(int fd, SMB_ACL_T acl_d); +int sys_acl_free_text(char *text); +int sys_acl_free_acl(SMB_ACL_T acl_d) ; int sys_acl_get_entry( SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p); int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); @@ -528,6 +548,7 @@ BOOL sid_split_rid(DOM_SID *sid, uint32 *rid); void sid_copy(DOM_SID *dst, const DOM_SID *src); DOM_SID *sid_dup(DOM_SID *src); BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid); +int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2); BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2); size_t sid_size(DOM_SID *sid); @@ -2085,8 +2106,7 @@ BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan, uint32 neg_flags, DOM_CHAL *srv_chal); BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal); BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]); -BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, - NET_USER_INFO_3 *user_info3); +BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3); BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr); BOOL change_trust_account_password( char *domain, char *remote_machine_list); diff --git a/source3/include/rpc_client_proto.h b/source3/include/rpc_client_proto.h index 3b94c37d59..210a352cf4 100644 --- a/source3/include/rpc_client_proto.h +++ b/source3/include/rpc_client_proto.h @@ -70,8 +70,7 @@ BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan, uint32 neg_flags, DOM_CHAL *srv_chal); BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal); BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]); -BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, - NET_USER_INFO_3 *user_info3); +BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3); BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr); BOOL change_trust_account_password( char *domain, char *remote_machine_list); diff --git a/source3/include/smb_acls.h b/source3/include/smb_acls.h index 578e9f2751..4469432e36 100644 --- a/source3/include/smb_acls.h +++ b/source3/include/smb_acls.h @@ -95,6 +95,42 @@ typedef struct acl *SMB_ACL_ENTRY_T; #elif defined(HAVE_SOLARIS_ACLS) +/* + * Code donated by Toomas Soome <tsoome@ut.ee>. + * Based on the implementation by Michael Davidson <md@sco.COM> for UnixWare. + */ + +typedef int SMB_ACL_TAG_T; +typedef int SMB_ACL_TYPE_T; +typedef ushort *SMB_ACL_PERMSET_T; +typedef ushort SMB_ACL_PERM_T; +#define SMB_ACL_READ 4 +#define SMB_ACL_WRITE 2 +#define SMB_ACL_EXECUTE 1 + +/* Types of ACLs. */ +#define SMB_ACL_USER USER +#define SMB_ACL_USER_OBJ USER_OBJ +#define SMB_ACL_GROUP GROUP +#define SMB_ACL_GROUP_OBJ GROUP_OBJ +#define SMB_ACL_OTHER OTHER_OBJ +#define SMB_ACL_MASK CLASS_OBJ + +typedef struct SMB_ACL_T { + int size; + int count; + int next; + struct acl acl[1]; +} *SMB_ACL_T; + +typedef struct acl *SMB_ACL_ENTRY_T; + +#define SMB_ACL_FIRST_ENTRY 0 +#define SMB_ACL_NEXT_ENTRY 1 + +#define SMB_ACL_TYPE_ACCESS 0 +#define SMB_ACL_TYPE_DEFAULT 1 + #elif defined(HAVE_IRIX_ACLS) #else /* No ACLs. */ diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c index 640684ffca..94f0a10d46 100644 --- a/source3/lib/sysacls.c +++ b/source3/lib/sysacls.c @@ -731,6 +731,542 @@ int sys_acl_free_acl(SMB_ACL_T acl_d) } #elif defined(HAVE_SOLARIS_ACLS) +/* + * Code donated by Toomas Soome <tsoome@ut.ee>. + * Based on the implementation by Michael Davidson <md@sco.COM> for UnixWare. + */ + +#define INITIAL_ACL_SIZE 16 + +int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p) +{ + if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) { + errno = EINVAL; + return -1; + } + + if (entry_p == NULL) { + errno = EINVAL; + return -1; + } + + if (entry_id == SMB_ACL_FIRST_ENTRY) { + acl_d->next = 0; + } + + if (acl_d->next < 0) { + errno = EINVAL; + return -1; + } + + if (acl_d->next >= acl_d->count) { + return 0; + } + + *entry_p = &acl_d->acl[acl_d->next++]; + + return 1; +} + +int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p) +{ + *type_p = entry_d->a_type; + + return 0; +} + +int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) +{ + *permset_p = &entry_d->a_perm; + + return 0; +} + +void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d) +{ + if (entry_d->a_type != SMB_ACL_USER + && entry_d->a_type != SMB_ACL_GROUP) { + errno = EINVAL; + return NULL; + } + + return &entry_d->a_id; +} + +SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type) +{ + SMB_ACL_T acl_d; + int count; /* # of ACL entries allocated */ + int naccess; /* # of access ACL entries */ + int ndefault; /* # of default ACL entries */ + + if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) { + errno = EINVAL; + return NULL; + } + + count = INITIAL_ACL_SIZE; + if ((acl_d = sys_acl_init(count)) == NULL) { + return NULL; + } + + while ((count = acl(path_p, GETACL, count, &acl_d->acl[0])) < 0 + && errno == ENOSPC) { + + if ((count = acl(path_p, GETACLCNT, 0, NULL)) < 0) { + return NULL; + } + + sys_acl_free_acl(acl_d); + + if ((acl_d = sys_acl_init(count)) == NULL) { + return NULL; + } + } + + if (count < 0) { + return NULL; + } + + /* + * calculate the number of access and default ACL entries + * + * Note: we assume that the acl() system call returned a + * well formed ACL which is sorted so that all of the + * access ACL entries preceed any default ACL entries + */ + for (naccess = 0; naccess < count; naccess++) { + if (acl_d->acl[naccess].a_type & ACL_DEFAULT) + break; + } + ndefault = count - naccess; + + /* + * if the caller wants the default ACL we have to copy + * the entries down to the start of the acl[] buffer + * and mask out the ACL_DEFAULT flag from the type field + */ + if (type == SMB_ACL_TYPE_DEFAULT) { + int i, j; + + for (i = 0, j = naccess; i < ndefault; i++, j++) { + acl_d->acl[i] = acl_d->acl[j]; + acl_d->acl[i].a_type &= ~ACL_DEFAULT; + } + + acl_d->count = ndefault; + } else { + acl_d->count = naccess; + } + + return acl_d; +} + +SMB_ACL_T sys_acl_get_fd(int fd) +{ + SMB_ACL_T acl_d; + int count; /* # of ACL entries allocated */ + int naccess; /* # of access ACL entries */ + + count = INITIAL_ACL_SIZE; + if ((acl_d = sys_acl_init(count)) == NULL) { + return NULL; + } + + while ((count = facl(fd, GETACL, count, &acl_d->acl[0])) < 0 + && errno == ENOSPC) { + + if ((count = facl(fd, GETACLCNT, 0, NULL)) < 0) { + return NULL; + } + + sys_acl_free_acl(acl_d); + + if ((acl_d = sys_acl_init(count)) == NULL) { + return NULL; + } + } + + if (count < 0) { + return NULL; + } + + /* + * calculate the number of access ACL entries + */ + for (naccess = 0; naccess < count; naccess++) { + if (acl_d->acl[naccess].a_type & ACL_DEFAULT) + break; + } + + acl_d->count = naccess; + + return acl_d; +} + +int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d) +{ + *permset_d = 0; + + return 0; +} + +int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm) +{ + if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE + && perm != SMB_ACL_EXECUTE) { + errno = EINVAL; + return -1; + } + + if (permset_d == NULL) { + errno = EINVAL; + return -1; + } + + *permset_d |= perm; + + return 0; +} + +int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm) +{ + return *permset_d & perm; +} + +char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p) +{ + int i; + int len, maxlen; + char *text; + + /* + * use an initial estimate of 20 bytes per ACL entry + * when allocating memory for the text representation + * of the ACL + */ + len = 0; + maxlen = 20 * acl_d->count; + if ((text = malloc(maxlen)) == NULL) { + errno = ENOMEM; + return NULL; + } + + for (i = 0; i < acl_d->count; i++) { + struct acl *ap = &acl_d->acl[i]; + struct passwd *pw; + struct group *gr; + char tagbuf[12]; + char idbuf[12]; + char *tag; + char *id = ""; + char perms[4]; + int nbytes; + + switch (ap->a_type) { + /* + * for debugging purposes it's probably more + * useful to dump unknown tag types rather + * than just returning an error + */ + default: + slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x", + ap->a_type); + tag = tagbuf; + slprintf(idbuf, sizeof(idbuf)-1, "%ld", + (long)ap->a_id); + id = idbuf; + break; + + case SMB_ACL_USER: + if ((pw = getpwuid(ap->a_id)) == NULL) { + slprintf(idbuf, sizeof(idbuf)-1, "%ld", + (long)ap->a_id); + id = idbuf; + } else { + id = pw->pw_name; + } + case SMB_ACL_USER_OBJ: + tag = "user"; + break; + + case SMB_ACL_GROUP: + if ((gr = getgrgid(ap->a_id)) == NULL) { + slprintf(idbuf, sizeof(idbuf)-1, "%ld", + (long)ap->a_id); + id = idbuf; + } else { + id = gr->gr_name; + } + case SMB_ACL_GROUP_OBJ: + tag = "group"; + break; + + case SMB_ACL_OTHER: + tag = "other"; + break; + + case SMB_ACL_MASK: + tag = "mask"; + break; + + } + + perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-'; + perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-'; + perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-'; + perms[3] = '\0'; + + /* <tag> : <qualifier> : rwx \n \0 */ + nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1; + + if ((len + nbytes) > maxlen) { + /* + * allocate enough additional memory for this + * entry and an estimate of another 20 bytes + * for each entry still to be processed + */ + maxlen += nbytes + 20 * (acl_d->count - i); + + if ((text = realloc(text, maxlen)) == NULL) { + errno = ENOMEM; + return NULL; + } + } + + slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms); + len += nbytes - 1; + } + + if (len_p) + *len_p = len; + + return text; +} + +SMB_ACL_T sys_acl_init(int count) +{ + SMB_ACL_T a; + + if (count < 0) { + errno = EINVAL; + return NULL; + } + + /* + * note that since the definition of the structure pointed + * to by the SMB_ACL_T includes the first element of the + * acl[] array, this actually allocates an ACL with room + * for (count+1) entries + */ + if ((a = malloc(sizeof(*a) + count * sizeof(struct acl))) == NULL) { + errno = ENOMEM; + return NULL; + } + + a->size = count + 1; + a->count = 0; + a->next = -1; + + return a; +} + + +int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p) +{ + SMB_ACL_T acl_d; + SMB_ACL_ENTRY_T entry_d; + + if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) { + errno = EINVAL; + return -1; + } + + if (acl_d->count >= acl_d->size) { + errno = ENOSPC; + return -1; + } + + entry_d = &acl_d->acl[acl_d->count++]; + entry_d->a_type = 0; + entry_d->a_id = -1; + entry_d->a_perm = 0; + *entry_p = entry_d; + + return 0; +} + +int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type) +{ + switch (tag_type) { + case SMB_ACL_USER: + case SMB_ACL_USER_OBJ: + case SMB_ACL_GROUP: + case SMB_ACL_GROUP_OBJ: + case SMB_ACL_OTHER: + case SMB_ACL_MASK: + entry_d->a_type = tag_type; + break; + default: + errno = EINVAL; + return -1; + } + + return 0; +} + +int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p) +{ + if (entry_d->a_type != SMB_ACL_GROUP + && entry_d->a_type != SMB_ACL_USER) { + errno = EINVAL; + return -1; + } + + entry_d->a_id = *((id_t *)qual_p); + + return 0; +} + +int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d) +{ + if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) { + return EINVAL; + } + + entry_d->a_perm = *permset_d; + + return 0; +} + +int sys_acl_valid(SMB_ACL_T acl_d) +{ + if (aclsort(acl_d->count, 0, acl_d->acl) != 0) { + errno = EINVAL; + return -1; + } + + return 0; +} + +int sys_acl_set_file(char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d) +{ + struct stat s; + struct acl *acl_p; + int acl_count; + struct acl *acl_buf = NULL; + int ret; + + if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) { + errno = EINVAL; + return -1; + } + + if (stat(name, &s) != 0) { + return -1; + } + + acl_p = &acl_d->acl[0]; + acl_count = acl_d->count; + + /* + * if it's a directory there is extra work to do + * since the acl() system call will replace both + * the access ACLs and the default ACLs (if any) + */ + if (S_ISDIR(s.st_mode)) { + SMB_ACL_T acc_acl; + SMB_ACL_T def_acl; + SMB_ACL_T tmp_acl; + int i; + + if (type == SMB_ACL_TYPE_ACCESS) { + acc_acl = acl_d; + def_acl = + tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_DEFAULT); + + } else { + def_acl = acl_d; + acc_acl = + tmp_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS); + } + + if (tmp_acl == NULL) { + return -1; + } + + /* + * 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])); + + if (acl_buf == NULL) { + sys_acl_free_acl(tmp_acl); + errno = ENOMEM; + return -1; + } + + /* + * copy the access control and default entries into the buffer + */ + memcpy(&acl_buf[0], &acc_acl->acl[0], + acc_acl->count * sizeof(acl_buf[0])); + + memcpy(&acl_buf[acc_acl->count], &def_acl->acl[0], + def_acl->count * sizeof(acl_buf[0])); + + /* + * set the ACL_DEFAULT flag on the default entries + */ + for (i = acc_acl->count; i < acl_count; i++) { + acl_buf[i].a_type |= ACL_DEFAULT; + } + + sys_acl_free_acl(tmp_acl); + + } else if (type != SMB_ACL_TYPE_ACCESS) { + errno = EINVAL; + return -1; + } + + if (aclsort(acl_count, 0, acl_p) != 0) { + errno = EINVAL; + ret = -1; + } else { + ret = acl(name, SETACL, acl_count, acl_p); + } + + if (acl_buf) { + free(acl_buf); + } + + return ret; +} + +int sys_acl_set_fd(int fd, SMB_ACL_T acl_d) +{ + if (aclsort(acl_d->count, 0, acl_d->acl) != 0) { + errno = EINVAL; + return -1; + } + + return facl(fd, SETACL, acl_d->count, &acl_d->acl[0]); +} + +int sys_acl_free_text(char *text) +{ + free(text); + return 0; +} + +int sys_acl_free_acl(SMB_ACL_T acl_d) +{ + free(acl_d); + return 0; +} + #elif defined(HAVE_IRIX_ACLS) #else /* No ACLs. */ diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 35238b9467..1ed1db4d0a 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -425,7 +425,8 @@ password ?).\n", cli->desthost )); if (r_s.switch_value != validation_level) { /* report different switch_value */ - DEBUG(0,("cli_net_sam_logon: switch_value of %u expected %x\n", r_s.switch_value)); + DEBUG(0,("cli_net_sam_logon: switch_value of %x expected %x\n", (unsigned int)validation_level, + (unsigned int)r_s.switch_value)); retval = NT_STATUS_INVALID_PARAMETER; } |