source: rtems/cpukit/httpd/um.c @ a85d8ec

4.104.114.84.95
Last change on this file since a85d8ec was a6b4c0df, checked in by Joel Sherrill <joel.sherrill@…>, on 09/01/00 at 10:57:21

2000-08-30 Joel Sherrill <joel@…>

  • Merged version 2.1 of GoAhead? webserver. This update was submitted by Antti P Miettinen <antti.p.miettinen@…>.
  • NOTES, base64.c, ejIntrn.h, emfdb.c, emfdb.h, md5.h, md5c.c, um.c, um.h: New files.
  • wbase64.c: Removed.
  • Makefile.am, asp.c, balloc.c, default.c, ej.h, ejlex.c, ejparse.c, form.c, h.c, handler.c, mime.c, misc.c, ringq.c, rom.c, security.c, socket.c, sym.c, uemf.c, uemf.h, url.c, value.c, webcomp.c, webmain.c, webpage.c, webrom.c, webs.c, webs.h, websuemf.c, wsIntrn.h: Modified.
  • Property mode set to 100644
File size: 29.7 KB
Line 
1/*
2 *      um.c -- User Management
3 *
4 *      Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
5 *
6 *      See the file "license.txt" for usage and redistribution license requirements
7 *
8 *      $Id$
9 */
10
11/******************************** Description *********************************/
12/*
13 *      User Management routines for adding/deleting/changing users and groups
14 *  Also, routines for determining user access
15 */
16
17/********************************* Includes ***********************************/
18
19#include        "um.h"
20#include        "emfdb.h"
21#include        "webs.h"
22
23/********************************** Defines ***********************************/
24
25#define UM_DB_FILENAME  T("um.xml")
26#define UM_TXT_FILENAME T("umconfig.txt")
27
28/*
29 *      Table names
30 */
31#define UM_USER_TABLENAME       T("users")
32#define UM_GROUP_TABLENAME      T("groups")
33#define UM_ACCESS_TABLENAME     T("access")
34
35/*
36 *      Column names
37 */
38#define UM_NAME                 T("name")
39#define UM_PASS                 T("password")
40#define UM_GROUP                T("group")
41#define UM_PROT                 T("prot")
42#define UM_DISABLE              T("disable")
43#define UM_METHOD               T("method")
44#define UM_PRIVILEGE    T("priv")
45#define UM_SECURE               T("secure")
46
47/*
48 *      XOR encryption mask
49 *              Note:   This string should be modified for individual sites
50 *                              in order to enhance user password security.
51 */
52#define UM_XOR_ENCRYPT  T("*j7a(L#yZ98sSd5HfSgGjMj8;Ss;d)(*&^#@$a2s0i3g")
53
54/******************************** Local Data **********************************/
55
56#ifdef UEMF
57/*
58 *      User table definition
59 */
60#define NUMBER_OF_USER_COLUMNS  5
61
62char_t  *userColumnNames[NUMBER_OF_USER_COLUMNS] = {
63                        UM_NAME, UM_PASS, UM_GROUP, UM_PROT, UM_DISABLE
64};
65
66int             userColumnTypes[NUMBER_OF_USER_COLUMNS] = {
67                        T_STRING, T_STRING, T_STRING, T_INT, T_INT
68};
69
70dbTable_t userTable = {
71        UM_USER_TABLENAME,
72        NUMBER_OF_USER_COLUMNS,
73        userColumnNames,
74        userColumnTypes,
75        0,
76        NULL
77};
78
79/*
80 *      Group table definition
81 */
82#define NUMBER_OF_GROUP_COLUMNS 5
83
84char_t  *groupColumnNames[NUMBER_OF_GROUP_COLUMNS] = {
85                        UM_NAME, UM_PRIVILEGE, UM_METHOD, UM_PROT, UM_DISABLE
86};
87
88int             groupColumnTypes[NUMBER_OF_GROUP_COLUMNS] = {
89                        T_STRING, T_INT, T_INT, T_INT, T_INT
90};
91
92dbTable_t groupTable = {
93        UM_GROUP_TABLENAME,
94        NUMBER_OF_GROUP_COLUMNS,
95        groupColumnNames,
96        groupColumnTypes,
97        0,
98        NULL
99};
100
101/*
102 *      Access Limit table definition
103 */
104#define NUMBER_OF_ACCESS_COLUMNS        4
105
106char_t  *accessColumnNames[NUMBER_OF_ACCESS_COLUMNS] = {
107                        UM_NAME, UM_METHOD, UM_SECURE, UM_GROUP
108};
109
110int             accessColumnTypes[NUMBER_OF_ACCESS_COLUMNS] = {
111                        T_STRING, T_INT, T_INT, T_STRING
112};
113
114dbTable_t accessTable = {
115        UM_ACCESS_TABLENAME,
116        NUMBER_OF_ACCESS_COLUMNS,
117        accessColumnNames,
118        accessColumnTypes,
119        0,
120        NULL
121};
122#endif  /* #ifdef UEMF */
123
124/*
125 *      Database Identifier returned from dbOpen()
126 */
127static int              didUM = -1;     
128
129/*
130 *      Configuration database persist filename
131 */
132static char_t   *saveFilename = NULL;
133
134static int              umOpenCount = 0;                /* count of apps using this module */
135
136/*************************** Forward Declarations *****************************/
137
138static bool_t umCheckName(char_t *name);
139
140/*********************************** Code *************************************/
141/*
142 *      umOpen() registers the UM tables in the fake emf-database
143 */
144
145int umOpen()
146{
147        if (++umOpenCount != 1) {
148                return didUM;
149        }
150/*
151 *      Do not initialize if intialization has already taken place
152 */
153        if (didUM == -1) {
154                didUM = dbOpen(UM_USER_TABLENAME, UM_DB_FILENAME, NULL, 0);
155#ifdef UEMF
156                dbRegisterDBSchema(&userTable);
157                dbRegisterDBSchema(&groupTable);
158                dbRegisterDBSchema(&accessTable);
159#endif
160        }
161
162        if (saveFilename == NULL) {
163                saveFilename = bstrdup(B_L, UM_TXT_FILENAME);
164        }
165
166        return didUM;
167}
168
169/******************************************************************************/
170/*
171 *      umClose() frees up the UM tables in the fake emf-database
172 */
173
174void umClose()
175{
176        if (--umOpenCount > 0) {
177                return;
178        }
179/*
180 *      Do not close if intialization has not taken place
181 */
182        if (didUM != -1) {
183                dbClose(didUM);
184                didUM = -1;
185        }
186
187        if (saveFilename != NULL) {
188                bfree(B_L, saveFilename);
189                saveFilename = NULL;
190        }
191}
192
193/******************************************************************************/
194/*
195 *      umCommit() persists all of the UM tables
196 */
197
198int     umCommit(char_t *filename)
199{
200        if (filename && *filename) {
201                if (saveFilename != NULL) {
202                        bfree(B_L, saveFilename);
203                }
204
205                saveFilename = bstrdup(B_L, filename);
206        }
207
208        a_assert (saveFilename && *saveFilename);
209        trace(3, T("UM: Writing User Configuration to file <%s>\n"),
210                saveFilename);
211
212        return dbSave(didUM, saveFilename, 0);
213}
214
215/******************************************************************************/
216/*
217 *      umRestore() loads up the UM tables with persisted data
218 */
219
220int umRestore(char_t *filename)
221{
222        if (filename && *filename) {
223                if (saveFilename != NULL) {
224                        bfree(B_L, saveFilename);
225                }
226
227                saveFilename = bstrdup(B_L, filename);
228        }
229
230        a_assert(saveFilename && *saveFilename);
231
232        trace(3, T("UM: Loading User Configuration from file <%s>\n"),
233                saveFilename);
234
235/*
236 *      First empty the database, otherwise we wind up with duplicates!
237 */
238        dbZero(didUM);
239        return dbLoad(didUM, saveFilename, 0);
240}
241
242/******************************************************************************/
243/*
244 *      Encrypt/Decrypt a text string. 
245 *              Returns the number of characters encrypted.
246 */
247
248static int umEncryptString(char_t *textString)
249{
250        char_t  *enMask;
251        char_t  enChar;
252        int             numChars;
253
254        a_assert(textString);
255
256        enMask = UM_XOR_ENCRYPT;
257        numChars = 0;
258
259        while (*textString) {
260                enChar = *textString ^ *enMask;
261/*
262 *              Do not produce encrypted text with embedded linefeeds or tabs.
263 *                      Simply use existing character.
264 */
265                if (enChar && !gisspace(enChar))
266                        *textString = enChar;
267/*
268 *              Increment all pointers.
269 */
270                enMask++;
271                textString++;
272                numChars++;
273/*
274 *              Wrap encryption mask pointer if at end of length.
275 */
276                if (*enMask == '\0') {
277                        enMask = UM_XOR_ENCRYPT;
278                }
279        }
280
281        return numChars;
282}
283
284/******************************************************************************/
285/*
286 *      umGetFirstRowData() -   return a pointer to the first non-blank key value
287 *                                                      in the given column for the given table.
288 */
289
290static char_t *umGetFirstRowData(char_t *tableName, char_t *columnName)
291{
292        char_t  *columnData;
293        int             row;
294        int             check;
295
296        a_assert(tableName && *tableName);
297        a_assert(columnName && *columnName);
298
299        row = 0;
300/*
301 *      Move through table until we retrieve the first row with non-null
302 *      column data.
303 */
304        columnData = NULL;
305        while ((check = dbReadStr(didUM, tableName, columnName, row++,
306                &columnData)) == 0 || (check == DB_ERR_ROW_DELETED)) {
307                if (columnData && *columnData) {
308                        return columnData;
309                }
310        }
311
312        return NULL;
313}
314
315/******************************************************************************/
316/*
317 *      umGetNextRowData() -    return a pointer to the first non-blank
318 *                                              key value following the given one.
319 */
320
321static char_t *umGetNextRowData(char_t *tableName, char_t *columnName,
322                                                                char_t *keyLast)
323{
324        char_t  *key;
325        int             row;
326        int             check;
327
328        a_assert(tableName && *tableName);
329        a_assert(columnName && *columnName);
330        a_assert(keyLast && *keyLast);
331/*
332 *      Position row counter to row where the given key value was found
333 */
334        row = 0;
335        key = NULL;
336
337        while ((((check = dbReadStr(didUM, tableName, columnName, row++,
338                &key)) == 0) || (check == DB_ERR_ROW_DELETED)) &&
339                ((key == NULL) || (gstrcmp(key, keyLast) != 0))) {
340        }
341/*
342 *      If the last key value was not found, return NULL
343 */
344        if (!key || gstrcmp(key, keyLast) != 0) {
345                return NULL;
346        }
347/*
348 *      Move through table until we retrieve the next row with a non-null key
349 */
350        while (((check = dbReadStr(didUM, tableName, columnName, row++, &key))
351                == 0) || (check == DB_ERR_ROW_DELETED)) {
352                if (key && *key && (gstrcmp(key, keyLast) != 0)) {
353                        return key;
354                }
355        }
356
357        return NULL;
358}
359
360/******************************************************************************/
361/*
362 *      umAddUser() - Adds a user to the "users" table.
363 */
364
365int     umAddUser(char_t *user, char_t *pass, char_t *group,
366                          bool_t prot, bool_t disabled)
367{
368        int             row;
369        char_t  *password;
370
371        a_assert(user && *user);
372        a_assert(pass && *pass);
373        a_assert(group && *group);
374
375        trace(3, T("UM: Adding User <%s>\n"), user);
376
377/*
378 *      Do not allow duplicates
379 */
380        if (umUserExists(user)) {
381                return UM_ERR_DUPLICATE;
382        }
383
384/*
385 *      Make sure user name and password contain valid characters
386 */
387        if (!umCheckName(user)) {
388                return UM_ERR_BAD_NAME;
389        }
390
391        if (!umCheckName(pass)) {
392                return UM_ERR_BAD_PASSWORD;
393        }
394
395/*
396 *      Make sure group exists
397 */
398        if (!umGroupExists(group)) {
399                return UM_ERR_NOT_FOUND;
400        }
401
402/*
403 *      Now create the user record
404 */
405        row = dbAddRow(didUM, UM_USER_TABLENAME);
406
407        if (row < 0) {
408                return UM_ERR_GENERAL;
409        }
410
411        if (dbWriteStr(didUM, UM_USER_TABLENAME, UM_NAME, row, user) != 0) {
412                return UM_ERR_GENERAL;
413        }
414
415        password = bstrdup(B_L, pass);
416        umEncryptString(password);
417        dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password);
418        bfree(B_L, password);
419        dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group);
420        dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, prot);
421        dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, disabled);
422
423        return 0;
424}
425
426/******************************************************************************/
427/*
428 *      umDeleteUser() - remove a user from the "users" table
429 */
430
431int     umDeleteUser(char_t *user)
432{
433        int row;
434
435        a_assert(user && *user);
436        trace(3, T("UM: Deleting User <%s>\n"), user);
437/*
438 *      Check to see if user is delete-protected
439 */
440        if (umGetUserProtected(user)) {
441                return UM_ERR_PROTECTED;
442        }
443
444/*
445 *      If found, delete the user from the database
446 */
447        if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) >= 0) {
448                return dbDeleteRow(didUM, UM_USER_TABLENAME, row);
449        }
450
451        return UM_ERR_NOT_FOUND;
452}
453
454/******************************************************************************/
455/*
456 *      umGetFirstUser() -      Returns the user ID of the first user found in the
457 *                                              "users" table.
458 */
459
460char_t *umGetFirstUser()
461{
462        return umGetFirstRowData(UM_USER_TABLENAME, UM_NAME);
463}
464
465/******************************************************************************/
466/*
467 *      umGetNextUser() Returns the next user found in the "users" table after
468 *                                      the given user.         
469 */
470
471char_t *umGetNextUser(char_t *userLast)
472{
473        return umGetNextRowData(UM_USER_TABLENAME, UM_NAME, userLast);
474}
475
476/******************************************************************************/
477/*
478 *      umUserExists()  Returns TRUE if userid exists.
479 */
480
481bool_t umUserExists(char_t *user)
482{
483        a_assert(user && *user);
484
485        if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0) >= 0) {
486                return TRUE;
487        } else {
488                return FALSE;
489        }
490}
491
492/******************************************************************************/
493/*
494 *      umGetUserPassword() returns a de-crypted copy of the user password
495 */
496
497char_t *umGetUserPassword(char_t *user)
498{
499        char_t  *password;
500        int             row;
501
502        a_assert(user && *user);
503
504        password = NULL;
505        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
506
507        if (row >= 0) {
508                char_t *pass = NULL;
509                dbReadStr(didUM, UM_USER_TABLENAME, UM_PASS, row, &pass);
510/*
511 *              Decrypt password
512 *              Note, this function returns a copy of the password, which must
513 *              be deleted at some time in the future.
514 */
515                password = bstrdup(B_L, pass);
516                umEncryptString(password);
517        }
518
519        return password;
520}
521
522/******************************************************************************/
523/*
524 *      umSetUserPassword() updates the user password in the user "table" after
525 *                                              encrypting the given password
526 */
527
528int     umSetUserPassword(char_t *user, char_t *pass)
529{
530        int             row, nRet;
531        char_t  *password;
532
533        a_assert(user && *user);
534        a_assert(pass && *pass);
535        trace(3, T("UM: Attempting to change the password for user <%s>\n"), user);
536/*
537 *      Find the row of the user
538 */
539        if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) < 0) {
540                return UM_ERR_NOT_FOUND;
541        }
542
543        password = bstrdup(B_L, pass);
544        umEncryptString(password);
545        nRet = dbWriteStr(didUM, UM_USER_TABLENAME, UM_PASS, row, password);
546        bfree(B_L, password);
547
548        return nRet;
549}
550
551/******************************************************************************/
552/*
553 *      umGetUserGroup() returns the name of the user group
554 */
555
556char_t *umGetUserGroup(char_t *user)
557{
558        char_t  *group;
559        int             row;
560
561        a_assert(user && *user);
562        group = NULL;
563/*
564 *      Find the row of the user
565 */
566        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
567
568        if (row >= 0) {
569                dbReadStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, &group);
570        }
571
572        return group;
573}
574
575/******************************************************************************/
576/*
577 *      umSetUserGroup() Sets the name of the user group for the user
578 */
579
580int     umSetUserGroup(char_t *user, char_t *group)
581{
582        int row;
583
584        a_assert(user && *user);
585        a_assert(group && *group);
586/*
587 *      Find the row of the user
588 */
589        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
590
591        if (row >= 0) {
592                return dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group);
593        } else {
594                return UM_ERR_NOT_FOUND;
595        }
596}
597
598/******************************************************************************/
599/*
600 *      umGetUserEnabled() - returns if the user is enabled
601 *      Returns FALSE if the user is not found.
602 */
603
604bool_t  umGetUserEnabled(char_t *user)
605{
606        int disabled, row;
607
608        a_assert(user && *user);
609
610        disabled = 1;
611/*
612 *      Find the row of the user
613 */
614        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
615
616        if (row >= 0) {
617                dbReadInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, &disabled);
618        }
619
620        return (bool_t)!disabled;
621}
622
623/******************************************************************************/
624/*
625 *      umSetUserEnabled() Enables/disables the user
626 */
627int     umSetUserEnabled(char_t *user, bool_t enabled)
628{
629        int row;
630
631        a_assert(user && *user);
632/*
633 *      Find the row of the user
634 */
635        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
636        if (row >= 0) {
637                return dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, !enabled);
638        } else {
639                return UM_ERR_NOT_FOUND;
640        }
641}
642
643/******************************************************************************/
644/*
645 *      umGetUserProtected() - determine deletability of user
646 */
647
648bool_t umGetUserProtected(char_t *user)
649{
650        int protect, row;
651
652        a_assert(user && *user);
653/*
654 *      Find the row of the user
655 */
656        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
657        protect = FALSE;
658
659        if (row >= 0) {
660                dbReadInt(didUM, UM_USER_TABLENAME, UM_PROT, row, &protect);
661        }
662
663        return (bool_t)protect;
664}
665
666/******************************************************************************/
667/*
668 *      umSetUserProtected() sets the delete protection for the user
669 */
670int     umSetUserProtected(char_t *user, bool_t protect)
671{
672        int row;
673
674        a_assert(user && *user);
675/*
676 *      Find the row of the user
677 */
678        row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0);
679
680        if (row >= 0) {
681                return dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, protect);
682        } else {
683                return UM_ERR_NOT_FOUND;
684        }
685}
686
687
688/******************************************************************************/
689/*
690 *      umAddGroup() adds a group to the "Group" table
691 */
692
693int     umAddGroup(char_t *group, short priv, accessMeth_t am,
694                           bool_t prot, bool_t disabled)
695{
696        int row;
697
698        a_assert(group && *group);
699        trace(3, T("UM: Adding group <%s>\n"), group);
700       
701/*
702 *      Do not allow duplicates
703 */
704        if (umGroupExists(group)) {
705                return UM_ERR_DUPLICATE;
706        }
707
708/*
709 *      Only allow valid characters in key field
710 */
711        if (!umCheckName(group)) {
712                return UM_ERR_BAD_NAME;
713        }
714
715/*
716 *      Add a new row to the table
717 */
718        if ((row = dbAddRow(didUM, UM_GROUP_TABLENAME)) < 0) {
719                return UM_ERR_GENERAL;
720        }
721
722/*
723 *      Write the key field
724 */
725        if (dbWriteStr(didUM, UM_GROUP_TABLENAME, UM_NAME, row, group) != 0) {
726                return UM_ERR_GENERAL;
727        }
728
729/*
730 *      Write the remaining fields
731 */
732        dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, priv);
733        dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am);
734        dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, prot);
735        dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, disabled);
736
737        return 0;
738}
739
740/******************************************************************************/
741/*
742 *      umDeleteGroup() - Delete a user group, if not protected
743 */
744
745int     umDeleteGroup(char_t *group)
746{
747        int row;
748
749        a_assert(group && *group);
750        trace(3, T("UM: Deleting Group <%s>\n"), group);
751
752/*
753 *      Check to see if the group is in use
754 */
755        if (umGetGroupInUse(group)) {
756                return UM_ERR_IN_USE;
757        }
758
759/*
760 *      Check to see if the group is delete-protected
761 */
762        if (umGetGroupProtected(group)) {
763                return UM_ERR_PROTECTED;
764        }
765
766/*
767 *      Find the row of the group to delete
768 */
769        if ((row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0)) < 0) {
770                return UM_ERR_NOT_FOUND;
771        }
772
773        return dbDeleteRow(didUM, UM_GROUP_TABLENAME, row);
774}
775
776/******************************************************************************/
777/*
778 *      umGroupExists() returns TRUE if group exists, FALSE otherwise
779 */
780
781bool_t umGroupExists(char_t *group)
782{
783        a_assert(group && *group);
784
785        if (dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0) >= 0) {
786                return TRUE;
787        } else {
788                return FALSE;
789        }
790}
791
792
793/******************************************************************************/
794/*
795 *      umGetGroupInUse() returns TRUE if the group is referenced by a user or by
796 *  an access limit.
797 */
798
799bool_t umGetGroupInUse(char_t *group)
800{
801        a_assert(group && *group);
802
803/*
804 *      First, check the user table
805 */
806        if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_GROUP, group, 0) >= 0) {
807                return TRUE;
808        }
809
810/*
811 *      Second, check the access limit table
812 */
813        if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, group, 0) >= 0) {
814                return TRUE;
815        }
816
817        return FALSE;
818}
819
820
821/******************************************************************************/
822/*
823 *      umGetFirstGroup() - return a pointer to the first non-blank group name
824 */
825
826char_t *umGetFirstGroup()
827{
828        return umGetFirstRowData(UM_GROUP_TABLENAME, UM_NAME);
829}
830
831/******************************************************************************/
832/*
833 *      umGetNextGroup() -      return a pointer to the first non-blank group name
834 *                                              following the given group name
835 */
836
837char_t *umGetNextGroup(char_t *groupLast)
838{
839        return umGetNextRowData(UM_GROUP_TABLENAME, UM_NAME, groupLast);
840}
841
842/******************************************************************************/
843/*
844 *      Returns the default access method to use for a given group
845 */
846
847accessMeth_t umGetGroupAccessMethod(char_t *group)
848{
849        int am, row;
850
851        a_assert(group && *group);
852        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
853
854        if (row >= 0) {
855                dbReadInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int *)&am);
856        } else {
857                am = AM_INVALID;
858        }
859
860        return (accessMeth_t) am;
861}
862
863/******************************************************************************/
864/*
865 *      Set the default access method to use for a given group
866 */
867
868int     umSetGroupAccessMethod(char_t *group, accessMeth_t am)
869{
870        int row;
871
872        a_assert(group && *group);
873        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
874
875        if (row >= 0) {
876                return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_METHOD, row, (int) am);
877        } else {
878                return UM_ERR_NOT_FOUND;
879        }
880}
881
882/******************************************************************************/
883/*
884 *      Returns the privilege mask for a given group
885 */
886
887short umGetGroupPrivilege(char_t *group)
888{
889        int privilege, row;
890
891        a_assert(group && *group);
892        privilege = -1;
893        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
894
895        if (row >= 0) {
896                dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, &privilege);
897        }
898
899        return (short) privilege;
900}
901
902/******************************************************************************/
903/*
904 *      Set the privilege mask for a given group
905 */
906
907int     umSetGroupPrivilege(char_t *group, short privilege)
908{
909        int row;
910
911        a_assert(group && *group);
912        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
913
914        if (row >= 0) {
915                return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row,
916                        (int)privilege);
917        } else {
918                return UM_ERR_NOT_FOUND;
919        }
920}
921
922/******************************************************************************/
923/*
924 *      Returns the enabled setting for a given group.
925 *      Returns FALSE if group is not found.
926 */
927
928bool_t umGetGroupEnabled(char_t *group)
929{
930        int disabled, row;
931
932        a_assert(group && *group);
933        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
934        disabled = 1;
935
936        if (row >= 0) {
937                dbReadInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, &disabled);
938        }
939
940        return (bool_t) !disabled;
941}
942
943/******************************************************************************/
944/*
945 *      Sets the enabled setting for a given group.
946 */
947
948int umSetGroupEnabled(char_t *group, bool_t enabled)
949{
950        int row;
951
952        a_assert(group && *group);
953        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
954
955        if (row >= 0) {
956                return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row,
957                        (int) !enabled);
958        } else {
959                return UM_ERR_NOT_FOUND;
960        }
961}
962
963/******************************************************************************/
964/*
965 *      Returns the protected setting for a given group
966 *  Returns FALSE if user is not found
967 */
968
969bool_t umGetGroupProtected(char_t *group)
970{
971        int protect, row;
972
973        a_assert(group && *group);
974
975        protect = 0;
976        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
977        if (row >= 0) {
978                dbReadInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, &protect);
979        }
980
981        return (bool_t) protect;
982}
983
984/******************************************************************************/
985/*
986 *      Sets the protected setting for a given group
987 */
988
989int     umSetGroupProtected(char_t *group, bool_t protect)
990{
991        int row;
992
993        a_assert(group && *group);
994        row = dbSearchStr(didUM, UM_GROUP_TABLENAME, UM_NAME, group, 0);
995
996        if (row >= 0) {
997                return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row,
998                        (int) protect);
999        } else {
1000                return UM_ERR_NOT_FOUND;
1001        }
1002}
1003
1004
1005/******************************************************************************/
1006/*
1007 *      umAddAccessLimit() adds an access limit to the "access" table
1008 */
1009
1010int     umAddAccessLimit(char_t *url, accessMeth_t am, short secure, char_t *group)
1011{
1012        int row;
1013
1014        a_assert(url && *url);
1015        trace(3, T("UM: Adding Access Limit for <%s>\n"), url);
1016
1017/*
1018 *      Do not allow duplicates
1019 */
1020        if (umAccessLimitExists(url)) {
1021                return UM_ERR_DUPLICATE;
1022        }
1023
1024/*
1025 *      Add a new row to the table
1026 */
1027        if ((row = dbAddRow(didUM, UM_ACCESS_TABLENAME)) < 0) {
1028                return UM_ERR_GENERAL;
1029        }
1030
1031/*
1032 *      Write the key field
1033 */
1034        if(dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, row, url) < 0) {
1035                return UM_ERR_GENERAL;
1036        }
1037
1038/*
1039 *      Write the remaining fields
1040 */
1041        dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int)am);
1042        dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, (int)secure);
1043        dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group);
1044
1045        return 0;
1046}
1047
1048/******************************************************************************/
1049/*
1050 *      umDeleteAccessLimit()
1051 */
1052
1053int     umDeleteAccessLimit(char_t *url)
1054{
1055        int row;
1056
1057        a_assert(url && *url);
1058        trace(3, T("UM: Deleting Access Limit for <%s>\n"), url);
1059/*
1060 *      Find the row of the access limit to delete
1061 */
1062        if ((row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0)) < 0) {
1063                return UM_ERR_NOT_FOUND;
1064        }
1065
1066        return dbDeleteRow(didUM, UM_ACCESS_TABLENAME, row);
1067}
1068
1069/******************************************************************************/
1070/*
1071 *      umGetFirstGroup() - return a pointer to the first non-blank access limit
1072 */
1073
1074char_t *umGetFirstAccessLimit()
1075{
1076        return umGetFirstRowData(UM_ACCESS_TABLENAME, UM_NAME);
1077}
1078
1079/******************************************************************************/
1080/*
1081 *      umGetNextAccessLimit() -        return a pointer to the first non-blank
1082 *                                                              access limit following the given one
1083 */
1084
1085char_t *umGetNextAccessLimit(char_t *urlLast)
1086{
1087        return umGetNextRowData(UM_ACCESS_TABLENAME, UM_NAME, urlLast);
1088}
1089
1090/******************************************************************************/
1091/*
1092 *      umAccessLimitExists() returns TRUE if this access limit exists
1093 */
1094
1095bool_t  umAccessLimitExists(char_t *url)
1096{
1097        a_assert(url && *url);
1098
1099        if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0) < 0) {
1100                return FALSE;
1101        } else {
1102                return TRUE;
1103        }
1104}
1105
1106/******************************************************************************/
1107/*
1108 *      umGetAccessLimit() returns the Access Method for the URL
1109 */
1110
1111accessMeth_t umGetAccessLimitMethod(char_t *url)
1112{
1113        int am, row;
1114
1115        am = (int) AM_INVALID;
1116        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1117
1118        if (row >= 0) {
1119                dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, &am);
1120        }
1121
1122        return (accessMeth_t) am;
1123}
1124
1125/******************************************************************************/
1126/*
1127 *      umSetAccessLimitMethod() - set Access Method for Access Limit
1128 */
1129
1130int     umSetAccessLimitMethod(char_t *url, accessMeth_t am)
1131{
1132        int row;
1133
1134        a_assert(url && *url);
1135        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1136
1137        if (row >= 0) {
1138                return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, (int) am);
1139        } else {
1140                return UM_ERR_NOT_FOUND;
1141        }
1142}
1143
1144/******************************************************************************/
1145/*
1146 *      umGetAccessLimitSecure() - returns secure switch for access limit
1147 */
1148
1149short umGetAccessLimitSecure(char_t *url)
1150{
1151        int secure, row;
1152
1153        a_assert(url && *url);
1154        secure = -1;
1155        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1156
1157        if (row >= 0) {
1158                dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, &secure);
1159        }
1160
1161        return (short)secure;
1162}
1163
1164/******************************************************************************/
1165/*
1166 *      umSetAccessLimitSecure() - sets the secure flag for the URL
1167 */
1168
1169int     umSetAccessLimitSecure(char_t *url, short secure)
1170{
1171        int row;
1172
1173        a_assert(url && *url);
1174        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1175
1176        if (row >= 0) {
1177                return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row,
1178                        (int)secure);
1179        } else {
1180                return UM_ERR_NOT_FOUND;
1181        }
1182}
1183
1184/******************************************************************************/
1185/*
1186 *      umGetAccessLimitGroup() - returns the user group of the access limit
1187 */
1188
1189char_t *umGetAccessLimitGroup(char_t *url)
1190{
1191        char_t  *group;
1192        int             row;
1193
1194        a_assert(url && *url);
1195        group = NULL;
1196        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1197
1198        if (row >= 0) {
1199                dbReadStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, &group);
1200        }
1201
1202        return group;
1203}
1204
1205/******************************************************************************/
1206/*
1207 *      umSetAccessLimitGroup() - sets the user group for the access limit.
1208 */
1209
1210int     umSetAccessLimitGroup(char_t *url, char_t *group)
1211{
1212        int row;
1213
1214        a_assert(url && *url);
1215        row = dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_NAME, url, 0);
1216
1217        if (row >= 0) {
1218                return dbWriteStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, row, group);
1219        } else {
1220                return UM_ERR_NOT_FOUND;
1221        }
1222}
1223
1224/******************************************************************************/
1225/*
1226 *      Returns the access limit to use for a given URL, by checking for URLs up
1227 *      the directory tree.  Creates a new string that must be deleted.
1228 */
1229
1230char_t *umGetAccessLimit(char_t *url)
1231{
1232        char_t  *urlRet, *urlCheck, *lastChar;
1233        int             len;
1234       
1235        a_assert(url && *url);
1236        urlRet = NULL;
1237        urlCheck = bstrdup(B_L, url);
1238        a_assert(urlCheck);
1239        len = gstrlen(urlCheck);
1240/*
1241 *      Scan back through URL to see if there is a "parent" access limit
1242 */
1243        while (len && !urlRet) {
1244                if (umAccessLimitExists(urlCheck)) {
1245                        urlRet = bstrdup(B_L, urlCheck);
1246                } else {
1247/*
1248 *      Trim the end portion of the URL to the previous directory marker
1249 */
1250                        lastChar = urlCheck + len;
1251                        lastChar--;
1252
1253                        while ((lastChar >= urlCheck) && ((*lastChar == '/') ||
1254                                (*lastChar == '\\'))) {
1255                                *lastChar = 0;
1256                                lastChar--;
1257                        }
1258
1259                        while ((lastChar >= urlCheck) && (*lastChar != '/') &&
1260                                (*lastChar != '\\')) {
1261                                *lastChar = 0;
1262                                lastChar--;
1263                        }
1264
1265                        len = gstrlen(urlCheck);
1266                }
1267        }
1268        bfree (B_L, urlCheck);
1269
1270        return urlRet;
1271}
1272
1273/******************************************************************************/
1274/*
1275 *      Returns the access method to use for a given URL
1276 */
1277
1278accessMeth_t umGetAccessMethodForURL(char_t *url)
1279{
1280        accessMeth_t    amRet;
1281        char_t                  *urlHavingLimit, *group;
1282       
1283        urlHavingLimit = umGetAccessLimit(url);
1284        if (urlHavingLimit) {
1285                group = umGetAccessLimitGroup(urlHavingLimit);
1286
1287                if (group && *group) {
1288                        amRet = umGetGroupAccessMethod(group);
1289                } else {
1290                        amRet = umGetAccessLimitMethod(urlHavingLimit);
1291                }
1292
1293                bfree(B_L, urlHavingLimit);
1294        } else {
1295                amRet = AM_FULL;
1296        }
1297
1298        return amRet;
1299}
1300
1301/******************************************************************************/
1302/*
1303 *      Returns TRUE if user can access URL
1304 */
1305
1306bool_t umUserCanAccessURL(char_t *user, char_t *url)
1307{
1308        accessMeth_t    amURL;
1309        char_t                  *group, *usergroup, *urlHavingLimit;
1310        short                   priv;
1311       
1312        a_assert(user && *user);
1313        a_assert(url && *url);
1314
1315/*
1316 *      Make sure user exists
1317 */
1318        if (!umUserExists(user)) {
1319                return FALSE;
1320        }
1321
1322/*
1323 *      Make sure user is enabled
1324 */
1325        if (!umGetUserEnabled(user)) {
1326                return FALSE;
1327        }
1328
1329/*
1330 *      Make sure user has sufficient privileges (any will do)
1331 */
1332        usergroup = umGetUserGroup(user);
1333        priv = umGetGroupPrivilege(usergroup);
1334        if (priv == 0) {
1335                return FALSE;
1336        }
1337
1338/*
1339 *      Make sure user's group is enabled
1340 */
1341        if (!umGetGroupEnabled(usergroup)) {
1342                return FALSE;
1343        }
1344
1345/*
1346 *      The access method of the user group must not be AM_NONE
1347 */
1348        if (umGetGroupAccessMethod(usergroup) == AM_NONE) {
1349                return FALSE;
1350        }
1351
1352/*
1353 *      Check to see if there is an Access Limit for this URL
1354 */
1355        urlHavingLimit = umGetAccessLimit(url);
1356        if (urlHavingLimit) {
1357                amURL = umGetAccessLimitMethod(urlHavingLimit);
1358                group = umGetAccessLimitGroup(urlHavingLimit);
1359                bfree(B_L, urlHavingLimit);
1360        } else {
1361/*
1362 *              If there isn't an access limit for the URL, user has full access
1363 */
1364                return TRUE;
1365        }
1366
1367/*
1368 *      If the access method for the URL is AM_NONE then
1369 *      the file "doesn't exist".
1370 */
1371        if (amURL == AM_NONE) {
1372                return FALSE;
1373        }
1374       
1375/*
1376 *      If Access Limit has a group specified, then the user must be a
1377 *      member of that group
1378 */
1379        if (group && *group) {
1380                if (usergroup && (gstrcmp(group, usergroup) != 0)) {
1381                        return FALSE;
1382                }
1383        }
1384
1385/*
1386 *      Otherwise, user can access the URL
1387 */
1388        return TRUE;
1389}
1390
1391/******************************************************************************/
1392/*
1393 *      Returns TRUE if given name has only valid chars
1394 */
1395
1396static bool_t umCheckName(char_t *name)
1397{
1398        a_assert(name && *name);
1399
1400        if (name && *name) {
1401                while (*name) {
1402                        if (gisspace(*name)) {
1403                                return FALSE;
1404                        }
1405
1406                        name++;
1407                }
1408
1409                return TRUE;
1410        }
1411
1412        return FALSE;
1413}
1414
1415/******************************************************************************/
Note: See TracBrowser for help on using the repository browser.