{
krb5_context ctx = 0;
krb5_ccache cc = 0;
- char * realm = 0;
- char ** realmlist = 0;
+ char * realm = 0, * userrealm = 0;
krb5_principal principal = 0;
char * pname = 0;
krb5_error_code code;
code = KFW_AFS_get_cellconfig( cell, (void*)&cellconfig, local_cell);
if ( code ) goto cleanup;
- realm = strchr(username,'@');
- if ( realm ) {
+ realm = afs_realm_of_cell(ctx, &cellconfig); // do not free
+ userrealm = strchr(username,'@');
+ if (userrealm) {
pname = strdup(username);
- realm = strchr(pname, '@');
- *realm = '\0';
+ userrealm = strchr(pname, '@');
+ *userrealm = '\0';
/* handle kerberos iv notation */
while ( dot = strchr(pname,'.') ) {
*dot = '/';
}
- *realm++ = '@';
+ *userrealm++ = '@';
} else {
- realm = afs_realm_of_cell(ctx, &cellconfig); // do not free
pname = malloc(strlen(username) + strlen(realm) + 2);
strcpy(pname, username);
{
static char lastcell[MAXCELLCHARS+1] = { 0 };
static char confname[512] = { 0 };
+#ifdef AFS_ID_TO_NAME
char username_copy[BUFSIZ];
+#endif /* AFS_ID_TO_NAME */
long viceId; /* AFS uid of user */
int status = 0;
#ifdef ALLOW_REGISTER
{
long rc = 0;
CREDENTIALS creds;
+#ifdef USE_KRB4
KTEXT_ST ticket;
+#endif /* USE_KRB4 */
struct ktc_principal aserver;
struct ktc_principal aclient;
char realm_of_user[REALM_SZ]; /* Kerberos realm of user */
krb5_creds * k5creds = 0;
krb5_error_code code;
krb5_principal client_principal = 0;
+ krb5_data * k5data;
int i, retry = 0;
CurrentState = 0;
goto skip_krb5_init;
}
- if ( strchr(krb5_princ_component(ctx,client_principal,0),'.') != NULL )
+ /* lookfor client principals which cannot be distinguished
+ * from Kerberos 4 multi-component principal names
+ */
+ k5data = krb5_princ_component(ctx,client_principal,0);
+ for ( i=0; i<k5data->length; i++ ) {
+ if ( k5data->data[i] == '.' )
+ break;
+ }
+ if (i != k5data->length)
{
OutputDebugString("Illegal Principal name contains dot in first component\n");
rc = KRB5KRB_ERR_GENERIC;
* in either the free list or in the LRU queue. A read lock prevents someone
* from modifying the list(s), and a write lock is required for modifying
* the list. The actual data stored in the randomUid and randomAccess fields
- * is actually maintained as up-to-date or not via the scache llock.
+ * is actually maintained as up-to-date or not via the scache lock.
* An aclent structure is free if it has no back vnode pointer.
*/
osi_rwlock_t cm_aclLock; /* lock for system's aclents */
cm_aclent_t *cm_aclLRUp; /* LRUQ for dudes in vnode's lists */
cm_aclent_t *cm_aclLRUEndp; /* ditto */
+
+/* This function must be called with cm_aclLock and the aclp->back_mx held */
+static void CleanupACLEnt(cm_aclent_t * aclp)
+{
+ cm_aclent_t *taclp;
+ cm_aclent_t **laclpp;
+
+ if (aclp->backp) {
+ /*
+ * Remove the entry from the vnode's list
+ */
+ laclpp = &aclp->backp->randomACLp;
+ for ( taclp = *laclpp; taclp; laclpp = &taclp->nextp, taclp = *laclpp ) {
+ if (taclp == aclp)
+ break;
+ }
+ if (!taclp)
+ osi_panic("CleanupACLEnt race",__FILE__,__LINE__);
+ *laclpp = aclp->nextp; /* remove from the vnode's list */
+ aclp->backp = NULL;
+ }
+
+ /* release the old user */
+ if (aclp->userp) {
+ cm_ReleaseUser(aclp->userp);
+ aclp->userp = NULL;
+ }
+
+ aclp->randomAccess = 0;
+ aclp->tgtLifetime = 0;
+}
+
/*
* Get an acl cache entry for a particular user and file, or return that it doesn't exist.
* Called with the scp locked.
long retval = -1;
lock_ObtainWrite(&cm_aclLock);
+ *rightsp = 0; /* get a new acl from server if we don't find a
+ * current entry
+ */
for (aclp = scp->randomACLp; aclp; aclp = aclp->nextp) {
if (aclp->userp == userp) {
- if (aclp->tgtLifetime && aclp->tgtLifetime <= (long) osi_Time()) {
+ if (aclp->tgtLifetime && aclp->tgtLifetime <= osi_Time()) {
/* ticket expired */
- aclp->tgtLifetime = 0;
- *rightsp = 0; /* get a new acl from server */
-
- /* Shouldn't we remove this entry from the scp?
- * 2005-01-25 - jaltman@secure-endpoints.com
- */
+ osi_QRemove((osi_queue_t **) &cm_aclLRUp, &aclp->q);
+ CleanupACLEnt(aclp);
+ osi_QAddT((osi_queue_t **) &cm_aclLRUp,
+ (osi_queue_t **) &cm_aclLRUEndp,
+ &aclp->q);
} else {
*rightsp = aclp->randomAccess;
if (cm_aclLRUEndp == aclp)
static cm_aclent_t *GetFreeACLEnt(void)
{
cm_aclent_t *aclp;
- cm_aclent_t *taclp;
- cm_aclent_t **laclpp;
if (cm_aclLRUp == NULL)
osi_panic("empty aclent LRU", __FILE__, __LINE__);
aclp = cm_aclLRUEndp;
- if (aclp == cm_aclLRUEndp)
- cm_aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q);
+ cm_aclLRUEndp = (cm_aclent_t *) osi_QPrev(&aclp->q);
osi_QRemove((osi_queue_t **) &cm_aclLRUp, &aclp->q);
- if (aclp->backp) {
- /*
- * Remove the entry from the vnode's list
- */
- laclpp = &aclp->backp->randomACLp;
- for (taclp = *laclpp; taclp; laclpp = &taclp->nextp, taclp = *laclpp) {
- if (taclp == aclp)
- break;
- }
- if (!taclp)
- osi_panic("GetFreeACLEnt race", __FILE__, __LINE__);
- *laclpp = aclp->nextp; /* remove from vnode list */
- aclp->backp = NULL;
- }
-
- /* release the old user */
- if (aclp->userp) {
- cm_ReleaseUser(aclp->userp);
- aclp->userp = NULL;
- }
+ CleanupACLEnt(aclp);
return aclp;
}
struct cm_scache *backp; /* back ptr to vnode */
struct cm_user *userp; /* user whose access is cached */
long randomAccess; /* watch for more rights in acl.h */
- long tgtLifetime; /* time this expires */
+ unsigned long tgtLifetime; /* time this expires */
} cm_aclent_t;
extern osi_rwlock_t cm_aclLock;
// BOOL : TRUE/FALSE (match/mistmatch)
BOOL
-szWildCardMatchFileName(PSZ pattern, PSZ name)
+szWildCardMatchFileName(PSZ pattern, PSZ name, int casefold)
{
PSZ pename; // points to the last 'name' character
PSZ p;
if (*pattern == '\0')
return TRUE;
for (p = pename; p >= name; --p) {
- if ((mapCaseTable[*p] == mapCaseTable[*pattern]) &&
- szWildCardMatchFileName(pattern + 1, p + 1))
+ if ((casefold && (mapCaseTable[*p] == mapCaseTable[*pattern]) ||
+ !casefold && (*p == *pattern)) &&
+ szWildCardMatchFileName(pattern + 1, p + 1, casefold))
return TRUE;
} /* endfor */
return FALSE;
default:
- if (mapCaseTable[*name] != mapCaseTable[*pattern])
+ if ((casefold && mapCaseTable[*name] != mapCaseTable[*pattern]) ||
+ (!casefold && *name != *pattern))
return FALSE;
++pattern, ++name;
break;
int smb_V3MatchMask(char *namep, char *maskp, int flags)
{
char * newmask;
- int i, j, star, qmark, retval;
+ int i, j, star, qmark, casefold, retval;
/* make sure we only match 8.3 names, if requested */
if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep))
return 0;
+ casefold = (flags & CM_FLAG_CASEFOLD) ? 1 : 0;
+
/* optimize the pattern:
* if there is a mixture of '?' and '*',
* for example the sequence "*?*?*?*"
}
newmask[j++] = '\0';
- retval = szWildCardMatchFileName(newmask, namep) ? 1:0;
+ retval = szWildCardMatchFileName(newmask, namep, casefold) ? 1:0;
free(newmask);
return retval;
}
if (scp->fileType != CM_SCACHETYPE_FILE) {
- if (dscp)
- cm_ReleaseSCache(dscp);
+ if (dscp)
+ cm_ReleaseSCache(dscp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
/* (only applies to single component case) */
if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
cm_ReleaseSCache(scp);
- cm_ReleaseSCache(dscp);
+ if (dscp)
+ cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
return CM_ERROR_NOTDIR;