source: lab.git/Dev/utvpn/utvpn-unix-v101-7101-public/src/Cedar/Account.c @ 072e48b

trunk
Last change on this file since 072e48b was a1bae3e, checked in by mitty <mitty@…>, 12 years ago
  • copy vendor drop to trunk

git-svn-id: https://lab.mitty.jp/svn/lab/trunk@147 7d2118f6-f56c-43e7-95a2-4bb3031d96e7

  • Property mode set to 100644
File size: 28.5 KB
Line 
1// SoftEther UT-VPN SourceCode
2//
3// Copyright (C) 2004-2010 SoftEther Corporation.
4// Copyright (C) 2004-2010 University of Tsukuba, Japan.
5// Copyright (C) 2003-2010 Daiyuu Nobori.
6// All Rights Reserved.
7//
8// http://utvpn.tsukuba.ac.jp/
9//
10// This program is free software; you can redistribute it and/or
11// modify it under the terms of the GNU General Public License
12// version 2 as published by the Free Software Foundation.
13//
14// This program is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License version 2
20// along with this program; if not, write to the Free Software
21// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22//
23// このファイルは GPL バージョン 2 ライセンスで公開されています。
24// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
25// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
26// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
27// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
28//
29// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
30// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
31// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
32// ホストされています。
33// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
34// および、試験または研究のために利用が行われることを想定して配布
35// しています。
36// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
37// あります。
38// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
39// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
40// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
41// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
42// に組み込みさせていただきます。
43//
44// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
45// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
46//
47// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
48// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
49// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
50// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
51// ください。
52//
53// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
54// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
55// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
56// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
57// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
58// 公益保護にご協力いただきますようお願い申し上げます。
59//
60// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
61// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
62// を保護するための努力を行います。
63//
64// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
65// 日本国内の脆弱性情報届出受付公的機関:
66//         独立行政法人 情報処理推進機構
67//         http://www.ipa.go.jp/security/vuln/report/
68//
69// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
70// 連絡先: http://www.softether.co.jp/jp/contact/
71
72// -----------------------------------------------
73// [ChangeLog]
74// 2010.05.20
75//  新規リリース by SoftEther
76// -----------------------------------------------
77
78// Account.c
79// アカウントマネージャ
80
81#include "CedarPch.h"
82
83// ポリシー項目
84POLICY_ITEM policy_item[] =
85{
86//  番号,   数値,   省略可能, 最小, 最大, デフォルト, 単位文字列
87// Ver 2.0
88    {0,     false,  false,  0,  0,  0,      NULL},          // Access
89    {1,     false,  false,  0,  0,  0,      NULL},          // DHCPFilter
90    {2,     false,  false,  0,  0,  0,      NULL},          // DHCPNoServer
91    {3,     false,  false,  0,  0,  0,      NULL},          // DHCPForce
92    {4,     false,  false,  0,  0,  0,      NULL},          // NoBridge
93    {5,     false,  false,  0,  0,  0,      NULL},          // NoRouting
94    {6,     false,  false,  0,  0,  0,      NULL},          // CheckMac
95    {7,     false,  false,  0,  0,  0,      NULL},          // CheckIP
96    {8,     false,  false,  0,  0,  0,      NULL},          // ArpDhcpOnly
97    {9,     false,  false,  0,  0,  0,      NULL},          // PrivacyFilter
98    {10,    false,  false,  0,  0,  0,      NULL},          // NoServer
99    {11,    false,  false,  0,  0,  0,      NULL},          // NoBroadcastLimiter
100    {12,    false,  false,  0,  0,  0,      NULL},          // MonitorPort
101    {13,    true,   false,  1,  32, 32,     "POL_INT_COUNT"},   // MaxConnection
102    {14,    true,   false,  5,  60, 20,     "POL_INT_SEC"}, // TimeOut
103    {15,    true,   true,   1,  65535,  0,  "POL_INT_COUNT"},   // MaxMac
104    {16,    true,   true,   1,  65535,  0,  "POL_INT_COUNT"},   // MaxIP
105    {17,    true,   true,   1,  4294967295UL,   0,  "POL_INT_BPS"}, // MaxUpload
106    {18,    true,   true,   1,  4294967295UL,   0,  "POL_INT_BPS"}, // MaxDownload
107    {19,    false,  false,  0,  0,  0,      NULL},          // FixPassword
108    {20,    true,   true,   1,  65535,  0,  "POL_INT_COUNT"},   // MultiLogins
109    {21,    false,  false,  0,  0,  0,      NULL},          // NoQoS
110// Ver 3.0
111    {22,    false,  false,  0,  0,  0,      NULL},          // RSandRAFilter
112    {23,    false,  false,  0,  0,  0,      NULL},          // RAFilter
113    {24,    false,  false,  0,  0,  0,      NULL},          // DHCPv6Filter
114    {25,    false,  false,  0,  0,  0,      NULL},          // DHCPv6NoServer
115    {26,    false,  false,  0,  0,  0,      NULL},          // NoRoutingV6
116    {27,    false,  false,  0,  0,  0,      NULL},          // CheckIPv6
117    {28,    false,  false,  0,  0,  0,      NULL},          // NoServerV6
118    {29,    true,   true,   1,  65535,  0,  "POL_INT_COUNT"},   // MaxIPv6
119    {30,    false,  false,  0,  0,  0,      NULL},          // NoSavePassword
120    {31,    true,   true,   1,  4294967295UL,   0,  "POL_INT_SEC"}, // AutoDisconnect
121    {32,    false,  false,  0,  0,  0,      NULL},          // FilterIPv4
122    {33,    false,  false,  0,  0,  0,      NULL},          // FilterIPv6
123    {34,    false,  false,  0,  0,  0,      NULL},          // FilterNonIP
124    {35,    false,  false,  0,  0,  0,      NULL},          // NoIPv6DefaultRouterInRA
125    {36,    false,  false,  0,  0,  0,      NULL},          // NoIPv6DefaultRouterInRAWhenIPv6
126    {37,    true,   true,   1,  4095,   0,  "POL_INT_VLAN"},    // VLanId
127};
128
129// ポリシー名を正規化する
130char *NormalizePolicyName(char *name)
131{
132    // 引数チェック
133    if (name == NULL)
134    {
135        return NULL;
136    }
137
138    return PolicyIdToStr(PolicyStrToId(name));
139}
140
141// ポリシーの値をフォーマット
142void FormatPolicyValue(wchar_t *str, UINT size, UINT id, UINT value)
143{
144    POLICY_ITEM *p;
145    // 引数チェック
146    if (str == NULL)
147    {
148        return;
149    }
150
151    p = GetPolicyItem(id);
152
153    if (p->TypeInt == false)
154    {
155        // bool 型
156        if (value == 0)
157        {
158            UniStrCpy(str, size, L"No");
159        }
160        else
161        {
162            UniStrCpy(str, size, L"Yes");
163        }
164    }
165    else
166    {
167        // int 型
168        if (value == 0 && p->AllowZero)
169        {
170            UniStrCpy(str, size, _UU("CMD_NO_SETTINGS"));
171        }
172        else
173        {
174            UniFormat(str, size, _UU(p->FormatStr), value);
175        }
176    }
177}
178
179// ポリシーとして設定可能な値の範囲を説明する文字列を取得
180void GetPolicyValueRangeStr(wchar_t *str, UINT size, UINT id)
181{
182    POLICY_ITEM *p;
183    // 引数チェック
184    if (str == NULL)
185    {
186        return;
187    }
188
189    p = GetPolicyItem(id);
190
191    if (p->TypeInt == false)
192    {
193        // bool 型
194        UniStrCpy(str, size, _UU("CMD_PolicyList_Range_Bool"));
195    }
196    else
197    {
198        wchar_t *tag;
199        wchar_t tmp1[256], tmp2[256];
200
201        // int 型
202        if (p->AllowZero)
203        {
204            tag = _UU("CMD_PolicyList_Range_Int_2");
205        }
206        else
207        {
208            tag = _UU("CMD_PolicyList_Range_Int_1");
209        }
210
211        UniFormat(tmp1, sizeof(tmp1), _UU(p->FormatStr), p->MinValue);
212        UniFormat(tmp2, sizeof(tmp2), _UU(p->FormatStr), p->MaxValue);
213
214        UniFormat(str, size, tag, tmp1, tmp2);
215    }
216}
217
218// ポリシーアイテムの取得
219POLICY_ITEM *GetPolicyItem(UINT id)
220{
221    return &policy_item[id];
222}
223
224// 指定されたポリシーがカスケード接続でサポートされているかどうか
225bool PolicyIsSupportedForCascade(UINT i)
226{
227    // このあたりは急いで実装したのでコードがあまり美しくない。
228    if (i == 0 || i == 4 || i == 5 || i == 9 || i == 12 || i == 13 ||
229        i == 14 || i == 19 || i == 20 || i == 21 || i == 26 || i == 30 || i == 31 || i == 36)
230    {
231        // これらの項目はカスケード接続でサポートされていない
232        return false;
233    }
234
235    return true;
236}
237
238// ID をポリシーの名前に変換
239char *PolicyIdToStr(UINT i)
240{
241    // このあたりは急いで実装したのでコードがあまり美しくない。
242    switch (i)
243    {
244    // Ver 2.0
245    case 0:     return "Access";
246    case 1:     return "DHCPFilter";
247    case 2:     return "DHCPNoServer";
248    case 3:     return "DHCPForce";
249    case 4:     return "NoBridge";
250    case 5:     return "NoRouting";
251    case 6:     return "CheckMac";
252    case 7:     return "CheckIP";
253    case 8:     return "ArpDhcpOnly";
254    case 9:     return "PrivacyFilter";
255    case 10:    return "NoServer";
256    case 11:    return "NoBroadcastLimiter";
257    case 12:    return "MonitorPort";
258    case 13:    return "MaxConnection";
259    case 14:    return "TimeOut";
260    case 15:    return "MaxMac";
261    case 16:    return "MaxIP";
262    case 17:    return "MaxUpload";
263    case 18:    return "MaxDownload";
264    case 19:    return "FixPassword";
265    case 20:    return "MultiLogins";
266    case 21:    return "NoQoS";
267
268    // Ver 3.0
269    case 22:    return "RSandRAFilter";
270    case 23:    return "RAFilter";
271    case 24:    return "DHCPv6Filter";
272    case 25:    return "DHCPv6NoServer";
273    case 26:    return "NoRoutingV6";
274    case 27:    return "CheckIPv6";
275    case 28:    return "NoServerV6";
276    case 29:    return "MaxIPv6";
277    case 30:    return "NoSavePassword";
278    case 31:    return "AutoDisconnect";
279    case 32:    return "FilterIPv4";
280    case 33:    return "FilterIPv6";
281    case 34:    return "FilterNonIP";
282    case 35:    return "NoIPv6DefaultRouterInRA";
283    case 36:    return "NoIPv6DefaultRouterInRAWhenIPv6";
284    case 37:    return "VLanId";
285    }
286
287    return NULL;
288}
289
290// ポリシーの名前を ID に変換
291UINT PolicyStrToId(char *name)
292{
293    UINT i;
294    // 引数チェック
295    if (name == NULL)
296    {
297        return INFINITE;
298    }
299
300    for (i = 0;i < NUM_POLICY_ITEM;i++)
301    {
302        if (StartWith(PolicyIdToStr(i), name))
303        {
304            return i;
305        }
306    }
307
308    return INFINITE;
309}
310
311// ポリシーの総数を取得
312UINT PolicyNum()
313{
314    return NUM_POLICY_ITEM;
315}
316
317// 指定した名前をアカウント名として使用できるかどうか確認する
318bool IsUserName(char *name)
319{
320    // このあたりは急いで実装したのでコードがあまり美しくない。
321    char tmp[MAX_SIZE];
322    // 引数チェック
323    if (name == NULL)
324    {
325        return false;
326    }
327
328    StrCpy(tmp, sizeof(tmp), name);
329    name = tmp;
330
331    Trim(name);
332
333    if (StrLen(name) == 0)
334    {
335        return false;
336    }
337
338    if (StrCmpi(name, "*") == 0)
339    {
340        return true;
341    }
342
343    if (IsSafeStr(name) == false)
344    {
345        return false;
346    }
347
348    if (StrCmpi(name, LINK_USER_NAME) == 0)
349    {
350        return false;
351    }
352
353    if (StartWith(name, L3_USERNAME))
354    {
355        return false;
356    }
357
358    if (StrCmpi(name, LINK_USER_NAME_PRINT) == 0)
359    {
360        return false;
361    }
362
363    if (StrCmpi(name, SNAT_USER_NAME) == 0)
364    {
365        return false;
366    }
367
368    if (StrCmpi(name, SNAT_USER_NAME_PRINT) == 0)
369    {
370        return false;
371    }
372
373    if (StrCmpi(name, BRIDGE_USER_NAME) == 0)
374    {
375        return false;
376    }
377
378    if (StrCmpi(name, BRIDGE_USER_NAME_PRINT) == 0)
379    {
380        return false;
381    }
382
383    if (StrCmpi(name, ADMINISTRATOR_USERNAME) == 0)
384    {
385        return false;
386    }
387
388    return true;
389}
390
391// ポリシーのタイトルを取得する
392wchar_t *GetPolicyTitle(UINT id)
393{
394    char tmp[MAX_SIZE];
395    Format(tmp, sizeof(tmp), "POL_%u", id);
396
397    return _UU(tmp);
398}
399
400// ポリシーの説明を取得する
401wchar_t *GetPolicyDescription(UINT id)
402{
403    char tmp[MAX_SIZE];
404    Format(tmp, sizeof(tmp), "POL_EX_%u", id);
405
406    return _UU(tmp);
407}
408
409// ポリシーデータのクローン
410POLICY *ClonePolicy(POLICY *policy)
411{
412    POLICY *ret;
413    // 引数チェック
414    if (policy == NULL)
415    {
416        return NULL;
417    }
418
419    ret = ZeroMalloc(sizeof(POLICY));
420    Copy(ret, policy, sizeof(POLICY));
421
422    return ret;
423}
424
425// ポリシーを上書きする (古いバージョンを上書きする場合は新しいバージョンのデータは残す)
426void OverwritePolicy(POLICY **target, POLICY *p)
427{
428    // 引数チェック
429    if (target == NULL)
430    {
431        return;
432    }
433
434    if (p == NULL)
435    {
436        // ポリシー消去
437        if (*target != NULL)
438        {
439            Free(*target);
440            *target = NULL;
441        }
442    }
443    else
444    {
445        if (p->Ver3)
446        {
447            // Ver 3
448            if (*target != NULL)
449            {
450                Free(*target);
451                *target = NULL;
452            }
453
454            *target = ClonePolicy(p);
455        }
456        else
457        {
458            // Ver 2
459            if (*target == NULL)
460            {
461                *target = ClonePolicy(p);
462            }
463            else
464            {
465                Copy(*target, p, NUM_POLICY_ITEM_FOR_VER2 * sizeof(UINT));
466            }
467        }
468    }
469}
470
471// ユーザーポリシーの設定
472void SetUserPolicy(USER *u, POLICY *policy)
473{
474    // 引数チェック
475    if (u == NULL)
476    {
477        return;
478    }
479
480    Lock(u->lock);
481    {
482        OverwritePolicy(&u->Policy, policy);
483    }
484    Unlock(u->lock);
485}
486
487// ユーザーポリシーの取得
488POLICY *GetUserPolicy(USER *u)
489{
490    POLICY *ret;
491    // 引数チェック
492    if (u == NULL)
493    {
494        return NULL;
495    }
496
497    Lock(u->lock);
498    {
499        if (u->Policy == NULL)
500        {
501            ret = NULL;
502        }
503        else
504        {
505            ret = ClonePolicy(u->Policy);
506        }
507    }
508    Unlock(u->lock);
509
510    return ret;
511}
512
513// グループポリシーの設定
514void SetGroupPolicy(USERGROUP *g, POLICY *policy)
515{
516    // 引数チェック
517    if (g == NULL)
518    {
519        return;
520    }
521
522    Lock(g->lock);
523    {
524        OverwritePolicy(&g->Policy, policy);
525    }
526    Unlock(g->lock);
527}
528
529// グループポリシーの取得
530POLICY *GetGroupPolicy(USERGROUP *g)
531{
532    POLICY *ret;
533    // 引数チェック
534    if (g == NULL)
535    {
536        return NULL;
537    }
538
539    Lock(g->lock);
540    {
541        if (g->Policy == NULL)
542        {
543            ret = NULL;
544        }
545        else
546        {
547            ret = ClonePolicy(g->Policy);
548        }
549    }
550    Unlock(g->lock);
551
552    return ret;
553}
554
555// デフォルトのポリシーを返す
556POLICY *GetDefaultPolicy()
557{
558    // このあたりは急いで実装したのでコードがあまり美しくない。
559    static POLICY def_policy =
560    {
561        true,
562        false,
563        false,
564        false,
565        false,
566        false,
567        false,
568        false,
569        false,
570        false,
571        false,
572        false,
573        false,
574        32,
575        20,
576        0,
577        0,
578        0,
579        0,
580        false,
581        0,
582        false,
583        false,
584        false,
585        false,
586        false,
587        false,
588        false,
589        false,
590        0,
591        false,
592        0,
593        false,
594        false,
595        false,
596        false,
597        false,
598    };
599
600    return &def_policy;
601}
602
603// NT 認証データの作成
604void *NewNTAuthData(wchar_t *username)
605{
606    AUTHNT *a;
607    // 引数チェック
608    a = ZeroMallocEx(sizeof(AUTHNT), true);
609    a->NtUsername = CopyUniStr(username);
610
611    return a;
612}
613
614// Radius 認証データの作成
615void *NewRadiusAuthData(wchar_t *username)
616{
617    AUTHRADIUS *a;
618    // 引数チェック
619    a = ZeroMallocEx(sizeof(AUTHRADIUS), true);
620    a->RadiusUsername = CopyUniStr(username);
621
622    return a;
623}
624
625// ルート証明書による認証データの作成
626void *NewRootCertAuthData(X_SERIAL *serial, wchar_t *common_name)
627{
628    AUTHROOTCERT *a;
629
630    a = ZeroMallocEx(sizeof(AUTHROOTCERT), true);
631    if (common_name != NULL && UniIsEmptyStr(common_name) == false)
632    {
633        a->CommonName = CopyUniStr(common_name);
634    }
635    if (serial != NULL && serial->size >= 1)
636    {
637        a->Serial = CloneXSerial(serial);
638    }
639
640    return a;
641}
642
643// ユーザー証明書認証データの作成
644void *NewUserCertAuthData(X *x)
645{
646    AUTHUSERCERT *a;
647
648    a = ZeroMalloc(sizeof(AUTHUSERCERT));
649    a->UserX = CloneX(x);
650
651    return a;
652}
653
654// パスワードのハッシュ
655void HashPassword(void *dst, char *username, char *password)
656{
657    BUF *b;
658    char *username_upper;
659    // 引数チェック
660    if (dst == NULL || username == NULL || password == NULL)
661    {
662        return;
663    }
664
665    b = NewBuf();
666    username_upper = CopyStr(username);
667    StrUpper(username_upper);
668    WriteBuf(b, password, StrLen(password));
669    WriteBuf(b, username_upper, StrLen(username_upper));
670    Hash(dst, b->Buf, b->Size, true);
671
672    FreeBuf(b);
673    Free(username_upper);
674}
675
676// パスワード認証データの作成
677void *NewPasswordAuthData(char *username, char *password)
678{
679    AUTHPASSWORD *pw;
680    // 引数チェック
681    if (username == NULL || password == NULL)
682    {
683        return NULL;
684    }
685
686    pw = ZeroMalloc(sizeof(AUTHPASSWORD));
687    HashPassword(pw->HashedKey, username, password);
688
689    return pw;
690}
691void *NewPasswordAuthDataRaw(UCHAR *hashed_password)
692{
693    AUTHPASSWORD *pw;
694    // 引数チェック
695    if (hashed_password == NULL)
696    {
697        return NULL;
698    }
699
700    pw = ZeroMalloc(sizeof(AUTHPASSWORD));
701    Copy(pw->HashedKey, hashed_password, SHA1_SIZE);
702
703    return pw;
704}
705
706// ユーザーの認証データのコピー
707void *CopyAuthData(void *authdata, UINT authtype)
708{
709    AUTHPASSWORD *pw = (AUTHPASSWORD *)authdata;
710    AUTHUSERCERT *usercert = (AUTHUSERCERT *)authdata;
711    AUTHROOTCERT *rootcert = (AUTHROOTCERT *)authdata;
712    AUTHRADIUS *radius = (AUTHRADIUS *)authdata;
713    AUTHNT *nt = (AUTHNT *)authdata;
714    // 引数チェック
715    if (authdata == NULL || authtype == AUTHTYPE_ANONYMOUS)
716    {
717        return NULL;
718    }
719
720    switch (authtype)
721    {
722    case AUTHTYPE_PASSWORD:
723        {
724            AUTHPASSWORD *ret = ZeroMalloc(sizeof(AUTHPASSWORD));
725            Copy(ret, pw, sizeof(AUTHPASSWORD));
726            return ret;
727        }
728        break;
729
730    case AUTHTYPE_USERCERT:
731        {
732            AUTHUSERCERT *ret = ZeroMalloc(sizeof(AUTHUSERCERT));
733            ret->UserX = CloneX(usercert->UserX);
734            return ret;
735        }
736        break;
737
738    case AUTHTYPE_ROOTCERT:
739        {
740            AUTHROOTCERT *ret = ZeroMalloc(sizeof(AUTHROOTCERT));
741            ret->CommonName = CopyUniStr(rootcert->CommonName);
742            ret->Serial = CloneXSerial(rootcert->Serial);
743            return ret;
744        }
745        break;
746
747    case AUTHTYPE_RADIUS:
748        {
749            AUTHRADIUS *ret = ZeroMalloc(sizeof(AUTHRADIUS));
750            ret->RadiusUsername = UniCopyStr(radius->RadiusUsername);
751            return ret;
752        }
753        break;
754
755    case AUTHTYPE_NT:
756        {
757            AUTHNT *ret = ZeroMalloc(sizeof(AUTHNT));
758            ret->NtUsername = UniCopyStr(nt->NtUsername);
759            return ret;
760        }
761        break;
762    }
763
764    return NULL;
765}
766
767// ユーザーの認証データのセット
768void SetUserAuthData(USER *u, UINT authtype, void *authdata)
769{
770    // 引数チェック
771    if (u == NULL)
772    {
773        return;
774    }
775    if (authtype != AUTHTYPE_ANONYMOUS && authdata == NULL)
776    {
777        return;
778    }
779
780    Lock(u->lock);
781    {
782        if (u->AuthType != AUTHTYPE_ANONYMOUS)
783        {
784            // 現在の認証データの解放
785            FreeAuthData(u->AuthType, u->AuthData);
786        }
787        // 新しい認証データの設定
788        u->AuthType = authtype;
789        u->AuthData = authdata;
790    }
791    Unlock(u->lock);
792}
793
794// グループのトラフィックデータを加算
795void AddGroupTraffic(USERGROUP *g, TRAFFIC *diff)
796{
797    // 引数チェック
798    if (g == NULL || diff == NULL)
799    {
800        return;
801    }
802
803    Lock(g->lock);
804    {
805        AddTraffic(g->Traffic, diff);
806    }
807    Unlock(g->lock);
808}
809
810// ユーザーのトラフィックデータを加算
811void AddUserTraffic(USER *u, TRAFFIC *diff)
812{
813    // 引数チェック
814    if (u == NULL || diff == NULL)
815    {
816        return;
817    }
818
819    Lock(u->lock);
820    {
821        AddTraffic(u->Traffic, diff);
822    }
823    Unlock(u->lock);
824}
825
826// グループのトラフィック情報をセット
827void SetGroupTraffic(USERGROUP *g, TRAFFIC *t)
828{
829    // 引数チェック
830    if (g == NULL)
831    {
832        return;
833    }
834
835    Lock(g->lock);
836    {
837        if (t != NULL)
838        {
839            Copy(g->Traffic, t, sizeof(TRAFFIC));
840        }
841        else
842        {
843            Zero(g->Traffic, sizeof(TRAFFIC));
844        }
845    }
846    Unlock(g->lock);
847}
848
849// ユーザーのトラフィック情報をセット
850void SetUserTraffic(USER *u, TRAFFIC *t)
851{
852    // 引数チェック
853    if (u == NULL)
854    {
855        return;
856    }
857
858    Lock(u->lock);
859    {
860        if (t != NULL)
861        {
862            Copy(u->Traffic, t, sizeof(TRAFFIC));
863        }
864        else
865        {
866            Zero(u->Traffic, sizeof(TRAFFIC));
867        }
868    }
869    Unlock(u->lock);
870}
871
872// ユーザーをグループに所属させる
873void JoinUserToGroup(USER *u, USERGROUP *g)
874{
875    // 引数チェック
876    if (u == NULL)
877    {
878        return;
879    }
880
881    if (g != NULL)
882    {
883        // 参加
884        Lock(u->lock);
885        {
886            Lock(g->lock);
887            {
888                if (u->Group != NULL)
889                {
890                    // まずユーザーをグループから外す
891                    ReleaseGroup(u->Group);
892                    u->Group = NULL;
893                    Free(u->GroupName);
894                    u->GroupName = NULL;
895                }
896                // ユーザーをグループに追加する
897                u->GroupName = CopyStr(g->Name);
898                u->Group = g;
899                AddRef(g->ref);
900            }
901            Unlock(g->lock);
902        }
903        Unlock(u->lock);
904    }
905    else
906    {
907        // 脱退
908        Lock(u->lock);
909        {
910            if (u->Group != NULL)
911            {
912                // ユーザーをグループから外す
913                ReleaseGroup(u->Group);
914                u->Group = NULL;
915                Free(u->GroupName);
916                u->GroupName = NULL;
917            }
918        }
919        Unlock(u->lock);
920    }
921}
922
923// グループ名チェック
924bool AcIsGroup(HUB *h, char *name)
925{
926    USERGROUP *g;
927    // 引数チェック
928    if (h == NULL || name == NULL || NO_ACCOUNT_DB(h))
929    {
930        return false;
931    }
932
933    g = AcGetGroup(h, name);
934    if (g == NULL)
935    {
936        return false;
937    }
938    ReleaseGroup(g);
939
940    return true;
941}
942
943// ユーザー名チェック
944bool AcIsUser(HUB *h, char *name)
945{
946    USER *u;
947    // 引数チェック
948    if (h == NULL || name == NULL || NO_ACCOUNT_DB(h))
949    {
950        return false;
951    }
952
953    u = AcGetUser(h, name);
954    if (u == NULL)
955    {
956        return false;
957    }
958    ReleaseUser(u);
959
960    return true;
961}
962
963// グループの取得
964USERGROUP *AcGetGroup(HUB *h, char *name)
965{
966    USERGROUP *g, t;
967    // 引数チェック
968    if (h == NULL || name == NULL || NO_ACCOUNT_DB(h))
969    {
970        return NULL;
971    }
972
973    t.Name = name;
974    g = Search(h->HubDb->GroupList, &t);
975    if (g == NULL)
976    {
977        return NULL;
978    }
979    AddRef(g->ref);
980
981    return g;
982}
983
984// ユーザーの取得
985USER *AcGetUser(HUB *h, char *name)
986{
987    USER *u, t;
988    // 引数チェック
989    if (h == NULL || name == NULL || NO_ACCOUNT_DB(h))
990    {
991        return NULL;
992    }
993
994    t.Name = name;
995    u = Search(h->HubDb->UserList, &t);
996    if (u == NULL)
997    {
998        return NULL;
999    }
1000    AddRef(u->ref);
1001
1002    return u;
1003}
1004
1005// ユーザーの削除
1006bool AcDeleteUser(HUB *h, char *name)
1007{
1008    USER *u;
1009    // 引数チェック
1010    if (h == NULL || name == NULL)
1011    {
1012        return false;
1013    }
1014
1015    u = AcGetUser(h, name);
1016    if (u == NULL)
1017    {
1018        return false;
1019    }
1020
1021    if (Delete(h->HubDb->UserList, u))
1022    {
1023        ReleaseUser(u);
1024    }
1025
1026    ReleaseUser(u);
1027
1028    return true;
1029}
1030
1031// グループの削除
1032bool AcDeleteGroup(HUB *h, char *name)
1033{
1034    USERGROUP *g;
1035    UINT i;
1036    // 引数チェック
1037    if (h == NULL || name == NULL)
1038    {
1039        return false;
1040    }
1041
1042    g = AcGetGroup(h, name);
1043    if (g == NULL)
1044    {
1045        return false;
1046    }
1047
1048    if (Delete(h->HubDb->GroupList, g))
1049    {
1050        ReleaseGroup(g);
1051    }
1052
1053    for (i = 0;i < LIST_NUM(h->HubDb->UserList);i++)
1054    {
1055        USER *u = LIST_DATA(h->HubDb->UserList, i);
1056        Lock(u->lock);
1057        {
1058            if (u->Group == g)
1059            {
1060                JoinUserToGroup(u, NULL);
1061            }
1062        }
1063        Unlock(u->lock);
1064    }
1065
1066    ReleaseGroup(g);
1067
1068    return true;
1069}
1070
1071// グループの追加
1072bool AcAddGroup(HUB *h, USERGROUP *g)
1073{
1074    // 引数チェック
1075    if (h == NULL || g == NULL || NO_ACCOUNT_DB(h))
1076    {
1077        return false;
1078    }
1079
1080    if (LIST_NUM(h->HubDb->GroupList) >= MAX_GROUPS)
1081    {
1082        return false;
1083    }
1084
1085    if (AcIsGroup(h, g->Name) != false)
1086    {
1087        return false;
1088    }
1089
1090    Insert(h->HubDb->GroupList, g);
1091    AddRef(g->ref);
1092
1093    return true;
1094}
1095
1096// ユーザーの追加
1097bool AcAddUser(HUB *h, USER *u)
1098{
1099    // 引数チェック
1100    if (h == NULL || u == NULL || NO_ACCOUNT_DB(h))
1101    {
1102        return false;
1103    }
1104
1105    if (LIST_NUM(h->HubDb->UserList) >= MAX_USERS)
1106    {
1107        return false;
1108    }
1109
1110    if (AcIsUser(h, u->Name) != false)
1111    {
1112        return false;
1113    }
1114
1115    Insert(h->HubDb->UserList, u);
1116    AddRef(u->ref);
1117
1118    return true;
1119}
1120
1121// ユーザーの解放
1122void ReleaseUser(USER *u)
1123{
1124    // 引数チェック
1125    if (u == NULL)
1126    {
1127        return;
1128    }
1129
1130    if (Release(u->ref) == 0)
1131    {
1132        CleanupUser(u);
1133    }
1134}
1135
1136// ユーザーのクリーンアップ
1137void CleanupUser(USER *u)
1138{
1139    // 引数チェック
1140    if (u == NULL)
1141    {
1142        return;
1143    }
1144
1145    DeleteLock(u->lock);
1146    Free(u->Name);
1147    Free(u->RealName);
1148    Free(u->Note);
1149    Free(u->GroupName);
1150    if (u->Group != NULL)
1151    {
1152        ReleaseGroup(u->Group);
1153    }
1154
1155    // 認証データの解放
1156    FreeAuthData(u->AuthType, u->AuthData);
1157
1158    if (u->Policy)
1159    {
1160        // ポリシー解放
1161        Free(u->Policy);
1162    }
1163
1164    FreeTraffic(u->Traffic);
1165
1166    Free(u);
1167}
1168
1169// 認証データの解放
1170void FreeAuthData(UINT authtype, void *authdata)
1171{
1172    AUTHPASSWORD *pw = (AUTHPASSWORD *)authdata;
1173    AUTHUSERCERT *uc = (AUTHUSERCERT *)authdata;
1174    AUTHROOTCERT *rc = (AUTHROOTCERT *)authdata;
1175    AUTHRADIUS *rd = (AUTHRADIUS *)authdata;
1176    AUTHNT *nt = (AUTHNT *)authdata;
1177    // 引数チェック
1178    if (authtype == AUTHTYPE_ANONYMOUS || authdata == NULL)
1179    {
1180        return;
1181    }
1182
1183    switch (authtype)
1184    {
1185    case AUTHTYPE_PASSWORD:
1186        // パスワード認証
1187        // 何も解放しない
1188        break;
1189
1190    case AUTHTYPE_USERCERT:
1191        // ユーザー証明書
1192        FreeX(uc->UserX);
1193        break;
1194
1195    case AUTHTYPE_ROOTCERT:
1196        // ルート証明書
1197        if (rc->Serial != NULL)
1198        {
1199            FreeXSerial(rc->Serial);
1200        }
1201        if (rc->CommonName != NULL)
1202        {
1203            Free(rc->CommonName);
1204        }
1205        break;
1206
1207    case AUTHTYPE_RADIUS:
1208        // Radius 認証
1209        Free(rd->RadiusUsername);
1210        break;
1211
1212    case AUTHTYPE_NT:
1213        // Windows NT 認証
1214        Free(nt->NtUsername);
1215        break;
1216    }
1217
1218    Free(authdata);
1219}
1220
1221// ユーザーの作成
1222USER *NewUser(char *name, wchar_t *realname, wchar_t *note, UINT authtype, void *authdata)
1223{
1224    USER *u;
1225    // 引数チェック
1226    if (name == NULL || realname == NULL || note == NULL)
1227    {
1228        return NULL;
1229    }
1230    if (authtype != AUTHTYPE_ANONYMOUS && authdata == NULL)
1231    {
1232        return NULL;
1233    }
1234
1235    u = ZeroMalloc(sizeof(USER));
1236    u->lock = NewLock();
1237    u->ref = NewRef();
1238    u->Name = CopyStr(name);
1239    u->RealName = CopyUniStr(realname);
1240    u->Note = CopyUniStr(note);
1241    u->GroupName = NULL;
1242    u->Group = NULL;
1243    u->AuthType = authtype;
1244    u->AuthData = authdata;
1245    u->CreatedTime = SystemTime64();
1246    u->UpdatedTime = SystemTime64();
1247
1248    u->Policy = NULL;
1249    u->Traffic = NewTraffic();
1250
1251    return u;
1252}
1253
1254// グループの解放
1255void ReleaseGroup(USERGROUP *g)
1256{
1257    // 引数チェック
1258    if (g == NULL)
1259    {
1260        return;
1261    }
1262
1263    if (Release(g->ref) == 0)
1264    {
1265        CleanupGroup(g);
1266    }
1267}
1268
1269// グループのクリーンアップ
1270void CleanupGroup(USERGROUP *g)
1271{
1272    // 引数チェック
1273    if (g == NULL)
1274    {
1275        return;
1276    }
1277
1278    Free(g->Name);
1279    Free(g->RealName);
1280    Free(g->Note);
1281
1282    if (g->Policy)
1283    {
1284        // ポリシー解放
1285        Free(g->Policy);
1286    }
1287
1288
1289    FreeTraffic(g->Traffic);
1290
1291    DeleteLock(g->lock);
1292    Free(g);
1293}
1294
1295// 新しいグループを作成
1296USERGROUP *NewGroup(char *name, wchar_t *realname, wchar_t *note)
1297{
1298    USERGROUP *g;
1299    // 引数チェック
1300    if (name == NULL || realname == NULL || note == NULL)
1301    {
1302        return NULL;
1303    }
1304
1305    g = ZeroMalloc(sizeof(USERGROUP));
1306    g->lock = NewLock();
1307    g->ref = NewRef();
1308    g->Name = CopyStr(name);
1309    g->RealName = CopyUniStr(realname);
1310    g->Note = CopyUniStr(note);
1311    g->Policy = NULL;
1312    g->Traffic = NewTraffic();
1313
1314    return g;
1315}
1316
1317// HUB のアカウントデータベースのロック
1318void AcLock(HUB *h)
1319{
1320    // 引数チェック
1321    if (h == NULL)
1322    {
1323        return;
1324    }
1325    if (NO_ACCOUNT_DB(h))
1326    {
1327        return;
1328    }
1329
1330    // グループとユーザーをロック
1331    LockList(h->HubDb->GroupList);
1332    LockList(h->HubDb->UserList);
1333}
1334
1335// HUB のアカウントデータベースのロック解除
1336void AcUnlock(HUB *h)
1337{
1338    // 引数チェック
1339    if (h == NULL)
1340    {
1341        return;
1342    }
1343    if (NO_ACCOUNT_DB(h))
1344    {
1345        return;
1346    }
1347
1348    // グループとユーザーをロック解除
1349    UnlockList(h->HubDb->UserList);
1350    UnlockList(h->HubDb->GroupList);
1351}
1352
1353// グループ名比較関数
1354int CompareGroupName(void *p1, void *p2)
1355{
1356    USERGROUP *g1, *g2;
1357    // 引数チェック
1358    if (p1 == NULL || p2 == NULL)
1359    {
1360        return 0;
1361    }
1362    g1 = *(USERGROUP **)p1;
1363    g2 = *(USERGROUP **)p2;
1364    if (g1 == NULL || g2 == NULL)
1365    {
1366        return 0;
1367    }
1368
1369    return StrCmpi(g1->Name, g2->Name);
1370}
1371
1372// ユーザー名比較関数
1373int CompareUserName(void *p1, void *p2)
1374{
1375    USER *u1, *u2;
1376    // 引数チェック
1377    if (p1 == NULL || p2 == NULL)
1378    {
1379        return 0;
1380    }
1381    u1 = *(USER **)p1;
1382    u2 = *(USER **)p2;
1383    if (u1 == NULL || u2 == NULL)
1384    {
1385        return 0;
1386    }
1387
1388    return StrCmpi(u1->Name, u2->Name);
1389}
1390
Note: See TracBrowser for help on using the repository browser.