ActiveDirectoryのユーザアカウントのパスワード有効期限を取得するには?

解決


どら  2010-03-17 14:20:27  No: 71483  IP: [192.*.*.*]

いつもお世話になっております。
Win XP Pro SP2 + VS.net 2008(SDK)で表題の処理を行うツールを開発してい
ます。

ADSIをいろいろ調べて、ADのルートDNからGetメソッドで「maxPwdAge」を取得
し、ユーザの最終パスワード変更日時(「pwdLastSet」と思われる)を取得し、
これらの値から計算できるっぽい事までわかりました。

Getメソッドで、上記2つの値は取得できるのですが、取得した値のvtを確認す
ると9(VT_DISPATCH)となっておりました。

IDispatchに関して少し調べてみたのですが、何が何やら・・・(汗)

この取得した値からパスワードの有効期限を取得するにはどの様にすればよい
のでしょうか?
また、もっと簡単に取得する方法があるのでしょうか?

ご存じの方いらっしゃいましたら、ご教授お願いいたします。

exe実行ユーザのパスワードの有効期限を取得しようとして書きかけのソース
を以下に記載しておきます。

    BSTR l_bstrUserPath = NULL;
    VARIANT l_verDomainName;
    VARIANT l_verMaxPassAge;
    VARIANT l_verLastPassChange;
    IADsADSystemInfo *l_ADSISysInfo;
    IADs *l_pIADs;
    WCHAR *l_pwUserPath = NULL;
    WCHAR *l_pwDomain = NULL;

    //RootDSEからADのパスワード寿命を取得
    if(FAILED(ADsGetObject(L"LDAP://RootDSE", IID_IADs, (void**) &l_pIADs)))
    {
        return FALSE;
    }
    if(FAILED(l_pIADs->Get(L"defaultNamingContext", &l_verDomainName)))
    {
        l_pIADs->Release();
        return FALSE;
    }

    l_pwDomain = new WCHAR[lstrlen(L"LDAP://") + lstrlen(l_verDomainName.bstrVal) + 1];
    if(l_pwDomain == NULL)
    {
        VariantClear(&l_verDomainName);
        l_pIADs->Release();
        return FALSE;
    }

    lstrcpy(l_pwDomain, L"LDAP://");
    lstrcat(l_pwDomain, l_verDomainName.bstrVal);
    l_pwDomain[lstrlen(L"LDAP://") + lstrlen(l_verDomainName.bstrVal)] = L'\0';


    l_pIADs->Release();
    if(FAILED(ADsGetObject(l_pwDomain, IID_IADs, (void**) &l_pIADs)))
    {
        if(l_pwDomain != NULL)
        {
            delete[] l_pwDomain;
            l_pwDomain = NULL;
        }
        return FALSE;
    }

    if(l_pwDomain != NULL)
    {
        delete[] l_pwDomain;
        l_pwDomain = NULL;
    }

    if(FAILED(l_pIADs->Get(L"maxPwdAge", &l_verMaxPassAge)))
    {
        l_pIADs->Release();
        return FALSE;
    }

    l_pIADs->Release();

    //ログオンユーザの
    if(FAILED(CoCreateInstance(CLSID_ADSystemInfo, NULL, CLSCTX_INPROC_SERVER, IID_IADsADSystemInfo, (void**)&l_ADSISysInfo)))
    {
        return FALSE;
    }

    if(FAILED(l_ADSISysInfo->get_UserName(&l_bstrUserPath)))
    {
        l_ADSISysInfo->Release();
        return FALSE;
    }

    l_pwUserPath = new WCHAR[lstrlen(L"LDAP://") + lstrlen(l_bstrUserPath) + 1];
    if(l_pwUserPath == NULL)
    {
        l_ADSISysInfo->Release();
        return FALSE;
    }

    lstrcpy(l_pwUserPath, L"LDAP://");
    lstrcat(l_pwUserPath, l_bstrUserPath);
    l_pwUserPath[lstrlen(L"LDAP://") + lstrlen(l_bstrUserPath)] = L'\0';

    if(FAILED(ADsGetObject(l_pwUserPath, IID_IADs, (void**) &l_pIADs)))
    {
        if(l_pwUserPath != NULL)
        {
            delete[] l_pwUserPath;
            l_pwUserPath = NULL;
        }
        l_ADSISysInfo->Release();
        return FALSE;
    }

    //パスワードの最終変更日時を取得
    if(FAILED(l_pIADs->Get(L"pwdLastSet", &l_verLastPassChange)))
    {
        if(l_pwUserPath != NULL)
        {
            delete[] l_pwUserPath;
            l_pwUserPath = NULL;
        }
        l_ADSISysInfo->Release();
        return FALSE;
    }

    //各種解放処理
    VariantClear(&l_verMaxPassAge);
    VariantClear(&l_verLastPassChange);
    l_pIADs->Release();
    if(l_pwUserPath != NULL)
    {
        delete[] l_pwUserPath;
        l_pwUserPath = NULL;
    }
    l_ADSISysInfo->Release();
    SysFreeString(l_bstrUserPath);
    return TRUE;

編集 削除
オショウ  2010-03-18 02:19:07  No: 71484  IP: [192.*.*.*]

過去ログ検索しましたか?

http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200906/09060015.txt

で、有用な情報があると思うんですが・・・

以上。参考まで

編集 削除
どら  2010-03-18 15:11:10  No: 71485  IP: [192.*.*.*]

オショウさん

ありがとうございます!!
大変参考になり、無事取得することができました。
(get_PasswordExpirationDateはLDAP://ではなくWijnNT://でとってこないと
いけないんですね。GetUserNameExでユーザ名を取得する事にしました^^)

本当にありがとうございました!!

参考にする人はいないと思いますが、作成したソースを抜粋しておきます。

      IADsUser *lpIADsUser;
      WCHAR *l_pwUserPath = NULL;
      DATE l_PasswordExpirationDate;
      SYSTEMTIME l_stPasswordExpirationDate;

      WCHAR UserName[1024];
      DWORD lenUserName;


      //「domain\user」でユーザ名を取得
      GetUserNameEx(NameSamCompatible, UserName, &lenUserName);

      //「\」→「/」に置換(「domain/user」にする)
      for(;lenUserName > 0; lenUserName--)
      {
            if(UserName[lenUserName] == L'\\')
            {
                  UserName[lenUserName] = L'/';
            }
      }


      //ADSIで情報を取得するための文字列を作成()
      l_pwUserPath = new WCHAR[lstrlen(L"WinNT://") + lstrlen(UserName) + 1];
      if(l_pwUserPath == NULL)
      {
            return FALSE;
      }
      lstrcpy(l_pwUserPath, L"WinNT://");
      lstrcat(l_pwUserPath, UserName);
      l_pwUserPath[lstrlen(L"WinNT://") + lstrlen(UserName)] = L'\0';

      //ユーザ情報を取得
      if(FAILED(ADsGetObject(l_pwUserPath, IID_IADsUser, (void**) &lpIADsUser)))
      {
            //各種解放処理
            if(l_pwUserPath != NULL)
            {
                  delete[] l_pwUserPath;
                  l_pwUserPath = NULL;
            }
            return FALSE;
      }

      //パスワード有効期限取得
      if(FAILED(lpIADsUser->get_PasswordExpirationDate(&l_PasswordExpirationDate)))
      {
            MessageBox(NULL, L"パスワード有効期限取得失敗", L"Debug", MB_OK);
            //各種解放処理
            if(l_pwUserPath != NULL)
            {
                  delete[] l_pwUserPath;
                  l_pwUserPath = NULL;
            }
            return FALSE;
      }

      //(必要があれば)VARIANT Time をSystemTimeに変換
//    VariantTimeToSystemTime((DOUBLE)l_PasswordExpirationDate, &l_stPasswordExpirationDate);
      


      //各種解放処理
      lpIADsUser->Release();
      if(l_pwUserPath != NULL)
      {
            delete[] l_pwUserPath;
            l_pwUserPath = NULL;
      }
      return TRUE;

編集 削除