Added an option to secaudit for getting a user mapping proposal

Get a user mapping proposal by designating a file created on Windows
by the user to be mapped to the current one on Linux.
This is expected to be easier to use than "usermap".
This commit is contained in:
Jean-Pierre André 2012-09-12 09:31:35 +02:00
parent 7c600754dd
commit 2223b8796c

View File

@ -10,6 +10,7 @@
* -h displaying hexadecimal security descriptors within a file
* -r recursing in a directory
* -s setting backed-up NTFS ACLs
* -u getting a user mapping proposal
* -v verbose (very verbose if set twice)
* also, if compile-time option is set
* -t run internal tests (with no access to storage)
@ -198,6 +199,10 @@
* Jul 2012, version 1.3.24
* - added self-tests for authenticated users
* - added display of ace-inherited flag
* - made runnable on OpenIndiana
*
* Aug 2012, version 1.4.0
* - added an option for user mapping proposal
*/
/*
@ -221,7 +226,7 @@
* General parameters which may have to be adapted to needs
*/
#define AUDT_VERSION "1.3.24"
#define AUDT_VERSION "1.4.0"
#define GET_FILE_SECURITY "ntfs_get_file_security"
#define SET_FILE_SECURITY "ntfs_set_file_security"
@ -477,7 +482,9 @@ unsigned int getfull(char*, const char*);
BOOL updatefull(const char *name, DWORD flags, char *attr);
BOOL setfull(const char*, int, BOOL);
BOOL singleshow(const char*);
void showmounted(const char*);
BOOL proposal(const char*, const char*);
BOOL showmounted(const char*);
BOOL processmounted(const char*);
BOOL recurseshow(const char*);
BOOL singleset(const char*, int);
BOOL recurseset(const char*, int);
@ -492,6 +499,7 @@ BOOL iterate(RECURSE, const char*, mode_t);
#else
BOOL backup(const char*, const char*);
BOOL listfiles(const char*, const char*);
BOOL mapproposal(const char*, const char*);
#endif
#if POSIXACLS
BOOL setfull_posix(const char *, const struct POSIX_SECURITY*, BOOL);
@ -639,6 +647,7 @@ BOOL opt_e; /* restore extra (currently windows attribs) */
BOOL opt_h; /* display an hexadecimal descriptor in a file */
BOOL opt_r; /* recursively apply to subdirectories */
BOOL opt_s; /* restore NTFS ACLs */
BOOL opt_u; /* user mapping proposal */
#if SELFTESTS & !USESTUBS
BOOL opt_t; /* run self-tests */
#endif
@ -4648,6 +4657,69 @@ BOOL setfull(const char *fullname, int mode, BOOL isdir)
return (err);
}
BOOL proposal(const char *name, const char *attr)
{
int uoff, goff;
int i;
u64 uauth, gauth;
int ucnt, gcnt;
int uid, gid;
BOOL err;
err = FALSE;
#ifdef WIN32
uid = gid = 0;
#else
uid = getuid();
gid = getgid();
#endif
uoff = get4l(attr,4);
uauth = get6h(attr,uoff+2);
ucnt = attr[uoff+1] & 255;
goff = get4l(attr,8);
gauth = get6h(attr,goff+2);
gcnt = attr[goff+1] & 255;
if ((ucnt == 5) && (gcnt == 5)
&& (uauth == 5) && (gauth == 5)
&& (get4l(attr,uoff+8) == 21) && (get4l(attr,goff+8) == 21)) {
printf("# User mapping proposal\n");
if (uid)
printf("%d::",uid);
else
printf("user::");
printf("S-%d-%llu",attr[uoff] & 255,uauth);
for (i=0; i<ucnt; i++)
printf("-%lu",get4l(attr,uoff+8+4*i));
printf("\n");
if (gid)
printf(":%d:",gid);
else
printf(":group:");
printf("S-%d-%llu",attr[goff] & 255,gauth);
for (i=0; i<gcnt; i++)
printf("-%lu",get4l(attr,goff+8+4*i));
printf("\n");
/* generic rule, based on group */
printf("::S-%d-%llu",attr[goff] & 255,gauth);
for (i=0; i<gcnt-1; i++)
printf("-%lu",get4l(attr,goff+8+4*i));
printf("-10000\n");
if (!uid || !gid) {
printf("# Please replace \"user\" and \"group\" by the uid and gid\n");
printf("# of the Linux owner and group of ");
printname(stdout,name);
printf("\n");
}
} else {
printf("** Not possible : ");
printname(stdout,name);
printf(" was not created by a Windows user\n");
err = TRUE;
}
return (err);
}
#ifdef WIN32
/*
@ -4885,6 +4957,31 @@ BOOL singleshow(const char *fullname)
return (err);
}
BOOL mapproposal(const char *fullname)
{
char attr[256];
ULONG attrsz;
int attrib;
int err;
err = FALSE;
attrsz = 0;
attrib = GetFileAttributesW((LPCWSTR)fullname);
if ((attrib != INVALID_FILE_ATTRIBUTES)
&& GetFileSecurityW((LPCWSTR)fullname,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION,
(char*)attr,256,&attrsz)) {
err = proposal(fullname,attr);
} else {
printf("** Could not access ");
printname(stdout,fullname);
printf("\n");
printerror(stdout);
err = TRUE;
}
return (err);
}
#if POSIXACLS
BOOL recurseset_posix(const char *fullname, const struct POSIX_SECURITY *pxdesc)
@ -5273,7 +5370,7 @@ static ssize_t ntfs_getxattr(const char *path, const char *name, void *value, si
* Display all the parameters associated to a mounted file
*/
void showmounted(const char *fullname)
BOOL showmounted(const char *fullname)
{
static char attr[MAXATTRSZ];
@ -5289,7 +5386,9 @@ void showmounted(const char *fullname)
u32 attrib;
int level;
BOOL isdir;
BOOL err;
err = FALSE;
if (!stat(fullname,&st)) {
isdir = S_ISDIR(st.st_mode);
printf("%s ",(isdir ? "Directory" : "File"));
@ -5360,21 +5459,65 @@ void showmounted(const char *fullname)
if (mapped)
ntfs_free_mapping(context.mapping);
#endif
} else
} else {
printf("Descriptor fails sanity check\n");
errors++;
}
} else {
printf("** Could not get the NTFS ACL, check whether file is on NTFS\n");
errors++;
}
} else
} else {
printf("%s not found\n",fullname);
err = TRUE;
}
return (err);
}
BOOL processmounted(const char *fullname)
{
static char attr[MAXATTRSZ];
struct stat st;
int attrsz;
BOOL err;
err = FALSE;
if (!opt_u)
err = showmounted(fullname);
else
if (!stat(fullname,&st)) {
attrsz = ntfs_getxattr(fullname,"system.ntfs_acl",attr,MAXATTRSZ);
if (attrsz > 0) {
if (opt_v) {
hexdump(attr,attrsz,8);
printf("Computed hash : 0x%08lx\n",
(unsigned long)hash((le32*)attr,attrsz));
}
if (ntfs_valid_descr(attr,attrsz)) {
err = proposal(fullname, attr);
} else {
printf("*** Descriptor fails sanity check\n");
errors++;
}
} else {
printf("** Could not get the NTFS ACL, check whether file is on NTFS\n");
errors++;
}
} else {
printf("%s not found\n",fullname);
err = TRUE;
}
return (err);
}
#else /* HAVE_SETXATTR */
void showmounted(const char *fullname __attribute__((unused)))
BOOL processmounted(const char *fullname __attribute__((unused)))
{
fprintf(stderr,"Not possible on this configuration\n");
fprintf(stderr,"Not possible on this configuration,\n");
fprintf(stderr,"you have to use an unmounted partition\n");
return (TRUE);
}
#endif /* HAVE_SETXATTR */
@ -5688,6 +5831,47 @@ BOOL listfiles(const char *volume, const char *root)
return (err);
}
BOOL mapproposal(const char *volume, const char *name)
{
BOOL err;
u32 attrsz;
int securindex;
char attr[256]; /* header (20) and a couple of SIDs (max 40 each) */
err = FALSE;
if (!getuid() && open_security_api()) {
if (open_volume(volume,MS_RDONLY)) {
attrsz = 0;
securindex = ntfs_get_file_security(ntfs_context,name,
OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION,
(char*)attr,MAXATTRSZ,&attrsz);
if (securindex)
err = proposal(name,attr);
else {
fprintf(stderr,"*** Could not get the ACL of %s\n",
name);
printerror(stdout);
errors++;
}
close_volume(volume);
} else {
fprintf(stderr,"Could not open volume %s\n",volume);
printerror(stdout);
err = TRUE;
}
close_security_api();
} else {
if (getuid())
fprintf(stderr,"This is only possible as root\n");
else
fprintf(stderr,"Could not open security API\n");
err = TRUE;
}
return (err);
}
#endif
#ifndef WIN32
@ -6718,7 +6902,7 @@ int getoptions(int argc, char *argv[])
opt_a = FALSE;
opt_b = FALSE;
opt_e = FALSE;
opt_e = FALSE;
opt_h = FALSE;
#if FORCEMASK
opt_m = FALSE;
@ -6728,6 +6912,7 @@ int getoptions(int argc, char *argv[])
#if SELFTESTS & !USESTUBS
opt_t = FALSE;
#endif
opt_u = FALSE;
opt_v = 0;
xarg = 1;
err = FALSE;
@ -6767,6 +6952,9 @@ int getoptions(int argc, char *argv[])
opt_t = TRUE;
break;
#endif
case 'u' :
opt_u = TRUE;
break;
case 'v' :
opt_v++;
break;
@ -6778,7 +6966,7 @@ int getoptions(int argc, char *argv[])
narg = argc - xarg;
#ifdef WIN32
if ( ((opt_h || opt_s) && (narg > 1))
|| ((opt_r || opt_b) && ((narg < 1) || (narg > 2)))
|| ((opt_r || opt_b || opt_u) && ((narg < 1) || (narg > 2)))
#if SELFTESTS & !USESTUBS
|| (opt_t && (narg > 0))
#endif
@ -6812,6 +7000,8 @@ int getoptions(int argc, char *argv[])
fprintf(stderr," set the security parameters of file to perms\n");
fprintf(stderr," secaudit -r[v] perms directory\n");
fprintf(stderr," set the security parameters of files in directory to perms\n");
fprintf(stderr," secaudit -u file\n");
fprintf(stderr," get a user mapping proposal applicable to file\n");
#if POSIXACLS
fprintf(stderr," Note: perms can be an octal mode or a Posix ACL description\n");
#else
@ -6822,12 +7012,13 @@ int getoptions(int argc, char *argv[])
#else
if ( (opt_h && (narg > 1))
|| (opt_a && (narg != 1))
|| ((opt_r || opt_b || opt_s) && ((narg < 1) || (narg > 3)))
|| ((opt_r || opt_b || opt_s || opt_u)
&& ((narg < 1) || (narg > 3)))
#if SELFTESTS & !USESTUBS
|| (opt_t && (narg > 0))
#endif
|| (opt_e && !opt_s)
|| (!opt_h && !opt_a && !opt_r && !opt_b && !opt_s
|| (!opt_h && !opt_a && !opt_r && !opt_b && !opt_s && !opt_u
#if SELFTESTS & !USESTUBS
&& !opt_t
#endif
@ -6861,8 +7052,12 @@ int getoptions(int argc, char *argv[])
fprintf(stderr," set the security parameters of file to perms\n");
fprintf(stderr," secaudit -r[v] volume perms directory\n");
fprintf(stderr," set the security parameters of files in directory to perms\n");
fprintf(stderr," secaudit -u volume file\n");
fprintf(stderr," get a user mapping proposal applicable to file\n");
#ifdef HAVE_SETXATTR
fprintf(stderr," special case, does not require being root :\n");
fprintf(stderr," special cases, do not require being root :\n");
fprintf(stderr," secaudit -u mounted-file\n");
fprintf(stderr," get a user mapping proposal applicable to mounted file\n");
fprintf(stderr," secaudit [-v] mounted-file\n");
fprintf(stderr," display the security parameters of a mounted file\n");
#endif
@ -7065,23 +7260,27 @@ char *argv[];
filename = (char*)malloc(2*size + 2);
if (filename) {
makeutf16(filename,argv[xarg]);
if (opt_u) {
cmderr = mapproposal(filename);
} else {
#if POSIXACLS
if (local_build_mapping(context.mapping,filename)) {
printf("*** Could not get user mapping data\n");
warnings++;
}
if (local_build_mapping(context.mapping,filename)) {
printf("*** Could not get user mapping data\n");
warnings++;
}
#endif
if (opt_b)
cmderr = backup(filename);
else {
if (opt_r)
cmderr = listfiles(filename);
else
cmderr = singleshow(filename);
}
if (opt_b)
cmderr = backup(filename);
else {
if (opt_r)
cmderr = listfiles(filename);
else
cmderr = singleshow(filename);
}
#if POSIXACLS
ntfs_free_mapping(context.mapping);
ntfs_free_mapping(context.mapping);
#endif
}
free(filename);
} else {
fprintf(stderr,"No more memory\n");
@ -7195,7 +7394,8 @@ char *argv[];
printf("** %u %s found\n",errors,
(errors > 1 ? "errors were" : "error was"));
else
printf("No errors were found\n");
if (!cmderr)
printf("No errors were found\n");
if (!isatty(1)) {
fflush(stdout);
if (warnings)
@ -7280,7 +7480,7 @@ int main(int argc, char *argv[])
if (opt_s)
cmderr = dorestore(argv[xarg],stdin);
else
showmounted(argv[xarg]);
cmderr = processmounted(argv[xarg]);
break;
case 2 :
if (opt_b)
@ -7297,7 +7497,10 @@ int main(int argc, char *argv[])
cmderr = TRUE;
}
} else
cmderr = listfiles(argv[xarg],argv[xarg+1]);
if (opt_u)
cmderr = mapproposal(argv[xarg],argv[xarg+1]);
else
cmderr = listfiles(argv[xarg],argv[xarg+1]);
break;
case 3 :
p = argv[xarg+1];