Implemented Last Login and Created columns for User Manager. Fixes #NX-1219
[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_ldapDn;
193 TCHAR *m_ldapId;
194 time_t m_created;
195
196 bool loadCustomAttributes(DB_HANDLE hdb);
197 bool saveCustomAttributes(DB_HANDLE hdb);
198
199 public:
200 UserDatabaseObject();
201 UserDatabaseObject(DB_HANDLE hdb, DB_RESULT hResult, int row);
202 UserDatabaseObject(UINT32 id, const TCHAR *name);
203 virtual ~UserDatabaseObject();
204
205 virtual bool saveToDatabase(DB_HANDLE hdb);
206 virtual bool deleteFromDatabase(DB_HANDLE hdb);
207
208 virtual void fillMessage(NXCPMessage *msg);
209 virtual void modifyFromMessage(NXCPMessage *msg);
210
211 virtual json_t *toJson() const;
212
213 UINT32 getId() const { return m_id; }
214 const TCHAR *getName() const { return m_name; }
215 const TCHAR *getDescription() const { return m_description; }
216 UINT64 getSystemRights() const { return m_systemRights; }
217 UINT32 getFlags() const { return m_flags; }
218 TCHAR *getGuidAsText(TCHAR *buffer) const { return m_guid.toString(buffer); }
219 const TCHAR *getDn() const { return m_ldapDn; }
220 const TCHAR *getLdapId() const { return m_ldapId; }
221
222 bool isGroup() const { return (m_id & GROUP_FLAG) != 0; }
223 bool isDeleted() const { return (m_flags & UF_DELETED) ? true : false; }
224 bool isDisabled() const { return (m_flags & UF_DISABLED) ? true : false; }
225 bool isModified() const { return (m_flags & UF_MODIFIED) ? true : false; }
226 bool isLDAPUser() const { return (m_flags & UF_LDAP_USER) ? true : false; }
227
228 void setDeleted() { m_flags |= UF_DELETED; }
229 void enable();
230 void disable();
231 void setFlags(UINT32 flags) { m_flags = flags; }
232 void removeSyncException();
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
240 void setDn(const TCHAR *dn);
241 void setLdapId(const TCHAR *id);
242 void detachLdapUser();
243 };
244
245 /**
246 * Hash types
247 */
248 enum PasswordHashType
249 {
250 PWD_HASH_SHA1 = 0,
251 PWD_HASH_SHA256 = 1
252 };
253
254 /**
255 * Password salt length
256 */
257 #define PASSWORD_SALT_LENGTH 8
258
259 /**
260 * Password hash size
261 */
262 #define PWD_HASH_SIZE(t) ((t == PWD_HASH_SHA256) ? SHA256_DIGEST_SIZE : ((t == PWD_HASH_SHA1) ? SHA1_DIGEST_SIZE : 0))
263
264 /**
265 * Hashed password
266 */
267 struct PasswordHash
268 {
269 PasswordHashType hashType;
270 BYTE hash[SHA256_DIGEST_SIZE];
271 BYTE salt[PASSWORD_SALT_LENGTH];
272 };
273
274 /**
275 * User object
276 */
277 class NXCORE_EXPORTABLE User : public UserDatabaseObject
278 {
279 protected:
280 TCHAR m_fullName[MAX_USER_FULLNAME];
281 PasswordHash m_password;
282 int m_graceLogins;
283 int m_authMethod;
284 int m_certMappingMethod;
285 TCHAR *m_certMappingData;
286 time_t m_disabledUntil;
287 time_t m_lastPasswordChange;
288 time_t m_lastLogin;
289 int m_minPasswordLength;
290 int m_authFailures;
291 TCHAR m_xmppId[MAX_XMPP_ID_LEN];
292
293 public:
294 User();
295 User(DB_HANDLE hdb, DB_RESULT hResult, int row);
296 User(UINT32 id, const TCHAR *name);
297 virtual ~User();
298
299 virtual bool saveToDatabase(DB_HANDLE hdb);
300 virtual bool deleteFromDatabase(DB_HANDLE hdb);
301
302 virtual void fillMessage(NXCPMessage *msg);
303 virtual void modifyFromMessage(NXCPMessage *msg);
304
305 virtual json_t *toJson() const;
306
307 const TCHAR *getFullName() { return m_fullName; }
308 int getGraceLogins() { return m_graceLogins; }
309 int getAuthMethod() { return m_authMethod; }
310 int getCertMappingMethod() { return m_certMappingMethod; }
311 time_t getLastLoginTime() { return m_lastLogin; }
312 time_t getPasswordChangeTime() { return m_lastPasswordChange; }
313 const TCHAR *getCertMappingData() { return m_certMappingData; }
314 bool isIntruderLockoutActive() { return (m_flags & UF_INTRUDER_LOCKOUT) != 0; }
315 bool canChangePassword() { return (m_flags & UF_CANNOT_CHANGE_PASSWORD) == 0; }
316 int getMinMasswordLength() { return m_minPasswordLength; }
317 time_t getReEnableTime() { return m_disabledUntil; }
318 const TCHAR *getXmppId() { return m_xmppId; }
319
320 bool validatePassword(const TCHAR *password);
321 void decreaseGraceLogins() { if (m_graceLogins > 0) m_graceLogins--; m_flags |= UF_MODIFIED; }
322 void setPassword(const TCHAR *password, bool clearChangePasswdFlag);
323 void increaseAuthFailures();
324 void resetAuthFailures() { m_authFailures = 0; m_flags |= UF_MODIFIED; }
325 void updateLastLogin() { m_lastLogin = time(NULL); m_flags |= UF_MODIFIED; }
326 void updatePasswordChangeTime() { m_lastPasswordChange = time(NULL); m_flags |= UF_MODIFIED; }
327 void setFullName(const TCHAR *fullName);
328 void enable();
329 };
330
331 /**
332 * Group object
333 */
334 class NXCORE_EXPORTABLE Group : public UserDatabaseObject
335 {
336 protected:
337 int m_memberCount;
338 UINT32 *m_members;
339
340 public:
341 Group();
342 Group(DB_HANDLE hdb, DB_RESULT hResult, int row);
343 Group(UINT32 id, const TCHAR *name);
344 virtual ~Group();
345
346 virtual void fillMessage(NXCPMessage *msg);
347 virtual void modifyFromMessage(NXCPMessage *msg);
348
349 virtual bool saveToDatabase(DB_HANDLE hdb);
350 virtual bool deleteFromDatabase(DB_HANDLE hdb);
351
352 virtual json_t *toJson() const;
353
354 void addUser(UINT32 userId);
355 void deleteUser(UINT32 userId);
356 bool isMember(UINT32 userId, IntegerArray<UINT32> *searchPath = NULL);
357 int getMembers(UINT32 **members);
358 };
359
360 /**
361 * Access list element structure
362 */
363 typedef struct
364 {
365 UINT32 dwUserId;
366 UINT32 dwAccessRights;
367 } ACL_ELEMENT;
368
369 /**
370 * Access list class
371 */
372 class AccessList
373 {
374 private:
375 int m_size;
376 int m_allocated;
377 ACL_ELEMENT *m_elements;
378
379 public:
380 AccessList();
381 ~AccessList();
382
383 bool getUserRights(UINT32 dwUserId, UINT32 *pdwAccessRights);
384 void addElement(UINT32 dwUserId, UINT32 dwAccessRights);
385 bool deleteElement(UINT32 dwUserId);
386 void deleteAll();
387
388 void enumerateElements(void (* pHandler)(UINT32, UINT32, void *), void *pArg);
389
390 void fillMessage(NXCPMessage *pMsg);
391
392 json_t *toJson();
393 };
394
395 /**
396 * Functions
397 */
398 BOOL LoadUsers();
399 void SaveUsers(DB_HANDLE hdb, UINT32 watchdogId);
400 void SendUserDBUpdate(int code, UINT32 id, UserDatabaseObject *object);
401 void SendUserDBUpdate(int code, UINT32 id);
402 UINT32 AuthenticateUser(const TCHAR *login, const TCHAR *password, UINT32 dwSigLen, void *pCert,
403 BYTE *pChallenge, UINT32 *pdwId, UINT64 *pdwSystemRights,
404 bool *pbChangePasswd, bool *pbIntruderLockout, bool *closeOtherSessions,
405 bool ssoAuth, UINT32 *graceLogins);
406 bool AuthenticateUserForXMPPCommands(const char *xmppId);
407 bool AuthenticateUserForXMPPSubscription(const char *xmppId);
408
409 UINT32 NXCORE_EXPORTABLE ValidateUserPassword(UINT32 userId, const TCHAR *login, const TCHAR *password, bool *isValid);
410 UINT32 NXCORE_EXPORTABLE SetUserPassword(UINT32 id, const TCHAR *newPassword, const TCHAR *oldPassword, bool changeOwnPassword);
411 bool CheckUserMembershipInternal(UINT32 userId, UINT32 groupId, IntegerArray<UINT32> *searchPath);
412 bool NXCORE_EXPORTABLE CheckUserMembership(UINT32 userId, UINT32 groupId);
413 UINT32 NXCORE_EXPORTABLE DeleteUserDatabaseObject(UINT32 id, bool alreadyLocked = false);
414 UINT32 NXCORE_EXPORTABLE CreateNewUser(const TCHAR *name, bool isGroup, UINT32 *id);
415 UINT32 NXCORE_EXPORTABLE ModifyUserDatabaseObject(NXCPMessage *msg, json_t **oldData, json_t **newData);
416 UINT32 NXCORE_EXPORTABLE DetachLdapUser(UINT32 id);
417 Iterator<UserDatabaseObject> NXCORE_EXPORTABLE *OpenUserDatabase();
418 void NXCORE_EXPORTABLE CloseUserDatabase(Iterator<UserDatabaseObject> *it);
419 const TCHAR NXCORE_EXPORTABLE *GetUserDbObjectAttr(UINT32 id, const TCHAR *name);
420 UINT32 NXCORE_EXPORTABLE GetUserDbObjectAttrAsULong(UINT32 id, const TCHAR *name);
421 void NXCORE_EXPORTABLE SetUserDbObjectAttr(UINT32 id, const TCHAR *name, const TCHAR *value);
422 bool NXCORE_EXPORTABLE ResolveUserId(UINT32 id, TCHAR *buffer, int bufSize);
423 void UpdateLDAPUser(const TCHAR* dn, Entry *obj);
424 void RemoveDeletedLDAPEntries(StringObjectMap<Entry> *entryListDn, StringObjectMap<Entry> *entryListId, UINT32 m_action, bool isUser);
425 void UpdateLDAPGroup(const TCHAR* dn, Entry *obj);
426 THREAD_RESULT THREAD_CALL SyncLDAPUsers(void *arg);
427 void FillGroupMembershipInfo(NXCPMessage *msg, UINT32 userId);
428 void UpdateGroupMembership(UINT32 userId, int numGroups, UINT32 *groups);
429 void DumpUsers(CONSOLE_CTX pCtx);
430
431 /**
432 * CAS API
433 */
434 void CASReadSettings();
435 bool CASAuthenticate(const char *ticket, TCHAR *loginName);
436
437 #endif