char wd[256];
char t[100], u[100], *p, *path;
int zilch;
- int code;
+ DWORD code;
DWORD dwLow, dwHigh;
HKEY parmKey;
DWORD dummyLen;
long code = 0;
if (cm_freelanceEnabled) {
- StringCbCopyA(ioctlp->outDatap, 999999, "Freelance.Local.Root");
- ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
+ if (cm_GetRootCellName(ioctlp->outDatap))
+ StringCbCopyA(ioctlp->outDatap, 999999, "Freelance.Local.Root");
+ ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
} else if (cm_data.rootCellp) {
/* return the default cellname to the caller */
StringCbCopyA(ioctlp->outDatap, 999999, cm_data.rootCellp->name);
ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
} else {
/* if we don't know our default cell, return failure */
- code = CM_ERROR_NOSUCHCELL;
+ code = CM_ERROR_NOSUCHCELL;
}
return code;
return 1;
}
+static int
+IsFreelanceRoot(char *apath)
+{
+ struct ViceIoctl blob;
+ afs_int32 code;
+
+ blob.in_size = 0;
+ blob.out_size = MAXSIZE;
+ blob.out = space;
+
+ code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
+ if (code == 0)
+ return !strcmp("Freelance.Local.Root",space);
+ return 1; /* assume it is because it is more restrictive that way */
+}
+
/* return a static pointer to a buffer */
static char *
Parent(char *apath)
return mydata;
}
+static DWORD IsFreelance(void)
+{
+ HKEY parmKey;
+ DWORD code;
+ DWORD dummyLen;
+ DWORD enabled = 0;
+
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ dummyLen = sizeof(cm_freelanceEnabled);
+ code = RegQueryValueEx(parmKey, "FreelanceClient", NULL, NULL,
+ (BYTE *) &enabled, &dummyLen);
+ RegCloseKey (parmKey);
+ }
+ return enabled;
+}
+
#define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
-BOOL IsAdmin (void)
+static BOOL IsAdmin (void)
{
static BOOL fAdmin = FALSE;
static BOOL fTested = FALSE;
struct vldbentry vldbEntry;
#endif /* not WIN32 */
struct ViceIoctl blob;
+ char * parent;
/*
volName = ++tmpName;
}
- if (!InAFS(Parent(as->parms[0].items->data))) {
+ parent = Parent(as->parms[0].items->data);
+ if (!InAFS(parent)) {
fprintf(stderr,"%s: mount points must be created within the AFS file system\n", pn);
return 1;
}
+ if ( IsFreelanceRoot(parent) && !IsAdmin() ) {
+ fprintf(stderr,"%s: Only AFS Client Administrators may alter the root.afs volume\n", pn);
+ return 1;
+ }
+
if (!cellName) {
blob.in_size = 0;
blob.out_size = MAXSIZE;
error = 1;
continue; /* don't bother trying */
}
- blob.out_size = 0;
+
+ if ( IsFreelanceRoot(Parent(tp)) && !IsAdmin() ) {
+ fprintf(stderr,"%s: Only AFS Client Administrators may alter the root.afs volume\n", pn);
+ error = 1;
+ continue; /* skip */
+ }
+
+ blob.out_size = 0;
blob.in = tp;
blob.in_size = strlen(tp)+1;
code = pioctl(tbuffer, VIOC_AFS_DELETE_MT_PT, &blob, 0);
ncbp->ncb_length = sizeof(lana_list);
code = Netbios(ncbp);
if (code != 0) {
- osi_Log1(smb_logp, "Netbios NCBENUM error code %d", code);
+ afsi_log("Netbios NCBENUM error code %d", code);
osi_panic(s, __FILE__, __LINE__);
}
}
if (code == 0)
code = ncbp->ncb_retcode;
if (code != 0) {
- osi_Log2(smb_logp, "Netbios NCBRESET lana %d error code %d", lana_list.lana[i], code);
+ afsi_log("Netbios NCBRESET lana %d error code %d", lana_list.lana[i], code);
lana_list.lana[i] = 255; /* invalid lana */
} else {
- osi_Log1(smb_logp, "Netbios NCBRESET lana %d succeeded", lana_list.lana[i]);
+ afsi_log("Netbios NCBRESET lana %d succeeded", lana_list.lana[i]);
}
}
#else
len=lstrlen(smb_localNamep);
memset(smb_sharename,' ',NCBNAMSZ);
memcpy(smb_sharename,smb_localNamep,len);
- osi_Log1(smb_logp, "lana_list.length %d", lana_list.length);
+ afsi_log("lana_list.length %d", lana_list.length);
/* Keep the name so we can unregister it later */
for (l = 0; l < lana_list.length; l++) {
code = Netbios(ncbp, dos_ncb);
#endif /* !DJGPP */
- osi_Log4(smb_logp, "Netbios NCBADDNAME lana=%d code=%d retcode=%d complete=%d",
+ afsi_log("Netbios NCBADDNAME lana=%d code=%d retcode=%d complete=%d",
lana, code, ncbp->ncb_retcode, ncbp->ncb_cmd_cplt);
{
char name[NCBNAMSZ+1];
name[NCBNAMSZ]=0;
memcpy(name,ncbp->ncb_name,NCBNAMSZ);
- osi_Log1(smb_logp, "Netbios NCBADDNAME added new name >%s<",osi_LogSaveString(smb_logp, name));
+ afsi_log("Netbios NCBADDNAME added new name >%s<",name);
}
if (code == 0) code = ncbp->ncb_retcode;
if (code == 0) {
- osi_Log1(smb_logp, "Netbios NCBADDNAME succeeded on lana %d\n", lana);
+ afsi_log("Netbios NCBADDNAME succeeded on lana %d\n", lana);
#ifdef DJGPP
/* we only use one LANA with djgpp */
lana_list.lana[0] = lana;
#endif
}
else {
- osi_Log2(smb_logp, "Netbios NCBADDNAME lana %d error code %d", lana, code);
+ afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
if (code == NRC_BRIDGE) { /* invalid LANA num */
lana_list.lana[l] = 255;
continue;
}
else if (code == NRC_DUPNAME) {
- osi_Log0(smb_logp, "Name already exists; try to delete it");
+ afsi_log("Name already exists; try to delete it");
memset(ncbp, 0, sizeof(*ncbp));
ncbp->ncb_command = NCBDELNAME;
memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
if (code == 0)
code = ncbp->ncb_retcode;
else {
- osi_Log2(smb_logp, "Netbios NCBDELNAME lana %d error code %d\n", lana, code);
+ afsi_log("Netbios NCBDELNAME lana %d error code %d\n", lana, code);
}
if (code != 0 || delname_tried) {
lana_list.lana[l] = 255;
}
}
else {
- osi_Log2(smb_logp, "Netbios NCBADDNAME lana %d error code %d", lana, code);
+ afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
lana_list.lana[l] = 255; /* invalid lana */
osi_panic(s, __FILE__, __LINE__);
}
sprintf(message,"MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
nts, ntsEx);
OutputDebugString(message);
- osi_Log2(smb_logp,"MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
- nts, ntsEx);
+ afsi_log(message);
} else {
OutputDebugString("MsV1_0SetProcessOption success");
- osi_Log0(smb_logp,"MsV1_0SetProcessOption success");
+ afsi_log("MsV1_0SetProcessOption success");
}
/* END - code from Larry */
#include <time.h>
#include <winsock2.h>
#include <errno.h>
+#include <assert.h>
#include <osi.h>
#include <afsint.h>
}
/* this function returns TRUE (1) if the file is in AFS, otherwise false (0) */
-static int InAFS(apath)
-register char *apath; {
+static int InAFS(register char *apath)
+{
struct ViceIoctl blob;
register afs_int32 code;
code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
if (code) {
- if ((errno == EINVAL) || (errno == ENOENT)) return 0;
+ if ((errno == EINVAL) || (errno == ENOENT))
+ return 0;
}
return 1;
}
+static int
+IsFreelanceRoot(char *apath)
+{
+ struct ViceIoctl blob;
+ afs_int32 code;
+
+ blob.in_size = 0;
+ blob.out_size = MAXSIZE;
+ blob.out = space;
+
+ code = pioctl(apath, VIOC_FILE_CELL_NAME, &blob, 1);
+ if (code == 0)
+ return !strcmp("Freelance.Local.Root",space);
+ return 1; /* assume it is because it is more restrictive that way */
+}
+
+#define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
+
+static BOOL IsAdmin (void)
+{
+ static BOOL fAdmin = FALSE;
+ static BOOL fTested = FALSE;
+
+ if (!fTested)
+ {
+ /* Obtain the SID for the AFS client admin group. If the group does
+ * not exist, then assume we have AFS client admin privileges.
+ */
+ PSID psidAdmin = NULL;
+ DWORD dwSize, dwSize2;
+ char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
+ char *pszRefDomain = NULL;
+ SID_NAME_USE snu = SidTypeGroup;
+
+ dwSize = sizeof(pszAdminGroup);
+
+ if (!GetComputerName(pszAdminGroup, &dwSize)) {
+ /* Can't get computer name. We return false in this case.
+ Retain fAdmin and fTested. This shouldn't happen.*/
+ return FALSE;
+ }
+
+ dwSize = 0;
+ dwSize2 = 0;
+
+ strcat(pszAdminGroup,"\\");
+ strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME);
+
+ LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu);
+ /* that should always fail. */
+
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ /* if we can't find the group, then we allow the operation */
+ fAdmin = TRUE;
+ return TRUE;
+ }
+
+ if (dwSize == 0 || dwSize2 == 0) {
+ /* Paranoia */
+ fAdmin = TRUE;
+ return TRUE;
+ }
+
+ psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize);
+ assert(psidAdmin);
+ pszRefDomain = (char *)malloc(dwSize2);
+ assert(pszRefDomain);
+
+ if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) {
+ /* We can't lookup the group now even though we looked it up earlier.
+ Could this happen? */
+ fAdmin = TRUE;
+ } else {
+ /* Then open our current ProcessToken */
+ HANDLE hToken;
+
+ if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
+ {
+
+ if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) {
+ /* We'll have to allocate a chunk of memory to store the list of
+ * groups to which this user belongs; find out how much memory
+ * we'll need.
+ */
+ DWORD dwSize = 0;
+ PTOKEN_GROUPS pGroups;
+
+ GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize);
+
+ pGroups = (PTOKEN_GROUPS)malloc(dwSize);
+ assert(pGroups);
+
+ /* Allocate that buffer, and read in the list of groups. */
+ if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize))
+ {
+ /* Look through the list of group SIDs and see if any of them
+ * matches the AFS Client Admin group SID.
+ */
+ size_t iGroup = 0;
+ for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup)
+ {
+ if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) {
+ fAdmin = TRUE;
+ }
+ }
+ }
+
+ if (pGroups)
+ free(pGroups);
+ }
+
+ /* if do not have permission because we were not explicitly listed
+ * in the Admin Client Group let's see if we are the SYSTEM account
+ */
+ if (!fAdmin) {
+ PTOKEN_USER pTokenUser;
+ SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
+ PSID pSidLocalSystem = 0;
+ DWORD gle;
+
+ GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
+
+ pTokenUser = (PTOKEN_USER)malloc(dwSize);
+ assert(pTokenUser);
+
+ if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
+ gle = GetLastError();
+
+ if (AllocateAndInitializeSid( &SIDAuth, 1,
+ SECURITY_LOCAL_SYSTEM_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &pSidLocalSystem))
+ {
+ if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) {
+ fAdmin = TRUE;
+ }
+
+ FreeSid(pSidLocalSystem);
+ }
+
+ if ( pTokenUser )
+ free(pTokenUser);
+ }
+ }
+ }
+
+ free(psidAdmin);
+ free(pszRefDomain);
+
+ fTested = TRUE;
+ }
+
+ return fAdmin;
+}
+
/* return a static pointer to a buffer */
static char *Parent(apath)
char *apath; {
register struct cmd_syndesc *as; {
register afs_int32 code;
struct ViceIoctl blob;
+ char * parent;
- if (!InAFS(Parent(as->parms[0].items->data))) {
+ parent = Parent(as->parms[0].items->data);
+
+ if (!InAFS(parent)) {
fprintf(stderr,"%s: symlinks must be created within the AFS file system\n", pn);
return 1;
}
+ if ( IsFreelanceRoot(parent) && !IsAdmin() ) {
+ fprintf(stderr,"%s: Only AFS Client Administrators may alter the root.afs volume\n", pn);
+ return 1;
+ }
+
strcpy(space, as->parms[1].items->data);
#ifdef WIN32
/* create symlink with a special pioctl for Windows NT, since it doesn't
code = pioctl(tbuffer, VIOC_LISTSYMLINK, &blob, 0);
if (code) {
if (errno == EINVAL)
- fprintf(stderr,"fs: '%s' is not a symlink.\n", ti->data);
+ fprintf(stderr,"symlink: '%s' is not a symlink.\n", ti->data);
else {
Die(errno, ti->data);
}
continue; /* don't bother trying */
}
+
+ if ( IsFreelanceRoot(Parent(tp)) && !IsAdmin() ) {
+ fprintf(stderr,"symlink: Only AFS Client Administrators may alter the root.afs volume\n");
+ code = 1;
+ continue; /* skip */
+ }
+
blob.out_size = 0;
blob.in = tp;
blob.in_size = strlen(tp)+1;
if (code) {
Die(errno, ti->data);
}
-
}
return code;
}