התחברות לשרת ldap

התחברות לשרת ldap

כהמשך לשאלה ששאלתי לפני כחודש.
מצב נתון:
אצל הלקוח יש שרת LDAP ואני צריך לבדוק מולו הרשאות של משתמשים. שחזרתי את המכונה של הלקוח עד כמה שיכולתי אצלנו, ובדקתי מולה.
קוד הפיתון שמצורף כקובץ TXT, נכתב ספציפית לבדיקות: (המערכת האמיתית מן הסתם תשתמש בחלק מהקוד הזה)



התוצאה במשרד (מול שרת הבדיקות):
$$>test_ldap_grps_1.pyFilter == (&(objectClass=user)(cn=ca4))
results == [('CN=ca4,DC=test,DC=local,DC=domain', {'primaryGroupID': ['513'], 'logonCount': ['0'], 'cn': ['ca4'], 'countryCode': ['0'], 'dSCorePropagationData': ['16010101000000.0Z'], 'objectClass': ['top', 'person', 'organizationalPerson', 'user'], 'userPrincipalName': ['[email protected]'], 'lastLogonTimestamp': ['130606496321699064'], 'instanceType': ['4'], 'distinguishedName': ['CN=ca4,DC=test,DC=local,DC=domain'], 'sAMAccountType': ['805306368'], 'objectSid': ['\x01\x05\x00\x00\x00\x00\x00\x05\x15\x00\x00\x00\xc4Jy\x08K\xc94\x8e\x8f\x1e\xcd\x96W\x04\x00\x00'], 'whenCreated': ['20140601213859.0Z'], 'uSNCreated': ['12788'], 'badPasswordTime': ['130606517298027248'], 'pwdLastSet': ['130591819072140892'], 'sAMAccountName': ['ca4'], 'objectCategory': ['CN=Person,CN=Schema,CN=Configuration,DC=test,DC=local,DC=domain'], 'objectGUID': ['\xb4\xb8.\x8ah\x00\x84M\x84\xe4\xd5\xa3\xe2)\x84\x7f'], 'whenChanged': ['20141116221352.0Z'], 'badPwdCount': ['0'], 'accountExpires': ['9223372036854775807'], 'displayName': ['ca4'], 'name': ['ca4'], 'memberOf': ['CN=ca_manager,DC=test,DC=local,DC=domain', 'CN=ca_tech,DC=test,DC=local,DC=domain', 'CN=ca_change,DC=test,DC=local,DC=domain', 'CN=ca,DC=test,DC=local,DC=domain'], 'codePage': ['0'], 'userAccountControl': ['66048'], 'lastLogon': ['130606528359838513'], 'uSNChanged': ['41278'], 'givenName': ['ca4'], 'lastLogoff': ['0']}), (None, ['ldap://ForestDnsZones.test.local.domain/DC=ForestDnsZones,DC=test,DC=local,DC=domain']), (None, ['ldap://DomainDnsZones.test.local.domain/DC=DomainDnsZones,DC=test,DC=local,DC=domain']), (None, ['ldap://test.local.domain/CN=Configuration,DC=test,DC=local,DC=domain'])]
['ca_manager', 'ca_tech', 'ca_change', 'ca']
התוצאה על רשת הלקוח:
$$>test_ldap_grps_1.py
Filter == (&(objectClass=user)(cn=ca4))
results == [('CN=ca4,DC=test,DC=local,DC=domain', None)]
None
בשני המקרים אפשר לראות שלא היתה בעיה של כניסה למערכת (אין שגיאת credentials ), אבל המערכת האמיתית החזירה פחות נתונים ממה שציפיתי.
1. למישהו יש רעיון היכן שגיתי בבניית הsearch או הפילטר?
2. אם יש פה freelancer, שיודע לפתור את הבעיה ומוכן לבוא לשטח (הלקוח שלנו הוא חברה גדולה, אז אני לא יכול להוציא שרת מהמפעלים שלהם...), אשמח אם ייצור קשר שאוכל לבקש הצעת מחיר (קשר בנושא זה - בבקשה רק במסר).

גיא.
 

thinking8

New member
יש מצב שנגעת בקוד?

על פניו התשאול נכון, ייתכן שבפניה אתה מבקש רק שדות מסויימים ועל כל לא מקבל תשובה.
בנוסף אתה יכול לבצע את אותה הפניה מכלי בשם Softerra LDAP Administrator 2013.1 (64-bit)
ולבדוק מה התוצאה.
 
ברור שנגעתי בקוד


מפני שהזנתי כhard-code את שם המשתמש, הססמא וכתובת השרת.
בכל אופן, אלו השדות היחידים ששיניתי. שרת הproduction הוא "לא שלי", ואין לי אפשרות להתקין עליו תוכנות נוספות (פיתון זמין לי, כולל המודולים שהגדרתי מראש שאצטרך). הפניה זהה בין שתי המערכות (בחלק ההוא של הקוד לא שיניתי). הגדרות האבטחה אצל הלקוח "מחמירות" (כשהגשתי בשוגג שאילתה על "objectClass=group", קיבלתי הסבר ש"זה אסור" לאחר הודעת השגיאה מהמערכת).
 

yossik111

New member
לא מכיר את הפייתון , אבל אינטואיטיבית

אין מצב שאחד מה return statements מוציא אותך החוצה "לפני הזמן" ?
ניתן לדבג זאת בקלות יחסית (להבנתי ) על ידי שתילה זמנית של פקודות הדפסה מחרוזות מתאימות לפני כול return statement שכזה .
שוב , לא מתעסק עם פייתון (בשלב זה ) אבל אני מניח שזה שניתן לעשות זאת (אם ב php ניתן אזי נראה לי שבפייתון ודאי (כמו בעצם בכול שפה / סקריפט תיכנות (לפחות ברובם))).
יוס.
 
מנסה להבין היכן להוסיף את ההדפסות

הקוד שמחזיר את הנתונים הוא:
&nbsp
results = l.search_s(dn_recs, ldap.SCOPE_SUBTREE, f_filterStr)
&nbsp
לפניו יש לי רק עובדת המשתמש binded, ואחריו יש מה שהודפס.
&nbsp
על כל פנים, קיבלתי המלצה בפורום אחר להעלות את רמת הlog ולקרוא שם, אנסה בפעם הבאה שאוכל להגיע ללקוח.
 

yossik111

New member
בהתבסס על קטע הקוד שלך

הוספתי משהוא מאד גולמי ואינטואיטיבי - השורות עם הספרות והקוים (שוב , לא מכיר את הפייתון (סינטקס - כמו למשל קטע סגירת ותיחום הלולאות) - אבל הרעיון אני מניח ברור .
אני מניח (אלא אם אני מפספס כאן משהוא ) שזה יכול לעזור לך בעניין הדיבאגינג בקטע שתדע בדיוק היכן יוצא קטע הקוד / התוכנית וכ'ו ומה הוא מספיק לבצע עד אז .
יוס.
 
שים לב, הערך שמגיע במקור לפונקציה

get_membership_from_answer - כבר לא כולל את הנתונים (צרפתי פלט של results עוד לפני הparsing של הפונקציה המדוברת. באיבר של המילון שבמערכת ה"בדיקות" החזיר את רשימת הקבוצות שהמשתמש משוייך להן, במערכת ה"אמיתית" החזיר None (המקבילה של פיתון לnull).
&nbsp
 

yossik111

New member
כן שמתי לב עכשיו (שנכנסתי קצת יותר לקוד

,הייתי חייב לרוץ בבוקר לסידורים)
כלומר הבעייה (להבנתי) היא בתוצא של
search_s(dn_recs, ldap.SCOPE_SUBTREE, f_filterStr)
הייתי בונה קוד מזוקק (לבדיקה כמובן ) שמתבסס רק על הפעולה הנ"ל ומנסה כול מני מניפולציות עם הארגומנטים (פרמטרים ) .
אני לא מכיר את האובייקט הנ"ל של ה ldap וה methods /options שלו ויותר מכך איזה ארגומנטים הוא/הם יכולים לקבל אך יתכן שהוא מרשה מספר משתנה של ארגומטים (ואפילו אחד ) כך שאתה יכול לרדת לרזלוצית בדיקה מאד קטנה ולראות למשל מהו הארגומנט הבעייתי .
שוב , מתנצל , לא מכיר את האובייקט הנ" כלל ויתכן שאני מדבר כלל לא לעניין , אבל הצעתי שיטה לבדיקה (שאם היא ישימה , קרוב לוודאי שניסית אותה כבר
)
יוס.
 

thinking8

New member
תבדוק מה מקבל הערך של f_filterStr

יכול להיות שזה מבקש דברים מסויימים בלבד
 
הערך של f_filterStr זהה בשני המקרים

Filter == (&(objectClass=user)(cn=ca4))
(מתוך הדפסת הdebug של המערכת).
 

isackris

New member
למה לא לבקש את ה memberof attribute ישירות בקריאה ל search

יחסוך תעבורת רשת ויתכן שהשרת לא מסכים להחזיר את כל ה attributes
&nbsp
הייתי מציע לעשות נסיונות עם ldapsearch הסניטקס דומה, ולבדוק מה הולך וחוזר ב wireshark
&nbsp
והאבטחה שם משעשעת.. "זה אסור" אוי, סליחה..
 
הידע שלי בAD נמוך למדי

אבדוק ביום א' מה שהמלצת. (רק במחשב המקומי, כי להגיע ללקוח זה "סיפור").
לצערי אצל הלקוח לא אוכל להתקין wireshark. (אולי אצליח לשכנע את הIT שלהם לאפשר לי, קשה להאמין).
 

F00D Is G00D

New member
עם איזה הרשאות אתה מתשאל את ה ldap?

Anonymous במקרה? (אתה מתחבר עם יוזר כלשהוא? או פשוט מתחיל לתשאל?)
אם כן, זה ייכול להסביר למה בסביבה אחת אתה מקבל תוצאות, והשנייה לא מאפשרת anonymous
&nbsp
ובשביל לפתור את זה - או שתמציא לעצמך יוזר אפליקטיבי, או שתשתמש במשתמשסיסמא שאותם אתה גם מאמת בשביל לעשות גם את בשאילתות או שתעבוד עם פתרון אוטנטיקציה/קרברוס מוכן לפייתון (זה גם ייכול לחסוך לך טעויות אפשריות, ובדיקות קלט)
&nbsp
אגב, אני מניח שאפשר גם לעשות שאילתה יותר מהירה ופשוט לשאול את ldap האם יוזר x חבר בקבוצה y ולקבל תשובה בולייאנית.
ייחסוך לך את הפרסור של המידע.
 
השתמשתי בשם המשתמש והססמא אותם קיבלתי

והידע שלי "לוקה בחסר", ולא הצלחתי למצוא בגוגל איך לשאול "האם X (או האם אני) חבר בקבוצה Y". יתכן מאד שלמשתמש אותו הגדירו לי, אין הרשאות לתשאל מעבר למה שהמלצת.
 

isackris

New member
LDAP

זה עץ היררכי של entities, לכל entity יש DN המורכב מה CN שלו ומהמיקום שלו בעץ.
&nbsp
בנוסף לכל entity יש attributes and values, לדוגמה ב AD לכל user or group יתכנו מספר memberOf attributes כך ש ה value של כל אחד מהם זה ה DN של group אליו משתייך ה user באופן ישיר (אין תמיכה ב nested, ניתן להשיג עם קריאות רקורסיביות).
&nbsp
כמו שהזכרתי לעיל, כשמבצעים שאילתא ניתן לציין שאתה מעוניין אך ורק ב attributes מסוימים כגון memberOf בקריאה ל search_s בפרמטר האחרון, ראה:
http://www.python-ldap.org/doc/html/ldap.html
&nbsp
מניח שניתן גם לערוך את הפילטר בכדי שבכלל יחזיר תשובה רק אם ה user נמצא בקבוצה, ע"י שתוסיף memberOf=FULL_DN_OF_THE_GROUP
אבל גם באופן זה הייתי ממליץ לציין את ה attributes בהם את מעוניין.
&nbsp
שים לב ש CN ב AD לא בהכרח זהה ל username ה CN זה מה שאתה רואה בעץ של ADUAC לעומת זאת ה username זה ה sAMAccountName attribute בטאב פנימי (בשרתי LDAP סטנדרטים בד"כ ה username יהיה ה uid).
&nbsp
אתה לא חייב wireshark on site אתה יכול לשמור עם tcpdump ולפתוח עם wireshark אח"כ.
&nbsp
שים לב שלעיתים הגדרות אבטחה בצד שרת לא יאפשרו שאילתות ללא SSL אז שווה לנסות גם.
 

F00D Is G00D

New member


הנה דוגמא שניסיתי עכשיו אצלי במעבדה שמחזירה את היוזר, אם הוא אכן חבר בקבוצה:
(sAMAccountName=F00D)(memberof:1.2.840.113556.1.4.1941:=CN=GR_SuperLabSrv5_Admins,OU=OU_Groups,DC=SuperLab,DC=local)


F00D= My user name
memberof:1.2.840.113556.1.4.1941 = Means look in different group levels, That’s to allow nested groups.
SuperLabSrv5_Admins = The group I’m checking against

מצטער שאנחנו עדיין לא מגיעים למטרה.. ישבתי קצת לקרוא ובגדול פייטון פשוט לא מספיק ידידותית (כולל התוספים) בשביל לעשות את זה כמו שצריך, אלא באמת רק ע"י השאילתות... יש ספריה שכביכול מאפשרת יותר (pywin32) אבל אני לא רואה שכ"כ משתמשים בה..
 

isackris

New member
example

not sure it will help but it's better ldap wise..

# python tapuz.py |sed s/real/example/g
Filter == (&(objectClass=user)(cn=administrator))
results == [('CN=Administrator,CN=Users,DC=example,DC=com', {'memberOf': ['CN=tst_grp_cn,CN=Users,DC=example,DC=com', 'CN=Group Policy Creator Owners,CN=Users,DC=example,DC=com', 'CN=Domain Admins,CN=Users,DC=example,DC=com', 'CN=Enterprise Admins,CN=Users,DC=example,DC=com', 'CN=Schema Admins,CN=Users,DC=example,DC=com', 'CN=Administrators,CN=Builtin,DC=example,DC=com']}), (None, ['ldap://ForestDnsZones.example.com/DC=ForestDnsZones,DC=example,DC=com']), (None, ['ldap://DomainDnsZones.example.com/DC=DomainDnsZones,DC=example,DC=com']), (None, ['ldap://example.com/CN=Configuration,DC=example,DC=com'])]

['tst_grp_cn', 'Group Policy Creator Owners', 'Domain Admins', 'Enterprise Admins', 'Schema Admins', 'Administrators']
 

yossik111

New member
הפעלת audit של ה AD (או יתכן בכלל שהוא מופעל כבר)

לא אמורה לתת לך תשובה ( על ידי רשומה מתאימה ב EV (זמן ארוע התשאול (זמן הפעלת התוכנית) והיוזר והמכונה שמייצרים את הארוע וכ'ו)) , לשאלה "יתכן מאד שלמשתמש אותו הגדירו לי, אין הרשאות לתשאל ..." ?
אם לא תווצר רשומה כזאת , ניתן להסיק למשל שאין לך בעיית הרשאות ?
יוס.
 
למעלה