Added LDAP id to structure
[public/netxms.git] / src / server / include / nms_users.h
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2014 Victor Kirhenshtein
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: nms_users.h
20 **
21 **/
22
23 #if WITH_LDAP
24
25 #if !defined(__hpux)
26 #define LDAP_DEPRECATED 1
27 #endif
28
29 #ifdef _WIN32
30
31 #include <winldap.h>
32 #include <winber.h>
33
34 #else /* _WIN32 */
35
36 #include <ldap.h>
37 #if HAVE_LDAP_SSL_H
38 #include <ldap_ssl.h>
39 #endif
40
41 #if !HAVE_BER_INT_T
42 typedef int ber_int_t;
43 #endif
44
45 #endif /* _WIN32 */
46
47 #endif /* WITH_LDAP */
48
49 /**
50 * LDAP entry (object)
51 */
52 class Entry
53 {
54 public:
55 UINT32 m_type;
56 TCHAR* m_loginName;
57 TCHAR* m_fullName;
58 TCHAR* m_description;
59 TCHAR* m_id;
60 StringSet *m_memberList;
61
62 Entry();
63 ~Entry();
64 };
65
66 #if WITH_LDAP
67
68 // Defines to handle string encoding difference between Windows and other systems
69 #ifdef _WIN32
70
71 #define LDAP_CHAR TCHAR
72 #define ldap_strchr _tcschr
73 #define ldap_strstr _tcsstr
74 #define ldap_strrchr _tcsrchr
75 #define ldap_strcpy _tcscpy
76 #define ldap_strcat _tcscat
77 #define ldap_strlen _tcslen
78 #define ldap_timeval l_timeval
79 #define ldap_strdup _tcsdup
80 #define ldap_snprintf _sntprintf
81 #define LdapConfigRead ConfigReadStr
82 #define _TLDAP(x) _T(x)
83 #define LDAP_TFMT _T("%s")
84
85 #else
86
87 #define LDAP_CHAR char
88 #define ldap_strchr strchr
89 #define ldap_strstr strstr
90 #define ldap_strrchr strrchr
91 #define ldap_strcpy strcpy
92 #define ldap_strcat strcat
93 #define ldap_strlen strlen
94 #define ldap_timeval timeval
95 #define ldap_strdup strdup
96 #define ldap_snprintf snprintf
97 #define LdapConfigRead ConfigReadStrUTF8
98 #define _TLDAP(x) x
99 #define LDAP_TFMT _T("%hs")
100
101 #endif // _WIN32
102 #endif // WITH_LDAP
103
104 /**
105 * LDAP connector
106 */
107 class LDAPConnection
108 {
109 private:
110 #if WITH_LDAP
111 LDAP *m_ldapConn;
112 LDAP_CHAR m_connList[MAX_CONFIG_VALUE];
113 LDAP_CHAR m_searchBase[MAX_CONFIG_VALUE];
114 LDAP_CHAR m_searchFilter[MAX_CONFIG_VALUE];
115 LDAP_CHAR m_userDN[MAX_CONFIG_VALUE];
116 LDAP_CHAR m_userPassword[MAX_PASSWORD];
117 char m_ldapFullNameAttr[MAX_CONFIG_VALUE];
118 char m_ldapLoginNameAttr[MAX_CONFIG_VALUE];
119 char m_ldapDescriptionAttr[MAX_CONFIG_VALUE];
120 char m_ldapUsreIdAttr[MAX_CONFIG_VALUE];
121 char m_ldapGroupIdAttr[MAX_CONFIG_VALUE];
122 TCHAR m_userClass[MAX_CONFIG_VALUE];
123 TCHAR m_groupClass[MAX_CONFIG_VALUE];
124 int m_action;
125 int m_secure;
126 int m_pageSize;
127
128 void closeLDAPConnection();
129 void initLDAP();
130 UINT32 loginLDAP();
131 TCHAR *getErrorString(int code);
132 void getAllSyncParameters();
133 void compareGroupList();
134 void compareUserLists();
135 TCHAR *getAttrValue(LDAPMessage *entry, const char *attr, UINT32 i = 0);
136 TCHAR *getIdAttrValue(LDAPMessage *entry, const char *attr);
137 void prepareStringForInit(LDAP_CHAR *connectionLine);
138 int readInPages(LDAP_CHAR *base);
139 void fillLists(LDAPMessage *searchResult);
140 TCHAR *ldap_internal_get_dn(LDAP *conn, LDAPMessage *entry);
141 void updateMembers(StringSet *memberList, const char *firstAttr, LDAPMessage *firstEntry, const LDAP_CHAR *dn);
142 #endif // WITH_LDAP
143
144 public:
145 #if WITH_LDAP
146 LDAPConnection();
147 ~LDAPConnection();
148 #endif // WITH_LDAP
149
150 void syncUsers();
151 UINT32 ldapUserLogin(const TCHAR *name, const TCHAR *password);
152 };
153
154 #ifndef _nms_users_h_
155 #define _nms_users_h_
156
157 /**
158 * Maximum number of grace logins allowed for user
159 */
160 #define MAX_GRACE_LOGINS 5
161
162 /**
163 * Maximum length of XMPP ID
164 */
165 #define MAX_XMPP_ID_LEN 128
166
167 /**
168 * Authentication methods
169 */
170 enum UserAuthMethod
171 {
172 AUTH_NETXMS_PASSWORD = 0,
173 AUTH_RADIUS = 1,
174 AUTH_CERTIFICATE = 2,
175 AUTH_CERT_OR_PASSWD = 3,
176 AUTH_CERT_OR_RADIUS = 4
177 };
178
179 /**
180 * Generic user database object
181 */
182 class NXCORE_EXPORTABLE UserDatabaseObject
183 {
184 protected:
185 UINT32 m_id;
186 uuid m_guid;
187 TCHAR m_name[MAX_USER_NAME];
188 TCHAR m_description[MAX_USER_DESCR];
189 UINT64 m_systemRights;
190 UINT32 m_flags;
191 StringMap m_attributes; // Custom attributes
192 TCHAR *m_userDn;
193 TCHAR *m_ldapId;
194
195 bool loadCustomAttributes(DB_HANDLE hdb);
196 bool saveCustomAttributes(DB_HANDLE hdb);
197
198 public:
199 UserDatabaseObject();
200 UserDatabaseObject(DB_HANDLE hdb, DB_RESULT hResult, int row);
201 UserDatabaseObject(UINT32 id, const TCHAR *name);
202 virtual ~UserDatabaseObject();
203
204 virtual bool saveToDatabase(DB_HANDLE hdb);
205 virtual bool deleteFromDatabase(DB_HANDLE hdb);
206
207 virtual void fillMessage(NXCPMessage *msg);
208 virtual void modifyFromMessage(NXCPMessage *msg);
209 void detachLdapUser();
210
211 UINT32 getId() const { return m_id; }
212 const TCHAR *getName() const { return m_name; }
213 const TCHAR *getDescription() const { return m_description; }
214 UINT64 getSystemRights() const { return m_systemRights; }
215 UINT32 getFlags() const { return m_flags; }
216 TCHAR *getGuidAsText(TCHAR *buffer) const { return m_guid.toString(buffer); }
217 const TCHAR *getDn() const { return m_userDn; }
218 const TCHAR *getLdapId() const { return m_ldapId; }
219
220 bool isGroup() const { return (m_id & GROUP_FLAG) != 0; }
221 bool isDeleted() const { return (m_flags & UF_DELETED) ? true : false; }
222 bool isDisabled() const { return (m_flags & UF_DISABLED) ? true : false; }
223 bool isModified() const { return (m_flags & UF_MODIFIED) ? true : false; }
224 bool isLDAPUser() const { return (m_flags & UF_LDAP_USER) ? true : false; }
225 bool hasSyncException() const { return (m_flags & UF_SYNC_EXCEPTION) ? true : false; }
226
227 void setDeleted() { m_flags |= UF_DELETED; }
228 void enable();
229 void disable();
230 void setFlags(UINT32 flags) { m_flags = flags; }
231 void removeSyncException();
232 void setSyncException();
233
234 const TCHAR *getAttribute(const TCHAR *name) { return m_attributes.get(name); }
235 UINT32 getAttributeAsULong(const TCHAR *name);
236 void setAttribute(const TCHAR *name, const TCHAR *value) { m_attributes.set(name, value); m_flags |= UF_MODIFIED; }
237 void setName(const TCHAR *name);
238 void setDescription(const TCHAR *description);
239 void setDn(const TCHAR *dn);
240 void setLdapId(const TCHAR *id);
241 };
242
243 /**
244 * Hash types
245 */
246 enum PasswordHashType
247 {
248 PWD_HASH_SHA1 = 0,
249 PWD_HASH_SHA256 = 1
250 };
251
252 /**
253 * Password salt length
254 */
255 #define PASSWORD_SALT_LENGTH 8
256
257 /**
258 * Password hash size
259 */
260 #define PWD_HASH_SIZE(t) ((t == PWD_HASH_SHA256) ? SHA256_DIGEST_SIZE : ((t == PWD_HASH_SHA1) ? SHA1_DIGEST_SIZE : 0))
261
262 /**
263 * Hashed password
264 */
265 struct PasswordHash
266 {
267 PasswordHashType hashType;
268 BYTE hash[SHA256_DIGEST_SIZE];
269 BYTE salt[PASSWORD_SALT_LENGTH];
270 };
271
272 /**
273 * User object
274 */
275 class NXCORE_EXPORTABLE User : public UserDatabaseObject
276 {
277 protected:
278 TCHAR m_fullName[MAX_USER_FULLNAME];
279 PasswordHash m_password;
280 int m_graceLogins;
281 int m_authMethod;
282 int m_certMappingMethod;
283 TCHAR *m_certMappingData;
284 time_t m_disabledUntil;
285 time_t m_lastPasswordChange;
286 time_t m_lastLogin;
287 int m_minPasswordLength;
288 int m_authFailures;
289 TCHAR m_xmppId[MAX_XMPP_ID_LEN];
290
291 public:
292 User();
293 User(DB_HANDLE hdb, DB_RESULT hResult, int row);
294 User(UINT32 id, const TCHAR *name);
295 virtual ~User();
296
297 virtual bool saveToDatabase(DB_HANDLE hdb);
298 virtual bool deleteFromDatabase(DB_HANDLE hdb);
299
300 virtual void fillMessage(NXCPMessage *msg);
301 virtual void modifyFromMessage(NXCPMessage *msg);
302
303 const TCHAR *getFullName() { return m_fullName; }
304 int getGraceLogins() { return m_graceLogins; }
305 int getAuthMethod() { return m_authMethod; }
306 int getCertMappingMethod() { return m_certMappingMethod; }
307 time_t getLastLoginTime() { return m_lastLogin; }
308 time_t getPasswordChangeTime() { return m_lastPasswordChange; }
309 const TCHAR *getCertMappingData() { return m_certMappingData; }
310 bool isIntruderLockoutActive() { return (m_flags & UF_INTRUDER_LOCKOUT) != 0; }
311 bool canChangePassword() { return (m_flags & UF_CANNOT_CHANGE_PASSWORD) == 0; }
312 int getMinMasswordLength() { return m_minPasswordLength; }
313 time_t getReEnableTime() { return m_disabledUntil; }
314 const TCHAR *getXmppId() { return m_xmppId; }
315
316 bool validatePassword(const TCHAR *password);
317 void decreaseGraceLogins() { if (m_graceLogins > 0) m_graceLogins--; m_flags |= UF_MODIFIED; }
318 void setPassword(const TCHAR *password, bool clearChangePasswdFlag);
319 void increaseAuthFailures();
320 void resetAuthFailures() { m_authFailures = 0; m_flags |= UF_MODIFIED; }
321 void updateLastLogin() { m_lastLogin = time(NULL); m_flags |= UF_MODIFIED; }
322 void updatePasswordChangeTime() { m_lastPasswordChange = time(NULL); m_flags |= UF_MODIFIED; }
323 void setFullName(const TCHAR *fullName);
324 void enable();
325 };
326
327 /**
328 * Group object
329 */
330 class NXCORE_EXPORTABLE Group : public UserDatabaseObject
331 {
332 protected:
333 int m_memberCount;
334 UINT32 *m_members;
335
336 public:
337 Group();
338 Group(DB_HANDLE hdb, DB_RESULT hResult, int row);
339 Group(UINT32 id, const TCHAR *name);
340 virtual ~Group();
341
342 virtual void fillMessage(NXCPMessage *msg);
343 virtual void modifyFromMessage(NXCPMessage *msg);
344
345 virtual bool saveToDatabase(DB_HANDLE hdb);
346 virtual bool deleteFromDatabase(DB_HANDLE hdb);
347
348 void addUser(UINT32 userId);
349 void deleteUser(UINT32 userId);
350 bool isMember(UINT32 userId);
351 int getMembers(UINT32 **members);
352 };
353
354 /**
355 * Access list element structure
356 */
357 typedef struct
358 {
359 UINT32 dwUserId;
360 UINT32 dwAccessRights;
361 } ACL_ELEMENT;
362
363 /**
364 * Access list class
365 */
366 class AccessList
367 {
368 private:
369 int m_size;
370 int m_allocated;
371 ACL_ELEMENT *m_elements;
372
373 public:
374 AccessList();
375 ~AccessList();
376
377 bool getUserRights(UINT32 dwUserId, UINT32 *pdwAccessRights);
378 void addElement(UINT32 dwUserId, UINT32 dwAccessRights);
379 bool deleteElement(UINT32 dwUserId);
380 void deleteAll();
381
382 void enumerateElements(void (* pHandler)(UINT32, UINT32, void *), void *pArg);
383
384 void fillMessage(NXCPMessage *pMsg);
385 };
386
387 /**
388 * Functions
389 */
390 BOOL LoadUsers();
391 void SaveUsers(DB_HANDLE hdb);
392 void SendUserDBUpdate(int code, UINT32 id, UserDatabaseObject *object);
393 void SendUserDBUpdate(int code, UINT32 id);
394 UINT32 AuthenticateUser(const TCHAR *login, const TCHAR *password, UINT32 dwSigLen, void *pCert,
395 BYTE *pChallenge, UINT32 *pdwId, UINT64 *pdwSystemRights,
396 bool *pbChangePasswd, bool *pbIntruderLockout, bool ssoAuth);
397 bool AuthenticateUserForXMPPCommands(const char *xmppId);
398 bool AuthenticateUserForXMPPSubscription(const char *xmppId);
399
400 UINT32 NXCORE_EXPORTABLE ValidateUserPassword(UINT32 userId, const TCHAR *login, const TCHAR *password, bool *isValid);
401 UINT32 NXCORE_EXPORTABLE SetUserPassword(UINT32 id, const TCHAR *newPassword, const TCHAR *oldPassword, bool changeOwnPassword);
402 bool NXCORE_EXPORTABLE CheckUserMembership(UINT32 userId, UINT32 groupId);
403 UINT32 NXCORE_EXPORTABLE DeleteUserDatabaseObject(UINT32 id, bool alreadyLocked = false);
404 UINT32 NXCORE_EXPORTABLE CreateNewUser(const TCHAR *name, bool isGroup, UINT32 *id);
405 UINT32 NXCORE_EXPORTABLE ModifyUserDatabaseObject(NXCPMessage *msg);
406 UINT32 NXCORE_EXPORTABLE DetachLdapUser(UINT32 id);
407 Iterator<UserDatabaseObject> NXCORE_EXPORTABLE *OpenUserDatabase();
408 void NXCORE_EXPORTABLE CloseUserDatabase(Iterator<UserDatabaseObject> *it);
409 const TCHAR NXCORE_EXPORTABLE *GetUserDbObjectAttr(UINT32 id, const TCHAR *name);
410 UINT32 NXCORE_EXPORTABLE GetUserDbObjectAttrAsULong(UINT32 id, const TCHAR *name);
411 void NXCORE_EXPORTABLE SetUserDbObjectAttr(UINT32 id, const TCHAR *name, const TCHAR *value);
412 bool NXCORE_EXPORTABLE ResolveUserId(UINT32 id, TCHAR *buffer, int bufSize);
413 void UpdateLDAPUser(const TCHAR* dn, Entry *obj);
414 void RemoveDeletedLDAPEntries(StringObjectMap<Entry> *entryListDn, StringObjectMap<Entry> *entryListId, UINT32 m_action, bool isUser);
415 void UpdateLDAPGroup(const TCHAR* dn, Entry *obj);
416 THREAD_RESULT THREAD_CALL SyncLDAPUsers(void *arg);
417 void FillGroupMembershipInfo(NXCPMessage *msg, UINT32 userId);
418 void UpdateGroupMembership(UINT32 userId, int numGroups, UINT32 *groups);
419 void DumpUsers(CONSOLE_CTX pCtx);
420
421 /**
422 * CAS API
423 */
424 void CASReadSettings();
425 bool CASAuthenticate(const char *ticket, TCHAR *loginName);
426
427 #endif