Пример #1
0
int
Leash_afs_unlog(
    void
    )
{
#ifdef NO_AFS
    return(0);
#else
    long	rc;
    char    HostName[64];
    DWORD   CurrentState;

    if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine)
        return(0);

    CurrentState = 0;
    memset(HostName, '\0', sizeof(HostName));
    gethostname(HostName, sizeof(HostName));
    if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
        return(0);
    if (CurrentState != SERVICE_RUNNING)
        return(0);

    rc = ktc_ForgetAllTokens();

    return(0);
#endif
}
Пример #2
0
static long
GetIoctlHandle(char *fileNamep, HANDLE * handlep)
{
    HKEY hk;
    char *drivep = NULL;
    char netbiosName[MAX_NB_NAME_LENGTH]="AFS";
    DWORD CurrentState = 0;
    char  HostName[64] = "";
    char tbuffer[MAX_PATH]="";
    HANDLE fh;
    char szUser[128] = "";
    char szClient[MAX_PATH] = "";
    char szPath[MAX_PATH] = "";
    NETRESOURCE nr;
    DWORD res;
    DWORD ioctlDebug = IoctlDebug();
    DWORD gle;
    DWORD dwAttrib;
    DWORD dwSize = sizeof(szUser);
    BOOL  usingRDR = FALSE;
    int saveerrno;
    UINT driveType;
    int sharingViolation;

    memset(HostName, '\0', sizeof(HostName));
    gethostname(HostName, sizeof(HostName));
    if (!DisableServiceManagerCheck() &&
        GetServiceStatus(HostName, TEXT("TransarcAFSDaemon"), &CurrentState) == NOERROR &&
        CurrentState != SERVICE_RUNNING)
    {
        if ( ioctlDebug ) {
            saveerrno = errno;
            fprintf(stderr, "pioctl GetServiceStatus(%s) == %d\r\n",
                    HostName, CurrentState);
            errno = saveerrno;
        }
	return -1;
    }

    if (RDR_Ready()) {
        usingRDR = TRUE;

        if ( ioctlDebug ) {
            saveerrno = errno;
            fprintf(stderr, "pioctl Redirector is ready\r\n");
            errno = saveerrno;
        }

        if (RegOpenKey (HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY, &hk) == 0)
        {
            DWORD dwSize = sizeof(netbiosName);
            DWORD dwType = REG_SZ;
            RegQueryValueExA (hk, "NetbiosName", NULL, &dwType, (PBYTE)netbiosName, &dwSize);
            RegCloseKey (hk);

            if ( ioctlDebug ) {
                saveerrno = errno;
                fprintf(stderr, "pioctl NetbiosName = \"%s\"\r\n", netbiosName);
                errno = saveerrno;
            }
        } else {
            if ( ioctlDebug ) {
                saveerrno = errno;
                gle = GetLastError();
                fprintf(stderr, "pioctl Unable to open \"HKLM\\%s\" using NetbiosName = \"AFS\" GLE=0x%x\r\n",
                        HostName, CurrentState, gle);
                errno = saveerrno;
            }
        }
    } else {
        if ( ioctlDebug ) {
            saveerrno = errno;
            fprintf(stderr, "pioctl Redirector is not ready\r\n");
            errno = saveerrno;
        }

        if (!GetEnvironmentVariable("AFS_PIOCTL_SERVER", netbiosName, sizeof(netbiosName)))
            lana_GetNetbiosName(netbiosName,LANA_NETBIOS_NAME_FULL);

        if ( ioctlDebug ) {
            saveerrno = errno;
            fprintf(stderr, "pioctl NetbiosName = \"%s\"\r\n", netbiosName);
            errno = saveerrno;
        }
    }

    if (fileNamep) {
        drivep = strchr(fileNamep, ':');
        if (drivep && (drivep - fileNamep) >= 1) {
            tbuffer[0] = *(drivep - 1);
            tbuffer[1] = ':';
            tbuffer[2] = '\0';

            driveType = GetDriveType(tbuffer);
            switch (driveType) {
            case DRIVE_UNKNOWN:
            case DRIVE_REMOTE:
                if (DriveIsMappedToAFS(tbuffer, netbiosName) ||
                    DriveIsGlobalAutoMapped(tbuffer))
                    strcpy(&tbuffer[2], SMB_IOCTL_FILENAME);
                else
                    return -1;
                break;
            default:
                if (DriveIsGlobalAutoMapped(tbuffer))
                    strcpy(&tbuffer[2], SMB_IOCTL_FILENAME);
                else
                    return -1;
            }
        } else if (fileNamep[0] == fileNamep[1] &&
		   (fileNamep[0] == '\\' || fileNamep[0] == '/'))
        {
            int count = 0, i = 0;

            while (count < 4 && fileNamep[i]) {
                tbuffer[i] = fileNamep[i];
                if ( tbuffer[i] == '\\' ||
		     tbuffer[i] == '/')
                    count++;
		i++;
            }
            if (fileNamep[i] == 0 || (fileNamep[i-1] != '\\' && fileNamep[i-1] != '/'))
                tbuffer[i++] = '\\';
            tbuffer[i] = 0;
            strcat(tbuffer, SMB_IOCTL_FILENAME_NOSLASH);
        } else {
            char curdir[MAX_PATH]="";

            GetCurrentDirectory(sizeof(curdir), curdir);
            if ( curdir[1] == ':' ) {
                tbuffer[0] = curdir[0];
                tbuffer[1] = ':';
                tbuffer[2] = '\0';

                driveType = GetDriveType(tbuffer);
                switch (driveType) {
                case DRIVE_UNKNOWN:
                case DRIVE_REMOTE:
                    if (DriveIsMappedToAFS(tbuffer, netbiosName) ||
                        DriveIsGlobalAutoMapped(tbuffer))
                        strcpy(&tbuffer[2], SMB_IOCTL_FILENAME);
                    else
                        return -1;
                    break;
                default:
                    if (DriveIsGlobalAutoMapped(tbuffer))
                        strcpy(&tbuffer[2], SMB_IOCTL_FILENAME);
                    else
                        return -1;
                }
            } else if (curdir[0] == curdir[1] &&
                       (curdir[0] == '\\' || curdir[0] == '/'))
            {
                int count = 0, i = 0;

                while (count < 4 && curdir[i]) {
                    tbuffer[i] = curdir[i];
		    if ( tbuffer[i] == '\\' ||
			 tbuffer[i] == '/')
			count++;
		    i++;
                }
                if (curdir[i] == 0 || (curdir[i-1] != '\\' && curdir[i-1] != '/'))
                    tbuffer[i++] = '\\';
                tbuffer[i] = 0;
                strcat(tbuffer, SMB_IOCTL_FILENAME_NOSLASH);
            }
        }
    }
    if (!tbuffer[0]) {
        /* No file name starting with drive colon specified, use UNC name */
        sprintf(tbuffer,"\\\\%s\\all%s",netbiosName,SMB_IOCTL_FILENAME);
    }

    if ( ioctlDebug ) {
        saveerrno = errno;
        fprintf(stderr, "pioctl filename = \"%s\"\r\n", tbuffer);
        errno = saveerrno;
    }

    fflush(stdout);

    /*
     * Try to find the correct path and authentication
     */
    dwAttrib = GetFileAttributes(tbuffer);
    if (dwAttrib == INVALID_FILE_ATTRIBUTES) {
        int  gonext = 0;

        gle = GetLastError();
        if (gle && ioctlDebug ) {
            char buf[4096];

            saveerrno = errno;
            if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                               NULL,
                               gle,
                               MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
                               buf,
                               4096,
                               NULL
                               ) )
            {
                fprintf(stderr,"pioctl GetFileAttributes(%s) failed: 0x%X\r\n\t[%s]\r\n",
                        tbuffer,gle,buf);
            }
            errno = saveerrno;
            SetLastError(gle);
        }

        /* with the redirector interface, fail immediately.  there is nothing to retry */
        if (usingRDR)
            return -1;

        if (!GetEnvironmentVariable("AFS_PIOCTL_SERVER", szClient, sizeof(szClient)))
            lana_GetNetbiosName(szClient, LANA_NETBIOS_NAME_FULL);

        if (RegOpenKey (HKEY_CURRENT_USER,
                         TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hk) == 0)
        {
            DWORD dwType = REG_SZ;
            RegQueryValueEx (hk, TEXT("Logon User Name"), NULL, &dwType, (PBYTE)szUser, &dwSize);
            RegCloseKey (hk);
        }

        if ( szUser[0] ) {
            if ( ioctlDebug ) {
                saveerrno = errno;
                fprintf(stderr, "pioctl Explorer logon user: [%s]\r\n",szUser);
                errno = saveerrno;
            }
            sprintf(szPath, "\\\\%s", szClient);
            memset (&nr, 0x00, sizeof(NETRESOURCE));
            nr.dwType=RESOURCETYPE_DISK;
            nr.lpLocalName=0;
            nr.lpRemoteName=szPath;
            res = WNetAddConnection2(&nr,NULL,szUser,0);
            if (res) {
                if ( ioctlDebug ) {
                    saveerrno = errno;
                    fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                             szPath,szUser,res);
                    errno = saveerrno;
                }
                gonext = 1;
            }

            sprintf(szPath, "\\\\%s\\all", szClient);
            res = WNetAddConnection2(&nr,NULL,szUser,0);
            if (res) {
                if ( ioctlDebug ) {
                    saveerrno = errno;
                    fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                             szPath,szUser,res);
                    errno = saveerrno;
                }
                gonext = 1;
            }

            if (gonext)
                goto try_lsa_principal;

            dwAttrib = GetFileAttributes(tbuffer);
            if (dwAttrib == INVALID_FILE_ATTRIBUTES) {
                gle = GetLastError();
                if (gle && ioctlDebug ) {
                    char buf[4096];

                    saveerrno = errno;
                    if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                                        NULL,
                                        gle,
                                        MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
                                        buf,
                                        4096,
                                        NULL
                                        ) )
                    {
                        fprintf(stderr,"pioctl GetFileAttributes(%s) failed: 0x%X\r\n\t[%s]\r\n",
                                 tbuffer,gle,buf);
                    }
                    errno = saveerrno;
                    SetLastError(gle);
                }
            }
        }
    }

  try_lsa_principal:
    if (!usingRDR &&
        dwAttrib == INVALID_FILE_ATTRIBUTES) {
        int  gonext = 0;

        dwSize = sizeof(szUser);
        if (GetLSAPrincipalName(szUser, dwSize)) {
            if ( ioctlDebug ) {
                saveerrno = errno;
                fprintf(stderr, "pioctl LSA Principal logon user: [%s]\r\n",szUser);
                errno = saveerrno;
            }
            sprintf(szPath, "\\\\%s", szClient);
            memset (&nr, 0x00, sizeof(NETRESOURCE));
            nr.dwType=RESOURCETYPE_DISK;
            nr.lpLocalName=0;
            nr.lpRemoteName=szPath;
            res = WNetAddConnection2(&nr,NULL,szUser,0);
            if (res) {
                if ( ioctlDebug ) {
                    saveerrno = errno;
                    fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                             szPath,szUser,res);
                    errno = saveerrno;
                }
                gonext = 1;
            }

            sprintf(szPath, "\\\\%s\\all", szClient);
            res = WNetAddConnection2(&nr,NULL,szUser,0);
            if (res) {
                if ( ioctlDebug ) {
                    saveerrno = errno;
                    fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                             szPath,szUser,res);
                    errno = saveerrno;
                }
                gonext = 1;
            }

            if (gonext)
                goto try_sam_compat;

            dwAttrib = GetFileAttributes(tbuffer);
            if (dwAttrib == INVALID_FILE_ATTRIBUTES) {
                gle = GetLastError();
                if (gle && ioctlDebug ) {
                    char buf[4096];

                    saveerrno = errno;
                    if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                                        NULL,
                                        gle,
                                        MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
                                        buf,
                                        4096,
                                        NULL
                                        ) )
                    {
                        fprintf(stderr,"pioctl GetFileAttributes(%s) failed: 0x%X\r\n\t[%s]\r\n",
                                 tbuffer,gle,buf);
                    }
                    errno = saveerrno;
                    SetLastError(gle);
                }
            }
        }
    }

  try_sam_compat:
    if (!usingRDR &&
        dwAttrib == INVALID_FILE_ATTRIBUTES) {
        dwSize = sizeof(szUser);
        if (GetUserNameEx(NameSamCompatible, szUser, &dwSize)) {
            if ( ioctlDebug ) {
                saveerrno = errno;
                fprintf(stderr, "pioctl SamCompatible logon user: [%s]\r\n",szUser);
                errno = saveerrno;
            }
            sprintf(szPath, "\\\\%s", szClient);
            memset (&nr, 0x00, sizeof(NETRESOURCE));
            nr.dwType=RESOURCETYPE_DISK;
            nr.lpLocalName=0;
            nr.lpRemoteName=szPath;
            res = WNetAddConnection2(&nr,NULL,szUser,0);
            if (res) {
                if ( ioctlDebug ) {
                    saveerrno = errno;
                    fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                             szPath,szUser,res);
                    errno = saveerrno;
                }
            }

            sprintf(szPath, "\\\\%s\\all", szClient);
            res = WNetAddConnection2(&nr,NULL,szUser,0);
            if (res) {
                if ( ioctlDebug ) {
                    saveerrno = errno;
                    fprintf(stderr, "pioctl WNetAddConnection2(%s,%s) failed: 0x%X\r\n",
                             szPath,szUser,res);
                    errno = saveerrno;
                }
                return -1;
            }

            dwAttrib = GetFileAttributes(tbuffer);
            if (dwAttrib == INVALID_FILE_ATTRIBUTES) {
                gle = GetLastError();
                if (gle && ioctlDebug ) {
                    char buf[4096];

                    saveerrno = errno;
                    if ( FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                                        NULL,
                                        gle,
                                        MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),
                                        buf,
                                        4096,
                                        NULL
                                        ) )
                    {
                        fprintf(stderr,"pioctl GetFileAttributes(%s) failed: 0x%X\r\n\t[%s]\r\n",
                                 tbuffer,gle,buf);
                    }
                    errno = saveerrno;
                }
                return -1;
            }
        } else {
            fprintf(stderr, "GetUserNameEx(NameSamCompatible) failed: 0x%X\r\n", GetLastError());
            return -1;
        }
    }

    if ( dwAttrib != (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) {
        fprintf(stderr, "GetFileAttributes(%s) returned: 0x%08X\r\n",
                tbuffer, dwAttrib);
        return -1;
    }

    /* tbuffer now contains the correct path; now open the file */
    sharingViolation = 0;
    do {
        if (sharingViolation)
            Sleep(100);
        fh = CreateFile(tbuffer, FILE_READ_DATA | FILE_WRITE_DATA,
                        FILE_SHARE_READ, NULL, OPEN_EXISTING,
                        FILE_FLAG_WRITE_THROUGH, NULL);
        sharingViolation++;
    } while (fh == INVALID_HANDLE_VALUE &&
             GetLastError() == ERROR_SHARING_VIOLATION &&
             sharingViolation < 100);
    fflush(stdout);

    if (fh == INVALID_HANDLE_VALUE)
        return -1;

    /* return fh and success code */
    *handlep = fh;
    return 0;
}
Пример #3
0
bool ServiceEventContext::IsValid() const {
  return GetServiceStatus() != NULL
    && GetServiceTask() != NULL
    && GetServiceSettings() != NULL;
}
Пример #4
0
int
not_an_API_LeashAFSGetToken(
    TICKETINFO * ticketinfo,
    TicketList** ticketList,
    char * kerberosPrincipal
    )
{
#ifdef NO_AFS
    return(0);
#else
    struct ktc_principal    aserver;
    struct ktc_principal    aclient;
    struct ktc_token        atoken;
    int                     EndMonth;
    int                     EndDay;
    int                     cellNum;
    int                     BreakAtEnd;
    char                    UserName[64];
    char                    CellName[64];
    char                    ServiceName[64];
    char                    InstanceName[64];
    char                    EndTime[16];
    char                    Buffer[256];
    char                    Months[12][4] = {"Jan\0", "Feb\0", "Mar\0", "Apr\0", "May\0", "Jun\0", "Jul\0", "Aug\0", "Sep\0", "Oct\0", "Nov\0", "Dec\0"};
    char                    TokenStatus[16];
    time_t                  CurrentTime;
    struct tm               *newtime;
    DWORD                   CurrentState;
    DWORD                   rc;
    char                    HostName[64];


    TicketList* list = NULL;
    if ( ticketinfo ) {
        ticketinfo->btickets = NO_TICKETS;
        ticketinfo->principal[0] = '\0';
    }
    if ( !kerberosPrincipal )
        kerberosPrincipal = "";

    if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine)
        return(0);

    CurrentState = 0;
    memset(HostName, '\0', sizeof(HostName));
    gethostname(HostName, sizeof(HostName));
    if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
        return(0);
    if (CurrentState != SERVICE_RUNNING)
        return(0);

    BreakAtEnd = 0;
    cellNum = 0;
    while (1)
    {
        if (rc = ktc_ListTokens(cellNum, &cellNum, &aserver))
        {
            if (rc != KTC_NOENT)
                return(0);

            if (BreakAtEnd == 1)
                break;
        }
        BreakAtEnd = 1;
        memset(&atoken, '\0', sizeof(atoken));
        if (rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient))
        {
            if (rc == KTC_ERROR)
                return(0);

            continue;
        }

        if (!list)
        {
            list = (TicketList*) calloc(1, sizeof(TicketList));
            (*ticketList) = list;
        }
        else
        {
            list->next = (struct TicketList*) calloc(1, sizeof(TicketList));
            list = (TicketList*) list->next;
        }

        CurrentTime = time(NULL);

        newtime = localtime(&atoken.endTime);

        memset(UserName, '\0', sizeof(UserName));
        strcpy(UserName, aclient.name);

        memset(CellName, '\0', sizeof(CellName));
        strcpy(CellName, aclient.cell);

        memset(InstanceName, '\0', sizeof(InstanceName));
        strcpy(InstanceName, aclient.instance);

        memset(ServiceName, '\0', sizeof(ServiceName));
        strcpy(ServiceName, aserver.name);

        memset(TokenStatus, '\0', sizeof(TokenStatus));

        EndDay = newtime->tm_mday;

        EndMonth = newtime->tm_mon + 1;;

        sprintf(EndTime, "%02d:%02d:%02d", newtime->tm_hour, newtime->tm_min, newtime->tm_sec);

        sprintf(Buffer,"                          %s %02d %s      %s%s%s@%s  %s",
                Months[EndMonth - 1], EndDay, EndTime,
                UserName,
                InstanceName[0] ? "." : "",
                InstanceName,
                CellName,
                TokenStatus);

        list->theTicket = (char*) calloc(1, sizeof(Buffer));
        if (!list->theTicket)
        {
#ifdef USE_MESSAGE_BOX
            MessageBox(NULL, "Memory Error", "Error", MB_OK);
#endif /* USE_MESSAGE_BOX */
            return ENOMEM;
        }

        strcpy(list->theTicket, Buffer);
        list->name = strdup(aclient.name);
        list->inst = aclient.instance[0] ? strdup(aclient.instance) : NULL;
        list->realm = strdup(aclient.cell);
        list->encTypes = NULL;
        list->addrCount = 0;
        list->addrList = NULL;

        if ( ticketinfo ) {
            sprintf(Buffer,"%s@%s",UserName,CellName);
            if (!ticketinfo->principal[0] || !stricmp(Buffer,kerberosPrincipal)) {
                strcpy(ticketinfo->principal, Buffer);
                ticketinfo->issue_date = 0;
                ticketinfo->lifetime = atoken.endTime;
                ticketinfo->renew_till = 0;

                _tzset();
                if ( ticketinfo->lifetime - time(0) <= 0L )
                    ticketinfo->btickets = EXPD_TICKETS;
                else
                    ticketinfo->btickets = GOOD_TICKETS;
            }
        }
    }
    return(0);
#endif
}
Пример #5
0
int
Leash_afs_klog(
    char *service,
    char *cell,
    char *realm,
    int LifeTime
    )
{
/////#ifdef NO_AFS
#if defined(NO_AFS) || defined(NO_KRB4)
    return(0);
#else
    long	rc;
////This is defined in krb.h:
    CREDENTIALS	creds;
    KTEXT_ST	ticket;
    struct ktc_principal	aserver;
    struct ktc_principal	aclient;
    char	realm_of_user[REALM_SZ]; /* Kerberos realm of user */
    char	realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */
    char	local_cell[MAXCELLCHARS+1];
    char	Dmycell[MAXCELLCHARS+1];
    struct ktc_token	atoken;
    struct ktc_token	btoken;
    afsconf_cell	ak_cellconfig; /* General information about the cell */
    char	RealmName[128];
    char	CellName[128];
    char	ServiceName[128];
    DWORD       CurrentState;
    char        HostName[64];
    BOOL        try_krb5 = 0;
    int         retry = 0;
    int         len;
#ifndef NO_KRB5
    krb5_context  context = 0;
    krb5_ccache  _krb425_ccache = 0;
    krb5_creds increds;
    krb5_creds * k5creds = 0;
    krb5_error_code r;
    krb5_principal client_principal = 0;
    krb5_flags		flags = 0;
#endif /* NO_KRB5 */

    if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine)
        return(0);

    if ( !realm ) realm = "";
    if ( !cell )  cell = "";
    if ( !service ) service = "";

    CurrentState = 0;
    memset(HostName, '\0', sizeof(HostName));
    gethostname(HostName, sizeof(HostName));
    if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
        return(0);
    if (CurrentState != SERVICE_RUNNING)
        return(0);

    memset(RealmName, '\0', sizeof(RealmName));
    memset(CellName, '\0', sizeof(CellName));
    memset(ServiceName, '\0', sizeof(ServiceName));
    memset(realm_of_user, '\0', sizeof(realm_of_user));
    memset(realm_of_cell, '\0', sizeof(realm_of_cell));
    memset(Dmycell, '\0', sizeof(Dmycell));

    // NULL or empty cell returns information on local cell
    if (cell && cell[0])
        strcpy(Dmycell, cell);
    rc = get_cellconfig(Dmycell, &ak_cellconfig, local_cell);
    if (rc && cell && cell[0]) {
        memset(Dmycell, '\0', sizeof(Dmycell));
        rc = get_cellconfig(Dmycell, &ak_cellconfig, local_cell);
    }
    if (rc)
        return(rc);

#ifndef NO_KRB5
    if (!(r = Leash_krb5_initialize(&context, &_krb425_ccache))) {
        int i;

        memset((char *)&increds, 0, sizeof(increds));

        (*pkrb5_cc_get_principal)(context, _krb425_ccache, &client_principal);
        i = krb5_princ_realm(context, client_principal)->length;
        if (i > REALM_SZ-1)
            i = REALM_SZ-1;
        strncpy(realm_of_user,krb5_princ_realm(context, client_principal)->data,i);
        realm_of_user[i] = 0;
        try_krb5 = 1;
    }
#endif /* NO_KRB5 */

#ifndef NO_KRB4
    if ( !try_krb5 || !realm_of_user[0] ) {
        if ((rc = (*pkrb_get_tf_realm)((*ptkt_string)(), realm_of_user)) != KSUCCESS)
        {
            return(rc);
        }
    }
#endif
    strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig));

    if (strlen(service) == 0)
        strcpy(ServiceName, "afs");
    else
        strcpy(ServiceName, service);

    if (strlen(cell) == 0)
        strcpy(CellName, local_cell);
    else
        strcpy(CellName, cell);

    if (strlen(realm) == 0)
        strcpy(RealmName, realm_of_cell);
    else
        strcpy(RealmName, realm);

    memset(&creds, '\0', sizeof(creds));

#ifndef NO_KRB5
    if ( try_krb5 ) {
        /* First try Service/Cell@REALM */
        if (r = (*pkrb5_build_principal)(context, &increds.server,
                                      strlen(RealmName),
                                      RealmName,
                                      ServiceName,
                                      CellName,
                                      0))
        {
            try_krb5 = 0;
            goto use_krb4;
        }

        increds.client = client_principal;
        increds.times.endtime = 0;
        /* Ask for DES since that is what V4 understands */
        increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;

#ifdef KRB5_TC_NOTICKET
        flags = 0;
        r = pkrb5_cc_set_flags(context, _krb425_ccache, flags);
#endif
        if (r == 0)
            r = pkrb5_get_credentials(context, 0, _krb425_ccache, &increds, &k5creds);
        if (r == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
			r == KRB5KRB_ERR_GENERIC /* Heimdal */) {
            /* Next try Service@REALM */
            pkrb5_free_principal(context, increds.server);
            r = pkrb5_build_principal(context, &increds.server,
                                      strlen(RealmName),
                                      RealmName,
                                      ServiceName,
                                      0);
            if (r == 0)
                r = pkrb5_get_credentials(context, 0, _krb425_ccache, &increds, &k5creds);
        }

        pkrb5_free_principal(context, increds.server);
        pkrb5_free_principal(context, client_principal);
#ifdef KRB5_TC_NOTICKET
        flags = KRB5_TC_NOTICKET;
        pkrb5_cc_set_flags(context, _krb425_ccache, flags);
#endif
        (void) pkrb5_cc_close(context, _krb425_ccache);
        _krb425_ccache = 0;

        if (r || k5creds == 0) {
            pkrb5_free_context(context);
            try_krb5 = 0;
            goto use_krb4;
        }

        /* This code inserts the entire K5 ticket into the token
         * No need to perform a krb524 translation which is
         * commented out in the code below
         */
        if ( use_krb524() || k5creds->ticket.length > MAXKTCTICKETLEN )
            goto try_krb524d;

        memset(&aserver, '\0', sizeof(aserver));
        strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1);
        strncpy(aserver.cell, CellName, MAXKTCREALMLEN - 1);

        memset(&atoken, '\0', sizeof(atoken));
        atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
        atoken.startTime = k5creds->times.starttime;
        atoken.endTime = k5creds->times.endtime;
        memcpy(&atoken.sessionKey, k5creds->keyblock.contents, k5creds->keyblock.length);
        atoken.ticketLen = k5creds->ticket.length;
        memcpy(atoken.ticket, k5creds->ticket.data, atoken.ticketLen);

      retry_gettoken5:
        rc = ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient);
        if (rc != 0 && rc != KTC_NOENT && rc != KTC_NOCELL) {
            if ( rc == KTC_NOCM && retry < 20 ) {
                Sleep(500);
                retry++;
                goto retry_gettoken5;
            }
            goto try_krb524d;
        }

        if (atoken.kvno == btoken.kvno &&
             atoken.ticketLen == btoken.ticketLen &&
             !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) &&
             !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen))
        {
            /* Success */
            pkrb5_free_creds(context, k5creds);
            pkrb5_free_context(context);
            return(0);
        }

        // * Reset the "aclient" structure before we call ktc_SetToken.
        // * This structure was first set by the ktc_GetToken call when
        // * we were comparing whether identical tokens already existed.

        len = min(k5creds->client->data[0].length,MAXKTCNAMELEN - 1);
        strncpy(aclient.name, k5creds->client->data[0].data, len);
        aclient.name[len] = '\0';

        if ( k5creds->client->length > 1 ) {
            char * p;
            strcat(aclient.name, ".");
            p = aclient.name + strlen(aclient.name);
            len = min(k5creds->client->data[1].length,MAXKTCNAMELEN - strlen(aclient.name) - 1);
            strncpy(p, k5creds->client->data[1].data, len);
            p[len] = '\0';
        }
        aclient.instance[0] = '\0';

        strcpy(aclient.cell, realm_of_cell);

        len = min(k5creds->client->realm.length,strlen(realm_of_cell));
        if ( strncmp(realm_of_cell, k5creds->client->realm.data, len) ) {
            char * p;
            strcat(aclient.name, "@");
            p = aclient.name + strlen(aclient.name);
            len = min(k5creds->client->realm.length,MAXKTCNAMELEN - strlen(aclient.name) - 1);
            strncpy(p, k5creds->client->realm.data, len);
            p[len] = '\0';
        }

        rc = ktc_SetToken(&aserver, &atoken, &aclient, 0);
        if (!rc) {
            /* Success */
            pkrb5_free_creds(context, k5creds);
            pkrb5_free_context(context);
            return(0);
        }

      try_krb524d:
        /* This requires krb524d to be running with the KDC */
        r = pkrb524_convert_creds_kdc(context, k5creds, &creds);
        pkrb5_free_creds(context, k5creds);
		pkrb5_free_context(context);
        if (r) {
            try_krb5 = 0;
            goto use_krb4;
        }
        rc = KSUCCESS;
    } else
#endif /* NO_KRB5 */
    {
      use_krb4:
	rc = KFAILURE;
    }
    if (rc != KSUCCESS)
    {
            return(rc);
    }

	memset(&aserver, '\0', sizeof(aserver));
    strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1);
    strncpy(aserver.cell, CellName, MAXKTCNAMELEN - 1);

    memset(&atoken, '\0', sizeof(atoken));
    atoken.kvno = creds.kvno;
    atoken.startTime = creds.issue_date;
    atoken.endTime = (*pkrb_life_to_time)(creds.issue_date,creds.lifetime);
    memcpy(&atoken.sessionKey, creds.session, 8);
    atoken.ticketLen = creds.ticket_st.length;
    memcpy(atoken.ticket, creds.ticket_st.dat, atoken.ticketLen);

    if (!(rc = ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient)) &&
        atoken.kvno == btoken.kvno &&
        atoken.ticketLen == btoken.ticketLen &&
        !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) &&
        !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen))
    {
        return(0);
    }

    // * Reset the "aclient" structure before we call ktc_SetToken.
    // * This structure was first set by the ktc_GetToken call when
    // * we were comparing whether identical tokens already existed.

    strncpy(aclient.name, creds.pname, MAXKTCNAMELEN - 1);
    aclient.name[MAXKTCNAMELEN - 1] = '\0';
    if (creds.pinst[0])
    {
        strncat(aclient.name, ".", MAXKTCNAMELEN - 1 - strlen(aclient.name));
        aclient.name[MAXKTCNAMELEN - 1] = '\0';
        strncat(aclient.name, creds.pinst, MAXKTCNAMELEN - 1 - strlen(aclient.name));
        aclient.name[MAXKTCNAMELEN - 1] = '\0';
    }
    strcpy(aclient.instance, "");

    if ( strcmp(realm_of_cell, creds.realm) )
    {
        strncat(aclient.name, "@", MAXKTCNAMELEN - 1 - strlen(aclient.name));
        aclient.name[MAXKTCNAMELEN - 1] = '\0';
        strncat(aclient.name, creds.realm, MAXKTCNAMELEN - 1 - strlen(aclient.name));
        aclient.name[MAXKTCNAMELEN - 1] = '\0';
    }
    aclient.name[MAXKTCNAMELEN-1] = '\0';

    strcpy(aclient.cell, CellName);

    // * NOTE: On WIN32, the order of SetToken params changed...
    // * to   ktc_SetToken(&aserver, &aclient, &atoken, 0)
    // * from ktc_SetToken(&aserver, &atoken, &aclient, 0) on Unix...
    // * The afscompat ktc_SetToken provides the Unix order

    if (rc = ktc_SetToken(&aserver, &atoken, &aclient, 0))
    {
        Leash_afs_error(rc, "ktc_SetToken()");
        return(rc);
    }

    return(0);
#endif
}
Пример #6
0
void
ObtainTokensFromUserIfNeeded(HWND hWnd)
{
    char * rootcell = NULL;
    char   cell[MAXCELLCHARS+1] = "";
    char   password[PROBE_PASSWORD_LEN+1];
    struct afsconf_cell cellconfig;
    struct ktc_principal    aserver;
    struct ktc_principal    aclient;
    struct ktc_token	atoken;
    krb5_timestamp now = 0;
    BOOL serverReachable = 0;
    int rc;
    DWORD       CurrentState, code;
    char        HostName[64];
    int         use_kfw = KFW_is_available();

    SYSTEMTIME stNow;
    FILETIME ftNow;
    LONGLONG llNow;
    FILETIME ftExpires;
    LONGLONG llExpires;
    SYSTEMTIME stExpires;

    CurrentState = 0;
    memset(HostName, '\0', sizeof(HostName));
    gethostname(HostName, sizeof(HostName));
    if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
        return;
    if (CurrentState != SERVICE_RUNNING) {
        SendMessage(hWnd, WM_START_SERVICE, FALSE, 0L);
        return;
    }

    rootcell = (char *)GlobalAlloc(GPTR,MAXCELLCHARS+1);
    if (!rootcell) 
        goto cleanup;

    code = KFW_AFS_get_cellconfig(cell, (void*)&cellconfig, rootcell);
    if (code) 
        goto cleanup;

    memset(&aserver, '\0', sizeof(aserver));
    strcpy(aserver.name, "afs");
    strcpy(aserver.cell, rootcell);

    GetLocalTime (&stNow);
    SystemTimeToFileTime (&stNow, &ftNow);
    llNow = (((LONGLONG)ftNow.dwHighDateTime) << 32) + (LONGLONG)(ftNow.dwLowDateTime);
    llNow /= c100ns1SECOND;

    rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient);
    if ( rc == 0 ) {
        TimeToSystemTime (&stExpires, atoken.endTime);
        SystemTimeToFileTime (&stExpires, &ftExpires);
        llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime);
        llExpires /= c100ns1SECOND;

        if (llNow < llExpires)
            goto cleanup;

        if ( IsDebuggerPresent() ) {
            char message[256];
            sprintf(message,"ObtainTokensFromUserIfNeeded: %d  now = %ul  endTime = %ul\n",
                     rc, llNow, llExpires);
            OutputDebugString(message);
        }
    }

#ifdef USE_FSPROBE
    serverReachable = cellPing(NULL);
#else
    if (use_kfw) {
        // If we can't use the FSProbe interface we can attempt to forge
        // a kinit and if we can back an invalid user error we know the
        // kdc is at least reachable
        serverReachable = KFW_probe_kdc(&cellconfig);
    } else {
        int i;

        for ( i=0 ; i<PROBE_PASSWORD_LEN ; i++ )
            password[i] = 'x';

        code = ObtainNewCredentials(rootcell, PROBE_USERNAME, password, TRUE);
        switch ( code ) {
        case INTK_BADPW:
        case KERB_ERR_PRINCIPAL_UNKNOWN:
        case KERB_ERR_SERVICE_EXP:
        case RD_AP_TIME:
            serverReachable = TRUE;
            break;
        default:
            serverReachable = FALSE;
        }
    }
#endif
    if ( !serverReachable ) {
        if ( IsDebuggerPresent() )
            OutputDebugString("Server Unreachable\n");
        goto cleanup;
    }

    if ( IsDebuggerPresent() )
        OutputDebugString("Server Reachable\n");

    if ( use_kfw ) {
#ifdef USE_MS2MIT
        KFW_import_windows_lsa();
#endif /* USE_MS2MIT */
        KFW_AFS_renew_expiring_tokens();
        KFW_AFS_renew_token_for_cell(rootcell);

        rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient);
        if ( rc == 0 ) {
            TimeToSystemTime (&stExpires, atoken.endTime);
            SystemTimeToFileTime (&stExpires, &ftExpires);
            llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime);
            llExpires /= c100ns1SECOND;
        
            if (llNow < llExpires)
                goto cleanup;
        }
    }

    SendMessage(hWnd, WM_OBTAIN_TOKENS, FALSE, (long)rootcell);
    rootcell = NULL;    // rootcell freed by message receiver

  cleanup:
    if (rootcell)
        GlobalFree(rootcell);

    return;
}