lib/sysacls.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Samba system utilities for ACL support.
00004    Copyright (C) Jeremy Allison 2000.
00005    Copyright (C) Volker Lendecke 2006
00006    Copyright (C) Michael Adam 2006
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 #include "includes.h"
00024 
00025 #undef  DBGC_CLASS
00026 #define DBGC_CLASS DBGC_ACLS
00027 
00028 /*
00029  * Note that while this code implements sufficient functionality
00030  * to support the sys_acl_* interfaces it does not provide all
00031  * of the semantics of the POSIX ACL interfaces.
00032  *
00033  * In particular, an ACL entry descriptor (SMB_ACL_ENTRY_T) returned
00034  * from a call to sys_acl_get_entry() should not be assumed to be
00035  * valid after calling any of the following functions, which may
00036  * reorder the entries in the ACL.
00037  *
00038  *      sys_acl_valid()
00039  *      sys_acl_set_file()
00040  *      sys_acl_set_fd()
00041  */
00042 
00043 int sys_acl_get_entry(SMB_ACL_T acl_d, int entry_id, SMB_ACL_ENTRY_T *entry_p)
00044 {
00045         if (entry_id != SMB_ACL_FIRST_ENTRY && entry_id != SMB_ACL_NEXT_ENTRY) {
00046                 errno = EINVAL;
00047                 return -1;
00048         }
00049 
00050         if (entry_p == NULL) {
00051                 errno = EINVAL;
00052                 return -1;
00053         }
00054 
00055         if (entry_id == SMB_ACL_FIRST_ENTRY) {
00056                 acl_d->next = 0;
00057         }
00058 
00059         if (acl_d->next < 0) {
00060                 errno = EINVAL;
00061                 return -1;
00062         }
00063 
00064         if (acl_d->next >= acl_d->count) {
00065                 return 0;
00066         }
00067 
00068         *entry_p = &acl_d->acl[acl_d->next++];
00069 
00070         return 1;
00071 }
00072 
00073 int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *type_p)
00074 {
00075         *type_p = entry_d->a_type;
00076 
00077         return 0;
00078 }
00079 
00080 int sys_acl_get_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
00081 {
00082         *permset_p = &entry_d->a_perm;
00083 
00084         return 0;
00085 }
00086 
00087 void *sys_acl_get_qualifier(SMB_ACL_ENTRY_T entry_d)
00088 {
00089         if (entry_d->a_type == SMB_ACL_USER) {
00090                 return &entry_d->uid;
00091                 }
00092 
00093         if (entry_d->a_type == SMB_ACL_GROUP) {
00094                 return &entry_d->gid;
00095         }
00096 
00097         errno = EINVAL;
00098                 return NULL;
00099 }
00100 
00101 int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
00102 {
00103         *permset_d = 0;
00104 
00105         return 0;
00106 }
00107 
00108 int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
00109 {
00110         if (perm != SMB_ACL_READ && perm != SMB_ACL_WRITE
00111             && perm != SMB_ACL_EXECUTE) {
00112                 errno = EINVAL;
00113                 return -1;
00114                 }
00115  
00116         if (permset_d == NULL) {
00117                 errno = EINVAL;
00118                 return -1;
00119         }
00120 
00121         *permset_d |= perm;
00122  
00123         return 0;
00124 }
00125 
00126 int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm)
00127 {
00128         return *permset_d & perm;
00129 }
00130 
00131 char *sys_acl_to_text(SMB_ACL_T acl_d, ssize_t *len_p)
00132 {
00133         int     i;
00134         int     len, maxlen;
00135         char    *text;
00136 
00137         /*
00138          * use an initial estimate of 20 bytes per ACL entry
00139          * when allocating memory for the text representation
00140          * of the ACL
00141          */
00142         len     = 0;
00143         maxlen  = 20 * acl_d->count;
00144         if ((text = (char *)SMB_MALLOC(maxlen)) == NULL) {
00145                 errno = ENOMEM;
00146                 return NULL;
00147         }
00148 
00149         for (i = 0; i < acl_d->count; i++) {
00150                 struct smb_acl_entry *ap = &acl_d->acl[i];
00151                 struct group    *gr;
00152                 char            tagbuf[12];
00153                 char            idbuf[12];
00154                 const char      *tag;
00155                 const char      *id     = "";
00156                 char            perms[4];
00157                 int             nbytes;
00158 
00159                 switch (ap->a_type) {
00160                         /*
00161                          * for debugging purposes it's probably more
00162                          * useful to dump unknown tag types rather
00163                          * than just returning an error
00164                          */
00165                         default:
00166                                 slprintf(tagbuf, sizeof(tagbuf)-1, "0x%x",
00167                                          ap->a_type);
00168                                 tag = tagbuf;
00169                                 break;
00170  
00171                         case SMB_ACL_USER:
00172                                 id = uidtoname(ap->uid);
00173                         case SMB_ACL_USER_OBJ:
00174                                 tag = "user";
00175                                 break;
00176 
00177                         case SMB_ACL_GROUP:
00178                                 if ((gr = getgrgid(ap->gid)) == NULL) {
00179                                         slprintf(idbuf, sizeof(idbuf)-1, "%ld",
00180                                                 (long)ap->gid);
00181                                         id = idbuf;
00182                                 } else {
00183                                         id = gr->gr_name;
00184                                 }
00185                         case SMB_ACL_GROUP_OBJ:
00186                                 tag = "group";
00187                                 break;
00188 
00189                         case SMB_ACL_OTHER:
00190                                 tag = "other";
00191                                 break;
00192 
00193                         case SMB_ACL_MASK:
00194                                 tag = "mask";
00195                                 break;
00196 
00197                 }
00198 
00199                 perms[0] = (ap->a_perm & SMB_ACL_READ) ? 'r' : '-';
00200                 perms[1] = (ap->a_perm & SMB_ACL_WRITE) ? 'w' : '-';
00201                 perms[2] = (ap->a_perm & SMB_ACL_EXECUTE) ? 'x' : '-';
00202                 perms[3] = '\0';
00203 
00204                 /*          <tag>      :  <qualifier>   :  rwx \n  \0 */
00205                 nbytes = strlen(tag) + 1 + strlen(id) + 1 + 3 + 1 + 1;
00206 
00207                 /*
00208                  * If this entry would overflow the buffer
00209                  * allocate enough additional memory for this
00210                  * entry and an estimate of another 20 bytes
00211                  * for each entry still to be processed
00212                  */
00213                 if ((len + nbytes) > maxlen) {
00214                         maxlen += nbytes + 20 * (acl_d->count - i);
00215                         if ((text = (char *)SMB_REALLOC(text, maxlen)) == NULL) {
00216                         errno = ENOMEM;
00217                                 return NULL;
00218                 }
00219         }
00220 
00221                 slprintf(&text[len], nbytes-1, "%s:%s:%s\n", tag, id, perms);
00222                 len += nbytes - 1;
00223         }
00224 
00225         if (len_p)
00226                 *len_p = len;
00227 
00228         return text;
00229 }
00230 
00231 SMB_ACL_T sys_acl_init(int count)
00232 {
00233         SMB_ACL_T       a;
00234 
00235         if (count < 0) {
00236                 errno = EINVAL;
00237                 return NULL;
00238         }
00239 
00240         /*
00241          * note that since the definition of the structure pointed
00242          * to by the SMB_ACL_T includes the first element of the
00243          * acl[] array, this actually allocates an ACL with room
00244          * for (count+1) entries
00245          */
00246         if ((a = (struct smb_acl_t *)SMB_MALLOC(
00247                      sizeof(struct smb_acl_t) +
00248                      count * sizeof(struct smb_acl_entry))) == NULL) {
00249                 errno = ENOMEM;
00250                 return NULL;
00251         }
00252  
00253         a->size = count + 1;
00254         a->count = 0;
00255         a->next = -1;
00256 
00257         return a;
00258 }
00259 
00260 int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p)
00261 {
00262         SMB_ACL_T       acl_d;
00263         SMB_ACL_ENTRY_T entry_d;
00264 
00265         if (acl_p == NULL || entry_p == NULL || (acl_d = *acl_p) == NULL) {
00266                 errno = EINVAL;
00267                 return -1;
00268         }
00269 
00270         if (acl_d->count >= acl_d->size) {
00271                 errno = ENOSPC;
00272                 return -1;
00273         }
00274 
00275         entry_d         = &acl_d->acl[acl_d->count++];
00276         entry_d->a_type = SMB_ACL_TAG_INVALID;
00277         entry_d->uid    = -1;
00278         entry_d->gid    = -1;
00279         entry_d->a_perm = 0;
00280         *entry_p        = entry_d;
00281 
00282         return 0;
00283 }
00284 
00285 int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type)
00286 {
00287         switch (tag_type) {
00288                 case SMB_ACL_USER:
00289                 case SMB_ACL_USER_OBJ:
00290                 case SMB_ACL_GROUP:
00291                 case SMB_ACL_GROUP_OBJ:
00292                 case SMB_ACL_OTHER:
00293                 case SMB_ACL_MASK:
00294                         entry_d->a_type = tag_type;
00295                         break;
00296                 default:
00297                         errno = EINVAL;
00298                         return -1;
00299                 }
00300 
00301         return 0;
00302 }
00303 
00304 int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p)
00305 {
00306         if (entry_d->a_type == SMB_ACL_USER) {
00307                 entry_d->uid = *((uid_t *)qual_p);
00308                 return 0;
00309                 }
00310         if (entry_d->a_type == SMB_ACL_GROUP) {
00311                 entry_d->gid = *((gid_t *)qual_p);
00312                 return 0;
00313         }
00314 
00315         errno = EINVAL;
00316         return -1;
00317 }
00318 
00319 int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d)
00320 {
00321         if (*permset_d & ~(SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE)) {
00322                 errno = EINVAL;
00323                 return -1;
00324         }
00325 
00326         entry_d->a_perm = *permset_d;
00327  
00328         return 0;
00329 }
00330 
00331 int sys_acl_free_text(char *text)
00332 {
00333         SAFE_FREE(text);
00334         return 0;
00335 }
00336 
00337 int sys_acl_free_acl(SMB_ACL_T acl_d) 
00338 {
00339         SAFE_FREE(acl_d);
00340         return 0;
00341 }
00342 
00343 int sys_acl_free_qualifier(void *qual, SMB_ACL_TAG_T tagtype)
00344 {
00345         return 0;
00346 }
00347 
00348 int sys_acl_valid(SMB_ACL_T acl_d)
00349 {
00350         errno = EINVAL;
00351         return -1;
00352 }
00353 
00354 /*
00355  * acl_get_file, acl_get_fd, acl_set_file, acl_set_fd and
00356  * sys_acl_delete_def_file are to be redirected to the default
00357  * statically-bound acl vfs module, but they are replacable.
00358  */
00359  
00360 #if defined(HAVE_POSIX_ACLS)
00361  
00362 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle, 
00363                            const char *path_p, SMB_ACL_TYPE_T type)
00364 {
00365         return posixacl_sys_acl_get_file(handle, path_p, type);
00366 }
00367  
00368 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
00369 {
00370         return posixacl_sys_acl_get_fd(handle, fsp, fd);
00371 }
00372  
00373 int sys_acl_set_file(vfs_handle_struct *handle,
00374                      const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
00375 {
00376         return posixacl_sys_acl_set_file(handle, name, type, acl_d);
00377 }
00378  
00379 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
00380                    int fd, SMB_ACL_T acl_d)
00381 {
00382         return posixacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
00383 }
00384 
00385 int sys_acl_delete_def_file(vfs_handle_struct *handle,
00386                             const char *path)
00387 {
00388         return posixacl_sys_acl_delete_def_file(handle, path);
00389 }
00390 
00391 #elif defined(HAVE_AIX_ACLS)
00392 
00393 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
00394                            const char *path_p, SMB_ACL_TYPE_T type)
00395 {
00396         return aixacl_sys_acl_get_file(handle, path_p, type);
00397 }
00398 
00399 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
00400 {
00401         return aixacl_sys_acl_get_fd(handle, fsp, fd);
00402 }
00403 
00404 int sys_acl_set_file(vfs_handle_struct *handle,
00405                      const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
00406 {
00407         return aixacl_sys_acl_set_file(handle, name, type, acl_d);
00408 }
00409 
00410 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
00411                    int fd, SMB_ACL_T acl_d)
00412 {
00413         return aixacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
00414 }
00415 
00416 int sys_acl_delete_def_file(vfs_handle_struct *handle,
00417                             const char *path)
00418 {
00419         return aixacl_sys_acl_delete_def_file(handle, path);
00420 }
00421 
00422 #elif defined(HAVE_TRU64_ACLS)
00423  
00424 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
00425                            const char *path_p, SMB_ACL_TYPE_T type)
00426 {
00427         return tru64acl_sys_acl_get_file(handle, path_p, type);
00428 }
00429 
00430 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
00431 {
00432         return tru64acl_sys_acl_get_fd(handle, fsp, fd);
00433 }
00434 
00435 int sys_acl_set_file(vfs_handle_struct *handle,
00436                      const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
00437 {
00438         return tru64acl_sys_acl_set_file(handle, name, type, acl_d);
00439 }
00440 
00441 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
00442                    int fd, SMB_ACL_T acl_d)
00443 {
00444         return tru64acl_sys_acl_set_fd(handle, fsp, fd, acl_d);
00445 }
00446 
00447 int sys_acl_delete_def_file(vfs_handle_struct *handle,
00448                             const char *path)
00449 {
00450         return tru64acl_sys_acl_delete_def_file(handle, path);
00451 }
00452 
00453 #elif defined(HAVE_SOLARIS_ACLS) || defined(HAVE_UNIXWARE_ACLS)
00454 
00455 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
00456                            const char *path_p, SMB_ACL_TYPE_T type)
00457 {
00458         return solarisacl_sys_acl_get_file(handle, path_p, type);
00459 }
00460 
00461 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
00462 {
00463         return solarisacl_sys_acl_get_fd(handle, fsp, fd);
00464 }
00465 
00466 int sys_acl_set_file(vfs_handle_struct *handle,
00467                      const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
00468 {
00469         return solarisacl_sys_acl_set_file(handle, name, type, acl_d);
00470 }
00471 
00472 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
00473                    int fd, SMB_ACL_T acl_d)
00474 {
00475         return solarisacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
00476 }
00477 
00478 int sys_acl_delete_def_file(vfs_handle_struct *handle,
00479                             const char *path)
00480 {
00481         return solarisacl_sys_acl_delete_def_file(handle, path);
00482 }
00483 
00484 #elif defined(HAVE_HPUX_ACLS)
00485 
00486 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
00487                            const char *path_p, SMB_ACL_TYPE_T type)
00488 {
00489         return hpuxacl_sys_acl_get_file(handle, path_p, type);
00490 }
00491 
00492 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
00493 {
00494         return hpuxacl_sys_acl_get_fd(handle, fsp, fd);
00495 }
00496 
00497 int sys_acl_set_file(vfs_handle_struct *handle,
00498                      const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
00499 {
00500         return hpuxacl_sys_acl_set_file(handle, name, type, acl_d);
00501 }
00502 
00503 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
00504                    int fd, SMB_ACL_T acl_d)
00505 {
00506         return hpuxacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
00507 }
00508 
00509 int sys_acl_delete_def_file(vfs_handle_struct *handle,
00510                             const char *path)
00511 {
00512         return hpuxacl_sys_acl_delete_def_file(handle, path);
00513 }
00514 
00515 #elif defined(HAVE_IRIX_ACLS)
00516 
00517 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
00518                            const char *path_p, SMB_ACL_TYPE_T type)
00519 {
00520         return irixacl_sys_acl_get_file(handle, path_p, type);
00521 }
00522 
00523 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
00524 {
00525         return irixacl_sys_acl_get_fd(handle, fsp, fd);
00526 }
00527 
00528 int sys_acl_set_file(vfs_handle_struct *handle,
00529                      const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
00530 {
00531         return irixacl_sys_acl_set_file(handle, name, type, acl_d);
00532 }
00533 
00534 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
00535                    int fd, SMB_ACL_T acl_d)
00536 {
00537         return irixacl_sys_acl_set_fd(handle, fsp, fd, acl_d);
00538 }
00539 
00540 int sys_acl_delete_def_file(vfs_handle_struct *handle,
00541                             const char *path)
00542 {
00543         return irixacl_sys_acl_delete_def_file(handle, path);
00544 }
00545 
00546 #else /* No ACLs. */
00547 
00548 SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle,
00549                            const char *path_p, SMB_ACL_TYPE_T type)
00550 {
00551 #ifdef ENOTSUP
00552         errno = ENOTSUP;
00553 #else
00554         errno = ENOSYS;
00555 #endif
00556         return NULL;
00557 }
00558 
00559 SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
00560 {
00561 #ifdef ENOTSUP
00562         errno = ENOTSUP;
00563 #else
00564         errno = ENOSYS;
00565 #endif
00566         return NULL;
00567 }
00568 
00569 int sys_acl_set_file(vfs_handle_struct *handle,
00570                      const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d)
00571 {
00572 #ifdef ENOTSUP
00573         errno = ENOTSUP;
00574 #else
00575         errno = ENOSYS;
00576 #endif
00577         return -1;
00578 }
00579 
00580 int sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
00581                    int fd, SMB_ACL_T acl_d)
00582 {
00583 #ifdef ENOTSUP
00584         errno = ENOTSUP;
00585 #else
00586         errno = ENOSYS;
00587 #endif
00588         return -1;
00589 }
00590 
00591 int sys_acl_delete_def_file(vfs_handle_struct *handle,
00592                             const char *path)
00593 {
00594 #ifdef ENOTSUP
00595         errno = ENOTSUP;
00596 #else
00597         errno = ENOSYS;
00598 #endif
00599         return -1;
00600 }
00601 
00602 #endif
00603 
00604 /************************************************************************
00605  Deliberately outside the ACL defines. Return 1 if this is a "no acls"
00606  errno, 0 if not.
00607 ************************************************************************/
00608 
00609 int no_acl_syscall_error(int err)
00610 {
00611 #if defined(ENOSYS)
00612         if (err == ENOSYS) {
00613                 return 1;
00614         }
00615 #endif
00616 #if defined(ENOTSUP)
00617         if (err == ENOTSUP) {
00618                 return 1;
00619         }
00620 #endif
00621         return 0;
00622 }

Sambaに対してSat Aug 29 21:22:59 2009に生成されました。  doxygen 1.4.7