1 \documentstyle[times,fullpage,rcsid]{article}
5 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 %% Make _ actually generate an _, and allow line-breaking after it.
9 \def_{\underscore\penalty75\relax}
10 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
12 \newcommand{\test}[1]{\begin{description}
13 \setlength{\itemsep}{0pt}
19 \newcommand{\numtest}[2]{\begin{description}
20 \setlength{\itemsep}{0pt}
27 \newcommand{\Number}[1]{\item[Number:] #1}
28 \newcommand{\Reason}[1]{\item[Reason:] #1}
29 %\newcommand{\Call}[1]{\item[Call:] #1}
30 \newcommand{\Expected}[1]{\item[Expected:] #1}
31 \newcommand{\Conditions}[1]{\item[Conditions:] #1}
32 \newcommand{\Priority}[1]{\item[Priority:] #1}
33 \newcommand{\Status}[1]{\item[Status:] #1}
34 %\newcommand{\Number}[1]{}
35 %\newcommand{\Reason}[1]{}
36 \newcommand{\Call}[1]{}
37 %\newcommand{\Expected}[1]{}
38 %\newcommand{\Conditions}[1]{}
39 %\newcommand{\Priority}[1]{}
41 \title{OpenV*Secure 1.0 Admin API\\
42 Unit Test Description\footnote{\rcsHeader}}
43 \author{Jonathan I. Kamens}
51 \section{Introduction}
53 The following is a description of a black-box unit test of the
54 OpenV*Secure Admin API. Each API function is listed, followed by the
55 tests that shoud be performed on it.
57 The tests described here are based on the ``OV*Secure Admin Functional
58 Specifications'' revision 1.27, dated November 17, 1993.
60 Since inter-realm functionality is not a requirement for OpenV*Secure
61 1.0, it is not tested.
63 All tests which test for success should verify, using some means other
64 than the return value of the function being tested, that the requested
65 operation was successfully performed. For example: for init, test
66 that other operations can be performed after init; for destroy, test
67 that other operations can't be performed after destroy; for modify
68 functions, verify that all modifications to the database which should
69 have taken place did, and that the new, modified data is in effect;
70 for get operations, verify that the data retrieved is the data that
71 should actually be in the database.
73 As of now the tests are being re-worked to use database comparision routines
74 simular to the GUI tests. This routines are not completly in place yet. The
75 purpose for using these routines is for better detection of incorrect
76 database modification.
78 Similarly, all tests which test for failure should verify that the
79 no component of the requested operation took place. For example: if
80 init fails, other operations should not work. If a modify fails, all
81 data in the database should be the same as it was before the attempt
82 to modify, and the old data should still be what is enforced.
83 Furthermore, tests which test for failure should verify that the
84 failure code returned is correct for the specific failure condition
87 Most of the tests listed below should be run twice -- once locally on
88 the server after linking against the server API library, and once
89 talking to the server via authenticated Sun RPC after linking against
90 the client API library. Tests which should only be run locally or via
91 RPC are labelled with a ``local'' or ``RPC''.
93 Furthermore, in addition to the tests labelled below, a test should be
94 implemented to verify that a client can't perform operations on the
95 server through the client API library when it's linked against
96 standard Sun RPC instead of OpenV*Secure's authenticated Sun RPC.
97 This will require a client with a modified version of ovsec_kadm_init
98 which doesn't call auth_gssapi_create. This client should call this
99 modified ovsec_kadm_init and then call some other admin API function,
100 specifying arguments to both functions that would work if the
101 authenciated Sun RPC had been used, but shouldn't if authentication
102 wasn't used. The test should verify that the API function call after
103 the init doesn't succeed.
105 \section{ovsec_kadm_init}
108 \Reason{An empty string realm is rejected.}
113 \Reason{A realm containing invalid characters is rejected.}
118 \Reason{A non-existent realm is rejected.}
123 \Reason{A bad service name representing an existing principal
124 (different from the client principal) is rejected.}
130 \Reason{A bad service name representing a non-existent
131 principal is rejected.}
137 \Reason{A bad service name identical to the (existing) client
144 \Reason{A null password causes password prompting.}
149 \Reason{An empty-string causes password prompting}
154 \Reason{An incorrect password which is the password of another
161 \Reason{An incorrect password which isn't the password of any
168 \Reason{A null client_name is rejected.}
172 % Empty string client name is legal.
174 %\Reason{An empty-string client_name is rejected.}
178 \Reason{A client_name referring to a non-existent principal in
179 the default realm is rejected.}
185 \Reason{A client_name referring to a non-existent principal
186 with the local realm specified explicitly is rejected.}
192 \Reason{A client_name referring to a non-existent principal in
193 a nonexistent realm is rejected.}
199 \Reason{A client_name referring to an existing principal in a
200 nonexistent realm is rejected.}
206 \Reason{Valid invocation.}
211 \Reason{Valid invocation (explicit client realm).}
216 \Reason{Valid invocation (CHANGEPW_SERVICE).}
221 \Reason{Valid invocation (explicit service realm).}
226 \Reason{Valid invocation (database access allowed after init).}
231 \Reason{Init fails when called twice in a row.}
236 \Reason{A null password causes master-key prompting.}
242 \Reason{A non-null password causes reading from the kstash.}
249 \Reason{Null service name is ignored in local invocation.}
255 \Reason{Non-null service name is ignored in local invocation.}
261 \Reason{Can't do ``get'' operation before calling init.}
266 \Reason{Can't do ``add'' operation before calling init.}
271 \Reason{Can't do ``modify'' operation before calling init.}
276 \Reason{Can't do ``delete'' operation before calling init.}
281 \Reason{Can init after failed init attempt.}
286 \section{ovsec_kadm_destroy}
289 \Reason{Valid invocation.}
294 \Reason{Valid invocation (``get'' not allowed after destroy).}
299 \Reason{Valid invocation (``add'' not allowed after destroy).}
304 \Reason{Valid invocation (``modify'' not allowed after destroy).}
309 \Reason{Valid invocation (``delete'' not allowed after destroy).}
314 \Reason{Fails if database not initialized.}
319 \Reason{Fails if invoked twice in a row.}
324 \Reason{Database can be reinitialized after destroy.}
328 \section{ovsec_kadm_create_principal}
330 %In the tests below, ``getu'' refers to a user who has only ``get'' access,
331 %''addu'' refers to a user who has only ``add'' access, ``modifyu'' refers to
332 %a user who has only ``modify'' access, and ``deleteu'' refers to a user
333 %who has only ``delete'' access. ``amu'' refers to a user with ``add'' and
334 %''modify'' access. ``new_princ'' refers to a principal entry structure
335 %filled in as follows:
337 % krb5_parse_name("newuser", \&new_princ.principal);
338 % krb5_timeofday(\&new_princ.princ_expire_time);
339 % new_princ.princ_expire_time += 130;
340 % krb5_timeofday(\&new_princ.last_pwd_change);
341 % new_princ.last_pwd_change += 140;
342 % krb5_timeofday(\&new_princ.pw_expiration);
343 % new_princ.pw_expiration += 150;
344 % new_princ.max_life = 160;
345 % krb5_parse_name("usera", \&new_princ.mod_name);
346 % krb5_timeofday(\&new_princ.mod_date);
347 % new_princ.mod_date += 170;
348 % new_princ.attributes = 0xabcdabcd;
349 % new_princ.kvno = 180;
350 % new_princ.mkvno = 190;
351 % new_princ.policy = null;
352 % new_princ.aux_attributes = 0xdeadbeef;
354 %The offsets of 130 through 190 above are used to ensure that the
355 %fields are all known to be different from each other, so that
356 %accidentally switched fields can be detected. Some of the fields in
357 %this structure may be changed by the tests, but they should clean up
361 \Reason{Fails if database not initialized.}
366 \Reason{Fails on null princ argument.}
371 \Reason{Fails on null password argument.}
376 \Reason{Fails on empty-string password argument.}
381 \Reason{Fails when mask contains undefined bit.}
386 \Reason{Fails when mask contains LAST_PWD_CHANGE bit.}
391 \Reason{Fails when mask contains MOD_TIME bit.}
396 \Reason{Fails when mask contains MOD_NAME bit.}
401 \Reason{Fails when mask contains MKVNO bit.}
406 \Reason{Fails when mask contains AUX_ATTRIBUTES bit.}
411 \Reason{Fails when mask contains POLICY_CLR bit.}
416 \Reason{Fails for caller with no access bits.}
421 \Reason{Fails when caller has ``get'' access and not ``add''.}
427 \Reason{Fails when caller has ``modify'' access and not ``add''.}
433 \Reason{Fails when caller has ``delete'' access and not ``add''.}
439 \Reason{Fails when caller connected with CHANGEPW_SERVICE.}
445 \Reason{Fails on attempt to create existing principal.}
450 \Reason{Fails when password is too short.}
455 \Reason{Fails when password has too few classes.}
460 \Reason{Fails when password is in dictionary.}
465 \Reason{Nonexistent policy is rejected.}
470 \Reason{Fails on invalid principal name.}
475 \Reason{Valid invocation.}
480 \Reason{Succeeds when caller has ``add'' access and another one.}
485 %\Reason{Fails when password is too short, when override_qual is true.}
489 %\Reason{Fails when password has too few classes, when
490 % override_qual is true.}
494 %\Reason{Fails when password is in dictionary, when override_qual is
499 \Reason{Succeeds when assigning policy.}
505 \Reason{Allows 0 (never) for princ_expire_time.}
510 \Reason{Allows 0 (never) for pw_expiration when there's no policy.}
515 \Reason{Allows 0 (never) for pw_expiration when there's a policy with
521 \Reason{Accepts 0 (never) for pw_expiration when there's a policy with
522 non-zero pw_max_life, but actually sets pw_expiration to now +
528 \Reason{Accepts and sets non-zero pw_expiration when no policy.}
533 \Reason{Accepts and sets non-zero pw_expiration when there's a policy
534 with zero pw_max_life.}
539 \Reason{Accepts and sets non-zero pw_expiration when there's a policy
540 with pw_max_life later than the specified pw_expiration.}
545 \Reason{Accepts non-zero pw_expiration and limits it to now +
546 pw_max_life when it's later than now + non-zero pw_max_life in
553 \Reason{Sets pw_expiration to 0 (never) if there's no policy and no
554 specified pw_expiration.}
560 \Reason{Sets pw_expiration to 0 (never) if it isn't specified and the
561 policy has a 0 (never) pw_max_life.}
567 \Reason{Sets pw_expiration to now + pw_max_life if it isn't specified
568 and the policy has a non-zero pw_max_life.}
574 \Reason{Allows 0 (forever) for max_life.}
580 \Reason{Doesn't modify or free mod_name on success.}
585 \Reason{Doesn't modify or free mod_name on failure.}
588 \section{ovsec_kadm_delete_principal}
591 \Reason{Fails if database not initialized.}
596 \Reason{Fails on null principal.}
600 % Empty string principal is legal.
602 %\Reason{Fails on empty-string principal.}
605 % There is not invalid principal names
607 %\Reason{Fails on invalid principal name.}
612 \Reason{Fails on nonexistent principal.}
618 \Reason{Fails when caller connected with CHANGEPW_SERVICE.}
625 \Reason{Fails if caller has ``add'' access and not ``delete''.}
632 \Reason{Fails if caller has ``modify'' access and not ``delete''.}
639 \Reason{Fails if caller has ``get'' access and not ``delete''.}
646 \Reason{Fails if caller has no access bits.}
653 \Reason{Valid invocation.}
659 \Reason{Valid invocation (on principal with policy).}
665 \section{ovsec_kadm_modify_principal}
668 \Reason{Fails if database not initialized.}
674 \Reason{Fails if user connected with CHANGEPW_SERVICE.}
680 \Reason{Fails on mask with undefined bit set.}
685 \Reason{Fails on mask with PRINCIPAL set.}
691 \Reason{Fails on mask with LAST_PWD_CHANGE set.}
696 \Reason{Fails on mask with MOD_TIME set.}
701 \Reason{Fails on mask with MOD_NAME set.}
706 \Reason{Fails on mask with MKVNO set.}
712 \Reason{Fails on mask with AUX_ATTRIBUTES set.}
717 \Reason{Fails on nonexistent principal.}
723 \Reason{Fails for user with no access bits.}
730 \Reason{Fails for user with ``get'' access.}
737 \Reason{Fails for user with ``add'' access.}
744 \Reason{Fails for user with ``delete'' access.}
751 \Reason{Succeeds for user with ``modify'' access.}
757 \Reason{Succeeds for user with ``modify'' and another access.}
764 \Reason{Fails when nonexistent policy is specified.}
770 \Reason{Succeeds when existent policy is specified.}
775 \Reason{Updates policy count when setting policy from none.}
780 \Reason{Updates policy count when clearing policy from set.}
785 \Reason{Updates policy count when setting policy from other policy.}
790 \Reason{Policy reference count remains unchanged when policy is
792 \status{Implemented.}
796 \Reason{Allows 0 (never) for pw_expiration when there's no policy.}
801 \Reason{Allows 0 (never) for pw_expiration when there's a policy with
807 \Reason{Accepts 0 (never) for pw_expiration when there's a policy with
808 non-zero pw_max_life, but actually sets pw_expiration to
809 last_pwd_change + pw_max_life.}
814 \Reason{Accepts and sets non-zero pw_expiration when no policy.}
819 \Reason{Accepts and sets non-zero pw_expiration when there's a policy
820 with zero pw_max_life.}
825 \Reason{Accepts and sets non-zero pw_expiration when there's a policy
826 with pw_max_life later than the specified pw_expiration.}
831 \Reason{Accepts non-zero pw_expiration and limits it to last_pwd_change +
832 pw_max_life when it's later than last_pwd_change + non-zero
833 pw_max_life in policy.}
839 \Reason{Sets pw_expiration to 0 (never) if there's no policy and no
840 specified pw_expiration.}
846 \Reason{Sets pw_expiration to 0 (never) if it isn't specified and the
847 policy has a 0 (never) pw_max_life.}
853 \Reason{Sets pw_expiration to now + pw_max_life if it isn't specified
854 and the policy has a non-zero pw_max_life.}
860 \Reason{Accepts princ_expire_time change.}
868 \Reason{Accepts attributes change.}
874 \Reason{Accepts attributes change (KRB5_KDB_REQUIRES_PW_CHANGE).}
880 \Reason{Accepts attributes change (KRB5_DISALLOW_TGT_BASE).}
886 \Reason{Accepts attributes change (KRB5_PW_CHANGE_SERVICE).}
892 \Reason{Accepts max_life change.}
898 \Reason{Accepts kvno change.}
903 \Reason{Behaves correctly when policy is set to the same as it was
909 \Reason{Behaves properly when POLICY_CLR is specified and there was no
916 \Reason{Accepts 0 (never) for princ_expire_time.}
922 \Reason{Accepts 0 for max_life.}
927 \Reason{Rejects null principal argument.}
933 \Reason{Doesn't modify or free mod_name on success.}
938 \Reason{Doesn't modify or free mod_name on failure.}
942 \section{ovsec_kadm_rename_principal}
945 \Reason{Fails if database not initialized.}
951 \Reason{Fails if user connected with CHANGEPW_SERVICE.}
958 \Reason{Fails for user with no access bits.}
964 \Reason{Fails for user with ``modify'' access and not ``add'' or
971 \Reason{Fails for user with ``get'' access and not ``add'' or
978 \Reason{Fails for user with ``modify'' and ``add'' but not ``delete''.}
984 \Reason{Fails for user with ``modify'' and ``delete'' but not ``add''.}
990 \Reason{Fails for user with ``get'' and ``add'' but not ``delete''.}
996 \Reason{Fails for user with ``get'' and ``delete'' but not ``add.''}
1002 \Reason{Fails for user with ``modify'', ``get'' and ``add'', but not
1005 \Status{Implemented}
1009 \Reason{Fails for user with ``modify'', ``get'' and ``delete'', but
1012 \Status{Implemented}
1017 \Reason{Fails for user with ``add'' but not ``delete''.}
1019 \Status{Implemented}
1024 \Reason{Fails for user with ``delete'' but not ``add''.}
1026 \Status{Implemented}
1031 \Reason{Succeeds for user with ``add'' and ``delete''.}
1032 \Status{Implemented}
1037 \Reason{Fails if target principal name exists.}
1038 \Status{Implemented}
1043 \section{ovsec_kadm_chpass_principal}
1044 \label{ovseckadmchpassprincipal}
1046 \subsection{Quality/history enforcement tests}
1048 This section lists a series of tests which will be run a number of
1049 times, with various parameter settings (e.g., which access bits user
1050 has, whether user connected with ADMIN_SERVICE or CHANGEPW_SERVICE,
1051 etc.). The table following the
1052 list of tests gives the various parameter settings under which the
1053 tests should be run, as well which should succeed and which should
1054 fail for each choice of parameter settings.
1056 \subsubsection{List of tests}
1058 The test number of each of these tests is an offset from the base
1059 given in the table below.
1063 \Reason{With history setting of 1, change password to itself.}
1067 \Reason{With history setting of 2 but no password changes since
1068 principal creation, change password to itself.}
1072 \Reason{With history setting of 2 and one password change since
1073 principal creation, change password to itself
1074 and directly previous password.}
1079 \Reason{With a history setting of 3 and no password changes,
1080 change password to itself.}
1085 \Reason{With a history setting of 3 and 1 password change,
1086 change password to itself or previous password.}
1091 \Reason{With a history setting of 3 and 2 password changes,
1092 change password to itself and the two previous passwords.}
1097 \Reason{Change to previously unused password when now -
1098 last_pwd_change $<$ pw_min_life.}
1103 \Reason{Change to previously unused password that doesn't contain enough
1109 \Reason{Change to previously unused password that's too short.}
1114 \Reason{Change to previously unused password that's in the dictionary.}
1117 \subsubsection{List of parameter settings}
1119 In the table below, ``7 passes'' means that test 7 above passes and
1120 the rest of the tests fail.
1122 \begin{tabular}{llllll}
1123 Base & Modify access? & Own password? & Service & Pass/Fail \\ \hline
1124 0 & No & Yes & ADMIN & all fail \\
1125 20 & No & Yes & CHANGEPW & all fail \\
1126 40 & No & No & ADMIN & all fail \\
1127 60 & No & No & CHANGEPW & all fail \\
1128 80 & Yes & Yes & ADMIN & all fail \\
1129 100 & Yes & Yes & CHANGEPW & all fail \\
1130 120 & Yes & No & ADMIN & all fail \\
1131 140 & Yes & No & CHANGEPW & all fail \\
1134 \subsection{Other quality/history tests}
1138 \Reason{With history of 1, can change password to anything other than
1139 itself that doesn't conflict with other quality
1144 \Reason{With history of 2 and 2 password changes, can change password
1145 to original password.}
1150 \Reason{With history of 3 and 3 password changes, can change password
1151 to original password.}
1156 \Reason{Can change password when now - last_pwd_change $>$ pw_min_life.}
1161 \Reason{Can change password when it contains exactly the number of
1162 classes required by the policy.}
1167 \Reason{Can change password when it is exactly the length required by
1173 \Reason{Can change password to a word that isn't in the dictionary.}
1177 \subsection{Other tests}
1180 \Reason{Fails if database not initialized.}
1184 \Reason{Fails for non-existent principal.}
1188 \Reason{Fails for null password.}
1193 \Reason{Fails for empty-string password.}
1198 \Reason{Pw_expiration is set to now + max_pw_life if policy exists and
1199 has non-zero max_pw_life.}
1204 \Reason{Pw_expiration is set to 0 if policy exists and has zero
1210 \Reason{Pw_expiration is set to 0 if no policy.}
1215 \Reason{KRB5_KDC_REQUIRES_PWCHANGE bit is cleared when password is
1216 successfully changed.}
1221 \Reason{Fails for user with no access bits, on other's password.}
1226 \Reason{Fails for user with ``get'' but not ``modify'' access, on
1231 \Reason{Fails for user with ``delete'' but not ``modify'' access, on
1236 \Reason{Fails for user with ``add'' but not ``modify'' access, on
1241 \Reason{Succeeds for user with ``get'' and ``modify'' access, on
1247 \Reason{Succeeds for user with ``modify'' but not ``get'' access, on
1252 %\Reason{Password that would succeed if override_qual were false fails
1253 % if override_qual is true.}
1254 %\Expected{Returns CANNOT_OVERRIDE.}
1258 \section{ovsec_kadm_chpass_principal_util}
1260 Rerun all the tests listed for ovsec_kadm_chpass_principal above in
1261 Section \ref{ovseckadmchpassprincipal}. Verify that they succeed
1262 and fail in the same circumstances. Also verify that in each failure
1263 case, the error message returned in msg_ret is as specified in the
1264 functional specification.
1266 Also, run the following additional tests.
1269 \Reason{Null msg_ret is rejected.}
1274 \Reason{New password is put into pw_ret, when it's prompted for.}
1279 Reason{New password is put into pw_ret, when it's supplied by the
1285 \Reason{Successful invocation when pw_ret is null.}
1290 \section{ovsec_kadm_randkey_principal}
1292 \subsection{TOOSOON enforcement tests}
1294 This test should be run a number of times, as indicated in the table
1295 following it. The table also indicates the expected result of each
1299 \Reason{Change key when now - last_pwd_change $<$ pw_min_life.}
1302 \subsubsection{List of parameter settings}
1304 \begin{tabular}{llllll}
1305 Number & Modify Access? & Own Key? & Service & Pass/Fail \\ \hline
1306 1 & No & Yes & ADMIN & fail \\
1307 3 & No & Yes & CHANGEPW & fail \\
1308 5 & No & No & ADMIN & fail \\
1309 7 & No & No & CHANGEPW & fail \\
1310 9 & Yes & Yes & ADMIN & fail \\
1311 11 & Yes & Yes & CHANGEPW & fail \\
1312 13 & Yes & No & ADMIN & fail \\
1313 15 & Yes & No & CHANGEPW & fail \\
1316 \subsection{Other tests}
1319 \Reason{Fails if database not initialized.}
1323 \Reason{Fails for non-existent principal.}
1327 \Reason{Fails for null keyblock pointer.}
1332 \Reason{Pw_expiration is set to now + max_pw_life if policy exists and
1333 has non-zero max_pw_life.}
1338 \Reason{Pw_expiration is set to 0 if policy exists and has zero
1344 \Reason{Pw_expiration is set to 0 if no policy.}
1349 \Reason{KRB5_KDC_REQUIRES_PWCHANGE bit is cleared when key is
1350 successfully changed.}
1355 \Reason{Fails for user with no access bits, on other's password.}
1360 \Reason{Fails for user with ``get'' but not ``modify'' access, on
1365 \Reason{Fails for user with ``delete'' but not ``modify'' access, on
1370 \Reason{Fails for user with ``add'' but not ``modify'' access, on
1375 \Reason{Succeeds for user with ``get'' and ``modify'' access, on
1381 \Reason{Succeeds for user with ``modify'' but not ``get'' access, on
1386 \Reason{The new key that's assigned is truly random. XXX not sure how
1392 \section{ovsec_kadm_get_principal}
1395 \Reason{Fails for null ent.}
1396 \Status{Implemented}
1400 \Reason{Fails for non-existent principal.}
1401 \Status{Implemented}
1406 \Reason{Fails for user with no access bits, retrieving other principal.}
1408 \Status{Implemented}
1413 \Reason{Fails for user with ``add'' but not ``get'', getting principal
1414 other than his own, using ADMIN_SERVICE.}
1416 \Status{Implemented}
1420 \Reason{Fails for user with ``modify'' but not ``get'', getting
1421 principal other than his own, using ADMIN_SERVICE.}
1423 \Status{Implemented}
1427 \Reason{Fails for user with ``delete'' but not ``get'', getting
1428 principal other than his own, using ADMIN_SERVICE.}
1430 \Status{Implemented}
1434 \Reason{Fails for user with ``delete'' but not ``get'', getting
1435 principal other than his own, using CHANGEPW_SERVICE.}
1437 \Status{Implemented}
1442 \Reason{Fails for user with ``get'', getting principal other than his
1443 own, using CHANGEPW_SERVICE.}
1445 \Status{Implemented}
1450 \Reason{Succeeds for user without ``get'', retrieving self, using
1453 \Status{Implemented}
1457 \Reason{Succeeds for user without ``get'', retrieving self, using
1459 \Status{Implemented}
1463 \Reason{Succeeds for user with ``get'', retrieving self, using
1465 \Status{Implemented}
1469 \Reason{Succeeds for user with ``get'', retrieving self, using
1471 \Status{Implemented}
1476 \Reason{Succeeds for user with ``get'', retrieving other user, using
1478 \Status{Implemented}
1482 \Reason{Succeeds for user with ``get'' and ``modify'', retrieving
1483 other principal, using ADMIN_SERVICE.}
1484 \Status{Implemented}
1489 \section{ovsec_kadm_create_policy}
1492 \Reason{Fails for mask with undefined bit set.}
1493 \Status{Implemented - untested}
1498 \Reason{Fails if caller connected with CHANGEPW_SERVICE.}
1500 \Status{Implemented}
1504 \Reason{Fails for mask without POLICY bit set.}
1505 \Status{Implemented - untested}
1509 \Reason{Fails for mask with REF_COUNT bit set.}
1510 \Status{Implemented}
1514 \Reason{Fails for invalid policy name.}
1515 \Status{Implemented - untested}
1520 \Reason{Fails for existing policy name.}
1521 \Status{Implemented}
1525 \Reason{Fails for null policy name.}
1526 \Status{Implemented - untested}
1531 \Reason{Fails for empty-string policy name.}
1532 \Status{Implemented}
1537 \Reason{Accepts 0 for pw_min_life.}
1538 \Status{Implemented}
1543 \Reason{Accepts non-zero for pw_min_life.}
1544 \Status{Implemented}
1549 \Reason{Accepts 0 for pw_max_life.}
1550 \Status{Implemented}
1555 \Reason{Accepts non-zero for pw_max_life.}
1556 \Status{Implemented}
1561 \Reason{Rejects 0 for pw_min_length.}
1562 \Status{Implemented}
1567 \Reason{Accepts non-zero for pw_min_length.}
1568 \Status{Implemented}
1573 \Reason{Rejects 0 for pw_min_classes.}
1574 \Status{Implemented}
1579 \Reason{Accepts 1 for pw_min_classes.}
1580 \Status{Implemented}
1585 \Reason{Accepts 4 for pw_min_classes.}
1586 \Status{Implemented}
1591 \Reason{Rejects 5 for pw_min_classes.}
1592 \Status{Implemented}
1597 \Reason{Rejects 0 for pw_history_num.}
1598 \Status{Implemented}
1603 \Reason{Accepts 1 for pw_history_num.}
1604 \Status{Implemented}
1609 \Reason{Accepts 10 for pw_history_num.}
1610 \Status{Implemented}
1614 \Reason{Rejects 11 for pw_history_num.}
1615 \Status{Implemented - untested}
1620 \Reason{Fails for user with no access bits.}
1622 \Status{Implemented}
1627 \Reason{Fails for user with ``get'' but not ``add''.}
1629 \Status{Implemented}
1633 \Reason{Fails for user with ``modify'' but not ``add.''}
1635 \Status{Implemented - untested}
1639 \Reason{Fails for user with ``delete'' but not ``add.''}
1641 \Status{Implemented - untested}
1646 \Reason{Succeeds for user with ``add.''}
1647 \Status{Implemented}
1651 \Reason{Succeeds for user with ``get'' and ``add.''}
1652 \Status{Implemented - untested}
1656 \Reason{Rejects null policy argument.}
1657 \Status{Implemented - untested}
1661 \Reason{Rejects pw_min_life greater than pw_max_life.}
1665 \section{ovsec_kadm_delete_policy}
1668 \Reason{Fails for null policy name.}
1673 \Reason{Fails for empty-string policy name.}
1674 \Status{Implemented}
1678 \Reason{Fails for non-existent policy name.}
1682 \Reason{Fails for bad policy name.}
1687 \Reason{Fails if caller connected with CHANGEPW_SERVICE.}
1689 \Status{Implemented}
1694 \Reason{Fails for user with no access bits.}
1696 \Status{Implemented}
1701 \Reason{Fails for user with ``add'' but not ``delete''.}
1703 \Status{Implemented}
1707 \Reason{Fails for user with ``modify'' but not ``delete''.}
1712 \Reason{Fails for user with ``get'' but not ``delete.''}
1718 \Reason{Succeeds for user with only ``delete''.}
1719 \Status{Implemented}
1723 \Reason{Succeeds for user with ``delete'' and ``add''.}
1728 \Reason{Fails for policy with non-zero reference count.}
1729 \Status{Implemented}
1734 \section{ovsec_kadm_modify_policy}
1737 \Reason{Fails for mask with undefined bit set.}
1743 \Reason{Fails if caller connected with CHANGEPW_SERVICE.}
1744 \Status{Implemented}
1748 \Reason{Fails for mask with POLICY bit set.}
1752 \Reason{Fails for mask with REF_COUNT bit set.}
1753 \status{Implemented}
1757 \Reason{Fails for invalid policy name.}
1761 \Reason{Fails for non-existent policy name.}
1765 \Reason{Fails for null policy name.}
1770 \Reason{Fails for empty-string policy name.}
1771 \Status{Implemented}
1776 \Reason{Accepts 0 for pw_min_life.}
1777 \Status{Implemented}
1782 \Reason{Accepts non-zero for pw_min_life.}
1783 \Status{Implemented}
1788 \Reason{Accepts 0 for pw_max_life.}
1789 \Status{Implemented}
1794 \Reason{Accepts non-zero for pw_max_life.}
1795 \Status{Implemented}
1800 \Reason{Accepts 0 for pw_min_length.}
1801 \Status{Implemented}
1806 \Reason{Accepts non-zero for pw_min_length.}
1807 \Status{Implemented}
1812 \Reason{Rejects 0 for pw_min_classes.}
1813 \Status{Implemented}
1818 \Reason{Accepts 1 for pw_min_classes.}
1819 \Status{Implemented}
1824 \Reason{Accepts 4 for pw_min_classes.}
1825 \Status{Implemented}
1830 \Reason{Rejects 5 for pw_min_classes.}
1831 \Status{Implemented}
1836 \Reason{Rejects 0 for pw_history_num.}
1837 \Status{Implemented}
1842 \Reason{Accepts 1 for pw_history_num.}
1843 \Status{Implemented}
1848 \Reason{Accepts 10 for pw_history_num.}
1849 \Status{Implemented}
1854 \Reason{Fails for user with no access bits.}
1856 \Status{Implemented}
1861 \Reason{Fails for user with ``get'' but not ``modify''.}
1863 \Status{Implemented}
1867 \Reason{Fails for user with ``add'' but not ``modify.''}
1872 \Reason{Fails for user with ``delete'' but not ``modify.''}
1878 \Reason{Succeeds for user with ``modify.''}
1879 \Status{Implemented}
1883 \Reason{Succeeds for user with ``get'' and ``modify.''}
1887 \Reason{Rejects null policy argument.}
1891 \Reason{Rejects change which makes pw_min_life greater than
1895 \section{ovsec_kadm_get_policy}
1898 \Reason{Fails for null policy.}
1902 \Reason{Fails for invalid policy name.}
1907 \Reason{Fails for empty-string policy name.}
1908 \Status{Implemented}
1912 \Reason{Fails for non-existent policy name.}
1916 \Reason{Fails for null ent.}
1921 \Reason{Fails for user with no access bits trying to get other's
1922 policy, using ADMIN_SERVICE.}
1924 \Status{Implemented}
1929 \Reason{Fails for user with ``add'' but not ``get'' trying to get
1930 other's policy, using ADMIN_SERVICE.}
1932 \Status{Implemented}
1936 \Reason{Fails for user with ``modify'' but not ``get'' trying to get
1937 other's policy, using ADMIN_SERVICE.}
1942 \Reason{Fails for user with ``delete'' but not ``get'' trying to get
1943 other's policy, using ADMIN_SERVICE.}
1948 \Reason{Fails for user with ``delete'' but not ``get'' trying to get
1949 other's policy, using CHANGEPW_SERVICE.}
1955 \Reason{Succeeds for user with only ``get'', trying to get own policy,
1956 using ADMIN_SERVICE.}
1957 \Status{Implemented}
1962 \Reason{Succeeds for user with only ``get'', trying to get own policy,
1963 using CHANGEPW_SERVICE.}
1964 \Status{Implemented}
1968 \Reason{Succeeds for user with ``add'' and ``get'', trying to get own
1969 policy, using ADMIN_SERVICE.}
1973 \Reason{Succeeds for user with ``add'' and ``get'', trying to get own
1974 policy, using CHANGEPW_SERVICE.}
1978 \Reason{Succeeds for user without ``get'', trying to get own policy,
1979 using ADMIN_SERVICE.}
1984 \Reason{Succeeds for user without ``get'', trying to get own policy,
1985 using CHANGEPW_SERVICE.}
1986 \Status{Implemented}
1991 \Reason{Succeeds for user with ``get'', trying to get other's policy,
1992 using ADMIN_SERVICE.}
1993 \Status{Implemented}
1998 \Reason{Fails for user with ``get'', trying to get other's policy,
1999 using CHANGEPW_SERVICE.}
2001 \Status{Implemented}
2005 \Reason{Succeeds for user with ``modify'' and ``get'', trying to get
2006 other's policy, using ADMIN_SERVICE.}
2010 \Reason{Fails for user with ``modify'' and ``get'', trying to get
2011 other's policy, using CHANGEPW_SERVICE.}
2016 \section{ovsec_kadm_free_principal_ent}
2018 In addition to the tests listed here, a memory-leak detector such as
2019 TestCenter, Purify or dbmalloc should be used to verify that the
2020 memory freed by this function is really freed.
2023 \Reason{Null princ succeeds.}
2027 \Reason{Non-null princ succeeds.}
2031 \section{ovsec_kadm_free_policy_ent}
2033 In addition to the tests listed here, a memory-leak detector such as
2034 TestCenter, Purify or dbmalloc should be used to verify that the
2035 memory freed by this function is really freed.
2038 \Reason{Null policy succeeds.}
2042 \Reason{Non-null policy succeeds.}
2047 \section{ovsec_kadm_get_privs}
2050 \Reason{Fails for null pointer argument.}
2053 This test should be run with the 16 possible combinations of access
2054 bits (since there are 4 access bits, there are $2^4 = 16$ possible
2055 combinations of them):
2059 \Reason{Returns correct bit mask for access bits of user.}
2063 This test should be run locally:
2067 \Reason{Returns 0x0f.}