From: Chris B. <buc...@us...> - 2011-06-08 22:00:15
|
Update of /cvsroot/sblim/sfcb In directory vz-cvs-3.sog:/tmp/cvs-serv9892 Modified Files: httpAdapter.c cimXmlRequest.c cimXmlRequest.h default.reg.in configure.ac ChangeLog NEWS Added Files: cimAccountPassthrough.mof cimAccountPassthroughProvider.c Log Message: [ 3313833 ] Allow for passthrough for expired user to update password Index: cimXmlRequest.c =================================================================== RCS file: /cvsroot/sblim/sfcb/cimXmlRequest.c,v retrieving revision 1.61 retrieving revision 1.62 diff -u -d -r1.61 -r1.62 --- cimXmlRequest.c 21 Dec 2010 23:01:49 -0000 1.61 +++ cimXmlRequest.c 8 Jun 2011 22:00:12 -0000 1.62 @@ -349,6 +349,27 @@ return rs; }; +#ifdef ALLOW_UPDATE_EXPIRED_PW + +static char * +getErrExpiredSegment() +{ + char* msg = sfcb_snprintf("<ERROR CODE=\"2\" \ +DESCRIPTION=\"User Account Expired\">\n\ +<INSTANCE CLASSNAME=\"CIM_Error\">\n\ +<PROPERTY NAME=\"ErrorType\" TYPE=\"uint16\">\ +<VALUE>1</VALUE></PROPERTY>\n\ +<PROPERTY NAME=\"OtherErrorType\" TYPE=\"string\">\ +<VALUE>Password Expired</VALUE></PROPERTY>\n\ +<PROPERTY NAME=\"ProbableCause\" TYPE=\"uint16\">\ +<VALUE>117</VALUE></PROPERTY>\n\ +</INSTANCE>\n</ERROR>\n"); + + return msg; +} + +#endif /* ALLOW_UPDATE_EXPIRED_PW */ + static RespSegments ctxErrResponse(RequestHdr * hdr, BinRequestContext * ctx, int meth) { @@ -2628,12 +2649,27 @@ {invokeMethod}, //OPS_InvokeMethod 24 }; -RespSegments handleCimXmlRequest(CimXmlRequestContext * ctx) +RespSegments sendHdrToHandler(RequestHdr* hdr, CimXmlRequestContext* ctx) { + + RespSegments rs; + Handler hdlr; + HeapControl *hc; + + hc = markHeap(); + hdlr = handlers[hdr->opType]; + rs = hdlr.handler(ctx, hdr); + releaseHeap(hc); + + ctx->className = hdr->className; + ctx->operation = hdr->opType; + + return rs; +} + +RespSegments handleCimXmlRequest(CimXmlRequestContext * ctx, int flags) { RespSegments rs; RequestHdr hdr; - Handler hdlr; - HeapControl *hc; #ifdef SFCB_DEBUG struct rusage us,ue; struct timeval sv, ev; @@ -2668,15 +2704,34 @@ rs = iMethodErrResponse(&hdr,getErrSegment(CMPI_RC_ERR_FAILED, "invalid imethodcall XML")); } - } else { - hc = markHeap(); - hdlr = handlers[hdr.opType]; - rs = hdlr.handler(ctx, &hdr); - releaseHeap(hc); - - ctx->className=hdr.className; - ctx->operation=hdr.opType; + } + +#ifdef ALLOW_UPDATE_EXPIRED_PW + else if (flags) { + + /* pulled from 1.4 branch's buildInvokeMethodRequest() */ + XtokMethodCall *req = hdr.cimRequest; + hdr.className = req->op.className.data; + + /* request from user with an expired password AND requesting password update */ + if (flags == (HCR_UPDATE_PW | HCR_EXPIRED_PW) && hdr.className && + (strcasecmp(hdr.className, "SFCB_Account") == 0) && hdr.methodCall) { + rs = sendHdrToHandler(&hdr, ctx); + } + else { /* expired user tried to invoke non-UpdatePassword request */ + if (hdr.methodCall) { + rs = methodErrResponse(&hdr, getErrExpiredSegment()); + } else { + rs = iMethodErrResponse(&hdr, getErrExpiredSegment()); + } + } } +#endif /* ALLOW_UPDATE_EXPIRED_PW */ + + else { + rs = sendHdrToHandler(&hdr, ctx); + } + rs.buffer = hdr.xmlBuffer; freeCimXmlRequest(hdr); Index: ChangeLog =================================================================== RCS file: /cvsroot/sblim/sfcb/ChangeLog,v retrieving revision 1.658 retrieving revision 1.659 diff -u -d -r1.658 -r1.659 --- ChangeLog 8 Jun 2011 20:29:13 -0000 1.658 +++ ChangeLog 8 Jun 2011 22:00:12 -0000 1.659 @@ -1,3 +1,10 @@ +2011-06-08 Chris Buccella <buc...@li...> + + * cimAccountPassthroughProvider.c, cimAccountPassthrough.mof, + cimXmlRequest.c, cimXmlRequest.h, httpAdapter.c, Makefile.am, + configure.ac, default.reg.in: + [ 3313833 ] Allow for passthrough for expired user to update password + 2011-05-02 Michael Chase-Salerno <br...@li...> * configure.ac Index: cimXmlRequest.h =================================================================== RCS file: /cvsroot/sblim/sfcb/cimXmlRequest.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- cimXmlRequest.h 16 May 2006 13:10:20 -0000 1.6 +++ cimXmlRequest.h 8 Jun 2011 22:00:12 -0000 1.7 @@ -60,8 +60,12 @@ int operation; } CimXmlRequestContext; -extern RespSegments handleCimXmlRequest(CimXmlRequestContext * ctx); +extern RespSegments handleCimXmlRequest(CimXmlRequestContext * ctx, int flags); extern int cleanupCimXmlRequest(RespSegments * rs); +#ifdef ALLOW_UPDATE_EXPIRED_PW + #define HCR_EXPIRED_PW 1 /* flag: expired user tries to auth */ + #define HCR_UPDATE_PW 2 /* flag: UpdateExpiredPassword HTTP header */ +#endif #endif --- NEW FILE: cimAccountPassthrough.mof --- [Description ("SFCB_Account is a dummy class used for the sole purpose of " "allowing an InvokeMethod request from an expired user to " "pass through to the CIM_Account provider in order to update " "the expired password." )] class SFCB_Account { [Description ("Provide the new password to be used in the " "ModifyInstance operation on CIM_Account. " )] uint8 UpdateExpiredPassword( [IN] string UserPassword, [OUT] string Message); }; Index: configure.ac =================================================================== RCS file: /cvsroot/sblim/sfcb/configure.ac,v retrieving revision 1.118 retrieving revision 1.119 diff -u -d -r1.118 -r1.119 --- configure.ac 8 Jun 2011 20:29:13 -0000 1.118 +++ configure.ac 8 Jun 2011 22:00:12 -0000 1.119 @@ -117,6 +117,10 @@ [AC_HELP_STRING([--enable-uds], [Enable UDS authentication.])]) +AC_ARG_ENABLE(expired-pw-update, + [AC_HELP_STRING([--enable-expired-pw-update], + [allow a user with an expired account to invoke a password update for CIM_Account (see docs).])]) + # Size checks AC_CHECK_SIZEOF(void*) AC_CHECK_SIZEOF(int) @@ -183,6 +187,13 @@ AC_DEFINE(SLP_HOSTNAME_LIB,,[SLP Hostname lib enabled]) fi +if test "$enable_expired_pw_update" == "yes"; then + LOAD_SFCBACCOUNT_PROVIDER= + AC_DEFINE(ALLOW_UPDATE_EXPIRED_PW,1,[Expired Account Password Update enabled]) +else + LOAD_SFCBACCOUNT_PROVIDER='#' +fi +AC_SUBST(LOAD_SFCBACCOUNT_PROVIDER) # Check and configure requested tests. if test "$enable_tests" == "yes"; then @@ -195,7 +206,7 @@ fi fi if test "$enable_tests" != ""; then - enable_settableretry="yes" ++ enable_settableretry="yes" fi @@ -511,6 +522,7 @@ AM_CONDITIONAL(IPV6,[test "$enable_ipv6" == "yes"]) AM_CONDITIONAL(LOCAL_CONNECT_NO_INDICATION,[test "$enable_local_connect_only" == "yes" -a "$enable_indications" == "no"]) AM_CONDITIONAL(LOCAL_CONNECT_ONLY,[test "$enable_local_connect_only" == "yes"]) +AM_CONDITIONAL(ACCOUNT_PASSTHRU,[test "$enable_expired_pw_update" == "yes"]) AC_CONFIG_FILES([Makefile sfcb.spec sfcbrepos.sh sfcbstage.sh sfcbunstage.sh sfcbuuid.sh sfcb.cfg.pre getSchema.sh.pre 20_indication.mof.pre @@ -538,6 +550,7 @@ echo -e "uds"\\t\\t\\t\\t"${enable_uds:-no}" echo -e "tests"\\t\\t\\t\\t"${enable_tests:-no}" echo -e "debug"\\t\\t\\t\\t"${enable_debug:-no}" +echo -e "Allow expired account pw update"\\t"${enable_expired_pw_update:-no}" echo -e "Settable retry parameters"\\t"${enable_settableretry:-no}" echo ================================================================= echo Index: httpAdapter.c =================================================================== RCS file: /cvsroot/sblim/sfcb/httpAdapter.c,v retrieving revision 1.88 retrieving revision 1.89 diff -u -d -r1.88 -r1.89 --- httpAdapter.c 8 Mar 2011 20:47:11 -0000 1.88 +++ httpAdapter.c 8 Jun 2011 22:00:12 -0000 1.89 @@ -749,6 +749,7 @@ struct timeval sv, ev; CimXmlRequestContext ctx; int breakloop; + int hcrFlags = 0; /* flags to pass to handleCimRequest() */ _SFCB_ENTER(TRACE_HTTPDAEMON, "doHttpRequest"); @@ -894,6 +895,11 @@ discardInput=2; } } +#ifdef ALLOW_UPDATE_EXPIRED_PW + else if (strncasecmp(hdr, "Pragma: UpdateExpiredPassword", 29) == 0) { + hcrFlags |= HCR_UPDATE_PW; + } +#endif } #if defined USE_SSL @@ -917,6 +923,7 @@ #endif int authorized = 0; + int barc = 0; #ifdef HAVE_UDS if (!discardInput && doUdsAuth) { struct sockaddr_un sun; @@ -930,13 +937,28 @@ } #endif if (!authorized && !discardInput && doBa) { - if (inBuf.authorization && (baValidate(inBuf.authorization,&inBuf.principal) != AUTH_PASS)) { - char more[]="WWW-Authenticate: Basic realm=\"cimom\"\r\n"; - genError(conn_fd, &inBuf, 401, "Unauthorized", more); - /* we continue to parse headers and empty the socket - to be graceful with the client */ - discardInput=1; - } + + if (inBuf.authorization) { + barc = baValidate(inBuf.authorization,&inBuf.principal); +#ifdef ALLOW_UPDATE_EXPIRED_PW + if (barc == AUTH_EXPIRED) { + hcrFlags |= HCR_EXPIRED_PW; + } + else if (barc == AUTH_PASS) { + hcrFlags = 0; /* clear flags so non-expired user doesn't update pw */ + } + else if (barc == AUTH_FAIL) { +#else + if (barc != AUTH_PASS) { +#endif + char more[]="WWW-Authenticate: Basic realm=\"cimom\"\r\n"; + genError(conn_fd, &inBuf, 401, "Unauthorized", more); + /* we continue to parse headers and empty the socket + to be graceful with the client */ + discardInput=1; + } + } + #if defined USE_SSL else if (sfcbSSLMode && ccVerifyMode != CC_VERIFY_IGNORE) { /* associate certificate with principal for next request */ @@ -1005,7 +1027,7 @@ } #endif - response = handleCimXmlRequest(&ctx); + response = handleCimXmlRequest(&ctx, hcrFlags); } else { response = nullResponse; Index: NEWS =================================================================== RCS file: /cvsroot/sblim/sfcb/NEWS,v retrieving revision 1.584 retrieving revision 1.585 diff -u -d -r1.584 -r1.585 --- NEWS 16 May 2011 22:14:08 -0000 1.584 +++ NEWS 8 Jun 2011 22:00:12 -0000 1.585 @@ -3,6 +3,7 @@ New features: - 3190623 Set *IsSettable properties to false for IndicationService +- 3313833 Allow for passthrough for expired user to update password Bugs fixed: Index: default.reg.in =================================================================== RCS file: /cvsroot/sblim/sfcb/default.reg.in,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- default.reg.in 17 May 2010 20:24:08 -0000 1.14 +++ default.reg.in 8 Jun 2011 22:00:12 -0000 1.15 @@ -70,6 +70,13 @@ @LOAD_INDICATION_PROVIDER@ type: association @LOAD_INDICATION_PROVIDER@ namespace: root/interop # +@LOAD_SFCBACCOUNT_PROVIDER@[SFCB_Account] +@LOAD_SFCBACCOUNT_PROVIDER@ provider: CimAccountPassthroughProvider +@LOAD_SFCBACCOUNT_PROVIDER@ location: sfccimAccountPassthroughProvider +@LOAD_SFCBACCOUNT_PROVIDER@ type: method +@LOAD_SFCBACCOUNT_PROVIDER@ namespace: root/interop +@LOAD_SFCBACCOUNT_PROVIDER@ parameters: AccountClass=root/cimv2:cim_account +# [SFCB_RegisteredProfile] provider: ProfileProvider location: sfcProfileProvider --- NEW FILE: cimAccountPassthroughProvider.c --- /* * cimAccountPassthroughProvider.c * * (C) Copyright IBM Corp. 2011 * * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE * CONSTITUTES RECIPIENTS ACCEPTANCE OF THE AGREEMENT. * * You can obtain a current copy of the Eclipse Public License from * http://www.opensource.org/licenses/eclipse-1.0.php * * Author: Chris Buccella <buc...@li...> * * Description: * * This provider's only function is to handle an InvokeMethod request * for UpdateExpiredPassword and pass it on to the CIM_Account provider * */ #include "cmpi/cmpidt.h" #include "cmpi/cmpift.h" #include "cmpi/cmpimacs.h" #include <stdlib.h> #include <string.h> #include "trace.h" #include "native.h" /* * ------------------------------------------------------------------------- */ static const CMPIBroker *_broker; void setStatus(CMPIStatus *st, CMPIrc rc, char *msg) { st->rc = rc; if (rc != 0 && msg) st->msg = sfcb_native_new_CMPIString(msg, NULL, 0); else st->msg = NULL; } CMPIStatus CimAccountPassthroughProviderMethodCleanup(CMPIMethodMI * mi, const CMPIContext *ctx, CMPIBoolean terminate) { CMPIStatus st = { CMPI_RC_OK, NULL }; _SFCB_ENTER(TRACE_PROVIDERS, "CimAccountPassthroughProviderMethodCleanup"); _SFCB_RETURN(st); } CMPIStatus CimAccountPassthroughProviderInvokeMethod(CMPIMethodMI * mi, const CMPIContext *ctx, const CMPIResult *rslt, const CMPIObjectPath * ref, const char *methodName, const CMPIArgs * in, CMPIArgs * out) { CMPIStatus st = { CMPI_RC_OK, NULL }; _SFCB_ENTER(TRACE_PROVIDERS, "CimAccountPassthroughProviderInvokeMethod"); _SFCB_TRACE(1, ("--- Method: %s", methodName)); CMPIData arg = CMGetArg(in, "UserPassword", &st); if (st.rc != CMPI_RC_OK) { setStatus(&st, CMPI_RC_ERR_NOT_FOUND, "Required argument UserPassword missing"); _SFCB_RETURN(st); } const char* newPW = CMGetCharPtr(arg.value.string); if (strcasecmp(methodName, "UpdateExpiredPassword") == 0) { /* check to see if parameters were specified in providerRegister */ CMPIStatus parm_st = { CMPI_RC_OK, NULL }; CMPIData parmdata = CMGetContextEntry(ctx, "sfcbProviderParameters", &parm_st); char* acct_cn = "CIM_Account"; char* acct_ns = "root/cimv2"; if (parm_st.rc == CMPI_RC_OK ) { const char* parms = CMGetCharPtr(parmdata.value.string); /* cacheLimit is currently the only param, so just take whatever is after the '=' */ char* val = strchr(parms,'='); if (val) { char* colon = strchr(val,':'); if (colon) { // acct_cn = colon + sizeof(char); acct_cn = colon+1; colon[0] = '\0'; acct_ns = val+1; } } } CMPIObjectPath *caOp = CMNewObjectPath(_broker, acct_ns, acct_cn, &st); if (strcasecmp(acct_cn, "cim_account")) { if (!CMClassPathIsA(_broker, caOp, "cim_account", &st)) { setStatus(&st, CMPI_RC_ERR_NOT_FOUND, "Class specified for password update not a CIM_Account"); _SFCB_RETURN(st); } } CMPIData principal = CMGetContextEntry(ctx, "CMPIPrincipal", &st); char* httpUser = CMGetCharPtr(principal.value.string); /* Important! We assume the Name key = the expired HTTP user */ CMPIData item, nameKey; CMPIString* nameKeyStr; CMPIEnumeration *enm = CBEnumInstanceNames(_broker, ctx, caOp, &st); CMPIInstance *caInst = NULL; while (enm && CMHasNext(enm, &st)) { // fprintf(stderr, " got an instance of CIM_Account\n"); item = CMGetNext(enm, &st); caOp = item.value.ref; nameKey = CMGetKey(caOp, "Name", &st); if (st.rc == CMPI_RC_OK) { nameKeyStr = nameKey.value.string; if (strcmp(CMGetCharsPtr(nameKeyStr, &st), httpUser) == 0) { caInst = CBGetInstance(_broker, ctx, caOp, NULL, &st); break; } } } if (caInst) { /* ok to send ModifyInstance request to CIM_Account prov */ CMPIString* npwv; npwv = CMNewString(_broker, newPW, NULL); CMPIArray *pwArray = CMNewArray(_broker, 1, CMPI_string, &st); st = CMSetArrayElementAt(pwArray, 0, (CMPIValue*)&(npwv), CMPI_string); CMSetProperty(caInst, "UserPassword", (CMPIValue*)&(pwArray), CMPI_stringA); st = CBModifyInstance(_broker, ctx, caOp, caInst, NULL); CMPIValue av; av.string = st.msg; CMAddArg(out, "Message", &av, CMPI_string); } else { /* no caInst; probably wrong principal (UserName didn't match) */ _SFCB_TRACE(1, ("--- Invalid request method: %s", methodName)); setStatus(&st, CMPI_RC_ERR_NOT_FOUND, "No matching CIM_Account for user"); } } else { _SFCB_TRACE(1, ("--- Invalid request method: %s", methodName)); setStatus(&st, CMPI_RC_ERR_METHOD_NOT_FOUND, "Invalid request method"); } _SFCB_RETURN(st); } CMMethodMIStub(CimAccountPassthroughProvider, CimAccountPassthroughProvider, _broker, CMNoHook); /* MODELINES */ /* DO NOT EDIT BELOW THIS COMMENT */ /* Modelines are added by 'make pretty' */ /* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil; -*- */ /* vi:set ts=2 sts=2 sw=2 expandtab: */ |