We have a table (this is oracle, but you can easily translate for your database):

(note, assumes you have a hibernate_sequence Oracle sequence... you could adjust that to do something else or uuid if you like...

CREATE TABLE SERVICE_PRINCIPALS
(
  PRINCIPAL_NAME     VARCHAR2(512 CHAR),
  ID                 INTEGER,
  LAST_UPDATED       TIMESTAMP(6),
  REASON             VARCHAR2(4000 CHAR)
);

COMMENT ON COLUMN SERVICE_PRINCIPALS.REASON IS 'reason for adding this principal';




CREATE UNIQUE INDEX SERVICE_PRINCIPALS_PK ON SERVICE_PRINCIPALS
(PRINCIPAL_NAME);


ALTER TABLE SERVICE_PRINCIPALS ADD (
  CONSTRAINT SERVICE_PRINCIPALS_PK
  PRIMARY KEY
  (PRINCIPAL_NAME)
  USING INDEX SERVICE_PRINCIPALS_PK);

Then we have a subject source (subjectproperties not sources.xml):

#########################################
## Configuration for source id: servPrinc
## Source configName: servPrinc
#########################################
subjectApi.source.servPrinc.id = servPrinc

# this is a friendly name for the source
subjectApi.source.servPrinc.name = Kerberos service principals

# type is not used all that much.  Can have multiple types, comma separate.  Can be person, group, application
subjectApi.source.servPrinc.types = application

# the adapter class implements the interface: edu.internet2.middleware.subject.Source
# adapter class must extend: edu.internet2.middleware.subject.provider.BaseSourceAdapter
# edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter2  :  if doing JDBC this should be used if possible.  All subject da
ta in one table/view.
# edu.internet2.middleware.grouper.subj.GrouperJdbcSourceAdapter   :  oldest JDBC source.  Put freeform queries in here
# edu.internet2.middleware.grouper.subj.GrouperJndiSourceAdapter   :  used for LDAP
subjectApi.source.servPrinc.adapterClass = edu.internet2.middleware.subject.provider.JDBCSourceAdapter

subjectApi.source.servPrinc.param.jdbcConnectionProvider.value = edu.internet2.middleware.grouper.subj.GrouperJdbcConnectionProvider

subjectApi.source.servPrinc.param.maxPageSize.value = 100

# ldap attribute which is the subject id.  e.g. exampleEduRegID   Each subject has one and only one subject id.  Generally it is opa
que and permanent.
subjectApi.source.servPrinc.param.SubjectID_AttributeType.value = loginid

# attribute which is the subject name
subjectApi.source.servPrinc.param.Name_AttributeType.value = name

# attribute which is the subject description
subjectApi.source.servPrinc.param.Description_AttributeType.value = description

# the 1st sort attribute for lists on screen that are derived from member table (e.g. search for member in group)
# you can have up to 5 sort attributes 
subjectApi.source.servPrinc.param.sortAttribute0.value = loginid

# the 1st search attribute for lists on screen that are derived from member table (e.g. search for member in group)
# you can have up to 5 search attributes 
subjectApi.source.servPrinc.param.searchAttribute0.value = loginid

subjectApi.source.servPrinc.param.useInClauseForIdAndIdentifier.value = true

subjectApi.source.servPrinc.param.identifierAttributes.value = loginid

#searchSubject: find a subject by ID.  ID is generally an opaque and permanent identifier, e.g. 12345678.
#  Each subject has one and only on ID.  Returns one result when searching for one ID.
subjectApi.source.servPrinc.search.searchSubject.param.numParameters.value = 1

# sql is the sql to search for the subject by id should use an {inclause}
subjectApi.source.servPrinc.search.searchSubject.param.sql.value = select    principal_name as name,    principal_name as loginid,   principal_name as description from    service_principals where     {inclause}

# inclause allows searching by subject for multiple ids or identifiers in one query, must have {inclause} in the sql query,
#    this will be subsituted to in clause with the following.  Should use a question mark ? for bind variable
subjectApi.source.servPrinc.search.searchSubject.param.inclause.value = principal_name = ?

#searchSubjectByIdentifier: find a subject by identifier.  Identifier is anything that uniquely
#  identifies the user, e.g. jsmith or jsmith@institution.edu.
#  Subjects can have multiple identifiers.  Note: it is nice to have if identifiers are unique
#  even across sources.  Returns one result when searching for one identifier.
subjectApi.source.servPrinc.search.searchSubjectByIdentifier.param.numParameters.value = 1

# sql is the sql to search for the subject by identifier should use an {inclause}
subjectApi.source.servPrinc.search.searchSubjectByIdentifier.param.sql.value = select    principal_name as name,    principal_name as loginid,    principal_name as description from    service_principals where     {inclause}

# inclause allows searching by subject for multiple ids or identifiers in one query, must have {inclause} in the sql query,
#    this will be subsituted to in clause with the following.  Should use a question mark ? for bind variable
subjectApi.source.servPrinc.search.searchSubjectByIdentifier.param.inclause.value = principal_name = ?

#   search: find subjects by free form search.  Returns multiple results.
subjectApi.source.servPrinc.search.search.param.numParameters.value = 1

# sql is the sql to search for the subject free-form search.  user question marks for bind variables
subjectApi.source.servPrinc.search.search.param.sql.value = select    principal_name as name,    principal_name as loginid,    principal_name as description from    service_principals where    (lower(principal_name) like lower(concat('%',concat(?,'%'))))



Then we have a subject source (sources.xml (if you havent converted to subject.properties yet), not subject.properties):

  <!-- Service Principal Subject Resolver -->
 <source adapterClass="edu.internet2.middleware.subject.provider.JDBCSourceAdapter">
    <id>servPrinc</id>
    <name>Kerberos service principals</name>
     <type>application</type>
     <init-param>
       <param-name>jdbcConnectionProvider</param-name>
       <param-value>edu.internet2.middleware.grouper.subj.GrouperJdbcConnectionProvider</param-value>
     </init-param>
     
    <!-- on a findPage() this is the most results returned --> 
    <init-param>
      <param-name>maxPageSize</param-name>
      <param-value>100</param-value>
    </init-param>
      <init-param>
       <param-name>SubjectID_AttributeType</param-name>
       <param-value>loginid</param-value>
     </init-param>
     <init-param>
       <param-name>Name_AttributeType</param-name>
       <param-value>name</param-value>
     </init-param>
     <init-param>
       <param-name>Description_AttributeType</param-name>
       <param-value>description</param-value>
     </init-param>
     <!-- init-param>
       <param-name>maxResults</param-name>
       <param-value>1000</param-value>
     </init-param -->

     <init-param>
       <param-name>sortAttribute0</param-name>
       <param-value>loginid</param-value>
     </init-param>
     <init-param>
       <param-name>searchAttribute0</param-name>
       <param-value>loginid</param-value>
     </init-param>
      <!-- if you are going to use the inclause attribute
        on the search to make the queries batchable when searching
        by id or identifier -->
      <init-param>
        <param-name>useInClauseForIdAndIdentifier</param-name>
        <param-value>true</param-value>
      </init-param>
      
      <!-- comma separate the identifiers for this row, this is for the findByIdentifiers if using an in clause -->
      <init-param>
        <param-name>identifierAttributes</param-name>
        <param-value>loginid</param-value>
      </init-param>
     <search>
         <searchType>searchSubject</searchType>
      <param>
          <param-name>numParameters</param-name>
          <param-value>1</param-value>
        </param>
         <param>
             <param-name>sql</param-name>
             <param-value>
select
   principal_name as name,
   principal_name as loginid,
   principal_name as description
from
   service_principals
where
    {inclause}
             </param-value>
          </param>
          <param>
              <param-name>inclause</param-name>
              <param-value>
 principal_name = ?
             </param-value>
          </param>
     </search>
     <search>
         <searchType>searchSubjectByIdentifier</searchType>
      <param>
          <param-name>numParameters</param-name>
          <param-value>1</param-value>
        </param>
         <param>
             <param-name>sql</param-name>
             <param-value>
select
   principal_name as name,
   principal_name as loginid,
   principal_name as description
from
   service_principals
where
    {inclause}
             </param-value>
          </param>
          <param>
              <param-name>inclause</param-name>
              <param-value>
 principal_name = ?
             </param-value>
         </param>
     </search>
     <search>
        <searchType>search</searchType>
     <param>
          <param-name>numParameters</param-name>
          <param-value>1</param-value>
        </param>
         <param>
             <param-name>sql</param-name>
             <param-value>
select
   principal_name as name,
   principal_name as loginid,
   principal_name as description
from
   service_principals
where
   (lower(principal_name) like lower(concat('%',concat(?,'%'))))
             </param-value>
         </param>
     </search>
   </source>

Here is a GSH script (oracle) to add a new one:

edit kerb and reason...


[appadmin@fastprod-mgmt-01 bin]$ more createKerbTest.gsh 
grouperSession = GrouperSession.startRootSession();
kerb = "test_kerb/school.edu";
reason = "test kerb";
sqlRun("insert into service_principals (principal_name, id, last_updated, reason) values ('" + kerb + "', hibernate_sequence.nextval, systimestamp, '" + reason + "')");
addMember("school:etc:ldapUsers", kerb);
addMember("school:etc:webServiceClientUsers", kerb);
[appadmin@fastprod-mgmt-01 bin]$ ./gsh createKerbTest.gsh

Heres a GSH script (postgres) to add a new one:

grouperSession = GrouperSession.startRootSession();
kerb = "test_kerb2/school.edu";
reason = "test kerb2 for john smith in dept a";
sqlRun("insert into service_principals (principal_name, id, last_updated, reason) values ('" + kerb + "', (select max(id)+1 from service_principals), CURRENT_TIMESTAMP, '" + reason + "')");
addMember("school:etc:ldapUsers", kerb);
addMember("school:etc:webServiceClientUsers", kerb);
  • No labels